<commit_before>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2008 Scientific Computing and Imaging Institute,
   University of Utah.

   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/

/**
  \file    ConsoleOut.cpp
  \author  Jens Krueger
           SCI Institute
           University of Utah
  \date    August 2008
*/

#include <cstring>
#include "ConsoleOut.h"
#include "Basics/Console.h"

/// ANSI escape codes for various colors.
///@{
static const char C_DGRAY[]  = "\033[01;30m";
static const char C_NORM[]   = "\033[00m";
static const char C_RED[]    = "\033[01;31m";
static const char C_YELLOW[] = "\033[01;33m";
static const char C_GREEN[]  = "\033[01;32m";
static const char C_MAG[]    = "\033[01;35m";
static const char C_LBLUE[]  = "\033[01;36m";
static const char C_WHITE[]  = "\033[01;27m";
///@}

ConsoleOut::ConsoleOut() {
  Message("ConsoleOut::ConsoleOut:","Starting up ConsoleDebug out");
}

ConsoleOut::~ConsoleOut() {
  Message("ConsoleOut::~ConsoleOut:","Shutting down ConsoleDebug out");
}

void ConsoleOut::printf(enum DebugChannel channel, const char* source,
                        const char* msg)
{
  char buff[16384];
  strncpy(buff, msg, 16384);
  ReplaceSpecialChars(buff, 16384);
#ifdef DETECTED_OS_WINDOWS
  Console::printf("%s (%s): %s\n", ChannelToString(channel), source, buff);
#else
  const char *color = C_NORM;
  switch(channel) {
    case CHANNEL_FINAL:   /* FALL THROUGH */
    case CHANNEL_NONE:    color = C_NORM; break;
    case CHANNEL_ERROR:   color = C_RED; break;
    case CHANNEL_WARNING: color = C_YELLOW; break;
    case CHANNEL_MESSAGE: color = C_DGRAY; break;
    case CHANNEL_OTHER:   color = C_LBLUE; break;
  }
  Console::printf("%s%s%s (%s): %s\n", color, ChannelToString(channel), C_NORM,
                  source, buff);
#endif
}
void ConsoleOut::printf(const char *s) const
{
  Console::printf("%s\n", s);
}
<commit_msg>fixed unsafe warning on windows<commit_after>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2008 Scientific Computing and Imaging Institute,
   University of Utah.

   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/

/**
  \file    ConsoleOut.cpp
  \author  Jens Krueger
           SCI Institute
           University of Utah
  \date    August 2008
*/

#include <cstring>
#include "ConsoleOut.h"
#include "Basics/Console.h"

/// ANSI escape codes for various colors.
///@{
static const char C_DGRAY[]  = "\033[01;30m";
static const char C_NORM[]   = "\033[00m";
static const char C_RED[]    = "\033[01;31m";
static const char C_YELLOW[] = "\033[01;33m";
static const char C_GREEN[]  = "\033[01;32m";
static const char C_MAG[]    = "\033[01;35m";
static const char C_LBLUE[]  = "\033[01;36m";
static const char C_WHITE[]  = "\033[01;27m";
///@}

ConsoleOut::ConsoleOut() {
  Message("ConsoleOut::ConsoleOut:","Starting up ConsoleDebug out");
}

ConsoleOut::~ConsoleOut() {
  Message("ConsoleOut::~ConsoleOut:","Shutting down ConsoleDebug out");
}

