<commit_before>/*
 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
 * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "core/inspector/InspectorFrontendHost.h"

#include "bindings/v8/ScriptFunctionCall.h"
#include "bindings/v8/ScriptState.h"
#include "core/clipboard/Pasteboard.h"
#include "core/fetch/ResourceFetcher.h"
#include "core/frame/LocalFrame.h"
#include "core/html/parser/TextResourceDecoder.h"
#include "core/inspector/InspectorController.h"
#include "core/inspector/InspectorFrontendClient.h"
#include "core/loader/FrameLoader.h"
#include "core/page/ContextMenuController.h"
#include "core/page/ContextMenuProvider.h"
#include "core/page/Page.h"
#include "core/rendering/RenderTheme.h"
#include "platform/ContextMenu.h"
#include "platform/ContextMenuItem.h"
#include "platform/SharedBuffer.h"
#include "platform/UserGestureIndicator.h"
#include "platform/network/ResourceError.h"
#include "platform/network/ResourceRequest.h"
#include "platform/network/ResourceResponse.h"

namespace WebCore {

class FrontendMenuProvider FINAL : public ContextMenuProvider {
public:
    static PassRefPtr<FrontendMenuProvider> create(InspectorFrontendHost* frontendHost, ScriptObject frontendApiObject, const Vector<ContextMenuItem>& items)
    {
        return adoptRef(new FrontendMenuProvider(frontendHost, frontendApiObject, items));
    }

    void disconnect()
    {
        m_frontendApiObject = ScriptObject();
        m_frontendHost = 0;
    }

private:
    FrontendMenuProvider(InspectorFrontendHost* frontendHost, ScriptObject frontendApiObject, const Vector<ContextMenuItem>& items)
        : m_frontendHost(frontendHost)
        , m_frontendApiObject(frontendApiObject)
        , m_items(items)
    {
    }

    virtual ~FrontendMenuProvider()
    {
        contextMenuCleared();
    }

    virtual void populateContextMenu(ContextMenu* menu) OVERRIDE
    {
        for (size_t i = 0; i < m_items.size(); ++i)
            menu->appendItem(m_items[i]);
    }

    virtual void contextMenuItemSelected(const ContextMenuItem* item) OVERRIDE
    {
        if (m_frontendHost) {
            UserGestureIndicator gestureIndicator(DefinitelyProcessingNewUserGesture);
            int itemNumber = item->action() - ContextMenuItemBaseCustomTag;

            ScriptFunctionCall function(m_frontendApiObject, "contextMenuItemSelected");
            function.appendArgument(itemNumber);
            function.call();
        }
    }

    virtual void contextMenuCleared() OVERRIDE
    {
        if (m_frontendHost) {
            ScriptFunctionCall function(m_frontendApiObject, "contextMenuCleared");
            function.call();

            m_frontendHost->m_menuProvider = 0;
        }
        m_items.clear();
    }

    InspectorFrontendHost* m_frontendHost;
    ScriptObject m_frontendApiObject;
    Vector<ContextMenuItem> m_items;
};

InspectorFrontendHost::InspectorFrontendHost(InspectorFrontendClient* client, Page* frontendPage)
    : m_client(client)
    , m_frontendPage(frontendPage)
    , m_menuProvider(0)
{
    ScriptWrappable::init(this);
}

InspectorFrontendHost::~InspectorFrontendHost()
{
    ASSERT(!m_client);
}

void InspectorFrontendHost::disconnectClient()
{
    m_client = 0;
    if (m_menuProvider)
        m_menuProvider->disconnect();
    m_frontendPage = 0;
}

void InspectorFrontendHost::setZoomFactor(float zoom)
{
    m_frontendPage->mainFrame()->setPageAndTextZoomFactors(zoom, 1);
}

float InspectorFrontendHost::zoomFactor()
{
    return m_frontendPage->mainFrame()->pageZoomFactor();
}

void InspectorFrontendHost::inspectedURLChanged(const String& newURL)
{
    if (m_client)
        m_client->inspectedURLChanged(newURL);
}

void InspectorFrontendHost::setInjectedScriptForOrigin(const String& origin, const String& script)
{
    m_frontendPage->inspectorController().setInjectedScriptForOrigin(origin, script);
}

void InspectorFrontendHost::copyText(const String& text)
{
    Pasteboard::generalPasteboard()->writePlainText(text, Pasteboard::CannotSmartReplace);
}

static String escapeUnicodeNonCharacters(const String& str)
{
    StringBuilder dst;
    for (unsigned i = 0; i < str.length(); ++i) {
        UChar c = str[i];
        if (c > 126) {
            unsigned symbol = static_cast<unsigned>(c);
            String symbolCode = String::format("\\u%04X", symbol);
            dst.append(symbolCode);
        } else {
            dst.append(c);
        }

    }
    return dst.toString();
}

void InspectorFrontendHost::sendMessageToBackend(const String& message)
{
    if (m_client)
        m_client->sendMessageToBackend(escapeUnicodeNonCharacters(message));
}

void InspectorFrontendHost::sendMessageToEmbedder(const String& message)
{
    if (m_client)
        m_client->sendMessageToEmbedder(escapeUnicodeNonCharacters(message));
}

void InspectorFrontendHost::showContextMenu(Event* event, const Vector<ContextMenuItem>& items)
{
    if (!event)
        return;

    ASSERT(m_frontendPage);
    ScriptState* frontendScriptState = mainWorldScriptState(m_frontendPage->mainFrame());
    ScriptObject frontendApiObject;
    if (!ScriptGlobalObject::get(frontendScriptState, "InspectorFrontendAPI", frontendApiObject)) {
        ASSERT_NOT_REACHED();
        return;
    }
    RefPtr<FrontendMenuProvider> menuProvider = FrontendMenuProvider::create(this, frontendApiObject, items);
    m_frontendPage->contextMenuController().showContextMenu(event, menuProvider);
    m_menuProvider = menuProvider.get();
}

String InspectorFrontendHost::getSelectionBackgroundColor()
{
    return RenderTheme::theme().activeSelectionBackgroundColor().serialized();
}

String InspectorFrontendHost::getSelectionForegroundColor()
{
    return RenderTheme::theme().activeSelectionForegroundColor().serialized();
}

bool InspectorFrontendHost::isUnderTest()
{
    return m_client && m_client->isUnderTest();
}

} // namespace WebCore
<commit_msg>Use less conservative condition when detecting noncharacter unicode symbols<commit_after>/*
 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
 * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "core/inspector/InspectorFrontendHost.h"

#include "bindings/v8/ScriptFunctionCall.h"
#include "bindings/v8/ScriptState.h"
#include "core/clipboard/Pasteboard.h"
#include "core/fetch/ResourceFetcher.h"
#include "core/frame/LocalFrame.h"
#include "core/html/parser/TextResourceDecoder.h"
#include "core/inspector/InspectorController.h"
#include "core/inspector/InspectorFrontendClient.h"
#include "core/loader/FrameLoader.h"
#include "core/page/ContextMenuController.h"
#include "core/page/ContextMenuProvider.h"
#include "core/page/Page.h"
#include "core/rendering/RenderTheme.h"
#include "platform/ContextMenu.h"
#include "platform/ContextMenuItem.h"
#include "platform/SharedBuffer.h"
#include "platform/UserGestureIndicator.h"
#include "platform/network/ResourceError.h"
#include "platform/network/ResourceRequest.h"
#include "platform/network/ResourceResponse.h"

namespace WebCore {

class FrontendMenuProvider FINAL : public ContextMenuProvider {
public:
    static PassRefPtr<FrontendMenuProvider> create(InspectorFrontendHost* frontendHost, ScriptObject frontendApiObject, const Vector<ContextMenuItem>& items)
    {
        return adoptRef(new FrontendMenuProvider(frontendHost, frontendApiObject, items));
    }

    void disconnect()
    {
        m_frontendApiObject = ScriptObject();
        m_frontendHost = 0;
    }

private:
    FrontendMenuProvider(InspectorFrontendHost* frontendHost, ScriptObject frontendApiObject, const Vector<ContextMenuItem>& items)
        : m_frontendHost(frontendHost)
        , m_frontendApiObject(frontendApiObject)
        , m_items(items)
    {
    }

    virtual ~FrontendMenuProvider()
    {
        contextMenuCleared();
    }

    virtual void populateContextMenu(ContextMenu* menu) OVERRIDE
    {
        for (size_t i = 0; i < m_items.size(); ++i)
            menu->appendItem(m_items[i]);
    }

    virtual void contextMenuItemSelected(const ContextMenuItem* item) OVERRIDE
    {
        if (m_frontendHost) {
            UserGestureIndicator gestureIndicator(DefinitelyProcessingNewUserGesture);
            int itemNumber = item->action() - ContextMenuItemBaseCustomTag;

            ScriptFunctionCall function(m_frontendApiObject, "contextMenuItemSelected");
            function.appendArgument(itemNumber);
            function.call();
        }
    }

    virtual void contextMenuCleared() OVERRIDE
    {
        if (m_frontendHost) {
            ScriptFunctionCall function(m_frontendApiObject, "contextMenuCleared");
            function.call();

            m_frontendHost->m_menuProvider = 0;
        }
        m_items.clear();
    }

    InspectorFrontendHost* m_frontendHost;
    ScriptObject m_frontendApiObject;
    Vector<ContextMenuItem> m_items;
};

InspectorFrontendHost::InspectorFrontendHost(InspectorFrontendClient* client, Page* frontendPage)
    : m_client(client)
    , m_frontendPage(frontendPage)
    , m_menuProvider(0)
{
    ScriptWrappable::init(this);
}

InspectorFrontendHost::~InspectorFrontendHost()
{
    ASSERT(!m_client);
}

void InspectorFrontendHost::disconnectClient()
{
    m_client = 0;
    if (m_menuProvider)
        m_menuProvider->disconnect();
    m_frontendPage = 0;
}

void InspectorFrontendHost::setZoomFactor(float zoom)
{
    m_frontendPage->mainFrame()->setPageAndTextZoomFactors(zoom, 1);
}

float InspectorFrontendHost::zoomFactor()
{
    return m_frontendPage->mainFrame()->pageZoomFactor();
}

void InspectorFrontendHost::inspectedURLChanged(const String& newURL)
{
    if (m_client)
        m_client->inspectedURLChanged(newURL);
}

void InspectorFrontendHost::setInjectedScriptForOrigin(const String& origin, const String& script)
{
    m_frontendPage->inspectorController().setInjectedScriptForOrigin(origin, script);
}

void InspectorFrontendHost::copyText(const String& text)
{
    Pasteboard::generalPasteboard()->writePlainText(text, Pasteboard::CannotSmartReplace);
}

static String escapeUnicodeNonCharacters(const String& str)
{
    StringBuilder dst;
    for (unsigned i = 0; i < str.length(); ++i) {
        UChar c = str[i];
        if (c >= 0xD800) {
            unsigned symbol = static_cast<unsigned>(c);
            String symbolCode = String::format("\\u%04X", symbol);
            dst.append(symbolCode);
        } else {
            dst.append(c);
        }

    }
    return dst.toString();
}

void InspectorFrontendHost::sendMessageToBackend(const String& message)
{
    if (m_client)
        m_client->sendMessageToBackend(escapeUnicodeNonCharacters(message));
}

void InspectorFrontendHost::sendMessageToEmbedder(const String& message)
{
    if (m_client)
        m_client->sendMessageToEmbedder(escapeUnicodeNonCharacters(message));
}

void InspectorFrontendHost::showContextMenu(Event* event, const Vector<ContextMenuItem>& items)
{
    if (!event)
        return;

    ASSERT(m_frontendPage);
    ScriptState* frontendScriptState = mainWorldScriptState(m_frontendPage->mainFrame());
    ScriptObject frontendApiObject;
    if (!ScriptGlobalObject::get(frontendScriptState, "InspectorFrontendAPI", frontendApiObject)) {
        ASSERT_NOT_REACHED();
        return;
    }
    RefPtr<FrontendMenuProvider> menuProvider = FrontendMenuProvider::create(this, frontendApiObject, items);
    m_frontendPage->contextMenuController().showContextMenu(event, menuProvider);
    m_menuProvider = menuProvider.get();
}

String InspectorFrontendHost::getSelectionBackgroundColor()
{
    return RenderTheme::theme().activeSelectionBackgroundColor().serialized();
}

String InspectorFrontendHost::getSelectionForegroundColor()
{
    return RenderTheme::theme().activeSelectionForegroundColor().serialized();
}

bool InspectorFrontendHost::isUnderTest()
{
    return m_client && m_client->isUnderTest();
}

} // namespace WebCore
<|endoftext|>


<commit_before>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <stdio.h>
#include <stdlib.h>

#include "testdriverconfig.h" // SRC and BIN dir definitions
#include "specification.h" // parsing spec files
#include "testuriresolver.h"
#include "testdriver_common.h"

#include "util/properties.h"

#include <zorba/static_context.h>
#include <zorba/util/file.h>

#include <zorbatypes/URI.h>
#include <zorbautils/strutil.h>

#include "zorba_test_setting.h"

#ifndef ZORBA_MINIMAL_STORE
#include <simplestore/simplestore.h>
#include "store/naive/simple_store.h"
#else
#include "store/minimal/min_store.h"
#endif

#include "testdriver_comparator.h"

#define EXPECTED_ERROR  0
#define UNEXPECTED_ERROR  6

std::string rbkt_src_dir = zorba::RBKT_SRC_DIR;
std::string rbkt_bin_dir = zorba::RBKT_BINARY_DIR;
std::string w3c_ts = "w3c_testsuite/";

void loadProperties ()
{
  zorba::Properties::load(0, NULL);
}

int analyzeError (const Specification &lSpec, const TestErrorHandler& errHandler)
{
  if (isErrorExpected(errHandler, &lSpec)) {
    printErrors(errHandler, "The following execution error occurred as expected", false);
    return EXPECTED_ERROR;
  } else {
    printErrors(errHandler, "Unexpected error executing query", false);
    std::cout << "Expected error(s)";
    for (std::vector<std::string>::const_iterator lIter = lSpec.errorsBegin();
         lIter != lSpec.errorsEnd(); ++lIter)
      {
        std::cout << " " << *lIter;
      }
    std::cout << std::endl;
    return UNEXPECTED_ERROR;
  }
}

int
#ifdef _WIN32_WCE
_tmain(int argc, _TCHAR* argv[])
#else
main(int argc, char** argv)
#endif
{
  if ( argc < 2 )
  {
    std::cout << "\nusage:   testdriver [testfile_1] [testfile_2] ..." << std::endl;
    return 1;
  }

  int errors;
  Specification lSpec;

  loadProperties ();

  // Instantiate the store and the zorba query processor
#ifdef ZORBA_MINIMAL_STORE
  zorba::storeminimal::SimpleStore* store =
  zorba::storeminimal::SimpleStore::getInstance();
#else
  zorba::simplestore::SimpleStore* store =
  zorba::simplestore::SimpleStoreManager::getStore();
#endif
  if (store == NULL) return 20;

  zorba::Zorba * engine = zorba::Zorba::getInstance(store);
  if (engine == NULL) return 21;

  int i = 1;
  for (;;) {
    if (strcmp (argv [i], "--rbkt-src") == 0) {
      rbkt_src_dir = argv [i + 1];
      i += 2;
    } else if (strcmp (argv [i], "--rbkt-bin") == 0) {
      rbkt_bin_dir = argv [i + 1];
      i += 2;
    } else break;
  }

  DriverContext driverContext;
  driverContext.theEngine = engine;
  driverContext.theRbktSourceDir = rbkt_src_dir;
  driverContext.theSpec = &lSpec;

  for (int testcnt = 1; i < argc; ++i, ++testcnt)
  {
    std::string Queriesdir = "/Queries/";

    int path_flags = zorba::file::CONVERT_SLASHES | zorba::file::RESOLVE;

    // Form the full pathname for the file containing the query and make sure
    // that the file exists.
    zorba::file lQueryFile (rbkt_src_dir + Queriesdir + argv[i], path_flags);

    if ( (! lQueryFile.exists ()) || lQueryFile.is_directory () )
    {
      std::cout << "\n query file " << lQueryFile.get_path()
                << " does not exist or is not a file" << std::endl;
      return 2;
    }

    // Check if this is w3c_testsuite test.
    std::string path = lQueryFile.get_path();
    bool isW3Ctest = ( path.find ( "w3c_testsuite" ) != std::string::npos );

    // Form the full pathname for the files that will receive the result or the
    // errors of this query. Then, delete these files if they exist already from
    // previous runs of the query. Finaly, create (if necessary) all the dirs
    // in the pathname of the result and error files.
    std::string lQueryWithoutSuffix =
    std::string(argv[i]).substr( 0, std::string(argv[i]).rfind('.') );

    zorba::file lResultFile (rbkt_bin_dir + "/QueryResults/"
                             + lQueryWithoutSuffix + ".xml.res", path_flags);

    zorba::file lErrorFile  (rbkt_bin_dir + "/"
                             + lQueryWithoutSuffix + ".err", path_flags);

    if ( lResultFile.exists () ) { lResultFile.remove (); }
    if ( lErrorFile.exists () )  { lErrorFile.remove ();  }

    zorba::file lBucket (lResultFile.branch_path());
    if ( ! lBucket.exists () )
      lBucket.deep_mkdir (); // create deep directories

    // Form the full pathname for the .spec file that may be associated
    // with this query. If the .spec file exists, read its contents to
    // extract args to be passed to the query (e.g., external var bindings),
    // exprected errors, or the pathnames of reference-result files.
    zorba::file lSpecFile(rbkt_src_dir + "/Queries/" + lQueryWithoutSuffix + ".spec",
                          path_flags);

    if ( lSpecFile.exists ())
      lSpec.parseFile(lSpecFile.get_path());

    // Get the pathnames of the reference-result files found in the .spec
    // file (if any).
    std::vector<zorba::file> lRefFiles;
    bool lRefFileExists = false;
    for (std::vector<std::string>::const_iterator lIter = lSpec.resultsBegin();
         lIter != lSpec.resultsEnd();
         ++lIter)
    {
      std::string lTmp = *lIter;
      zorba::str_replace_all(lTmp, "$RBKT_SRC_DIR", rbkt_src_dir);
      zorba::file lRefFile(lTmp, path_flags);
      if (lRefFile.exists())
      {
        lRefFileExists = true;
      }
      else
      {
        std::cout << "Warning: missing reference result file "
                  << lRefFile.get_path () << std::endl;
      }
      lRefFiles.push_back(lRefFile);
    }

    // If no ref-results file was specified in the .spec file, create a default
    // finename for that file. For w3c tests, the ref file is the same for
    // xqueryx and xquery tests, hence, we remove the string xqueryx or xquery
    // from the path
    if (lRefFiles.size () == 0)
    {
      std::string lRefFileTmpString = lQueryWithoutSuffix;

      if (isW3Ctest)
      {
        if (lQueryWithoutSuffix.find("XQueryX") != std::string::npos)
          lRefFileTmpString = lRefFileTmpString.erase(14, 8);
        else if (lQueryWithoutSuffix.find("XQuery") != std::string::npos)
          lRefFileTmpString = lRefFileTmpString.erase(14, 7);
      }

      lRefFiles.push_back(zorba::file(rbkt_src_dir + "/ExpQueryResults/" +
                                      lRefFileTmpString + ".xml.res"));

      if (lRefFiles [0].exists())
        lRefFileExists = true;
    }

    // print the query
    std::cout << "Query:" << std::endl;
    zorba::printFile(std::cout, lQueryFile.get_path());
    std::cout << std::endl;

    // Create the static context. If this is a w3c query, install special uri
    // resolvers in the static context.
    zorba::StaticContext_t lContext = engine->createStaticContext();

    std::auto_ptr<zorba::TestSchemaURIResolver>      resolver;
    std::auto_ptr<zorba::TestModuleURIResolver>      mresolver;
    std::auto_ptr<zorba::TestCollectionURIResolver>  cresolver;

    if ( isW3Ctest )
    {
      std::string w3cDataDir = "/Queries/w3c_testsuite/TestSources/";
      std::string uri_map_file = rbkt_src_dir + w3cDataDir + "uri.txt";
      std::string mod_map_file = rbkt_src_dir + w3cDataDir + "module.txt";
      std::string col_map_file = rbkt_src_dir + w3cDataDir + "collection.txt";

      resolver.reset(new zorba::TestSchemaURIResolver(uri_map_file.c_str()));

      mresolver.reset(new zorba::TestModuleURIResolver(mod_map_file.c_str(),
                                                       lQueryWithoutSuffix));

      cresolver.reset(new zorba::TestCollectionURIResolver(col_map_file.c_str(),
                                                           rbkt_src_dir));
      lContext->setSchemaURIResolver ( resolver.get() );
      lContext->setModuleURIResolver ( mresolver.get() );
      lContext->setCollectionURIResolver ( cresolver.get() );
    }

    TestErrorHandler errHandler;

    // create and compile the query
    std::string lQueryString;
    slurp_file(lQueryFile.get_path().c_str(), lQueryString, rbkt_src_dir, rbkt_bin_dir);

    zorba::XQuery_t lQuery = engine->createQuery (&errHandler);
    lQuery->setFileName (lQueryFile.get_path ());
    lQuery->compile (lQueryString.c_str(), lContext, getCompilerHints());

    errors = -1;
    if ( errHandler.errors() )
    {
      errors = analyzeError (lSpec, errHandler);
      if( errors == UNEXPECTED_ERROR )
        return 6;
    }
    else // no compilation errors
    {
      // Create dynamic context and set in it the external variables, the current
      // date & time, and the timezone.
      createDynamicContext(driverContext, lContext, lQuery);

      errors = -1;
      {
        { // serialize xml
          std::ofstream lResFileStream(lResultFile.get_path().c_str());
          assert (lResFileStream.good());
          Zorba_SerializerOptions lSerOptions;
          lSerOptions.ser_method = ZORBA_SERIALIZATION_METHOD_XML;
          lSerOptions.omit_xml_declaration = ZORBA_OMIT_XML_DECLARATION_YES;
          lSerOptions.indent = ZORBA_INDENT_NO;

          lQuery->serialize(lResFileStream, &lSerOptions);
        }

        if (lSpec.errorsSize() == 0 && ! lRefFileExists )
        {
          std::cout << "No reference result and no expected errors." << std::endl;
          return 3;
        }

        if (errHandler.errors())
        {
          errors = analyzeError (lSpec, errHandler);
        }
        else if ( lSpec.errorsSize() > 0 )
        {
          if ( ! lRefFileExists )
          {
            std::cout << "Expected error(s)";
            for (std::vector<std::string>::const_iterator lIter = lSpec.errorsBegin();
                lIter != lSpec.errorsEnd(); ++lIter)
            {
              std::cout << " " << *lIter;
            }
            if ( lResultFile.exists () && lResultFile.get_size () == 0)
              std::cout << " but got empty result" << std::endl;
            else {
              std::cout << " but got result:" << std::endl;
              zorba::printFile(std::cout, lResultFile.get_path());
              std::cout << "=== end of result ===" << std::endl;
            }
            return 7;
          }
        }
      }

      if( errors == UNEXPECTED_ERROR)
      {
        return 6;
      }
      else if( errors == -1 )
      {
        std::cout << "Result:" << std::endl;
        zorba::printFile(std::cout, lResultFile.get_path());
        std::cout << "=== end of result ===" << std::endl;
        std::cout.flush();
        size_t i = 1;
        for (std::vector<zorba::file>::const_iterator lIter = lRefFiles.begin();
             lIter != lRefFiles.end(); ++lIter)
        {
          int lLine, lCol, lPos; // where do the files differ
          std::string lRefLine, lResultLine;
          bool lRes = zorba::fileEquals(lIter->c_str(),
                                        lResultFile.c_str(),
                                        lLine, lCol, lPos,
                                        lRefLine, lResultLine);
          if (lRes)
          {
            std::cout << "testdriver: success (non-canonical result # " << i
                      << " matches)" << std::endl;
            return 0;
          }

          std::cout << "testdriver: non-canonical result for reference result # "
                    << i << " doesn't match." << std::endl;

          int lCanonicalRes = zorba::canonicalizeAndCompare(lSpec.getComparisonMethod(),
                                                            lIter->c_str(),
                                                            lResultFile.c_str(),
                                                            rbkt_bin_dir);
          if (lCanonicalRes == 0)
          {
            std::cout << "testdriver: success (canonical result # " << i
                      << " matches)" << std::endl;
            return 0;
          }
          std::cout << "testdriver: canonical result for reference result # " << i
                    << " doesn't match." << std::endl;
          ++i;
        } // for

        std::cout << "testdriver: none of the reference results matched" << std::endl;
        return 8;
      }
    }
  }
  std::cout << "testdriver: success" << std::endl;
  return 0;
}
<commit_msg>Clarified testdriver output<commit_after>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <stdio.h>
#include <stdlib.h>

#include "testdriverconfig.h" // SRC and BIN dir definitions
#include "specification.h" // parsing spec files
#include "testuriresolver.h"
#include "testdriver_common.h"

#include "util/properties.h"

#include <zorba/static_context.h>
#include <zorba/util/file.h>

#include <zorbatypes/URI.h>
#include <zorbautils/strutil.h>

#include "zorba_test_setting.h"

#ifndef ZORBA_MINIMAL_STORE
#include <simplestore/simplestore.h>
#include "store/naive/simple_store.h"
#else
#include "store/minimal/min_store.h"
#endif

#include "testdriver_comparator.h"

#define EXPECTED_ERROR  0
#define UNEXPECTED_ERROR  6

std::string rbkt_src_dir = zorba::RBKT_SRC_DIR;
std::string rbkt_bin_dir = zorba::RBKT_BINARY_DIR;
std::string w3c_ts = "w3c_testsuite/";

void loadProperties ()
{
  zorba::Properties::load(0, NULL);
}

int analyzeError (const Specification &lSpec, const TestErrorHandler& errHandler)
{
  if (isErrorExpected(errHandler, &lSpec)) {
    printErrors(errHandler, "The following execution error occurred as expected", false);
    return EXPECTED_ERROR;
  } else {
    printErrors(errHandler, "Unexpected error executing query", false);
    std::cout << "Expected error(s):";
    for (std::vector<std::string>::const_iterator lIter = lSpec.errorsBegin();
         lIter != lSpec.errorsEnd(); ++lIter)
    {
        std::cout << " " << *lIter;
    }
    if (lSpec.errorsSize () == 0) { std::cout << " (none)"; }
    std::cout << std::endl;
    return UNEXPECTED_ERROR;
  }
}

int
#ifdef _WIN32_WCE
_tmain(int argc, _TCHAR* argv[])
#else
main(int argc, char** argv)
#endif
{
  if ( argc < 2 )
  {
    std::cout << "\nusage:   testdriver [testfile_1] [testfile_2] ..." << std::endl;
    return 1;
  }

  int errors;
  Specification lSpec;

  loadProperties ();

  // Instantiate the store and the zorba query processor
#ifdef ZORBA_MINIMAL_STORE
  zorba::storeminimal::SimpleStore* store =
  zorba::storeminimal::SimpleStore::getInstance();
#else
  zorba::simplestore::SimpleStore* store =
  zorba::simplestore::SimpleStoreManager::getStore();
#endif
  if (store == NULL) return 20;

  zorba::Zorba * engine = zorba::Zorba::getInstance(store);
  if (engine == NULL) return 21;

  int i = 1;
  for (;;) {
    if (strcmp (argv [i], "--rbkt-src") == 0) {
      rbkt_src_dir = argv [i + 1];
      i += 2;
    } else if (strcmp (argv [i], "--rbkt-bin") == 0) {
      rbkt_bin_dir = argv [i + 1];
      i += 2;
    } else break;
  }

  DriverContext driverContext;
  driverContext.theEngine = engine;
  driverContext.theRbktSourceDir = rbkt_src_dir;
  driverContext.theSpec = &lSpec;

  for (int testcnt = 1; i < argc; ++i, ++testcnt)
  {
    std::string Queriesdir = "/Queries/";

    int path_flags = zorba::file::CONVERT_SLASHES | zorba::file::RESOLVE;

    // Form the full pathname for the file containing the query and make sure
    // that the file exists.
    zorba::file lQueryFile (rbkt_src_dir + Queriesdir + argv[i], path_flags);

    if ( (! lQueryFile.exists ()) || lQueryFile.is_directory () )
    {
      std::cout << "\n query file " << lQueryFile.get_path()
                << " does not exist or is not a file" << std::endl;
      return 2;
    }

    // Check if this is w3c_testsuite test.
    std::string path = lQueryFile.get_path();
    bool isW3Ctest = ( path.find ( "w3c_testsuite" ) != std::string::npos );

    // Form the full pathname for the files that will receive the result or the
    // errors of this query. Then, delete these files if they exist already from
    // previous runs of the query. Finaly, create (if necessary) all the dirs
    // in the pathname of the result and error files.
    std::string lQueryWithoutSuffix =
    std::string(argv[i]).substr( 0, std::string(argv[i]).rfind('.') );

    zorba::file lResultFile (rbkt_bin_dir + "/QueryResults/"
                             + lQueryWithoutSuffix + ".xml.res", path_flags);

    zorba::file lErrorFile  (rbkt_bin_dir + "/"
                             + lQueryWithoutSuffix + ".err", path_flags);

    if ( lResultFile.exists () ) { lResultFile.remove (); }
    if ( lErrorFile.exists () )  { lErrorFile.remove ();  }

    zorba::file lBucket (lResultFile.branch_path());
    if ( ! lBucket.exists () )
      lBucket.deep_mkdir (); // create deep directories

    // Form the full pathname for the .spec file that may be associated
    // with this query. If the .spec file exists, read its contents to
    // extract args to be passed to the query (e.g., external var bindings),
    // exprected errors, or the pathnames of reference-result files.
    zorba::file lSpecFile(rbkt_src_dir + "/Queries/" + lQueryWithoutSuffix + ".spec",
                          path_flags);

    if ( lSpecFile.exists ())
      lSpec.parseFile(lSpecFile.get_path());

    // Get the pathnames of the reference-result files found in the .spec
    // file (if any).
    std::vector<zorba::file> lRefFiles;
    bool lRefFileExists = false;
    for (std::vector<std::string>::const_iterator lIter = lSpec.resultsBegin();
         lIter != lSpec.resultsEnd();
         ++lIter)
    {
      std::string lTmp = *lIter;
      zorba::str_replace_all(lTmp, "$RBKT_SRC_DIR", rbkt_src_dir);
      zorba::file lRefFile(lTmp, path_flags);
      if (lRefFile.exists())
      {
        lRefFileExists = true;
      }
      else
      {
        std::cout << "Warning: missing reference result file "
                  << lRefFile.get_path () << std::endl;
      }
      lRefFiles.push_back(lRefFile);
    }

    // If no ref-results file was specified in the .spec file, create a default
    // finename for that file. For w3c tests, the ref file is the same for
    // xqueryx and xquery tests, hence, we remove the string xqueryx or xquery
    // from the path
    if (lRefFiles.size () == 0)
    {
      std::string lRefFileTmpString = lQueryWithoutSuffix;

      if (isW3Ctest)
      {
        if (lQueryWithoutSuffix.find("XQueryX") != std::string::npos)
          lRefFileTmpString = lRefFileTmpString.erase(14, 8);
        else if (lQueryWithoutSuffix.find("XQuery") != std::string::npos)
          lRefFileTmpString = lRefFileTmpString.erase(14, 7);
      }

      lRefFiles.push_back(zorba::file(rbkt_src_dir + "/ExpQueryResults/" +
                                      lRefFileTmpString + ".xml.res"));

      if (lRefFiles [0].exists())
        lRefFileExists = true;
    }

    // print the query
    std::cout << "Query:" << std::endl;
    zorba::printFile(std::cout, lQueryFile.get_path());
    std::cout << std::endl;

    // Create the static context. If this is a w3c query, install special uri
    // resolvers in the static context.
    zorba::StaticContext_t lContext = engine->createStaticContext();

    std::auto_ptr<zorba::TestSchemaURIResolver>      resolver;
    std::auto_ptr<zorba::TestModuleURIResolver>      mresolver;
    std::auto_ptr<zorba::TestCollectionURIResolver>  cresolver;

    if ( isW3Ctest )
    {
      std::string w3cDataDir = "/Queries/w3c_testsuite/TestSources/";
      std::string uri_map_file = rbkt_src_dir + w3cDataDir + "uri.txt";
      std::string mod_map_file = rbkt_src_dir + w3cDataDir + "module.txt";
      std::string col_map_file = rbkt_src_dir + w3cDataDir + "collection.txt";

      resolver.reset(new zorba::TestSchemaURIResolver(uri_map_file.c_str()));

      mresolver.reset(new zorba::TestModuleURIResolver(mod_map_file.c_str(),
                                                       lQueryWithoutSuffix));

      cresolver.reset(new zorba::TestCollectionURIResolver(col_map_file.c_str(),
                                                           rbkt_src_dir));
      lContext->setSchemaURIResolver ( resolver.get() );
      lContext->setModuleURIResolver ( mresolver.get() );
      lContext->setCollectionURIResolver ( cresolver.get() );
    }

    TestErrorHandler errHandler;

    // create and compile the query
    std::string lQueryString;
    slurp_file(lQueryFile.get_path().c_str(), lQueryString, rbkt_src_dir, rbkt_bin_dir);

    zorba::XQuery_t lQuery = engine->createQuery (&errHandler);
    lQuery->setFileName (lQueryFile.get_path ());
    lQuery->compile (lQueryString.c_str(), lContext, getCompilerHints());

    errors = -1;
    if ( errHandler.errors() )
    {
      errors = analyzeError (lSpec, errHandler);
      if( errors == UNEXPECTED_ERROR )
        return 6;
    }
    else // no compilation errors
    {
      // Create dynamic context and set in it the external variables, the current
      // date & time, and the timezone.
      createDynamicContext(driverContext, lContext, lQuery);

      errors = -1;
      {
        { // serialize xml
          std::ofstream lResFileStream(lResultFile.get_path().c_str());
          assert (lResFileStream.good());
          Zorba_SerializerOptions lSerOptions;
          lSerOptions.ser_method = ZORBA_SERIALIZATION_METHOD_XML;
          lSerOptions.omit_xml_declaration = ZORBA_OMIT_XML_DECLARATION_YES;
          lSerOptions.indent = ZORBA_INDENT_NO;

          lQuery->serialize(lResFileStream, &lSerOptions);
        }

        if (lSpec.errorsSize() == 0 && ! lRefFileExists )
        {
          std::cout << "No reference result and no expected errors." << std::endl;
          return 3;
        }

        if (errHandler.errors())
        {
          errors = analyzeError (lSpec, errHandler);
        }
        else if ( lSpec.errorsSize() > 0 )
        {
          if ( ! lRefFileExists )
          {
            std::cout << "Expected error(s)";
            for (std::vector<std::string>::const_iterator lIter = lSpec.errorsBegin();
                lIter != lSpec.errorsEnd(); ++lIter)
            {
              std::cout << " " << *lIter;
            }
            if ( lResultFile.exists () && lResultFile.get_size () == 0)
              std::cout << " but got empty result" << std::endl;
            else {
              std::cout << " but got result:" << std::endl;
              zorba::printFile(std::cout, lResultFile.get_path());
              std::cout << "=== end of result ===" << std::endl;
            }
            return 7;
          }
        }
      }

      if( errors == UNEXPECTED_ERROR)
      {
        return 6;
      }
      else if( errors == -1 )
      {
        std::cout << "Result:" << std::endl;
        zorba::printFile(std::cout, lResultFile.get_path());
        std::cout << "=== end of result ===" << std::endl;
        std::cout.flush();
        size_t i = 1;
        for (std::vector<zorba::file>::const_iterator lIter = lRefFiles.begin();
             lIter != lRefFiles.end(); ++lIter)
        {
          int lLine, lCol, lPos; // where do the files differ
          std::string lRefLine, lResultLine;
          bool lRes = zorba::fileEquals(lIter->c_str(),
                                        lResultFile.c_str(),
                                        lLine, lCol, lPos,
                                        lRefLine, lResultLine);
          if (lRes)
          {
            std::cout << "testdriver: success (non-canonical result # " << i
                      << " matches)" << std::endl;
            return 0;
          }

          std::cout << "testdriver: non-canonical result for reference result # "
                    << i << " doesn't match." << std::endl;

          int lCanonicalRes = zorba::canonicalizeAndCompare(lSpec.getComparisonMethod(),
                                                            lIter->c_str(),
                                                            lResultFile.c_str(),
                                                            rbkt_bin_dir);
          if (lCanonicalRes == 0)
          {
            std::cout << "testdriver: success (canonical result # " << i
                      << " matches)" << std::endl;
            return 0;
          }
          std::cout << "testdriver: canonical result for reference result # " << i
                    << " doesn't match." << std::endl;
          ++i;
        } // for

        std::cout << "testdriver: none of the reference results matched" << std::endl;
        return 8;
      }
    }
  }
  std::cout << "testdriver: success" << std::endl;
  return 0;
}
<|endoftext|>


<commit_before>#include "dl32TestConfig.h"

#if DL32TESTS_CURRENTTEST == DL32TEST_REFACTORING_TYPINGTEST

#include "dl32Typing.h"
#include <iostream>
#include <typeinfo>
#include <string>

using namespace std;

int main()
{
    typedef dl32TypeList<char , int , float , double> myList;

    /* TypeList indexing test */

    //Checks if the type at index 2 is a float:
    if(dl32TypeChecking<float,myList::type_at<2>>::same_type)
        cout << "ok!" << endl;
    else
        cout << "mmm... Cascao raro" << endl;

    /* Inheritance checking test */

    class Foo{};
    class FooChild : public Foo {};

    if(dl32TypeChecking<Foo,FooChild>::superclass_subclass)
        cout << "ok!" << endl;
    else
        cout << "mmm... Cascao raro" << endl;

    /* Type traits checking test */

    cout << std::boolalpha;
    cout << (bool) dl32TypeTraits<int>::hasConst << endl;
    cout << (bool) dl32TypeTraits<int*>::isPointer << endl;
    cout << (bool) dl32TypeTraits<int&>::isReference << endl;
    cout << (bool) dl32TypeTraits<int&>::isRvalue << endl;

    /* end */

    cin.sync();
    cin.get();
}

