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

/* Dlib library */
#include "../lib/dlib/all/source.cpp"

#include "globals.hpp"
#include <time.h>
#include <stdio.h>
#if 0
#ifdef _WINDOWS
#include <psapi.h>
#endif
#endif

#ifdef _WINDOWS
#define localtime_r(t, tm) localtime_s(tm, t)
#define gmtime_r(t, tm) gmtime_s(tm, t)

#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
#define DELTA_EPOCH_IN_MICROSECS  11644473600000000Ui64
#else
#define DELTA_EPOCH_IN_MICROSECS  11644473600000000ULL
#endif

#endif

using namespace std;

string int64ToString(uint64_t i)
{
  ostringstream stm;
  stm << i;
  return stm.str();
}

string intToString(unsigned int i)
{
  ostringstream stm;
  stm << i;
  return stm.str();
}

string floatToString(double f)
{
  char s[32];
  sprintf(s, "%.7g", f);
  return (string) s;
}

string toUpperCase(string& text)
{
  for (unsigned int i = 0; i < text.length(); i++)
  {
    text[i] = toupper(text[i]);
  }

  return text;
}

bool isNonNegativeInteger(const string& s)
{
  for (unsigned int i = 0; i < s.length(); i++)
  {
    if (!isdigit(s[i]))
    {
      return false;
    }
  }

  return true;
}

string getCurrentTime(TimeFormat format)
{
  char timestamp[64];
  struct tm timeinfo;
  time_t sec;
  long usec;

  if (format == GMT_UV_SEC)
  {
#ifdef _WINDOWS
    FILETIME ft;
    unsigned __int64 tmpres = 0;
    static int tzflag;

    GetSystemTimeAsFileTime(&ft);

    tmpres |= ft.dwHighDateTime;
    tmpres <<= 32;
    tmpres |= ft.dwLowDateTime;

    tmpres /= 10;  /*convert into microseconds*/
    tmpres -= DELTA_EPOCH_IN_MICROSECS;
    sec = (long)(tmpres / 1000000UL);
    usec = (long)(tmpres % 1000000UL);
#else
    struct timeval tv;
    gettimeofday(&tv, NULL);
    sec = tv.tv_sec;
    usec = tv.tv_usec;
#endif
  }
  else
  {
    sec = time(NULL);
  }

  if (format == LOCAL)
    localtime_r(&sec, &timeinfo);
  else
    gmtime_r(&sec, &timeinfo);

  switch (format)
  {
    case HUM_READ:
      strftime(timestamp, 50, "%a, %d %b %Y %H:%M:%S %Z", &timeinfo);
      break;
    case GMT:
      strftime(timestamp, 50, "%Y-%m-%dT%H:%M:%SZ", &timeinfo);
      break;
    case GMT_UV_SEC:
      strftime(timestamp, 50, "%Y-%m-%dT%H:%M:%S", &timeinfo);
      break;
    case LOCAL:
      strftime(timestamp, 50, "%Y-%m-%dT%H:%M:%S%z", &timeinfo);
      break;
  }

  if (format == GMT_UV_SEC)
  {
    sprintf(timestamp + strlen(timestamp), ".%06dZ", (int) usec);
  }
  else
  {
    strcat(timestamp, "Z");
  }

  return string(timestamp);
}

uint64_t getCurrentTimeInMicros()
{
  uint64_t now;
#ifdef _WINDOWS
  SYSTEMTIME st;
  GetSystemTime(&st);
  now = st.wSecond * 1000000;
  now += st.wMilliseconds;
#else
  struct timeval tv;
  struct timezone tz;

  gettimeofday(&tv, &tz);
  now = tv.tv_sec * 1000000 + tv.tv_usec;
#endif
  return now;
}

string getRelativeTimeString(uint64_t aTime)
{
  char timeBuffer[50];
  time_t seconds;
  int micros;
  struct tm * timeinfo;

  seconds = aTime / 1000000;
  micros = aTime % 1000000;

  timeinfo = gmtime(&seconds);
  strftime(timeBuffer, 50, "%Y-%m-%dT%H:%M:%S", timeinfo);
  sprintf(timeBuffer + strlen(timeBuffer), ".%06dZ", micros);

  return string(timeBuffer);
}

unsigned int getCurrentTimeInSec()
{
  return time(NULL);
}

void replaceIllegalCharacters(string& data)
{
  for (unsigned int i=0; i<data.length(); i++)
  {
    char c = data[i];
    switch (c) {
      case '&': data.replace(i, 1, "&"); break;
      case '<': data.replace(i, 1, "<"); break;
      case '>': data.replace(i, 1, ">"); break;
    }
  }
}

int getEnumeration(const string& name, const string *array, unsigned int size)
{
  for (unsigned int i = 0; i < size; i++)
  {
    if (name == array[i])
    {
       return i;
    }
  }

  return ENUM_MISS;
}

uint64_t parseTimeMicro(std::string &aTime)
{
  struct tm timeinfo;
  memset(&timeinfo, 0, sizeof(timeinfo));
  char ms[16];

  int c = sscanf(aTime.c_str(), "%d-%d-%dT%d:%d:%d%15s", &timeinfo.tm_year, &timeinfo.tm_mon, &timeinfo.tm_mday,
                 &timeinfo.tm_hour, &timeinfo.tm_min, &timeinfo.tm_sec, (char*) &ms);
  ms[15] = '\0';

  timeinfo.tm_mon -= 1;
  timeinfo.tm_year -= 1900;

  if (c < 7)
    return 0;

  uint64_t time = (mktime(&timeinfo) - timezone) * 1000000;

  int ms_v = 0;
  int len = strlen(ms);
  if (len > 0) {
    ms_v = strtol(ms + 1, 0, 10);
    for (int pf = 7 - len; pf > 0; pf--)
      ms_v *= 10;
  }

  return time + ms_v;
}

static string::size_type insertPrefix(string &aPath, string::size_type &aPos,
				      const string aPrefix)
{
  aPath.insert(aPos, aPrefix);
  aPos += aPrefix.length();
  aPath.insert(aPos++, ":");

  return aPos;
}

static bool hasNamespace(const string &aPath, string::size_type aStart)
{
  string::size_type len = aPath.length(), pos = aStart;
  while (pos < len)
  {
    if (aPath[pos] == ':')
      return true;
    else if (!isalpha(aPath[pos]))
      return false;
    pos++;
  }

  return false;
}

string addNamespace(const string aPath, const string aPrefix)
{
  if (aPrefix.empty())
    return aPath;

  string newPath = aPath;
  string::size_type pos = 0;
  // Special case for relative pathing
  if (newPath[pos] != '/')
  {
    if (!hasNamespace(newPath, pos))
      insertPrefix(newPath, pos, aPrefix);
  }

  while ((pos = newPath.find('/', pos)) != string::npos && pos < newPath.length() - 1)
  {
    pos ++;
    if (newPath[pos] == '/')
      pos++;

    // Make sure there are no existing prefixes
    if (newPath[pos] != '*' && newPath[pos] != '\0' && !hasNamespace(newPath, pos))
      insertPrefix(newPath, pos, aPrefix);
  }

  pos = 0;
  while ((pos = newPath.find('|', pos)) != string::npos)
  {
    pos ++;
    if (newPath[pos] != '/' && !hasNamespace(newPath, pos))
      insertPrefix(newPath, pos, aPrefix);
  }

  return newPath;
}

bool isMTConnectUrn(const char *aUrn)
{
  return strncmp(aUrn, "urn:mtconnect.org:MTConnect", 27) == 0;
}

#if 0
long getMemorySize()
{
  long size = 0;

#ifdef _WINDOWS
  HANDLE myself = GetCurrentProcess();
  PROCESS_MEMORY_COUNTERS memory;
  if (GetProcessMemoryInfo(myself, &memory, sizeof(memory))) {
    size = (long) (memory.PeakWorkingSetSize / 1024);
  }
#else
  struct rusage memory;
  if (getrusage(RUSAGE_SELF, &memory) == 0) {
    size = memory.ru_maxrss;
  }
#endif

  return size;
}
#endif
<commit_msg>made get current time micros use file time for more accuracy.<commit_after>/*
 * Copyright Copyright 2012, System Insights, Inc.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/* Dlib library */
#include "../lib/dlib/all/source.cpp"

#include "globals.hpp"
#include <time.h>
#include <stdio.h>
#if 0
#ifdef _WINDOWS
#include <psapi.h>
#endif
#endif

#ifdef _WINDOWS
#define localtime_r(t, tm) localtime_s(tm, t)
#define gmtime_r(t, tm) gmtime_s(tm, t)

#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
#define DELTA_EPOCH_IN_MICROSECS  11644473600000000Ui64
#else
#define DELTA_EPOCH_IN_MICROSECS  11644473600000000ULL
#endif

#endif

using namespace std;

string int64ToString(uint64_t i)
{
  ostringstream stm;
  stm << i;
  return stm.str();
}

string intToString(unsigned int i)
{
  ostringstream stm;
  stm << i;
  return stm.str();
}

string floatToString(double f)
{
  char s[32];
  sprintf(s, "%.7g", f);
  return (string) s;
}

string toUpperCase(string& text)
{
  for (unsigned int i = 0; i < text.length(); i++)
  {
    text[i] = toupper(text[i]);
  }

  return text;
}

bool isNonNegativeInteger(const string& s)
{
  for (unsigned int i = 0; i < s.length(); i++)
  {
    if (!isdigit(s[i]))
    {
      return false;
    }
  }

  return true;
}

string getCurrentTime(TimeFormat format)
{
  char timestamp[64];
  struct tm timeinfo;
  time_t sec;
  long usec;

  if (format == GMT_UV_SEC)
  {
#ifdef _WINDOWS
    FILETIME ft;
    unsigned __int64 tmpres = 0;
    static int tzflag;

    GetSystemTimeAsFileTime(&ft);

    tmpres |= ft.dwHighDateTime;
    tmpres <<= 32;
    tmpres |= ft.dwLowDateTime;

    tmpres /= 10;  /*convert into microseconds*/
    tmpres -= DELTA_EPOCH_IN_MICROSECS;
    sec = (long)(tmpres / 1000000UL);
    usec = (long)(tmpres % 1000000UL);
#else
    struct timeval tv;
    gettimeofday(&tv, NULL);
    sec = tv.tv_sec;
    usec = tv.tv_usec;
#endif
  }
  else
  {
    sec = time(NULL);
  }

  if (format == LOCAL)
    localtime_r(&sec, &timeinfo);
  else
    gmtime_r(&sec, &timeinfo);

  switch (format)
  {
    case HUM_READ:
      strftime(timestamp, 50, "%a, %d %b %Y %H:%M:%S %Z", &timeinfo);
      break;
    case GMT:
      strftime(timestamp, 50, "%Y-%m-%dT%H:%M:%SZ", &timeinfo);
      break;
    case GMT_UV_SEC:
      strftime(timestamp, 50, "%Y-%m-%dT%H:%M:%S", &timeinfo);
      break;
    case LOCAL:
      strftime(timestamp, 50, "%Y-%m-%dT%H:%M:%S%z", &timeinfo);
      break;
  }

  if (format == GMT_UV_SEC)
  {
    sprintf(timestamp + strlen(timestamp), ".%06dZ", (int) usec);
  }
  else
  {
    strcat(timestamp, "Z");
  }

  return string(timestamp);
}

uint64_t getCurrentTimeInMicros()
{
  uint64_t now;
#ifdef _WINDOWS
  FILETIME ft;
  unsigned __int64 tmpres = 0;
  static int tzflag;

  GetSystemTimeAsFileTime(&ft);

  now |= ft.dwHighDateTime;
  now <<= 32;
  now |= ft.dwLowDateTime;

  now /= 10;  /*convert into microseconds*/
  now -= DELTA_EPOCH_IN_MICROSECS;
#else
  struct timeval tv;
  struct timezone tz;

  gettimeofday(&tv, &tz);
  now = tv.tv_sec * 1000000 + tv.tv_usec;
#endif
  return now;
}

string getRelativeTimeString(uint64_t aTime)
{
  char timeBuffer[50];
  time_t seconds;
  int micros;
  struct tm * timeinfo;

  seconds = aTime / 1000000;
  micros = aTime % 1000000;

  timeinfo = gmtime(&seconds);
  strftime(timeBuffer, 50, "%Y-%m-%dT%H:%M:%S", timeinfo);
  sprintf(timeBuffer + strlen(timeBuffer), ".%06dZ", micros);

  return string(timeBuffer);
}

unsigned int getCurrentTimeInSec()
{
  return time(NULL);
}

