<commit_before>#include <cassert>
#include <iostream>

#include <libport/containers.hh>
#include <libport/debug.hh>
#include <libport/windows.hh>
#include <libport/unistd.h>

#ifndef WIN32
# include <syslog.h>
# include <pthread.h>
#endif

#ifndef LIBPORT_DEBUG_DISABLE

namespace libport
{

  namespace debug
  {
    categories_type& get_categories()
    {
      static categories_type categories;
      return categories;
    }

    int add_category(const std::string& name)
    {
      get_categories()[name] = true;
      return 42;
    }

    int enable_category(const std::string& name)
    {
      get_categories()[name] = true;
      return 42;
    }

    int disable_category(const std::string& name)
    {
      get_categories()[name] = false;
      return 42;
    }

    bool test_category(const std::string& name)
    {
      return get_categories()[name];
    }
  }

  Debug::Debug()
    : categories_stack_()
    , level_stack_()
    , locations_(getenv("GD_LOC"))
    , timestamps_(getenv("GD_TIME"))
    , filter_(1)
  {
    push_level(1);
    if (const char* lvl_c = getenv("GD_LEVEL"))
    {
      std::string lvl = lvl_c;
      if (lvl == "NONE")
        filter_ = 0;
      else if (lvl == "LOG")
        filter_ = 1;
      else if (lvl == "TRACE")
        filter_ = 2;
      else if (lvl == "DEBUG")
        filter_ = 3;
      else if (lvl == "DUMP")
        filter_ = 4;
      else
        // Don't use GD_ABORT here, we're in the debugger constructor!
        assert(!"invalid debug level (NONE, LOG, TRACE, DEBUG, DUMP)");
    }
  }

  Debug::~Debug()
  {}

  void
  Debug::filter(unsigned lvl)
  {
    filter_ = lvl;
  }

  void
  Debug::debug(const std::string& msg,
               types::Type type,
               const std::string& fun,
               const std::string& file,
               unsigned line)
  {
    if (disabled())
      return;
    message(msg, type, fun, file, line);
  }

  libport::Finally::action_type
  Debug::push_category(const std::string& category)
  {
    categories_stack_.push_back(category);
    return boost::bind(&Debug::pop_category, this);
  }

  libport::Finally::action_type
  Debug::push_level(unsigned lvl)
  {
    level_stack_.push_back(lvl);
    return boost::bind(&Debug::pop_level, this);
  }

  bool
  Debug::disabled()
  {
    return !debug::test_category(category()) || level_stack_.back() > filter_;
  }

  static void noop()
  {}

  libport::Finally::action_type
  Debug::push(const std::string& msg,
              const std::string& fun,
              const std::string& file,
              unsigned line)
  {
    if (disabled())
      return noop;
    message_push(msg, fun, file, line);
    return boost::bind(&Debug::pop, this);
  }

  void
  Debug::pop_category()
  {
    categories_stack_.pop_back();
  }

  void
  Debug::pop_level()
  {
    level_stack_.pop_back();
  }

  std::string
  Debug::category()
  {
    assert(!categories_stack_.empty());
    return categories_stack_.back();
  }

#define ATTRIBUTE(Name)                         \
                                                \
  void Debug::Name(bool v)                      \
  {                                             \
    Name##_ = v;                                \
  }                                             \
                                                \
  bool Debug::Name()                            \
  {                                             \
    return Name##_;                             \
  }                                             \

  ATTRIBUTE(locations);
  ATTRIBUTE(timestamps);

#undef ATTRIBUTE

  void Debug::abort(const std::string& msg)
  {
    GD_ERROR(msg);
    std::abort();
    throw 0;
  }

  ConsoleDebug::ConsoleDebug()
    : indent_(0)
  {}

  static void show_time()
  {
    time_t     now;
    struct tm  *ts;
    char       buf[80];

    now = time(NULL);
    ts = localtime(&now);
    strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", ts);
    std::cerr << buf;
  }

  void
  ConsoleDebug::color(int color, bool bold)
  {
    static bool tty = isatty(STDOUT_FILENO);
    static boost::format format("[33;0%s;%sm");
    if (tty)
      std::cerr << str(format % (bold ? 1 : 0) % color);
  }

  void
  ConsoleDebug::reset()
  {
    color(0);
  }

  static Debug::colors::Color
  msg_color(Debug::types::Type type)
  {
    switch (type)
    {
      case Debug::types::info:
        return Debug::colors::white;
      case Debug::types::warn:
        return Debug::colors::yellow;
      case Debug::types::error:
        return Debug::colors::red;
    };
    GD_UNREACHABLE();
  }

  void
  ConsoleDebug::message(const std::string& msg,
                        types::Type type,
                        const std::string& fun,
                        const std::string& file,
                        unsigned line)
  {
    Debug::colors::Color c = msg_color(type);
    if (timestamps())
    {
      color(c);
      show_time();
      std::cerr << "    ";
    }
    color(colors::purple);
    std::cerr << "[" << category() << "] ";
    {
      static bool pid = getenv("GD_PID");
      if (pid)
        std::cerr << "[" << getpid() << "] ";
    }
#ifndef WIN32
    {
      static bool thread = getenv("GD_THREAD");
      if (thread)
        std::cerr << "[" << pthread_self() << "] ";
    }
#endif
    color(c);
    for (unsigned i = 0; i < indent_; ++i)
      std::cerr << " ";
    std::cerr << msg;
    if (locations())
    {
      color(colors::blue);
      std::cerr << "    (" << fun << ", " << file << ":" << line << ")";
    }
    std::cerr << std::endl;
  }

  void
  ConsoleDebug::message_push(const std::string& msg,
                             const std::string& fun,
                             const std::string& file,
                             unsigned line)
  {
    debug(msg, types::info, fun, file, line);
    indent_ += 2;
  }

  void
  ConsoleDebug::pop()
  {
    indent_ -= 2;
  }

  std::string gd_ihexdump(const unsigned char* data, unsigned size)
  {
    std::string res;
    bool first = true;
    for (unsigned i = 0; i < size; ++i)
    {
      if (first)
        first = false;
      else
        res += " ";
      static boost::format format("0x%x");
      // This is sick, but we have to cast to int, or boost::format
      // will print the character.
      res += str(format % static_cast<unsigned int>(data[i]));
    }
    return res;
  }

#ifndef WIN32
  /*-------------.
  | Syslog debug |
  `-------------*/

  SyslogDebug::SyslogDebug(const std::string& program)
  {
    static boost::format format("Opening syslog session for '%s'");

    openlog(strdup(program.c_str()), LOG_PID, LOG_DAEMON);
    syslog(LOG_INFO | LOG_DAEMON, "%s", (format % program).str().c_str());
  }

  SyslogDebug::~SyslogDebug()
  {
    syslog(LOG_INFO | LOG_DAEMON, "Closing syslog session.");
    closelog();
  }

  static
  int type_to_prio(Debug::types::Type t)
  {
    switch (t)
    {
#define CASE(In, Out)                           \
      case Debug::types::In: return Out; break
      CASE(info,  LOG_INFO);
      CASE(warn,  LOG_WARNING);
      CASE(error, LOG_ERR);
      // Pacify Gcc.
    }
    abort();
#undef CASE
  }

  void
  SyslogDebug::message(const std::string& msg,
                        types::Type type,
                        const std::string& fun,
                        const std::string& file,
                        unsigned line)
  {
    std::stringstream s;
    s << "[" << category() << "] ";
    for (unsigned i = 0; i < indent_; ++i)
      s << " ";
    s << msg;
    if (locations())
      s << "    (" << fun << ", " << file << ":" << line << ")";
    int prio = type_to_prio(type) | LOG_DAEMON;
    syslog(prio, "%s", s.str().c_str());
  }

  void
  SyslogDebug::message_push(const std::string& msg,
                             const std::string& fun,
                             const std::string& file,
                             unsigned line)
  {
    debug(msg, types::info, fun, file, line);
    indent_ += 2;
  }

  void
  SyslogDebug::pop()
  {
    indent_ -= 2;
  }
#endif

  boost::function0<Debug*> make_debugger;

  Debug* debugger()
  {
#ifndef WIN32
    static std::map<pthread_t, Debug*> debuggers;
    pthread_t id = pthread_self();
    if (!libport::mhas(debuggers, id))
      debuggers[id] = make_debugger();
    return debuggers[id];
#else
    static Debug* debug = make_debugger();
    return debug;
#endif
  }

}

#endif
<commit_msg>Debug: do not use static boost::format in multithread context.<commit_after>#include <cassert>
#include <iostream>

#include <libport/containers.hh>
#include <libport/debug.hh>
#include <libport/windows.hh>
#include <libport/unistd.h>

#ifndef WIN32
# include <syslog.h>
# include <pthread.h>
#endif

#ifndef LIBPORT_DEBUG_DISABLE

namespace libport
{

  namespace debug
  {
    categories_type& get_categories()
    {
      static categories_type categories;
      return categories;
    }

    int add_category(const std::string& name)
    {
      get_categories()[name] = true;
      return 42;
    }

    int enable_category(const std::string& name)
    {
      get_categories()[name] = true;
      return 42;
    }

    int disable_category(const std::string& name)
    {
      get_categories()[name] = false;
      return 42;
    }

    bool test_category(const std::string& name)
    {
      return get_categories()[name];
    }
  }

  Debug::Debug()
    : categories_stack_()
    , level_stack_()
    , locations_(getenv("GD_LOC"))
    , timestamps_(getenv("GD_TIME"))
    , filter_(1)
  {
    push_level(1);
    if (const char* lvl_c = getenv("GD_LEVEL"))
    {
      std::string lvl = lvl_c;
      if (lvl == "NONE")
        filter_ = 0;
      else if (lvl == "LOG")
        filter_ = 1;
      else if (lvl == "TRACE")
        filter_ = 2;
      else if (lvl == "DEBUG")
        filter_ = 3;
      else if (lvl == "DUMP")
        filter_ = 4;
      else
        // Don't use GD_ABORT here, we're in the debugger constructor!
        assert(!"invalid debug level (NONE, LOG, TRACE, DEBUG, DUMP)");
    }
  }

  Debug::~Debug()
  {}

  void
  Debug::filter(unsigned lvl)
  {
    filter_ = lvl;
  }

  void
  Debug::debug(const std::string& msg,
               types::Type type,
               const std::string& fun,
               const std::string& file,
               unsigned line)
  {
    if (disabled())
      return;
    message(msg, type, fun, file, line);
  }

  libport::Finally::action_type
  Debug::push_category(const std::string& category)
  {
    categories_stack_.push_back(category);
    return boost::bind(&Debug::pop_category, this);
  }

  libport::Finally::action_type
  Debug::push_level(unsigned lvl)
  {
    level_stack_.push_back(lvl);
    return boost::bind(&Debug::pop_level, this);
  }

  bool
  Debug::disabled()
  {
    return !debug::test_category(category()) || level_stack_.back() > filter_;
  }

  static void noop()
  {}

  libport::Finally::action_type
  Debug::push(const std::string& msg,
              const std::string& fun,
              const std::string& file,
              unsigned line)
  {
    if (disabled())
      return noop;
    message_push(msg, fun, file, line);
    return boost::bind(&Debug::pop, this);
  }

  void
  Debug::pop_category()
  {
    categories_stack_.pop_back();
  }

  void
  Debug::pop_level()
  {
    level_stack_.pop_back();
  }

  std::string
  Debug::category()
  {
    assert(!categories_stack_.empty());
    return categories_stack_.back();
  }

#define ATTRIBUTE(Name)                         \
                                                \
  void Debug::Name(bool v)                      \
  {                                             \
    Name##_ = v;                                \
  }                                             \
                                                \
  bool Debug::Name()                            \
  {                                             \
    return Name##_;                             \
  }                                             \

  ATTRIBUTE(locations);
  ATTRIBUTE(timestamps);

#undef ATTRIBUTE

  void Debug::abort(const std::string& msg)
  {
    GD_ERROR(msg);
    std::abort();
    throw 0;
  }

  ConsoleDebug::ConsoleDebug()
    : indent_(0)
  {}

  static void show_time()
  {
    time_t     now;
    struct tm  *ts;
    char       buf[80];

    now = time(NULL);
    ts = localtime(&now);
    strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", ts);
    std::cerr << buf;
  }

  void
  ConsoleDebug::color(int color, bool bold)
  {
    static bool tty = isatty(STDOUT_FILENO);
    boost::format format("[33;0%s;%sm");
    if (tty)
      std::cerr << str(format % (bold ? 1 : 0) % color);
  }

  void
  ConsoleDebug::reset()
  {
    color(0);
  }

  static Debug::colors::Color
  msg_color(Debug::types::Type type)
  {
    switch (type)
    {
      case Debug::types::info:
        return Debug::colors::white;
      case Debug::types::warn:
        return Debug::colors::yellow;
      case Debug::types::error:
        return Debug::colors::red;
    };
    GD_UNREACHABLE();
  }