#endif<commit_msg>Loki: Fixed merge conflict (Im an idiot and i forget that i had pushed a commit yesterday in another PC...)<commit_after>#include "dl32TestConfig.h"

#if DL32TESTS_CURRENTTEST == DL32TEST_REFACTORING_TYPINGTEST

#include "dl32Typing.h"
#include <iostream>
#include <typeinfo>
#include <string>

using namespace std;

int main()
{
    typedef dl32TypeList<char , int , float , double> myList;

    /* TypeList indexing test */

    if(dl32TypeChecking<float,myList::type_at<2>>::same_type)
        cout << "ok!" << endl;
    else
        cout << "mmm... Cascao raro" << endl;

    /* Inheritance checking test */

    class Foo{};
    class FooChild : public Foo {};

    if(dl32TypeChecking<Foo,FooChild>::superclass_subclass)
        cout << "ok!" << endl;
    else
        cout << "mmm... Cascao raro" << endl;

    /* Type traits checking test */

    cout << std::boolalpha;
    cout << (bool) dl32TypeTraits<int>::hasConst << endl;
    cout << (bool) dl32TypeTraits<int*>::isPointer << endl;
    cout << (bool) dl32TypeTraits<int&>::isReference << endl;
    cout << (bool) dl32TypeTraits<int&>::isRvalue << endl;

    /* end */

    cin.sync();
    cin.get();
}