void ConsoleOut::printf(enum DebugChannel channel, const char* source,
                        const char* msg)
{
  char buff[16384];
#ifdef DETECTED_OS_WINDOWS
  strncpy_s(buff, 16384, msg, 16384);
#else
  strncpy(buff, msg, 16384);
#endif
  ReplaceSpecialChars(buff, 16384);
#ifdef DETECTED_OS_WINDOWS
  Console::printf("%s (%s): %s\n", ChannelToString(channel), source, buff);
#else
  const char *color = C_NORM;
  switch(channel) {
    case CHANNEL_FINAL:   /* FALL THROUGH */
    case CHANNEL_NONE:    color = C_NORM; break;
    case CHANNEL_ERROR:   color = C_RED; break;
    case CHANNEL_WARNING: color = C_YELLOW; break;
    case CHANNEL_MESSAGE: color = C_DGRAY; break;
    case CHANNEL_OTHER:   color = C_LBLUE; break;
  }
  Console::printf("%s%s%s (%s): %s\n", color, ChannelToString(channel), C_NORM,
                  source, buff);
#endif
}
void ConsoleOut::printf(const char *s) const
{
  Console::printf("%s\n", s);
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2005-2008 by Marc Boris Duerner
 *
 * 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.
 *
 * As a special exception, you may use this file as part of a free
 * software library without restriction. Specifically, if other files
 * instantiate templates or use macros or inline functions from this
 * file, or you compile this file and link it with other files to
 * produce an executable, this file does not by itself cause the
 * resulting executable to be covered by the GNU General Public
 * License. This exception does not however invalidate any other
 * reasons why the executable file might be covered by the GNU Library
 * General Public License.
 *
 * 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.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
#include "fileimpl.h"
#include "cxxtools/ioerror.h"
#include "cxxtools/systemerror.h"
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

namespace cxxtools {

// EACCES Permission denied.
// EMFILE Too many file descriptors in use by process.
// ENOENT Directory does not exist, or name is an empty string.
// ENOTDIR name is not a directory.
// EBUSY  pathname is currently in use by the system or some process that prevents its  removal.
// EFAULT pathname points outside your accessible address space.
// EINVAL pathname has .  as last component.
// ELOOP  Too many symbolic links were encountered in resolving pathname.
// ENAMETOOLONG pathname was too long.
// ENOMEM Insufficient kernel memory was available.
// ENOTEMPTY pathname contains entries other than . and .. ; or, pathname has ..  as its final component.
// EPERM  The directory containing pathname has the sticky bit (S_ISVTX) set
// EPERM  The filesystem containing pathname does not support the removal of directories.
// EROFS  pathname refers to a file on a read-only filesystem.
void throwErrno(const std::string& path, const cxxtools::SourceInfo& si)
{
    if(errno == EEXIST)
        throw AccessFailed(path, si);

    switch(errno)
    {
        case EIO:
        case EBADF:
        case EBUSY:
        case ENOSPC:
        case EMLINK:
        case ENOTEMPTY:
        case EXDEV:
            throw IOError( strerror(errno), si );

        case EACCES:
        case EPERM:
        case EROFS:
        case ENXIO:
            throw PermissionDenied(path, si);

        case ELOOP:
        case ENAMETOOLONG:
        case ENOENT:
        case ENOTDIR:
        case EISDIR:
            throw FileNotFound(path, si);

        case ENODEV:
            throw DeviceNotFound(path, si);

       case ENOMEM:
           throw std::bad_alloc();

        default: // EFAULT EMFILE EOVERFLOW
            throw SystemError( strerror(errno), si );
    }
}

void throwFileErrno(const std::string& path, const cxxtools::SourceInfo& si)
{
    switch(errno)
    {
        case ELOOP:
        case ENAMETOOLONG:
        case ENOENT:
        case ENOTDIR:
        case EISDIR:
            throw FileNotFound(path, si);

        default: throwErrno(path, si);
    }
}

std::size_t FileImpl::size(const std::string& path)
{
    struct stat buff;

    if( 0 != stat(path.c_str(), &buff) )
    {
        throwFileErrno(path, CXXTOOLS_SOURCEINFO);
    }

    return buff.st_size;
}

void FileImpl::resize(const std::string& path, std::size_t newSize)
{
    int ret = 0;
    do
    {
        ret = truncate(path.c_str(), newSize);
    }
    while ( ret == EINTR );

    if(ret != 0)
        throwFileErrno( path, CXXTOOLS_SOURCEINFO);
}

void FileImpl::remove(const std::string& path)
{
    if(0 != ::remove(path.c_str()))
        throwFileErrno(path, CXXTOOLS_SOURCEINFO);
}

void FileImpl::move(const std::string& path, const std::string& to)
{
    if( 0 != ::rename(path.c_str(), to.c_str()) )
        throwFileErrno(path, CXXTOOLS_SOURCEINFO);
}

void FileImpl::create(const std::string& path)
{
    int fd = open(path.c_str(), O_RDWR|O_EXCL|O_CREAT, 0777);
    if( fd < 0 )
        throwFileErrno(path, CXXTOOLS_SOURCEINFO);

    ::close(fd);
}

}
<commit_msg>put local functions into anonymous namespace<commit_after>/*
 * Copyright (C) 2005-2008 by Marc Boris Duerner
 *
 * 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.
 *
 * As a special exception, you may use this file as part of a free
 * software library without restriction. Specifically, if other files
 * instantiate templates or use macros or inline functions from this
 * file, or you compile this file and link it with other files to
 * produce an executable, this file does not by itself cause the
 * resulting executable to be covered by the GNU General Public
 * License. This exception does not however invalidate any other
 * reasons why the executable file might be covered by the GNU Library
 * General Public License.
 *
 * 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.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
#include "fileimpl.h"
#include "cxxtools/ioerror.h"
#include "cxxtools/systemerror.h"
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

namespace cxxtools {

namespace {

// EACCES Permission denied.
// EMFILE Too many file descriptors in use by process.
// ENOENT Directory does not exist, or name is an empty string.
// ENOTDIR name is not a directory.
// EBUSY  pathname is currently in use by the system or some process that prevents its  removal.
// EFAULT pathname points outside your accessible address space.
// EINVAL pathname has .  as last component.
// ELOOP  Too many symbolic links were encountered in resolving pathname.
// ENAMETOOLONG pathname was too long.
// ENOMEM Insufficient kernel memory was available.
// ENOTEMPTY pathname contains entries other than . and .. ; or, pathname has ..  as its final component.
// EPERM  The directory containing pathname has the sticky bit (S_ISVTX) set
// EPERM  The filesystem containing pathname does not support the removal of directories.
// EROFS  pathname refers to a file on a read-only filesystem.
void throwErrno(const std::string& path, const cxxtools::SourceInfo& si)
{
    if(errno == EEXIST)
        throw AccessFailed(path, si);

    switch(errno)
    {
        case EIO:
        case EBADF:
        case EBUSY:
        case ENOSPC:
        case EMLINK:
        case ENOTEMPTY:
        case EXDEV:
            throw IOError( strerror(errno), si );

        case EACCES:
        case EPERM:
        case EROFS:
        case ENXIO:
            throw PermissionDenied(path, si);

        case ELOOP:
        case ENAMETOOLONG:
        case ENOENT:
        case ENOTDIR:
        case EISDIR:
            throw FileNotFound(path, si);

        case ENODEV:
            throw DeviceNotFound(path, si);

       case ENOMEM:
           throw std::bad_alloc();

        default: // EFAULT EMFILE EOVERFLOW
            throw SystemError( strerror(errno), si );
    }
}

void throwFileErrno(const std::string& path, const cxxtools::SourceInfo& si)
{
    switch(errno)
    {
        case ELOOP:
        case ENAMETOOLONG:
        case ENOENT:
        case ENOTDIR:
        case EISDIR:
            throw FileNotFound(path, si);

        default: throwErrno(path, si);
    }
}

}

std::size_t FileImpl::size(const std::string& path)
{
    struct stat buff;

    if( 0 != stat(path.c_str(), &buff) )
    {
        throwFileErrno(path, CXXTOOLS_SOURCEINFO);
    }

    return buff.st_size;
}

void FileImpl::resize(const std::string& path, std::size_t newSize)
{
    int ret = 0;
    do
    {
        ret = truncate(path.c_str(), newSize);
    }
    while ( ret == EINTR );

    if(ret != 0)
        throwFileErrno( path, CXXTOOLS_SOURCEINFO);
}

void FileImpl::remove(const std::string& path)
{
    if(0 != ::remove(path.c_str()))
        throwFileErrno(path, CXXTOOLS_SOURCEINFO);
}

void FileImpl::move(const std::string& path, const std::string& to)
{
    if( 0 != ::rename(path.c_str(), to.c_str()) )
        throwFileErrno(path, CXXTOOLS_SOURCEINFO);
}

void FileImpl::create(const std::string& path)
{
    int fd = open(path.c_str(), O_RDWR|O_EXCL|O_CREAT, 0777);
    if( fd < 0 )
        throwFileErrno(path, CXXTOOLS_SOURCEINFO);

    ::close(fd);
}

}
<|endoftext|>


<commit_before>#include "api/plugin_instance.h"
#include "core/core.h"
#include "core/log.h"
#include "core/math.h"
#include "core/plugin_handler.h"
#include "session/session.h"
#include "settings.h"
//#include <imgui.h>
#include "ui/imgui_setup.h"
#include "ui/ui_layout.h"
#include "ui/menu.h"
#include "ui/dialogs.h"

#include <bgfx.h>
#include <bgfxplatform.h>
#include <stdio.h>
#include <stdlib.h>

#ifdef PRODBG_WIN
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif

#include <remotery.h>

// TODO: Fix me

int Window_buildPluginMenu(PluginData** plugins, int count);

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

struct Context
{
    int width;
    int height;
    float mouseX;
    float mouseY;
    int mouseLmb;
    int keyDown;
    int keyMod;
    Session* session;   // one session right now
};

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

static Context s_context;
//Remotery* s_remotery;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

static const char* s_plugins[] =
{
    "sourcecode_plugin",
    "disassembly_plugin",
    "locals_plugin",
    "callstack_plugin",
    "registers_plugin",
    "breakpoints_plugin",
    "hex_memory_plugin",
#ifdef PRODBG_MAC
    "lldb_plugin",
#endif
};

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

static void setLayout(UILayout* layout)
{
    Context* context = &s_context;
    IMGUI_preUpdate(context->mouseX, context->mouseY, context->mouseLmb, context->keyDown, context->keyMod);
    Session_setLayout(context->session, layout, (float)context->width, (float)context->height);
    IMGUI_postUpdate();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void loadLayout()
{
    UILayout layout;

    if (UILayout_loadLayout(&layout, "data/current_layout.json"))
    {
        setLayout(&layout);
        return;
    }

    if (UILayout_loadLayout(&layout, "data/default_layout.json"))
        setLayout(&layout);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_create(void* window, int width, int height)
{
    Context* context = &s_context;
    //Rect settingsRect;

    context->session = Session_create();

	/*
    if (RMT_ERROR_NONE != rmt_CreateGlobalInstance(&s_remotery))
    {
    	log_error("Unable to setup Remotery");
        return;
    }
    */

    //Settings_getWindowRect(&settingsRect);
    //width = settingsRect.width;
    //height = settingsRect.height;

    (void)window;

    for (uint32_t i = 0; i < sizeof_array(s_plugins); ++i)
    {
        PluginHandler_addPlugin(OBJECT_DIR, s_plugins[i]);
    }

#if BX_PLATFORM_OSX
    bgfx::osxSetNSWindow(window);
#elif BX_PLATFORM_WINDOWS
    bgfx::winSetHwnd((HWND)window);
#else
    //bgfx::winSetHwnd(0);
#endif

    bgfx::init();
    bgfx::reset(width, height);
    bgfx::setViewSeq(0, true);

    context->width = width;
    context->height = height;

    IMGUI_setup(width, height);

    loadLayout();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_update()
{
    Context* context = &s_context;

	rmt_ScopedCPUSample(ProDBG_update);

    bgfx::setViewRect(0, 0, 0, (uint16_t)context->width, (uint16_t)context->height);
    bgfx::setViewClear(0, BGFX_CLEAR_COLOR_BIT | BGFX_CLEAR_DEPTH_BIT, 0x101010ff, 1.0f, 0);
    bgfx::submit(0);

	{
		rmt_ScopedCPUSample(IMGUI_preUpdate);
    	IMGUI_preUpdate(context->mouseX, context->mouseY, context->mouseLmb, context->keyDown, context->keyMod);
	}

    // TODO: Support multiple sessions

	{
		rmt_ScopedCPUSample(Session_update);
    	Session_update(context->session);
	}

    /*

       bool show = true;

       ImGui::Begin("ImGui Test", &show, ImVec2(550, 480), true, ImGuiWindowFlags_ShowBorders);

       if (ImGui::Button("Test0r testing!"))
       {
        printf("test\n");
       }

       ImGui::End();
     */

	{
		rmt_ScopedCPUSample(IMGUI_postUpdate);
    	IMGUI_postUpdate();
	}

	{
		rmt_ScopedCPUSample(bgfx_frame);
    	bgfx::frame();
	}
}

// Temprory test for monkey

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_setWindowSize(int width, int height)
{
    Context* context = &s_context;

    context->width = width;
    context->height = height;

    //bgfx::reset(width, height);
    //IMGUI_setup(width, height);
    ProDBG_update();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_applicationLaunched()
{
    int pluginCount = 0;
    printf("building menu!\n");
    Window_buildPluginMenu(PluginHandler_getPlugins(&pluginCount), pluginCount);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_destroy()
{
    UILayout layout;
    Context* context = &s_context;

    //rmt_DestroyGlobalInstance(s_remotery);

    Session_getLayout(context->session, &layout, (float)context->width, (float)context->height);
    UILayout_saveLayout(&layout, "data/current_layout.json");

    Settings_save();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_timedUpdate()
{
    ProDBG_update();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

static void onLoadRunExec(Session* session, const char* filename)
{
    PluginData* pluginData = PluginHandler_findPlugin(0, "lldb_plugin", "LLDB Mac", true);

    if (!pluginData)
    {
        log_error("Unable to find LLDB Mac backend\n");
        return;
    }

    Session_startLocal(session, (PDBackendPlugin*)pluginData->plugin, filename);

    // Temp test
    // Session_startLocal(context->session, (PDBackendPlugin*)pluginData->plugin, "t2-output/macosx-clang-debug-default/ProDBG.app/Contents/MacOS/prodbg");
    // Session_startLocal(context->session, (PDBackendPlugin*)pluginData->plugin, OBJECT_DIR "/crashing_native");
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Events

void ProDBG_event(int eventId)
{
    Context* context = &s_context;

    int count;

    PluginData** pluginsData = PluginHandler_getPlugins(&count);

    // TODO: This code really needs to be made more robust.

    if (eventId >= PRODBG_MENU_PLUGIN_START && eventId < PRODBG_MENU_PLUGIN_START + 9)
    {
        ViewPluginInstance* instance = PluginInstance_createViewPlugin(pluginsData[eventId - PRODBG_MENU_PLUGIN_START]);
        Session_addViewPlugin(context->session, instance);
        return;
    }

    switch (eventId)
    {
        case PRODBG_MENU_FILE_OPEN_AND_RUN_EXE:
        {
            char filename[4096];

            if (Dialog_open(filename))
            {
                onLoadRunExec(context->session, filename);
            }

            break;
        }

        case PRODBG_MENU_FILE_OPEN_SOURCE:
        {
            char filename[4096];

            if (Dialog_open(filename))
            {
                Session_loadSourceFile(context->session, filename);
            }

            break;
        }

        case PRODBG_MENU_DEBUG_BREAK:
        {
            Session_action(context->session, PDAction_break);
            log_info("trying to break...\n");
            break;
        }

        case PRODBG_MENU_DEBUG_ATTACH_TO_REMOTE:
        {
            Session_startRemote(context->session, "127.0.0.1", 1340);
            break;
        }

        case PRODBG_MENU_DEBUG_TOGGLE_BREAKPOINT:
        {
            Session_toggleBreakpointCurrentLine(context->session);
            break;
        }

        case PRODBG_MENU_DEBUG_STEP_OVER:
        {
            Session_stepOver(context->session);
            break;
        }

        case PRODBG_MENU_DEBUG_STEP_IN:
        {
            Session_stepIn(context->session);
            break;
        }
    }
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_scroll(float deltaX, float deltaY, int flags)
{
    (void)deltaX;
    (void)deltaY;
    (void)flags;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_setMousePos(float x, float y)
{
    Context* context = &s_context;

    context->mouseX = x;
    context->mouseY = y;

    IMGUI_setMouse(x, y, context->mouseLmb);

    //ProDBG_update();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_setMouseState(int button, int state)
{
    Context* context = &s_context;
    (void)button;

    context->mouseLmb = state;

    IMGUI_setMouse(context->mouseX, context->mouseY, state);

    //ProDBG_update();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_keyDown(int key, int modifier)
{
    IMGUI_setKeyDown(key, modifier);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_keyUp(int key, int modifier)
{
    IMGUI_setKeyUp(key, modifier);
}

<commit_msg>Register dbgeng_plugin with prodbg<commit_after>#include "api/plugin_instance.h"
#include "core/core.h"
#include "core/log.h"
#include "core/math.h"
#include "core/plugin_handler.h"
#include "session/session.h"
#include "settings.h"
//#include <imgui.h>
#include "ui/imgui_setup.h"
#include "ui/ui_layout.h"
#include "ui/menu.h"
#include "ui/dialogs.h"

#include <bgfx.h>
#include <bgfxplatform.h>
#include <stdio.h>
#include <stdlib.h>

#ifdef PRODBG_WIN
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif

#include <remotery.h>

// TODO: Fix me

int Window_buildPluginMenu(PluginData** plugins, int count);

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

struct Context
{
    int width;
    int height;
    float mouseX;
    float mouseY;
    int mouseLmb;
    int keyDown;
    int keyMod;
    Session* session;   // one session right now
};

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

static Context s_context;
//Remotery* s_remotery;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

static const char* s_plugins[] =
{
    "sourcecode_plugin",
    "disassembly_plugin",
    "locals_plugin",
    "callstack_plugin",
    "registers_plugin",
    "breakpoints_plugin",
    "hex_memory_plugin",
#ifdef PRODBG_MAC
    "lldb_plugin",
#endif
#ifdef PRODBG_WIN
	"dbgeng_plugin",
#endif
};

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

static void setLayout(UILayout* layout)
{
    Context* context = &s_context;
    IMGUI_preUpdate(context->mouseX, context->mouseY, context->mouseLmb, context->keyDown, context->keyMod);
    Session_setLayout(context->session, layout, (float)context->width, (float)context->height);
    IMGUI_postUpdate();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void loadLayout()
{
    UILayout layout;

    if (UILayout_loadLayout(&layout, "data/current_layout.json"))
    {
        setLayout(&layout);
        return;
    }

    if (UILayout_loadLayout(&layout, "data/default_layout.json"))
        setLayout(&layout);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_create(void* window, int width, int height)
{
    Context* context = &s_context;
    //Rect settingsRect;

    context->session = Session_create();

	/*
    if (RMT_ERROR_NONE != rmt_CreateGlobalInstance(&s_remotery))
    {
    	log_error("Unable to setup Remotery");
        return;
    }
    */

    //Settings_getWindowRect(&settingsRect);
    //width = settingsRect.width;
    //height = settingsRect.height;

    (void)window;

    for (uint32_t i = 0; i < sizeof_array(s_plugins); ++i)
    {
        PluginHandler_addPlugin(OBJECT_DIR, s_plugins[i]);
    }

#if BX_PLATFORM_OSX
    bgfx::osxSetNSWindow(window);
#elif BX_PLATFORM_WINDOWS
    bgfx::winSetHwnd((HWND)window);
#else
    //bgfx::winSetHwnd(0);
#endif

    bgfx::init();
    bgfx::reset(width, height);
    bgfx::setViewSeq(0, true);

    context->width = width;
    context->height = height;

    IMGUI_setup(width, height);

    loadLayout();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_update()
{
    Context* context = &s_context;

	rmt_ScopedCPUSample(ProDBG_update);

    bgfx::setViewRect(0, 0, 0, (uint16_t)context->width, (uint16_t)context->height);
    bgfx::setViewClear(0, BGFX_CLEAR_COLOR_BIT | BGFX_CLEAR_DEPTH_BIT, 0x101010ff, 1.0f, 0);
    bgfx::submit(0);

	{
		rmt_ScopedCPUSample(IMGUI_preUpdate);
    	IMGUI_preUpdate(context->mouseX, context->mouseY, context->mouseLmb, context->keyDown, context->keyMod);
	}

    // TODO: Support multiple sessions

	{
		rmt_ScopedCPUSample(Session_update);
    	Session_update(context->session);
	}

    /*

       bool show = true;

       ImGui::Begin("ImGui Test", &show, ImVec2(550, 480), true, ImGuiWindowFlags_ShowBorders);

       if (ImGui::Button("Test0r testing!"))
       {
        printf("test\n");
       }

       ImGui::End();
     */

	{
		rmt_ScopedCPUSample(IMGUI_postUpdate);
    	IMGUI_postUpdate();
	}

	{
		rmt_ScopedCPUSample(bgfx_frame);
    	bgfx::frame();
	}
}

// Temprory test for monkey

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_setWindowSize(int width, int height)
{
    Context* context = &s_context;

    context->width = width;
    context->height = height;

    //bgfx::reset(width, height);
    //IMGUI_setup(width, height);
    ProDBG_update();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_applicationLaunched()
{
    int pluginCount = 0;
    printf("building menu!\n");
    Window_buildPluginMenu(PluginHandler_getPlugins(&pluginCount), pluginCount);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_destroy()
{
    UILayout layout;
    Context* context = &s_context;

    //rmt_DestroyGlobalInstance(s_remotery);

    Session_getLayout(context->session, &layout, (float)context->width, (float)context->height);
    UILayout_saveLayout(&layout, "data/current_layout.json");

    Settings_save();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_timedUpdate()
{
    ProDBG_update();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

static void onLoadRunExec(Session* session, const char* filename)
{
    PluginData* pluginData = PluginHandler_findPlugin(0, "lldb_plugin", "LLDB Mac", true);

    if (!pluginData)
    {
        log_error("Unable to find LLDB Mac backend\n");
        return;
    }

    Session_startLocal(session, (PDBackendPlugin*)pluginData->plugin, filename);

    // Temp test
    // Session_startLocal(context->session, (PDBackendPlugin*)pluginData->plugin, "t2-output/macosx-clang-debug-default/ProDBG.app/Contents/MacOS/prodbg");
    // Session_startLocal(context->session, (PDBackendPlugin*)pluginData->plugin, OBJECT_DIR "/crashing_native");
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Events

void ProDBG_event(int eventId)
{
    Context* context = &s_context;

    int count;

    PluginData** pluginsData = PluginHandler_getPlugins(&count);

    // TODO: This code really needs to be made more robust.

    if (eventId >= PRODBG_MENU_PLUGIN_START && eventId < PRODBG_MENU_PLUGIN_START + 9)
    {
        ViewPluginInstance* instance = PluginInstance_createViewPlugin(pluginsData[eventId - PRODBG_MENU_PLUGIN_START]);
        Session_addViewPlugin(context->session, instance);
        return;
    }

    switch (eventId)
    {
        case PRODBG_MENU_FILE_OPEN_AND_RUN_EXE:
        {
            char filename[4096];

            if (Dialog_open(filename))
            {
                onLoadRunExec(context->session, filename);
            }

            break;
        }

        case PRODBG_MENU_FILE_OPEN_SOURCE:
        {
            char filename[4096];

            if (Dialog_open(filename))
            {
                Session_loadSourceFile(context->session, filename);
            }

            break;
        }

        case PRODBG_MENU_DEBUG_BREAK:
        {
            Session_action(context->session, PDAction_break);
            log_info("trying to break...\n");
            break;
        }

        case PRODBG_MENU_DEBUG_ATTACH_TO_REMOTE:
        {
            Session_startRemote(context->session, "127.0.0.1", 1340);
            break;
        }

        case PRODBG_MENU_DEBUG_TOGGLE_BREAKPOINT:
        {
            Session_toggleBreakpointCurrentLine(context->session);
            break;
        }

        case PRODBG_MENU_DEBUG_STEP_OVER:
        {
            Session_stepOver(context->session);
            break;
        }

        case PRODBG_MENU_DEBUG_STEP_IN:
        {
            Session_stepIn(context->session);
            break;
        }
    }
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_scroll(float deltaX, float deltaY, int flags)
{
    (void)deltaX;
    (void)deltaY;
    (void)flags;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_setMousePos(float x, float y)
{
    Context* context = &s_context;

    context->mouseX = x;
    context->mouseY = y;

    IMGUI_setMouse(x, y, context->mouseLmb);

    //ProDBG_update();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_setMouseState(int button, int state)
{
    Context* context = &s_context;
    (void)button;

    context->mouseLmb = state;

    IMGUI_setMouse(context->mouseX, context->mouseY, state);

    //ProDBG_update();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_keyDown(int key, int modifier)
{
    IMGUI_setKeyDown(key, modifier);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_keyUp(int key, int modifier)
{
    IMGUI_setKeyUp(key, modifier);
}

<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 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 "base/logging.h"
#include "base/scoped_ptr.h"
#include "sandbox/src/sharedmem_ipc_server.h"
#include "sandbox/src/sharedmem_ipc_client.h"
#include "sandbox/src/sandbox.h"
#include "sandbox/src/sandbox_types.h"
#include "sandbox/src/crosscall_params.h"
#include "sandbox/src/crosscall_server.h"

namespace sandbox {

SharedMemIPCServer::SharedMemIPCServer(HANDLE target_process,
                                       DWORD target_process_id,
                                       HANDLE target_job,
                                       ThreadProvider* thread_provider,
                                       Dispatcher* dispatcher)
    : client_control_(NULL),
      thread_provider_(thread_provider),
      target_process_(target_process),
      target_process_id_(target_process_id),
      target_job_object_(target_job),
      call_dispatcher_(dispatcher) {
}

SharedMemIPCServer::~SharedMemIPCServer() {
  // Free the wait handles associated with the thread pool.
  if (!thread_provider_->UnRegisterWaits(this)) {
    // Better to leak than to crash.
    return;
  }
  // Free the IPC signal events.
  ServerContexts::iterator it;
  for (it = server_contexts_.begin(); it != server_contexts_.end(); ++it) {
    ServerControl* context = (*it);
    ::CloseHandle(context->ping_event);
    ::CloseHandle(context->pong_event);
    delete context;
  }
}

bool SharedMemIPCServer::Init(void* shared_mem, size_t shared_size,
                              size_t channel_size) {
  // The shared memory needs to be at least as big as a channel.
  if (shared_size < channel_size) {
    return false;
  }
  // The channel size should be aligned.
  if (0 != (channel_size % 32)) {
    return false;
  }

  // Calculate how many channels we can fit in the shared memory.
  shared_size -= offsetof(IPCControl, channels);
  size_t channel_count = shared_size / (sizeof(ChannelControl) + channel_size);

  // If we cannot fit even one channel we bail out.
  if (0 == channel_count) {
    return false;
  }
  // Calculate the start of the first channel.
  size_t base_start = (sizeof(ChannelControl)* channel_count) +
                       offsetof(IPCControl, channels);

  client_control_ = reinterpret_cast<IPCControl*>(shared_mem);
  client_control_->channels_count = 0;

  // This is the initialization that we do per-channel. Basically:
  // 1) make two events (ping & pong)
  // 2) create handles to the events for the client and the server.
  // 3) initialize the channel (client_context) with the state.
  // 4) initialize the server side of the channel (service_context).
  // 5) call the thread provider RegisterWait to register the ping events.
  for (size_t ix = 0; ix != channel_count; ++ix) {
    ChannelControl* client_context = &client_control_->channels[ix];
    ServerControl* service_context = new ServerControl;
    server_contexts_.push_back(service_context);

    if (!MakeEvents(&service_context->ping_event,
                    &service_context->pong_event,
                    &client_context->ping_event,
                    &client_context->pong_event)) {
      return false;
    }

    client_context->channel_base = base_start;
    client_context->state = kFreeChannel;

    // Note that some of these values are available as members of this
    // object but we put them again into the service_context because we
    // will be called on a static method (ThreadPingEventReady)
    service_context->shared_base = reinterpret_cast<char*>(shared_mem);
    service_context->channel_size = channel_size;
    service_context->channel = client_context;
    service_context->channel_buffer = service_context->shared_base +
                                      client_context->channel_base;
    service_context->dispatcher = call_dispatcher_;
    service_context->target_info.process = target_process_;
    service_context->target_info.process_id = target_process_id_;
    service_context->target_info.job_object = target_job_object_;
    // Advance to the next channel.
    base_start += channel_size;
    // Register the ping event with the threadpool.
    thread_provider_->RegisterWait(this, service_context->ping_event,
                                   ThreadPingEventReady, service_context);
  }

  // We create a mutex that the server locks. If the server dies unexpectedly,
  // the thread that owns it will fail to release the lock and windows will
  // report to the target (when it tries to acquire it) that the wait was
  // abandoned. Note: We purposely leak the local handle because we want it to
  // be closed by Windows itself so it is properly marked as abandoned if the
  // server dies.
  if (!::DuplicateHandle(::GetCurrentProcess(),
                         ::CreateMutexW(NULL, TRUE, NULL),
                         target_process_, &client_control_->server_alive,
                         SYNCHRONIZE | EVENT_MODIFY_STATE, FALSE, 0)) {
    return false;
  }
  // This last setting indicates to the client all is setup.
  client_control_->channels_count = channel_count;
  return true;
}

// Releases memory allocated for IPC arguments, if needed.
void ReleaseArgs(const IPCParams* ipc_params, void* args[kMaxIpcParams]) {
  for (size_t i = 0; i < kMaxIpcParams; i++) {
    if (args[i]) {
      switch (ipc_params->args[i]) {
        case WCHAR_TYPE: {
          delete reinterpret_cast<std::wstring*>(args[i]);
          args[i] = NULL;
          break;
        }
        case INOUTPTR_TYPE: {
          delete reinterpret_cast<CountedBuffer*>(args[i]);
          args[i] = NULL;
          break;
        }
        default: break;
      }
    }
  }
}

// Fills up the list of arguments (args and ipc_params) for an IPC call.
bool GetArgs(CrossCallParamsEx* params, IPCParams* ipc_params,
             void* args[kMaxIpcParams]) {
  if (kMaxIpcParams < params->GetParamsCount())
    return false;

  for (size_t i = 0; i < params->GetParamsCount(); i++) {
    size_t size;
    ArgType type;
    args[i] = params->GetRawParameter(i, &size, &type);
    if (args[i]) {
      ipc_params->args[i] = type;
      switch (type) {
        case WCHAR_TYPE: {
          std::wstring* data = new std::wstring;
          if (!params->GetParameterStr(i, data)) {
            args[i] = 0;
            ReleaseArgs(ipc_params, args);
            return false;
          }
          args[i] = data;
          break;
        }
        case ULONG_TYPE: {
          ULONG data;
          if (!params->GetParameter32(i, &data)) {
            ReleaseArgs(ipc_params, args);
            return false;
          }
          args[i] = bit_cast<void*>(data);
          break;
        }
        case INOUTPTR_TYPE: {
          if (!args[i]) {
            ReleaseArgs(ipc_params, args);
            return false;
          }
          CountedBuffer* buffer = new CountedBuffer(args[i] , size);
          args[i] = buffer;
          break;
        }
        default: break;
      }
    }
  }
  return true;
}

bool SharedMemIPCServer::InvokeCallback(const ServerControl* service_context,
                                        void* ipc_buffer,
                                        CrossCallReturn* call_result) {
  // Set the default error code;
  SetCallError(SBOX_ERROR_INVALID_IPC, call_result);
  size_t output_size = 0;
  // Parse, verify and copy the message. The handler operates on a copy
  // of the message so the client cannot play dirty tricks by changing the
  // data in the channel while the IPC is being processed.
  scoped_ptr<CrossCallParamsEx> params(
      CrossCallParamsEx::CreateFromBuffer(ipc_buffer,
                                          service_context->channel_size,
                                          &output_size));
  if (!params.get())
    return false;

  uint32 tag = params->GetTag();
  COMPILE_ASSERT(0 == INVALID_TYPE, Incorrect_type_enum);
  IPCParams ipc_params = {0} ;
  ipc_params.ipc_tag = tag;

  void* args[kMaxIpcParams];
  if (!GetArgs(params.get(), &ipc_params, args))
    return false;

  IPCInfo ipc_info = {0};
  ipc_info.ipc_tag = tag;
  ipc_info.client_info = &service_context->target_info;
  Dispatcher* dispatcher = service_context->dispatcher;
  DCHECK(dispatcher);
  bool error = true;
  Dispatcher* handler = NULL;

  Dispatcher::CallbackGeneric callback_generic;
  handler = dispatcher->OnMessageReady(&ipc_params, &callback_generic);
  if (handler) {
    switch (params->GetParamsCount()) {
      case 0: {
        // Ask the IPC dispatcher if she can service this IPC.
        Dispatcher::Callback0 callback =
            reinterpret_cast<Dispatcher::Callback0>(callback_generic);
        if (!(handler->*callback)(&ipc_info))
          break;
        error = false;
        break;
      }
      case 1: {
        Dispatcher::Callback1 callback =
            reinterpret_cast<Dispatcher::Callback1>(callback_generic);
        if (!(handler->*callback)(&ipc_info, args[0]))
          break;
        error = false;
        break;
      }
      case 2: {
        Dispatcher::Callback2 callback =
            reinterpret_cast<Dispatcher::Callback2>(callback_generic);
        if (!(handler->*callback)(&ipc_info, args[0], args[1]))
          break;
        error = false;
        break;
      }
      case 3: {
        Dispatcher::Callback3 callback =
            reinterpret_cast<Dispatcher::Callback3>(callback_generic);
        if (!(handler->*callback)(&ipc_info, args[0], args[1], args[2]))
          break;
        error = false;
        break;
      }
      case 4: {
        Dispatcher::Callback4 callback =
            reinterpret_cast<Dispatcher::Callback4>(callback_generic);
        if (!(handler->*callback)(&ipc_info, args[0], args[1], args[2],
                                  args[3]))
          break;
        error = false;
        break;
      }
      case 5: {
        Dispatcher::Callback5 callback =
            reinterpret_cast<Dispatcher::Callback5>(callback_generic);
        if (!(handler->*callback)(&ipc_info, args[0], args[1], args[2], args[3],
                                  args[4]))
          break;
        error = false;
        break;
      }
      case 6: {
        Dispatcher::Callback6 callback =
            reinterpret_cast<Dispatcher::Callback6>(callback_generic);
        if (!(handler->*callback)(&ipc_info, args[0], args[1], args[2], args[3],
                                  args[4], args[5]))
          break;
        error = false;
        break;
      }
      case 7: {
        Dispatcher::Callback7 callback =
            reinterpret_cast<Dispatcher::Callback7>(callback_generic);
        if (!(handler->*callback)(&ipc_info, args[0], args[1], args[2], args[3],
                                  args[4], args[5], args[6]))
          break;
        error = false;
        break;
      }
      case 8: {
        Dispatcher::Callback8 callback =
            reinterpret_cast<Dispatcher::Callback8>(callback_generic);
        if (!(handler->*callback)(&ipc_info, args[0], args[1], args[2], args[3],
                                  args[4], args[5], args[6], args[7]))
          break;
        error = false;
        break;
      }
      case 9: {
        Dispatcher::Callback9 callback =
            reinterpret_cast<Dispatcher::Callback9>(callback_generic);
        if (!(handler->*callback)(&ipc_info, args[0], args[1], args[2], args[3],
                                  args[4], args[5], args[6], args[7], args[8]))
          break;
        error = false;
        break;
      }
      default:  {
        NOTREACHED();
        break;
      }
    }
  }

  if (error) {
    if (handler)
      SetCallError(SBOX_ERROR_FAILED_IPC, call_result);
  } else {
    memcpy(call_result, &ipc_info.return_info, sizeof(*call_result));
    SetCallSuccess(call_result);
    if (params->IsInOut()) {
      // Maybe the params got changed by the broker. We need to upadte the
      // memory section.
      memcpy(ipc_buffer, params.get(), output_size);
    }
  }

  ReleaseArgs(&ipc_params, args);

  return !error;
}

// This function gets called by a thread from the thread pool when a
// ping event fires. The context is the same as passed in the RegisterWait()
// call above.
void __stdcall SharedMemIPCServer::ThreadPingEventReady(void* context,
                                                        unsigned char) {
  if (NULL == context) {
    DCHECK(false);
    return;
  }
  ServerControl* service_context = reinterpret_cast<ServerControl*>(context);
  // Since the event fired, the channel *must* be busy. Change to kAckChannel
  // while we service it.
  LONG last_state =
    ::InterlockedCompareExchange(&service_context->channel->state,
                                 kAckChannel, kBusyChannel);
  if (kBusyChannel != last_state) {
    DCHECK(false);
    return;
  }

  // Prepare the result structure. At this point we will return some result
  // even if the IPC is invalid, malformed or has no handler.
  CrossCallReturn call_result = {0};
  void* buffer = service_context->channel_buffer;

  InvokeCallback(service_context, buffer, &call_result);

  // Copy the answer back into the channel and signal the pong event. This
  // should wake up the client so he can finish the the ipc cycle.
  CrossCallParams* call_params = reinterpret_cast<CrossCallParams*>(buffer);
  memcpy(call_params->GetCallReturn(), &call_result, sizeof(call_result));
  ::InterlockedExchange(&service_context->channel->state, kAckChannel);
  ::SetEvent(service_context->pong_event);
}

bool SharedMemIPCServer::MakeEvents(HANDLE* server_ping, HANDLE* server_pong,
                                    HANDLE* client_ping, HANDLE* client_pong) {
  // Note that the IPC client has no right to delete the events. That would
  // cause problems. The server *owns* the events.
  const DWORD kDesiredAccess = SYNCHRONIZE | EVENT_MODIFY_STATE ;

  // The events are auto reset, and start not signaled.
  *server_ping = ::CreateEventW(NULL, FALSE, FALSE, NULL);
  if (!::DuplicateHandle(::GetCurrentProcess(), *server_ping, target_process_,
                         client_ping, kDesiredAccess, FALSE, 0)) {
    return false;
  }
  *server_pong = ::CreateEventW(NULL, FALSE, FALSE, NULL);
  if (!::DuplicateHandle(::GetCurrentProcess(), *server_pong, target_process_,
                         client_pong, kDesiredAccess, FALSE, 0)) {
    return false;
  }
  return true;
}

}  // namespace sandbox
<commit_msg>Fix potential memleak in GetArgs.<commit_after>// Copyright (c) 2009 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 "base/logging.h"
#include "base/scoped_ptr.h"
#include "sandbox/src/sharedmem_ipc_server.h"
#include "sandbox/src/sharedmem_ipc_client.h"
#include "sandbox/src/sandbox.h"
#include "sandbox/src/sandbox_types.h"
#include "sandbox/src/crosscall_params.h"
#include "sandbox/src/crosscall_server.h"

namespace sandbox {

SharedMemIPCServer::SharedMemIPCServer(HANDLE target_process,
                                       DWORD target_process_id,
                                       HANDLE target_job,
                                       ThreadProvider* thread_provider,
                                       Dispatcher* dispatcher)
    : client_control_(NULL),
      thread_provider_(thread_provider),
      target_process_(target_process),
      target_process_id_(target_process_id),
      target_job_object_(target_job),
      call_dispatcher_(dispatcher) {
}

SharedMemIPCServer::~SharedMemIPCServer() {
  // Free the wait handles associated with the thread pool.
  if (!thread_provider_->UnRegisterWaits(this)) {
    // Better to leak than to crash.
    return;
  }
  // Free the IPC signal events.
  ServerContexts::iterator it;
  for (it = server_contexts_.begin(); it != server_contexts_.end(); ++it) {
    ServerControl* context = (*it);
    ::CloseHandle(context->ping_event);
    ::CloseHandle(context->pong_event);
    delete context;
  }
}

bool SharedMemIPCServer::Init(void* shared_mem, size_t shared_size,
                              size_t channel_size) {
  // The shared memory needs to be at least as big as a channel.
  if (shared_size < channel_size) {
    return false;
  }
  // The channel size should be aligned.
  if (0 != (channel_size % 32)) {
    return false;
  }

  // Calculate how many channels we can fit in the shared memory.
  shared_size -= offsetof(IPCControl, channels);
  size_t channel_count = shared_size / (sizeof(ChannelControl) + channel_size);

  // If we cannot fit even one channel we bail out.
  if (0 == channel_count) {
    return false;
  }
  // Calculate the start of the first channel.
  size_t base_start = (sizeof(ChannelControl)* channel_count) +
                       offsetof(IPCControl, channels);

  client_control_ = reinterpret_cast<IPCControl*>(shared_mem);
  client_control_->channels_count = 0;

  // This is the initialization that we do per-channel. Basically:
  // 1) make two events (ping & pong)
  // 2) create handles to the events for the client and the server.
  // 3) initialize the channel (client_context) with the state.
  // 4) initialize the server side of the channel (service_context).
  // 5) call the thread provider RegisterWait to register the ping events.
  for (size_t ix = 0; ix != channel_count; ++ix) {
    ChannelControl* client_context = &client_control_->channels[ix];
    ServerControl* service_context = new ServerControl;
    server_contexts_.push_back(service_context);

    if (!MakeEvents(&service_context->ping_event,
                    &service_context->pong_event,
                    &client_context->ping_event,
                    &client_context->pong_event)) {
      return false;
    }

    client_context->channel_base = base_start;
    client_context->state = kFreeChannel;

    // Note that some of these values are available as members of this
    // object but we put them again into the service_context because we
    // will be called on a static method (ThreadPingEventReady)
    service_context->shared_base = reinterpret_cast<char*>(shared_mem);
    service_context->channel_size = channel_size;
    service_context->channel = client_context;
    service_context->channel_buffer = service_context->shared_base +
                                      client_context->channel_base;
    service_context->dispatcher = call_dispatcher_;
    service_context->target_info.process = target_process_;
    service_context->target_info.process_id = target_process_id_;
    service_context->target_info.job_object = target_job_object_;
    // Advance to the next channel.
    base_start += channel_size;
    // Register the ping event with the threadpool.
    thread_provider_->RegisterWait(this, service_context->ping_event,
                                   ThreadPingEventReady, service_context);
  }

  // We create a mutex that the server locks. If the server dies unexpectedly,
  // the thread that owns it will fail to release the lock and windows will
  // report to the target (when it tries to acquire it) that the wait was
  // abandoned. Note: We purposely leak the local handle because we want it to
  // be closed by Windows itself so it is properly marked as abandoned if the
  // server dies.
  if (!::DuplicateHandle(::GetCurrentProcess(),
                         ::CreateMutexW(NULL, TRUE, NULL),
                         target_process_, &client_control_->server_alive,
                         SYNCHRONIZE | EVENT_MODIFY_STATE, FALSE, 0)) {
    return false;
  }
  // This last setting indicates to the client all is setup.
  client_control_->channels_count = channel_count;
  return true;
}

// Releases memory allocated for IPC arguments, if needed.
void ReleaseArgs(const IPCParams* ipc_params, void* args[kMaxIpcParams]) {
  for (size_t i = 0; i < kMaxIpcParams; i++) {
    if (args[i]) {
      switch (ipc_params->args[i]) {
        case WCHAR_TYPE: {
          delete reinterpret_cast<std::wstring*>(args[i]);
          args[i] = NULL;
          break;
        }
        case INOUTPTR_TYPE: {
          delete reinterpret_cast<CountedBuffer*>(args[i]);
          args[i] = NULL;
          break;
        }
        default: break;
      }
    }
  }
}

// Fills up the list of arguments (args and ipc_params) for an IPC call.
bool GetArgs(CrossCallParamsEx* params, IPCParams* ipc_params,
             void* args[kMaxIpcParams]) {
  if (kMaxIpcParams < params->GetParamsCount())
    return false;

  for (size_t i = 0; i < params->GetParamsCount(); i++) {
    size_t size;
    ArgType type;
    args[i] = params->GetRawParameter(i, &size, &type);
    if (args[i]) {
      ipc_params->args[i] = type;
      switch (type) {
        case WCHAR_TYPE: {
          scoped_ptr<std::wstring> data(new std::wstring);
          if (!params->GetParameterStr(i, data.get())) {
            args[i] = 0;
            ReleaseArgs(ipc_params, args);
            return false;
          }
          args[i] = data.release();
          break;
        }
        case ULONG_TYPE: {
          ULONG data;
          if (!params->GetParameter32(i, &data)) {
            ReleaseArgs(ipc_params, args);
            return false;
          }
          args[i] = bit_cast<void*>(data);
          break;
        }
        case INOUTPTR_TYPE: {
          if (!args[i]) {
            ReleaseArgs(ipc_params, args);
            return false;
          }
          CountedBuffer* buffer = new CountedBuffer(args[i] , size);
          args[i] = buffer;
          break;
        }
        default: break;
      }
    }
  }
  return true;
}

bool SharedMemIPCServer::InvokeCallback(const ServerControl* service_context,
                                        void* ipc_buffer,
                                        CrossCallReturn* call_result) {
  // Set the default error code;
  SetCallError(SBOX_ERROR_INVALID_IPC, call_result);
  size_t output_size = 0;
  // Parse, verify and copy the message. The handler operates on a copy
  // of the message so the client cannot play dirty tricks by changing the
  // data in the channel while the IPC is being processed.
  scoped_ptr<CrossCallParamsEx> params(
      CrossCallParamsEx::CreateFromBuffer(ipc_buffer,
                                          service_context->channel_size,
                                          &output_size));
  if (!params.get())
    return false;

  uint32 tag = params->GetTag();
  COMPILE_ASSERT(0 == INVALID_TYPE, Incorrect_type_enum);
  IPCParams ipc_params = {0};
  ipc_params.ipc_tag = tag;

  void* args[kMaxIpcParams];
  if (!GetArgs(params.get(), &ipc_params, args))
    return false;

  IPCInfo ipc_info = {0};
  ipc_info.ipc_tag = tag;
  ipc_info.client_info = &service_context->target_info;
  Dispatcher* dispatcher = service_context->dispatcher;
  DCHECK(dispatcher);
  bool error = true;
  Dispatcher* handler = NULL;

  Dispatcher::CallbackGeneric callback_generic;
  handler = dispatcher->OnMessageReady(&ipc_params, &callback_generic);
  if (handler) {
    switch (params->GetParamsCount()) {
      case 0: {
        // Ask the IPC dispatcher if she can service this IPC.
        Dispatcher::Callback0 callback =
            reinterpret_cast<Dispatcher::Callback0>(callback_generic);
        if (!(handler->*callback)(&ipc_info))
          break;
        error = false;
        break;
      }
      case 1: {
        Dispatcher::Callback1 callback =
            reinterpret_cast<Dispatcher::Callback1>(callback_generic);
        if (!(handler->*callback)(&ipc_info, args[0]))
          break;
        error = false;
        break;
      }
      case 2: {
        Dispatcher::Callback2 callback =
            reinterpret_cast<Dispatcher::Callback2>(callback_generic);
        if (!(handler->*callback)(&ipc_info, args[0], args[1]))
          break;
        error = false;
        break;
      }
      case 3: {
        Dispatcher::Callback3 callback =
            reinterpret_cast<Dispatcher::Callback3>(callback_generic);
        if (!(handler->*callback)(&ipc_info, args[0], args[1], args[2]))
          break;
        error = false;
        break;
      }
      case 4: {
        Dispatcher::Callback4 callback =
            reinterpret_cast<Dispatcher::Callback4>(callback_generic);
        if (!(handler->*callback)(&ipc_info, args[0], args[1], args[2],
                                  args[3]))
          break;
        error = false;
        break;
      }
      case 5: {
        Dispatcher::Callback5 callback =
            reinterpret_cast<Dispatcher::Callback5>(callback_generic);
        if (!(handler->*callback)(&ipc_info, args[0], args[1], args[2], args[3],
                                  args[4]))
          break;
        error = false;
        break;
      }
      case 6: {
        Dispatcher::Callback6 callback =
            reinterpret_cast<Dispatcher::Callback6>(callback_generic);
        if (!(handler->*callback)(&ipc_info, args[0], args[1], args[2], args[3],
                                  args[4], args[5]))
          break;
        error = false;
        break;
      }
      case 7: {
        Dispatcher::Callback7 callback =
            reinterpret_cast<Dispatcher::Callback7>(callback_generic);
        if (!(handler->*callback)(&ipc_info, args[0], args[1], args[2], args[3],
                                  args[4], args[5], args[6]))
          break;
        error = false;
        break;
      }
      case 8: {
        Dispatcher::Callback8 callback =
            reinterpret_cast<Dispatcher::Callback8>(callback_generic);
        if (!(handler->*callback)(&ipc_info, args[0], args[1], args[2], args[3],
                                  args[4], args[5], args[6], args[7]))
          break;
        error = false;
        break;
      }
      case 9: {
        Dispatcher::Callback9 callback =
            reinterpret_cast<Dispatcher::Callback9>(callback_generic);
        if (!(handler->*callback)(&ipc_info, args[0], args[1], args[2], args[3],
                                  args[4], args[5], args[6], args[7], args[8]))
          break;
        error = false;
        break;
      }
      default:  {
        NOTREACHED();
        break;
      }
    }
  }

  if (error) {
    if (handler)
      SetCallError(SBOX_ERROR_FAILED_IPC, call_result);
  } else {
    memcpy(call_result, &ipc_info.return_info, sizeof(*call_result));
    SetCallSuccess(call_result);
    if (params->IsInOut()) {
      // Maybe the params got changed by the broker. We need to upadte the
      // memory section.
      memcpy(ipc_buffer, params.get(), output_size);
    }
  }

  ReleaseArgs(&ipc_params, args);

  return !error;
}

// This function gets called by a thread from the thread pool when a
// ping event fires. The context is the same as passed in the RegisterWait()
// call above.
void __stdcall SharedMemIPCServer::ThreadPingEventReady(void* context,
                                                        unsigned char) {
  if (NULL == context) {
    DCHECK(false);
    return;
  }
  ServerControl* service_context = reinterpret_cast<ServerControl*>(context);
  // Since the event fired, the channel *must* be busy. Change to kAckChannel
  // while we service it.
  LONG last_state =
    ::InterlockedCompareExchange(&service_context->channel->state,
                                 kAckChannel, kBusyChannel);
  if (kBusyChannel != last_state) {
    DCHECK(false);
    return;
  }

  // Prepare the result structure. At this point we will return some result
  // even if the IPC is invalid, malformed or has no handler.
  CrossCallReturn call_result = {0};
  void* buffer = service_context->channel_buffer;

  InvokeCallback(service_context, buffer, &call_result);

  // Copy the answer back into the channel and signal the pong event. This
  // should wake up the client so he can finish the the ipc cycle.
  CrossCallParams* call_params = reinterpret_cast<CrossCallParams*>(buffer);
  memcpy(call_params->GetCallReturn(), &call_result, sizeof(call_result));
  ::InterlockedExchange(&service_context->channel->state, kAckChannel);
  ::SetEvent(service_context->pong_event);
}

bool SharedMemIPCServer::MakeEvents(HANDLE* server_ping, HANDLE* server_pong,
                                    HANDLE* client_ping, HANDLE* client_pong) {
  // Note that the IPC client has no right to delete the events. That would
  // cause problems. The server *owns* the events.
  const DWORD kDesiredAccess = SYNCHRONIZE | EVENT_MODIFY_STATE;

  // The events are auto reset, and start not signaled.
  *server_ping = ::CreateEventW(NULL, FALSE, FALSE, NULL);
  if (!::DuplicateHandle(::GetCurrentProcess(), *server_ping, target_process_,
                         client_ping, kDesiredAccess, FALSE, 0)) {
    return false;
  }
  *server_pong = ::CreateEventW(NULL, FALSE, FALSE, NULL);
  if (!::DuplicateHandle(::GetCurrentProcess(), *server_pong, target_process_,
                         client_pong, kDesiredAccess, FALSE, 0)) {
    return false;
  }
  return true;
}

}  // namespace sandbox
<|endoftext|>


<commit_before>/*
 Copyright (C) 2012-2014 Soomla Inc.

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

#include "soomla/domain/CCMarketItem.h"

#include <soomla/CCJsonHelper.h>

USING_NS_CC;

namespace soomla {

CCMarketItem* CCMarketItem::create(const std::string& productId, double price) {
    CCMarketItem* ret = new CCMarketItem();
    if (ret->init(productId, price)) {
        ret->autorelease();
    } else {
        CC_SAFE_DELETE(ret);
    }
    return ret;
}

bool CCMarketItem::init(const std::string& productId, double price) {
    setProductId(productId);
    setPrice(price);
    return true;
}

bool CCMarketItem::initWithValueMap(const cocos2d::ValueMap& dict) {
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
    char const* key = CCStoreConsts::JSON_MARKET_ITEM_ANDROID_ID;
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    char const* key = CCStoreConsts::JSON_MARKET_ITEM_IOS_ID;
#else
    char const* key = CCStoreConsts::JSON_MARKET_ITEM_PRODUCT_ID;
#endif
    CCASSERT(dict.count(key), "invalid object type in dictionary");
    if (dict.count(key)) {
        setProductId(dict.at(key).asString());
    } else {
        fillProductIdFromValueMap(dict);
    }

    fillPriceFromValueMap(dict);

    fillMarketPriceAndCurrencyFromValueMap(dict);
    fillMarketTitleFromValueMap(dict);
    fillMarketDescriptionFromValueMap(dict);
    fillMarketCurrencyCodeFromValueMap(dict);

    if (dict.count(CCStoreConsts::JSON_MARKET_ITEM_MARKET_PRICE_MICROS)) {
        auto item = dict.at(CCStoreConsts::JSON_MARKET_ITEM_MARKET_PRICE_MICROS)
                        .asDouble();
        if (mMarketPriceMicros != item) {
            setMarketPriceMicros(item);
        }
    } else {
        fillMarketPriceMicrosFromValueMap(dict);
    }

    return true;
}

cocos2d::ValueMap CCMarketItem::toValueMap() {
    ValueMap map;

    putProductIdToValueMap(map);
    putPriceToValueMap(map);

    putMarketPriceAndCurrencyToValueMap(map);
    putMarketTitleToValueMap(map);
    putMarketDescriptionToValueMap(map);
    putMarketCurrencyCodeToValueMap(map);
    putMarketPriceMicrosToValueMap(map);

    return putTypeData(map, CCStoreConsts::JSON_JSON_TYPE_MARKET_ITEM);
}

void CCMarketItem::fillProductIdFromValueMap(const cocos2d::ValueMap& map) {
    if (map.count(CCStoreConsts::JSON_MARKET_ITEM_PRODUCT_ID)) {
        setProductId(
            map.at(CCStoreConsts::JSON_MARKET_ITEM_PRODUCT_ID).asString());
    } else {
        setProductId("");
    }
}

void CCMarketItem::putProductIdToValueMap(cocos2d::ValueMap& map) {
    map[CCStoreConsts::JSON_MARKET_ITEM_PRODUCT_ID] = getProductId();
}

void CCMarketItem::fillPriceFromValueMap(const cocos2d::ValueMap& map) {
    if (map.count(CCStoreConsts::JSON_MARKET_ITEM_PRICE)) {
        setPrice(map.at(CCStoreConsts::JSON_MARKET_ITEM_PRICE).asDouble());
    } else {
        setPrice(0.);
    }
}

void CCMarketItem::putPriceToValueMap(cocos2d::ValueMap& map) {
    map[CCStoreConsts::JSON_MARKET_ITEM_PRICE] = getPrice();
}

void CCMarketItem::fillMarketPriceAndCurrencyFromValueMap(
    const cocos2d::ValueMap& map) {
    if (map.count(CCStoreConsts::JSON_MARKET_ITEM_MARKET_PRICE)) {
        setMarketPriceAndCurrency(
            map.at(CCStoreConsts::JSON_MARKET_ITEM_MARKET_PRICE).asString());
    } else {
        setMarketPriceAndCurrency("");
    }
}

void CCMarketItem::putMarketPriceAndCurrencyToValueMap(cocos2d::ValueMap& map) {
    map[CCStoreConsts::JSON_MARKET_ITEM_MARKET_PRICE] =
        getMarketPriceAndCurrency();
}

void CCMarketItem::fillMarketTitleFromValueMap(const cocos2d::ValueMap& map) {
    if (map.count(CCStoreConsts::JSON_MARKET_ITEM_MARKET_TITLE)) {
        setMarketTitle(
            map.at(CCStoreConsts::JSON_MARKET_ITEM_MARKET_TITLE).asString());
    } else {
        setMarketTitle("");
    }
}

void CCMarketItem::putMarketTitleToValueMap(cocos2d::ValueMap& map) {
    map[CCStoreConsts::JSON_MARKET_ITEM_MARKET_TITLE] = getMarketTitle();
}

void CCMarketItem::fillMarketDescriptionFromValueMap(
    const cocos2d::ValueMap& map) {
    if (map.count(CCStoreConsts::JSON_MARKET_ITEM_MARKET_DESCRIPTION)) {
        setMarketDescription(
            map.at(CCStoreConsts::JSON_MARKET_ITEM_MARKET_DESCRIPTION)
                .asString());
    } else {
        setMarketDescription("");
    }
}

void CCMarketItem::putMarketDescriptionToValueMap(cocos2d::ValueMap& map) {
    map[CCStoreConsts::JSON_MARKET_ITEM_MARKET_DESCRIPTION] =
        getMarketDescription();
}

void CCMarketItem::fillMarketCurrencyCodeFromValueMap(
    const cocos2d::ValueMap& map) {
    if (map.count(CCStoreConsts::JSON_MARKET_ITEM_MARKET_CURRENCY_CODE)) {
        setMarketCurrencyCode(
            map.at(CCStoreConsts::JSON_MARKET_ITEM_MARKET_CURRENCY_CODE)
                .asString());
    } else {
        setMarketCurrencyCode("");
    }
}

void CCMarketItem::putMarketCurrencyCodeToValueMap(cocos2d::ValueMap& map) {
    map[CCStoreConsts::JSON_MARKET_ITEM_MARKET_CURRENCY_CODE] =
        getMarketCurrencyCode();
}

void CCMarketItem::fillMarketPriceMicrosFromValueMap(
    const cocos2d::ValueMap& map) {
    if (map.count(CCStoreConsts::JSON_MARKET_ITEM_MARKET_PRICE_MICROS)) {
        setMarketPriceMicros(
            map.at(CCStoreConsts::JSON_MARKET_ITEM_MARKET_PRICE_MICROS)
                .asDouble());
    } else {
        setMarketPriceMicros(0.);
    }
}

void CCMarketItem::putMarketPriceMicrosToValueMap(cocos2d::ValueMap& map) {
    map[CCStoreConsts::JSON_MARKET_ITEM_MARKET_PRICE_MICROS] =
        getMarketPriceMicros();
}
}; // namespace soomla
<commit_msg>Fix assertions in soomla.<commit_after>/*
 Copyright (C) 2012-2014 Soomla Inc.

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

#include "soomla/domain/CCMarketItem.h"

#include <soomla/CCJsonHelper.h>

USING_NS_CC;

namespace soomla {

CCMarketItem* CCMarketItem::create(const std::string& productId, double price) {
    CCMarketItem* ret = new CCMarketItem();
    if (ret->init(productId, price)) {
        ret->autorelease();
    } else {
        CC_SAFE_DELETE(ret);
    }
    return ret;
}

bool CCMarketItem::init(const std::string& productId, double price) {
    setProductId(productId);
    setPrice(price);
    return true;
}

bool CCMarketItem::initWithValueMap(const cocos2d::ValueMap& dict) {
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
    char const* key = CCStoreConsts::JSON_MARKET_ITEM_ANDROID_ID;
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    char const* key = CCStoreConsts::JSON_MARKET_ITEM_IOS_ID;
#else
    char const* key = CCStoreConsts::JSON_MARKET_ITEM_PRODUCT_ID;
#endif
    // FIXME: ??? Always assertions.
    // CCASSERT(dict.count(key), "invalid object type in dictionary");
    if (dict.count(key)) {
        setProductId(dict.at(key).asString());
    } else {
        fillProductIdFromValueMap(dict);
    }

    fillPriceFromValueMap(dict);

    fillMarketPriceAndCurrencyFromValueMap(dict);
    fillMarketTitleFromValueMap(dict);
    fillMarketDescriptionFromValueMap(dict);
    fillMarketCurrencyCodeFromValueMap(dict);

    if (dict.count(CCStoreConsts::JSON_MARKET_ITEM_MARKET_PRICE_MICROS)) {
        auto item = dict.at(CCStoreConsts::JSON_MARKET_ITEM_MARKET_PRICE_MICROS)
                        .asDouble();
        if (mMarketPriceMicros != item) {
            setMarketPriceMicros(item);
        }
    } else {
        fillMarketPriceMicrosFromValueMap(dict);
    }

    return true;
}

cocos2d::ValueMap CCMarketItem::toValueMap() {
    ValueMap map;

    putProductIdToValueMap(map);
    putPriceToValueMap(map);

    putMarketPriceAndCurrencyToValueMap(map);
    putMarketTitleToValueMap(map);
    putMarketDescriptionToValueMap(map);
    putMarketCurrencyCodeToValueMap(map);
    putMarketPriceMicrosToValueMap(map);

    return putTypeData(map, CCStoreConsts::JSON_JSON_TYPE_MARKET_ITEM);
}

void CCMarketItem::fillProductIdFromValueMap(const cocos2d::ValueMap& map) {
    if (map.count(CCStoreConsts::JSON_MARKET_ITEM_PRODUCT_ID)) {
        setProductId(
            map.at(CCStoreConsts::JSON_MARKET_ITEM_PRODUCT_ID).asString());
    } else {
        setProductId("");
    }
}

void CCMarketItem::putProductIdToValueMap(cocos2d::ValueMap& map) {
    map[CCStoreConsts::JSON_MARKET_ITEM_PRODUCT_ID] = getProductId();
}

void CCMarketItem::fillPriceFromValueMap(const cocos2d::ValueMap& map) {
    if (map.count(CCStoreConsts::JSON_MARKET_ITEM_PRICE)) {
        setPrice(map.at(CCStoreConsts::JSON_MARKET_ITEM_PRICE).asDouble());
    } else {
        setPrice(0.);
    }
}

void CCMarketItem::putPriceToValueMap(cocos2d::ValueMap& map) {
    map[CCStoreConsts::JSON_MARKET_ITEM_PRICE] = getPrice();
}

void CCMarketItem::fillMarketPriceAndCurrencyFromValueMap(
    const cocos2d::ValueMap& map) {
    if (map.count(CCStoreConsts::JSON_MARKET_ITEM_MARKET_PRICE)) {
        setMarketPriceAndCurrency(
            map.at(CCStoreConsts::JSON_MARKET_ITEM_MARKET_PRICE).asString());
    } else {
        setMarketPriceAndCurrency("");
    }
}

void CCMarketItem::putMarketPriceAndCurrencyToValueMap(cocos2d::ValueMap& map) {
    map[CCStoreConsts::JSON_MARKET_ITEM_MARKET_PRICE] =
        getMarketPriceAndCurrency();
}

void CCMarketItem::fillMarketTitleFromValueMap(const cocos2d::ValueMap& map) {
    if (map.count(CCStoreConsts::JSON_MARKET_ITEM_MARKET_TITLE)) {
        setMarketTitle(
            map.at(CCStoreConsts::JSON_MARKET_ITEM_MARKET_TITLE).asString());
    } else {
        setMarketTitle("");
    }
}

void CCMarketItem::putMarketTitleToValueMap(cocos2d::ValueMap& map) {
    map[CCStoreConsts::JSON_MARKET_ITEM_MARKET_TITLE] = getMarketTitle();
}

void CCMarketItem::fillMarketDescriptionFromValueMap(
    const cocos2d::ValueMap& map) {
    if (map.count(CCStoreConsts::JSON_MARKET_ITEM_MARKET_DESCRIPTION)) {
        setMarketDescription(
            map.at(CCStoreConsts::JSON_MARKET_ITEM_MARKET_DESCRIPTION)
                .asString());
    } else {
        setMarketDescription("");
    }
}

void CCMarketItem::putMarketDescriptionToValueMap(cocos2d::ValueMap& map) {
    map[CCStoreConsts::JSON_MARKET_ITEM_MARKET_DESCRIPTION] =
        getMarketDescription();
}

void CCMarketItem::fillMarketCurrencyCodeFromValueMap(
    const cocos2d::ValueMap& map) {
    if (map.count(CCStoreConsts::JSON_MARKET_ITEM_MARKET_CURRENCY_CODE)) {
        setMarketCurrencyCode(
            map.at(CCStoreConsts::JSON_MARKET_ITEM_MARKET_CURRENCY_CODE)
                .asString());
    } else {
        setMarketCurrencyCode("");
    }
}

void CCMarketItem::putMarketCurrencyCodeToValueMap(cocos2d::ValueMap& map) {
    map[CCStoreConsts::JSON_MARKET_ITEM_MARKET_CURRENCY_CODE] =
        getMarketCurrencyCode();
}

void CCMarketItem::fillMarketPriceMicrosFromValueMap(
    const cocos2d::ValueMap& map) {
    if (map.count(CCStoreConsts::JSON_MARKET_ITEM_MARKET_PRICE_MICROS)) {
        setMarketPriceMicros(
            map.at(CCStoreConsts::JSON_MARKET_ITEM_MARKET_PRICE_MICROS)
                .asDouble());
    } else {
        setMarketPriceMicros(0.);
    }
}

void CCMarketItem::putMarketPriceMicrosToValueMap(cocos2d::ValueMap& map) {
    map[CCStoreConsts::JSON_MARKET_ITEM_MARKET_PRICE_MICROS] =
        getMarketPriceMicros();
}
}; // namespace soomla
<|endoftext|>


<commit_before>
//
// This source file is part of appleseed.
// Visit http://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2014-2015 Esteban Tovagliari, The appleseedhq Organization
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

// appleseed.foundation headers.
#include "foundation/platform/sharedlibrary.h"
#include "foundation/utility/test.h"

using namespace foundation;

TEST_SUITE(Foundation_Platform_SharedLibrary)
{

#if defined _WIN32
    const char* TestLibraryName = "kernel32.dll";
    const char* TestSymbolName = "LoadLibraryA";
#elif defined __APPLE__
    const char* TestLibraryName = "libc.dylib";
    const char* TestSymbolName = "printf";
#else
    const char* TestLibraryName = "libc.so";
    const char* TestSymbolName = "printf";
#endif

    TEST_CASE(LoadSystemLibAndGetSymbol)
    {
        const SharedLibrary lib(TestLibraryName);

        void* symbol = lib.get_symbol(TestSymbolName, false);

        EXPECT_NEQ(0, symbol);
    }

    TEST_CASE(CannotLoadSharedLibrary)
    {
        EXPECT_EXCEPTION(
            ExceptionCannotLoadSharedLib,
            SharedLibrary("LibraryDoesNotExist"));
    }

    TEST_CASE(CannotGetSymbol_ThrowExceptionIsTrue)
    {
        const SharedLibrary lib(TestLibraryName);

        EXPECT_EXCEPTION(
            ExceptionSharedLibCannotGetSymbol,
            lib.get_symbol("SymbolDoesNotExist", false));
    }

    TEST_CASE(CannotGetSymbol_ThrowExceptionIsFalse)
    {
        const SharedLibrary lib(TestLibraryName);

        void* symbol = lib.get_symbol("SymbolDoesNotExist");

        EXPECT_EQ(0, symbol);
    }
}
<commit_msg>Fix shared library unit tests on Linux<commit_after>
//
// This source file is part of appleseed.
// Visit http://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2014-2015 Esteban Tovagliari, The appleseedhq Organization
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

// appleseed.foundation headers.
#include "foundation/platform/sharedlibrary.h"
#include "foundation/utility/test.h"

using namespace foundation;

TEST_SUITE(Foundation_Platform_SharedLibrary)
{

#if defined _WIN32
    const char* TestLibraryName = "kernel32.dll";
    const char* TestSymbolName = "LoadLibraryA";
#elif defined __APPLE__
    const char* TestLibraryName = "libc.dylib";
    const char* TestSymbolName = "printf";
#else
    const char* TestLibraryName = "libdl.so";
    const char* TestSymbolName = "dlopen";
#endif

    TEST_CASE(LoadSystemLibAndGetSymbol)
    {
        const SharedLibrary lib(TestLibraryName);

        void* symbol = lib.get_symbol(TestSymbolName, false);

        EXPECT_NEQ(0, symbol);
    }

    TEST_CASE(CannotLoadSharedLibrary)
    {
        EXPECT_EXCEPTION(
            ExceptionCannotLoadSharedLib,
            SharedLibrary("LibraryDoesNotExist"));
    }

    TEST_CASE(CannotGetSymbol_ThrowExceptionIsTrue)
    {
        const SharedLibrary lib(TestLibraryName);

        EXPECT_EXCEPTION(
            ExceptionSharedLibCannotGetSymbol,
            lib.get_symbol("SymbolDoesNotExist", false));
    }

    TEST_CASE(CannotGetSymbol_ThrowExceptionIsFalse)
    {
        const SharedLibrary lib(TestLibraryName);

        void* symbol = lib.get_symbol("SymbolDoesNotExist");

        EXPECT_EQ(0, symbol);
    }
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: xlstream.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 19:09:58 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// ============================================================================

#ifndef SC_XLSTREAM_HXX
#include "xlstream.hxx"
#endif

// Encryption/decryption ======================================================

const ByteString XclCryptoHelper::GetBiff5WbProtPassword()
{
    static const ByteString saPass( "VelvetSweatshop" );
    return saPass;
}

const String XclCryptoHelper::GetBiff8WbProtPassword()
{
    static const String saPass( GetBiff5WbProtPassword(), RTL_TEXTENCODING_ASCII_US );
    return saPass;
}

// ============================================================================

<commit_msg>INTEGRATION: CWS pchfix01 (1.3.216); FILE MERGED 2006/07/12 10:01:57 kaib 1.3.216.1: #i67080# Converted cxx files in sc, added initial project level pch and stripped old PCH definitions.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: xlstream.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: kz $ $Date: 2006-07-21 12:20:54 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"

// ============================================================================

#ifndef SC_XLSTREAM_HXX
#include "xlstream.hxx"
#endif

// Encryption/decryption ======================================================

const ByteString XclCryptoHelper::GetBiff5WbProtPassword()
{
    static const ByteString saPass( "VelvetSweatshop" );
    return saPass;
}

const String XclCryptoHelper::GetBiff8WbProtPassword()
{
    static const String saPass( GetBiff5WbProtPassword(), RTL_TEXTENCODING_ASCII_US );
    return saPass;
}

// ============================================================================

<|endoftext|>