  void
  ConsoleDebug::message(const std::string& msg,
                        types::Type type,
                        const std::string& fun,
                        const std::string& file,
                        unsigned line)
  {
    Debug::colors::Color c = msg_color(type);
    if (timestamps())
    {
      color(c);
      show_time();
      std::cerr << "    ";
    }
    color(colors::purple);
    std::cerr << "[" << category() << "] ";
    {
      static bool pid = getenv("GD_PID");
      if (pid)
        std::cerr << "[" << getpid() << "] ";
    }
#ifndef WIN32
    {
      static bool thread = getenv("GD_THREAD");
      if (thread)
        std::cerr << "[" << pthread_self() << "] ";
    }
#endif
    color(c);
    for (unsigned i = 0; i < indent_; ++i)
      std::cerr << " ";
    std::cerr << msg;
    if (locations())
    {
      color(colors::blue);
      std::cerr << "    (" << fun << ", " << file << ":" << line << ")";
    }
    std::cerr << std::endl;
  }

  void
  ConsoleDebug::message_push(const std::string& msg,
                             const std::string& fun,
                             const std::string& file,
                             unsigned line)
  {
    debug(msg, types::info, fun, file, line);
    indent_ += 2;
  }

  void
  ConsoleDebug::pop()
  {
    indent_ -= 2;
  }

  std::string gd_ihexdump(const unsigned char* data, unsigned size)
  {
    std::string res;
    bool first = true;
    for (unsigned i = 0; i < size; ++i)
    {
      if (first)
        first = false;
      else
        res += " ";
      boost::format format("0x%x");
      // This is sick, but we have to cast to int, or boost::format
      // will print the character.
      res += str(format % static_cast<unsigned int>(data[i]));
    }
    return res;
  }

#ifndef WIN32
  /*-------------.
  | Syslog debug |
  `-------------*/

  SyslogDebug::SyslogDebug(const std::string& program)
  {
    boost::format format("Opening syslog session for '%s'");

    openlog(strdup(program.c_str()), LOG_PID, LOG_DAEMON);
    syslog(LOG_INFO | LOG_DAEMON, "%s", (format % program).str().c_str());
  }

  SyslogDebug::~SyslogDebug()
  {
    syslog(LOG_INFO | LOG_DAEMON, "Closing syslog session.");
    closelog();
  }

  static
  int type_to_prio(Debug::types::Type t)
  {
    switch (t)
    {
#define CASE(In, Out)                           \
      case Debug::types::In: return Out; break
      CASE(info,  LOG_INFO);
      CASE(warn,  LOG_WARNING);
      CASE(error, LOG_ERR);
      // Pacify Gcc.
    }
    abort();
#undef CASE
  }

  void
  SyslogDebug::message(const std::string& msg,
                        types::Type type,
                        const std::string& fun,
                        const std::string& file,
                        unsigned line)
  {
    std::stringstream s;
    s << "[" << category() << "] ";
    for (unsigned i = 0; i < indent_; ++i)
      s << " ";
    s << msg;
    if (locations())
      s << "    (" << fun << ", " << file << ":" << line << ")";
    int prio = type_to_prio(type) | LOG_DAEMON;
    syslog(prio, "%s", s.str().c_str());
  }

  void
  SyslogDebug::message_push(const std::string& msg,
                             const std::string& fun,
                             const std::string& file,
                             unsigned line)
  {
    debug(msg, types::info, fun, file, line);
    indent_ += 2;
  }

  void
  SyslogDebug::pop()
  {
    indent_ -= 2;
  }
#endif

  boost::function0<Debug*> make_debugger;

  Debug* debugger()
  {
#ifndef WIN32
    static std::map<pthread_t, Debug*> debuggers;
    pthread_t id = pthread_self();
    if (!libport::mhas(debuggers, id))
      debuggers[id] = make_debugger();
    return debuggers[id];
#else
    static Debug* debug = make_debugger();
    return debug;
#endif
  }

}

#endif
<|endoftext|>


<commit_before>/******************************************************************************
 * ois_bind.cpp - bindings for OIS
 ******************************************************************************
 * This file is part of
 *     __ __              _
 *    / // /_____ ____   (_)
 *   / // // ___// __ \ / /
 *  / // // /__ / /_/ // /
 * /_//_/ \___/ \____//_/
 *
 * Low Level C Ogre Interface (llcoi)
 *
 * See http://code.google.com/p/llcoi/ for more information.
 *
 * Copyright (c) 2011, Llcoi Team
 *
 * License: MIT
 *
 * 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.
 ******************************************************************************/
#include "ogre_interface.h"
#include "ois_interface.h"
#include "binding_utils.h" // ois_mouse_event_to_llcoi_mouse_event

#include <OISMouse.h>
#include <OISKeyboard.h>
#include <OISJoyStick.h>
#include <OISInputManager.h>

InputSystemHandle create_input_system(unsigned int window_handle)
{
	OIS::InputManager* input = OIS::InputManager::createInputSystem(window_handle);
    return reinterpret_cast<InputSystemHandle>(input);
}

InputSystemHandle create_input_system_ex(ParamListHandle handle)
{
    OIS::ParamList* paramlist = reinterpret_cast<OIS::ParamList*>(handle);
    OIS::InputManager* input = OIS::InputManager::createInputSystem(*paramlist);
    return reinterpret_cast<InputSystemHandle>(input);
}

void destroy_input_system(InputSystemHandle handle)
{
    OIS::InputManager* input = reinterpret_cast<OIS::InputManager*>(handle);
	OIS::InputManager::destroyInputSystem(input);
}

MouseInputHandle create_mouse_object(InputSystemHandle handle, int buffered)
{
    OIS::InputManager* input = reinterpret_cast<OIS::InputManager*>(handle);
	OIS::Mouse* mouse = static_cast<OIS::Mouse*>(input->createInputObject( OIS::OISMouse, (bool)buffered ));
	return reinterpret_cast<MouseInputHandle>(mouse);
}

KeyboardInputHandle create_keyboard_object(InputSystemHandle handle, int buffered)
{
    OIS::InputManager* input = reinterpret_cast<OIS::InputManager*>(handle);
    OIS::Keyboard* keyboard = static_cast<OIS::Keyboard*>(input->createInputObject( OIS::OISKeyboard, (bool)buffered ));
	return reinterpret_cast<KeyboardInputHandle>(keyboard);
}

void destroy_mouse_object(InputSystemHandle handle, MouseInputHandle mouse_handle)
{
    OIS::InputManager* input = reinterpret_cast<OIS::InputManager*>(handle);
	OIS::Mouse* mouse = reinterpret_cast<OIS::Mouse*>(mouse_handle);
	input->destroyInputObject(mouse);
}

void destroy_keyboard_object(InputSystemHandle handle, KeyboardInputHandle keyboard_handle)
{
    OIS::InputManager* input = reinterpret_cast<OIS::InputManager*>(handle);
	OIS::Keyboard* keyboard = reinterpret_cast<OIS::Keyboard*>(keyboard_handle);
	input->destroyInputObject(keyboard);
}

int keyboard_is_key_down(KeyboardInputHandle keyboard_handle, enum KeyCode key_code)
{
    OIS::Keyboard* keyboard = reinterpret_cast<OIS::Keyboard*>(keyboard_handle);
    if(keyboard->isKeyDown((OIS::KeyCode)key_code))
        return 1;
    return 0;
}

int keyboard_is_modifier_down(KeyboardInputHandle keyboard_handle, Key_Modifier key_modifier)
{
    OIS::Keyboard* keyboard = reinterpret_cast<OIS::Keyboard*>(keyboard_handle);
    if(keyboard->isModifierDown((OIS::Keyboard::Modifier)key_modifier))
        return 1;
    return 0;
}

MouseState mouse_get_state(MouseInputHandle mouse_handle)
{
    OIS::Mouse* mouse = reinterpret_cast<OIS::Mouse*>(mouse_handle);
    OIS::MouseState state = mouse->getMouseState();
    MouseState out_state;
    out_state.buttons = state.buttons;
    out_state.height = state.height;
    out_state.width = state.width;
    out_state.X.abs = state.X.abs;
    out_state.X.rel = state.X.rel;
    out_state.X.absOnly = state.X.absOnly;
    out_state.Y.abs = state.Y.abs;
    out_state.Y.rel = state.Y.rel;
    out_state.Y.absOnly = state.Y.absOnly;
    out_state.Z.abs = state.Z.abs;
    out_state.Z.rel = state.Z.rel;
    out_state.Z.absOnly = state.Z.absOnly;
    return out_state;
}

void mouse_set_buffered(MouseInputHandle mouse_handle, int buffered)
{
    OIS::Mouse* mouse = reinterpret_cast<OIS::Mouse*>(mouse_handle);
    mouse->setBuffered((bool)buffered);
}

void keyboard_set_buffered(KeyboardInputHandle keyboard_handle, int buffered)
{
    OIS::Keyboard* keyboard = reinterpret_cast<OIS::Keyboard*>(keyboard_handle);
    keyboard->setBuffered((bool)buffered);
}

void keyboard_capture(KeyboardInputHandle keyboard_handle)
{
    OIS::Keyboard* keyboard = reinterpret_cast<OIS::Keyboard*>(keyboard_handle);
    keyboard->capture();
}

void mouse_capture(MouseInputHandle mouse_handle)
{
    OIS::Mouse* mouse = reinterpret_cast<OIS::Mouse*>(mouse_handle);
    mouse->capture();
}

ParamListHandle ois_create_paramlist()
{
    OIS::ParamList* paramlist = new OIS::ParamList;
    return reinterpret_cast<ParamListHandle>(paramlist);
}

void ois_destroy_paramlist(ParamListHandle handle)
{
    OIS::ParamList* paramlist = reinterpret_cast<OIS::ParamList*>(handle);
    delete paramlist;
}

void ois_add_pair(ParamListHandle handle, const char* field, const char* value)
{
    OIS::ParamList* paramlist = reinterpret_cast<OIS::ParamList*>(handle);
    paramlist->insert(
        std::make_pair(
            std::string(field), std::string(value)
        )
    );
}

class MouseListenerCTX : public OIS::MouseListener
{
public:
    MouseListenerCTX(MouseMovedEvent _moved, MousePressedEvent _pressed, MouseReleasedEvent _released, void* data) :
                     moved(_moved), pressed(_pressed), released(_released), userdata(data)
    {
    }

    bool mouseMoved(const OIS::MouseEvent &arg)
    {
        MouseEvent evt;

        // Convert OIS MouseEvent to LLCOI MouseEvent
        ois_mouse_event_to_llcoi_mouse_event(&arg, &evt);

        // Fire off the callback.
        return moved(&evt, userdata);
    }