void replaceIllegalCharacters(string& data)
{
  for (unsigned int i=0; i<data.length(); i++)
  {
    char c = data[i];
    switch (c) {
      case '&': data.replace(i, 1, "&"); break;
      case '<': data.replace(i, 1, "<"); break;
      case '>': data.replace(i, 1, ">"); break;
    }
  }
}

int getEnumeration(const string& name, const string *array, unsigned int size)
{
  for (unsigned int i = 0; i < size; i++)
  {
    if (name == array[i])
    {
       return i;
    }
  }

  return ENUM_MISS;
}

uint64_t parseTimeMicro(std::string &aTime)
{
  struct tm timeinfo;
  memset(&timeinfo, 0, sizeof(timeinfo));
  char ms[16];

  int c = sscanf(aTime.c_str(), "%d-%d-%dT%d:%d:%d%15s", &timeinfo.tm_year, &timeinfo.tm_mon, &timeinfo.tm_mday,
                 &timeinfo.tm_hour, &timeinfo.tm_min, &timeinfo.tm_sec, (char*) &ms);
  ms[15] = '\0';

  timeinfo.tm_mon -= 1;
  timeinfo.tm_year -= 1900;

  if (c < 7)
    return 0;

  uint64_t time = (mktime(&timeinfo) - timezone) * 1000000;

  int ms_v = 0;
  int len = strlen(ms);
  if (len > 0) {
    ms_v = strtol(ms + 1, 0, 10);
    for (int pf = 7 - len; pf > 0; pf--)
      ms_v *= 10;
  }

  return time + ms_v;
}

static string::size_type insertPrefix(string &aPath, string::size_type &aPos,
				      const string aPrefix)
{
  aPath.insert(aPos, aPrefix);
  aPos += aPrefix.length();
  aPath.insert(aPos++, ":");

  return aPos;
}

static bool hasNamespace(const string &aPath, string::size_type aStart)
{
  string::size_type len = aPath.length(), pos = aStart;
  while (pos < len)
  {
    if (aPath[pos] == ':')
      return true;
    else if (!isalpha(aPath[pos]))
      return false;
    pos++;
  }

  return false;
}

string addNamespace(const string aPath, const string aPrefix)
{
  if (aPrefix.empty())
    return aPath;

  string newPath = aPath;
  string::size_type pos = 0;
  // Special case for relative pathing
  if (newPath[pos] != '/')
  {
    if (!hasNamespace(newPath, pos))
      insertPrefix(newPath, pos, aPrefix);
  }

  while ((pos = newPath.find('/', pos)) != string::npos && pos < newPath.length() - 1)
  {
    pos ++;
    if (newPath[pos] == '/')
      pos++;

    // Make sure there are no existing prefixes
    if (newPath[pos] != '*' && newPath[pos] != '\0' && !hasNamespace(newPath, pos))
      insertPrefix(newPath, pos, aPrefix);
  }

  pos = 0;
  while ((pos = newPath.find('|', pos)) != string::npos)
  {
    pos ++;
    if (newPath[pos] != '/' && !hasNamespace(newPath, pos))
      insertPrefix(newPath, pos, aPrefix);
  }

  return newPath;
}

bool isMTConnectUrn(const char *aUrn)
{
  return strncmp(aUrn, "urn:mtconnect.org:MTConnect", 27) == 0;
}

#if 0
long getMemorySize()
{
  long size = 0;

#ifdef _WINDOWS
  HANDLE myself = GetCurrentProcess();
  PROCESS_MEMORY_COUNTERS memory;
  if (GetProcessMemoryInfo(myself, &memory, sizeof(memory))) {
    size = (long) (memory.PeakWorkingSetSize / 1024);
  }
#else
  struct rusage memory;
  if (getrusage(RUSAGE_SELF, &memory) == 0) {
    size = memory.ru_maxrss;
  }
#endif

  return size;
}
#endif
<|endoftext|>


<commit_before>// Copyright (C) 2016 Elviss Strazdins
// This file is part of the Ouzel engine.

#include <cstdlib>
#include <GL/gl.h>
#include <GL/glext.h>
#include "ApplicationLinux.h"
#include "core/Engine.h"
#include "events/Event.h"
#include "input/Input.h"
#include "input/linux/InputLinux.h"
#include "WindowLinux.h"

namespace ouzel
{
    ApplicationLinux::ApplicationLinux(int aArgc, char* aArgv[]):
        Application(aArgc, aArgv)
    {
    }

    int ApplicationLinux::run()
    {
        ouzelMain(args);

        if (!sharedEngine)
        {
            return EXIT_FAILURE;
        }

        sharedEngine->begin();

        if (sharedEngine->getRenderer()->getDriver() == graphics::Renderer::Driver::EMPTY)
        {
            for (;;)
            {
                executeAll();

                if (!sharedEngine->draw())
                {
                    sharedEngine->exit();
                    break;
                }
            }
        }
        else
        {
            XEvent event;

            WindowLinux* windowLinux = static_cast<WindowLinux*>(sharedEngine->getWindow());

            while (active)
            {
                executeAll();

                if (sharedEngine->draw())
                {
                    while (sharedEngine->isActive())
                    {
                        // XNextEvent will block if there is no event pending, so don't call it if engine is running
                        if (sharedEngine->isRunning() && !XPending(windowLinux->getDisplay()))
                        {
                            break;
                        }

                        XNextEvent(windowLinux->getDisplay(), &event);

                        switch (event.type)
                        {
                            case ClientMessage:
                            {
                                if (static_cast<Atom>(event.xclient.data.l[0]) == windowLinux->getDeleteMessage())
                                {
                                    sharedEngine->exit();
                                }
                                break;
                            }
                            case FocusIn:
                                sharedEngine->resume();
                                break;
                            case FocusOut:
                                sharedEngine->pause();
                                break;
                            case KeyPress: // keyboard
                            case KeyRelease:
                            {
                                KeySym keySym = XkbKeycodeToKeysym(windowLinux->getDisplay(), event.xkey.keycode, 0, event.xkey.state & ShiftMask ? 1 : 0);

                                if (event.type == KeyPress)
                                {
                                    sharedEngine->getInput()->keyDown(input::InputLinux::convertKeyCode(keySym),
                                                                      input::InputLinux::getModifiers(event.xkey.state));
                                }
                                else
                                {
                                    sharedEngine->getInput()->keyUp(input::InputLinux::convertKeyCode(keySym),
                                                                    input::InputLinux::getModifiers(event.xkey.state));
                                }
                                break;
                            }
                            case ButtonPress: // mouse button
                            case ButtonRelease:
                            {
                                Vector2 pos(static_cast<float>(event.xbutton.x),
                                            static_cast<float>(event.xbutton.y));

                                input::MouseButton button;

                                switch (event.xbutton.button)
                                {
                                case 1:
                                    button = input::MouseButton::LEFT;
                                    break;
                                case 2:
                                    button = input::MouseButton::RIGHT;
                                    break;
                                case 3:
                                    button = input::MouseButton::MIDDLE;
                                    break;
                                default:
                                    button = input::MouseButton::NONE;
                                    break;
                                }

                                if (event.type == ButtonPress)
                                {
                                    sharedEngine->getInput()->mouseDown(button,
                                                                        sharedEngine->getWindow()->convertWindowToNormalizedLocation(pos),
                                                                        input::InputLinux::getModifiers(event.xbutton.state));
                                }
                                else
                                {
                                    sharedEngine->getInput()->mouseUp(button,
                                                                      sharedEngine->getWindow()->convertWindowToNormalizedLocation(pos),
                                                                      input::InputLinux::getModifiers(event.xbutton.state));
                                }
                                break;
                            }
                            case MotionNotify:
                            {
                                Vector2 pos(static_cast<float>(event.xmotion.x),
                                            static_cast<float>(event.xmotion.y));

                                sharedEngine->getInput()->mouseMove(sharedEngine->getWindow()->convertWindowToNormalizedLocation(pos),
                                                                    input::InputLinux::getModifiers(event.xmotion.state));

                                break;
                            }
                            case ConfigureNotify:
                            {
                                windowLinux->handleResize(Size2(static_cast<float>(event.xconfigure.width),
                                                                static_cast<float>(event.xconfigure.height)));
                                break;
                            }
                            case Expose:
                            {
                                // need redraw
                                break;
                            }
                        }
                    }
                }
                else
                {
                    break;
                }
            }
        }

        sharedEngine->end();

        return EXIT_SUCCESS;
    }
}
<commit_msg>Fix Linux exit<commit_after>// Copyright (C) 2016 Elviss Strazdins
// This file is part of the Ouzel engine.

#include <cstdlib>
#include <GL/gl.h>
#include <GL/glext.h>
#include "ApplicationLinux.h"
#include "core/Engine.h"
#include "events/Event.h"
#include "input/Input.h"
#include "input/linux/InputLinux.h"
#include "WindowLinux.h"

namespace ouzel
{
    ApplicationLinux::ApplicationLinux(int aArgc, char* aArgv[]):
        Application(aArgc, aArgv)
    {
    }

    int ApplicationLinux::run()
    {
        ouzelMain(args);

        if (!sharedEngine)
        {
            return EXIT_FAILURE;
        }

        sharedEngine->begin();

        if (sharedEngine->getRenderer()->getDriver() == graphics::Renderer::Driver::EMPTY)
        {
            for (;;)
            {
                executeAll();

                if (!sharedEngine->draw())
                {
                    break;
                }
            }
        }
        else
        {
            XEvent event;

            WindowLinux* windowLinux = static_cast<WindowLinux*>(sharedEngine->getWindow());

            while (active)
            {
                executeAll();

                if (sharedEngine->draw())
                {
                    while (sharedEngine->isActive())
                    {
                        // XNextEvent will block if there is no event pending, so don't call it if engine is running
                        if (sharedEngine->isRunning() && !XPending(windowLinux->getDisplay()))
                        {
                            break;
                        }

                        XNextEvent(windowLinux->getDisplay(), &event);

                        switch (event.type)
                        {
                            case ClientMessage:
                            {
                                if (static_cast<Atom>(event.xclient.data.l[0]) == windowLinux->getDeleteMessage())
                                {
                                    exit();
                                }
                                break;
                            }
                            case FocusIn:
                                sharedEngine->resume();
                                break;
                            case FocusOut:
                                sharedEngine->pause();
                                break;
                            case KeyPress: // keyboard
                            case KeyRelease:
                            {
                                KeySym keySym = XkbKeycodeToKeysym(windowLinux->getDisplay(), event.xkey.keycode, 0, event.xkey.state & ShiftMask ? 1 : 0);

                                if (event.type == KeyPress)
                                {
                                    sharedEngine->getInput()->keyDown(input::InputLinux::convertKeyCode(keySym),
                                                                      input::InputLinux::getModifiers(event.xkey.state));
                                }
                                else
                                {
                                    sharedEngine->getInput()->keyUp(input::InputLinux::convertKeyCode(keySym),
                                                                    input::InputLinux::getModifiers(event.xkey.state));
                                }
                                break;
                            }
                            case ButtonPress: // mouse button
                            case ButtonRelease:
                            {
                                Vector2 pos(static_cast<float>(event.xbutton.x),
                                            static_cast<float>(event.xbutton.y));

                                input::MouseButton button;

                                switch (event.xbutton.button)
                                {
                                case 1:
                                    button = input::MouseButton::LEFT;
                                    break;
                                case 2:
                                    button = input::MouseButton::RIGHT;
                                    break;
                                case 3:
                                    button = input::MouseButton::MIDDLE;
                                    break;
                                default:
                                    button = input::MouseButton::NONE;
                                    break;
                                }

                                if (event.type == ButtonPress)
                                {
                                    sharedEngine->getInput()->mouseDown(button,
                                                                        sharedEngine->getWindow()->convertWindowToNormalizedLocation(pos),
                                                                        input::InputLinux::getModifiers(event.xbutton.state));
                                }
                                else
                                {
                                    sharedEngine->getInput()->mouseUp(button,
                                                                      sharedEngine->getWindow()->convertWindowToNormalizedLocation(pos),
                                                                      input::InputLinux::getModifiers(event.xbutton.state));
                                }
                                break;
                            }
                            case MotionNotify:
                            {
                                Vector2 pos(static_cast<float>(event.xmotion.x),
                                            static_cast<float>(event.xmotion.y));

                                sharedEngine->getInput()->mouseMove(sharedEngine->getWindow()->convertWindowToNormalizedLocation(pos),
                                                                    input::InputLinux::getModifiers(event.xmotion.state));

                                break;
                            }
                            case ConfigureNotify:
                            {
                                windowLinux->handleResize(Size2(static_cast<float>(event.xconfigure.width),
                                                                static_cast<float>(event.xconfigure.height)));
                                break;
                            }
                            case Expose:
                            {
                                // need redraw
                                break;
                            }
                        }
                    }
                }
                else
                {
                    break;
                }
            }
        }

        sharedEngine->end();

        return EXIT_SUCCESS;
    }
}
<|endoftext|>


