<commit_before>/**
 *  For conditions of distribution and use, see copyright notice in license.txt
 *
 *  @file   JavascriptInstance.cpp
 *  @brief  Javascript script instance used wit EC_Script.
 */

#include "StableHeaders.h"
#include "DebugOperatorNew.h"
#include "JavascriptInstance.h"
#include "JavascriptModule.h"
#include "ScriptMetaTypeDefines.h"
#include "NaaliCoreTypeDefines.h"
#include "EC_Script.h"
#include "IModule.h"
#include "AssetAPI.h"
#include "IAssetProvider.h" //to check if the code was loaded from a local or remote storage

#include "LoggingFunctions.h"
DEFINE_POCO_LOGGING_FUNCTIONS("JavascriptInstance")

#include <QFile>

#include "MemoryLeakCheck.h"

JavascriptInstance::JavascriptInstance(const QString &fileName, JavascriptModule *module)
:engine_(0),
sourceFile(fileName),
module_(module),
evaluated(false)
{
    CreateEngine();
    Load();
}

JavascriptInstance::JavascriptInstance(ScriptAssetPtr scriptRef, JavascriptModule *module)
:engine_(0),
scriptRef_(scriptRef),
module_(module),
evaluated(false)
{
    CreateEngine();
    Load();
}

JavascriptInstance::~JavascriptInstance()
{
    DeleteEngine();
}

void JavascriptInstance::Load()
{
    if (!engine_)
        CreateEngine();

    // Can't specify both a file source and an Asset API source.
    assert(sourceFile.isEmpty() || scriptRef_.get() == 0);

    //determine based on code origin whether it can be trusted with system access or not
    if (scriptRef_.get())
    {
        AssetProviderPtr provider = scriptRef_.get()->GetAssetProvider();
        if (provider->Name() == "Local")
            trusted_ = true;
        else
            trusted_ = false;
    }

    if (sourceFile.length() > 0)
    {
        program_ = LoadScript(sourceFile);
        trusted_ = true; //this is a local file directly, right?
    }

    // Do we even have a script to execute?
    if (program_.isEmpty() && (!scriptRef_.get() || scriptRef_->scriptContent.isEmpty()))
    {
        LogError("JavascriptInstance::Load: No script content to load!");
        return;
    }

    QString scriptSourceFilename = (scriptRef_.get() ? scriptRef_->Name() : sourceFile);
    QString &scriptContent = (scriptRef_.get() ? scriptRef_->scriptContent : program_);

    QScriptSyntaxCheckResult syntaxResult = engine_->checkSyntax(scriptContent);
    if (syntaxResult.state() != QScriptSyntaxCheckResult::Valid)
    {
        LogError("Syntax error in script " + scriptSourceFilename.toStdString() + "," + QString::number(syntaxResult.errorLineNumber()).toStdString() +
            ": " + syntaxResult.errorMessage().toStdString());

        // Delete our loaded script content (if any exists).
        program_ == "";
    }
}

QString JavascriptInstance::LoadScript(const QString &fileName)
{
    QString filename = fileName.trimmed();

    // First check if the include was supposed to go through the Asset API.
    if (module_)
    {
        ScriptAssetPtr asset = boost::dynamic_pointer_cast<ScriptAsset>(module_->GetFramework()->Asset()->GetAsset(fileName));
        if (asset)
            return asset->scriptContent;
    }

    // Otherwise, treat fileName as a local file to load up.

    QFile scriptFile(filename);
    if (!scriptFile.open(QIODevice::ReadOnly))
    {
        LogError(("JavascriptInstance::LoadScript: Failed to load script from file " + filename + "!").toStdString());
        return "";
    }

    QString result = scriptFile.readAll();
    scriptFile.close();

    QString trimmedResult = result.trimmed();
    if (trimmedResult.isEmpty())
    {
        LogWarning(("JavascriptInstance::LoadScript: Warning Loaded script from file " + filename + ", but the content was empty.").toStdString());
        return "";
    }
    return result;
}

void JavascriptInstance::Unload()
{
    DeleteEngine();
}

void JavascriptInstance::Run()
{
    // Need to have either absolute file path source or an Asset API source.
    if (!scriptRef_.get() && program_.isEmpty())
    {
        LogError("JavascriptInstance::Run: Cannot run, no script reference loaded.");
        return;
    }

    // Can't specify both a file source and an Asset API source.
    assert(sourceFile.isEmpty() || scriptRef_.get() == 0);

    // If we've already evaluated this script once before, create a new script engine to run it again, or otherwise
    // the effects would stack (we'd possibly register into signals twice, or other odd side effects).
    // We never allow a script to be run twice in this kind of "stacking" manner.
    if (evaluated)
    {
        Unload();
        Load();
    }

    if (!engine_)
    {
        LogError("JavascriptInstance::Run: Cannot run, script engine not loaded.");
        return;
    }

    // If no script specified at all, we'll have to abort.
    if (!scriptRef_.get() && program_.isEmpty())
        return;

    QString scriptSourceFilename = (scriptRef_.get() ? scriptRef_->Name() : sourceFile);
    QString &scriptContent = (scriptRef_.get() ? scriptRef_->scriptContent : program_);

    included_files_.clear();
    QScriptValue result = engine_->evaluate(scriptContent, scriptSourceFilename);
    if (engine_->hasUncaughtException())
        LogError(result.toString().toStdString());

    evaluated = true;
}

void JavascriptInstance::RegisterService(QObject *serviceObject, const QString &name)
{
    if (!engine_)
    {
        LogError("JavascriptInstance::RegisterService: No Qt script engine created when trying to register service to js script instance.");
        return;
    }
    if (!serviceObject)
    {
        LogError("JavascriptInstance::RegisterService: Trying to pass a null service object pointer to RegisterService!");
        return;
    }

    QScriptValue scriptValue = engine_->newQObject(serviceObject);
    engine_->globalObject().setProperty(name, scriptValue);
}

void JavascriptInstance::IncludeFile(const QString &path)
{
    for (uint i = 0; i < included_files_.size(); ++i)
    {
        if (included_files_[i].toLower() == path.toLower())
        {
            LogDebug("JavascriptInstance::IncludeFile: Not including already included file " + path.toStdString());
            return;
        }
    }

    QString script = LoadScript(path);

    QScriptContext *context = engine_->currentContext();
    assert(context);
    if (!context)
    {
        LogError("JavascriptInstance::IncludeFile: QScriptEngine::currentContext() returned null!");
        return;
    }

    QScriptContext *parent = context->parentContext();
    if (!parent)
    {
        LogError("JavascriptInstance::IncludeFile: QScriptEngine::parentContext() returned null!");
        return;
    }

    context->setActivationObject(context->parentContext()->activationObject());
    context->setThisObject(context->parentContext()->thisObject());

    QScriptSyntaxCheckResult syntaxResult = engine_->checkSyntax(script);
    if(syntaxResult.state() != QScriptSyntaxCheckResult::Valid)
    {
        LogError("JavascriptInstance::IncludeFile: Syntax error in " + path.toStdString() + syntaxResult.errorMessage().toStdString()
            + " In line:" + QString::number(syntaxResult.errorLineNumber()).toStdString());
        return;
    }

    QScriptValue result = engine_->evaluate(script);

    included_files_.push_back(path);

    if (engine_->hasUncaughtException())
        LogError(result.toString().toStdString());
}

void JavascriptInstance::ImportExtension(const QString &scriptExtensionName)
{
    assert(engine_);
    if (!engine_)
    {
        LogWarning(("JavascriptInstance::ImportExtension(" + scriptExtensionName + ") failed, QScriptEngine==null!").toStdString());
        return;
    }

    QStringList extension_whitelist; //the search is system wide, so whitelist is best to not leak to 3rd party libs
    extension_whitelist << "qt.core" << "qt.gui" << "qt.xml" << "qt.xmlpatterns" << "qt.opengl" << "qt.phonon"; //webkit not allowed directly so scripts can't open hidden browsers to do malicious stuff. uitools to be investigated

    QStringList qtcore_blacklist; //the types in qt.core which are not safe. should probably be a whitelist too.
    qtcore_blacklist << "QDir" << "QFile" << "QFileSystemWatcher" << "QFileInfo" << "QLibrary" << "QPluginLoader";

    if (!trusted_ && !extension_whitelist.contains(scriptExtensionName, Qt::CaseInsensitive))
    {
        LogWarning("JavascriptInstance::ImportExtension: refusing to load a QtScript plugin for an untrusted instance: " + scriptExtensionName.toStdString());
        return;
    }

    QScriptValue success = engine_->importExtension(scriptExtensionName);
    if (!success.isUndefined()) // Yes, importExtension returns undefinedValue if the import succeeds. http://doc.qt.nokia.com/4.7/qscriptengine.html#importExtension
        LogWarning(std::string("JavascriptInstance::ImportExtension: Failed to load ") + scriptExtensionName.toStdString() + " plugin for QtScript!");

    if (!trusted_)
    {
        QScriptValue exposed;
        foreach (const QString &blacktype, qtcore_blacklist)
        {
            exposed = engine_->globalObject().property(blacktype);
            if (exposed.isValid())
            {
                engine_->globalObject().setProperty(blacktype, QScriptValue::QScriptValue()); //passing an invalid val removes the property, http://doc.qt.nokia.com/4.6/qscriptvalue.html#setProperty
                //LogInfo("JavascriptInstance::ImportExtension: removed a type from the untrusted context: " + blacktype.toStdString());
            }
        }
    }
}

void JavascriptInstance::CreateEngine()
{
    if (engine_)
        DeleteEngine();
    engine_ = new QScriptEngine;
    connect(engine_, SIGNAL(signalHandlerException(const QScriptValue &)), SLOT(OnSignalHandlerException(const QScriptValue &)));

    ExposeQtMetaTypes(engine_);
    ExposeNaaliCoreTypes(engine_);
    ExposeCoreApiMetaTypes(engine_);

    EC_Script *ec = dynamic_cast<EC_Script *>(owner_.lock().get());
    module_->PrepareScriptInstance(this, ec);
    evaluated = false;
}

void JavascriptInstance::DeleteEngine()
{
    if (!engine_)
        return;

    program_ = "";
    engine_->abortEvaluation();

    // As a convention, we call a function 'OnScriptDestroyed' for each JS script
    // so that they can clean up their data before the script is removed from the object,
    // or when the system is unloading.

    QScriptValue destructor = engine_->globalObject().property("OnScriptDestroyed");
    if (!destructor.isUndefined())
        destructor.call();
    SAFE_DELETE(engine_);
}

void JavascriptInstance::OnSignalHandlerException(const QScriptValue& exception)
{
    LogError(exception.toString().toStdString());
}

<commit_msg>remove phonon from untrusted js whitelist. it can listen to mic and write files.<commit_after>/**
 *  For conditions of distribution and use, see copyright notice in license.txt
 *
 *  @file   JavascriptInstance.cpp
 *  @brief  Javascript script instance used wit EC_Script.
 */

#include "StableHeaders.h"
#include "DebugOperatorNew.h"
#include "JavascriptInstance.h"
#include "JavascriptModule.h"
#include "ScriptMetaTypeDefines.h"
#include "NaaliCoreTypeDefines.h"
#include "EC_Script.h"
#include "IModule.h"
#include "AssetAPI.h"
#include "IAssetProvider.h" //to check if the code was loaded from a local or remote storage

#include "LoggingFunctions.h"
DEFINE_POCO_LOGGING_FUNCTIONS("JavascriptInstance")

#include <QFile>

#include "MemoryLeakCheck.h"

JavascriptInstance::JavascriptInstance(const QString &fileName, JavascriptModule *module)
:engine_(0),
sourceFile(fileName),
module_(module),
evaluated(false)
{
    CreateEngine();
    Load();
}

JavascriptInstance::JavascriptInstance(ScriptAssetPtr scriptRef, JavascriptModule *module)
:engine_(0),
scriptRef_(scriptRef),
module_(module),
evaluated(false)
{
    CreateEngine();
    Load();
}

JavascriptInstance::~JavascriptInstance()
{
    DeleteEngine();
}