    bool mousePressed(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
    {
        MouseEvent evt;
        MouseButtonID llcoi_id;

        // Convert OIS MouseEvent to LLCOI MouseEvent
        ois_mouse_event_to_llcoi_mouse_event(&arg, &evt);

        llcoi_id = ois_mbid_to_llcoi_mbid(id);

        // Fire off the callback.
        pressed(&evt, llcoi_id, userdata);
    }

    bool mouseReleased(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
    {
        MouseEvent evt;
        MouseButtonID llcoi_id;

        // Convert OIS MouseEvent to LLCOI MouseEvent
        ois_mouse_event_to_llcoi_mouse_event(&arg, &evt);

        llcoi_id = ois_mbid_to_llcoi_mbid(id);

        // Fire off the callback.
        return released(&evt, llcoi_id, userdata);
    }

    MouseMovedEvent moved;
    MousePressedEvent pressed;
    MouseReleasedEvent released;

    void* userdata;
};

MouseListenerHandle mouse_set_event_callback(MouseInputHandle handle, MouseMovedEvent moved, MousePressedEvent pressed, MouseReleasedEvent released, void* userdata)
{
    OIS::Mouse* mouse = reinterpret_cast<OIS::Mouse*>(handle);
    MouseListenerCTX* listener = new MouseListenerCTX(moved, pressed, released, userdata);
    mouse->setEventCallback(listener);
    return reinterpret_cast<MouseListenerHandle>(listener);
}

void mouse_remove_event_callback(MouseInputHandle mouse_handle, MouseListenerHandle handle)
{
    OIS::Mouse* mouse          = reinterpret_cast<OIS::Mouse*>(mouse_handle);
    MouseListenerCTX* listener = reinterpret_cast<MouseListenerCTX*>(handle);
    mouse->setEventCallback(0);
    delete listener;
}
<commit_msg>tweaking mouse event callbacks<commit_after>/******************************************************************************
 * ois_bind.cpp - bindings for OIS
 ******************************************************************************
 * This file is part of
 *     __ __              _
 *    / // /_____ ____   (_)
 *   / // // ___// __ \ / /
 *  / // // /__ / /_/ // /
 * /_//_/ \___/ \____//_/
 *
 * Low Level C Ogre Interface (llcoi)
 *
 * See http://code.google.com/p/llcoi/ for more information.
 *
 * Copyright (c) 2011, Llcoi Team
 *
 * License: MIT
 *
 * 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.
 ******************************************************************************/
#include "ogre_interface.h"
#include "ois_interface.h"
#include "binding_utils.h" // ois_mouse_event_to_llcoi_mouse_event

#include <OISMouse.h>
#include <OISKeyboard.h>
#include <OISJoyStick.h>
#include <OISInputManager.h>

InputSystemHandle create_input_system(unsigned int window_handle)
{
	OIS::InputManager* input = OIS::InputManager::createInputSystem(window_handle);
    return reinterpret_cast<InputSystemHandle>(input);
}

InputSystemHandle create_input_system_ex(ParamListHandle handle)
{
    OIS::ParamList* paramlist = reinterpret_cast<OIS::ParamList*>(handle);
    OIS::InputManager* input = OIS::InputManager::createInputSystem(*paramlist);
    return reinterpret_cast<InputSystemHandle>(input);
}

void destroy_input_system(InputSystemHandle handle)
{
    OIS::InputManager* input = reinterpret_cast<OIS::InputManager*>(handle);
	OIS::InputManager::destroyInputSystem(input);
}

MouseInputHandle create_mouse_object(InputSystemHandle handle, int buffered)
{
    OIS::InputManager* input = reinterpret_cast<OIS::InputManager*>(handle);
	OIS::Mouse* mouse = static_cast<OIS::Mouse*>(input->createInputObject( OIS::OISMouse, (bool)buffered ));
	return reinterpret_cast<MouseInputHandle>(mouse);
}

KeyboardInputHandle create_keyboard_object(InputSystemHandle handle, int buffered)
{
    OIS::InputManager* input = reinterpret_cast<OIS::InputManager*>(handle);
    OIS::Keyboard* keyboard = static_cast<OIS::Keyboard*>(input->createInputObject( OIS::OISKeyboard, (bool)buffered ));
	return reinterpret_cast<KeyboardInputHandle>(keyboard);
}

void destroy_mouse_object(InputSystemHandle handle, MouseInputHandle mouse_handle)
{
    OIS::InputManager* input = reinterpret_cast<OIS::InputManager*>(handle);
	OIS::Mouse* mouse = reinterpret_cast<OIS::Mouse*>(mouse_handle);
	input->destroyInputObject(mouse);
}

void destroy_keyboard_object(InputSystemHandle handle, KeyboardInputHandle keyboard_handle)
{
    OIS::InputManager* input = reinterpret_cast<OIS::InputManager*>(handle);
	OIS::Keyboard* keyboard = reinterpret_cast<OIS::Keyboard*>(keyboard_handle);
	input->destroyInputObject(keyboard);
}

int keyboard_is_key_down(KeyboardInputHandle keyboard_handle, enum KeyCode key_code)
{
    OIS::Keyboard* keyboard = reinterpret_cast<OIS::Keyboard*>(keyboard_handle);
    if(keyboard->isKeyDown((OIS::KeyCode)key_code))
        return 1;
    return 0;
}

int keyboard_is_modifier_down(KeyboardInputHandle keyboard_handle, Key_Modifier key_modifier)
{
    OIS::Keyboard* keyboard = reinterpret_cast<OIS::Keyboard*>(keyboard_handle);
    if(keyboard->isModifierDown((OIS::Keyboard::Modifier)key_modifier))
        return 1;
    return 0;
}

MouseState mouse_get_state(MouseInputHandle mouse_handle)
{
    OIS::Mouse* mouse = reinterpret_cast<OIS::Mouse*>(mouse_handle);
    OIS::MouseState state = mouse->getMouseState();
    MouseState out_state;
    out_state.buttons = state.buttons;
    out_state.height = state.height;
    out_state.width = state.width;
    out_state.X.abs = state.X.abs;
    out_state.X.rel = state.X.rel;
    out_state.X.absOnly = state.X.absOnly;
    out_state.Y.abs = state.Y.abs;
    out_state.Y.rel = state.Y.rel;
    out_state.Y.absOnly = state.Y.absOnly;
    out_state.Z.abs = state.Z.abs;
    out_state.Z.rel = state.Z.rel;
    out_state.Z.absOnly = state.Z.absOnly;
    return out_state;
}

void mouse_set_buffered(MouseInputHandle mouse_handle, int buffered)
{
    OIS::Mouse* mouse = reinterpret_cast<OIS::Mouse*>(mouse_handle);
    mouse->setBuffered((bool)buffered);
}

void keyboard_set_buffered(KeyboardInputHandle keyboard_handle, int buffered)
{
    OIS::Keyboard* keyboard = reinterpret_cast<OIS::Keyboard*>(keyboard_handle);
    keyboard->setBuffered((bool)buffered);
}

void keyboard_capture(KeyboardInputHandle keyboard_handle)
{
    OIS::Keyboard* keyboard = reinterpret_cast<OIS::Keyboard*>(keyboard_handle);
    keyboard->capture();
}

void mouse_capture(MouseInputHandle mouse_handle)
{
    OIS::Mouse* mouse = reinterpret_cast<OIS::Mouse*>(mouse_handle);
    mouse->capture();
}

ParamListHandle ois_create_paramlist()
{
    OIS::ParamList* paramlist = new OIS::ParamList;
    return reinterpret_cast<ParamListHandle>(paramlist);
}

void ois_destroy_paramlist(ParamListHandle handle)
{
    OIS::ParamList* paramlist = reinterpret_cast<OIS::ParamList*>(handle);
    delete paramlist;
}

void ois_add_pair(ParamListHandle handle, const char* field, const char* value)
{
    OIS::ParamList* paramlist = reinterpret_cast<OIS::ParamList*>(handle);
    paramlist->insert(
        std::make_pair(
            std::string(field), std::string(value)
        )
    );
}

class MouseListenerCTX : public OIS::MouseListener
{
public:
    MouseListenerCTX(MouseMovedEvent _moved, MousePressedEvent _pressed, MouseReleasedEvent _released, void* data) :
                     moved(_moved), pressed(_pressed), released(_released), userdata(data)
    {
    }

    bool mouseMoved(const OIS::MouseEvent &arg)
    {
        MouseEvent evt;
        bool result;

        // Convert OIS MouseEvent to LLCOI MouseEvent
        ois_mouse_event_to_llcoi_mouse_event(&arg, &evt);

        // Fire off the callback.
        result = moved(&evt, userdata);
        return result;
    }

    bool mousePressed(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
    {
        MouseEvent evt;
        MouseButtonID llcoi_id;
        bool result;

        // Convert OIS MouseEvent to LLCOI MouseEvent
        ois_mouse_event_to_llcoi_mouse_event(&arg, &evt);

        llcoi_id = ois_mbid_to_llcoi_mbid(id);

        // Fire off the callback.
        result = pressed(&evt, llcoi_id, userdata);
        return result;
    }

    bool mouseReleased(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
    {
        MouseEvent evt;
        MouseButtonID llcoi_id;
        bool result;

        // Convert OIS MouseEvent to LLCOI MouseEvent
        ois_mouse_event_to_llcoi_mouse_event(&arg, &evt);

        llcoi_id = ois_mbid_to_llcoi_mbid(id);

        // Fire off the callback.
        result = released(&evt, llcoi_id, userdata);
        return result;
    }

    MouseMovedEvent moved;
    MousePressedEvent pressed;
    MouseReleasedEvent released;

    void* userdata;
};

MouseListenerHandle mouse_set_event_callback(MouseInputHandle handle, MouseMovedEvent moved, MousePressedEvent pressed, MouseReleasedEvent released, void* userdata)
{
    OIS::Mouse* mouse = reinterpret_cast<OIS::Mouse*>(handle);

    MouseListenerCTX* listener = new MouseListenerCTX(moved, pressed, released, userdata);

    mouse->setEventCallback(listener);
    return reinterpret_cast<MouseListenerHandle>(listener);
}

void mouse_remove_event_callback(MouseInputHandle mouse_handle, MouseListenerHandle handle)
{
    OIS::Mouse* mouse          = reinterpret_cast<OIS::Mouse*>(mouse_handle);
    MouseListenerCTX* listener = reinterpret_cast<MouseListenerCTX*>(handle);
    mouse->setEventCallback(0);
    delete listener;
}
<|endoftext|>


<commit_before>#include "mc-lang.h"
#include <cstring>
#include <cstdio>
#include <cerrno>
#include <stdexcept>

#define MC_LINE_SIZE	1024

mcLanguage::mcLanguage(mcIPerformer* performer):m_performer(performer) {
	if(!m_performer) throw runtime_error("invalid performer");
	m_commands.push_back(NULL);		//MC_TOKEN_NONE
	m_commands.push_back(&m_cmd_list);	//MC_TOKEN_LIST
	m_commands.push_back(NULL);		//MC_TOKEN_RUN
	m_commands.push_back(&m_cmd_open);	//MC_TOKEN_OPEN
	m_commands.push_back(&m_cmd_close);	//MC_TOKEN_CLOSE
	m_commands.push_back(&m_cmd_leave);	//MC_TOKEN_LEAVE
	m_commands.push_back(&m_cmd_quit);	//MC_TOKEN_QUIT
	m_commands.push_back(NULL);		//MC_TOKEN_HELP
	m_commands.push_back(&m_cmd_get);	//MC_TOKEN_GET
	m_commands.push_back(&m_cmd_put);	//MC_TOKEN_PUT
	m_commands.push_back(&m_cmd_post);	//MC_TOKEN_POST
	m_commands.push_back(&m_cmd_delete);	//MC_TOKEN_DELETE
	m_commands.push_back(&m_cmd_header);	//MC_TOKEN_HEADER
	m_commands.push_back(&m_cmd_verbose);	//MC_TOKEN_VERBOSE
}

mcLanguageState mcLanguage::run(string path){
	mcLanguageState state;
	FILE* fd = fopen(path.c_str(), "rb");
	if(!fd) {
		fprintf(stderr, "%s\n", strerror(errno));
		return MC_LANG_CONTINUE;
	}
	char buffer[MC_LINE_SIZE];
	do {
		char* line = fgets(buffer, MC_LINE_SIZE, stdin);
		if(!line) {
			return MC_LANG_HANG;
		} else if(!line[0] || line[0] == '\n') {
			state = MC_LANG_CONTINUE;
		} else {
			state = parse(line);
		}
	} while (state == MC_LANG_CONTINUE);
	return state;
}

mcLanguageState mcLanguage::prompt(void){
	mcLanguageState state;
	char buffer[MC_LINE_SIZE];
	do {
		fprintf(stdout, "%s> ", m_performer->current().c_str());
		char* line = fgets(buffer, MC_LINE_SIZE, stdin);
		if(!line) {
			fprintf(stderr, "IO error\n");
			return MC_LANG_HANG;
		} else if(!line[0] || line[0] == '\n') {
			state = MC_LANG_CONTINUE;
		} else {
			state = parse(line);
		}
	} while (state == MC_LANG_CONTINUE);
	return state;
}

mcLanguageState mcLanguage::parse(const char* line){
	mcScanner scanner(line);
	mcToken token = scanner.scan();
	mcLanguageState state;
	switch(token.id) {
		case MC_TOKEN_RUN:
			state = parse_run(scanner);
			break;
		case MC_TOKEN_HELP:
			state = parse_help(scanner);
			break;
		case MC_TOKEN_LIST:
		case MC_TOKEN_OPEN:
		case MC_TOKEN_CLOSE:
		case MC_TOKEN_LEAVE:
		case MC_TOKEN_QUIT:
		case MC_TOKEN_GET:
		case MC_TOKEN_PUT:
		case MC_TOKEN_POST:
		case MC_TOKEN_DELETE:
		case MC_TOKEN_HEADER:
		case MC_TOKEN_VERBOSE:
			{
				mcCommand* cmd = m_commands[token.id];
				if(!cmd) {
					fprintf(stderr, "%s is not available\n", token.buffer.c_str());
					state = MC_LANG_CONTINUE;
				} else {
					state = cmd->parse(scanner, m_performer);
				}
			}
			break;
		default:
			fprintf(stderr, "unknown instruction %s\n", token.buffer.c_str());
			state = MC_LANG_CONTINUE;
			break;
	}
	return state;
}

mcLanguageState mcLanguage::parse_run(mcScanner& scanner){
	mcLanguageState state;
	mcToken token;
	while(token = scanner.scan(), token.id == MC_TOKEN_STRING) {
		state = run(token.buffer);
	}
	if (token.id != MC_TOKEN_EOL) {
		fprintf(stderr, "invalid argument %s\n", token.buffer.c_str());
		state = MC_LANG_ERROR;
	}
	return state;
}

mcLanguageState mcLanguage::parse_help(mcScanner& scanner){
	mcToken token = scanner.scan();
	switch(token.id) {
		case MC_TOKEN_EOL:
			fprintf(stdout, "type help <command> for help on a specific command\n");
			fprintf(stdout, "Available sub commands:\n");
			for(vector<mcCommand*>::iterator it = m_commands.begin() ; it != m_commands.end() ; it++)
				if (*it) fprintf(stdout, "%s\n", (*it)->command().c_str());
			return MC_LANG_CONTINUE;
			break;
		case MC_TOKEN_LIST:
		case MC_TOKEN_OPEN:
		case MC_TOKEN_CLOSE:
		case MC_TOKEN_LEAVE:
		case MC_TOKEN_QUIT:
		case MC_TOKEN_GET:
		case MC_TOKEN_PUT:
		case MC_TOKEN_POST:
		case MC_TOKEN_DELETE:
		case MC_TOKEN_HEADER:
		case MC_TOKEN_VERBOSE:
			if(m_commands[token.id]) m_commands[token.id]->help();
			break;
		case MC_TOKEN_RUN:
			fprintf(stdout, "Usage: run [file]...\n");
			fprintf(stdout, "  runs macro files\n");
			break;
		default:
			fprintf(stderr, "Invalid command %s\n", token.buffer.c_str());
			break;
	}
	mcLanguageState state = MC_LANG_CONTINUE;
	token = scanner.scan();
	if (token.id != MC_TOKEN_EOL) {
		fprintf(stderr, "invalid argument %s\n", token.buffer.c_str());
		state = MC_LANG_ERROR;
	}
	return state;
}

<commit_msg>script runner is debugged<commit_after>#include "mc-lang.h"
#include <cstring>
#include <cstdio>
#include <cerrno>
#include <stdexcept>

#define MC_LINE_SIZE	1024

mcLanguage::mcLanguage(mcIPerformer* performer):m_performer(performer) {
	if(!m_performer) throw runtime_error("invalid performer");
	m_commands.push_back(NULL);		//MC_TOKEN_NONE
	m_commands.push_back(&m_cmd_list);	//MC_TOKEN_LIST
	m_commands.push_back(NULL);		//MC_TOKEN_RUN
	m_commands.push_back(&m_cmd_open);	//MC_TOKEN_OPEN
	m_commands.push_back(&m_cmd_close);	//MC_TOKEN_CLOSE
	m_commands.push_back(&m_cmd_leave);	//MC_TOKEN_LEAVE
	m_commands.push_back(&m_cmd_quit);	//MC_TOKEN_QUIT
	m_commands.push_back(NULL);		//MC_TOKEN_HELP
	m_commands.push_back(&m_cmd_get);	//MC_TOKEN_GET
	m_commands.push_back(&m_cmd_put);	//MC_TOKEN_PUT
	m_commands.push_back(&m_cmd_post);	//MC_TOKEN_POST
	m_commands.push_back(&m_cmd_delete);	//MC_TOKEN_DELETE
	m_commands.push_back(&m_cmd_header);	//MC_TOKEN_HEADER
	m_commands.push_back(&m_cmd_verbose);	//MC_TOKEN_VERBOSE
}

mcLanguageState mcLanguage::run(string path){
	mcLanguageState state;
	FILE* fd = fopen(path.c_str(), "rb");
	if(!fd) {
		fprintf(stderr, "%s\n", strerror(errno));
		return MC_LANG_HANG;
	}
	char buffer[MC_LINE_SIZE];
	do {
		char* line = fgets(buffer, MC_LINE_SIZE, fd);
		if(!line) {
			return MC_LANG_HANG;
		} else if(!line[0] || line[0] == '\n') {
			state = MC_LANG_CONTINUE;
		} else {
			state = parse(line);
		}
	} while (state == MC_LANG_CONTINUE);
	return state;
}

mcLanguageState mcLanguage::prompt(void){
	mcLanguageState state;
	char buffer[MC_LINE_SIZE];
	do {
		fprintf(stdout, "%s> ", m_performer->current().c_str());
		char* line = fgets(buffer, MC_LINE_SIZE, stdin);
		if(!line) {
			fprintf(stderr, "IO error\n");
			return MC_LANG_HANG;
		} else if(!line[0] || line[0] == '\n') {
			state = MC_LANG_CONTINUE;
		} else {
			state = parse(line);
		}
	} while (state == MC_LANG_CONTINUE);
	return state;
}

mcLanguageState mcLanguage::parse(const char* line){
	mcScanner scanner(line);
	mcToken token = scanner.scan();
	mcLanguageState state;
	switch(token.id) {
		case MC_TOKEN_RUN:
			state = parse_run(scanner);
			break;
		case MC_TOKEN_HELP:
			state = parse_help(scanner);
			break;
		case MC_TOKEN_LIST:
		case MC_TOKEN_OPEN:
		case MC_TOKEN_CLOSE:
		case MC_TOKEN_LEAVE:
		case MC_TOKEN_QUIT:
		case MC_TOKEN_GET:
		case MC_TOKEN_PUT:
		case MC_TOKEN_POST:
		case MC_TOKEN_DELETE:
		case MC_TOKEN_HEADER:
		case MC_TOKEN_VERBOSE:
			{
				mcCommand* cmd = m_commands[token.id];
				if(!cmd) {
					fprintf(stderr, "%s is not available\n", token.buffer.c_str());
					state = MC_LANG_CONTINUE;
				} else {
					state = cmd->parse(scanner, m_performer);
				}
			}
			break;
		default:
			fprintf(stderr, "unknown instruction %s\n", token.buffer.c_str());
			state = MC_LANG_CONTINUE;
			break;
	}
	return state;
}

mcLanguageState mcLanguage::parse_run(mcScanner& scanner){
	mcLanguageState state;
	mcToken token;
	while(token = scanner.scan(), token.id == MC_TOKEN_STRING) {
		state = run(token.buffer);
	}
	if (token.id != MC_TOKEN_EOL) {
		fprintf(stderr, "invalid argument %s\n", token.buffer.c_str());
		state = MC_LANG_ERROR;
	}
	return state;
}

mcLanguageState mcLanguage::parse_help(mcScanner& scanner){
	mcToken token = scanner.scan();
	switch(token.id) {
		case MC_TOKEN_EOL:
			fprintf(stdout, "type help <command> for help on a specific command\n");
			fprintf(stdout, "Available sub commands:\n");
			for(vector<mcCommand*>::iterator it = m_commands.begin() ; it != m_commands.end() ; it++)
				if (*it) fprintf(stdout, "%s\n", (*it)->command().c_str());
			return MC_LANG_CONTINUE;
			break;
		case MC_TOKEN_LIST:
		case MC_TOKEN_OPEN:
		case MC_TOKEN_CLOSE:
		case MC_TOKEN_LEAVE:
		case MC_TOKEN_QUIT:
		case MC_TOKEN_GET:
		case MC_TOKEN_PUT:
		case MC_TOKEN_POST:
		case MC_TOKEN_DELETE:
		case MC_TOKEN_HEADER:
		case MC_TOKEN_VERBOSE:
			if(m_commands[token.id]) m_commands[token.id]->help();
			break;
		case MC_TOKEN_RUN:
			fprintf(stdout, "Usage: run [file]...\n");
			fprintf(stdout, "  runs macro files\n");
			break;
		default:
			fprintf(stderr, "Invalid command %s\n", token.buffer.c_str());
			break;
	}
	mcLanguageState state = MC_LANG_CONTINUE;
	token = scanner.scan();
	if (token.id != MC_TOKEN_EOL) {
		fprintf(stderr, "invalid argument %s\n", token.buffer.c_str());
		state = MC_LANG_ERROR;
	}
	return state;
}

<|endoftext|>


<commit_before>/******************************************************************************
 * The MIT License (MIT)
 *
 * Copyright (c) 2015-2016 Baldur Karlsson
 * Copyright (c) 2014 Crytek
 *
 * 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.
 ******************************************************************************/

#include "type_helpers.h"
#include <string>
#include <vector>
#include "api/replay/renderdoc_replay.h"
#include "serialise/serialiser.h"
#include "serialise/string_utils.h"

template <>
string ToStrHelper<false, rdctype::str>::Get(const rdctype::str &el)
{
  return string(el.elems, el.elems + el.count);
}

template <>
string ToStrHelper<false, ResourceId>::Get(const ResourceId &el)
{
  char tostrBuf[256] = {0};

  StringFormat::snprintf(tostrBuf, 255, "ID %llu", el.id);

  return tostrBuf;
}

namespace rdctype
{
str &str::operator=(const std::string &in)
{
  Delete();
  count = (int32_t)in.size();
  if(count == 0)
  {
    elems = (char *)allocate(sizeof(char));
    elems[0] = 0;
  }
  else
  {
    elems = (char *)allocate(sizeof(char) * (count + 1));
    memcpy(elems, &in[0], sizeof(char) * in.size());
    elems[count] = 0;
  }
  return *this;
}

str &str::operator=(const char *const in)
{
  Delete();
  count = (int32_t)strlen(in);
  if(count == 0)
  {
    elems = (char *)allocate(sizeof(char));
    elems[0] = 0;
  }
  else
  {
    elems = (char *)allocate(sizeof(char) * (count + 1));
    memcpy(elems, &in[0], sizeof(char) * count);
    elems[count] = 0;
  }
  return *this;
}

};    // namespace rdctype
<commit_msg>Tweak string name of ResourceId to be all one word for easier searching<commit_after>/******************************************************************************
 * The MIT License (MIT)
 *
 * Copyright (c) 2015-2016 Baldur Karlsson
 * Copyright (c) 2014 Crytek
 *
 * 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.
 ******************************************************************************/

#include "type_helpers.h"
#include <string>
#include <vector>
#include "api/replay/renderdoc_replay.h"
#include "serialise/serialiser.h"
#include "serialise/string_utils.h"

template <>
string ToStrHelper<false, rdctype::str>::Get(const rdctype::str &el)
{
  return string(el.elems, el.elems + el.count);
}

template <>
string ToStrHelper<false, ResourceId>::Get(const ResourceId &el)
{
  char tostrBuf[256] = {0};

  StringFormat::snprintf(tostrBuf, 255, "ResID_%llu", el.id);

  return tostrBuf;
}

namespace rdctype
{
str &str::operator=(const std::string &in)
{
  Delete();
  count = (int32_t)in.size();
  if(count == 0)
  {
    elems = (char *)allocate(sizeof(char));
    elems[0] = 0;
  }
  else
  {
    elems = (char *)allocate(sizeof(char) * (count + 1));
    memcpy(elems, &in[0], sizeof(char) * in.size());
    elems[count] = 0;
  }
  return *this;
}

str &str::operator=(const char *const in)
{
  Delete();
  count = (int32_t)strlen(in);
  if(count == 0)
  {
    elems = (char *)allocate(sizeof(char));
    elems[0] = 0;
  }
  else
  {
    elems = (char *)allocate(sizeof(char) * (count + 1));
    memcpy(elems, &in[0], sizeof(char) * count);
    elems[count] = 0;
  }
  return *this;
}

};    // namespace rdctype
<|endoftext|>


<commit_before>/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2014. All Rights Reserved.                             */
/* Open Source Software - may be modified and shared by FRC teams. The code   */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project.                                                               */
/*----------------------------------------------------------------------------*/

#include "WPILib.h"
#include "gtest/gtest.h"
#include "TestBench.h"

/* The PCM switches the compressor up to 2 seconds after the pressure switch
  changes. */
static const double kCompressorDelayTime = 2.0;

/* Solenoids should change much more quickly */
static const double kSolenoidDelayTime = 0.1;

/* The voltage divider on the test bench should bring the compressor output
  to around these values. */
static const double kCompressorOnVoltage = 5.00;
static const double kCompressorOffVoltage = 1.68;

class PCMTest : public testing::Test {
protected:
  Compressor *m_compressor;

  DigitalOutput *m_fakePressureSwitch;
  AnalogInput *m_fakeCompressor;

  Solenoid *m_solenoid1, *m_solenoid2;
  DigitalInput *m_fakeSolenoid1, *m_fakeSolenoid2;

  virtual void SetUp() {
    m_compressor = new Compressor();

    m_fakePressureSwitch = new DigitalOutput(TestBench::kFakePressureSwitchChannel);
    m_fakeCompressor = new AnalogInput(TestBench::kFakeCompressorChannel);

    m_solenoid1 = new Solenoid(0);
    m_solenoid2 = new Solenoid(1);

    m_fakeSolenoid1 = new DigitalInput(TestBench::kFakeSolenoid1Channel);
    m_fakeSolenoid2 = new DigitalInput(TestBench::kFakeSolenoid2Channel);
  }

  virtual void TearDown() {
    delete m_compressor;
    delete m_fakePressureSwitch;
    delete m_fakeCompressor;
    delete m_solenoid1;
    delete m_solenoid2;
    delete m_fakeSolenoid1;
    delete m_fakeSolenoid2;
  }

  void Reset() {
    m_compressor->Stop();
    m_fakePressureSwitch->Set(false);
    m_solenoid1->Set(false);
    m_solenoid2->Set(false);
  }
};

/**
 * Test if the compressor turns on and off when the pressure switch is toggled
 */
TEST_F(PCMTest, PressureSwitch) {
  Reset();

  m_compressor->SetClosedLoopControl(true);

  // Turn on the compressor
  m_fakePressureSwitch->Set(true);
  Wait(kCompressorDelayTime);
  EXPECT_NEAR(kCompressorOnVoltage, m_fakeCompressor->GetVoltage(), 0.1)
    << "Compressor did not turn on when the pressure switch turned on.";

  // Turn off the compressor
  m_fakePressureSwitch->Set(false);
  Wait(kCompressorDelayTime);
  EXPECT_NEAR(kCompressorOffVoltage, m_fakeCompressor->GetVoltage(), 0.1)
    << "Compressor did not turn off when the pressure switch turned off.";
}

/**
 * Test if the correct solenoids turn on and off when they should
 */
TEST_F(PCMTest, Solenoid) {
  Reset();

  // Turn both solenoids off
  m_solenoid1->Set(false);
  m_solenoid2->Set(false);
  Wait(kSolenoidDelayTime);
  EXPECT_TRUE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn off";
  EXPECT_TRUE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn off";

  // Turn one solenoid on and one off
  m_solenoid1->Set(true);
  m_solenoid2->Set(false);
  Wait(kSolenoidDelayTime);
  EXPECT_FALSE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn on";
  EXPECT_TRUE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn off";

  // Turn one solenoid on and one off
  m_solenoid1->Set(false);
  m_solenoid2->Set(true);
  Wait(kSolenoidDelayTime);
  EXPECT_TRUE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn off";
  EXPECT_FALSE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn on";

  // Turn both on
  m_solenoid1->Set(true);
  m_solenoid2->Set(true);
  Wait(kSolenoidDelayTime);
  EXPECT_FALSE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn on";
  EXPECT_FALSE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn on";
}
<commit_msg>Fixed the PCM test solenoid numbers<commit_after>/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2014. All Rights Reserved.                             */
/* Open Source Software - may be modified and shared by FRC teams. The code   */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project.                                                               */
/*----------------------------------------------------------------------------*/

#include "WPILib.h"
#include "gtest/gtest.h"
#include "TestBench.h"

/* The PCM switches the compressor up to 2 seconds after the pressure switch
  changes. */
static const double kCompressorDelayTime = 2.0;

/* Solenoids should change much more quickly */
static const double kSolenoidDelayTime = 0.1;

/* The voltage divider on the test bench should bring the compressor output
  to around these values. */
static const double kCompressorOnVoltage = 5.00;
static const double kCompressorOffVoltage = 1.68;

class PCMTest : public testing::Test {
protected:
  Compressor *m_compressor;

  DigitalOutput *m_fakePressureSwitch;
  AnalogInput *m_fakeCompressor;

  Solenoid *m_solenoid1, *m_solenoid2;
  DigitalInput *m_fakeSolenoid1, *m_fakeSolenoid2;

  virtual void SetUp() {
    m_compressor = new Compressor();

    m_fakePressureSwitch = new DigitalOutput(TestBench::kFakePressureSwitchChannel);
    m_fakeCompressor = new AnalogInput(TestBench::kFakeCompressorChannel);

    m_solenoid1 = new Solenoid(7);
    m_solenoid2 = new Solenoid(6);

    m_fakeSolenoid1 = new DigitalInput(TestBench::kFakeSolenoid1Channel);
    m_fakeSolenoid2 = new DigitalInput(TestBench::kFakeSolenoid2Channel);
  }

  virtual void TearDown() {
    delete m_compressor;
    delete m_fakePressureSwitch;
    delete m_fakeCompressor;
    delete m_solenoid1;
    delete m_solenoid2;
    delete m_fakeSolenoid1;
    delete m_fakeSolenoid2;
  }

  void Reset() {
    m_compressor->Stop();
    m_fakePressureSwitch->Set(false);
    m_solenoid1->Set(false);
    m_solenoid2->Set(false);
  }
};

/**
 * Test if the compressor turns on and off when the pressure switch is toggled
 */
TEST_F(PCMTest, PressureSwitch) {
  Reset();

  m_compressor->SetClosedLoopControl(true);

  // Turn on the compressor
  m_fakePressureSwitch->Set(true);
  Wait(kCompressorDelayTime);
  EXPECT_NEAR(kCompressorOnVoltage, m_fakeCompressor->GetVoltage(), 0.1)
    << "Compressor did not turn on when the pressure switch turned on.";

  // Turn off the compressor
  m_fakePressureSwitch->Set(false);
  Wait(kCompressorDelayTime);
  EXPECT_NEAR(kCompressorOffVoltage, m_fakeCompressor->GetVoltage(), 0.1)
    << "Compressor did not turn off when the pressure switch turned off.";
}

/**
 * Test if the correct solenoids turn on and off when they should
 */
TEST_F(PCMTest, Solenoid) {
  Reset();

  // Turn both solenoids off
  m_solenoid1->Set(false);
  m_solenoid2->Set(false);
  Wait(kSolenoidDelayTime);
  EXPECT_TRUE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn off";
  EXPECT_TRUE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn off";

  // Turn one solenoid on and one off
  m_solenoid1->Set(true);
  m_solenoid2->Set(false);
  Wait(kSolenoidDelayTime);
  EXPECT_FALSE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn on";
  EXPECT_TRUE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn off";

  // Turn one solenoid on and one off
  m_solenoid1->Set(false);
  m_solenoid2->Set(true);
  Wait(kSolenoidDelayTime);
  EXPECT_TRUE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn off";
  EXPECT_FALSE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn on";

  // Turn both on
  m_solenoid1->Set(true);
  m_solenoid2->Set(true);
  Wait(kSolenoidDelayTime);
  EXPECT_FALSE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn on";
  EXPECT_FALSE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn on";
}
<|endoftext|>


<commit_before>#include "Log.hpp"

#include <stdarg.h>
#include <cstdio>

#include "FileLogger.hpp"

#ifdef ANDROID_PLATFORM
#include <android/log.h>
#elif	defined(WINDOWS_PLATFORM)
#include <windows.h>
#endif

#define LOG_TAG 		"MPACK"
#define	BUFFERSIZE 		128*1024

namespace MPACK
{
	#if defined(WINDOWS_PLATFORM) || defined(LINUX_PLATFORM)
	FileLogger *pFileLogger;
	#endif

	namespace Core
	{
		void Log::Initialize()
		{
	#if defined(WINDOWS_PLATFORM) || defined(LINUX_PLATFORM)
			pFileLogger=new FileLogger("log.html");
	#endif
		}

		void Log::Destroy()
		{
	#if defined(WINDOWS_PLATFORM) || defined(LINUX_PLATFORM)
			delete pFileLogger;
	#endif
		}

		void Log::Info(const char* pMessage, ...)
		{
			char buffer[BUFFERSIZE];
			va_list lVarArgs;
			va_start(lVarArgs, pMessage);
			vsprintf (buffer,pMessage,lVarArgs);
			va_end(lVarArgs);

	#ifdef ANDROID_PLATFORM
			__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "%s", buffer);
			__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "\n");
	#elif defined(WINDOWS_PLATFORM) || defined(LINUX_PLATFORM)
			printf("Info: %s\n", buffer);
			pFileLogger->Print(FileLogger::Succes,std::string(buffer));
	#endif
		}

		void Log::Error(const char* pMessage, ...)
		{
			char buffer[BUFFERSIZE];
			va_list lVarArgs;
			va_start(lVarArgs, pMessage);
			vsprintf (buffer,pMessage,lVarArgs);
			va_end(lVarArgs);

	#ifdef ANDROID_PLATFORM
			__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "%s", buffer);
			__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "\n");
	#elif defined(WINDOWS_PLATFORM) || defined(LINUX_PLATFORM)
			printf("Error: %s\n", buffer);
			pFileLogger->Print(FileLogger::CriticalFailure,"%s",buffer);
	#endif
		}

		void Log::Warn(const char* pMessage, ...)
		{
			char buffer[BUFFERSIZE];
			va_list lVarArgs;
			va_start(lVarArgs, pMessage);
			vsprintf (buffer,pMessage,lVarArgs);
			va_end(lVarArgs);

	#ifdef ANDROID_PLATFORM
			__android_log_print(ANDROID_LOG_WARN, LOG_TAG, "%s", buffer);
			__android_log_print(ANDROID_LOG_WARN, LOG_TAG, "\n");
	#elif defined(WINDOWS_PLATFORM) || defined(LINUX_PLATFORM)
			printf("Warning: %s\n", buffer);
			pFileLogger->Print(FileLogger::Warning,"%s",buffer);
	#endif
		}

		void Log::Debug(const char* pMessage, ...)
		{
			char buffer[BUFFERSIZE];
			va_list lVarArgs;
			va_start(lVarArgs, pMessage);
			vsprintf (buffer,pMessage,lVarArgs);
			va_end(lVarArgs);

	#ifdef ANDROID_PLATFORM
			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "%s", buffer);
			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "\n");
	#elif defined(WINDOWS_PLATFORM) || defined(LINUX_PLATFORM)
			printf("Debug: %s\n", buffer);
			pFileLogger->Print(FileLogger::Information,"%s",buffer);
	#endif
		}
	}
}
<commit_msg>Change log tag strings for console<commit_after>#include "Log.hpp"