<commit_before>//---------------------------------------------------------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 2004, 2005, 2006, 2008, 2012, 2013 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//---------------------------------------------------------------------------

#include <deal.II/lac/petsc_parallel_block_vector.h>

#ifdef DEAL_II_WITH_PETSC

#  include <deal.II/lac/petsc_block_vector.h>

DEAL_II_NAMESPACE_OPEN

namespace PETScWrappers
{
  namespace MPI
  {
    typedef types::global_dof_index size_type;

    BlockVector &
    BlockVector::operator = (const PETScWrappers::BlockVector &v)
    {
      Assert (v.get_block_indices() == this->get_block_indices(),
              ExcNonMatchingBlockVectors());

      for (unsigned int i=0; i<this->n_blocks(); ++i)
        this->block(i) = v.block(i);

      return *this;
    }

    void
    BlockVector::reinit (const unsigned int num_blocks)
    {
      std::vector<size_type> block_sizes (num_blocks, 0);
      this->block_indices.reinit (block_sizes);
      if (this->components.size() != this->n_blocks())
        this->components.resize(this->n_blocks());

      for (unsigned int i=0; i<this->n_blocks(); ++i)
        components[i].reinit (MPI_Comm(), 0, 0);

      collect_sizes();
    }
  }

}

DEAL_II_NAMESPACE_CLOSE

#endif // DEAL_II_WITH_PETSC
<commit_msg>pull fix to mainline<commit_after>//---------------------------------------------------------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 2004, 2005, 2006, 2008, 2012, 2013 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//---------------------------------------------------------------------------

#include <deal.II/lac/petsc_parallel_block_vector.h>

#ifdef DEAL_II_WITH_PETSC

#  include <deal.II/lac/petsc_block_vector.h>

DEAL_II_NAMESPACE_OPEN

namespace PETScWrappers
{
  namespace MPI
  {
    typedef types::global_dof_index size_type;

    BlockVector &
    BlockVector::operator = (const PETScWrappers::BlockVector &v)
    {
      Assert (v.get_block_indices() == this->get_block_indices(),
              ExcNonMatchingBlockVectors());

      for (unsigned int i=0; i<this->n_blocks(); ++i)
        this->block(i) = v.block(i);

      return *this;
    }

    void
    BlockVector::reinit (const unsigned int num_blocks)
    {
      std::vector<size_type> block_sizes (num_blocks, 0);
      this->block_indices.reinit (block_sizes);
      if (this->components.size() != this->n_blocks())
        this->components.resize(this->n_blocks());

      for (unsigned int i=0; i<this->n_blocks(); ++i)
        components[i].reinit (MPI_COMM_SELF, 0, 0);

      collect_sizes();
    }
  }

}

DEAL_II_NAMESPACE_CLOSE

#endif // DEAL_II_WITH_PETSC
<|endoftext|>


<commit_before>/*! \file urbi/uclient.hh
****************************************************************************
 * Definition of the URBI interface class
 *
 * Copyright (C) 2004, 2006, 2007, 2008, 2009 Jean-Christophe Baillie.
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
**********************************************************************/

#ifndef URBI_UCLIENT_HH
# define URBI_UCLIENT_HH

# include <libport/asio.hh>
# include <libport/pthread.h>
# include <libport/semaphore.hh>
# include <libport/utime.hh>

# include <urbi/uabstractclient.hh>

namespace urbi
{
  ///Linux implementation of UAbstractClient.
  /*! This implementation creates a thread for each instance of UClient, which
    listens on the associated socket.
  */
  class URBI_SDK_API UClient
    : public UAbstractClient
    , protected libport::Socket
  {
  public:
    using UAbstractClient::DEFAULT_HOST;

    /// Construction options.
    struct options
    {
      /// Backward compatibility with the previous UClient::UClient
      /// interface.  Don't make it "explicit" so that we can call
      /// "UClient(host, port)" and have the expected "server ==
      /// false".
      ///
      /// start defaults to true, for backward compatibility too.
      options(bool server = false);
# define UCLIENT_OPTION(Type, Name)    \
    public:                                     \
      options& Name(Type b);          \
      Type Name() const;                        \
    private:                                    \
      Type Name ## _;

      /// Whether in server mode.
      UCLIENT_OPTION(bool, server);
      /// Whether the socket autostarts.
      UCLIENT_OPTION(bool, start);
    };

# define UCLIENT_OPTION_IMPL(Class, Type, Name) \
  Class::options&                             \
  Class::options::Name(Type v)                \
  {                                             \
    Name ## _ = v;                              \
    return *this;                               \
  }                                             \
                                                \
  Type                                          \
  Class::options::Name() const                \
  {                                             \
    return Name ## _;                           \
  }

    /// \param opt  options: whether server, whether autostart.
    UClient(const std::string& host = DEFAULT_HOST,
            unsigned port = URBI_PORT,
	    size_t buflen = URBI_BUFLEN,
	    const options& opt = options());

    virtual ~UClient();

    /// Bounce to listen or connect, depending whether server mode.
    error_type start();
  protected:
    virtual error_type onClose();

  public:
    int closeUClient ();

    virtual void printf(const char * format, ...);
    virtual unsigned int getCurrentTime() const;

    UCallbackAction pong(const UMessage& msg);

    /// Activate KeepAlive functionality.
    /// \param pingInterval  is in milliseconds.
    /// \param pongTimeout   is in milliseconds.
    virtual void setKeepAliveCheck(unsigned pingInterval,
                                   unsigned pongTimeout);

    using UAbstractClient::send;

  protected:
    virtual int effectiveSend(const void* buffer, size_t size);

    libport::Socket* mySocketFactory();

    virtual void onConnect();

    virtual void onError(boost::system::error_code erc);

    virtual int onRead(const void*, size_t length);

  protected:
    /// Delay (in microseconds) without activity to check if the
    /// connection is yet available.
    libport::utime_t ping_interval_;

    /// Delay (in microseconds) of timeout to wait 'PONG'.
    libport::utime_t pong_timeout_;

    /// Send timeout error.
    void pongTimeout();

    void sendPing();

    libport::utime_t ping_sent_;

    libport::AsyncCallHandler pong_timeout_handler_;

    libport::Semaphore ping_sem_;

  private:
    /// Wrapper around Socket::connect.
    /// Client mode.
    error_type connect_();
    /// Wrapper around Socket::listen.
    /// Server mode.
    error_type listen_();
  };

} // namespace urbi
#endif
<commit_msg>uclient: publicly inherit from libport::Socket.<commit_after>/*! \file urbi/uclient.hh
****************************************************************************
 * Definition of the URBI interface class
 *
 * Copyright (C) 2004, 2006, 2007, 2008, 2009 Jean-Christophe Baillie.
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
**********************************************************************/

#ifndef URBI_UCLIENT_HH
# define URBI_UCLIENT_HH

# include <libport/asio.hh>
# include <libport/pthread.h>
# include <libport/semaphore.hh>
# include <libport/utime.hh>

# include <urbi/uabstractclient.hh>

namespace urbi
{
  ///Linux implementation of UAbstractClient.
  /*! This implementation creates a thread for each instance of UClient, which
    listens on the associated socket.
  */
  class URBI_SDK_API UClient
    : public UAbstractClient
    , public libport::Socket
  {
  public:
    using UAbstractClient::DEFAULT_HOST;

    /// Construction options.
    struct options
    {
      /// Backward compatibility with the previous UClient::UClient
      /// interface.  Don't make it "explicit" so that we can call
      /// "UClient(host, port)" and have the expected "server ==
      /// false".
      ///
      /// start defaults to true, for backward compatibility too.
      options(bool server = false);
# define UCLIENT_OPTION(Type, Name)    \
    public:                                     \
      options& Name(Type b);          \
      Type Name() const;                        \
    private:                                    \
      Type Name ## _;

      /// Whether in server mode.
      UCLIENT_OPTION(bool, server);
      /// Whether the socket autostarts.
      UCLIENT_OPTION(bool, start);
    };

# define UCLIENT_OPTION_IMPL(Class, Type, Name) \
  Class::options&                             \
  Class::options::Name(Type v)                \
  {                                             \
    Name ## _ = v;                              \
    return *this;                               \
  }                                             \
                                                \
  Type                                          \
  Class::options::Name() const                \
  {                                             \
    return Name ## _;                           \
  }

    /// \param opt  options: whether server, whether autostart.
    UClient(const std::string& host = DEFAULT_HOST,
            unsigned port = URBI_PORT,
	    size_t buflen = URBI_BUFLEN,
	    const options& opt = options());

    virtual ~UClient();

    /// Bounce to listen or connect, depending whether server mode.
    error_type start();
  protected:
    virtual error_type onClose();

  public:
    int closeUClient ();

    virtual void printf(const char * format, ...);
    virtual unsigned int getCurrentTime() const;

    UCallbackAction pong(const UMessage& msg);

    /// Activate KeepAlive functionality.
    /// \param pingInterval  is in milliseconds.
    /// \param pongTimeout   is in milliseconds.
    virtual void setKeepAliveCheck(unsigned pingInterval,
                                   unsigned pongTimeout);

    using UAbstractClient::send;

  protected:
    virtual int effectiveSend(const void* buffer, size_t size);

    libport::Socket* mySocketFactory();

    virtual void onConnect();

    virtual void onError(boost::system::error_code erc);

    virtual int onRead(const void*, size_t length);

  protected:
    /// Delay (in microseconds) without activity to check if the
    /// connection is yet available.
    libport::utime_t ping_interval_;

    /// Delay (in microseconds) of timeout to wait 'PONG'.
    libport::utime_t pong_timeout_;

    /// Send timeout error.
    void pongTimeout();

    void sendPing();

    libport::utime_t ping_sent_;

    libport::AsyncCallHandler pong_timeout_handler_;

    libport::Semaphore ping_sem_;

  private:
    /// Wrapper around Socket::connect.
    /// Client mode.
    error_type connect_();
    /// Wrapper around Socket::listen.
    /// Server mode.
    error_type listen_();
  };

} // namespace urbi
#endif
<|endoftext|>


<commit_before>#include <CoinMpsIO.hpp>

#include "DcoModel.hpp"
#include "DcoMessage.hpp"
#include "DcoTreeNode.hpp"
#include "DcoNodeDesc.hpp"
#include "DcoVariable.hpp"
#include "DcoLinearConstraint.hpp"
#include "DcoConicConstraint.hpp"

DcoModel::DcoModel() {
  solver_ = NULL;
  colLB_ = NULL;
  colUB_ = NULL;
  rowLB_ = NULL;
  rowUB_ = NULL;
  numCols_ = 0;
  numRows_ = 0;
  numLinearRows_ = 0;
  numConicRows_ = 0;
  matrix_ = NULL;
  objSense_ = 0.0;
  objCoef_ = NULL;
  numIntegerCols_ = 0;
  integerCols_ = NULL;
  numSolutions_ = 0;
  // todo(aykut) this might create problems.
  incObjValue_ = 0.0;
  incumbentSol_ = NULL;
  // todo(aykut) following two might create problems.
  cutoff_ = 0.0;
  cutoffInc_ = 0.0;
  currRelGap_ = 1e5;
  currAbsGap_ = 1e5;
  branchStrategy_ = NULL;
  rampUpBranchStrategy_ = NULL;
  activeNode_ = NULL;
  dcoPar_ = new DcoParams();
  numNodes_ = 0;
  numIterations_ = 0;;
  aveIterations_ = 0;
  numRelaxedCols_ = 0;
  relaxedCols_ = NULL;
  numRelaxedRows_ = 0;
  relaxedRows_ = NULL;
  dcoMessageHandler_ = new CoinMessageHandler();
#ifdef DISCO_DEBUG
  dcoMessageHandler_->setLogLevel(4);
#endif
  dcoMessages_ = new DcoMessage();
}