void JavascriptInstance::Load()
{
    if (!engine_)
        CreateEngine();

    // Can't specify both a file source and an Asset API source.
    assert(sourceFile.isEmpty() || scriptRef_.get() == 0);

    //determine based on code origin whether it can be trusted with system access or not
    if (scriptRef_.get())
    {
        AssetProviderPtr provider = scriptRef_.get()->GetAssetProvider();
        if (provider->Name() == "Local")
            trusted_ = true;
        else
            trusted_ = false;
    }

    if (sourceFile.length() > 0)
    {
        program_ = LoadScript(sourceFile);
        trusted_ = true; //this is a local file directly, right?
    }

    // Do we even have a script to execute?
    if (program_.isEmpty() && (!scriptRef_.get() || scriptRef_->scriptContent.isEmpty()))
    {
        LogError("JavascriptInstance::Load: No script content to load!");
        return;
    }

    QString scriptSourceFilename = (scriptRef_.get() ? scriptRef_->Name() : sourceFile);
    QString &scriptContent = (scriptRef_.get() ? scriptRef_->scriptContent : program_);

    QScriptSyntaxCheckResult syntaxResult = engine_->checkSyntax(scriptContent);
    if (syntaxResult.state() != QScriptSyntaxCheckResult::Valid)
    {
        LogError("Syntax error in script " + scriptSourceFilename.toStdString() + "," + QString::number(syntaxResult.errorLineNumber()).toStdString() +
            ": " + syntaxResult.errorMessage().toStdString());

        // Delete our loaded script content (if any exists).
        program_ == "";
    }
}

QString JavascriptInstance::LoadScript(const QString &fileName)
{
    QString filename = fileName.trimmed();

    // First check if the include was supposed to go through the Asset API.
    if (module_)
    {
        ScriptAssetPtr asset = boost::dynamic_pointer_cast<ScriptAsset>(module_->GetFramework()->Asset()->GetAsset(fileName));
        if (asset)
            return asset->scriptContent;
    }

    // Otherwise, treat fileName as a local file to load up.

    QFile scriptFile(filename);
    if (!scriptFile.open(QIODevice::ReadOnly))
    {
        LogError(("JavascriptInstance::LoadScript: Failed to load script from file " + filename + "!").toStdString());
        return "";
    }

    QString result = scriptFile.readAll();
    scriptFile.close();

    QString trimmedResult = result.trimmed();
    if (trimmedResult.isEmpty())
    {
        LogWarning(("JavascriptInstance::LoadScript: Warning Loaded script from file " + filename + ", but the content was empty.").toStdString());
        return "";
    }
    return result;
}

void JavascriptInstance::Unload()
{
    DeleteEngine();
}

void JavascriptInstance::Run()
{
    // Need to have either absolute file path source or an Asset API source.
    if (!scriptRef_.get() && program_.isEmpty())
    {
        LogError("JavascriptInstance::Run: Cannot run, no script reference loaded.");
        return;
    }

    // Can't specify both a file source and an Asset API source.
    assert(sourceFile.isEmpty() || scriptRef_.get() == 0);

    // If we've already evaluated this script once before, create a new script engine to run it again, or otherwise
    // the effects would stack (we'd possibly register into signals twice, or other odd side effects).
    // We never allow a script to be run twice in this kind of "stacking" manner.
    if (evaluated)
    {
        Unload();
        Load();
    }

    if (!engine_)
    {
        LogError("JavascriptInstance::Run: Cannot run, script engine not loaded.");
        return;
    }

    // If no script specified at all, we'll have to abort.
    if (!scriptRef_.get() && program_.isEmpty())
        return;

    QString scriptSourceFilename = (scriptRef_.get() ? scriptRef_->Name() : sourceFile);
    QString &scriptContent = (scriptRef_.get() ? scriptRef_->scriptContent : program_);

    included_files_.clear();
    QScriptValue result = engine_->evaluate(scriptContent, scriptSourceFilename);
    if (engine_->hasUncaughtException())
        LogError(result.toString().toStdString());

    evaluated = true;
}

void JavascriptInstance::RegisterService(QObject *serviceObject, const QString &name)
{
    if (!engine_)
    {
        LogError("JavascriptInstance::RegisterService: No Qt script engine created when trying to register service to js script instance.");
        return;
    }
    if (!serviceObject)
    {
        LogError("JavascriptInstance::RegisterService: Trying to pass a null service object pointer to RegisterService!");
        return;
    }

    QScriptValue scriptValue = engine_->newQObject(serviceObject);
    engine_->globalObject().setProperty(name, scriptValue);
}

void JavascriptInstance::IncludeFile(const QString &path)
{
    for (uint i = 0; i < included_files_.size(); ++i)
    {
        if (included_files_[i].toLower() == path.toLower())
        {
            LogDebug("JavascriptInstance::IncludeFile: Not including already included file " + path.toStdString());
            return;
        }
    }

    QString script = LoadScript(path);

    QScriptContext *context = engine_->currentContext();
    assert(context);
    if (!context)
    {
        LogError("JavascriptInstance::IncludeFile: QScriptEngine::currentContext() returned null!");
        return;
    }

    QScriptContext *parent = context->parentContext();
    if (!parent)
    {
        LogError("JavascriptInstance::IncludeFile: QScriptEngine::parentContext() returned null!");
        return;
    }

    context->setActivationObject(context->parentContext()->activationObject());
    context->setThisObject(context->parentContext()->thisObject());

    QScriptSyntaxCheckResult syntaxResult = engine_->checkSyntax(script);
    if(syntaxResult.state() != QScriptSyntaxCheckResult::Valid)
    {
        LogError("JavascriptInstance::IncludeFile: Syntax error in " + path.toStdString() + syntaxResult.errorMessage().toStdString()
            + " In line:" + QString::number(syntaxResult.errorLineNumber()).toStdString());
        return;
    }

    QScriptValue result = engine_->evaluate(script);

    included_files_.push_back(path);

    if (engine_->hasUncaughtException())
        LogError(result.toString().toStdString());
}

void JavascriptInstance::ImportExtension(const QString &scriptExtensionName)
{
    assert(engine_);
    if (!engine_)
    {
        LogWarning(("JavascriptInstance::ImportExtension(" + scriptExtensionName + ") failed, QScriptEngine==null!").toStdString());
        return;
    }

    QStringList extension_whitelist; //the search is system wide, so whitelist is best to not leak to 3rd party libs
    extension_whitelist << "qt.core" << "qt.gui" << "qt.xml" << "qt.xmlpatterns" << "qt.opengl"; //webkit not allowed directly so scripts can't open hidden browsers to do malicious stuff. uitools to be investigated

    QStringList qtcore_blacklist; //the types in qt.core which are not safe. should probably be a whitelist too.
    qtcore_blacklist << "QDir" << "QFile" << "QFileSystemWatcher" << "QFileInfo" << "QLibrary" << "QPluginLoader";

    if (!trusted_ && !extension_whitelist.contains(scriptExtensionName, Qt::CaseInsensitive))
    {
        LogWarning("JavascriptInstance::ImportExtension: refusing to load a QtScript plugin for an untrusted instance: " + scriptExtensionName.toStdString());
        return;
    }

    QScriptValue success = engine_->importExtension(scriptExtensionName);
    if (!success.isUndefined()) // Yes, importExtension returns undefinedValue if the import succeeds. http://doc.qt.nokia.com/4.7/qscriptengine.html#importExtension
        LogWarning(std::string("JavascriptInstance::ImportExtension: Failed to load ") + scriptExtensionName.toStdString() + " plugin for QtScript!");

    if (!trusted_)
    {
        QScriptValue exposed;
        foreach (const QString &blacktype, qtcore_blacklist)
        {
            exposed = engine_->globalObject().property(blacktype);
            if (exposed.isValid())
            {
                engine_->globalObject().setProperty(blacktype, QScriptValue::QScriptValue()); //passing an invalid val removes the property, http://doc.qt.nokia.com/4.6/qscriptvalue.html#setProperty
                //LogInfo("JavascriptInstance::ImportExtension: removed a type from the untrusted context: " + blacktype.toStdString());
            }
        }
    }
}

void JavascriptInstance::CreateEngine()
{
    if (engine_)
        DeleteEngine();
    engine_ = new QScriptEngine;
    connect(engine_, SIGNAL(signalHandlerException(const QScriptValue &)), SLOT(OnSignalHandlerException(const QScriptValue &)));

    ExposeQtMetaTypes(engine_);
    ExposeNaaliCoreTypes(engine_);
    ExposeCoreApiMetaTypes(engine_);

    EC_Script *ec = dynamic_cast<EC_Script *>(owner_.lock().get());
    module_->PrepareScriptInstance(this, ec);
    evaluated = false;
}

void JavascriptInstance::DeleteEngine()
{
    if (!engine_)
        return;

    program_ = "";
    engine_->abortEvaluation();

    // As a convention, we call a function 'OnScriptDestroyed' for each JS script
    // so that they can clean up their data before the script is removed from the object,
    // or when the system is unloading.

    QScriptValue destructor = engine_->globalObject().property("OnScriptDestroyed");
    if (!destructor.isUndefined())
        destructor.call();
    SAFE_DELETE(engine_);
}

void JavascriptInstance::OnSignalHandlerException(const QScriptValue& exception)
{
    LogError(exception.toString().toStdString());
}

<|endoftext|>


<commit_before>/*
Apagando e Ganhando
https://www.urionlinejudge.com.br/judge/pt/problems/view/1084
*/

#include <iostream>
#include <cstdlib>
#include <list>

using namespace std;

int main(void) {
    ios::sync_with_stdio(false);

    int N, D;

    while (cin >> N >> D >> ws, N != 0 || D != 0) {
        string number;
        list<char> l;

        int size = N;
        int desiredSize = N - D;

        getline(cin, number);

        for (int i = 0; i < N; i++) {
            l.push_back(number[i]);
        }

        while (size > desiredSize) {
            auto min = l.begin();

            for (auto it = l.begin(); it != l.end(); ++it) {
                if (*it < *min) min = it;

                if (*min == '0') break;
            }

            l.erase(min);
            size--;
        }

        for (auto it = l.begin(); it != l.end(); ++it) {
            cout << *it;
        }

        cout << '\n';
    }

    return EXIT_SUCCESS;
}
<commit_msg>1084<commit_after>/*
Apagando e Ganhando
https://www.urionlinejudge.com.br/judge/pt/problems/view/1084
*/

#include <iostream>
#include <cstdlib>
#include <vector>
#include <utility>
#include <algorithm>

using namespace std;

typedef pair<int, char> ic;