#include <stdarg.h>
#include <cstdio>

#include "FileLogger.hpp"

#ifdef ANDROID_PLATFORM
#include <android/log.h>
#elif	defined(WINDOWS_PLATFORM)
#include <windows.h>
#endif

#define LOG_TAG 		"MPACK"
#define	BUFFERSIZE 		128*1024

namespace MPACK
{
	#if defined(WINDOWS_PLATFORM) || defined(LINUX_PLATFORM)
	FileLogger *pFileLogger;
	#endif

	namespace Core
	{
		void Log::Initialize()
		{
	#if defined(WINDOWS_PLATFORM) || defined(LINUX_PLATFORM)
			pFileLogger=new FileLogger("log.html");
	#endif
		}

		void Log::Destroy()
		{
	#if defined(WINDOWS_PLATFORM) || defined(LINUX_PLATFORM)
			delete pFileLogger;
	#endif
		}

		void Log::Info(const char* pMessage, ...)
		{
			char buffer[BUFFERSIZE];
			va_list lVarArgs;
			va_start(lVarArgs, pMessage);
			vsprintf (buffer,pMessage,lVarArgs);
			va_end(lVarArgs);

	#ifdef ANDROID_PLATFORM
			__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "%s", buffer);
			__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "\n");
	#elif defined(WINDOWS_PLATFORM) || defined(LINUX_PLATFORM)
			printf("[  INFO ]   %s\n", buffer);
			pFileLogger->Print(FileLogger::Succes,std::string(buffer));
	#endif
		}

		void Log::Error(const char* pMessage, ...)
		{
			char buffer[BUFFERSIZE];
			va_list lVarArgs;
			va_start(lVarArgs, pMessage);
			vsprintf (buffer,pMessage,lVarArgs);
			va_end(lVarArgs);

	#ifdef ANDROID_PLATFORM
			__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "%s", buffer);
			__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "\n");
	#elif defined(WINDOWS_PLATFORM) || defined(LINUX_PLATFORM)
			printf("[ ERROR ]   %s\n", buffer);
			pFileLogger->Print(FileLogger::CriticalFailure,"%s",buffer);
	#endif
		}

		void Log::Warn(const char* pMessage, ...)
		{
			char buffer[BUFFERSIZE];
			va_list lVarArgs;
			va_start(lVarArgs, pMessage);
			vsprintf (buffer,pMessage,lVarArgs);
			va_end(lVarArgs);

	#ifdef ANDROID_PLATFORM
			__android_log_print(ANDROID_LOG_WARN, LOG_TAG, "%s", buffer);
			__android_log_print(ANDROID_LOG_WARN, LOG_TAG, "\n");
	#elif defined(WINDOWS_PLATFORM) || defined(LINUX_PLATFORM)
			printf("[WARNING]   %s\n", buffer);
			pFileLogger->Print(FileLogger::Warning,"%s",buffer);
	#endif
		}

		void Log::Debug(const char* pMessage, ...)
		{
			char buffer[BUFFERSIZE];
			va_list lVarArgs;
			va_start(lVarArgs, pMessage);
			vsprintf (buffer,pMessage,lVarArgs);
			va_end(lVarArgs);

	#ifdef ANDROID_PLATFORM
			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "%s", buffer);
			__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "\n");
	#elif defined(WINDOWS_PLATFORM) || defined(LINUX_PLATFORM)
			printf("[ DEBUG ]   %s\n", buffer);
			pFileLogger->Print(FileLogger::Information,"%s",buffer);
	#endif
		}
	}
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: XMLTextHeaderFooterContext.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 15:21:48 $
 *
 *  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 _COM_SUN_STAR_TEXT_XTEXT_HPP_