DcoModel::~DcoModel() {
  // solver_ is freed in main function.
  if (matrix_) {
    delete matrix_;
  }
  if (colLB_) {
    delete[] colLB_;
  }
  if (colUB_) {
    delete[] colUB_;
  }
  if (rowLB_) {
    delete[] rowLB_;
  }
  if (rowUB_) {
    delete[] rowUB_;
  }
  if (objCoef_) {
    delete[] objCoef_;
  }
  if (incumbentSol_) {
    delete[] incumbentSol_;
  }
  if (branchStrategy_) {
    delete branchStrategy_;
  }
  if (rampUpBranchStrategy_) {
    delete rampUpBranchStrategy_;
  }
  if (activeNode_) {
    delete activeNode_;
  }
  if (dcoPar_) {
    delete dcoPar_;
  }
  if (dcoMessageHandler_) {
    delete dcoMessageHandler_;
  }
  if (dcoMessages_) {
    delete dcoMessages_;
  }
  if (relaxedCols_) {
    delete[] relaxedCols_;
  }
  if (relaxedRows_) {
    delete[] relaxedRows_;
  }
}

#if defined(__OA__)
void DcoModel::setSolver(OsiSolverInterface * solver) {
  solver_ = solver;
}
#else
void DcoModel::setSolver(OsiConicSolverInterface * solver) {
  solver_ = solver;
}
#endif

void DcoModel::readInstance(char const * dataFile) {
  // get log level parameters
  int dcoLogLevel =  dcoPar_->entry(DcoParams::logLevel);
  // get input file name
  std::string input_file(dataFile);
  std::string base_name = input_file.substr(0, input_file.rfind('.'));
  std::string extension = input_file.substr(input_file.rfind('.')+1);
  if (extension.compare("mps")) {
    dcoMessageHandler_->message(DISCO_READ_MPSFILEONLY,
				*dcoMessages_) << CoinMessageEol;
  }
  // read mps file
  CoinMpsIO * reader = new CoinMpsIO;
  reader->messageHandler()->setLogLevel(dcoLogLevel);
  reader->readMps(dataFile, "");
  numCols_ = reader->getNumCols();
  numLinearRows_ = reader->getNumRows();
  matrix_ = new CoinPackedMatrix(*(reader->getMatrixByCol()));
  // == allocate variable bounds
  colLB_ = new double [numCols_];
  colUB_ = new double [numCols_];
  // == allocate row bounds
  rowLB_ = new double [numRows_];
  rowUB_ = new double [numRows_];
  // == copy bounds
  std::copy(reader->getColLower(), reader->getColLower()+numCols_, colLB_);
  std::copy(reader->getColUpper(), reader->getColUpper()+numCols_, colUB_);
  std::copy(reader->getRowLower(), reader->getRowLower()+numLinearRows_, rowLB_);
  std::copy(reader->getRowUpper(), reader->getRowUpper()+numLinearRows_, rowUB_);
  // == set objective sense
  objSense_ = dcoPar_->entry(DcoParams::objSense);
  // == allocate objective coefficients
  objCoef_ = new double [numCols_];
  double const * reader_obj = reader->getObjCoefficients();
  if (objSense_ > 0.0) {
    std::copy(reader_obj, reader_obj+numCols_, objCoef_);
  }
  else {
    for (int i = 0; i<numCols_; ++i) {
      objCoef_[i] = -reader_obj[i];
    }
  }
  // == load data to solver
  solver_->loadProblem(*matrix_, colLB_, colUB_, objCoef_,
		       rowLB_, rowUB_);
  // == add variables to the model
  readAddVariables(reader);
  // == add linear constraints to the model
  readAddLinearConstraints(reader);
  // == add conic constraints to the model
  readAddConicConstraints(reader);
  delete reader;
}

// Add variables to *this.
void DcoModel::readAddVariables(CoinMpsIO * reader) {
  // get variable integrality constraints
  char const * is_integer = reader->integerColumns();
  DcoIntegralityType * i_type = new DcoIntegralityType[numCols_];
  for (int i=0; i<numCols_; ++i) {
    if (is_integer[i]) {
      i_type[i] = DcoIntegralityTypeInt;
    }
    else {
      i_type[i] = DcoIntegralityTypeCont;
    }
  }
  // add variables
  BcpsVariable ** variables = new BcpsVariable*[numCols_];
  for (int i=0; i<numCols_; ++i) {
    variables[i] = new DcoVariable(colLB_[i], colUB_[i], colLB_[i],
				   colLB_[i], i_type[i]);
  }
  setVariables(variables, numCols_);
  delete[] i_type;
  // variables are now owned by BcpsModel, do not free them.
  // for (int i=0; i<numCols_; ++i) {
  //   delete variables[i];
  // }
  delete[] variables;
}

void DcoModel::readAddLinearConstraints(CoinMpsIO * reader) {
  // == add constraints to *this
  BcpsConstraint ** constraints = new BcpsConstraint*[numLinearRows_];
  CoinPackedMatrix const * matrix = reader->getMatrixByRow();
  int const * indices = matrix->getIndices();
  double const * values = matrix->getElements();
  int const * lengths = matrix->getVectorLengths();
  int const * starts = matrix->getVectorStarts();
  for (int i=0; i<numLinearRows_; ++i) {
    constraints[i] = new DcoLinearConstraint(lengths[i], indices+starts[i],
					     values+starts[i], rowLB_[i],
					     rowUB_[i]);
  }
  setConstraints(constraints, numLinearRows_);
  // constraints are owned by BcpsModel. Do not free them here.
  // for (int i=0; i<numRows_+numCones_; ++i) {
  //   delete constraints[i];
  // }
  delete[] constraints;
}

// read conic part and add conic constraints to the model.
void DcoModel::readAddConicConstraints(CoinMpsIO * reader) {
  int nOfCones = 0;
  int * coneStart = NULL;
  int * coneMembers = NULL;
  int * coneType = NULL;
  int reader_return = reader->readConicMps(NULL, coneStart, coneMembers,
				       coneType, nOfCones);
  // when there is no conic section status is -3.
  if (reader_return==-3) {
    dcoMessageHandler_->message(DISCO_READ_NOCONES,
				*dcoMessages_);
  }
  else if (reader_return!=0) {
    dcoMessageHandler_->message(DISCO_READ_MPSERROR,
				*dcoMessages_) << reader_return
					      << CoinMessageEol;
  }
  // store number of cones in the problem
  numConicRows_ = nOfCones;
  // log cone information messages
  if (nOfCones) {
    dcoMessageHandler_->message(DISCO_READ_CONESTATS1,
				*dcoMessages_) << nOfCones
					       << CoinMessageEol;
    for (int i=0; i<nOfCones; ++i) {
      dcoMessageHandler_->message(DISCO_READ_CONESTATS2,
				  *dcoMessages_)
	<< i
	<< coneStart[i+1] - coneStart[i]
	<< coneType[i]
	<< CoinMessageEol;
    }
  }
  // iterate over cones and add them to the model
  for (int i=0; i<nOfCones; ++i) {
    if (coneType[i]!=1 and coneType[i]!=2) {
      dcoMessageHandler_->message(DISCO_READ_CONEERROR,
				  *dcoMessages_) << CoinMessageEol;
    }
    int num_members = coneStart[i+1]-coneStart[i];
    if (coneType[i]==2 and num_members<3) {
      dcoMessageHandler_->message(DISCO_READ_ROTATEDCONESIZE,
				  *dcoMessages_) << CoinMessageEol;
    }
    DcoLorentzConeType type;
    if (coneType[i]==1) {
      type = DcoLorentzCone;
    }
    else if (coneType[i]==2) {
      type = DcoRotatedLorentzCone;
    }
    addConstraint(new DcoConicConstraint(type, num_members,
					 coneMembers+coneStart[i]));
    // cone_[i] = new OsiLorentzCone(type, num_members,
    //				  coneMembers+coneStart[i]);
#ifndef __OA__
    OsiLorentzConeType osi_type;
    if (coneType[i]==1) {
      osi_type = OSI_QUAD;
    }
    else if (coneType[i]==2) {
      osi_type = OSI_RQUAD;
    }
    solver_->addConicConstraint(osi_type, coneStart[i+1]-coneStart[i],
				coneMembers+coneStart[i]);
#endif
  }
  delete[] coneStart;
  delete[] coneMembers;
  delete[] coneType;
}

void DcoModel::preprocess() {
#ifdef __OA__
  approximateCones();
  // update row information
  numLinearRows_ = solver_->getNumRows();
  // update row bounds
  delete[] rowLB_;
  delete[] rowUB_;
  rowLB_ = new double [numRows_];
  rowUB_ = new double [numRows_];
  std::copy(solver_->getRowLower(),
	    solver_->getRowLower()+numLinearRows_,
	    rowLB_);
  std::copy(solver_->getRowUpper(),
	    solver_->getRowUpper()+numLinearRows_,
	    rowUB_);
#endif
}

void DcoModel::approximateCones() {
}

bool DcoModel::setupSelf() {
}

void DcoModel::postprocess() {
}

AlpsTreeNode * DcoModel::createRoot() {
  DcoTreeNode * root = new DcoTreeNode();
  DcoNodeDesc * desc = new DcoNodeDesc(this);
  root->setDesc(desc);
  std::vector<BcpsVariable *> cols = getVariables();
  std::vector<BcpsConstraint *> rows = getConstraints();
  int numCols = static_cast<int> (cols.size());
  int numRows = static_cast<int> (rows.size());
  int * varIndices1 = new int [numCols];
  int * varIndices2 = new int [numCols];
  int * varIndices3 = NULL;
  int * varIndices4 = NULL;
  double * vlhe = new double [numCols];
  double * vuhe = new double [numCols];
  double * vlse = NULL;
  double * vuse = NULL;
  int * conIndices1 = new int [numRows];
  int * conIndices2 = new int [numRows];
  int * conIndices3 = NULL;
  int * conIndices4 = NULL;
  double * clhe = new double [numRows];
  double * cuhe = new double [numRows];
  double * clse = NULL;
  double * cuse = NULL;
  //-------------------------------------------------------------
  // Get var bounds and indices.
  //-------------------------------------------------------------
  for (int i=0; i<numCols; ++i) {
    vlhe[i] = cols[i]->getLbHard();
    vuhe[i] = cols[i]->getUbHard();
    varIndices1[i] = i;
    varIndices2[i] = i;
  }
  //-------------------------------------------------------------
  // Get con bounds and indices.
  //-------------------------------------------------------------
  for (int i=0; i<numRows; ++i) {
    clhe[i] = rows[i]->getLbHard();
    cuhe[i] = rows[i]->getUbHard();
    conIndices1[i] = i;
    conIndices2[i] = i;
  }
  int * tempInd = NULL;
  BcpsObject ** tempObj = NULL;
  desc->assignVars(0, tempInd,
		   0, tempObj,
		   false, numCols, varIndices1, vlhe, /*Var hard lb*/
		   false, numCols, varIndices2, vuhe, /*Var hard ub*/
		   false, 0, varIndices3, vlse,       /*Var soft lb*/
		   false, 0, varIndices4, vuse);      /*Var soft ub*/
  desc->assignCons(0, tempInd,
		   0, tempObj,
		   false, numRows, conIndices1, clhe, /*Con hard lb*/
		   false, numRows, conIndices2, cuhe, /*Con hard ub*/
		   false, 0,conIndices3,clse,         /*Con soft lb*/
		   false, 0,conIndices4,cuse);        /*Con soft ub*/
  //-------------------------------------------------------------
  // Mark it as an explicit node.
  //-------------------------------------------------------------
  root->setExplicit(1);
  return root;
}
<commit_msg>row bounds bug fix.<commit_after>#include <CoinMpsIO.hpp>

#include "DcoModel.hpp"
#include "DcoMessage.hpp"
#include "DcoTreeNode.hpp"
#include "DcoNodeDesc.hpp"
#include "DcoVariable.hpp"
#include "DcoLinearConstraint.hpp"
#include "DcoConicConstraint.hpp"

DcoModel::DcoModel() {
  solver_ = NULL;
  colLB_ = NULL;
  colUB_ = NULL;
  rowLB_ = NULL;
  rowUB_ = NULL;
  numCols_ = 0;
  numRows_ = 0;
  numLinearRows_ = 0;
  numConicRows_ = 0;
  matrix_ = NULL;
  objSense_ = 0.0;
  objCoef_ = NULL;
  numIntegerCols_ = 0;
  integerCols_ = NULL;
  numSolutions_ = 0;
  // todo(aykut) this might create problems.
  incObjValue_ = 0.0;
  incumbentSol_ = NULL;
  // todo(aykut) following two might create problems.
  cutoff_ = 0.0;
  cutoffInc_ = 0.0;
  currRelGap_ = 1e5;
  currAbsGap_ = 1e5;
  branchStrategy_ = NULL;
  rampUpBranchStrategy_ = NULL;
  activeNode_ = NULL;
  dcoPar_ = new DcoParams();
  numNodes_ = 0;
  numIterations_ = 0;;
  aveIterations_ = 0;
  numRelaxedCols_ = 0;
  relaxedCols_ = NULL;
  numRelaxedRows_ = 0;
  relaxedRows_ = NULL;
  dcoMessageHandler_ = new CoinMessageHandler();
#ifdef DISCO_DEBUG
  dcoMessageHandler_->setLogLevel(4);
#endif
  dcoMessages_ = new DcoMessage();
}