#endif<|endoftext|>


<commit_before>#include "species_loader.hpp"
#include "species_loader_struct.hpp"
#include "obj_loader.hpp"
#include "fbx_species_loader.hpp"
#include "ascii_grid_loader.hpp"
#include "bmp_heightmap_loader.hpp"
#include "srtm_heightmap_loader.hpp"
#include "heightmap_loader_struct.hpp"
#include "code/ylikuutio/opengl/vboindexer.hpp"

// Include GLEW
#ifndef __GL_GLEW_H_INCLUDED
#define __GL_GLEW_H_INCLUDED
#include <GL/glew.h> // GLfloat, GLuint etc.
#endif

// Include GLM
#ifndef __GLM_GLM_HPP_INCLUDED
#define __GLM_GLM_HPP_INCLUDED
#include <glm/glm.hpp> // glm
#endif

// Include standard headers
#include <iostream> // std::cout, std::cin, std::cerr
#include <string>   // std::string
#include <vector>   // std::vector

namespace yli
{
    namespace load
    {
        bool load_species(
                const SpeciesLoaderStruct& species_loader_struct,
                std::vector<glm::vec3>& out_vertices,
                std::vector<glm::vec2>& out_UVs,
                std::vector<glm::vec3>& out_normals,
                std::vector<GLuint>& indices,
                std::vector<glm::vec3>& indexed_vertices,
                std::vector<glm::vec2>& indexed_UVs,
                std::vector<glm::vec3>& indexed_normals,
                GLuint* vertexbuffer,
                GLuint* uvbuffer,
                GLuint* normalbuffer,
                GLuint* elementbuffer,
                bool& vram_buffer_in_use,
                const bool is_debug_mode)
        {
            bool model_loading_result = false;
            bool needs_indexing = true;

            if (species_loader_struct.model_file_format == "obj" || species_loader_struct.model_file_format == "OBJ")
            {
                model_loading_result = yli::load::load_OBJ(
                        species_loader_struct.model_filename.c_str(),
                        out_vertices,
                        out_UVs,
                        out_normals);
            }
            else if (species_loader_struct.model_file_format == "fbx" || species_loader_struct.model_file_format == "FBX")
            {
                model_loading_result = yli::load::load_FBX(
                        species_loader_struct.model_filename,
                        species_loader_struct.mesh_i,
                        out_vertices,
                        out_UVs,
                        out_normals,
                        is_debug_mode);

                std::cout << species_loader_struct.model_filename << " loaded successfully.\n";
            }
            else if (species_loader_struct.model_file_format == "srtm" || species_loader_struct.model_file_format == "SRTM")
            {
                HeightmapLoaderStruct heightmap_loader_struct;
                heightmap_loader_struct.latitude = species_loader_struct.latitude;
                heightmap_loader_struct.longitude = species_loader_struct.longitude;
                heightmap_loader_struct.planet_radius = species_loader_struct.planet_radius;
                heightmap_loader_struct.divisor = species_loader_struct.divisor;

                model_loading_result = yli::load::load_SRTM_terrain(
                        heightmap_loader_struct,
                        species_loader_struct.model_filename,
                        out_vertices,
                        out_UVs,
                        out_normals,
                        *species_loader_struct.image_width_pointer,
                        *species_loader_struct.image_height_pointer,
                        species_loader_struct.x_step,
                        species_loader_struct.z_step,
                        species_loader_struct.triangulation_type,
                        species_loader_struct.should_ylikuutio_use_real_texture_coordinates);
            }
            else if (species_loader_struct.model_file_format == "bmp" || species_loader_struct.model_file_format == "BMP")
            {
                model_loading_result = yli::load::load_BMP_terrain(
                        species_loader_struct.model_filename,
                        out_vertices,
                        out_UVs,
                        out_normals,
                        *species_loader_struct.image_width_pointer,
                        *species_loader_struct.image_height_pointer,
                        species_loader_struct.color_channel,
                        species_loader_struct.x_step,
                        species_loader_struct.z_step,
                        species_loader_struct.triangulation_type,
                        species_loader_struct.should_ylikuutio_use_real_texture_coordinates);
            }
            else if (species_loader_struct.model_file_format == "ascii_grid" || species_loader_struct.model_file_format == "ASCII_grid")
            {
                model_loading_result = yli::load::load_ASCII_grid(
                        species_loader_struct.model_filename,
                        out_vertices,
                        out_UVs,
                        out_normals,
                        *species_loader_struct.image_width_pointer,
                        *species_loader_struct.image_height_pointer,
                        species_loader_struct.x_step,
                        species_loader_struct.z_step,
                        species_loader_struct.triangulation_type,
                        species_loader_struct.should_ylikuutio_use_real_texture_coordinates);
            }
            else
            {
                std::cerr << "ERROR: no model was loaded!\n";
                std::cerr << "Model file format: " << species_loader_struct.model_file_format << "\n";
                return false;
            }

            std::cout << "Indexing...\n";

            if (needs_indexing)
            {
                // Fill the index buffer.
                yli::opengl::indexVBO(
                        out_vertices,
                        out_UVs,
                        out_normals,
                        indices,
                        indexed_vertices,
                        indexed_UVs,
                        indexed_normals);

                std::cout << "Indexing completed successfully.\n";
            }
            else
            {
                indices.resize(out_vertices.size());

                for (GLuint i = 0; i < out_vertices.size(); i++)
                {
                    indices[i] = i;
                }

                indexed_vertices = out_vertices;
                indexed_UVs = out_UVs;
                indexed_normals = out_normals;
            }

            vram_buffer_in_use = species_loader_struct.vram_buffer_in_use;

            if (vram_buffer_in_use)
            {
                // Load it into a VBO.
                glGenBuffers(1, vertexbuffer);
                glBindBuffer(GL_ARRAY_BUFFER, *vertexbuffer);
                glBufferData(GL_ARRAY_BUFFER, indexed_vertices.size() * sizeof(glm::vec3), &indexed_vertices[0], GL_STATIC_DRAW);

                glGenBuffers(1, uvbuffer);
                glBindBuffer(GL_ARRAY_BUFFER, *uvbuffer);
                glBufferData(GL_ARRAY_BUFFER, indexed_UVs.size() * sizeof(glm::vec2), &indexed_UVs[0], GL_STATIC_DRAW);

                glGenBuffers(1, normalbuffer);
                glBindBuffer(GL_ARRAY_BUFFER, *normalbuffer);
                glBufferData(GL_ARRAY_BUFFER, indexed_normals.size() * sizeof(glm::vec3), &indexed_normals[0], GL_STATIC_DRAW);

                glGenBuffers(1, elementbuffer);
                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *elementbuffer);
                glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), &indices[0] , GL_STATIC_DRAW);
            }

            // TODO: Compute the graph of this object type to enable object vertex modification!
            return model_loading_result;
        }
    }
}
<commit_msg>Removed obsolete code.<commit_after>#include "species_loader.hpp"
#include "species_loader_struct.hpp"
#include "obj_loader.hpp"
#include "fbx_species_loader.hpp"
#include "ascii_grid_loader.hpp"
#include "bmp_heightmap_loader.hpp"
#include "srtm_heightmap_loader.hpp"
#include "heightmap_loader_struct.hpp"
#include "code/ylikuutio/opengl/vboindexer.hpp"