int main(void) {
    ios::sync_with_stdio(false);

    int N, D;

    while (cin >> N >> D >> ws, N != 0 || D != 0) {
        string number;
        vector<ic*> indexCharacters;

        getline(cin, number);

        for (int i = 0; i < N; i++) {
            ic *indexCharacter = new ic(i, number[i]);
            indexCharacters.push_back(indexCharacter);
        }

        sort(indexCharacters.begin(), indexCharacters.end(), [] (ic *a, ic *b) -> bool {
            if (a->second == b->second) {
                return a->first < b->first;
            }
            else {
                return a->second < b->second;
            }
        });

        sort(indexCharacters.begin() + D, indexCharacters.end(), [] (ic *a, ic *b) -> bool {
            return a->first < b->first;
        });

        for (int i = D; i < N; i++) {
            // cout << "(" << indexCharacters[i]->first << ", " << indexCharacters[i]->second << ") ";
            cout << indexCharacters[i]->second;
        }

        // for (int i = 0; i < N; i++) free(indexCharacters[i]);

        cout << '\n';
    }

    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>// Copyright (c) 2015, Matthew Malensek.
// Distributed under the BSD 2-Clause License (see LICENSE.txt for details)

#include "3RVX.h"

#pragma comment(lib, "gdiplus.lib")
#pragma comment(lib, "Wtsapi32.lib")

#include <ctime>
#include <gdiplus.h>
#include <iostream>
#include <Wtsapi32.h>

#include "DisplayManager.h"
#include "HotkeyManager.h"
#include "Logger.h"
#include "OSD/OSD.h"
#include "OSD/BrightnessOSD.h"
#include "OSD/EjectOSD.h"
#include "OSD/KeyboardOSD.h"
#include "OSD/VolumeOSD.h"
#include "Settings.h"
#include "Skin/SkinManager.h"

int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
    _In_ LPWSTR lpCmdLine, _In_ int nShowCmd) {

    Logger::Start();

    QCLOG(L"  _____ ______     ____  _______ ");
    QCLOG(L" |___ /|  _ \\ \\   / /\\ \\/ /___ / ");
    QCLOG(L"   |_ \\| |_) \\ \\ / /  \\  /  |_ \\ ");
    QCLOG(L"  ___) |  _ < \\ V /   /  \\ ___) |");
    QCLOG(L" |____/|_| \\_\\ \\_/   /_/\\_\\____/ ");
    QCLOG(L"");

    HANDLE mutex;
    mutex = CreateMutex(NULL, FALSE, L"Local\\3RVX");
    if (GetLastError() == ERROR_ALREADY_EXISTS) {
        if (mutex) {
            ReleaseMutex(mutex);
        }

        CLOG(L"A previous instance of the program is already running.\n"
            L"Requesting Settings dialog.");
        _3RVX::Message(_3RVX::MSG_SETTINGS, NULL);

#if defined(ENABLE_3RVX_LOG) && (defined(ENABLE_3RVX_LOGTOFILE) == FALSE)
        CLOG(L"Press [enter] to terminate");
        std::cin.get();
#endif

        return EXIT_SUCCESS;
    }

    CLOG(L"App directory: %s", Settings::AppDir().c_str());

    using namespace Gdiplus;
    ULONG_PTR gdiplusToken;
    GdiplusStartupInput gdiplusStartupInput;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

    _3RVX mainWnd(hInstance);

    HRESULT hr = CoInitializeEx(NULL,
        COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
    if (hr != S_OK) {
        CLOG(L"Failed to initialize the COM library.");
        return EXIT_FAILURE;
    }

    /* Tell the program to initialize */
    PostMessage(mainWnd.Handle(), _3RVX::WM_3RVX_CTRL, _3RVX::MSG_LOAD, NULL);

    /* Register for session change notifications */
    WTSRegisterSessionNotification(mainWnd.Handle(), NOTIFY_FOR_THIS_SESSION);

    /* Start the event loop */
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    GdiplusShutdown(gdiplusToken);
    CoUninitialize();

    Logger::Stop();

    return (int) msg.wParam;
}

_3RVX::_3RVX(HINSTANCE hInstance) :
Window(_3RVX::CLASS_3RVX, _3RVX::CLASS_3RVX, hInstance) {

}

void _3RVX::Initialize() {
    CLOG(L"Initializing...");

    delete _vOSD;
    delete _eOSD;
    delete _bOSD;
    delete _kOSD;
    _vOSD = nullptr;
    _eOSD = nullptr;
    _bOSD = nullptr;
    _kOSD = nullptr;

    Settings *settings = Settings::Instance();
    settings->Load();

    KillTimer(Window::Handle(), TIMER_FIRSTUPDATE);
    KillTimer(Window::Handle(), TIMER_UPDATE);
    if (settings->AutomaticUpdates()) {
        SetTimer(
            Window::Handle(),
            TIMER_FIRSTUPDATE,
            FIRSTUPDATE_INTERVAL,
            NULL);
    }

    SkinManager::Instance()->LoadSkin(settings->SkinXML());

    DisplayManager::UpdateMonitorMap();

    /* OSDs */
    _eOSD = new EjectOSD();
    _vOSD = new VolumeOSD();
    _bOSD = new BrightnessOSD();
    _kOSD = new KeyboardOSD();

    _osds.clear();
    _osds.push_back(_eOSD);
    _osds.push_back(_vOSD);
    _osds.push_back(_bOSD);
    _osds.push_back(_kOSD);

    /* Hotkey setup */
    if (_hkManager != NULL) {
        _hkManager->Shutdown();
    }
    _hkManager = HotkeyManager::Instance(Handle());

    _hotkeys = Settings::Instance()->Hotkeys();
    for (auto it = _hotkeys.begin(); it != _hotkeys.end(); ++it) {
        /* Enable arg caching */
        it->second.EnableArgCache();

        int combination = it->first;
        _hkManager->Register(combination);
    }
}

void _3RVX::ProcessHotkeys(HotkeyInfo &hki) {
    switch (hki.action) {
    case HotkeyInfo::IncreaseVolume:
    case HotkeyInfo::DecreaseVolume:
    case HotkeyInfo::SetVolume:
    case HotkeyInfo::Mute:
    case HotkeyInfo::VolumeSlider:
        if (_vOSD) {
            _vOSD->ProcessHotkeys(hki);
        }
        break;

    case HotkeyInfo::EjectDrive:
    case HotkeyInfo::EjectLastDisk:
        if (_eOSD) {
            _eOSD->ProcessHotkeys(hki);
        }
        break;

    case HotkeyInfo::IncreaseBrightness:
    case HotkeyInfo::DecreaseBrightness:
    case HotkeyInfo::SetBrightness:
        if (_bOSD) {
            _bOSD->ProcessHotkeys(hki);
        }
        break;

    case HotkeyInfo::MediaKey:
    case HotkeyInfo::VirtualKey:
        _kbHotkeyProcessor.ProcessHotkeys(hki);
        break;

    case HotkeyInfo::Run:
        if (hki.HasArgs()) {
            ShellExecute(NULL, L"open", hki.args[0].c_str(),
                NULL, NULL, SW_SHOWNORMAL);
        }
        break;

    case HotkeyInfo::DisableOSD:
        ToggleOSDs();
        break;

    case HotkeyInfo::Settings:
        ShellExecute(NULL, L"open", Settings::SettingsApp().c_str(),
            NULL, NULL, SW_SHOWNORMAL);
        break;

    case HotkeyInfo::Exit:
        SendMessage(Handle(), WM_CLOSE, NULL, NULL);
        break;
    }
}

void _3RVX::ToggleOSDs() {
    for (OSD *osd : _osds) {
        osd->Enabled(!(osd->Enabled()));
    }
}

LRESULT _3RVX::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    switch (message) {
    case WM_HOTKEY: {
        CLOG(L"Hotkey: %d", (int) wParam);
        HotkeyInfo hki = _hotkeys[(int) wParam];
        ProcessHotkeys(hki);
        break;
    }

    case WM_DISPLAYCHANGE: {
        CLOG(L"Detected display change");
        DisplayManager::UpdateMonitorMap();
        for (OSD *osd : _osds) {
            osd->OnDisplayChange();
        }
        break;
    }

    case WM_WTSSESSION_CHANGE: {
        CLOG(L"Detected session change");
        break;
    }

    case WM_CLOSE: {
        CLOG(L"Shutting down");
        HotkeyManager::Instance()->Shutdown();
        _vOSD->HideIcon();
        _eOSD->HideIcon();
        break;
    }

    case WM_DESTROY: {
        PostQuitMessage(0);
        break;
    }

    case WM_TIMER:
        if (wParam == TIMER_FIRSTUPDATE || wParam == TIMER_UPDATE) {
            CLOG(L"Received updater timer notification");
            Settings *settings = Settings::Instance();
            long long checkTime = settings->LastUpdateCheck();
            if ((std::time(nullptr) - checkTime) > (UPDATE_INTERVAL / 1000)) {
                /* Enough time has elapsed since the last update check */
                std::wstring settingsApp = Settings::SettingsApp();
                CLOG(L"Launching update task: %s %s",
                    settingsApp.c_str(), L"-update");
                ShellExecute(NULL, L"open",
                    Settings::SettingsApp().c_str(), L"-update", NULL, SW_HIDE);
            }

            if (wParam == TIMER_FIRSTUPDATE) {
                CLOG(L"Starting long-term update timer");
                /* If this was the first update check (30 min after launch),
                 * then kill the first update timer and start the main timer
                 * (checks on 24-hour intervals) */
                KillTimer(Window::Handle(), TIMER_FIRSTUPDATE);
                SetTimer(Window::Handle(), TIMER_UPDATE,
                    UPDATE_INTERVAL, NULL);
            }
        }
        break;
    }

    if (message == _3RVX::WM_3RVX_CTRL) {
        switch (wParam) {
        case _3RVX::MSG_LOAD:
            Initialize();
            break;

        case _3RVX::MSG_SETTINGS:
            Settings::LaunchSettingsApp();
            break;

        case _3RVX::MSG_HIDEOSD:
            int except = (OSDType) lParam;
            switch (except) {
            case Volume:
                if (_eOSD) { _eOSD->Hide(); }
                if (_bOSD) { _bOSD->Hide(); }
                break;

            case Eject:
                if (_vOSD) { _vOSD->Hide(); }
                if (_bOSD) { _bOSD->Hide(); }
                break;

            case Brightness:
                if (_vOSD) { _vOSD->Hide(); }
                if (_eOSD) { _eOSD->Hide(); }
            }

            break;
        }
    }

    return Window::WndProc(hWnd, message, wParam, lParam);
}
<commit_msg>Handle system colorization changes<commit_after>// Copyright (c) 2015, Matthew Malensek.
// Distributed under the BSD 2-Clause License (see LICENSE.txt for details)

#include "3RVX.h"

#pragma comment(lib, "gdiplus.lib")
#pragma comment(lib, "Wtsapi32.lib")

#include <ctime>
#include <gdiplus.h>
#include <iostream>
#include <Wtsapi32.h>

#include "DisplayManager.h"
#include "HotkeyManager.h"
#include "Logger.h"
#include "OSD/OSD.h"
#include "OSD/BrightnessOSD.h"
#include "OSD/EjectOSD.h"
#include "OSD/KeyboardOSD.h"
#include "OSD/VolumeOSD.h"
#include "Settings.h"
#include "Skin/SkinManager.h"