#include <com/sun/star/text/XText.hpp>
#endif
#ifndef _COM_SUN_STAR_TEXT_XRELATIVETEXTCONTENTREMOVE_HPP_
#include <com/sun/star/text/XRelativeTextContentRemove.hpp>
#endif
#ifndef _XMLOFF_NMSPMAP_HXX
#include "nmspmap.hxx"
#endif
#ifndef _XMLOFF_XMLNMSPE_HXX
#include "xmlnmspe.hxx"
#endif
#ifndef _XMLOFF_TEXTHEADERFOOTERCONTEXT_HXX_
#include "XMLTextHeaderFooterContext.hxx"
#endif
#ifndef _XMLOFF_TEXTTABLECONTEXT_HXX_
#include "XMLTextTableContext.hxx"
#endif
#ifndef _XMLOFF_XMLIMP_HXX
#include "xmlimp.hxx"
#endif

using namespace ::rtl;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::xml::sax;
//using namespace ::com::sun::star::style;
using namespace ::com::sun::star::text;
using namespace ::com::sun::star::beans;
//using namespace ::com::sun::star::container;
//using namespace ::com::sun::star::lang;
//using namespace ::com::sun::star::text;

TYPEINIT1( XMLTextHeaderFooterContext, SvXMLImportContext );