// Include GLEW
#ifndef __GL_GLEW_H_INCLUDED
#define __GL_GLEW_H_INCLUDED
#include <GL/glew.h> // GLfloat, GLuint etc.
#endif

// Include GLM
#ifndef __GLM_GLM_HPP_INCLUDED
#define __GLM_GLM_HPP_INCLUDED
#include <glm/glm.hpp> // glm
#endif

// Include standard headers
#include <iostream> // std::cout, std::cin, std::cerr
#include <string>   // std::string
#include <vector>   // std::vector

namespace yli
{
    namespace load
    {
        bool load_species(
                const SpeciesLoaderStruct& species_loader_struct,
                std::vector<glm::vec3>& out_vertices,
                std::vector<glm::vec2>& out_UVs,
                std::vector<glm::vec3>& out_normals,
                std::vector<GLuint>& indices,
                std::vector<glm::vec3>& indexed_vertices,
                std::vector<glm::vec2>& indexed_UVs,
                std::vector<glm::vec3>& indexed_normals,
                GLuint* vertexbuffer,
                GLuint* uvbuffer,
                GLuint* normalbuffer,
                GLuint* elementbuffer,
                bool& vram_buffer_in_use,
                const bool is_debug_mode)
        {
            bool model_loading_result = false;

            if (species_loader_struct.model_file_format == "obj" || species_loader_struct.model_file_format == "OBJ")
            {
                model_loading_result = yli::load::load_OBJ(
                        species_loader_struct.model_filename.c_str(),
                        out_vertices,
                        out_UVs,
                        out_normals);
            }
            else if (species_loader_struct.model_file_format == "fbx" || species_loader_struct.model_file_format == "FBX")
            {
                model_loading_result = yli::load::load_FBX(
                        species_loader_struct.model_filename,
                        species_loader_struct.mesh_i,
                        out_vertices,
                        out_UVs,
                        out_normals,
                        is_debug_mode);

                std::cout << species_loader_struct.model_filename << " loaded successfully.\n";
            }
            else if (species_loader_struct.model_file_format == "srtm" || species_loader_struct.model_file_format == "SRTM")
            {
                HeightmapLoaderStruct heightmap_loader_struct;
                heightmap_loader_struct.latitude = species_loader_struct.latitude;
                heightmap_loader_struct.longitude = species_loader_struct.longitude;
                heightmap_loader_struct.planet_radius = species_loader_struct.planet_radius;
                heightmap_loader_struct.divisor = species_loader_struct.divisor;

                model_loading_result = yli::load::load_SRTM_terrain(
                        heightmap_loader_struct,
                        species_loader_struct.model_filename,
                        out_vertices,
                        out_UVs,
                        out_normals,
                        *species_loader_struct.image_width_pointer,
                        *species_loader_struct.image_height_pointer,
                        species_loader_struct.x_step,
                        species_loader_struct.z_step,
                        species_loader_struct.triangulation_type,
                        species_loader_struct.should_ylikuutio_use_real_texture_coordinates);
            }
            else if (species_loader_struct.model_file_format == "bmp" || species_loader_struct.model_file_format == "BMP")
            {
                model_loading_result = yli::load::load_BMP_terrain(
                        species_loader_struct.model_filename,
                        out_vertices,
                        out_UVs,
                        out_normals,
                        *species_loader_struct.image_width_pointer,
                        *species_loader_struct.image_height_pointer,
                        species_loader_struct.color_channel,
                        species_loader_struct.x_step,
                        species_loader_struct.z_step,
                        species_loader_struct.triangulation_type,
                        species_loader_struct.should_ylikuutio_use_real_texture_coordinates);
            }
            else if (species_loader_struct.model_file_format == "ascii_grid" || species_loader_struct.model_file_format == "ASCII_grid")
            {
                model_loading_result = yli::load::load_ASCII_grid(
                        species_loader_struct.model_filename,
                        out_vertices,
                        out_UVs,
                        out_normals,
                        *species_loader_struct.image_width_pointer,
                        *species_loader_struct.image_height_pointer,
                        species_loader_struct.x_step,
                        species_loader_struct.z_step,
                        species_loader_struct.triangulation_type,
                        species_loader_struct.should_ylikuutio_use_real_texture_coordinates);
            }
            else
            {
                std::cerr << "ERROR: no model was loaded!\n";
                std::cerr << "Model file format: " << species_loader_struct.model_file_format << "\n";
                return false;
            }

            std::cout << "Indexing...\n";

            // Fill the index buffer.
            yli::opengl::indexVBO(
                    out_vertices,
                    out_UVs,
                    out_normals,
                    indices,
                    indexed_vertices,
                    indexed_UVs,
                    indexed_normals);

            std::cout << "Indexing completed successfully.\n";

            vram_buffer_in_use = species_loader_struct.vram_buffer_in_use;

            if (vram_buffer_in_use)
            {
                // Load it into a VBO.
                glGenBuffers(1, vertexbuffer);
                glBindBuffer(GL_ARRAY_BUFFER, *vertexbuffer);
                glBufferData(GL_ARRAY_BUFFER, indexed_vertices.size() * sizeof(glm::vec3), &indexed_vertices[0], GL_STATIC_DRAW);

                glGenBuffers(1, uvbuffer);
                glBindBuffer(GL_ARRAY_BUFFER, *uvbuffer);
                glBufferData(GL_ARRAY_BUFFER, indexed_UVs.size() * sizeof(glm::vec2), &indexed_UVs[0], GL_STATIC_DRAW);

                glGenBuffers(1, normalbuffer);
                glBindBuffer(GL_ARRAY_BUFFER, *normalbuffer);
                glBufferData(GL_ARRAY_BUFFER, indexed_normals.size() * sizeof(glm::vec3), &indexed_normals[0], GL_STATIC_DRAW);

                glGenBuffers(1, elementbuffer);
                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *elementbuffer);
                glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), &indices[0] , GL_STATIC_DRAW);
            }

            // TODO: Compute the graph of this object type to enable object vertex modification!
            return model_loading_result;
        }
    }
}
<|endoftext|>