int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
    _In_ LPWSTR lpCmdLine, _In_ int nShowCmd) {

    Logger::Start();

    QCLOG(L"  _____ ______     ____  _______ ");
    QCLOG(L" |___ /|  _ \\ \\   / /\\ \\/ /___ / ");
    QCLOG(L"   |_ \\| |_) \\ \\ / /  \\  /  |_ \\ ");
    QCLOG(L"  ___) |  _ < \\ V /   /  \\ ___) |");
    QCLOG(L" |____/|_| \\_\\ \\_/   /_/\\_\\____/ ");
    QCLOG(L"");

    HANDLE mutex;
    mutex = CreateMutex(NULL, FALSE, L"Local\\3RVX");
    if (GetLastError() == ERROR_ALREADY_EXISTS) {
        if (mutex) {
            ReleaseMutex(mutex);
        }

        CLOG(L"A previous instance of the program is already running.\n"
            L"Requesting Settings dialog.");
        _3RVX::Message(_3RVX::MSG_SETTINGS, NULL);

#if defined(ENABLE_3RVX_LOG) && (defined(ENABLE_3RVX_LOGTOFILE) == FALSE)
        CLOG(L"Press [enter] to terminate");
        std::cin.get();
#endif

        return EXIT_SUCCESS;
    }

    CLOG(L"App directory: %s", Settings::AppDir().c_str());

    using namespace Gdiplus;
    ULONG_PTR gdiplusToken;
    GdiplusStartupInput gdiplusStartupInput;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

    _3RVX mainWnd(hInstance);

    HRESULT hr = CoInitializeEx(NULL,
        COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
    if (hr != S_OK) {
        CLOG(L"Failed to initialize the COM library.");
        return EXIT_FAILURE;
    }

    /* Tell the program to initialize */
    PostMessage(mainWnd.Handle(), _3RVX::WM_3RVX_CTRL, _3RVX::MSG_LOAD, NULL);

    /* Register for session change notifications */
    WTSRegisterSessionNotification(mainWnd.Handle(), NOTIFY_FOR_THIS_SESSION);

    /* Start the event loop */
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    GdiplusShutdown(gdiplusToken);
    CoUninitialize();

    Logger::Stop();

    return (int) msg.wParam;
}

_3RVX::_3RVX(HINSTANCE hInstance) :
Window(_3RVX::CLASS_3RVX, _3RVX::CLASS_3RVX, hInstance) {

}

void _3RVX::Initialize() {
    CLOG(L"Initializing...");

    delete _vOSD;
    delete _eOSD;
    delete _bOSD;
    delete _kOSD;
    _vOSD = nullptr;
    _eOSD = nullptr;
    _bOSD = nullptr;
    _kOSD = nullptr;

    Settings *settings = Settings::Instance();
    settings->Load();

    KillTimer(Window::Handle(), TIMER_FIRSTUPDATE);
    KillTimer(Window::Handle(), TIMER_UPDATE);
    if (settings->AutomaticUpdates()) {
        SetTimer(
            Window::Handle(),
            TIMER_FIRSTUPDATE,
            FIRSTUPDATE_INTERVAL,
            NULL);
    }

    SkinManager::Instance()->LoadSkin(settings->SkinXML());

    DisplayManager::UpdateMonitorMap();

    /* OSDs */
    _eOSD = new EjectOSD();
    _vOSD = new VolumeOSD();
    _bOSD = new BrightnessOSD();
    _kOSD = new KeyboardOSD();

    _osds.clear();
    _osds.push_back(_eOSD);
    _osds.push_back(_vOSD);
    _osds.push_back(_bOSD);
    _osds.push_back(_kOSD);

    /* Hotkey setup */
    if (_hkManager != NULL) {
        _hkManager->Shutdown();
    }
    _hkManager = HotkeyManager::Instance(Handle());

    _hotkeys = Settings::Instance()->Hotkeys();
    for (auto it = _hotkeys.begin(); it != _hotkeys.end(); ++it) {
        /* Enable arg caching */
        it->second.EnableArgCache();

        int combination = it->first;
        _hkManager->Register(combination);
    }
}

void _3RVX::ProcessHotkeys(HotkeyInfo &hki) {
    switch (hki.action) {
    case HotkeyInfo::IncreaseVolume:
    case HotkeyInfo::DecreaseVolume:
    case HotkeyInfo::SetVolume:
    case HotkeyInfo::Mute:
    case HotkeyInfo::VolumeSlider:
        if (_vOSD) {
            _vOSD->ProcessHotkeys(hki);
        }
        break;

    case HotkeyInfo::EjectDrive:
    case HotkeyInfo::EjectLastDisk:
        if (_eOSD) {
            _eOSD->ProcessHotkeys(hki);
        }
        break;

    case HotkeyInfo::IncreaseBrightness:
    case HotkeyInfo::DecreaseBrightness:
    case HotkeyInfo::SetBrightness:
        if (_bOSD) {
            _bOSD->ProcessHotkeys(hki);
        }
        break;

    case HotkeyInfo::MediaKey:
    case HotkeyInfo::VirtualKey:
        _kbHotkeyProcessor.ProcessHotkeys(hki);
        break;

    case HotkeyInfo::Run:
        if (hki.HasArgs()) {
            ShellExecute(NULL, L"open", hki.args[0].c_str(),
                NULL, NULL, SW_SHOWNORMAL);
        }
        break;

    case HotkeyInfo::DisableOSD:
        ToggleOSDs();
        break;

    case HotkeyInfo::Settings:
        ShellExecute(NULL, L"open", Settings::SettingsApp().c_str(),
            NULL, NULL, SW_SHOWNORMAL);
        break;

    case HotkeyInfo::Exit:
        SendMessage(Handle(), WM_CLOSE, NULL, NULL);
        break;
    }
}

void _3RVX::ToggleOSDs() {
    for (OSD *osd : _osds) {
        osd->Enabled(!(osd->Enabled()));
    }
}

LRESULT _3RVX::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    switch (message) {
    case WM_HOTKEY: {
        CLOG(L"Hotkey: %d", (int) wParam);
        HotkeyInfo hki = _hotkeys[(int) wParam];
        ProcessHotkeys(hki);
        break;
    }

    case WM_DISPLAYCHANGE: {
        CLOG(L"Detected display change");
        DisplayManager::UpdateMonitorMap();
        for (OSD *osd : _osds) {
            osd->OnDisplayChange();
        }
        break;
    }

    case WM_DWMCOLORIZATIONCOLORCHANGED: {
        /* While this message contains the colorization color, we need to
         * refresh here to handle situations where the user has requested a
         * different color (undocumented colorization color, for example). */
        AccentColor::Instance()->Refresh();
    }

    case WM_WTSSESSION_CHANGE: {
        CLOG(L"Detected session change");
        break;
    }

    case WM_CLOSE: {
        CLOG(L"Shutting down");
        HotkeyManager::Instance()->Shutdown();
        _vOSD->HideIcon();
        _eOSD->HideIcon();
        break;
    }

    case WM_DESTROY: {
        PostQuitMessage(0);
        break;
    }

    case WM_TIMER:
        if (wParam == TIMER_FIRSTUPDATE || wParam == TIMER_UPDATE) {
            CLOG(L"Received updater timer notification");
            Settings *settings = Settings::Instance();
            long long checkTime = settings->LastUpdateCheck();
            if ((std::time(nullptr) - checkTime) > (UPDATE_INTERVAL / 1000)) {
                /* Enough time has elapsed since the last update check */
                std::wstring settingsApp = Settings::SettingsApp();
                CLOG(L"Launching update task: %s %s",
                    settingsApp.c_str(), L"-update");
                ShellExecute(NULL, L"open",
                    Settings::SettingsApp().c_str(), L"-update", NULL, SW_HIDE);
            }

            if (wParam == TIMER_FIRSTUPDATE) {
                CLOG(L"Starting long-term update timer");
                /* If this was the first update check (30 min after launch),
                 * then kill the first update timer and start the main timer
                 * (checks on 24-hour intervals) */
                KillTimer(Window::Handle(), TIMER_FIRSTUPDATE);
                SetTimer(Window::Handle(), TIMER_UPDATE,
                    UPDATE_INTERVAL, NULL);
            }
        }
        break;
    }

    if (message == _3RVX::WM_3RVX_CTRL) {
        switch (wParam) {
        case _3RVX::MSG_LOAD:
            Initialize();
            break;

        case _3RVX::MSG_SETTINGS:
            Settings::LaunchSettingsApp();
            break;

        case _3RVX::MSG_HIDEOSD:
            int except = (OSDType) lParam;
            switch (except) {
            case Volume:
                if (_eOSD) { _eOSD->Hide(); }
                if (_bOSD) { _bOSD->Hide(); }
                break;

            case Eject:
                if (_vOSD) { _vOSD->Hide(); }
                if (_bOSD) { _bOSD->Hide(); }
                break;

            case Brightness:
                if (_vOSD) { _vOSD->Hide(); }
                if (_eOSD) { _eOSD->Hide(); }
            }

            break;
        }
    }

    return Window::WndProc(hWnd, message, wParam, lParam);
}
<|endoftext|>


<commit_before>//
//   Copyright 2013 Pixar
//
//   Licensed under the Apache License, Version 2.0 (the "Apache License")
//   with the following modification; you may not use this file except in
//   compliance with the Apache License and the following modification to it:
//   Section 6. Trademarks. is deleted and replaced with:
//
//   6. Trademarks. This License does not grant permission to use the trade
//      names, trademarks, service marks, or product names of the Licensor
//      and its affiliates, except as required to comply with Section 4(c) of
//      the License and to reproduce the content of the NOTICE file.
//
//   You may obtain a copy of the Apache License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the Apache License with the above modification is
//   distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
//   KIND, either express or implied. See the Apache License for the specific
//   language governing permissions and limitations under the Apache License.
//

#include "shape_utils.h"

#include <cassert>
#include <cstdio>
#include <cstring>
#include <iterator>
#include <fstream>
#include <sstream>

//------------------------------------------------------------------------------
static char const * sgets( char * s, int size, char ** stream ) {
    for (int i=0; i<size; ++i) {
        if ( (*stream)[i]=='\n' or (*stream)[i]=='\0') {

            memcpy(s, *stream, i);
            s[i]='\0';

            if ((*stream)[i]=='\0')
                return 0;
            else {
                (*stream) += i+1;
                return s;
            }
        }
    }
    return 0;
}

//------------------------------------------------------------------------------
Shape::~Shape() {
    for (int i=0; i<(int)tags.size(); ++i)
        delete tags[i];

    for (int i=0; i<(int)mtls.size(); ++i)
        delete mtls[i];
}

//------------------------------------------------------------------------------
Shape * Shape::parseObj(char const * shapestr, Scheme shapescheme,
                        bool isLeftHanded, int axis, bool parsemtl) {

    Shape * s = new Shape;

    s->scheme = shapescheme;
    s->isLeftHanded = isLeftHanded;

    char * str=const_cast<char *>(shapestr), line[256], buf[256], usemtl=-1;
    bool done = false;
    while (not done) {
        done = sgets(line, sizeof(line), &str)==0;
        char* end = &line[strlen(line)-1];
        if (*end == '\n') *end = '\0'; // strip trailing nl
        float x, y, z, u, v;
        switch (line[0]) {
            case 'v': switch (line[1]) {
                          case ' ': if (sscanf(line, "v %f %f %f", &x, &y, &z) == 3) {
                                         s->verts.push_back(x);
                                         switch( axis ) {
                                             case 0 : s->verts.push_back(-z);
                                                      s->verts.push_back(y); break;
                                             case 1 : s->verts.push_back(y);
                                                      s->verts.push_back(z); break;
                                         }
                                    } break;
                          case 't': if (sscanf(line, "vt %f %f", &u, &v) == 2) {
                                        s->uvs.push_back(u);
                                        s->uvs.push_back(v);
                                    } break;
                          case 'n' : if (sscanf(line, "vn %f %f %f", &x, &y, &z) == 3) {
                                        s->normals.push_back(x);
                                        s->normals.push_back(y);
                                        s->normals.push_back(z);
                                     } break; // skip normals for now
                      } break;
            case 'f': if (line[1] == ' ') {
                          int vi, ti, ni;
                          const char* cp = &line[2];
                          while (*cp == ' ') cp++;
                          int nverts = 0, nitems=0;
                          while( (nitems=sscanf(cp, "%d/%d/%d", &vi, &ti, &ni))>0) {
                              nverts++;
                              s->faceverts.push_back(vi-1);
                              if(nitems >= 1) s->faceuvs.push_back(ti-1);
                              if(nitems >= 2) s->facenormals.push_back(ni-1);
                              while (*cp && *cp != ' ') cp++;
                              while (*cp == ' ') cp++;
                          }
                          s->nvertsPerFace.push_back(nverts);
                          if (not s->mtls.empty()) {
                              s->mtlbind.push_back(usemtl);
                          }
                      } break;
            case 't' : if (line[1] == ' ') {
                           Shape::tag * t = tag::parseTag( line );
                           if (t)
                               s->tags.push_back(t);
                       } break;
            case 'u' : if (parsemtl and sscanf(line, "usemtl %s", buf)==1) {
                           usemtl = s->FindMaterial(buf);
                       } break;
            case 'm' : if (parsemtl and sscanf(line, "mtllib %s", buf)==1) {
                           std::ifstream ifs(buf);
                           if (ifs) {
                               std::stringstream ss;
                               ss << ifs.rdbuf();
                               ifs.close();
                               std::string str = ss.str();
                               s->parseMtllib(str.c_str());
                               s->mtllib = buf;
                           }
                       } break;
        }
    }
    return s;
}