XMLTextHeaderFooterContext::XMLTextHeaderFooterContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
                       const OUString& rLName,
                       const uno::Reference<
                            xml::sax::XAttributeList > & xAttrList,
                        const Reference < XPropertySet > & rPageStylePropSet,
                       sal_Bool bFooter, sal_Bool bLft ) :
    SvXMLImportContext( rImport, nPrfx, rLName ),
    xPropSet( rPageStylePropSet ),
    sOn( OUString::createFromAscii( bFooter ? "FooterIsOn" : "HeaderIsOn" ) ),
    sShareContent( OUString::createFromAscii( bFooter ? "FooterIsShared"
                                                      : "HeaderIsShared" ) ),
    sText( OUString::createFromAscii( bFooter ? "FooterText" : "HeaderText" ) ),
    sTextLeft( OUString::createFromAscii( bFooter ? "FooterTextLeft"
                                                     : "HeaderTextLeft" ) ),
    bInsertContent( sal_True ),
    bLeft( bLft )
{
    if( bLeft )
    {
        Any aAny;

        aAny = xPropSet->getPropertyValue( sOn );
        sal_Bool bOn = *(sal_Bool *)aAny.getValue();

        if( bOn )
        {
            aAny = xPropSet->getPropertyValue( sShareContent );
            sal_Bool bShared = *(sal_Bool *)aAny.getValue();
            if( bShared )
            {
                // Don't share headers any longer
                bShared = sal_False;
                aAny.setValue( &bShared, ::getBooleanCppuType() );
                xPropSet->setPropertyValue( sShareContent, aAny );
            }
        }
        else
        {
            // If headers or footers are switched off, no content must be
            // inserted.
            bInsertContent = sal_False;
        }
    }
}

XMLTextHeaderFooterContext::~XMLTextHeaderFooterContext()
{
}

SvXMLImportContext *XMLTextHeaderFooterContext::CreateChildContext(
    sal_uInt16 nPrefix,
    const OUString& rLocalName,
    const uno::Reference< xml::sax::XAttributeList > & xAttrList )
{
    SvXMLImportContext *pContext = 0;
    if( bInsertContent )
    {
        if( !xOldTextCursor.is() )
        {
            sal_Bool bRemoveContent = sal_True;
            Any aAny;
            if( bLeft )
            {
                // Headers and footers are switched on already,
                // and they aren't shared.
                aAny = xPropSet->getPropertyValue( sTextLeft );
            }
            else
            {
                aAny = xPropSet->getPropertyValue( sOn );
                sal_Bool bOn = *(sal_Bool *)aAny.getValue();

                if( !bOn )
                {
                    // Switch header on
                    bOn = sal_True;
                    aAny.setValue( &bOn, ::getBooleanCppuType() );
                    xPropSet->setPropertyValue( sOn, aAny );

                    // The content has not to be removed, because the header
                    // or footer is empty already.
                    bRemoveContent;
                }

                // If a header or footer is not shared, share it now.
                aAny = xPropSet->getPropertyValue( sShareContent );
                sal_Bool bShared = *(sal_Bool *)aAny.getValue();
                if( !bShared )
                {
                    bShared = sal_True;
                    aAny.setValue( &bShared, ::getBooleanCppuType() );
                    xPropSet->setPropertyValue( sShareContent, aAny );
                }

                aAny = xPropSet->getPropertyValue( sText );
            }

            Reference < XText > xText;
            aAny >>= xText;

            if( bRemoveContent )
            {
                OUString sText;
                xText->setString( sText );
            }

            UniReference < XMLTextImportHelper > xTxtImport =
                GetImport().GetTextImport();

            xOldTextCursor = xTxtImport->GetCursor();
            xTxtImport->SetCursor( xText->createTextCursor() );
        }

        pContext =
            GetImport().GetTextImport()->CreateTextChildContext(
                GetImport(), nPrefix, rLocalName, xAttrList,
                XML_TEXT_TYPE_HEADER_FOOTER );
    }
    if( !pContext )
        pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );

    return pContext;
}

void XMLTextHeaderFooterContext::EndElement()
{
    if( xOldTextCursor.is() )
    {
        GetImport().GetTextImport()->DeleteParagraph();
        GetImport().GetTextImport()->SetCursor( xOldTextCursor );
    }
    else if( !bLeft )
    {
        // If no content has been inserted inro the header or footer,
        // switch it off.
        sal_Bool bOn = sal_False;
        Any aAny;
        aAny.setValue( &bOn, ::getBooleanCppuType() );
        xPropSet->setPropertyValue( sOn, aAny );
    }
}

<commit_msg>INTEGRATION: CWS warnings01 (1.8.32); FILE MERGED 2005/11/17 15:19:25 pl 1.8.32.2: #i55991# removed warnings 2005/11/03 17:47:11 cl 1.8.32.1: warning free code changes for unxlngi6<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: XMLTextHeaderFooterContext.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 18:45:55 $
 *
 *  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 _COM_SUN_STAR_TEXT_XTEXT_HPP_
#include <com/sun/star/text/XText.hpp>
#endif
#ifndef _COM_SUN_STAR_TEXT_XRELATIVETEXTCONTENTREMOVE_HPP_
#include <com/sun/star/text/XRelativeTextContentRemove.hpp>
#endif
#ifndef _XMLOFF_NMSPMAP_HXX
#include "nmspmap.hxx"
#endif
#ifndef _XMLOFF_XMLNMSPE_HXX
#include "xmlnmspe.hxx"
#endif
#ifndef _XMLOFF_TEXTHEADERFOOTERCONTEXT_HXX_
#include "XMLTextHeaderFooterContext.hxx"
#endif
#ifndef _XMLOFF_TEXTTABLECONTEXT_HXX_
#include "XMLTextTableContext.hxx"
#endif
#ifndef _XMLOFF_XMLIMP_HXX
#include "xmlimp.hxx"
#endif

using namespace ::rtl;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::xml::sax;
//using namespace ::com::sun::star::style;
using namespace ::com::sun::star::text;
using namespace ::com::sun::star::beans;
//using namespace ::com::sun::star::container;
//using namespace ::com::sun::star::lang;
//using namespace ::com::sun::star::text;

TYPEINIT1( XMLTextHeaderFooterContext, SvXMLImportContext );

XMLTextHeaderFooterContext::XMLTextHeaderFooterContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
                       const OUString& rLName,
                       const uno::Reference<
                            xml::sax::XAttributeList > &,
                        const Reference < XPropertySet > & rPageStylePropSet,
                       sal_Bool bFooter, sal_Bool bLft ) :
    SvXMLImportContext( rImport, nPrfx, rLName ),
    xPropSet( rPageStylePropSet ),
    sOn( OUString::createFromAscii( bFooter ? "FooterIsOn" : "HeaderIsOn" ) ),
    sShareContent( OUString::createFromAscii( bFooter ? "FooterIsShared"
                                                      : "HeaderIsShared" ) ),
    sText( OUString::createFromAscii( bFooter ? "FooterText" : "HeaderText" ) ),
    sTextLeft( OUString::createFromAscii( bFooter ? "FooterTextLeft"
                                                     : "HeaderTextLeft" ) ),
    bInsertContent( sal_True ),
    bLeft( bLft )
{
    if( bLeft )
    {
        Any aAny;

        aAny = xPropSet->getPropertyValue( sOn );
        sal_Bool bOn = *(sal_Bool *)aAny.getValue();

        if( bOn )
        {
            aAny = xPropSet->getPropertyValue( sShareContent );
            sal_Bool bShared = *(sal_Bool *)aAny.getValue();
            if( bShared )
            {
                // Don't share headers any longer
                bShared = sal_False;
                aAny.setValue( &bShared, ::getBooleanCppuType() );
                xPropSet->setPropertyValue( sShareContent, aAny );
            }
        }
        else
        {
            // If headers or footers are switched off, no content must be
            // inserted.
            bInsertContent = sal_False;
        }
    }
}

XMLTextHeaderFooterContext::~XMLTextHeaderFooterContext()
{
}

SvXMLImportContext *XMLTextHeaderFooterContext::CreateChildContext(
    sal_uInt16 nPrefix,
    const OUString& rLocalName,
    const uno::Reference< xml::sax::XAttributeList > & xAttrList )
{
    SvXMLImportContext *pContext = 0;
    if( bInsertContent )
    {
        if( !xOldTextCursor.is() )
        {
            sal_Bool bRemoveContent = sal_True;
            Any aAny;
            if( bLeft )
            {
                // Headers and footers are switched on already,
                // and they aren't shared.
                aAny = xPropSet->getPropertyValue( sTextLeft );
            }
            else
            {
                aAny = xPropSet->getPropertyValue( sOn );
                sal_Bool bOn = *(sal_Bool *)aAny.getValue();

                if( !bOn )
                {
                    // Switch header on
                    bOn = sal_True;
                    aAny.setValue( &bOn, ::getBooleanCppuType() );
                    xPropSet->setPropertyValue( sOn, aAny );

                    // The content has not to be removed, because the header
                    // or footer is empty already.
                    bRemoveContent = sal_False;
                }

                // If a header or footer is not shared, share it now.
                aAny = xPropSet->getPropertyValue( sShareContent );
                sal_Bool bShared = *(sal_Bool *)aAny.getValue();
                if( !bShared )
                {
                    bShared = sal_True;
                    aAny.setValue( &bShared, ::getBooleanCppuType() );
                    xPropSet->setPropertyValue( sShareContent, aAny );
                }

                aAny = xPropSet->getPropertyValue( sText );
            }

            Reference < XText > xText;
            aAny >>= xText;

            if( bRemoveContent )
            {
                OUString aText;
                xText->setString( aText );
            }

            UniReference < XMLTextImportHelper > xTxtImport =
                GetImport().GetTextImport();

            xOldTextCursor = xTxtImport->GetCursor();
            xTxtImport->SetCursor( xText->createTextCursor() );
        }

        pContext =
            GetImport().GetTextImport()->CreateTextChildContext(
                GetImport(), nPrefix, rLocalName, xAttrList,
                XML_TEXT_TYPE_HEADER_FOOTER );
    }
    if( !pContext )
        pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );

    return pContext;
}

void XMLTextHeaderFooterContext::EndElement()
{
    if( xOldTextCursor.is() )
    {
        GetImport().GetTextImport()->DeleteParagraph();
        GetImport().GetTextImport()->SetCursor( xOldTextCursor );
    }
    else if( !bLeft )
    {
        // If no content has been inserted inro the header or footer,
        // switch it off.
        sal_Bool bOn = sal_False;
        Any aAny;
        aAny.setValue( &bOn, ::getBooleanCppuType() );
        xPropSet->setPropertyValue( sOn, aAny );
    }
}

<|endoftext|>