DcoModel::~DcoModel() {
  // solver_ is freed in main function.
  if (matrix_) {
    delete matrix_;
  }
  if (colLB_) {
    delete[] colLB_;
  }
  if (colUB_) {
    delete[] colUB_;
  }
  if (rowLB_) {
    delete[] rowLB_;
  }
  if (rowUB_) {
    delete[] rowUB_;
  }
  if (objCoef_) {
    delete[] objCoef_;
  }
  if (incumbentSol_) {
    delete[] incumbentSol_;
  }
  if (branchStrategy_) {
    delete branchStrategy_;
  }
  if (rampUpBranchStrategy_) {
    delete rampUpBranchStrategy_;
  }
  if (activeNode_) {
    delete activeNode_;
  }
  if (dcoPar_) {
    delete dcoPar_;
  }
  if (dcoMessageHandler_) {
    delete dcoMessageHandler_;
  }
  if (dcoMessages_) {
    delete dcoMessages_;
  }
  if (relaxedCols_) {
    delete[] relaxedCols_;
  }
  if (relaxedRows_) {
    delete[] relaxedRows_;
  }
}

#if defined(__OA__)
void DcoModel::setSolver(OsiSolverInterface * solver) {
  solver_ = solver;
}
#else
void DcoModel::setSolver(OsiConicSolverInterface * solver) {
  solver_ = solver;
}
#endif

void DcoModel::readInstance(char const * dataFile) {
  // get log level parameters
  int dcoLogLevel =  dcoPar_->entry(DcoParams::logLevel);
  // get input file name
  std::string input_file(dataFile);
  std::string base_name = input_file.substr(0, input_file.rfind('.'));
  std::string extension = input_file.substr(input_file.rfind('.')+1);
  if (extension.compare("mps")) {
    dcoMessageHandler_->message(DISCO_READ_MPSFILEONLY,
				*dcoMessages_) << CoinMessageEol;
  }
  // read mps file
  CoinMpsIO * reader = new CoinMpsIO;
  reader->messageHandler()->setLogLevel(dcoLogLevel);
  reader->readMps(dataFile, "");
  numCols_ = reader->getNumCols();
  numLinearRows_ = reader->getNumRows();
  matrix_ = new CoinPackedMatrix(*(reader->getMatrixByCol()));
  // == allocate variable bounds
  colLB_ = new double [numCols_];
  colUB_ = new double [numCols_];
  // == allocate row bounds
  rowLB_ = new double [numLinearRows_];
  rowUB_ = new double [numLinearRows_];
  // == copy bounds
  std::copy(reader->getColLower(), reader->getColLower()+numCols_, colLB_);
  std::copy(reader->getColUpper(), reader->getColUpper()+numCols_, colUB_);
  std::copy(reader->getRowLower(), reader->getRowLower()+numLinearRows_, rowLB_);
  std::copy(reader->getRowUpper(), reader->getRowUpper()+numLinearRows_, rowUB_);
  // == set objective sense
  objSense_ = dcoPar_->entry(DcoParams::objSense);
  // == allocate objective coefficients
  objCoef_ = new double [numCols_];
  double const * reader_obj = reader->getObjCoefficients();
  if (objSense_ > 0.0) {
    std::copy(reader_obj, reader_obj+numCols_, objCoef_);
  }
  else {
    for (int i = 0; i<numCols_; ++i) {
      objCoef_[i] = -reader_obj[i];
    }
  }
  // == load data to solver
  solver_->loadProblem(*matrix_, colLB_, colUB_, objCoef_,
		       rowLB_, rowUB_);
  // == add variables to the model
  readAddVariables(reader);
  // == add linear constraints to the model
  readAddLinearConstraints(reader);
  // == add conic constraints to the model
  readAddConicConstraints(reader);
  delete reader;
}

// Add variables to *this.
void DcoModel::readAddVariables(CoinMpsIO * reader) {
  // get variable integrality constraints
  char const * is_integer = reader->integerColumns();
  DcoIntegralityType * i_type = new DcoIntegralityType[numCols_];
  for (int i=0; i<numCols_; ++i) {
    if (is_integer[i]) {
      i_type[i] = DcoIntegralityTypeInt;
    }
    else {
      i_type[i] = DcoIntegralityTypeCont;
    }
  }
  // add variables
  BcpsVariable ** variables = new BcpsVariable*[numCols_];
  for (int i=0; i<numCols_; ++i) {
    variables[i] = new DcoVariable(colLB_[i], colUB_[i], colLB_[i],
				   colLB_[i], i_type[i]);
  }
  setVariables(variables, numCols_);
  delete[] i_type;
  // variables are now owned by BcpsModel, do not free them.
  // for (int i=0; i<numCols_; ++i) {
  //   delete variables[i];
  // }
  delete[] variables;
}

void DcoModel::readAddLinearConstraints(CoinMpsIO * reader) {
  // == add constraints to *this
  BcpsConstraint ** constraints = new BcpsConstraint*[numLinearRows_];
  CoinPackedMatrix const * matrix = reader->getMatrixByRow();
  int const * indices = matrix->getIndices();
  double const * values = matrix->getElements();
  int const * lengths = matrix->getVectorLengths();
  int const * starts = matrix->getVectorStarts();
  for (int i=0; i<numLinearRows_; ++i) {
    constraints[i] = new DcoLinearConstraint(lengths[i], indices+starts[i],
					     values+starts[i], rowLB_[i],
					     rowUB_[i]);
  }
  setConstraints(constraints, numLinearRows_);
  // constraints are owned by BcpsModel. Do not free them here.
  // for (int i=0; i<numRows_+numCones_; ++i) {
  //   delete constraints[i];
  // }
  delete[] constraints;
}

void DcoModel::readAddConicConstraints(CoinMpsIO * reader) {
  int nOfCones = 0;
  int * coneStart = NULL;
  int * coneMembers = NULL;
  int * coneType = NULL;
  int reader_return = reader->readConicMps(NULL, coneStart, coneMembers,
				       coneType, nOfCones);
  // when there is no conic section status is -3.
  if (reader_return==-3) {
    dcoMessageHandler_->message(DISCO_READ_NOCONES,
				*dcoMessages_);
  }
  else if (reader_return!=0) {
    dcoMessageHandler_->message(DISCO_READ_MPSERROR,
				*dcoMessages_) << reader_return
					      << CoinMessageEol;
  }
  // store number of cones in the problem
  numConicRows_ = nOfCones;
  // log cone information messages
  if (nOfCones) {
    dcoMessageHandler_->message(DISCO_READ_CONESTATS1,
				*dcoMessages_) << nOfCones
					       << CoinMessageEol;
    for (int i=0; i<nOfCones; ++i) {
      dcoMessageHandler_->message(DISCO_READ_CONESTATS2,
				  *dcoMessages_)
	<< i
	<< coneStart[i+1] - coneStart[i]
	<< coneType[i]
	<< CoinMessageEol;
    }
  }
  // iterate over cones and add them to the model
  for (int i=0; i<nOfCones; ++i) {
    if (coneType[i]!=1 and coneType[i]!=2) {
      dcoMessageHandler_->message(DISCO_READ_CONEERROR,
				  *dcoMessages_) << CoinMessageEol;
    }
    int num_members = coneStart[i+1]-coneStart[i];
    if (coneType[i]==2 and num_members<3) {
      dcoMessageHandler_->message(DISCO_READ_ROTATEDCONESIZE,
				  *dcoMessages_) << CoinMessageEol;
    }
    DcoLorentzConeType type;
    if (coneType[i]==1) {
      type = DcoLorentzCone;
    }
    else if (coneType[i]==2) {
      type = DcoRotatedLorentzCone;
    }
    addConstraint(new DcoConicConstraint(type, num_members,
					 coneMembers+coneStart[i]));
    // cone_[i] = new OsiLorentzCone(type, num_members,
    //				  coneMembers+coneStart[i]);
#ifndef __OA__
    OsiLorentzConeType osi_type;
    if (coneType[i]==1) {
      osi_type = OSI_QUAD;
    }
    else if (coneType[i]==2) {
      osi_type = OSI_RQUAD;
    }
    solver_->addConicConstraint(osi_type, coneStart[i+1]-coneStart[i],
				coneMembers+coneStart[i]);
#endif
  }
  delete[] coneStart;
  delete[] coneMembers;
  delete[] coneType;
  // update rowLB_ and rowUB_, add conic row bounds
  double * temp = rowLB_;
  rowLB_ = new double[numLinearRows_+numConicRows_];
  std::copy(temp, temp+numLinearRows_, rowLB_);
  std::fill_n(rowLB_+numLinearRows_, numConicRows_, 0.0);
  delete[] temp;
  temp = rowUB_;
  rowUB_ = new double[numLinearRows_+numConicRows_];
  std::copy(temp, temp+numLinearRows_, rowUB_);
  std::fill_n(rowUB_+numLinearRows_, numConicRows_, DISCO_INFINITY);
  delete[] temp;
}

void DcoModel::preprocess() {
#ifdef __OA__
  approximateCones();
  // update row information
  numLinearRows_ = solver_->getNumRows();
  // update row bounds
  delete[] rowLB_;
  delete[] rowUB_;
  rowLB_ = new double [numRows_];
  rowUB_ = new double [numRows_];
  std::copy(solver_->getRowLower(),
	    solver_->getRowLower()+numLinearRows_,
	    rowLB_);
  std::copy(solver_->getRowUpper(),
	    solver_->getRowUpper()+numLinearRows_,
	    rowUB_);
#endif
}

void DcoModel::approximateCones() {
}

bool DcoModel::setupSelf() {
}

void DcoModel::postprocess() {
}

AlpsTreeNode * DcoModel::createRoot() {
  DcoTreeNode * root = new DcoTreeNode();
  DcoNodeDesc * desc = new DcoNodeDesc(this);
  root->setDesc(desc);
  std::vector<BcpsVariable *> cols = getVariables();
  std::vector<BcpsConstraint *> rows = getConstraints();
  int numCols = static_cast<int> (cols.size());
  int numRows = static_cast<int> (rows.size());
  int * varIndices1 = new int [numCols];
  int * varIndices2 = new int [numCols];
  int * varIndices3 = NULL;
  int * varIndices4 = NULL;
  double * vlhe = new double [numCols];
  double * vuhe = new double [numCols];
  double * vlse = NULL;
  double * vuse = NULL;
  int * conIndices1 = new int [numRows];
  int * conIndices2 = new int [numRows];
  int * conIndices3 = NULL;
  int * conIndices4 = NULL;
  double * clhe = new double [numRows];
  double * cuhe = new double [numRows];
  double * clse = NULL;
  double * cuse = NULL;
  //-------------------------------------------------------------
  // Get var bounds and indices.
  //-------------------------------------------------------------
  for (int i=0; i<numCols; ++i) {
    vlhe[i] = cols[i]->getLbHard();
    vuhe[i] = cols[i]->getUbHard();
    varIndices1[i] = i;
    varIndices2[i] = i;
  }
  //-------------------------------------------------------------
  // Get con bounds and indices.
  //-------------------------------------------------------------
  for (int i=0; i<numRows; ++i) {
    clhe[i] = rows[i]->getLbHard();
    cuhe[i] = rows[i]->getUbHard();
    conIndices1[i] = i;
    conIndices2[i] = i;
  }
  int * tempInd = NULL;
  BcpsObject ** tempObj = NULL;
  desc->assignVars(0, tempInd,
		   0, tempObj,
		   false, numCols, varIndices1, vlhe, /*Var hard lb*/
		   false, numCols, varIndices2, vuhe, /*Var hard ub*/
		   false, 0, varIndices3, vlse,       /*Var soft lb*/
		   false, 0, varIndices4, vuse);      /*Var soft ub*/
  desc->assignCons(0, tempInd,
		   0, tempObj,
		   false, numRows, conIndices1, clhe, /*Con hard lb*/
		   false, numRows, conIndices2, cuhe, /*Con hard ub*/
		   false, 0,conIndices3,clse,         /*Con soft lb*/
		   false, 0,conIndices4,cuse);        /*Con soft ub*/
  //-------------------------------------------------------------
  // Mark it as an explicit node.
  //-------------------------------------------------------------
  root->setExplicit(1);
  return root;
}
<|endoftext|>


<commit_before>#include <iostream>

#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>