//------------------------------------------------------------------------------
Shape::tag * Shape::tag::parseTag(char const * line) {
    tag * t = 0;

    const char* cp = &line[2];

    char tname[50];
    while (*cp == ' ') cp++;
    if (sscanf(cp, "%s", tname )!=1) return t;
    while (*cp && *cp != ' ') cp++;

    int nints=0, nfloats=0, nstrings=0;
    while (*cp == ' ') cp++;
    if (sscanf(cp, "%d/%d/%d", &nints, &nfloats, &nstrings)!=3) return t;
    while (*cp && *cp != ' ') cp++;

    std::vector<int> tintargs;
    for (int i=0; i<nints; ++i) {
        int val;
        while (*cp == ' ') cp++;
        if (sscanf(cp, "%d", &val)!=1) return t;
        tintargs.push_back(val);
        while (*cp && *cp != ' ') cp++;
    }

    std::vector<float> tfloatargs;
    for (int i=0; i<nfloats; ++i) {
        float val;
        while (*cp == ' ') cp++;
        if (sscanf(cp, "%f", &val)!=1) return t;
        tfloatargs.push_back(val);
        while (*cp && *cp != ' ') cp++;
    }

    std::vector<std::string> tstringargs;
    for (int i=0; i<nstrings; ++i) {
        char val[512];
        while (*cp == ' ') cp++;
        if (sscanf(cp, "%s", val)!=1) return t;
        tstringargs.push_back(std::string(val));
        while (*cp && *cp != ' ') cp++;
    }

    t = new Shape::tag;
    t->name = tname;
    t->intargs = tintargs;
    t->floatargs = tfloatargs;
    t->stringargs = tstringargs;

    return t;
}

//------------------------------------------------------------------------------
Shape::material::material() {
    memset(ka, 0, sizeof(float)*3);
    memset(kd, 0, sizeof(float)*3);
    memset(ks, 0, sizeof(float)*3);
    memset(tf, 0, sizeof(float)*3);
    ns = ni = d = 0.0f;
    illum=0;
}

//------------------------------------------------------------------------------
void Shape::parseMtllib(char const * mtlstr) {

    char * str=const_cast<char *>(mtlstr), line[256];

    material * mtl=0;

    bool done = false;
    float r, g, b, a;
    while (not done) {
        done = sgets(line, sizeof(line), &str)==0;
        char* end = &line[strlen(line)-1];
        if (*end == '\n') *end = '\0'; // strip trailing nl
        switch (line[0]) {
            case 'n': char name[256];
                      if (sscanf(line, "newmtl %s", name) == 1) {
                          mtl = new material;
                          mtl->name = name;
                          mtls.push_back(mtl);
                      } break;
            case 'K': if (sscanf(line+2, " %f %f %f", &r, &g, &b) == 3) {
                          switch (line[1]) {
                              case 'a': mtl->ka[0]=r; mtl->ka[1]=g; mtl->ka[2]=b; break;
                              case 'd': mtl->kd[0]=r; mtl->kd[1]=g; mtl->kd[2]=b; break;
                              case 's': mtl->ks[0]=r; mtl->ks[1]=g; mtl->ks[2]=b; break;
                          }
                      } break;
            case 'N': if (sscanf(line+2, " %f", &a) == 1) {
                          switch (line[1]) {
                              case 's' : mtl->ns = a; break;
                              case 'i' : mtl->ni = a; break;
                          }
                      } break;
            case 'd': if (sscanf(line, "d %f", &a) == 1) {
                          mtl->d = a;
                      } break;
            case 'T': if (line[1]=='f') {
                         if (sscanf(line, "Tf %f %f %f", &r, &g, &b) == 3) {
                             mtl->tf[0]=r; mtl->tf[1]=g; mtl->tf[2]=b;
                         } break;
                      } break;
            case 'i': int illum;
                      if (sscanf(line, "illum %d", &illum) == 1) {
                          mtl->illum = illum;
                      } break;
            case 's': if (sscanf(line, "sharpness %f", &a) == 1) {
                          mtl->sharpness = a;
                      } break;
        }
    }
}

//------------------------------------------------------------------------------
std::string Shape::tag::genTag() const {
    std::stringstream t;

    t<<"\"t \""<<name<<"\" ";

    t<<intargs.size()<<"/"<<floatargs.size()<<"/"<<stringargs.size()<<" ";

    std::copy(intargs.begin(), intargs.end(), std::ostream_iterator<int>(t));
    t<<" ";

    std::copy(floatargs.begin(), floatargs.end(), std::ostream_iterator<float>(t));
    t<<" ";

    std::copy(stringargs.begin(), stringargs.end(), std::ostream_iterator<std::string>(t));
    t<<"\\n\"\n";

    return t.str();
}

//------------------------------------------------------------------------------
std::string Shape::genShape(char const * name) const {
    std::stringstream sh;

    sh<<"static char const * "<<name<<" = \n";

    for (int i=0; i<(int)verts.size(); i+=3)
       sh << "\"v " << verts[i] << " " << verts[i+1] << " " << verts[i+2] <<"\\n\"\n";

    for (int i=0; i<(int)uvs.size(); i+=2)
       sh << "\"vt " << uvs[i] << " " << uvs[i+1] << "\\n\"\n";

    for (int i=0; i<(int)normals.size(); i+=3)
       sh << "\"vn " << normals[i] << " " << normals[i+1] << " " << normals[i+2] <<"\\n\"\n";

    sh << "\"s off\\n\"\n";

    for (int i=0, idx=0; i<(int)nvertsPerFace.size();++i) {
        sh << "\"f ";
        for (int j=0; j<nvertsPerFace[i];++j) {
            int vert = faceverts[idx+j]+1,
                uv = (int)faceuvs.size()>0 ? faceuvs[idx+j]+1 : vert,
                normal = (int)facenormals.size()>0 ? facenormals[idx+j]+1 : vert;
            sh << vert << "/" << uv << "/" << normal << " ";
        }
        sh << "\\n\"\n";
        idx+=nvertsPerFace[i];
    }

    for (int i=0; i<(int)tags.size(); ++i)
        sh << tags[i]->genTag();

    return sh.str();
}

//------------------------------------------------------------------------------
std::string Shape::genObj() const {
    std::stringstream sh;

    sh<<"# This file uses centimeters as units for non-parametric coordinates.\n\n";

    for (int i=0; i<(int)verts.size(); i+=3)
       sh << "v " << verts[i] << " " << verts[i+1] << " " << verts[i+2] <<"\n";

    for (int i=0; i<(int)uvs.size(); i+=2)
       sh << "vt " << uvs[i] << " " << uvs[i+1] << "\n";

    for (int i=0; i<(int)normals.size(); i+=3)
       sh << "vn " << normals[i] << " " << normals[i+1] << " " << normals[i+2] <<"\n";

    for (int i=0, idx=0; i<(int)nvertsPerFace.size();++i) {
        sh << "f ";
        for (int j=0; j<nvertsPerFace[i];++j) {
            int vert = faceverts[idx+j]+1,
                uv = (int)faceuvs.size()>0 ? faceuvs[idx+j]+1 : vert,
                normal = (int)facenormals.size()>0 ? facenormals[idx+j]+1 : vert;
            sh << vert << "/" << uv << "/" << normal << " ";
        }
        sh << "\n";
        idx+=nvertsPerFace[i];
    }

    for (int i=0; i<(int)tags.size(); ++i)
        sh << tags[i]->genTag();

    return sh.str();
}

//------------------------------------------------------------------------------
std::string Shape::genRIB() const {
    std::stringstream rib;

    rib << "HierarchicalSubdivisionMesh \"catmull-clark\" ";

    rib << "[";
    std::copy(nvertsPerFace.begin(), nvertsPerFace.end(), std::ostream_iterator<int>(rib));
    rib << "] ";

    rib << "[";
    std::copy(faceverts.begin(), faceverts.end(), std::ostream_iterator<int>(rib));
    rib << "] ";

    std::stringstream names, nargs, intargs, floatargs, strargs;
    for (int i=0; i<(int)tags.size();) {
        tag * t = tags[i];

        names << t->name;

        nargs << t->intargs.size() << " " << t->floatargs.size() << " " << t->stringargs.size();

        std::copy(t->intargs.begin(), t->intargs.end(), std::ostream_iterator<int>(intargs));

        std::copy(t->floatargs.begin(), t->floatargs.end(), std::ostream_iterator<float>(floatargs));

        std::copy(t->stringargs.begin(), t->stringargs.end(), std::ostream_iterator<std::string>(strargs));

        if (++i<(int)tags.size()) {
            names << " ";
            nargs << " ";
            intargs << " ";
            floatargs << " ";
            strargs << " ";
        }
    }

    rib << "["<<names.str()<<"] " << "["<<nargs.str()<<"] " << "["<<intargs.str()<<"] " << "["<<floatargs.str()<<"] " << "["<<strargs.str()<<"] ";

    rib << "\"P\" [";
    std::copy(verts.begin(), verts.end(), std::ostream_iterator<float>(rib));
    rib << "] ";

    return rib.str();
}
<commit_msg>Fixed a bug in our obj parser<commit_after>//
//   Copyright 2013 Pixar
//
//   Licensed under the Apache License, Version 2.0 (the "Apache License")
//   with the following modification; you may not use this file except in
//   compliance with the Apache License and the following modification to it:
//   Section 6. Trademarks. is deleted and replaced with:
//
//   6. Trademarks. This License does not grant permission to use the trade
//      names, trademarks, service marks, or product names of the Licensor
//      and its affiliates, except as required to comply with Section 4(c) of
//      the License and to reproduce the content of the NOTICE file.
//
//   You may obtain a copy of the Apache License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the Apache License with the above modification is
//   distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
//   KIND, either express or implied. See the Apache License for the specific
//   language governing permissions and limitations under the Apache License.
//

#include "shape_utils.h"

#include <cassert>
#include <cstdio>
#include <cstring>
#include <iterator>
#include <fstream>
#include <sstream>

//------------------------------------------------------------------------------
static char const * sgets( char * s, int size, char ** stream ) {
    for (int i=0; i<size; ++i) {
        if ( (*stream)[i]=='\n' or (*stream)[i]=='\0') {

            memcpy(s, *stream, i);
            s[i]='\0';

            if ((*stream)[i]=='\0')
                return 0;
            else {
                (*stream) += i+1;
                return s;
            }
        }
    }
    return 0;
}

//------------------------------------------------------------------------------
Shape::~Shape() {
    for (int i=0; i<(int)tags.size(); ++i)
        delete tags[i];

    for (int i=0; i<(int)mtls.size(); ++i)
        delete mtls[i];
}

//------------------------------------------------------------------------------
Shape * Shape::parseObj(char const * shapestr, Scheme shapescheme,
                        bool isLeftHanded, int axis, bool parsemtl) {

    Shape * s = new Shape;

    s->scheme = shapescheme;
    s->isLeftHanded = isLeftHanded;

    char * str=const_cast<char *>(shapestr), line[256], buf[256], usemtl=-1;
    bool done = false;
    while (not done) {
        done = sgets(line, sizeof(line), &str)==0;
        char* end = &line[strlen(line)-1];
        if (*end == '\n') *end = '\0'; // strip trailing nl
        float x, y, z, u, v;
        switch (line[0]) {
            case 'v': switch (line[1]) {
                          case ' ': if (sscanf(line, "v %f %f %f", &x, &y, &z) == 3) {
                                         s->verts.push_back(x);
                                         switch( axis ) {
                                             case 0 : s->verts.push_back(-z);
                                                      s->verts.push_back(y); break;
                                             case 1 : s->verts.push_back(y);
                                                      s->verts.push_back(z); break;
                                         }
                                    } break;
                          case 't': if (sscanf(line, "vt %f %f", &u, &v) == 2) {
                                        s->uvs.push_back(u);
                                        s->uvs.push_back(v);
                                    } break;
                          case 'n' : if (sscanf(line, "vn %f %f %f", &x, &y, &z) == 3) {
                                        s->normals.push_back(x);
                                        s->normals.push_back(y);
                                        s->normals.push_back(z);
                                     } break; // skip normals for now
                      } break;
            case 'f': if (line[1] == ' ') {
                          int vi, ti, ni;
                          const char* cp = &line[2];
                          while (*cp == ' ') cp++;
                          int nverts = 0, nitems=0;
                          while( (nitems=sscanf(cp, "%d/%d/%d", &vi, &ti, &ni))>0) {
                              nverts++;
                              s->faceverts.push_back(vi-1);
                              if(nitems > 1) s->faceuvs.push_back(ti-1);
                              if(nitems > 2) s->facenormals.push_back(ni-1);
                              while (*cp && *cp != ' ') cp++;
                              while (*cp == ' ') cp++;
                          }
                          s->nvertsPerFace.push_back(nverts);
                          if (not s->mtls.empty()) {
                              s->mtlbind.push_back(usemtl);
                          }
                      } break;
            case 't' : if (line[1] == ' ') {
                           Shape::tag * t = tag::parseTag( line );
                           if (t)
                               s->tags.push_back(t);
                       } break;
            case 'u' : if (parsemtl and sscanf(line, "usemtl %s", buf)==1) {
                           usemtl = s->FindMaterial(buf);
                       } break;
            case 'm' : if (parsemtl and sscanf(line, "mtllib %s", buf)==1) {
                           std::ifstream ifs(buf);
                           if (ifs) {
                               std::stringstream ss;
                               ss << ifs.rdbuf();
                               ifs.close();
                               std::string str = ss.str();
                               s->parseMtllib(str.c_str());
                               s->mtllib = buf;
                           }
                       } break;
        }
    }
    return s;
}