<commit_before>#include "test.hh"

#include <controller.hh>
#include "mock-ptrace.hh"

static int test_thread(void *priv)
{
	return 0;
}

TEST(controllerForkError)
{
	IController &controller = IController::getInstance();
	MockPtrace &ptrace = (MockPtrace &)IPtrace::getInstance();

	EXPECT_CALL(ptrace, forkAndAttach())
		.Times(AtLeast(1))
		.WillRepeatedly(Return(-1));

	controller.run();
}

TEST(controllerAddProcessForkError)
{
	IController &controller = IController::getInstance();
	MockPtrace &ptrace = (MockPtrace &)IPtrace::getInstance();

	EXPECT_CALL(ptrace, forkAndAttach())
		.Times(AtLeast(1))
		.WillRepeatedly(Return(-1));

	controller.addThread(test_thread, NULL);
	controller.run();
}

TEST(controllerRunChild)
{
	IController &controller = IController::getInstance();
	MockPtrace &ptrace = (MockPtrace &)IPtrace::getInstance();

	EXPECT_CALL(ptrace, forkAndAttach())
		.Times(AtLeast(1))
		.WillRepeatedly(Return(100));

	IPtrace::PtraceEvent ev, evDefault;

	evDefault.type = ptrace_exit;
	evDefault.eventId = 0;

	ev.type = ptrace_breakpoint;
	ev.eventId = 100;
	ev.addr = NULL;

	EXPECT_CALL(ptrace, continueExecution(_))
		.Times(AtLeast(1))
		.WillOnce(Return(ev))
		.WillRepeatedly(Return(evDefault));

	// Add two threads
	controller.addThread(test_thread, NULL);
	controller.addThread(test_thread, NULL);

	controller.run();
}
<commit_msg>unit test: Set expectations on ptrace::SingleStep<commit_after>#include "test.hh"

#include <controller.hh>
#include "mock-ptrace.hh"

static int test_thread(void *priv)
{
	return 0;
}

TEST(controllerForkError)
{
	IController &controller = IController::getInstance();
	MockPtrace &ptrace = (MockPtrace &)IPtrace::getInstance();

	EXPECT_CALL(ptrace, forkAndAttach())
		.Times(AtLeast(1))
		.WillRepeatedly(Return(-1));

	controller.run();
}

TEST(controllerAddProcessForkError)
{
	IController &controller = IController::getInstance();
	MockPtrace &ptrace = (MockPtrace &)IPtrace::getInstance();

	EXPECT_CALL(ptrace, forkAndAttach())
		.Times(AtLeast(1))
		.WillRepeatedly(Return(-1));

	controller.addThread(test_thread, NULL);
	controller.run();
}

TEST(controllerRunChild)
{
	IController &controller = IController::getInstance();
	MockPtrace &ptrace = (MockPtrace &)IPtrace::getInstance();

	EXPECT_CALL(ptrace, forkAndAttach())
		.Times(AtLeast(1))
		.WillRepeatedly(Return(100));

	IPtrace::PtraceEvent ev, evDefault;

	evDefault.type = ptrace_exit;
	evDefault.eventId = 0;

	ev.type = ptrace_breakpoint;
	ev.eventId = 100;
	ev.addr = NULL;

	EXPECT_CALL(ptrace, continueExecution(_))
		.Times(AtLeast(1))
		.WillOnce(Return(ev))
		.WillRepeatedly(Return(evDefault));

	EXPECT_CALL(ptrace, singleStep(_))
		.Times(AtLeast(1));

	// Add two threads
	controller.addThread(test_thread, NULL);
	controller.addThread(test_thread, NULL);

	controller.run();
}
<|endoftext|>


<commit_before>// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s

// This test is flaky on Darwin, once in a while it fails with EXC_I386_GPFLT.
// UNSUPPORTED: darwin

#include "test.h"
#include <errno.h>
#include <sys/mman.h>