#include <gtest/gtest.h>

#include <valijson/adapters/rapidjson_adapter.hpp>
#include <valijson/utils/rapidjson_utils.hpp>
#include <valijson/schema.hpp>
#include <valijson/schema_parser.hpp>
#include <valijson/validation_results.hpp>
#include <valijson/validator.hpp>

#define TEST_DATA_DIR "../tests/data"

using std::string;

using valijson::adapters::AdapterTraits;
using valijson::adapters::RapidJsonAdapter;
using valijson::utils::loadDocument;
using valijson::Schema;
using valijson::SchemaParser;
using valijson::Validator;
using valijson::ValidationResults;

class TestValidationErrors : public ::testing::Test
{

};

TEST_F(TestValidationErrors, AllOfConstraintFailure)
{
    // Load schema document
    rapidjson::Document schemaDocument;
    ASSERT_TRUE( loadDocument(TEST_DATA_DIR "/schemas/allof_integers_and_numbers.schema.json", schemaDocument) );
    RapidJsonAdapter schemaAdapter(schemaDocument);

    // Parse schema document
    Schema schema;
    SchemaParser schemaParser;
    ASSERT_NO_THROW( schemaParser.populateSchema(schemaAdapter, schema) );

    // Load test document
    rapidjson::Document testDocument;
    ASSERT_TRUE( loadDocument(TEST_DATA_DIR "/documents/array_doubles_1_2_3.json", testDocument) );
    RapidJsonAdapter testAdapter(testDocument);

    Validator validator;
    ValidationResults results;
    EXPECT_FALSE( validator.validate(schema, testAdapter, &results) );

    ValidationResults::Error error;

    EXPECT_TRUE( results.popError(error) );
    EXPECT_EQ( 2, error.context.size() );
    EXPECT_EQ( "<root>", error.context[0] );
    EXPECT_EQ( "[0]", error.context[1] );
    EXPECT_EQ( "Value type not permitted by 'type' constraint.", error.description );

    EXPECT_TRUE( results.popError(error) );
    EXPECT_EQ( 1, error.context.size() );
    EXPECT_EQ( "<root>", error.context[0] );
    EXPECT_EQ( "Failed to validate item #0 in array.", error.description );

    EXPECT_TRUE( results.popError(error) );
    EXPECT_EQ( 2, error.context.size() );
    EXPECT_EQ( "<root>", error.context[0] );
    EXPECT_EQ( "[1]", error.context[1] );
    EXPECT_EQ( "Value type not permitted by 'type' constraint.", error.description );

    EXPECT_TRUE( results.popError(error) );
    EXPECT_EQ( 1, error.context.size() );
    EXPECT_EQ( "<root>", error.context[0] );
    EXPECT_EQ( "Failed to validate item #1 in array.", error.description );

    EXPECT_TRUE( results.popError(error) );
    EXPECT_EQ( 2, error.context.size() );
    EXPECT_EQ( "<root>", error.context[0] );
    EXPECT_EQ( "[2]", error.context[1] );
    EXPECT_EQ( "Value type not permitted by 'type' constraint.", error.description );

    EXPECT_TRUE( results.popError(error) );
    EXPECT_EQ( 1, error.context.size() );
    EXPECT_EQ( "<root>", error.context[0] );
    EXPECT_EQ( "Failed to validate item #2 in array.", error.description );

    EXPECT_TRUE( results.popError(error) );
    EXPECT_EQ( 1, error.context.size() );
    EXPECT_EQ( "<root>", error.context[0] );
    EXPECT_EQ( "Failed to validate against child schema #0.", error.description );

    EXPECT_FALSE( results.popError(error) );

    while (results.popError(error)) {
        //std::cerr << error.context << std::endl;
        std::cerr << error.description << std::endl;
    }
}
<commit_msg>Fix signed/unsigned comparisons in tests<commit_after>#include <iostream>

#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>

#include <gtest/gtest.h>

#include <valijson/adapters/rapidjson_adapter.hpp>
#include <valijson/utils/rapidjson_utils.hpp>
#include <valijson/schema.hpp>
#include <valijson/schema_parser.hpp>
#include <valijson/validation_results.hpp>
#include <valijson/validator.hpp>

#define TEST_DATA_DIR "../tests/data"

using std::string;

using valijson::adapters::AdapterTraits;
using valijson::adapters::RapidJsonAdapter;
using valijson::utils::loadDocument;
using valijson::Schema;
using valijson::SchemaParser;
using valijson::Validator;
using valijson::ValidationResults;

class TestValidationErrors : public ::testing::Test
{

};

TEST_F(TestValidationErrors, AllOfConstraintFailure)
{
    // Load schema document
    rapidjson::Document schemaDocument;
    ASSERT_TRUE( loadDocument(TEST_DATA_DIR "/schemas/allof_integers_and_numbers.schema.json", schemaDocument) );
    RapidJsonAdapter schemaAdapter(schemaDocument);

    // Parse schema document
    Schema schema;
    SchemaParser schemaParser;
    ASSERT_NO_THROW( schemaParser.populateSchema(schemaAdapter, schema) );

    // Load test document
    rapidjson::Document testDocument;
    ASSERT_TRUE( loadDocument(TEST_DATA_DIR "/documents/array_doubles_1_2_3.json", testDocument) );
    RapidJsonAdapter testAdapter(testDocument);

    Validator validator;
    ValidationResults results;
    EXPECT_FALSE( validator.validate(schema, testAdapter, &results) );

    ValidationResults::Error error;

    EXPECT_TRUE( results.popError(error) );
    EXPECT_EQ( size_t(2), error.context.size() );
    EXPECT_EQ( "<root>", error.context[0] );
    EXPECT_EQ( "[0]", error.context[1] );
    EXPECT_EQ( "Value type not permitted by 'type' constraint.", error.description );

    EXPECT_TRUE( results.popError(error) );
    EXPECT_EQ( size_t(1), error.context.size() );
    EXPECT_EQ( "<root>", error.context[0] );
    EXPECT_EQ( "Failed to validate item #0 in array.", error.description );

    EXPECT_TRUE( results.popError(error) );
    EXPECT_EQ( size_t(2), error.context.size() );
    EXPECT_EQ( "<root>", error.context[0] );
    EXPECT_EQ( "[1]", error.context[1] );
    EXPECT_EQ( "Value type not permitted by 'type' constraint.", error.description );

    EXPECT_TRUE( results.popError(error) );
    EXPECT_EQ( size_t(1), error.context.size() );
    EXPECT_EQ( "<root>", error.context[0] );
    EXPECT_EQ( "Failed to validate item #1 in array.", error.description );

    EXPECT_TRUE( results.popError(error) );
    EXPECT_EQ( size_t(2), error.context.size() );
    EXPECT_EQ( "<root>", error.context[0] );
    EXPECT_EQ( "[2]", error.context[1] );
    EXPECT_EQ( "Value type not permitted by 'type' constraint.", error.description );

    EXPECT_TRUE( results.popError(error) );
    EXPECT_EQ( size_t(1), error.context.size() );
    EXPECT_EQ( "<root>", error.context[0] );
    EXPECT_EQ( "Failed to validate item #2 in array.", error.description );

    EXPECT_TRUE( results.popError(error) );
    EXPECT_EQ( size_t(1), error.context.size() );
    EXPECT_EQ( "<root>", error.context[0] );
    EXPECT_EQ( "Failed to validate against child schema #0.", error.description );

    EXPECT_FALSE( results.popError(error) );

    while (results.popError(error)) {
        //std::cerr << error.context << std::endl;
        std::cerr << error.description << std::endl;
    }
}
<|endoftext|>


<commit_before>//=============================================================================
// File:       entity.cpp
// Contents:   Definitions for DwEntity
// Maintainer: Doug Sauder <dwsauder@fwb.gulf.net>
// WWW:        http://www.fwb.gulf.net/~dwsauder/mimepp.html
// $Revision$
// $Date$
//
// Copyright (c) 1996, 1997 Douglas W. Sauder
// All rights reserved.
//
// IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT,
// INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
// THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER
// HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT
// NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
// BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
// SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
//
//=============================================================================

#define DW_IMPLEMENTATION

#include <mimelib/config.h>
#include <mimelib/debug.h>
#include <mimelib/string.h>
#include <mimelib/enum.h>
#include <mimelib/entity.h>
#include <mimelib/headers.h>
#include <mimelib/body.h>
#include <mimelib/mediatyp.h>

class DwEntityParser {
    friend class DwEntity;
private:
    DwEntityParser(const DwString&);
    void Parse();
    const DwString mString;
    DwString mHeaders;
    DwString mBody;
};

DwEntityParser::DwEntityParser(const DwString& aStr)
  : mString(aStr)
{
    Parse();
}

void DwEntityParser::Parse()
{
    const char* buf = mString.data();
    size_t bufEnd = mString.length();
    size_t pos = 0;
    size_t headersStart = 0;
    size_t headersLength = 0;
    size_t lineStart = pos;
    DwBool isHeaderLine = DwFalse;
    // If first character is a LF (ANSI C or UNIX)
    // or if first two characters are CR LF (MIME or DOS),
    // there are no headers.
    if (pos < bufEnd && buf[pos] != '\n'
        && ! (buf[pos] == '\r' && pos+1 < bufEnd && buf[pos+1] == '\n')) {

        while (pos < bufEnd) {
            // End of line marked by LF
            if (buf[pos] == '\n') {
                ++pos;
                if (!isHeaderLine) {
                    pos = lineStart;
                    break;
                }
                // Check for LF LF
                else if (pos < bufEnd && buf[pos] == '\n') {
                    break;
                }
                lineStart = pos;
                isHeaderLine = DwFalse;
            }
            // End of line marked by CRLF
            else if (buf[pos] == '\r' && pos+1 < bufEnd
                && buf[pos+1] == '\n') {
                pos += 2;
                if (!isHeaderLine) {
                    pos = lineStart;
                    break;
                }
                // Check for CR LF CR LF
                else if (pos+1 < bufEnd && buf[pos] == '\r'
                    && buf[pos+1] == '\n') {
                    break;
                }
                lineStart = pos;
                isHeaderLine = DwFalse;
            }
            // End of line marked by CRLF
            else if (buf[pos] == '\r' && pos+1 < bufEnd
                && buf[pos+1] == '\n') {
                pos += 2;
                if (!isHeaderLine) {
                    pos = lineStart;
                    break;
                }
                // Check for CR LF CR LF
                else if (pos+1 < bufEnd && buf[pos] == '\r'
                    && buf[pos+1] == '\n') {
                    break;
                }
                lineStart = pos;
                isHeaderLine = DwFalse;
            }
            else if (buf[pos] == ':') {
                isHeaderLine = DwTrue;
                ++pos;
            }
            else if (pos == lineStart &&
                (buf[pos] == ' ' || buf[pos] == '\t')) {
                isHeaderLine = DwTrue;
                ++pos;
                            }
            else {
                ++pos;
            }
        }
    }
    headersLength = pos;
    mHeaders = mString.substr(headersStart, headersLength);
    // Skip blank line
    // LF (ANSI C or UNIX)
    if (pos < bufEnd && buf[pos] == '\n') {
        ++pos;
    }
    // CR LF (MIME or DOS)
    else if (pos < bufEnd && buf[pos] == '\r'
        && pos+1 < bufEnd && buf[pos+1] == '\n') {

        pos += 2;
    }
    size_t bodyStart = pos;
    size_t bodyLength = mString.length() - bodyStart;
    mBody = mString.substr(bodyStart, bodyLength);
}

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

const char* const DwEntity::sClassName = "DwEntity";

DwEntity::DwEntity()
{
    mHeaders = DwHeaders::NewHeaders("", this);
    ASSERT(mHeaders != 0);
    mBody = DwBody::NewBody("", this);
    ASSERT(mBody != 0);
    mClassId = kCidEntity;
    mClassName = sClassName;
    mBodySize = -1;
}

DwEntity::DwEntity(const DwEntity& aEntity)
  : DwMessageComponent(aEntity)
{
    mHeaders = (DwHeaders*) aEntity.mHeaders->Clone();
    ASSERT(mHeaders != 0);
    mHeaders->SetParent(this);
    mBody = (DwBody*) aEntity.mBody->Clone();
    ASSERT(mBody != 0);
    mBody->SetParent(this);
    mClassId = kCidEntity;
    mClassName = sClassName;
    mBodySize = aEntity.mBodySize;
}

DwEntity::DwEntity(const DwString& aStr, DwMessageComponent* aParent)
  : DwMessageComponent(aStr, aParent)
{
    mHeaders = DwHeaders::NewHeaders("", this);
    ASSERT(mHeaders != 0);
    mBody = DwBody::NewBody("", this);
    ASSERT(mBody != 0);
    mClassId = kCidEntity;
    mClassName = sClassName;
    mBodySize = -1;
}