//------------------------------------------------------------------------------
Shape::tag * Shape::tag::parseTag(char const * line) {
    tag * t = 0;

    const char* cp = &line[2];

    char tname[50];
    while (*cp == ' ') cp++;
    if (sscanf(cp, "%s", tname )!=1) return t;
    while (*cp && *cp != ' ') cp++;

    int nints=0, nfloats=0, nstrings=0;
    while (*cp == ' ') cp++;
    if (sscanf(cp, "%d/%d/%d", &nints, &nfloats, &nstrings)!=3) return t;
    while (*cp && *cp != ' ') cp++;

    std::vector<int> tintargs;
    for (int i=0; i<nints; ++i) {
        int val;
        while (*cp == ' ') cp++;
        if (sscanf(cp, "%d", &val)!=1) return t;
        tintargs.push_back(val);
        while (*cp && *cp != ' ') cp++;
    }

    std::vector<float> tfloatargs;
    for (int i=0; i<nfloats; ++i) {
        float val;
        while (*cp == ' ') cp++;
        if (sscanf(cp, "%f", &val)!=1) return t;
        tfloatargs.push_back(val);
        while (*cp && *cp != ' ') cp++;
    }

    std::vector<std::string> tstringargs;
    for (int i=0; i<nstrings; ++i) {
        char val[512];
        while (*cp == ' ') cp++;
        if (sscanf(cp, "%s", val)!=1) return t;
        tstringargs.push_back(std::string(val));
        while (*cp && *cp != ' ') cp++;
    }

    t = new Shape::tag;
    t->name = tname;
    t->intargs = tintargs;
    t->floatargs = tfloatargs;
    t->stringargs = tstringargs;

    return t;
}

//------------------------------------------------------------------------------
Shape::material::material() {
    memset(ka, 0, sizeof(float)*3);
    memset(kd, 0, sizeof(float)*3);
    memset(ks, 0, sizeof(float)*3);
    memset(tf, 0, sizeof(float)*3);
    ns = ni = d = 0.0f;
    illum=0;
}

//------------------------------------------------------------------------------
void Shape::parseMtllib(char const * mtlstr) {

    char * str=const_cast<char *>(mtlstr), line[256];

    material * mtl=0;

    bool done = false;
    float r, g, b, a;
    while (not done) {
        done = sgets(line, sizeof(line), &str)==0;
        char* end = &line[strlen(line)-1];
        if (*end == '\n') *end = '\0'; // strip trailing nl
        switch (line[0]) {
            case 'n': char name[256];
                      if (sscanf(line, "newmtl %s", name) == 1) {
                          mtl = new material;
                          mtl->name = name;
                          mtls.push_back(mtl);
                      } break;
            case 'K': if (sscanf(line+2, " %f %f %f", &r, &g, &b) == 3) {
                          switch (line[1]) {
                              case 'a': mtl->ka[0]=r; mtl->ka[1]=g; mtl->ka[2]=b; break;
                              case 'd': mtl->kd[0]=r; mtl->kd[1]=g; mtl->kd[2]=b; break;
                              case 's': mtl->ks[0]=r; mtl->ks[1]=g; mtl->ks[2]=b; break;
                          }
                      } break;
            case 'N': if (sscanf(line+2, " %f", &a) == 1) {
                          switch (line[1]) {
                              case 's' : mtl->ns = a; break;
                              case 'i' : mtl->ni = a; break;
                          }
                      } break;
            case 'd': if (sscanf(line, "d %f", &a) == 1) {
                          mtl->d = a;
                      } break;
            case 'T': if (line[1]=='f') {
                         if (sscanf(line, "Tf %f %f %f", &r, &g, &b) == 3) {
                             mtl->tf[0]=r; mtl->tf[1]=g; mtl->tf[2]=b;
                         } break;
                      } break;
            case 'i': int illum;
                      if (sscanf(line, "illum %d", &illum) == 1) {
                          mtl->illum = illum;
                      } break;
            case 's': if (sscanf(line, "sharpness %f", &a) == 1) {
                          mtl->sharpness = a;
                      } break;
        }
    }
}

//------------------------------------------------------------------------------
std::string Shape::tag::genTag() const {
    std::stringstream t;

    t<<"\"t \""<<name<<"\" ";

    t<<intargs.size()<<"/"<<floatargs.size()<<"/"<<stringargs.size()<<" ";

    std::copy(intargs.begin(), intargs.end(), std::ostream_iterator<int>(t));
    t<<" ";

    std::copy(floatargs.begin(), floatargs.end(), std::ostream_iterator<float>(t));
    t<<" ";

    std::copy(stringargs.begin(), stringargs.end(), std::ostream_iterator<std::string>(t));
    t<<"\\n\"\n";

    return t.str();
}

//------------------------------------------------------------------------------
std::string Shape::genShape(char const * name) const {
    std::stringstream sh;

    sh<<"static char const * "<<name<<" = \n";

    for (int i=0; i<(int)verts.size(); i+=3)
       sh << "\"v " << verts[i] << " " << verts[i+1] << " " << verts[i+2] <<"\\n\"\n";

    for (int i=0; i<(int)uvs.size(); i+=2)
       sh << "\"vt " << uvs[i] << " " << uvs[i+1] << "\\n\"\n";

    for (int i=0; i<(int)normals.size(); i+=3)
       sh << "\"vn " << normals[i] << " " << normals[i+1] << " " << normals[i+2] <<"\\n\"\n";

    sh << "\"s off\\n\"\n";

    for (int i=0, idx=0; i<(int)nvertsPerFace.size();++i) {
        sh << "\"f ";
        for (int j=0; j<nvertsPerFace[i];++j) {
            int vert = faceverts[idx+j]+1,
                uv = (int)faceuvs.size()>0 ? faceuvs[idx+j]+1 : vert,
                normal = (int)facenormals.size()>0 ? facenormals[idx+j]+1 : vert;
            sh << vert << "/" << uv << "/" << normal << " ";
        }
        sh << "\\n\"\n";
        idx+=nvertsPerFace[i];
    }

    for (int i=0; i<(int)tags.size(); ++i)
        sh << tags[i]->genTag();

    return sh.str();
}

//------------------------------------------------------------------------------
std::string Shape::genObj() const {
    std::stringstream sh;

    sh<<"# This file uses centimeters as units for non-parametric coordinates.\n\n";

    for (int i=0; i<(int)verts.size(); i+=3)
       sh << "v " << verts[i] << " " << verts[i+1] << " " << verts[i+2] <<"\n";

    for (int i=0; i<(int)uvs.size(); i+=2)
       sh << "vt " << uvs[i] << " " << uvs[i+1] << "\n";

    for (int i=0; i<(int)normals.size(); i+=3)
       sh << "vn " << normals[i] << " " << normals[i+1] << " " << normals[i+2] <<"\n";

    for (int i=0, idx=0; i<(int)nvertsPerFace.size();++i) {
        sh << "f ";
        for (int j=0; j<nvertsPerFace[i];++j) {
            int vert = faceverts[idx+j]+1,
                uv = (int)faceuvs.size()>0 ? faceuvs[idx+j]+1 : vert,
                normal = (int)facenormals.size()>0 ? facenormals[idx+j]+1 : vert;
            sh << vert << "/" << uv << "/" << normal << " ";
        }
        sh << "\n";
        idx+=nvertsPerFace[i];
    }

    for (int i=0; i<(int)tags.size(); ++i)
        sh << tags[i]->genTag();

    return sh.str();
}

//------------------------------------------------------------------------------
std::string Shape::genRIB() const {
    std::stringstream rib;

    rib << "HierarchicalSubdivisionMesh \"catmull-clark\" ";

    rib << "[";
    std::copy(nvertsPerFace.begin(), nvertsPerFace.end(), std::ostream_iterator<int>(rib));
    rib << "] ";

    rib << "[";
    std::copy(faceverts.begin(), faceverts.end(), std::ostream_iterator<int>(rib));
    rib << "] ";

    std::stringstream names, nargs, intargs, floatargs, strargs;
    for (int i=0; i<(int)tags.size();) {
        tag * t = tags[i];

        names << t->name;

        nargs << t->intargs.size() << " " << t->floatargs.size() << " " << t->stringargs.size();

        std::copy(t->intargs.begin(), t->intargs.end(), std::ostream_iterator<int>(intargs));

        std::copy(t->floatargs.begin(), t->floatargs.end(), std::ostream_iterator<float>(floatargs));

        std::copy(t->stringargs.begin(), t->stringargs.end(), std::ostream_iterator<std::string>(strargs));

        if (++i<(int)tags.size()) {
            names << " ";
            nargs << " ";
            intargs << " ";
            floatargs << " ";
            strargs << " ";
        }
    }

    rib << "["<<names.str()<<"] " << "["<<nargs.str()<<"] " << "["<<intargs.str()<<"] " << "["<<floatargs.str()<<"] " << "["<<strargs.str()<<"] ";

    rib << "\"P\" [";
    std::copy(verts.begin(), verts.end(), std::ostream_iterator<float>(rib));
    rib << "] ";

    return rib.str();
}
<|endoftext|>


<commit_before>/* Rapicorn C++ Remote Object Programming Extension
 * Copyright (C) 2010 Tim Janik
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * A copy of the GNU Lesser General Public License should ship along
 * with this library; if not, see http://www.gnu.org/copyleft/.
 */
#include "cxx-rope.hh"
using namespace Rapicorn;
#include "cxx-client.hh"        // generated client API
#include <ui/rope.hh>

namespace { // Anonymous

static Application
cxxrope_init_dispatcher (const String         &appname,
                         const vector<String> &cmdline_args)
{
  int cpu = Thread::Self::affinity (1);
  uint64 app_id = rope_thread_start (appname, cmdline_args, cpu);
  if (app_id == 0)
    throw_error ("failed to initialize rapicorn thread");
  // printout ("APPURL: 0x%016llx\n", app_id);
  /* minor hack to create the initial smart handler for an Application */
  Plic::FieldBuffer8 fb (4);
  fb.add_object (uint64 (app_id));
  Plic::FieldBufferReader fbr (fb);
  Application app (*rope_thread_coupler(), fbr);
  return app;
}

} // Anon

int
main (int   argc,
      char *argv[])
{
  const int clockid = CLOCK_REALTIME; // CLOCK_MONOTONIC
  RapicornInitValue ivalues[] = { { NULL } };
  rapicorn_init_core (&argc, &argv, NULL, ivalues);
  vector<String> cmdline_args;
  for (int i = 1; i < argc; i++)
    cmdline_args.push_back (argv[i]);
  Application app = cxxrope_init_dispatcher (argv[0], cmdline_args);
  double calls = 0, slowest = 0, fastest = 9e+9;
  for (uint j = 0; j < 29; j++)
    {
      app.test_counter_set (0);
      struct timespec ts0, ts1;
      const uint count = 7000;
      clock_gettime (clockid, &ts0);
      for (uint i = 0; i < count; i++)
        app.test_counter_inc_fetch ();
      clock_gettime (clockid, &ts1);
      assert (app.test_counter_get() == count);
      double t0 = ts0.tv_sec + ts0.tv_nsec / 1000000000.;
      double t1 = ts1.tv_sec + ts1.tv_nsec / 1000000000.;
      double call1 = (t1 - t0) / count;
      slowest = MAX (slowest, call1 * 1000000.);
      fastest = MIN (fastest, call1 * 1000000.);
      double this_calls = 1 / call1;
      calls = MAX (calls, this_calls);
    }
  double err = (slowest - fastest) / slowest;
  printout ("2way: best: %g calls/s; fastest: %.2fus; slowest: %.2fus; err: %.2f%%\n",
            calls, fastest, slowest, err * 100);
  return 0;
}