void *SubWorker(void *arg) {
  (void)arg;
  const int kMmapSize =  65536;
  for (int i = 0; i < 500; i++) {
    int *ptr = (int*)mmap(0, kMmapSize, PROT_READ | PROT_WRITE,
                          MAP_PRIVATE | MAP_ANON, -1, 0);
    if (ptr == MAP_FAILED)
      exit(printf("mmap failed: %d\n", errno));
    *ptr = 42;
    if (munmap(ptr, kMmapSize))
      exit(printf("munmap failed: %d\n", errno));
  }
  return 0;
}

void *Worker1(void *arg) {
  (void)arg;
  pthread_t th[4];
  for (int i = 0; i < 4; i++) {
    if (pthread_create(&th[i], 0, SubWorker, 0))
      exit(printf("pthread_create failed: %d\n", errno));
  }
  for (int i = 0; i < 4; i++) {
    if (pthread_join(th[i], 0))
      exit(printf("pthread_join failed: %d\n", errno));
  }
  return 0;
}

void *Worker(void *arg) {
  (void)arg;
  pthread_t th[4];
  for (int i = 0; i < 4; i++) {
    if (pthread_create(&th[i], 0, Worker1, 0))
      exit(printf("pthread_create failed: %d\n", errno));
  }
  for (int i = 0; i < 4; i++) {
    if (pthread_join(th[i], 0))
      exit(printf("pthread_join failed: %d\n", errno));
  }
  return 0;
}

int main() {
  pthread_t th[4];
  for (int i = 0; i < 4; i++) {
    if (pthread_create(&th[i], 0, Worker, 0))
      exit(printf("pthread_create failed: %d\n", errno));
  }
  for (int i = 0; i < 4; i++) {
    if (pthread_join(th[i], 0))
      exit(printf("pthread_join failed: %d\n", errno));
  }
  fprintf(stderr, "DONE\n");
}

// CHECK: DONE
<commit_msg>Reverting r259529 (Marking the mmap_stress.cc TSan test as unsupported on OS X)<commit_after>// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
#include "test.h"
#include <errno.h>
#include <sys/mman.h>

void *SubWorker(void *arg) {
  (void)arg;
  const int kMmapSize =  65536;
  for (int i = 0; i < 500; i++) {
    int *ptr = (int*)mmap(0, kMmapSize, PROT_READ | PROT_WRITE,
                          MAP_PRIVATE | MAP_ANON, -1, 0);
    if (ptr == MAP_FAILED)
      exit(printf("mmap failed: %d\n", errno));
    *ptr = 42;
    if (munmap(ptr, kMmapSize))
      exit(printf("munmap failed: %d\n", errno));
  }
  return 0;
}

void *Worker1(void *arg) {
  (void)arg;
  pthread_t th[4];
  for (int i = 0; i < 4; i++) {
    if (pthread_create(&th[i], 0, SubWorker, 0))
      exit(printf("pthread_create failed: %d\n", errno));
  }
  for (int i = 0; i < 4; i++) {
    if (pthread_join(th[i], 0))
      exit(printf("pthread_join failed: %d\n", errno));
  }
  return 0;
}

void *Worker(void *arg) {
  (void)arg;
  pthread_t th[4];
  for (int i = 0; i < 4; i++) {
    if (pthread_create(&th[i], 0, Worker1, 0))
      exit(printf("pthread_create failed: %d\n", errno));
  }
  for (int i = 0; i < 4; i++) {
    if (pthread_join(th[i], 0))
      exit(printf("pthread_join failed: %d\n", errno));
  }
  return 0;
}

int main() {
  pthread_t th[4];
  for (int i = 0; i < 4; i++) {
    if (pthread_create(&th[i], 0, Worker, 0))
      exit(printf("pthread_create failed: %d\n", errno));
  }
  for (int i = 0; i < 4; i++) {
    if (pthread_join(th[i], 0))
      exit(printf("pthread_join failed: %d\n", errno));
  }
  fprintf(stderr, "DONE\n");
}

// CHECK: DONE
<|endoftext|>


<commit_before>/*
 *
 * Copyright 2015, Google Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <node.h>

#include "grpc/grpc.h"
#include "grpc/grpc_security.h"
#include "grpc/support/log.h"
#include "call_credentials.h"
#include "call.h"

namespace grpc {
namespace node {

using Nan::Callback;
using Nan::EscapableHandleScope;
using Nan::HandleScope;
using Nan::Maybe;
using Nan::MaybeLocal;
using Nan::ObjectWrap;
using Nan::Persistent;
using Nan::Utf8String;

using v8::Exception;
using v8::External;
using v8::Function;
using v8::FunctionTemplate;
using v8::Integer;
using v8::Local;
using v8::Object;
using v8::ObjectTemplate;
using v8::Value;

Nan::Callback *CallCredentials::constructor;
Persistent<FunctionTemplate> CallCredentials::fun_tpl;

CallCredentials::CallCredentials(grpc_call_credentials *credentials)
    : wrapped_credentials(credentials) {}

CallCredentials::~CallCredentials() {
  grpc_call_credentials_release(wrapped_credentials);
}

void CallCredentials::Init(Local<Object> exports) {
  HandleScope scope;
  Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
  tpl->SetClassName(Nan::New("CallCredentials").ToLocalChecked());
  tpl->InstanceTemplate()->SetInternalFieldCount(1);
  Nan::SetPrototypeMethod(tpl, "compose", Compose);
  fun_tpl.Reset(tpl);
  Local<Function> ctr = Nan::GetFunction(tpl).ToLocalChecked();
  Nan::Set(ctr, Nan::New("createFromPlugin").ToLocalChecked(),
           Nan::GetFunction(
               Nan::New<FunctionTemplate>(CreateFromPlugin)).ToLocalChecked());
  Nan::Set(exports, Nan::New("CallCredentials").ToLocalChecked(), ctr);
  constructor = new Nan::Callback(ctr);
}

bool CallCredentials::HasInstance(Local<Value> val) {
  HandleScope scope;
  return Nan::New(fun_tpl)->HasInstance(val);
}

Local<Value> CallCredentials::WrapStruct(grpc_call_credentials *credentials) {
  EscapableHandleScope scope;
  const int argc = 1;
  if (credentials == NULL) {
    return scope.Escape(Nan::Null());
  }
  Local<Value> argv[argc] = {
    Nan::New<External>(reinterpret_cast<void *>(credentials))};
  MaybeLocal<Object> maybe_instance = Nan::NewInstance(
      constructor->GetFunction(), argc, argv);
  if (maybe_instance.IsEmpty()) {
    return scope.Escape(Nan::Null());
  } else {
    return scope.Escape(maybe_instance.ToLocalChecked());
  }
}

grpc_call_credentials *CallCredentials::GetWrappedCredentials() {
  return wrapped_credentials;
}

NAN_METHOD(CallCredentials::New) {
  if (info.IsConstructCall()) {
    if (!info[0]->IsExternal()) {
      return Nan::ThrowTypeError(
          "CallCredentials can only be created with the provided functions");
    }
    Local<External> ext = info[0].As<External>();
    grpc_call_credentials *creds_value =
        reinterpret_cast<grpc_call_credentials *>(ext->Value());
    CallCredentials *credentials = new CallCredentials(creds_value);
    credentials->Wrap(info.This());
    info.GetReturnValue().Set(info.This());
    return;
  } else {
    // This should never be called directly
    return Nan::ThrowTypeError(
        "CallCredentials can only be created with the provided functions");
  }
}

NAN_METHOD(CallCredentials::Compose) {
  if (!CallCredentials::HasInstance(info.This())) {
    return Nan::ThrowTypeError(
        "compose can only be called on CallCredentials objects");
  }
  if (!CallCredentials::HasInstance(info[0])) {
    return Nan::ThrowTypeError(
        "compose's first argument must be a CallCredentials object");
  }
  CallCredentials *self = ObjectWrap::Unwrap<CallCredentials>(info.This());
  CallCredentials *other = ObjectWrap::Unwrap<CallCredentials>(
      Nan::To<Object>(info[0]).ToLocalChecked());
  grpc_call_credentials *creds = grpc_composite_call_credentials_create(
      self->wrapped_credentials, other->wrapped_credentials, NULL);
  info.GetReturnValue().Set(WrapStruct(creds));
}

NAN_METHOD(CallCredentials::CreateFromPlugin) {
  if (!info[0]->IsFunction()) {
    return Nan::ThrowTypeError(
        "createFromPlugin's argument must be a function");
  }
  grpc_metadata_credentials_plugin plugin;
  plugin_state *state = new plugin_state;
  state->callback = new Nan::Callback(info[0].As<Function>());
  plugin.get_metadata = plugin_get_metadata;
  plugin.destroy = plugin_destroy_state;
  plugin.state = reinterpret_cast<void*>(state);
  grpc_call_credentials *creds = grpc_metadata_credentials_create_from_plugin(
      plugin, NULL);
  info.GetReturnValue().Set(WrapStruct(creds));
}

NAN_METHOD(PluginCallback) {
  // Arguments: status code, error details, metadata
  if (!info[0]->IsUint32()) {
    return Nan::ThrowTypeError(
        "The callback's first argument must be a status code");
  }
  if (!info[1]->IsString()) {
    return Nan::ThrowTypeError(
        "The callback's second argument must be a string");
  }
  if (!info[2]->IsObject()) {
    return Nan::ThrowTypeError(
        "The callback's third argument must be an object");
  }
  shared_ptr<Resources> resources(new Resources);
  grpc_status_code code = static_cast<grpc_status_code>(
      Nan::To<uint32_t>(info[0]).FromJust());
  char *details = *Utf8String(info[1]);
  grpc_metadata_array array;
  if (!CreateMetadataArray(Nan::To<Object>(info[2]).ToLocalChecked(),
                           &array, resources)){
    return Nan::ThrowError("Failed to parse metadata");
  }
  grpc_credentials_plugin_metadata_cb cb =
      reinterpret_cast<grpc_credentials_plugin_metadata_cb>(
          Nan::Get(info.Callee(),
                   Nan::New("cb").ToLocalChecked()
                   ).ToLocalChecked().As<External>()->Value());
  void *user_data =
      Nan::Get(info.Callee(),
               Nan::New("user_data").ToLocalChecked()
               ).ToLocalChecked().As<External>()->Value();
  cb(user_data, array.metadata, array.count, code, details);
}

NAUV_WORK_CB(SendPluginCallback) {
  Nan::HandleScope scope;
  plugin_callback_data *data = reinterpret_cast<plugin_callback_data*>(
      async->data);
  // Attach cb and user_data to plugin_callback so that it can access them later
  v8::Local<v8::Function> plugin_callback = Nan::GetFunction(
      Nan::New<v8::FunctionTemplate>(PluginCallback)).ToLocalChecked();
  Nan::Set(plugin_callback, Nan::New("cb").ToLocalChecked(),
           Nan::New<v8::External>(reinterpret_cast<void*>(data->cb)));
  Nan::Set(plugin_callback, Nan::New("user_data").ToLocalChecked(),
           Nan::New<v8::External>(data->user_data));
  const int argc = 2;
  v8::Local<v8::Value> argv[argc] = {
    Nan::New(data->service_url).ToLocalChecked(),
    plugin_callback
  };
  Nan::Callback *callback = data->state->callback;
  callback->Call(argc, argv);
  delete data;
  uv_unref((uv_handle_t *)async);
  uv_close((uv_handle_t *)async, (uv_close_cb)free);
}

void plugin_get_metadata(void *state, const char *service_url,
                         grpc_credentials_plugin_metadata_cb cb,
                         void *user_data) {
  uv_async_t *async = static_cast<uv_async_t*>(malloc(sizeof(uv_async_t)));
  uv_async_init(uv_default_loop(),
                async,
                SendPluginCallback);
  plugin_callback_data *data = new plugin_callback_data;
  data->state = reinterpret_cast<plugin_state*>(state);
  data->service_url = service_url;
  data->cb = cb;
  data->user_data = user_data;
  async->data = data;
  /* libuv says that it will coalesce calls to uv_async_send. If there is ever a
   * problem with a callback not getting called, that is probably the reason */
  uv_async_send(async);
}