DwEntity::~DwEntity()
{
    delete mHeaders;
    delete mBody;
}

const DwEntity& DwEntity::operator = (const DwEntity& aEntity)
{
    if (this == &aEntity) return *this;
    DwMessageComponent::operator = (aEntity);
    // Note: Because of the derived assignment problem, we cannot use the
    // assignment operator for DwHeaders and DwBody in the following.
    delete mHeaders;
    mHeaders = (DwHeaders*) aEntity.mHeaders->Clone();
    ASSERT(mHeaders != 0);
    mHeaders->SetParent(this);
    delete mBody;
    mBody = (DwBody*) aEntity.mBody->Clone();
    ASSERT(mBody != 0);
    mBody->SetParent(this);
    if (mParent) {
        mParent->SetModified();
    }
    return *this;
}

void DwEntity::Parse()
{
    mIsModified = 0;
    DwEntityParser parser(mString);
    mHeaders->FromString(parser.mHeaders);
    mHeaders->Parse();
    mBody->FromString(parser.mBody);
    mBody->Parse();
}

void DwEntity::Assemble(DwHeaders& aHeaders, DwBody& aBody)
{
    mString = "";
    mString += aHeaders.AsString();

    int len = mString.length();
#if defined(DW_EOL_CRLF)
    if (len>=3 && (mString[len-1]!='\n' || mString[len-3]!='\n'))
#else
    if (len>=2 && (mString[len-1]!='\n' || mString[len-2]!='\n'))
#endif
    {
        if ( (mString[len-1] == '\n') &&
             mHeaders->HasContentType() &&
             (mHeaders->ContentType().Type()    == DwMime::kTypeMultipart) &&
	     aBody.FirstBodyPart() )
        {
            /* this is the case when we should not add an DW_EOL since
               another newline is already added by DwBody::Assemble()
               right before a boundary string.
               Why is this bad for multipart-mixed? Well, multipart-
               mixed can be part of a multipart-signed and an additional
               empty line makes the mail invalid for a verification
               (the signature was computed based on the same content,
               but with a single newline).

	       We check for the existence of the first body part since
	       we treat the body as opaque in case a failure to parse
	       multipart-subtypes occurs.
            */
        }
        else
            mString += DW_EOL;
    }
    mString += aBody.AsString();
    mIsModified = 0;
}

void DwEntity::Assemble()
{
    if (!mIsModified) return;
    mBody->Assemble();
    mHeaders->Assemble();
    Assemble( *mHeaders, *mBody );
}

DwHeaders& DwEntity::Headers() const
{
    ASSERT(mHeaders != 0);
    return *mHeaders;
}

DwBody& DwEntity::Body() const
{
    return *mBody;
}

int DwEntity::BodySize() const
{
  if ( mBody->AsString().length() > 0 )
    return mBody->AsString().length();
  else if ( mBodySize > 0 )
    return mBodySize;
  else
    return 0;
}

#if defined(DW_DEBUG_VERSION)
void DwEntity::PrintDebugInfo(std::ostream& aStrm, int aDepth) const
{
    aStrm << "------------ Debug info for DwEntity class ------------\n";
    _PrintDebugInfo(aStrm);
    int depth = aDepth - 1;
    depth = (depth >= 0) ? depth : 0;
    if (aDepth == 0 || depth > 0) {
        mHeaders->PrintDebugInfo(aStrm, depth);
        mBody->PrintDebugInfo(aStrm, depth);
    }
}
#else
void DwEntity::PrintDebugInfo(std::ostream& , int ) const {}
#endif // defined(DW_DEBUG_VERSION)

#if defined(DW_DEBUG_VERSION)
void DwEntity::_PrintDebugInfo(std::ostream& aStrm) const
{
    DwMessageComponent::_PrintDebugInfo(aStrm);
    aStrm << "Headers:          " << mHeaders->ObjectId() << '\n';
    aStrm << "Body:             " << mBody->ObjectId() << '\n';
}
#else
void DwEntity::_PrintDebugInfo(std::ostream& ) const {}
#endif // defined(DW_DEBUG_VERSION)

void DwEntity::CheckInvariants() const
{
#if defined(DW_DEBUG_VERSION)
    DwMessageComponent::CheckInvariants();
    mHeaders->CheckInvariants();
    assert((DwMessageComponent*) this == mHeaders->Parent());
    mBody->CheckInvariants();
    assert((DwMessageComponent*) this == mBody->Parent());
#endif // defined(DW_DEBUG_VERSION)
}
<commit_msg>Wonderful way to obfuscate code ;)<commit_after>//=============================================================================
// File:       entity.cpp
// Contents:   Definitions for DwEntity
// Maintainer: Doug Sauder <dwsauder@fwb.gulf.net>
// WWW:        http://www.fwb.gulf.net/~dwsauder/mimepp.html
// $Revision$
// $Date$
//
// Copyright (c) 1996, 1997 Douglas W. Sauder
// All rights reserved.
//
// IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT,
// INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
// THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER
// HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT
// NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
// BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
// SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
//
//=============================================================================

#define DW_IMPLEMENTATION

#include <mimelib/config.h>
#include <mimelib/debug.h>
#include <mimelib/string.h>
#include <mimelib/enum.h>
#include <mimelib/entity.h>
#include <mimelib/headers.h>
#include <mimelib/body.h>
#include <mimelib/mediatyp.h>

class DwEntityParser {
    friend class DwEntity;
private:
    DwEntityParser(const DwString&);
    void Parse();
    const DwString mString;
    DwString mHeaders;
    DwString mBody;
};

DwEntityParser::DwEntityParser(const DwString& aStr)
  : mString(aStr)
{
    Parse();
}

void DwEntityParser::Parse()
{
    const char* buf = mString.data();
    size_t bufEnd = mString.length();
    size_t pos = 0;
    size_t headersStart = 0;
    size_t headersLength = 0;
    size_t lineStart = pos;
    DwBool isHeaderLine = DwFalse;
    // If first character is a LF (ANSI C or UNIX)
    // or if first two characters are CR LF (MIME or DOS),
    // there are no headers.
    if (pos < bufEnd && buf[pos] != '\n'
        && ! (buf[pos] == '\r' && pos+1 < bufEnd && buf[pos+1] == '\n')) {

        while (pos < bufEnd) {
            // End of line marked by LF
            if (buf[pos] == '\n') {
                ++pos;
                if (!isHeaderLine) {
                    pos = lineStart;
                    break;
                }
                // Check for LF LF
                else if (pos < bufEnd && buf[pos] == '\n') {
                    break;
                }
                lineStart = pos;
                isHeaderLine = DwFalse;
            }
            // End of line marked by CRLF
            else if (buf[pos] == '\r' && pos+1 < bufEnd
                && buf[pos+1] == '\n') {
                pos += 2;
                if (!isHeaderLine) {
                    pos = lineStart;
                    break;
                }
                // Check for CR LF CR LF
                else if (pos+1 < bufEnd && buf[pos] == '\r'
                    && buf[pos+1] == '\n') {
                    break;
                }
                lineStart = pos;
                isHeaderLine = DwFalse;
            }
            else if (buf[pos] == ':') {
                isHeaderLine = DwTrue;
                ++pos;
            }
            else if (pos == lineStart &&
                (buf[pos] == ' ' || buf[pos] == '\t')) {
                isHeaderLine = DwTrue;
                ++pos;
                            }
            else {
                ++pos;
            }
        }
    }
    headersLength = pos;
    mHeaders = mString.substr(headersStart, headersLength);
    // Skip blank line
    // LF (ANSI C or UNIX)
    if (pos < bufEnd && buf[pos] == '\n') {
        ++pos;
    }
    // CR LF (MIME or DOS)
    else if (pos < bufEnd && buf[pos] == '\r'
        && pos+1 < bufEnd && buf[pos+1] == '\n') {

        pos += 2;
    }
    size_t bodyStart = pos;
    size_t bodyLength = mString.length() - bodyStart;
    mBody = mString.substr(bodyStart, bodyLength);
}

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

const char* const DwEntity::sClassName = "DwEntity";

DwEntity::DwEntity()
{
    mHeaders = DwHeaders::NewHeaders("", this);
    ASSERT(mHeaders != 0);
    mBody = DwBody::NewBody("", this);
    ASSERT(mBody != 0);
    mClassId = kCidEntity;
    mClassName = sClassName;
    mBodySize = -1;
}

DwEntity::DwEntity(const DwEntity& aEntity)
  : DwMessageComponent(aEntity)
{
    mHeaders = (DwHeaders*) aEntity.mHeaders->Clone();
    ASSERT(mHeaders != 0);
    mHeaders->SetParent(this);
    mBody = (DwBody*) aEntity.mBody->Clone();
    ASSERT(mBody != 0);
    mBody->SetParent(this);
    mClassId = kCidEntity;
    mClassName = sClassName;
    mBodySize = aEntity.mBodySize;
}

DwEntity::DwEntity(const DwString& aStr, DwMessageComponent* aParent)
  : DwMessageComponent(aStr, aParent)
{
    mHeaders = DwHeaders::NewHeaders("", this);
    ASSERT(mHeaders != 0);
    mBody = DwBody::NewBody("", this);
    ASSERT(mBody != 0);
    mClassId = kCidEntity;
    mClassName = sClassName;
    mBodySize = -1;
}

DwEntity::~DwEntity()
{
    delete mHeaders;
    delete mBody;
}

const DwEntity& DwEntity::operator = (const DwEntity& aEntity)
{
    if (this == &aEntity) return *this;
    DwMessageComponent::operator = (aEntity);
    // Note: Because of the derived assignment problem, we cannot use the
    // assignment operator for DwHeaders and DwBody in the following.
    delete mHeaders;
    mHeaders = (DwHeaders*) aEntity.mHeaders->Clone();
    ASSERT(mHeaders != 0);
    mHeaders->SetParent(this);
    delete mBody;
    mBody = (DwBody*) aEntity.mBody->Clone();
    ASSERT(mBody != 0);
    mBody->SetParent(this);
    if (mParent) {
        mParent->SetModified();
    }
    return *this;
}

void DwEntity::Parse()
{
    mIsModified = 0;
    DwEntityParser parser(mString);
    mHeaders->FromString(parser.mHeaders);
    mHeaders->Parse();
    mBody->FromString(parser.mBody);
    mBody->Parse();
}

void DwEntity::Assemble(DwHeaders& aHeaders, DwBody& aBody)
{
    mString = "";
    mString += aHeaders.AsString();

    int len = mString.length();
#if defined(DW_EOL_CRLF)
    if (len>=3 && (mString[len-1]!='\n' || mString[len-3]!='\n'))
#else
    if (len>=2 && (mString[len-1]!='\n' || mString[len-2]!='\n'))
#endif
    {
        if ( (mString[len-1] == '\n') &&
             mHeaders->HasContentType() &&
             (mHeaders->ContentType().Type()    == DwMime::kTypeMultipart) &&
	     aBody.FirstBodyPart() )
        {
            /* this is the case when we should not add an DW_EOL since
               another newline is already added by DwBody::Assemble()
               right before a boundary string.
               Why is this bad for multipart-mixed? Well, multipart-
               mixed can be part of a multipart-signed and an additional
               empty line makes the mail invalid for a verification
               (the signature was computed based on the same content,
               but with a single newline).

	       We check for the existence of the first body part since
	       we treat the body as opaque in case a failure to parse
	       multipart-subtypes occurs.
            */
        }
        else
            mString += DW_EOL;
    }
    mString += aBody.AsString();
    mIsModified = 0;
}

void DwEntity::Assemble()
{
    if (!mIsModified) return;
    mBody->Assemble();
    mHeaders->Assemble();
    Assemble( *mHeaders, *mBody );
}

DwHeaders& DwEntity::Headers() const
{
    ASSERT(mHeaders != 0);
    return *mHeaders;
}

DwBody& DwEntity::Body() const
{
    return *mBody;
}

int DwEntity::BodySize() const
{
  if ( mBody->AsString().length() > 0 )
    return mBody->AsString().length();
  else if ( mBodySize > 0 )
    return mBodySize;
  else
    return 0;
}