<commit_before>/*-------------------------------------------------------------------------
 *
 *   FILE
 *	util.cxx
 *
 *   DESCRIPTION
 *      Various utility functions for libpqxx
 *
 * Copyright (c) 2003-2004, Jeroen T. Vermeulen <jtv@xs4all.nl>
 *
 * See COPYING for copyright license.  If you did not receive a file called
 * COPYING with this source code, please notify the distributor of this mistake,
 * or contact the author.
 *
 *-------------------------------------------------------------------------
 */
#include "pqxx/compiler.h"

#ifdef PQXX_HAVE_LOCALE
#include <locale>
#endif

#include <new>
#include <sstream>

#include "pqxx/util"

using namespace PGSTD;
using namespace pqxx::internal::pq;

namespace pqxx
{

template<> void from_string(const char Str[], long &Obj)
{
  const char *p = Str;
  bool neg = false;
  if (!isdigit(*p))
  {
    if (*p == '-')
    {
      neg = true;
      p++;
    }
    else
    {
      throw runtime_error("Could not convert string to integer: '" +
      	string(Str) + "'");
    }
  }

  long result = 0;
  if (neg) for (; isdigit(*p); ++p)
  {
    const long newresult = 10*result - (*p-'0');
    if (newresult > result)
      throw runtime_error("Integer too small to read: " + string(Str));
    result = newresult;
  }
  else for (; isdigit(*p); ++p)
  {
    const long newresult = 10*result + (*p-'0');
    if (newresult < result)
      throw runtime_error("Integer too large to read: " + string(Str));
    result = newresult;
  }

  if (*p)
    throw runtime_error("Unexpected text after integer: '" + string(Str) + "'");

  Obj = result;
}

template<> void from_string(const char Str[], unsigned long &Obj)
{
  if (!Str) throw runtime_error("Attempt to convert NULL string to integer");

  const char *p = Str;
  if (!isdigit(*p))
  {
    throw runtime_error("Could not convert string to unsigned integer: '" +
    	string(Str) + "'");
  }

  unsigned long result;
  for (result=0; isdigit(*p); ++p)
  {
    const unsigned long newresult = 10*result + (*p-'0');
    if (newresult < result)
      throw runtime_error("Unsigned integer too large to read: " + string(Str));

    result = newresult;
  }

  if (*p)
    throw runtime_error("Unexpected text after integer: '" + string(Str) + "'");

  Obj = result;
}

} // namespace pqxx

namespace
{
template<typename T> inline void from_string_signed(const char Str[], T &Obj)
{
  long L;
  pqxx::from_string(Str, L);
  const T result = T(L);
  if (result != L) throw runtime_error("Overflow in integer conversion");
  Obj = result;
}

template<typename T> inline void from_string_unsigned(const char Str[], T &Obj)
{
  unsigned long L;
  pqxx::from_string(Str, L);
  const T result = T(L);
  if (result != L)
    throw runtime_error("Overflow in unsigned integer conversion");
  Obj = result;
}

// These are hard.  Sacrifice performance and lean on standard library.
template<typename T> inline void from_string_float(const char Str[], T &Obj)
{
  locale Cloc("C");
  stringstream S(Str);
  S.imbue(Cloc);
  T result;
  if (!(S >> result))
    throw runtime_error("Could not convert string to numeric value: '" +
	string(Str) + "'");
  Obj = result;
}

} // namespace

namespace pqxx
{

template<> void from_string(const char Str[], int &Obj)
{
  from_string_signed(Str, Obj);
}

template<> void from_string(const char Str[], unsigned int &Obj)
{
  from_string_unsigned(Str, Obj);
}

template<> void from_string(const char Str[], short &Obj)
{
  from_string_signed(Str, Obj);
}

template<> void from_string(const char Str[], unsigned short &Obj)
{
  from_string_unsigned(Str, Obj);
}

template<> void from_string(const char Str[], float &Obj)
{
  float result;
  from_string_float(Str, result);
  Obj = result;
}

template<> void from_string(const char Str[], double &Obj)
{
  from_string_float(Str, Obj);
}

template<> void from_string(const char Str[], long double &Obj)
{
  from_string_float(Str, Obj);
}

template<> void from_string(const char Str[], bool &Obj)
{
  if (!Str)
    throw runtime_error("Attempt to read NULL string");

  bool OK, result=false;

  switch (Str[0])
  {
  case 0:
    result = false;
    OK = true;
    break;

  case 'f':
  case 'F':
    result = false;
    OK = !(Str[1] &&
	   (strcmp(Str+1, "alse") != 0) &&
	   (strcmp(Str+1, "ALSE") != 0));
    break;

  case '0':
    {
      int I;
      from_string(Str, I);
      result = (I != 0);
      OK = ((I == 0) || (I == 1));
    }
    break;

  case '1':
    result = true;
    OK = !Str[1];
    break;

  case 't':
  case 'T':
    result = true;
    OK = !(Str[1] &&
	   (strcmp(Str+1, "rue") != 0) &&
	   (strcmp(Str+1, "RUE") != 0));
    break;

  default:
    OK = false;
  }

  if (!OK)
    throw invalid_argument("Failed conversion to bool: '" + string(Str) + "'");

  Obj = result;
}

} // namespace pqxx

namespace
{
template<typename T> inline string to_string_unsigned(T Obj)
{
  if (!Obj) return "0";

  char buf[4*sizeof(T)+1];
  char *p = &buf[sizeof(buf)];
  *--p = '\0';
  for (T next; Obj > 0; Obj = next)
  {
    next = Obj / 10;
    char c = ('0' + Obj - (next*10));
    *--p = c;
  }
  return p;
}

template<typename T> inline string to_string_fallback(T Obj)
{
  stringstream S;
  S << Obj;
  string R;
  S >> R;
  return R;
}

template<typename T> inline string to_string_signed(T Obj)
{
  if (Obj < 0)
  {
    // Remember--the smallest negative number for a given two's-complement type
    // cannot be negated.
    if (-Obj > 0)
      return '-' + to_string_unsigned(-Obj);
    else
      return to_string_fallback(Obj);
  }

  return to_string_unsigned(Obj);
}

} // namespace

namespace pqxx
{
template<> string to_string(const short &Obj)
{
  return to_string_signed(Obj);
}

template<> string to_string(const unsigned short &Obj)
{
  return to_string_unsigned(Obj);
}

template<> string to_string(const int &Obj)
{
  return to_string_signed(Obj);
}

template<> string to_string(const unsigned int &Obj)
{
  return to_string_unsigned(Obj);
}

template<> string to_string(const long &Obj)
{
  return to_string_signed(Obj);
}

template<> string to_string(const unsigned long &Obj)
{
  return to_string_unsigned(Obj);
}

template<> string to_string(const float &Obj)
{
  return to_string_fallback(Obj);
}

template<> string to_string(const double &Obj)
{
  return to_string_fallback(Obj);
}

template<> string to_string(const long double &Obj)
{
  return to_string_fallback(Obj);
}

template<> string to_string(const bool &Obj)
{
  return Obj ? "true" : "false";
}

template<> string to_string(const char &Obj)
{
  string s;
  s += Obj;
  return s;
}

} // namespace pqxx

void pqxx::internal::FromString_string(const char Str[], string &Obj)
{
  if (!Str)
    throw runtime_error("Attempt to convert NULL C string to C++ string");
  Obj = Str;
}

void pqxx::internal::FromString_ucharptr(const char Str[],
    const unsigned char *&Obj)
{
  const char *C;
  FromString(Str, C);
  Obj = reinterpret_cast<const unsigned char *>(C);
}

#ifdef PQXX_HAVE_PQESCAPESTRING
namespace
{
string libpq_escape(const char str[], size_t len)
{
  char *buf = 0;
  string result;

  try
  {
    /* Going by the letter of the PQescapeString() documentation we only need
     * 2*len+1 bytes.  But what happens to nonprintable characters?  They might
     * be escaped to octal notation, whether in current or future versions of
     * libpq--in which case we would need this more conservative size.
     */
    buf = new char[5*len + 1];
  }
  catch (const bad_alloc &)
  {
    /* Okay, maybe we're just dealing with an extremely large string.  Try a
     * more aggressive size limit, which is likely to be just fine.
     */
    buf = new char[2*len+1];
  }

  try
  {
    const size_t bytes = PQescapeString(buf, str, len);
    result.assign(buf, bytes);
  }
  catch (const exception &)
  {
    delete [] buf;
    throw;
  }
  delete [] buf;

  return result;
}
} // namespace
#endif

string pqxx::sqlesc(const char str[])
{
  string result;
#ifdef PQXX_HAVE_PQESCAPESTRING
  result = libpq_escape(str, strlen(str));
#else
  for (size_t i=0; str[i]; ++i)
  {
    if (isprint(str[i]))
    {
      switch (str[i])
      {
      case '\'':
      case '\\':
	result += str[i];
      }
      result += str[i];
    }
    else
    {
        char s[8];
        sprintf(s,
	        "\\%03o",
		static_cast<unsigned int>(static_cast<unsigned char>(str[i])));
        result.append(s, 4);
    }
  }
#endif
  return result;
}

string pqxx::sqlesc(const char str[], size_t len)
{
  string result;
#ifdef PQXX_HAVE_PQESCAPESTRING
  result = libpq_escape(str, len);
#else
  for (size_t i=0; (i < len) && str[i]; ++i)
  {
    if (isprint(str[i]))
    {
      switch (str[i])
      {
      case '\'':
      case '\\':
	result += str[i];
      }
      result += str[i];
    }
    else
    {
        char s[8];
        sprintf(s,
	        "\\%03o",
		static_cast<unsigned int>(static_cast<unsigned char>(str[i])));
        result.append(s, 4);
    }
  }
#endif

  return result;
}

string pqxx::sqlesc(const string &str)
{
  string result;
  for (string::const_iterator i = str.begin(); i != str.end(); ++i)
  {
    if (isprint(*i) || isspace(*i))
    {
      switch (*i)
      {
      case '\'':
      case '\\':
	result += *i;
      }
      result += *i;
    }
    else
    {
        char s[8];
        sprintf(s,
	        "\\%03o",
		static_cast<unsigned int>(static_cast<unsigned char>(*i)));
        result.append(s, 4);
    }
  }
  return result;
}

string pqxx::internal::Quote_string(const string &Obj, bool EmptyIsNull)
{
  return (EmptyIsNull && Obj.empty()) ? "null" : ("'" + sqlesc(Obj) + "'");
}

string pqxx::internal::Quote_charptr(const char Obj[], bool EmptyIsNull)
{
  return Obj ? Quote(string(Obj), EmptyIsNull) : "null";
}

string pqxx::internal::namedclass::description() const
{
  try
  {
    string desc = classname();
    if (!name().empty()) desc += " '" + name() + "'";
    return desc;
  }
  catch (const exception &)
  {
    // Oops, string composition failed!  Probably out of memory.
    // Let's try something easier.
  }
  return name().empty() ? classname() : name();
}

void pqxx::internal::CheckUniqueRegistration(const namedclass *New,
    const namedclass *Old)
{
  if (!New)
    throw logic_error("libpqxx internal error: NULL pointer registered");
  if (Old)
  {
    if (Old == New)
      throw logic_error("Started " + New->description() + " twice");
    throw logic_error("Started " + New->description() + " "
		      "while " + Old->description() + " still active");
  }
}

void pqxx::internal::CheckUniqueUnregistration(const namedclass *New,
    const namedclass *Old)
{
  if (New != Old)
  {
    if (!New)
      throw logic_error("Expected to close " + Old->description() + ", "
	  		"but got NULL pointer instead");
    if (!Old)
      throw logic_error("Closed " + New->description() + ", "
	 		"which wasn't open");
    throw logic_error("Closed " + New->description() + "; "
		      "expected to close " + Old->description());
  }
}

void pqxx::internal::freepqmem(void *p)
{
#ifdef PQXX_HAVE_PQFREEMEM
  PQfreemem(p);
#else
  free(p);
#endif
}

void pqxx::internal::freenotif(PGnotify *p)
{
#ifdef PQXX_HAVE_PQFREENOTIFY
  PQfreeNotify(p);
#else
  freepqmem(p);
#endif
}

void pqxx::internal::sleep_seconds(int s)
{
#ifdef PQXX_HAVE_SLEEP
  // Use POSIX.1 sleep() if available
  sleep(s);
#elif defined(_WIN32)
  // Windows has its own Sleep(), which speaks milliseconds
  Sleep(s*1000);
#else
  // If all else fails, use select() on nothing and specify a timeout
  fd_set F;
  FD_ZERO(&F);
  struct timeval timeout;
  timeout.tv_sec = s;
  timeout.tv_usec = 0;
  if (select(0, &F, &F, &F, &timeout) == -1)
    throw runtime_error(strerror(errno));
#endif
}