void plugin_destroy_state(void *ptr) {
  plugin_state *state = reinterpret_cast<plugin_state *>(ptr);
  delete state->callback;
}

}  // namespace node
}  // namespace grpc
<commit_msg>Fixing implementations.<commit_after>/*
 *
 * Copyright 2015, Google Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <node.h>

#include "grpc/grpc.h"
#include "grpc/grpc_security.h"
#include "grpc/support/log.h"
#include "call_credentials.h"
#include "call.h"

namespace grpc {
namespace node {

using Nan::Callback;
using Nan::EscapableHandleScope;
using Nan::HandleScope;
using Nan::Maybe;
using Nan::MaybeLocal;
using Nan::ObjectWrap;
using Nan::Persistent;
using Nan::Utf8String;

using v8::Exception;
using v8::External;
using v8::Function;
using v8::FunctionTemplate;
using v8::Integer;
using v8::Local;
using v8::Object;
using v8::ObjectTemplate;
using v8::Value;

Nan::Callback *CallCredentials::constructor;
Persistent<FunctionTemplate> CallCredentials::fun_tpl;

CallCredentials::CallCredentials(grpc_call_credentials *credentials)
    : wrapped_credentials(credentials) {}

CallCredentials::~CallCredentials() {
  grpc_call_credentials_release(wrapped_credentials);
}

void CallCredentials::Init(Local<Object> exports) {
  HandleScope scope;
  Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
  tpl->SetClassName(Nan::New("CallCredentials").ToLocalChecked());
  tpl->InstanceTemplate()->SetInternalFieldCount(1);
  Nan::SetPrototypeMethod(tpl, "compose", Compose);
  fun_tpl.Reset(tpl);
  Local<Function> ctr = Nan::GetFunction(tpl).ToLocalChecked();
  Nan::Set(ctr, Nan::New("createFromPlugin").ToLocalChecked(),
           Nan::GetFunction(
               Nan::New<FunctionTemplate>(CreateFromPlugin)).ToLocalChecked());
  Nan::Set(exports, Nan::New("CallCredentials").ToLocalChecked(), ctr);
  constructor = new Nan::Callback(ctr);
}

bool CallCredentials::HasInstance(Local<Value> val) {
  HandleScope scope;
  return Nan::New(fun_tpl)->HasInstance(val);
}

Local<Value> CallCredentials::WrapStruct(grpc_call_credentials *credentials) {
  EscapableHandleScope scope;
  const int argc = 1;
  if (credentials == NULL) {
    return scope.Escape(Nan::Null());
  }
  Local<Value> argv[argc] = {
    Nan::New<External>(reinterpret_cast<void *>(credentials))};
  MaybeLocal<Object> maybe_instance = Nan::NewInstance(
      constructor->GetFunction(), argc, argv);
  if (maybe_instance.IsEmpty()) {
    return scope.Escape(Nan::Null());
  } else {
    return scope.Escape(maybe_instance.ToLocalChecked());
  }
}

grpc_call_credentials *CallCredentials::GetWrappedCredentials() {
  return wrapped_credentials;
}

NAN_METHOD(CallCredentials::New) {
  if (info.IsConstructCall()) {
    if (!info[0]->IsExternal()) {
      return Nan::ThrowTypeError(
          "CallCredentials can only be created with the provided functions");
    }
    Local<External> ext = info[0].As<External>();
    grpc_call_credentials *creds_value =
        reinterpret_cast<grpc_call_credentials *>(ext->Value());
    CallCredentials *credentials = new CallCredentials(creds_value);
    credentials->Wrap(info.This());
    info.GetReturnValue().Set(info.This());
    return;
  } else {
    // This should never be called directly
    return Nan::ThrowTypeError(
        "CallCredentials can only be created with the provided functions");
  }
}

NAN_METHOD(CallCredentials::Compose) {
  if (!CallCredentials::HasInstance(info.This())) {
    return Nan::ThrowTypeError(
        "compose can only be called on CallCredentials objects");
  }
  if (!CallCredentials::HasInstance(info[0])) {
    return Nan::ThrowTypeError(
        "compose's first argument must be a CallCredentials object");
  }
  CallCredentials *self = ObjectWrap::Unwrap<CallCredentials>(info.This());
  CallCredentials *other = ObjectWrap::Unwrap<CallCredentials>(
      Nan::To<Object>(info[0]).ToLocalChecked());
  grpc_call_credentials *creds = grpc_composite_call_credentials_create(
      self->wrapped_credentials, other->wrapped_credentials, NULL);
  info.GetReturnValue().Set(WrapStruct(creds));
}

NAN_METHOD(CallCredentials::CreateFromPlugin) {
  if (!info[0]->IsFunction()) {
    return Nan::ThrowTypeError(
        "createFromPlugin's argument must be a function");
  }
  grpc_metadata_credentials_plugin plugin;
  plugin_state *state = new plugin_state;
  state->callback = new Nan::Callback(info[0].As<Function>());
  plugin.get_metadata = plugin_get_metadata;
  plugin.destroy = plugin_destroy_state;
  plugin.state = reinterpret_cast<void*>(state);
  grpc_call_credentials *creds = grpc_metadata_credentials_create_from_plugin(
      plugin, NULL);
  info.GetReturnValue().Set(WrapStruct(creds));
}

NAN_METHOD(PluginCallback) {
  // Arguments: status code, error details, metadata
  if (!info[0]->IsUint32()) {
    return Nan::ThrowTypeError(
        "The callback's first argument must be a status code");
  }
  if (!info[1]->IsString()) {
    return Nan::ThrowTypeError(
        "The callback's second argument must be a string");
  }
  if (!info[2]->IsObject()) {
    return Nan::ThrowTypeError(
        "The callback's third argument must be an object");
  }
  shared_ptr<Resources> resources(new Resources);
  grpc_status_code code = static_cast<grpc_status_code>(
      Nan::To<uint32_t>(info[0]).FromJust());
  char *details = *Utf8String(info[1]);
  grpc_metadata_array array;
  if (!CreateMetadataArray(Nan::To<Object>(info[2]).ToLocalChecked(),
                           &array, resources)){
    return Nan::ThrowError("Failed to parse metadata");
  }
  grpc_credentials_plugin_metadata_cb cb =
      reinterpret_cast<grpc_credentials_plugin_metadata_cb>(
          Nan::Get(info.Callee(),
                   Nan::New("cb").ToLocalChecked()
                   ).ToLocalChecked().As<External>()->Value());
  void *user_data =
      Nan::Get(info.Callee(),
               Nan::New("user_data").ToLocalChecked()
               ).ToLocalChecked().As<External>()->Value();
  cb(user_data, array.metadata, array.count, code, details);
}

NAUV_WORK_CB(SendPluginCallback) {
  Nan::HandleScope scope;
  plugin_callback_data *data = reinterpret_cast<plugin_callback_data*>(
      async->data);
  // Attach cb and user_data to plugin_callback so that it can access them later
  v8::Local<v8::Function> plugin_callback = Nan::GetFunction(
      Nan::New<v8::FunctionTemplate>(PluginCallback)).ToLocalChecked();
  Nan::Set(plugin_callback, Nan::New("cb").ToLocalChecked(),
           Nan::New<v8::External>(reinterpret_cast<void*>(data->cb)));
  Nan::Set(plugin_callback, Nan::New("user_data").ToLocalChecked(),
           Nan::New<v8::External>(data->user_data));
  const int argc = 2;
  v8::Local<v8::Value> argv[argc] = {
    Nan::New(data->service_url).ToLocalChecked(),
    plugin_callback
  };
  Nan::Callback *callback = data->state->callback;
  callback->Call(argc, argv);
  delete data;
  uv_unref((uv_handle_t *)async);
  uv_close((uv_handle_t *)async, (uv_close_cb)free);
}

void plugin_get_metadata(void *state, grpc_auth_metadata_context context,
                         grpc_credentials_plugin_metadata_cb cb,
                         void *user_data) {
  uv_async_t *async = static_cast<uv_async_t*>(malloc(sizeof(uv_async_t)));
  uv_async_init(uv_default_loop(),
                async,
                SendPluginCallback);
  plugin_callback_data *data = new plugin_callback_data;
  data->state = reinterpret_cast<plugin_state*>(state);
  data->service_url = context.service_url;
  data->cb = cb;
  data->user_data = user_data;
  async->data = data;
  /* libuv says that it will coalesce calls to uv_async_send. If there is ever a
   * problem with a callback not getting called, that is probably the reason */
  uv_async_send(async);
}

void plugin_destroy_state(void *ptr) {
  plugin_state *state = reinterpret_cast<plugin_state *>(ptr);
  delete state->callback;
}

}  // namespace node
}  // namespace grpc
<|endoftext|>


<commit_before>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of libmeegotouch.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include "mapplicationmenubuttonview.h"
#include "mapplicationmenubuttonview_p.h"
#include "mapplicationmenubutton.h"
#include "mtheme.h"
#include "mviewcreator.h"
#include "mimagewidget.h"
#include "mlabel.h"
#include "mprogressindicator.h"
#include "mlayout.h"
#include "mgridlayoutpolicy.h"

#include <QFontMetricsF>

MApplicationMenuButtonViewPrivate::MApplicationMenuButtonViewPrivate()
    : iconImage(0),  arrowIconImage(0), spinner(0), layout(0)
{
}

MApplicationMenuButtonViewPrivate::~MApplicationMenuButtonViewPrivate()
{
    delete iconImage;
    delete arrowIconImage;
    delete spinner;
}

void MApplicationMenuButtonViewPrivate::init()
{
    iconImage = new MImageWidget(controller);
    arrowIconImage = new MImageWidget(controller);

    iconImage->setObjectName("NavigationBarMenuButtonIconImage");
    arrowIconImage->setObjectName("NavigationBarMenuButtonArrowImage");
    arrowIconImage->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
    label->setObjectName("NavigationBarMenuButtonLabel");

    layout = new MLayout();
    policy = new MGridLayoutPolicy(layout);

    policy->setContentsMargins(0, 0, 0, 0);
    controller->setLayout(layout);
}

void MApplicationMenuButtonViewPrivate::refreshStyleMode()
{
    Q_Q(MApplicationMenuButtonView);

    if (q->model()->down())
        q->style().setModePressed();
    else if (q->model()->checked())
        q->style().setModeSelected();
    else
        q->style().setModeDefault();

    label->setAlignment(q->style()->horizontalTextAlign() | q->style()->verticalTextAlign());

    refreshIconImage();
}