#if defined(DW_DEBUG_VERSION)
void DwEntity::PrintDebugInfo(std::ostream& aStrm, int aDepth) const
{
    aStrm << "------------ Debug info for DwEntity class ------------\n";
    _PrintDebugInfo(aStrm);
    int depth = aDepth - 1;
    depth = (depth >= 0) ? depth : 0;
    if (aDepth == 0 || depth > 0) {
        mHeaders->PrintDebugInfo(aStrm, depth);
        mBody->PrintDebugInfo(aStrm, depth);
    }
}
#else
void DwEntity::PrintDebugInfo(std::ostream& , int ) const {}
#endif // defined(DW_DEBUG_VERSION)

#if defined(DW_DEBUG_VERSION)
void DwEntity::_PrintDebugInfo(std::ostream& aStrm) const
{
    DwMessageComponent::_PrintDebugInfo(aStrm);
    aStrm << "Headers:          " << mHeaders->ObjectId() << '\n';
    aStrm << "Body:             " << mBody->ObjectId() << '\n';
}
#else
void DwEntity::_PrintDebugInfo(std::ostream& ) const {}
#endif // defined(DW_DEBUG_VERSION)

void DwEntity::CheckInvariants() const
{
#if defined(DW_DEBUG_VERSION)
    DwMessageComponent::CheckInvariants();
    mHeaders->CheckInvariants();
    assert((DwMessageComponent*) this == mHeaders->Parent());
    mBody->CheckInvariants();
    assert((DwMessageComponent*) this == mBody->Parent());
#endif // defined(DW_DEBUG_VERSION)
}
<|endoftext|>


<commit_before>/*
    open source routing machine
    Copyright (C) Dennis Luxen, 2010

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.

This program 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 General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
or see http://www.gnu.org/licenses/agpl.txt.
 */

#include <climits>
#include <fstream>
#include <istream>
#include <iostream>
#include <cstring>
#include <string>
#include <vector>

#ifdef _OPENMP
#include <omp.h>
#endif

#include "typedefs.h"

#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include "HttpServer/server.h"
#include "DataStructures/StaticGraph.h"

using namespace std;

typedef ContractionCleanup::Edge::EdgeData EdgeData;
typedef StaticGraph<EdgeData>::InputEdge GraphEdge;
typedef http::server<StaticGraph<EdgeData> > server;

/*
 * TODO: Description of command line arguments
 */

int main (int argc, char *argv[])
{
	double time;

	if(argc < 2)
	{
		cerr << "Correct usage:" << endl << argv[0] << " <hsgr data> <nodes data>" << endl;
		exit(-1);
	}

	if (argv[0] == 0) {
		cerr << "Missing data files!" << endl;
		return -1;
	}
	ifstream in(argv[1], ios::binary);
	ifstream in2(argv[2], ios::binary);
	NodeInformationHelpDesk * kdtreeService = new NodeInformationHelpDesk();

	time = get_timestamp();
	cout << "deserializing edge data from " << argv[1] << " ..." << flush;

	std::vector< GraphEdge> edgelist;
	while(!in.eof())
	{
		GraphEdge g;
		EdgeData e;

		int distance;
		bool shortcut;
		bool forward;
		bool backward;
		NodeID middle;
		NodeID source;
		NodeID target;

		in.read((char *)&(distance), sizeof(int));
		assert(distance > 0);
		in.read((char *)&(shortcut), sizeof(bool));
		in.read((char *)&(forward), sizeof(bool));
		in.read((char *)&(backward), sizeof(bool));
		in.read((char *)&(middle), sizeof(NodeID));
		in.read((char *)&(source), sizeof(NodeID));
		in.read((char *)&(target), sizeof(NodeID));
		e.backward = backward; e.distance = distance; e.forward = forward; e.middle = middle; e.shortcut = shortcut;
		g.data = e; g.source = source; g.target = target;

		edgelist.push_back(g);
	}

	in.close();
	cout << "in " << get_timestamp() - time << "s" << endl;
	cout << "search graph has " << edgelist.size() << " edges" << endl;
	time = get_timestamp();
	cout << "deserializing node map and building kd-tree ..." << flush;
	kdtreeService->initKDTree(in2);
	cout << "in " << get_timestamp() - time << "s" << endl;

	time = get_timestamp();
	StaticGraph<EdgeData> * graph = new StaticGraph<EdgeData>(kdtreeService->getNumberOfNodes()-1, edgelist);
	cout << "checking data sanity ..." << flush;
	NodeID numberOfNodes = graph->GetNumberOfNodes();
	for ( NodeID node = 0; node < numberOfNodes; ++node ) {
		for ( StaticGraph<EdgeData>::EdgeIterator edge = graph->BeginEdges( node ), endEdges = graph->EndEdges( node ); edge != endEdges; ++edge ) {
			const NodeID start = node;
			const NodeID target = graph->GetTarget( edge );
			const EdgeData& data = graph->GetEdgeData( edge );
			const NodeID middle = data.middle;
			assert(start != target);
			if(data.shortcut)
			{
				if(graph->FindEdge(start, middle) == SPECIAL_EDGEID && graph->FindEdge(middle, start) == SPECIAL_EDGEID)
				{
					assert(false);
					cerr << "hierarchy broken" << endl; exit(-1);
				}
				if(graph->FindEdge(middle, target) == SPECIAL_EDGEID && graph->FindEdge(target, middle) == SPECIAL_EDGEID)
				{
					assert(false);
					cerr << "hierarchy broken" << endl; exit(-1);
				}
			}
		}
		if(graph->GetOutDegree(node) == 0)
		{
		    cerr << "found node with degree 0: " << node << endl;
		}
	}
	cout << "in " << get_timestamp() - time << "s" << endl;
	cout << "building search graph ..." << flush;

	SearchEngine<EdgeData, StaticGraph<EdgeData> > * sEngine = new SearchEngine<EdgeData, StaticGraph<EdgeData> >(graph, kdtreeService);
	cout << "in " << get_timestamp() - time << "s" << endl;

	time = get_timestamp();
	try {
		// Block all signals for background thread.
		sigset_t new_mask;
		sigfillset(&new_mask);
		sigset_t old_mask;
		pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask);

		cout << "starting web server ..." << flush;
		// Run server in background thread.
		server s("0.0.0.0", "5000", omp_get_num_procs(), sEngine);
		boost::thread t(boost::bind(&server::run, &s));
		cout << "ok" << endl;

		// Restore previous signals.
		pthread_sigmask(SIG_SETMASK, &old_mask, 0);

		// Wait for signal indicating time to shut down.
		sigset_t wait_mask;
		sigemptyset(&wait_mask);
		sigaddset(&wait_mask, SIGINT);
		sigaddset(&wait_mask, SIGQUIT);
		sigaddset(&wait_mask, SIGTERM);
		pthread_sigmask(SIG_BLOCK, &wait_mask, 0);
		int sig = 0;
		sigwait(&wait_mask, &sig);
		// Stop the server.
		s.stop();
		t.join();
	}
	catch (std::exception& e)
	{
		std::cerr << "exception: " << e.what() << "\n";
	}
	cout << "graceful shutdown after " << get_timestamp() - time << "s" << endl;
	delete kdtreeService;
	return 0;
}
<commit_msg>corrected timing of kd tree construction<commit_after>/*
    open source routing machine
    Copyright (C) Dennis Luxen, 2010

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.

This program 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 General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
or see http://www.gnu.org/licenses/agpl.txt.
 */

#include <climits>
#include <fstream>
#include <istream>
#include <iostream>
#include <cstring>
#include <string>
#include <vector>

#ifdef _OPENMP
#include <omp.h>
#endif

#include "typedefs.h"

#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include "HttpServer/server.h"
#include "DataStructures/StaticGraph.h"

using namespace std;

typedef ContractionCleanup::Edge::EdgeData EdgeData;
typedef StaticGraph<EdgeData>::InputEdge GraphEdge;
typedef http::server<StaticGraph<EdgeData> > server;

/*
 * TODO: Description of command line arguments
 */

int main (int argc, char *argv[])
{
	double time;

	if(argc < 2)
	{
		cerr << "Correct usage:" << endl << argv[0] << " <hsgr data> <nodes data>" << endl;
		exit(-1);
	}

	if (argv[0] == 0) {
		cerr << "Missing data files!" << endl;
		return -1;
	}
	ifstream in(argv[1], ios::binary);
	ifstream in2(argv[2], ios::binary);
	NodeInformationHelpDesk * kdtreeService = new NodeInformationHelpDesk();

	time = get_timestamp();
	cout << "deserializing edge data from " << argv[1] << " ..." << flush;

	std::vector< GraphEdge> edgelist;
	while(!in.eof())
	{
		GraphEdge g;
		EdgeData e;

		int distance;
		bool shortcut;
		bool forward;
		bool backward;
		NodeID middle;
		NodeID source;
		NodeID target;

		in.read((char *)&(distance), sizeof(int));
		assert(distance > 0);
		in.read((char *)&(shortcut), sizeof(bool));
		in.read((char *)&(forward), sizeof(bool));
		in.read((char *)&(backward), sizeof(bool));
		in.read((char *)&(middle), sizeof(NodeID));
		in.read((char *)&(source), sizeof(NodeID));
		in.read((char *)&(target), sizeof(NodeID));
		e.backward = backward; e.distance = distance; e.forward = forward; e.middle = middle; e.shortcut = shortcut;
		g.data = e; g.source = source; g.target = target;

		edgelist.push_back(g);
	}

	in.close();
	cout << "in " << get_timestamp() - time << "s" << endl;
	cout << "search graph has " << edgelist.size() << " edges" << endl;
	time = get_timestamp();
	cout << "deserializing node map and building kd-tree ..." << flush;
	kdtreeService->initKDTree(in2);
	cout << "in " << get_timestamp() - time << "s" << endl;

	time = get_timestamp();
	StaticGraph<EdgeData> * graph = new StaticGraph<EdgeData>(kdtreeService->getNumberOfNodes()-1, edgelist);
	cout << "checking data sanity ..." << flush;
	NodeID numberOfNodes = graph->GetNumberOfNodes();
	for ( NodeID node = 0; node < numberOfNodes; ++node ) {
		for ( StaticGraph<EdgeData>::EdgeIterator edge = graph->BeginEdges( node ), endEdges = graph->EndEdges( node ); edge != endEdges; ++edge ) {
			const NodeID start = node;
			const NodeID target = graph->GetTarget( edge );
			const EdgeData& data = graph->GetEdgeData( edge );
			const NodeID middle = data.middle;
			assert(start != target);
			if(data.shortcut)
			{
				if(graph->FindEdge(start, middle) == SPECIAL_EDGEID && graph->FindEdge(middle, start) == SPECIAL_EDGEID)
				{
					assert(false);
					cerr << "hierarchy broken" << endl; exit(-1);
				}
				if(graph->FindEdge(middle, target) == SPECIAL_EDGEID && graph->FindEdge(target, middle) == SPECIAL_EDGEID)
				{
					assert(false);
					cerr << "hierarchy broken" << endl; exit(-1);
				}
			}
		}
		if(graph->GetOutDegree(node) == 0)
		{
		    cerr << "found node with degree 0: " << node << endl;
		}
	}
	cout << "in " << get_timestamp() - time << "s" << endl;
	time = get_timestamp();
	cout << "building search graph ..." << flush;

	SearchEngine<EdgeData, StaticGraph<EdgeData> > * sEngine = new SearchEngine<EdgeData, StaticGraph<EdgeData> >(graph, kdtreeService);
	cout << "in " << get_timestamp() - time << "s" << endl;

	time = get_timestamp();

	try {
		// Block all signals for background thread.
		sigset_t new_mask;
		sigfillset(&new_mask);
		sigset_t old_mask;
		pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask);

		cout << "starting web server ..." << flush;
		// Run server in background thread.
		server s("0.0.0.0", "5000", omp_get_num_procs(), sEngine);
		boost::thread t(boost::bind(&server::run, &s));
		cout << "ok" << endl;

		// Restore previous signals.
		pthread_sigmask(SIG_SETMASK, &old_mask, 0);

		// Wait for signal indicating time to shut down.
		sigset_t wait_mask;
		sigemptyset(&wait_mask);
		sigaddset(&wait_mask, SIGINT);
		sigaddset(&wait_mask, SIGQUIT);
		sigaddset(&wait_mask, SIGTERM);
		pthread_sigmask(SIG_BLOCK, &wait_mask, 0);
		int sig = 0;
		sigwait(&wait_mask, &sig);
		// Stop the server.
		s.stop();
		t.join();
	}
	catch (std::exception& e)
	{
		std::cerr << "exception: " << e.what() << "\n";
	}
	cout << "graceful shutdown after " << get_timestamp() - time << "s" << endl;
	delete kdtreeService;
	return 0;
}
<|endoftext|>


<commit_before><commit_msg>Create 1177 - Array Fill II.cpp<commit_after><|endoftext|>