<commit_msg>Add <cerrno> include<commit_after>/*-------------------------------------------------------------------------
 *
 *   FILE
 *	util.cxx
 *
 *   DESCRIPTION
 *      Various utility functions for libpqxx
 *
 * Copyright (c) 2003-2004, Jeroen T. Vermeulen <jtv@xs4all.nl>
 *
 * See COPYING for copyright license.  If you did not receive a file called
 * COPYING with this source code, please notify the distributor of this mistake,
 * or contact the author.
 *
 *-------------------------------------------------------------------------
 */
#include "pqxx/compiler.h"

#ifdef PQXX_HAVE_LOCALE
#include <locale>
#endif

#include <cerrno>
#include <new>
#include <sstream>

#include "pqxx/util"

using namespace PGSTD;
using namespace pqxx::internal::pq;

namespace pqxx
{

template<> void from_string(const char Str[], long &Obj)
{
  const char *p = Str;
  bool neg = false;
  if (!isdigit(*p))
  {
    if (*p == '-')
    {
      neg = true;
      p++;
    }
    else
    {
      throw runtime_error("Could not convert string to integer: '" +
      	string(Str) + "'");
    }
  }

  long result = 0;
  if (neg) for (; isdigit(*p); ++p)
  {
    const long newresult = 10*result - (*p-'0');
    if (newresult > result)
      throw runtime_error("Integer too small to read: " + string(Str));
    result = newresult;
  }
  else for (; isdigit(*p); ++p)
  {
    const long newresult = 10*result + (*p-'0');
    if (newresult < result)
      throw runtime_error("Integer too large to read: " + string(Str));
    result = newresult;
  }

  if (*p)
    throw runtime_error("Unexpected text after integer: '" + string(Str) + "'");

  Obj = result;
}

template<> void from_string(const char Str[], unsigned long &Obj)
{
  if (!Str) throw runtime_error("Attempt to convert NULL string to integer");

  const char *p = Str;
  if (!isdigit(*p))
  {
    throw runtime_error("Could not convert string to unsigned integer: '" +
    	string(Str) + "'");
  }

  unsigned long result;
  for (result=0; isdigit(*p); ++p)
  {
    const unsigned long newresult = 10*result + (*p-'0');
    if (newresult < result)
      throw runtime_error("Unsigned integer too large to read: " + string(Str));

    result = newresult;
  }

  if (*p)
    throw runtime_error("Unexpected text after integer: '" + string(Str) + "'");

  Obj = result;
}

} // namespace pqxx

namespace
{
template<typename T> inline void from_string_signed(const char Str[], T &Obj)
{
  long L;
  pqxx::from_string(Str, L);
  const T result = T(L);
  if (result != L) throw runtime_error("Overflow in integer conversion");
  Obj = result;
}

template<typename T> inline void from_string_unsigned(const char Str[], T &Obj)
{
  unsigned long L;
  pqxx::from_string(Str, L);
  const T result = T(L);
  if (result != L)
    throw runtime_error("Overflow in unsigned integer conversion");
  Obj = result;
}

// These are hard.  Sacrifice performance and lean on standard library.
template<typename T> inline void from_string_float(const char Str[], T &Obj)
{
  locale Cloc("C");
  stringstream S(Str);
  S.imbue(Cloc);
  T result;
  if (!(S >> result))
    throw runtime_error("Could not convert string to numeric value: '" +
	string(Str) + "'");
  Obj = result;
}

} // namespace

namespace pqxx
{

template<> void from_string(const char Str[], int &Obj)
{
  from_string_signed(Str, Obj);
}

template<> void from_string(const char Str[], unsigned int &Obj)
{
  from_string_unsigned(Str, Obj);
}

template<> void from_string(const char Str[], short &Obj)
{
  from_string_signed(Str, Obj);
}

template<> void from_string(const char Str[], unsigned short &Obj)
{
  from_string_unsigned(Str, Obj);
}

template<> void from_string(const char Str[], float &Obj)
{
  float result;
  from_string_float(Str, result);
  Obj = result;
}

template<> void from_string(const char Str[], double &Obj)
{
  from_string_float(Str, Obj);
}

template<> void from_string(const char Str[], long double &Obj)
{
  from_string_float(Str, Obj);
}

template<> void from_string(const char Str[], bool &Obj)
{
  if (!Str)
    throw runtime_error("Attempt to read NULL string");

  bool OK, result=false;

  switch (Str[0])
  {
  case 0:
    result = false;
    OK = true;
    break;

  case 'f':
  case 'F':
    result = false;
    OK = !(Str[1] &&
	   (strcmp(Str+1, "alse") != 0) &&
	   (strcmp(Str+1, "ALSE") != 0));
    break;

  case '0':
    {
      int I;
      from_string(Str, I);
      result = (I != 0);
      OK = ((I == 0) || (I == 1));
    }
    break;

  case '1':
    result = true;
    OK = !Str[1];
    break;

  case 't':
  case 'T':
    result = true;
    OK = !(Str[1] &&
	   (strcmp(Str+1, "rue") != 0) &&
	   (strcmp(Str+1, "RUE") != 0));
    break;

  default:
    OK = false;
  }

  if (!OK)
    throw invalid_argument("Failed conversion to bool: '" + string(Str) + "'");

  Obj = result;
}

} // namespace pqxx

namespace
{
template<typename T> inline string to_string_unsigned(T Obj)
{
  if (!Obj) return "0";

  char buf[4*sizeof(T)+1];
  char *p = &buf[sizeof(buf)];
  *--p = '\0';
  for (T next; Obj > 0; Obj = next)
  {
    next = Obj / 10;
    char c = ('0' + Obj - (next*10));
    *--p = c;
  }
  return p;
}

template<typename T> inline string to_string_fallback(T Obj)
{
  stringstream S;
  S << Obj;
  string R;
  S >> R;
  return R;
}

template<typename T> inline string to_string_signed(T Obj)
{
  if (Obj < 0)
  {
    // Remember--the smallest negative number for a given two's-complement type
    // cannot be negated.
    if (-Obj > 0)
      return '-' + to_string_unsigned(-Obj);
    else
      return to_string_fallback(Obj);
  }

  return to_string_unsigned(Obj);
}

} // namespace

namespace pqxx
{
template<> string to_string(const short &Obj)
{
  return to_string_signed(Obj);
}

template<> string to_string(const unsigned short &Obj)
{
  return to_string_unsigned(Obj);
}

template<> string to_string(const int &Obj)
{
  return to_string_signed(Obj);
}

template<> string to_string(const unsigned int &Obj)
{
  return to_string_unsigned(Obj);
}

template<> string to_string(const long &Obj)
{
  return to_string_signed(Obj);
}

template<> string to_string(const unsigned long &Obj)
{
  return to_string_unsigned(Obj);
}

template<> string to_string(const float &Obj)
{
  return to_string_fallback(Obj);
}

template<> string to_string(const double &Obj)
{
  return to_string_fallback(Obj);
}

template<> string to_string(const long double &Obj)
{
  return to_string_fallback(Obj);
}

template<> string to_string(const bool &Obj)
{
  return Obj ? "true" : "false";
}

template<> string to_string(const char &Obj)
{
  string s;
  s += Obj;
  return s;
}

} // namespace pqxx

void pqxx::internal::FromString_string(const char Str[], string &Obj)
{
  if (!Str)
    throw runtime_error("Attempt to convert NULL C string to C++ string");
  Obj = Str;
}

void pqxx::internal::FromString_ucharptr(const char Str[],
    const unsigned char *&Obj)
{
  const char *C;
  FromString(Str, C);
  Obj = reinterpret_cast<const unsigned char *>(C);
}

#ifdef PQXX_HAVE_PQESCAPESTRING
namespace
{
string libpq_escape(const char str[], size_t len)
{
  char *buf = 0;
  string result;

  try
  {
    /* Going by the letter of the PQescapeString() documentation we only need
     * 2*len+1 bytes.  But what happens to nonprintable characters?  They might
     * be escaped to octal notation, whether in current or future versions of
     * libpq--in which case we would need this more conservative size.
     */
    buf = new char[5*len + 1];
  }
  catch (const bad_alloc &)
  {
    /* Okay, maybe we're just dealing with an extremely large string.  Try a
     * more aggressive size limit, which is likely to be just fine.
     */
    buf = new char[2*len+1];
  }

  try
  {
    const size_t bytes = PQescapeString(buf, str, len);
    result.assign(buf, bytes);
  }
  catch (const exception &)
  {
    delete [] buf;
    throw;
  }
  delete [] buf;

  return result;
}
} // namespace
#endif

string pqxx::sqlesc(const char str[])
{
  string result;
#ifdef PQXX_HAVE_PQESCAPESTRING
  result = libpq_escape(str, strlen(str));
#else
  for (size_t i=0; str[i]; ++i)
  {
    if (isprint(str[i]))
    {
      switch (str[i])
      {
      case '\'':
      case '\\':
	result += str[i];
      }
      result += str[i];
    }
    else
    {
        char s[8];
        sprintf(s,
	        "\\%03o",
		static_cast<unsigned int>(static_cast<unsigned char>(str[i])));
        result.append(s, 4);
    }
  }
#endif
  return result;
}

string pqxx::sqlesc(const char str[], size_t len)
{
  string result;
#ifdef PQXX_HAVE_PQESCAPESTRING
  result = libpq_escape(str, len);
#else
  for (size_t i=0; (i < len) && str[i]; ++i)
  {
    if (isprint(str[i]))
    {
      switch (str[i])
      {
      case '\'':
      case '\\':
	result += str[i];
      }
      result += str[i];
    }
    else
    {
        char s[8];
        sprintf(s,
	        "\\%03o",
		static_cast<unsigned int>(static_cast<unsigned char>(str[i])));
        result.append(s, 4);
    }
  }
#endif

  return result;
}

string pqxx::sqlesc(const string &str)
{
  string result;
  for (string::const_iterator i = str.begin(); i != str.end(); ++i)
  {
    if (isprint(*i) || isspace(*i))
    {
      switch (*i)
      {
      case '\'':
      case '\\':
	result += *i;
      }
      result += *i;
    }
    else
    {
        char s[8];
        sprintf(s,
	        "\\%03o",
		static_cast<unsigned int>(static_cast<unsigned char>(*i)));
        result.append(s, 4);
    }
  }
  return result;
}

string pqxx::internal::Quote_string(const string &Obj, bool EmptyIsNull)
{
  return (EmptyIsNull && Obj.empty()) ? "null" : ("'" + sqlesc(Obj) + "'");
}

string pqxx::internal::Quote_charptr(const char Obj[], bool EmptyIsNull)
{
  return Obj ? Quote(string(Obj), EmptyIsNull) : "null";
}

string pqxx::internal::namedclass::description() const
{
  try
  {
    string desc = classname();
    if (!name().empty()) desc += " '" + name() + "'";
    return desc;
  }
  catch (const exception &)
  {
    // Oops, string composition failed!  Probably out of memory.
    // Let's try something easier.
  }
  return name().empty() ? classname() : name();
}

void pqxx::internal::CheckUniqueRegistration(const namedclass *New,
    const namedclass *Old)
{
  if (!New)
    throw logic_error("libpqxx internal error: NULL pointer registered");
  if (Old)
  {
    if (Old == New)
      throw logic_error("Started " + New->description() + " twice");
    throw logic_error("Started " + New->description() + " "
		      "while " + Old->description() + " still active");
  }
}

void pqxx::internal::CheckUniqueUnregistration(const namedclass *New,
    const namedclass *Old)
{
  if (New != Old)
  {
    if (!New)
      throw logic_error("Expected to close " + Old->description() + ", "
	  		"but got NULL pointer instead");
    if (!Old)
      throw logic_error("Closed " + New->description() + ", "
	 		"which wasn't open");
    throw logic_error("Closed " + New->description() + "; "
		      "expected to close " + Old->description());
  }
}

void pqxx::internal::freepqmem(void *p)
{
#ifdef PQXX_HAVE_PQFREEMEM
  PQfreemem(p);
#else
  free(p);
#endif
}

void pqxx::internal::freenotif(PGnotify *p)
{
#ifdef PQXX_HAVE_PQFREENOTIFY
  PQfreeNotify(p);
#else
  freepqmem(p);
#endif
}

void pqxx::internal::sleep_seconds(int s)
{
#ifdef PQXX_HAVE_SLEEP
  // Use POSIX.1 sleep() if available
  sleep(s);
#elif defined(_WIN32)
  // Windows has its own Sleep(), which speaks milliseconds
  Sleep(s*1000);
#else
  // If all else fails, use select() on nothing and specify a timeout
  fd_set F;
  FD_ZERO(&F);
  struct timeval timeout;
  timeout.tv_sec = s;
  timeout.tv_usec = 0;
  if (select(0, &F, &F, &F, &timeout) == -1)
    throw runtime_error(strerror(errno));
#endif
}

<|endoftext|>