// generated client implementation
#define PLIC_COUPLER() (*rope_thread_coupler())
#include "cxx-client.cc"
<commit_msg>ROPE: adaptions to logging changes<commit_after>/* Rapicorn C++ Remote Object Programming Extension
 * Copyright (C) 2010 Tim Janik
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * A copy of the GNU Lesser General Public License should ship along
 * with this library; if not, see http://www.gnu.org/copyleft/.
 */
#include "cxx-rope.hh"
using namespace Rapicorn;
#include "cxx-client.hh"        // generated client API
#include <ui/rope.hh>
#include <stdexcept>

namespace { // Anonymous

static Application
cxxrope_init_dispatcher (const String         &appname,
                         const vector<String> &cmdline_args)
{
  int cpu = Thread::Self::affinity (1);
  uint64 app_id = rope_thread_start (appname, cmdline_args, cpu);
  if (app_id == 0)
    throw std::runtime_error ("failed to initialize rapicorn thread");
  // printout ("APPURL: 0x%016llx\n", app_id);
  /* minor hack to create the initial smart handler for an Application */
  Plic::FieldBuffer8 fb (4);
  fb.add_object (uint64 (app_id));
  Plic::FieldBufferReader fbr (fb);
  Application app (*rope_thread_coupler(), fbr);
  return app;
}

} // Anon

int
main (int   argc,
      char *argv[])
{
  const int clockid = CLOCK_REALTIME; // CLOCK_MONOTONIC
  RapicornInitValue ivalues[] = { { NULL } };
  rapicorn_init_core (&argc, &argv, NULL, ivalues);
  vector<String> cmdline_args;
  for (int i = 1; i < argc; i++)
    cmdline_args.push_back (argv[i]);
  Application app = cxxrope_init_dispatcher (argv[0], cmdline_args);
  double calls = 0, slowest = 0, fastest = 9e+9;
  for (uint j = 0; j < 29; j++)
    {
      app.test_counter_set (0);
      struct timespec ts0, ts1;
      const uint count = 7000;
      clock_gettime (clockid, &ts0);
      for (uint i = 0; i < count; i++)
        app.test_counter_inc_fetch ();
      clock_gettime (clockid, &ts1);
      assert (app.test_counter_get() == count);
      double t0 = ts0.tv_sec + ts0.tv_nsec / 1000000000.;
      double t1 = ts1.tv_sec + ts1.tv_nsec / 1000000000.;
      double call1 = (t1 - t0) / count;
      slowest = MAX (slowest, call1 * 1000000.);
      fastest = MIN (fastest, call1 * 1000000.);
      double this_calls = 1 / call1;
      calls = MAX (calls, this_calls);
    }
  double err = (slowest - fastest) / slowest;
  printout ("2way: best: %g calls/s; fastest: %.2fus; slowest: %.2fus; err: %.2f%%\n",
            calls, fastest, slowest, err * 100);
  return 0;
}

// generated client implementation
#define PLIC_COUPLER() (*rope_thread_coupler())
#include "cxx-client.cc"
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkImageImport.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$
  Thanks:    Thanks to David G. Gobbi who developed this class.

Copyright (c) 1993-1999 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include "vtkByteSwap.h"
#include "vtkImageImport.h"

//----------------------------------------------------------------------------
vtkImageImport::vtkImageImport()
{
  int idx;

  this->ImportVoidPointer = 0;

  this->DataScalarType = VTK_SHORT;
  this->NumberOfScalarComponents = 1;

  for (idx = 0; idx < 3; ++idx)
    {
    this->DataExtent[idx*2] = this->DataExtent[idx*2 + 1] = 0;
    this->DataSpacing[idx] = 1.0;
    this->DataOrigin[idx] = 0.0;
    }
  this->SaveUserArray = 0;
}

//----------------------------------------------------------------------------
vtkImageImport::~vtkImageImport()
{
  if ((this->ImportVoidPointer) && (!this->SaveUserArray))
    {
    delete [] this->ImportVoidPointer;
    }
}

//----------------------------------------------------------------------------
void vtkImageImport::PrintSelf(ostream& os, vtkIndent indent)
{
  int idx;

  vtkImageSource::PrintSelf(os,indent);

  os << indent << "ImportVoidPointer: " << this->ImportVoidPointer << "\n";

  os << indent << "DataScalarType: "
     << vtkImageScalarTypeNameMacro(this->DataScalarType) << "\n";

  os << indent << "NumberOfScalarComponents: "
     << this->NumberOfScalarComponents << "\n";

  os << indent << "DataExtent: (" << this->DataExtent[0];
  for (idx = 1; idx < 6; ++idx)
    {
    os << ", " << this->DataExtent[idx];
    }
  os << ")\n";

  os << indent << "DataSpacing: (" << this->DataSpacing[0];
  for (idx = 1; idx < 3; ++idx)
    {
    os << ", " << this->DataSpacing[idx];
    }
  os << ")\n";

  os << indent << "DataOrigin: (" << this->DataOrigin[0];
  for (idx = 1; idx < 3; ++idx)
    {
    os << ", " << this->DataOrigin[idx];
    }
  os << ")\n";
}

//----------------------------------------------------------------------------
// This method returns the largest data that can be generated.
void vtkImageImport::ExecuteInformation()
{
  vtkImageData *output;
  unsigned long mem;

  // set the extent
  output->SetWholeExtent(this->DataExtent);

  // set the spacing
  output->SetSpacing(this->DataSpacing);

  // set the origin.
  output->SetOrigin(this->DataOrigin);

  // set data type
  output->SetScalarType(this->DataScalarType);
  output->SetNumberOfScalarComponents(this->NumberOfScalarComponents);

  // What if we are trying to process a VERY large 2D image?
  mem = output->GetScalarSize();
  mem = mem * (this->DataExtent[1] - this->DataExtent[0] + 1);
  mem = mem * (this->DataExtent[3] - this->DataExtent[2] + 1);
  mem = mem / 1000;
  mem = mem * (this->DataExtent[5] - this->DataExtent[4] + 1);
  if (mem < 1)
    {
    mem = 1;
    }

  output->SetEstimatedWholeMemorySize(mem);
  // Do not allow less than 1Kb per piece.
  output->SetMaximumNumberOfPieces(mem);
}

//----------------------------------------------------------------------------
// This function reads a data from a file.  The datas extent/axes
// are assumed to be the same as the file extent/order.
void vtkImageImport::Execute(vtkImageData *data)
{
  void *ptr = this->GetImportVoidPointer();
  int size =
    (this->DataExtent[1] - this->DataExtent[0]+1) *
    (this->DataExtent[3] - this->DataExtent[2]+1) *
    (this->DataExtent[5] - this->DataExtent[4]+1) *
    this->NumberOfScalarComponents;
  data->GetPointData()->GetScalars()->GetData()->SetVoidArray(ptr,size,1);
}

void vtkImageImport::CopyImportVoidPointer(void *ptr, int size)
{
  unsigned char *mem = new unsigned char [size];
  memcpy(mem,ptr,size);
  this->SetImportVoidPointer(mem,0);
}

void vtkImageImport::SetImportVoidPointer(void *ptr)
{
  this->SetImportVoidPointer(ptr,1);
}

void vtkImageImport::SetImportVoidPointer(void *ptr, int save)
{
  if (ptr != this->ImportVoidPointer)
    {
    if ((this->ImportVoidPointer) && (!this->SaveUserArray))
      {
      vtkDebugMacro (<< "Deleting the array...");
      delete [] this->ImportVoidPointer;
      }
    else
      {
      vtkDebugMacro (<<"Warning, array not deleted, but will point to new array.");
      }
    this->Modified();
    }
  this->SaveUserArray = save;
  this->ImportVoidPointer = ptr;
}

//----------------------------------------------------------------------------
void vtkImageImport::ModifyOutputUpdateExtent()
{
  int *wholeExtent, updateExtent[6], idx;

  this->GetOutput()->GetUpdateExtent(updateExtent);
  wholeExtent = this->GetOutput()->GetWholeExtent();
  for (idx = 0; idx < 3; ++idx)
    {
    updateExtent[idx*2] = wholeExtent[idx*2];
    updateExtent[idx*2+1] = wholeExtent[idx*2+1];
    }
  this->GetOutput()->SetUpdateExtent(updateExtent);
  this->Modified();
}
<commit_msg>big screw up fixed<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkImageImport.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$
  Thanks:    Thanks to David G. Gobbi who developed this class.

Copyright (c) 1993-1999 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include "vtkByteSwap.h"
#include "vtkImageImport.h"

//----------------------------------------------------------------------------
vtkImageImport::vtkImageImport()
{
  int idx;

  this->ImportVoidPointer = 0;

  this->DataScalarType = VTK_SHORT;
  this->NumberOfScalarComponents = 1;

  for (idx = 0; idx < 3; ++idx)
    {
    this->DataExtent[idx*2] = this->DataExtent[idx*2 + 1] = 0;
    this->DataSpacing[idx] = 1.0;
    this->DataOrigin[idx] = 0.0;
    }
  this->SaveUserArray = 0;
}

//----------------------------------------------------------------------------
vtkImageImport::~vtkImageImport()
{
  if ((this->ImportVoidPointer) && (!this->SaveUserArray))
    {
    delete [] this->ImportVoidPointer;
    }
}

//----------------------------------------------------------------------------
void vtkImageImport::PrintSelf(ostream& os, vtkIndent indent)
{
  int idx;

  vtkImageSource::PrintSelf(os,indent);

  os << indent << "ImportVoidPointer: " << this->ImportVoidPointer << "\n";

  os << indent << "DataScalarType: "
     << vtkImageScalarTypeNameMacro(this->DataScalarType) << "\n";

  os << indent << "NumberOfScalarComponents: "
     << this->NumberOfScalarComponents << "\n";

  os << indent << "DataExtent: (" << this->DataExtent[0];
  for (idx = 1; idx < 6; ++idx)
    {
    os << ", " << this->DataExtent[idx];
    }
  os << ")\n";

  os << indent << "DataSpacing: (" << this->DataSpacing[0];
  for (idx = 1; idx < 3; ++idx)
    {
    os << ", " << this->DataSpacing[idx];
    }
  os << ")\n";

  os << indent << "DataOrigin: (" << this->DataOrigin[0];
  for (idx = 1; idx < 3; ++idx)
    {
    os << ", " << this->DataOrigin[idx];
    }
  os << ")\n";
}

//----------------------------------------------------------------------------
// This method returns the largest data that can be generated.
void vtkImageImport::ExecuteInformation()
{
  vtkImageData *output = this->GetOutput();
  unsigned long mem;

  // set the extent
  output->SetWholeExtent(this->DataExtent);

  // set the spacing
  output->SetSpacing(this->DataSpacing);

  // set the origin.
  output->SetOrigin(this->DataOrigin);

  // set data type
  output->SetScalarType(this->DataScalarType);
  output->SetNumberOfScalarComponents(this->NumberOfScalarComponents);

  // What if we are trying to process a VERY large 2D image?
  mem = output->GetScalarSize();
  mem = mem * (this->DataExtent[1] - this->DataExtent[0] + 1);
  mem = mem * (this->DataExtent[3] - this->DataExtent[2] + 1);
  mem = mem / 1000;
  mem = mem * (this->DataExtent[5] - this->DataExtent[4] + 1);
  if (mem < 1)
    {
    mem = 1;
    }

  output->SetEstimatedWholeMemorySize(mem);
  // Do not allow less than 1Kb per piece.
  output->SetMaximumNumberOfPieces(mem);
}

//----------------------------------------------------------------------------
// This function reads a data from a file.  The datas extent/axes
// are assumed to be the same as the file extent/order.
void vtkImageImport::Execute(vtkImageData *data)
{
  void *ptr = this->GetImportVoidPointer();
  int size =
    (this->DataExtent[1] - this->DataExtent[0]+1) *
    (this->DataExtent[3] - this->DataExtent[2]+1) *
    (this->DataExtent[5] - this->DataExtent[4]+1) *
    this->NumberOfScalarComponents;
  data->GetPointData()->GetScalars()->GetData()->SetVoidArray(ptr,size,1);
}