void MApplicationMenuButtonViewPrivate::refreshLayout()
{
    Q_Q(MApplicationMenuButtonView);

    while (policy->count()) {
        policy->removeAt(0);
    }

    int colIndex = 0;
    MApplicationMenuButton *buttonController = (MApplicationMenuButton *)controller;
    if (buttonController->isIconVisible() && !buttonController->iconID().isEmpty()) {
        policy->addItem(iconImage, 0, colIndex++);
        policy->setAlignment(iconImage, Qt::AlignCenter);
        iconImage->show();
    } else {
        iconImage->hide();
    }
    policy->addItem(label, 0, colIndex++);
    policy->setAlignment(label, Qt::AlignCenter);

    arrowIconImage->hide();
    if (q->model()->progressIndicatorVisible() && spinner) {
        spinner->setUnknownDuration(true);
        policy->addItem(spinner, 0, colIndex++);
        policy->setAlignment(spinner, Qt::AlignCenter);
        spinner->show();
    } else {
        if (spinner) {
            spinner->hide();
            spinner->setUnknownDuration(false);
        }
        if (buttonController->isArrowIconVisible()) {
            policy->addItem(arrowIconImage, 0, colIndex++);
            policy->setAlignment(arrowIconImage, Qt::AlignLeft | Qt::AlignVCenter);
            arrowIconImage->show();
        }
    }
    q->updateGeometry();
}

void MApplicationMenuButtonViewPrivate::refreshIconImage()
{
    Q_Q(MApplicationMenuButtonView);

    QSize size = q->style()->iconSize();
    QString iconID = q->model()->iconID();

    if (toggleState() && !q->model()->toggledIconID().isEmpty())
        iconID = q->model()->toggledIconID();

    if (iconID != iconImage->image() ||
        (!iconID.isEmpty() && iconID == iconImage->image() && size != iconImage->imageSize())) {
        //Apply image and refresh layout only if image itself or size of the existing image
        //should be changed (avoid some flickering).
        iconImage->setImage(iconID, size);
        refreshLayout();
    }
}

MApplicationMenuButtonView::MApplicationMenuButtonView(MApplicationMenuButton *controller) :
    MButtonView(* new MApplicationMenuButtonViewPrivate, controller)
{
    Q_D(MApplicationMenuButtonView);
    d->init();
}

MApplicationMenuButtonView::MApplicationMenuButtonView(MApplicationMenuButtonViewPrivate &dd, MApplicationMenuButton *controller) :
    MButtonView(dd, controller)
{
    Q_D(MApplicationMenuButtonView);
    d->init();
}

MApplicationMenuButtonView::~MApplicationMenuButtonView()
{
}

// must override MButtonView::resizeEvent
void MApplicationMenuButtonView::resizeEvent(QGraphicsSceneResizeEvent *event)
{
    MButtonView::resizeEvent(event);
}

void MApplicationMenuButtonView::applyStyle()
{
    Q_D(MApplicationMenuButtonView);

    MButtonView::applyStyle();

    d->arrowIconImage->setImage(style()->arrowIcon(), style()->arrowIconSize());
    d->refreshStyleMode();
    d->refreshLayout();
    d->iconImage->setZoomFactor(1.0);
    d->arrowIconImage->setZoomFactor(1.0);

    update();
}

void MApplicationMenuButtonView::updateData(const QList<const char *>& modifications)
{
    Q_D(MApplicationMenuButtonView);

    MButtonView::updateData(modifications);
    const char *member;
    foreach(member, modifications) {
        if (member == MButtonModel::Text) {
            d->label->setText(model()->text());
        } else if (member == MButtonModel::TextVisible) {
            d->label->setVisible(model()->textVisible());
        } else if (member == MButtonModel::IconID || member == MButtonModel::ToggledIconID) {
            d->refreshIconImage();
        } else if (member == MButtonModel::IconVisible) {
            d->iconImage->setVisible(model()->iconVisible());
            d->refreshLayout();
        } else if (member == MApplicationMenuButtonModel::ProgressIndicatorVisible) {
            // to reduce the application startup time,  only create spinner when it is needed.
            if (d->spinner == 0) {
                d->spinner = new MProgressIndicator(d->controller, MProgressIndicator::spinnerType);
            }
            d->refreshLayout();
        } else if (member == MApplicationMenuButtonModel::ArrowIconVisible) {
            d->refreshLayout();
        } else if (member == MButtonModel::Down || member == MButtonModel::Checked ||
                   member == MButtonModel::Checkable) {
            d->refreshStyleMode();
        }
    }
    update();
}

void MApplicationMenuButtonView::setupModel()
{
    Q_D(MApplicationMenuButtonView);

    d->label->setText(model()->text());
    d->label->setVisible(model()->textVisible());

    d->refreshIconImage();

    MButtonView::setupModel();
}

M_REGISTER_VIEW_NEW(MApplicationMenuButtonView, MApplicationMenuButton)
<commit_msg>Changes: Adapt the mapplicationmenubuttonview to creating label on demand.<commit_after>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of libmeegotouch.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include "mapplicationmenubuttonview.h"
#include "mapplicationmenubuttonview_p.h"
#include "mapplicationmenubutton.h"
#include "mtheme.h"
#include "mviewcreator.h"
#include "mimagewidget.h"
#include "mlabel.h"
#include "mprogressindicator.h"
#include "mlayout.h"
#include "mgridlayoutpolicy.h"

#include <QFontMetricsF>

MApplicationMenuButtonViewPrivate::MApplicationMenuButtonViewPrivate()
    : iconImage(0),  arrowIconImage(0), spinner(0), layout(0)
{
}

MApplicationMenuButtonViewPrivate::~MApplicationMenuButtonViewPrivate()
{
    delete iconImage;
    delete arrowIconImage;
    delete spinner;
}

void MApplicationMenuButtonViewPrivate::init()
{
    iconImage = new MImageWidget(controller);
    arrowIconImage = new MImageWidget(controller);

    iconImage->setObjectName("NavigationBarMenuButtonIconImage");
    arrowIconImage->setObjectName("NavigationBarMenuButtonArrowImage");
    arrowIconImage->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);

    layout = new MLayout();
    policy = new MGridLayoutPolicy(layout);

    policy->setContentsMargins(0, 0, 0, 0);
    controller->setLayout(layout);
}

void MApplicationMenuButtonViewPrivate::refreshStyleMode()
{
    Q_Q(MApplicationMenuButtonView);

    if (q->model()->down())
        q->style().setModePressed();
    else if (q->model()->checked())
        q->style().setModeSelected();
    else
        q->style().setModeDefault();

    if (label)
        label->setAlignment(q->style()->horizontalTextAlign() | q->style()->verticalTextAlign());

    refreshIconImage();
}

void MApplicationMenuButtonViewPrivate::refreshLayout()
{
    Q_Q(MApplicationMenuButtonView);

    while (policy->count()) {
        policy->removeAt(0);
    }

    int colIndex = 0;
    MApplicationMenuButton *buttonController = (MApplicationMenuButton *)controller;
    if (buttonController->isIconVisible() && !buttonController->iconID().isEmpty()) {
        policy->addItem(iconImage, 0, colIndex++);
        policy->setAlignment(iconImage, Qt::AlignCenter);
        iconImage->show();
    } else {
        iconImage->hide();
    }

    if (label) {
        policy->addItem(label, 0, colIndex++);
        policy->setAlignment(label, Qt::AlignCenter);
    }

    arrowIconImage->hide();
    if (q->model()->progressIndicatorVisible() && spinner) {
        spinner->setUnknownDuration(true);
        policy->addItem(spinner, 0, colIndex++);
        policy->setAlignment(spinner, Qt::AlignCenter);
        spinner->show();
    } else {
        if (spinner) {
            spinner->hide();
            spinner->setUnknownDuration(false);
        }
        if (buttonController->isArrowIconVisible()) {
            policy->addItem(arrowIconImage, 0, colIndex++);
            policy->setAlignment(arrowIconImage, Qt::AlignLeft | Qt::AlignVCenter);
            arrowIconImage->show();
        }
    }
    q->updateGeometry();
}

void MApplicationMenuButtonViewPrivate::refreshIconImage()
{
    Q_Q(MApplicationMenuButtonView);

    QSize size = q->style()->iconSize();
    QString iconID = q->model()->iconID();

    if (toggleState() && !q->model()->toggledIconID().isEmpty())
        iconID = q->model()->toggledIconID();

    if (iconID != iconImage->image() ||
        (!iconID.isEmpty() && iconID == iconImage->image() && size != iconImage->imageSize())) {
        //Apply image and refresh layout only if image itself or size of the existing image
        //should be changed (avoid some flickering).
        iconImage->setImage(iconID, size);
        refreshLayout();
    }
}

MApplicationMenuButtonView::MApplicationMenuButtonView(MApplicationMenuButton *controller) :
    MButtonView(* new MApplicationMenuButtonViewPrivate, controller)
{
    Q_D(MApplicationMenuButtonView);
    d->init();
}

MApplicationMenuButtonView::MApplicationMenuButtonView(MApplicationMenuButtonViewPrivate &dd, MApplicationMenuButton *controller) :
    MButtonView(dd, controller)
{
    Q_D(MApplicationMenuButtonView);
    d->init();
}

MApplicationMenuButtonView::~MApplicationMenuButtonView()
{
}

// must override MButtonView::resizeEvent
void MApplicationMenuButtonView::resizeEvent(QGraphicsSceneResizeEvent *event)
{
    MButtonView::resizeEvent(event);
}

void MApplicationMenuButtonView::applyStyle()
{
    Q_D(MApplicationMenuButtonView);

    MButtonView::applyStyle();

    d->arrowIconImage->setImage(style()->arrowIcon(), style()->arrowIconSize());
    d->iconImage->setZoomFactor(1.0);
    d->arrowIconImage->setZoomFactor(1.0);

    if (d->label) {
        d->label->setObjectName("NavigationBarMenuButtonLabel");
    }

    d->refreshStyleMode();
    d->refreshLayout();
}

void MApplicationMenuButtonView::updateData(const QList<const char *>& modifications)
{
    Q_D(MApplicationMenuButtonView);

    MButtonView::updateData(modifications);
    bool mustRefreshLayout = false;
    bool mustRefreshStyleMode = false;
    const char *member;
    foreach(member, modifications) {
        if (member == MButtonModel::Text || member == MButtonModel::TextVisible) {
            mustRefreshLayout = true;
        } else if (member == MButtonModel::IconID || member == MButtonModel::ToggledIconID) {
            d->refreshIconImage();
        } else if (member == MButtonModel::IconVisible) {
            d->iconImage->setVisible(model()->iconVisible());
            mustRefreshLayout = true;
        } else if (member == MApplicationMenuButtonModel::ProgressIndicatorVisible) {
            // to reduce the application startup time,  only create spinner when it is needed.
            if (d->spinner == 0) {
                d->spinner = new MProgressIndicator(d->controller, MProgressIndicator::spinnerType);
            }
            mustRefreshLayout = true;
        } else if (member == MApplicationMenuButtonModel::ArrowIconVisible) {
            mustRefreshLayout = true;
        } else if (member == MButtonModel::Down || member == MButtonModel::Checked ||
                   member == MButtonModel::Checkable) {
            mustRefreshStyleMode = true;
        }
    }

    if (mustRefreshLayout)
        d->refreshLayout();

    if (mustRefreshStyleMode)
        d->refreshStyleMode();
}

void MApplicationMenuButtonView::setupModel()
{
    MButtonView::setupModel();

    QList<const char*> modifications;
    modifications << MButtonModel::IconID;
    modifications << MButtonModel::IconVisible;
    modifications << MApplicationMenuButtonModel::ProgressIndicatorVisible;
    modifications << MApplicationMenuButtonModel::ArrowIconVisible;

    updateData(modifications);
    update();
}

M_REGISTER_VIEW_NEW(MApplicationMenuButtonView, MApplicationMenuButton)
<|endoftext|>