void vtkImageImport::CopyImportVoidPointer(void *ptr, int size)
{
  unsigned char *mem = new unsigned char [size];
  memcpy(mem,ptr,size);
  this->SetImportVoidPointer(mem,0);
}

void vtkImageImport::SetImportVoidPointer(void *ptr)
{
  this->SetImportVoidPointer(ptr,1);
}

void vtkImageImport::SetImportVoidPointer(void *ptr, int save)
{
  if (ptr != this->ImportVoidPointer)
    {
    if ((this->ImportVoidPointer) && (!this->SaveUserArray))
      {
      vtkDebugMacro (<< "Deleting the array...");
      delete [] this->ImportVoidPointer;
      }
    else
      {
      vtkDebugMacro (<<"Warning, array not deleted, but will point to new array.");
      }
    this->Modified();
    }
  this->SaveUserArray = save;
  this->ImportVoidPointer = ptr;
}

//----------------------------------------------------------------------------
void vtkImageImport::ModifyOutputUpdateExtent()
{
  int *wholeExtent, updateExtent[6], idx;

  this->GetOutput()->GetUpdateExtent(updateExtent);
  wholeExtent = this->GetOutput()->GetWholeExtent();
  for (idx = 0; idx < 3; ++idx)
    {
    updateExtent[idx*2] = wholeExtent[idx*2];
    updateExtent[idx*2+1] = wholeExtent[idx*2+1];
    }
  this->GetOutput()->SetUpdateExtent(updateExtent);
  this->Modified();
}
<|endoftext|>


<commit_before>#include <iostream>
#include <vector>
#include <string>

void incCellValue(char &cellChar)
{
	if (cellChar >= '0' && cellChar <= '9')
		cellChar++;
}

void incAdjacents(std::vector<std::string>& board, int row, int col)
{
	bool hasLeft = col > 0;
	bool hasRight = col < board[row].size() - 1;
	bool hasAbove = row > 0;
	bool hasBelow = row < board.size() - 1;
	if (hasLeft)
	{
		incCellValue(board[row][col - 1]);
		if (hasAbove)
			incCellValue(board[row - 1][col - 1]);
		if (hasBelow)
			incCellValue(board[row + 1][col - 1]);
	}
	if (hasRight)
	{
		incCellValue(board[row][col + 1]);
		if (hasAbove)
			incCellValue(board[row - 1][col + 1]);
		if (hasBelow)
			incCellValue(board[row + 1][col + 1]);
	}
	if (hasAbove)
		incCellValue(board[row - 1][col]);
	if (hasBelow)
		incCellValue(board[row + 1][col]);
}

int main()
{
	int m, n;
	int fieldNumber = 1;
	while (true)
	{
		std::cin >> n >> m;
		if (n == 0 || std::cin.fail())
			break;
		std::cin.ignore();
		std::vector<std::string> board(n);
		for (int i = 0; i < n; i++)
			std::getline(std::cin, board[i]);

		for (int i = 0; i < n; i++)
		{
			std::string &line = board[i];
			for (int j = 0; j < line.size(); j++)
			{
				if (line[j] == '.')
					line[j] = '0';
			}
		}

		for (int i = 0; i < n; i++)
		{
			std::string &line = board[i];
			for (int j = 0; j < line.size(); j++)
                if (line[j] == '*')
                    incAdjacents(board, i, j);
		}

		if (fieldNumber > 1)
			std::cout << std::endl;

		std::cout << "Field #" << fieldNumber << ":" << std::endl;
		for (int i = 0; i < board.size(); i++)
			std::cout << board[i] << std::endl;
		fieldNumber++;
	}
}

<commit_msg>Code formatting corrected.<commit_after>#include <iostream>
#include <vector>
#include <string>

void incCellValue(char &cellChar)
{
	if (cellChar >= '0' && cellChar <= '9')
		cellChar++;
}

void incAdjacents(std::vector<std::string>& board, int row, int col)
{
	bool hasLeft = col > 0;
	bool hasRight = col < board[row].size() - 1;
	bool hasAbove = row > 0;
	bool hasBelow = row < board.size() - 1;
	if (hasLeft)
	{
		incCellValue(board[row][col - 1]);
		if (hasAbove)
			incCellValue(board[row - 1][col - 1]);
		if (hasBelow)
			incCellValue(board[row + 1][col - 1]);
	}
	if (hasRight)
	{
		incCellValue(board[row][col + 1]);
		if (hasAbove)
			incCellValue(board[row - 1][col + 1]);
		if (hasBelow)
			incCellValue(board[row + 1][col + 1]);
	}
	if (hasAbove)
		incCellValue(board[row - 1][col]);
	if (hasBelow)
		incCellValue(board[row + 1][col]);
}

int main()
{
	int m, n;
	int fieldNumber = 1;
	while (true)
	{
		std::cin >> n >> m;
		if (n == 0 || std::cin.fail())
			break;
		std::cin.ignore();
		std::vector<std::string> board(n);
		for (int i = 0; i < n; i++)
			std::getline(std::cin, board[i]);

		for (int i = 0; i < n; i++)
		{
			std::string &line = board[i];
			for (int j = 0; j < line.size(); j++)
			{
				if (line[j] == '.')
					line[j] = '0';
			}
		}

		for (int i = 0; i < n; i++)
		{
			std::string &line = board[i];
			for (int j = 0; j < line.size(); j++)
				if (line[j] == '*')
					incAdjacents(board, i, j);
		}

		if (fieldNumber > 1)
			std::cout << std::endl;

		std::cout << "Field #" << fieldNumber << ":" << std::endl;
		for (int i = 0; i < board.size(); i++)
			std::cout << board[i] << std::endl;
		fieldNumber++;
	}
}

<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "remoting/host/encoder_verbatim.h"

#include "gfx/rect.h"
#include "media/base/data_buffer.h"
#include "remoting/base/protocol/chromotocol.pb.h"

namespace remoting {

using media::DataBuffer;

void EncoderVerbatim::Encode(const DirtyRects& dirty_rects,
                             const uint8* const* input_data,
                             const int* strides,
                             bool key_frame,
                             DataAvailableCallback* data_available_callback) {
  int num_rects = dirty_rects.size();
  for (int i = 0; i < num_rects; i++) {
    scoped_refptr<DataBuffer> data;
    gfx::Rect dirty_rect = dirty_rects[i];
    scoped_ptr<UpdateStreamPacketHeader> header(new UpdateStreamPacketHeader);
    if (EncodeRect(dirty_rect,
                   input_data,
                   strides,
                   header.get(),
                   &data)) {
      EncodingState state = EncodingInProgress;
      if (i == 0) {
        state |= EncodingStarting;
      } else if (i == num_rects - 1) {
        state |= EncodingEnded;
      }
      data_available_callback->Run(header.release(),
                                   data,
                                   state);
    }
  }

  delete data_available_callback;
}

void EncoderVerbatim::SetSize(int width, int height) {
  width_ = width;
  height_ = height;
}

void EncoderVerbatim::SetPixelFormat(PixelFormat pixel_format) {
  // These are sorted so that the most common formats are checked first.
  // TODO(hclam): Extract this into a util function.
  if (pixel_format == PixelFormatRgb24) {
    bytes_per_pixel_ = 3;
  } else if (pixel_format == PixelFormatRgb565) {
    bytes_per_pixel_ = 2;
  } else if (pixel_format == PixelFormatRgb32) {
    bytes_per_pixel_ = 4;
  } else if (pixel_format != PixelFormatAscii) {
    bytes_per_pixel_ = 1;
  } else {
    NOTREACHED() << "Pixel format not supported";
  }
  pixel_format_ = pixel_format;
}

bool EncoderVerbatim::EncodeRect(const gfx::Rect& dirty,
                                 const uint8* const* input_data,
                                 const int* strides,
                                 UpdateStreamPacketHeader *header,
                                 scoped_refptr<DataBuffer>* output_data) {
  const int kPlanes = 3;

  // Calculate the size of output.
  int output_size = 0;
  for (int i = 0; i < kPlanes; ++i) {
    // TODO(hclam): Handle YUV since the height would be different.
    output_size += strides[i] * height_;
  }

  header->set_x(dirty.x());
  header->set_y(dirty.y());
  header->set_width(dirty.width());
  header->set_height(dirty.height());
  header->set_encoding(EncodingNone);
  header->set_pixel_format(pixel_format_);

  *output_data = new DataBuffer(new uint8[output_size], output_size);
  uint8* out = (*output_data)->GetWritableData();

  for (int i = 0; i < kPlanes; ++i) {
    const uint8* in = input_data[i];
    // Skip over planes that don't have data.
    if (!in)
      continue;

    // TODO(hclam): Handle YUV since the height would be different.
    for (int j = 0; j < height_; ++j) {
      int row_size = width_ * bytes_per_pixel_;
      DCHECK_LE(row_size, strides[i]);
      memcpy(out, in, row_size);
      in += strides[i];
      out += row_size;
    }
  }
  return true;
}

}  // namespace remoting
<commit_msg>remoting: Use GetBytesPerPixel util function in one more place.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "remoting/host/encoder_verbatim.h"

#include "gfx/rect.h"
#include "media/base/data_buffer.h"
#include "remoting/base/protocol_util.h"

namespace remoting {

using media::DataBuffer;

void EncoderVerbatim::Encode(const DirtyRects& dirty_rects,
                             const uint8* const* input_data,
                             const int* strides,
                             bool key_frame,
                             DataAvailableCallback* data_available_callback) {
  int num_rects = dirty_rects.size();
  for (int i = 0; i < num_rects; i++) {
    scoped_refptr<DataBuffer> data;
    gfx::Rect dirty_rect = dirty_rects[i];
    scoped_ptr<UpdateStreamPacketHeader> header(new UpdateStreamPacketHeader);
    if (EncodeRect(dirty_rect,
                   input_data,
                   strides,
                   header.get(),
                   &data)) {
      EncodingState state = EncodingInProgress;
      if (i == 0) {
        state |= EncodingStarting;
      } else if (i == num_rects - 1) {
        state |= EncodingEnded;
      }
      data_available_callback->Run(header.release(),
                                   data,
                                   state);
    }
  }

  delete data_available_callback;
}

void EncoderVerbatim::SetSize(int width, int height) {
  width_ = width;
  height_ = height;
}

void EncoderVerbatim::SetPixelFormat(PixelFormat pixel_format) {
  bytes_per_pixel_ = GetBytesPerPixel(pixel_format);
  pixel_format_ = pixel_format;
}

bool EncoderVerbatim::EncodeRect(const gfx::Rect& dirty,
                                 const uint8* const* input_data,
                                 const int* strides,
                                 UpdateStreamPacketHeader *header,
                                 scoped_refptr<DataBuffer>* output_data) {
  const int kPlanes = 3;

  // Calculate the size of output.
  int output_size = 0;
  for (int i = 0; i < kPlanes; ++i) {
    // TODO(hclam): Handle YUV since the height would be different.
    output_size += strides[i] * height_;
  }

  header->set_x(dirty.x());
  header->set_y(dirty.y());
  header->set_width(dirty.width());
  header->set_height(dirty.height());
  header->set_encoding(EncodingNone);
  header->set_pixel_format(pixel_format_);

  *output_data = new DataBuffer(new uint8[output_size], output_size);
  uint8* out = (*output_data)->GetWritableData();

  for (int i = 0; i < kPlanes; ++i) {
    const uint8* in = input_data[i];
    // Skip over planes that don't have data.
    if (!in)
      continue;

    // TODO(hclam): Handle YUV since the height would be different.
    for (int j = 0; j < height_; ++j) {
      int row_size = width_ * bytes_per_pixel_;
      DCHECK_LE(row_size, strides[i]);
      memcpy(out, in, row_size);
      in += strides[i];
      out += row_size;
    }
  }
  return true;
}

}  // namespace remoting
<|endoftext|>