<commit_before>#include "kwm.h"
#include "helpers.h"
#include "daemon.h"
#include "display.h"
#include "space.h"
#include "window.h"
#include "keys.h"
#include "interpreter.h"
#include "scratchpad.h"
#include "border.h"
#include "config.h"
#include "command.h"
#include "cursor.h"
#include "axlib/axlib.h"

#define internal static
const std::string KwmCurrentVersion = "Kwm Version 3.0.0";
std::map<CFStringRef, space_info> WindowTree;

ax_state AXState = {};
ax_display *FocusedDisplay;
ax_application *FocusedApplication;
ax_window *MarkedWindow;

kwm_mach KWMMach = {};
kwm_path KWMPath = {};
kwm_settings KWMSettings = {};
kwm_thread KWMThread = {};
kwm_hotkeys KWMHotkeys = {};
kwm_border FocusedBorder = {};
kwm_border MarkedBorder = {};
scratchpad Scratchpad = {};

CGEventRef CGEventCallback(CGEventTapProxy Proxy, CGEventType Type, CGEventRef Event, void *Refcon)
{
    switch(Type)
    {
        case kCGEventTapDisabledByTimeout:
        case kCGEventTapDisabledByUserInput:
        {
            if(!KWMMach.DisableEventTapInternal)
            {
                DEBUG("Restarting Event Tap");
                CGEventTapEnable(KWMMach.EventTap, true);
            }
        } break;
        case kCGEventKeyDown:
        {
            /* TODO(koekeishiya): Is there a better way to decide whether
                                  we should eat the CGEventRef or not (?) */
            if(KWMSettings.UseBuiltinHotkeys)
            {
                hotkey Eventkey = {}, *Hotkey = NULL;
                Hotkey = (hotkey *) calloc(1, sizeof(hotkey));
                if(Hotkey)
                {
                    CreateHotkeyFromCGEvent(Event, &Eventkey);
                    if(HotkeyExists(Eventkey.Mod, Eventkey.Key, Hotkey, KWMHotkeys.ActiveMode->Name))
                    {
                        AXLibConstructEvent(AXEvent_HotkeyPressed, Hotkey, false);
                        if(!Hotkey->Passthrough)
                            return NULL;
                    }
                    else
                    {
                        free(Hotkey);
                    }
                }
            }
        } break;
        case kCGEventMouseMoved:
        {
            if(KWMSettings.Focus == FocusModeAutoraise)
                AXLibConstructEvent(AXEvent_MouseMoved, NULL, false);
        } break;
        default: {} break;
    }

    return Event;
}

internal bool
CheckPrivileges()
{
    bool Result = false;
    const void * Keys[] = { kAXTrustedCheckOptionPrompt };
    const void * Values[] = { kCFBooleanTrue };

    CFDictionaryRef Options;
    Options = CFDictionaryCreate(kCFAllocatorDefault,
                                 Keys, Values, sizeof(Keys) / sizeof(*Keys),
                                 &kCFCopyStringDictionaryKeyCallBacks,
                                 &kCFTypeDictionaryValueCallBacks);

    Result = AXIsProcessTrustedWithOptions(Options);
    CFRelease(Options);

    return Result;
}

internal bool
CheckArguments(int argc, char **argv)
{
    bool Result = false;

    if(argc == 2)
    {
        std::string Arg = argv[1];
        if(Arg == "--version")
        {
            std::cout << KwmCurrentVersion << std::endl;
            Result = true;
        }
    }

    return Result;
}

internal bool
GetKwmFilePath()
{
    bool Result = false;
    char PathBuf[PROC_PIDPATHINFO_MAXSIZE];
    pid_t Pid = getpid();
    int Ret = proc_pidpath(Pid, PathBuf, sizeof(PathBuf));
    if (Ret > 0)
    {
        KWMPath.FilePath = PathBuf;

        std::size_t Split = KWMPath.FilePath.find_last_of("/\\");
        KWMPath.FilePath = KWMPath.FilePath.substr(0, Split);
        Result = true;
    }

    return Result;
}

internal void
KwmClearSettings()
{
    KWMHotkeys.Modes.clear();
    KWMSettings.WindowRules.clear();
    KWMSettings.SpaceSettings.clear();
    KWMSettings.DisplaySettings.clear();
    KWMHotkeys.ActiveMode = GetBindingMode("default");
}

internal void
KwmExecuteConfig()
{
    char *HomeP = std::getenv("HOME");
    if(!HomeP)
    {
        DEBUG("Failed to get environment variable 'HOME'");
        return;
    }

    KWMPath.EnvHome = HomeP;
    KwmParseConfig(KWMPath.ConfigFile);
}

internal void
KwmExecuteInitScript()
{
    std::string InitFile = KWMPath.EnvHome + "/" + KWMPath.ConfigFolder + "/init";

    struct stat Buffer;
    if(stat(InitFile.c_str(), &Buffer) == 0)
        KwmExecuteThreadedSystemCommand(InitFile);
}

internal void
SignalHandler(int Signum)
{
    ShowAllScratchpadWindows();
    DEBUG("SignalHandler() " << Signum);

    CloseBorder(&FocusedBorder);
    CloseBorder(&MarkedBorder);
    exit(Signum);
}

internal void
Fatal(const std::string &Err)
{
    std::cout << Err << std::endl;
    exit(1);
}

internal void
KwmInit()
{
    if(!CheckPrivileges())
        Fatal("Error: Could not access OSX Accessibility!");

    if(KwmStartDaemon())
        pthread_create(&KWMThread.Daemon, NULL, &KwmDaemonHandleConnectionBG, NULL);
    else
        Fatal("Error: Could not start daemon!");

    signal(SIGSEGV, SignalHandler);
    signal(SIGABRT, SignalHandler);
    signal(SIGTRAP, SignalHandler);
    signal(SIGTERM, SignalHandler);
    signal(SIGKILL, SignalHandler);
    signal(SIGINT, SignalHandler);

    KWMSettings.SplitRatio = 0.5;
    KWMSettings.SplitMode = SPLIT_OPTIMAL;
    KWMSettings.DefaultOffset = CreateDefaultScreenOffset();

    KWMSettings.UseBuiltinHotkeys = true;
    KWMSettings.UseMouseFollowsFocus = true;
    KWMSettings.OptimalRatio = 1.618;
    KWMSettings.LockToContainer = true;

    KWMSettings.Space = SpaceModeBSP;
    KWMSettings.Focus = FocusModeAutoraise;
    KWMSettings.Cycle = CycleModeScreen;

    FocusedBorder.Radius = -1;
    MarkedBorder.Radius = -1;

    KWMPath.ConfigFile = "kwmrc";
    KWMPath.ConfigFolder = ".kwm";
    KWMPath.BSPLayouts = "layouts";
    KWMHotkeys.ActiveMode = GetBindingMode("default");

    GetKwmFilePath();
}

void KwmQuit()
{
    ShowAllScratchpadWindows();
    CloseBorder(&FocusedBorder);
    CloseBorder(&MarkedBorder);

    exit(0);
}

void KwmReloadConfig()
{
    KwmClearSettings();
    KwmExecuteConfig();
}

int main(int argc, char **argv)
{
    if(CheckArguments(argc, argv))
        return 0;

    KwmInit();
    KWMMach.EventMask = ((1 << kCGEventKeyDown) |
                         (1 << kCGEventMouseMoved));

    KWMMach.EventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, kCGEventTapOptionDefault, KWMMach.EventMask, CGEventCallback, NULL);
    if(!KWMMach.EventTap || !CGEventTapIsEnabled(KWMMach.EventTap))
        Fatal("Error: Could not create event-tap!");

    CFRunLoopAddSource(CFRunLoopGetMain(),
                       CFMachPortCreateRunLoopSource(kCFAllocatorDefault, KWMMach.EventTap, 0),
                       kCFRunLoopCommonModes);
    CGEventTapEnable(KWMMach.EventTap, true);
    NSApplicationLoad();

    if(!AXLibDisplayHasSeparateSpaces())
        Fatal("Error: 'Displays have separate spaces' must be enabled!");

    /* NOTE(koekeishiya): Initialize AXLIB */
    AXLibInit(&AXState);
    AXLibStartEventLoop();

    ax_display *MainDisplay = AXLibMainDisplay();
    ax_display *Display = MainDisplay;
    do
    {
        ax_space *PrevSpace = Display->Space;
        Display->Space = AXLibGetActiveSpace(Display);
        Display->PrevSpace = PrevSpace;
        Display = AXLibNextDisplay(Display);
    } while(Display != MainDisplay);

    FocusedDisplay = MainDisplay;
    FocusedApplication = AXLibGetFocusedApplication();

    KwmExecuteConfig();
    KwmExecuteInitScript();
    CreateWindowNodeTree(MainDisplay);
    /* ----------------------------------- */

    CFRunLoopRun();
    return 0;
}
<commit_msg>initialize pointers to null<commit_after>#include "kwm.h"
#include "helpers.h"
#include "daemon.h"
#include "display.h"
#include "space.h"
#include "window.h"
#include "keys.h"
#include "interpreter.h"
#include "scratchpad.h"
#include "border.h"
#include "config.h"
#include "command.h"
#include "cursor.h"
#include "axlib/axlib.h"

#define internal static
const std::string KwmCurrentVersion = "Kwm Version 3.0.0";
std::map<CFStringRef, space_info> WindowTree;

ax_state AXState = {};
ax_display *FocusedDisplay = NULL;
ax_application *FocusedApplication = NULL;
ax_window *MarkedWindow = NULL;

kwm_mach KWMMach = {};
kwm_path KWMPath = {};
kwm_settings KWMSettings = {};
kwm_thread KWMThread = {};
kwm_hotkeys KWMHotkeys = {};
kwm_border FocusedBorder = {};
kwm_border MarkedBorder = {};
scratchpad Scratchpad = {};

CGEventRef CGEventCallback(CGEventTapProxy Proxy, CGEventType Type, CGEventRef Event, void *Refcon)
{
    switch(Type)
    {
        case kCGEventTapDisabledByTimeout:
        case kCGEventTapDisabledByUserInput:
        {
            if(!KWMMach.DisableEventTapInternal)
            {
                DEBUG("Restarting Event Tap");
                CGEventTapEnable(KWMMach.EventTap, true);
            }
        } break;
        case kCGEventKeyDown:
        {
            /* TODO(koekeishiya): Is there a better way to decide whether
                                  we should eat the CGEventRef or not (?) */
            if(KWMSettings.UseBuiltinHotkeys)
            {
                hotkey Eventkey = {}, *Hotkey = NULL;
                Hotkey = (hotkey *) calloc(1, sizeof(hotkey));
                if(Hotkey)
                {
                    CreateHotkeyFromCGEvent(Event, &Eventkey);
                    if(HotkeyExists(Eventkey.Mod, Eventkey.Key, Hotkey, KWMHotkeys.ActiveMode->Name))
                    {
                        AXLibConstructEvent(AXEvent_HotkeyPressed, Hotkey, false);
                        if(!Hotkey->Passthrough)
                            return NULL;
                    }
                    else
                    {
                        free(Hotkey);
                    }
                }
            }
        } break;
        case kCGEventMouseMoved:
        {
            if(KWMSettings.Focus == FocusModeAutoraise)
                AXLibConstructEvent(AXEvent_MouseMoved, NULL, false);
        } break;
        default: {} break;
    }

    return Event;
}

internal bool
CheckPrivileges()
{
    bool Result = false;
    const void * Keys[] = { kAXTrustedCheckOptionPrompt };
    const void * Values[] = { kCFBooleanTrue };

    CFDictionaryRef Options;
    Options = CFDictionaryCreate(kCFAllocatorDefault,
                                 Keys, Values, sizeof(Keys) / sizeof(*Keys),
                                 &kCFCopyStringDictionaryKeyCallBacks,
                                 &kCFTypeDictionaryValueCallBacks);

    Result = AXIsProcessTrustedWithOptions(Options);
    CFRelease(Options);

    return Result;
}

internal bool
CheckArguments(int argc, char **argv)
{
    bool Result = false;

    if(argc == 2)
    {
        std::string Arg = argv[1];
        if(Arg == "--version")
        {
            std::cout << KwmCurrentVersion << std::endl;
            Result = true;
        }
    }

    return Result;
}

internal bool
GetKwmFilePath()
{
    bool Result = false;
    char PathBuf[PROC_PIDPATHINFO_MAXSIZE];
    pid_t Pid = getpid();
    int Ret = proc_pidpath(Pid, PathBuf, sizeof(PathBuf));
    if (Ret > 0)
    {
        KWMPath.FilePath = PathBuf;

        std::size_t Split = KWMPath.FilePath.find_last_of("/\\");
        KWMPath.FilePath = KWMPath.FilePath.substr(0, Split);
        Result = true;
    }

    return Result;
}

internal void
KwmClearSettings()
{
    KWMHotkeys.Modes.clear();
    KWMSettings.WindowRules.clear();
    KWMSettings.SpaceSettings.clear();
    KWMSettings.DisplaySettings.clear();
    KWMHotkeys.ActiveMode = GetBindingMode("default");
}

internal void
KwmExecuteConfig()
{
    char *HomeP = std::getenv("HOME");
    if(!HomeP)
    {
        DEBUG("Failed to get environment variable 'HOME'");
        return;
    }

    KWMPath.EnvHome = HomeP;
    KwmParseConfig(KWMPath.ConfigFile);
}

internal void
KwmExecuteInitScript()
{
    std::string InitFile = KWMPath.EnvHome + "/" + KWMPath.ConfigFolder + "/init";

    struct stat Buffer;
    if(stat(InitFile.c_str(), &Buffer) == 0)
        KwmExecuteThreadedSystemCommand(InitFile);
}

internal void
SignalHandler(int Signum)
{
    ShowAllScratchpadWindows();
    DEBUG("SignalHandler() " << Signum);

    CloseBorder(&FocusedBorder);
    CloseBorder(&MarkedBorder);
    exit(Signum);
}

internal void
Fatal(const std::string &Err)
{
    std::cout << Err << std::endl;
    exit(1);
}

internal void
KwmInit()
{
    if(!CheckPrivileges())
        Fatal("Error: Could not access OSX Accessibility!");

    if(KwmStartDaemon())
        pthread_create(&KWMThread.Daemon, NULL, &KwmDaemonHandleConnectionBG, NULL);
    else
        Fatal("Error: Could not start daemon!");

    signal(SIGSEGV, SignalHandler);
    signal(SIGABRT, SignalHandler);
    signal(SIGTRAP, SignalHandler);
    signal(SIGTERM, SignalHandler);
    signal(SIGKILL, SignalHandler);
    signal(SIGINT, SignalHandler);

    KWMSettings.SplitRatio = 0.5;
    KWMSettings.SplitMode = SPLIT_OPTIMAL;
    KWMSettings.DefaultOffset = CreateDefaultScreenOffset();

    KWMSettings.UseBuiltinHotkeys = true;
    KWMSettings.UseMouseFollowsFocus = true;
    KWMSettings.OptimalRatio = 1.618;
    KWMSettings.LockToContainer = true;

    KWMSettings.Space = SpaceModeBSP;
    KWMSettings.Focus = FocusModeAutoraise;
    KWMSettings.Cycle = CycleModeScreen;

    FocusedBorder.Radius = -1;
    MarkedBorder.Radius = -1;

    KWMPath.ConfigFile = "kwmrc";
    KWMPath.ConfigFolder = ".kwm";
    KWMPath.BSPLayouts = "layouts";
    KWMHotkeys.ActiveMode = GetBindingMode("default");

    GetKwmFilePath();
}

void KwmQuit()
{
    ShowAllScratchpadWindows();
    CloseBorder(&FocusedBorder);
    CloseBorder(&MarkedBorder);

    exit(0);
}

void KwmReloadConfig()
{
    KwmClearSettings();
    KwmExecuteConfig();
}

int main(int argc, char **argv)
{
    if(CheckArguments(argc, argv))
        return 0;

    KwmInit();
    KWMMach.EventMask = ((1 << kCGEventKeyDown) |
                         (1 << kCGEventMouseMoved));

    KWMMach.EventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, kCGEventTapOptionDefault, KWMMach.EventMask, CGEventCallback, NULL);
    if(!KWMMach.EventTap || !CGEventTapIsEnabled(KWMMach.EventTap))
        Fatal("Error: Could not create event-tap!");

    CFRunLoopAddSource(CFRunLoopGetMain(),
                       CFMachPortCreateRunLoopSource(kCFAllocatorDefault, KWMMach.EventTap, 0),
                       kCFRunLoopCommonModes);
    CGEventTapEnable(KWMMach.EventTap, true);
    NSApplicationLoad();

    if(!AXLibDisplayHasSeparateSpaces())
        Fatal("Error: 'Displays have separate spaces' must be enabled!");

    /* NOTE(koekeishiya): Initialize AXLIB */
    AXLibInit(&AXState);
    AXLibStartEventLoop();

    ax_display *MainDisplay = AXLibMainDisplay();
    ax_display *Display = MainDisplay;
    do
    {
        ax_space *PrevSpace = Display->Space;
        Display->Space = AXLibGetActiveSpace(Display);
        Display->PrevSpace = PrevSpace;
        Display = AXLibNextDisplay(Display);
    } while(Display != MainDisplay);

    FocusedDisplay = MainDisplay;
    FocusedApplication = AXLibGetFocusedApplication();

    KwmExecuteConfig();
    KwmExecuteInitScript();
    CreateWindowNodeTree(MainDisplay);
    /* ----------------------------------- */

    CFRunLoopRun();
    return 0;
}
<|endoftext|>


<commit_before>/**********************************************************************
 *  Copyright (c) 2014, Jason W. DeGraw
 *  All rights reserved.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 **********************************************************************/

#include <model/Model.hpp>
#include <osversion/VersionTranslator.hpp>
#include <utilities/core/CommandLine.hpp>
#include <utilities/core/Path.hpp>
#include <utilities/sql/SqlFile.hpp>
#include <utilities/filetypes/EpwFile.hpp>

#include <string>
#include <iostream>
#include <QFile>

void usage( boost::program_options::options_description desc)
{
  std::cout << "Usage: epwtest --input-path=./path/to/input.txt" << std::endl;
  std::cout << "   or: epwtest input.txt" << std::endl;
  std::cout << desc << std::endl;
}

int main(int argc, char *argv[])
{
  std::string inputPathString;
  std::string outputPathString;
  boost::program_options::options_description desc("Allowed options");

  desc.add_options()
    ("help,h", "print help message")
    ("input-path,i", boost::program_options::value<std::string>(&inputPathString), "path to input txt file")
    ("output-path,o", boost::program_options::value<std::string>(&outputPathString), "path to output csv file")
    ("quiet,q", "suppress progress output");

  boost::program_options::positional_options_description pos;
  pos.add("input-path", -1);

  boost::program_options::variables_map vm;
  // The following try/catch block is necessary to avoid uncaught
  // exceptions when the program is executed with more than one
  // "positional" argument - there's got to be a better way.
  try {
    boost::program_options::store(boost::program_options::command_line_parser(argc,
      argv).options(desc).positional(pos).run(), vm);
    boost::program_options::notify(vm);
  } catch(std::exception&) {
    std::cout << "Execution failed: check arguments and retry."<< std::endl << std::endl;
    usage(desc);
    return EXIT_FAILURE;
  }

  if(vm.count("help")) {
    usage(desc);
    return EXIT_SUCCESS;
  }

  if(!vm.count("input-path")) {
    std::cout << "No input path given." << std::endl << std::endl;
    usage(desc);
    return EXIT_FAILURE;
  }

  // Open the output text file, expect one EPW file per line
  if(outputPathString.empty()) {
    outputPathString = "epwfailures.csv";
  }
  QFile outfile(QString().fromStdString(outputPathString));

  if (!outfile.open(QIODevice::WriteOnly | QIODevice::Text)) {
    std::cout << "Failed to open output file '" << outputPathString << "'" << std::endl;
    return EXIT_FAILURE;
  }

  QTextStream csv(&outfile);

  // Open the input text file, expect one EPW file per line
  QFile file(QString().fromStdString(inputPathString));

  if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
    std::cout << "Failed to open input file '" << inputPathString << "'" << std::endl;
    return EXIT_FAILURE;
  }

  QTextStream in(&file);

  QString line = in.readLine();
  while (!line.isNull()) {
    openstudio::path epwPath = openstudio::toPath(line);
    std::cout << line.toStdString() << std::endl;
    boost::optional<openstudio::EpwFile> epwFile;
    try {
      epwFile = openstudio::EpwFile(epwPath,true);
      if(!epwFile) {
        csv << line << ",returned" << endl;
        std::cout << "Failed to read " << line.toStdString() << std::endl;
      }
    } catch(openstudio::Exception &e) {
      csv << line << "," << e.message() << endl;
      std::cout << e.message() << std::endl;
    } catch(...) {
      csv << line << ",exception" << endl;
      std::cout << "Caught exception..." << std::endl;
    }
    line = in.readLine();
  }
  outfile.close();
  return EXIT_SUCCESS;
}
<commit_msg>Fix some bugs, add log output to csv<commit_after>/**********************************************************************
 *  Copyright (c) 2014, Jason W. DeGraw
 *  All rights reserved.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 **********************************************************************/

#include <model/Model.hpp>
#include <osversion/VersionTranslator.hpp>
#include <utilities/core/CommandLine.hpp>
#include <utilities/core/Path.hpp>
#include <utilities/sql/SqlFile.hpp>
#include <utilities/filetypes/EpwFile.hpp>

#include <string>
#include <iostream>
#include <QFile>

void usage( boost::program_options::options_description desc)
{
  std::cout << "Usage: epwtest --input-path=./path/to/input.txt" << std::endl;
  std::cout << "   or: epwtest input.txt" << std::endl;
  std::cout << desc << std::endl;
}

void mineSink(QTextStream &stream, openstudio::StringStreamLogSink &sink)
{
  BOOST_FOREACH(openstudio::LogMessage mesg, sink.logMessages()) {
    stream << "," << mesg.logMessage();
  }
  sink.resetStringStream();
}

int main(int argc, char *argv[])
{
  std::string inputPathString;
  std::string outputPathString;
  boost::program_options::options_description desc("Allowed options");

  desc.add_options()
    ("help,h", "print help message")
    ("input-path,i", boost::program_options::value<std::string>(&inputPathString), "path to input txt file")
    ("output-path,o", boost::program_options::value<std::string>(&outputPathString), "path to output csv file")
    ("quiet,q", "suppress progress output");

  boost::program_options::positional_options_description pos;
  pos.add("input-path", -1);

  boost::program_options::variables_map vm;
  // The following try/catch block is necessary to avoid uncaught
  // exceptions when the program is executed with more than one
  // "positional" argument - there's got to be a better way.
  try {
    boost::program_options::store(boost::program_options::command_line_parser(argc,
      argv).options(desc).positional(pos).run(), vm);
    boost::program_options::notify(vm);
  } catch(std::exception&) {
    std::cout << "Execution failed: check arguments and retry."<< std::endl << std::endl;
    usage(desc);
    return EXIT_FAILURE;
  }

  if(vm.count("help")) {
    usage(desc);
    return EXIT_SUCCESS;
  }

  if(!vm.count("input-path")) {
    std::cout << "No input path given." << std::endl << std::endl;
    usage(desc);
    return EXIT_FAILURE;
  }

  // Try to set up a log sink
  openstudio::StringStreamLogSink sink;
  sink.setChannelRegex(boost::regex("openstudio\\.EpwFile"));

  // Open the output text file, expect one EPW file per line
  if(outputPathString.empty()) {
    outputPathString = "epwfailures.csv";
  }
  QFile outfile(QString().fromStdString(outputPathString));

  if (!outfile.open(QIODevice::WriteOnly | QIODevice::Text)) {
    std::cout << "Failed to open output file '" << outputPathString << "'" << std::endl;
    return EXIT_FAILURE;
  }

  QTextStream csv(&outfile);

  // Open the input text file, expect one EPW file per line
  QFile file(QString().fromStdString(inputPathString));

  if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
    std::cout << "Failed to open input file '" << inputPathString << "'" << std::endl;
    return EXIT_FAILURE;
  }

  QTextStream in(&file);
  QString line = in.readLine();
  while (!line.isNull()) {
    openstudio::path epwPath = openstudio::toPath(line);
    std::cout << line.toStdString() << std::endl;
    boost::optional<openstudio::EpwFile> epwFile;
    try {
      epwFile = openstudio::EpwFile(epwPath,true);
      if(!epwFile) {
        csv << line << ",returned";
        mineSink(csv,sink);
        csv << endl;
        std::cout << "Failed to read " << line.toStdString() << std::endl;
      }
    } catch(openstudio::Exception &e) {
      csv << line << "," << e.message();
      mineSink(csv,sink);
      csv << endl;
      std::cout << e.message() << std::endl;
    } catch(...) {
      csv << line << ",exception";
      mineSink(csv,sink);
      csv << endl;
      std::cout << "Caught exception..." << std::endl;
    }
    line = in.readLine();
  }
  outfile.close();
  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/*
    Copyright (c) 2011 Volker Krause <vkrause@kde.org>

    This library is free software; you can redistribute it and/or modify it
    under the terms of the GNU Library General Public License as published by
    the Free Software Foundation; either version 2 of the License, or (at your
    option) any later version.

    This library is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
    License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to the
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
*/

#include "akstandarddirs.h"
#include "akapplication.h"

#include <libs/xdgbasedirs_p.h>

#include <QFile>

using namespace Akonadi;

QString AkStandardDirs::configFile(const QString& configFile, Akonadi::XdgBaseDirs::FileAccessMode openMode)
{
  const QString savePath = AkStandardDirs::saveDir( "config" ) + QLatin1Char( '/' ) + configFile;

  if ( openMode == XdgBaseDirs::WriteOnly )
    return savePath;

  QString path = XdgBaseDirs::findResourceFile( "config", QLatin1String("akonadi/") + configFile );
  // HACK: when using instance namespaces, ignore the non-namespaced file
  if ( !AkApplication::instanceIdentifier().isEmpty() && path.startsWith( XdgBaseDirs::homePath("config") ) )
    path.clear();

  if ( path.isEmpty() ) {
    return savePath;
  } else if ( openMode == XdgBaseDirs::ReadOnly || path == savePath ) {
    return path;
  }

  // file found in system paths and mode is ReadWrite, thus
  // we copy to the home path location and return this path
  QFile systemFile( path );

  systemFile.copy( savePath );

  return savePath;
}

QString AkStandardDirs::serverConfigFile(XdgBaseDirs::FileAccessMode openMode)
{
  return configFile( QLatin1String("akonadiserverrc"), openMode );
}

QString AkStandardDirs::connectionConfigFile(XdgBaseDirs::FileAccessMode openMode)
{
  return configFile( QLatin1String("akonadiconnectionrc"), openMode );
}

QString AkStandardDirs::agentConfigFile(XdgBaseDirs::FileAccessMode openMode)
{
  return configFile( QLatin1String("agentsrc"), openMode );
}

QString AkStandardDirs::saveDir(const char* resource, const QString& relPath)
{
  QString fullRelPath = QLatin1String("akonadi");
  if ( !AkApplication::instanceIdentifier().isEmpty() )
    fullRelPath += QLatin1Char('/') + AkApplication::instanceIdentifier();
  if ( !relPath.isEmpty() )
    fullRelPath += QLatin1Char('/') + relPath;
  return XdgBaseDirs::saveDir( resource, fullRelPath );
}
<commit_msg>Avoid name clashes with file names used by a non-namespaced instance.<commit_after>/*
    Copyright (c) 2011 Volker Krause <vkrause@kde.org>

    This library is free software; you can redistribute it and/or modify it
    under the terms of the GNU Library General Public License as published by
    the Free Software Foundation; either version 2 of the License, or (at your
    option) any later version.

    This library is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
    License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to the
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
*/

#include "akstandarddirs.h"
#include "akapplication.h"

#include <libs/xdgbasedirs_p.h>

#include <QFile>

using namespace Akonadi;

QString AkStandardDirs::configFile(const QString& configFile, Akonadi::XdgBaseDirs::FileAccessMode openMode)
{
  const QString savePath = AkStandardDirs::saveDir( "config" ) + QLatin1Char( '/' ) + configFile;

  if ( openMode == XdgBaseDirs::WriteOnly )
    return savePath;

  QString path = XdgBaseDirs::findResourceFile( "config", QLatin1String("akonadi/") + configFile );
  // HACK: when using instance namespaces, ignore the non-namespaced file
  if ( !AkApplication::instanceIdentifier().isEmpty() && path.startsWith( XdgBaseDirs::homePath("config") ) )
    path.clear();

  if ( path.isEmpty() ) {
    return savePath;
  } else if ( openMode == XdgBaseDirs::ReadOnly || path == savePath ) {
    return path;
  }

  // file found in system paths and mode is ReadWrite, thus
  // we copy to the home path location and return this path
  QFile systemFile( path );

  systemFile.copy( savePath );

  return savePath;
}

QString AkStandardDirs::serverConfigFile(XdgBaseDirs::FileAccessMode openMode)
{
  return configFile( QLatin1String("akonadiserverrc"), openMode );
}

QString AkStandardDirs::connectionConfigFile(XdgBaseDirs::FileAccessMode openMode)
{
  return configFile( QLatin1String("akonadiconnectionrc"), openMode );
}

QString AkStandardDirs::agentConfigFile(XdgBaseDirs::FileAccessMode openMode)
{
  return configFile( QLatin1String("agentsrc"), openMode );
}

QString AkStandardDirs::saveDir(const char* resource, const QString& relPath)
{
  QString fullRelPath = QLatin1String("akonadi");
  if ( !AkApplication::instanceIdentifier().isEmpty() )
    fullRelPath += QLatin1String("/instance/") + AkApplication::instanceIdentifier();
  if ( !relPath.isEmpty() )
    fullRelPath += QLatin1Char('/') + relPath;
  return XdgBaseDirs::saveDir( resource, fullRelPath );
}
<|endoftext|>


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

/*******************************************************************************
 * \file position_estimation.h
 *
 * \author MAV'RIC Team
 *
 * \brief This file performs the 3D position estimation, either by direct
 * integration or with correction with the GPS and pos_est->barometer
 *
 ******************************************************************************/

#ifndef POSITION_ESTIMATION_H__
#define POSITION_ESTIMATION_H__

#include "state.hpp"
#include "gps_ublox.hpp"
#include "bmp085.hpp"

extern "C"
{
	#include <stdbool.h>
	#include "ahrs.h"
	#include "coord_conventions.h"
	#include "constants.h"
}

// leaky velocity integration as a simple trick to emulate drag and avoid too large deviations (loss per 1 second)
#define VEL_DECAY 0.0f
#define POS_DECAY 0.0f

/**
 * \brief The position estimator structure
 */
typedef struct
{
	global_position_t origin;	///<	Global coordinates of the local frame's origin (ie. local (0, 0, 0) expressed in the global frame)
	float gravity;				///<	value of the Gravity for position estimation correction
} position_estimation_conf_t;

/**
 * \brief The position estimator structure
 */
typedef struct
{
	float kp_vel_gps[3];							///< The gain to correct the velocity estimation from the GPS
	float kp_pos_gps[3];							///< The gain to correct the position estimation from the GPS
	float kp_alt_baro;								///< The gain to correct the Z position estimation from the barometer
	float kp_vel_baro;								///< The gain to correct the position estimation from the barometer

	uint32_t time_last_gps_msg;						///< The time at which we received the last GPS message in ms
	uint32_t time_last_barometer_msg;				///< The time at which we received the last barometer message in ms
	bool init_gps_position;							///< The boolean flag ensuring that the GPS was initialized
	bool init_barometer;							///< The boolean flag ensuring that the barometer was initialized

	float vel_bf[3];								///< The 3D velocity in body frame
	float vel[3];									///< The 3D velocity in global frame

	float last_alt;									///< The value of the last altitude estimation
	float last_vel[3];								///< The last 3D velocity

	local_coordinates_t local_position;				///< The local position
	local_coordinates_t last_gps_pos;				///< The coordinates of the last GPS position

	float gravity;									///< The value of the gravity

	//barometer_t* barometer;							///< The pointer to the barometer structure
	Barometer* barometer;
	const gps_t* gps;								///< The pointer to the GPS structure
	const ahrs_t* ahrs;								///< The pointer to the attitude estimation structure
	state_t* state;									///< The pointer to the state structure

	bool* nav_plan_active;							///< The pointer to the waypoint set flag
} position_estimation_t;

/**
 * \brief	Initialize the position estimation module
 *
 * \param	pos_est					The pointer to the position estimation structure
 * \param	config					The configuration for default home position and gravity value
 * \param	state					The pointer to the state structure
 * \param	barometer				The pointer to the barometer structure
 * \param	gps						The pointer to the GPS structure
 * \param	ahrs					The pointer to the attitude estimation structure
 *
 * \return	True if the init succeed, false otherwise
 */
bool position_estimation_init(position_estimation_t* pos_est, const position_estimation_conf_t config, state_t* state, Barometer* barometer, const gps_t *gps, const ahrs_t *ahrs);

/**
 * \brief	Reset the home position and altitude
 *
 * \param	pos_est					The pointer to the position estimation structure
 */
void position_estimation_reset_home_altitude(position_estimation_t *pos_est);

/**
 * \brief	Position estimation update step, performing position estimation then position correction (function to be used)
 *
 * \param	pos_est					The pointer to the position estimation structure
 */
void position_estimation_update(position_estimation_t *pos_est);

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

/*******************************************************************************
 * \file position_estimation.h
 *
 * \author MAV'RIC Team
 *
 * \brief This file performs the 3D position estimation, either by direct
 * integration or with correction with the GPS and pos_est->barometer
 *
 ******************************************************************************/

#ifndef POSITION_ESTIMATION_H__
#define POSITION_ESTIMATION_H__

#include "state.hpp"
#include "gps_ublox.hpp"
#include "bmp085.hpp"

extern "C"
{
	#include <stdbool.h>
	#include "ahrs.h"
	#include "coord_conventions.h"
	#include "constants.h"
}

// leaky velocity integration as a simple trick to emulate drag and avoid too large deviations (loss per 1 second)
#define VEL_DECAY 0.0f
#define POS_DECAY 0.0f

/**
 * \brief The position estimator structure
 */
typedef struct
{
	global_position_t origin;	///<	Global coordinates of the local frame's origin (ie. local (0, 0, 0) expressed in the global frame)
	float gravity;				///<	value of the Gravity for position estimation correction
} position_estimation_conf_t;

/**
 * \brief The position estimator structure
 */
typedef struct
{
	float kp_vel_gps[3];							///< The gain to correct the velocity estimation from the GPS
	float kp_pos_gps[3];							///< The gain to correct the position estimation from the GPS
	float kp_alt_baro;								///< The gain to correct the Z position estimation from the barometer
	float kp_vel_baro;								///< The gain to correct the position estimation from the barometer

	uint32_t time_last_gps_msg;						///< The time at which we received the last GPS message in ms
	uint32_t time_last_barometer_msg;				///< The time at which we received the last barometer message in ms
	bool init_gps_position;							///< The boolean flag ensuring that the GPS was initialized
	bool init_barometer;							///< The boolean flag ensuring that the barometer was initialized

	float vel_bf[3];								///< The 3D velocity in body frame
	float vel[3];									///< The 3D velocity in global frame

	float last_alt;									///< The value of the last altitude estimation
	float last_vel[3];								///< The last 3D velocity

	local_coordinates_t local_position;				///< The local position
	local_coordinates_t last_gps_pos;				///< The coordinates of the last GPS position

	float gravity;									///< The value of the gravity

	Barometer* barometer;							///< The pointer to the barometer object
	const gps_t* gps;								///< The pointer to the GPS structure
	const ahrs_t* ahrs;								///< The pointer to the attitude estimation structure
	state_t* state;									///< The pointer to the state structure

	bool* nav_plan_active;							///< The pointer to the waypoint set flag
} position_estimation_t;

/**
 * \brief	Initialize the position estimation module
 *
 * \param	pos_est					The pointer to the position estimation structure
 * \param	config					The configuration for default home position and gravity value
 * \param	state					The pointer to the state structure
 * \param	barometer				The pointer to the barometer structure
 * \param	gps						The pointer to the GPS structure
 * \param	ahrs					The pointer to the attitude estimation structure
 *
 * \return	True if the init succeed, false otherwise
 */
bool position_estimation_init(position_estimation_t* pos_est, const position_estimation_conf_t config, state_t* state, Barometer* barometer, const gps_t *gps, const ahrs_t *ahrs);

/**
 * \brief	Reset the home position and altitude
 *
 * \param	pos_est					The pointer to the position estimation structure
 */
void position_estimation_reset_home_altitude(position_estimation_t *pos_est);

/**
 * \brief	Position estimation update step, performing position estimation then position correction (function to be used)
 *
 * \param	pos_est					The pointer to the position estimation structure
 */
void position_estimation_update(position_estimation_t *pos_est);

#endif // POSITION_ESTIMATION_H__<|endoftext|>


<commit_before>/*
 * UserStateLayer.cpp
 *
 * Copyright (C) 2020 by RStudio, PBC
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#include "UserStateLayer.hpp"

#include <core/system/Xdg.hpp>

#include <session/SessionOptions.hpp>
#include <session/prefs/UserState.hpp>

using namespace rstudio::core;

namespace rstudio {
namespace session {
namespace prefs {

UserStateLayer::UserStateLayer():
   PrefLayer(kUserStateUserLayer)
{
}

core::Error UserStateLayer::readPrefs()
{
   FilePath schemaFile = options().rResourcesPath().completePath("schema").completePath(kUserStateSchemaFile);

   // desktop and server versions of RStudio use separate state files so that mixing desktop and server
   // on the same machine is possible w/o side effects like sharing a source database
   stateFile_ = core::system::xdg::userDataDir().completePath(
         options().programMode() == kSessionProgramModeDesktop ?
            kUserStateFileDesktop :
            kUserStateFileServer);

   if (!stateFile_.exists())
   {
      // if there's no state file yet, check for a state file left by an older version of RStudio 1.3
      FilePath oldStateFile = core::system::xdg::userDataDir().completePath("rstudio-state.json");
      if (oldStateFile.exists())
      {
          // found an old file; attempt to migrate it
          Error error = oldStateFile.move(stateFile_);
          if (error)
              LOG_ERROR(error);
      }
   }

   return loadPrefsFromFile(stateFile_, schemaFile);
}

core::Error UserStateLayer::writePrefs(const core::json::Object &prefs)
{
   if (stateFile_.isEmpty())
   {
      return fileNotFoundError(ERROR_LOCATION);
   }

   RECURSIVE_LOCK_MUTEX(mutex_)
   {
      *cache_ = prefs;
   }
   END_LOCK_MUTEX

   return writePrefsToFile(*cache_, stateFile_);
}

} // namespace prefs
} // namespace session
} // namespace rstudio

<commit_msg>user state file only accessible by owning user<commit_after>/*
 * UserStateLayer.cpp
 *
 * Copyright (C) 2020 by RStudio, PBC
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#include "UserStateLayer.hpp"

#include <core/system/Xdg.hpp>

#include <session/SessionOptions.hpp>
#include <session/prefs/UserState.hpp>

using namespace rstudio::core;

namespace rstudio {
namespace session {
namespace prefs {

UserStateLayer::UserStateLayer():
   PrefLayer(kUserStateUserLayer)
{
}

core::Error UserStateLayer::readPrefs()
{
   FilePath schemaFile = options().rResourcesPath().completePath("schema").completePath(kUserStateSchemaFile);

   // desktop and server versions of RStudio use separate state files so that mixing desktop and server
   // on the same machine is possible w/o side effects like sharing a source database
   stateFile_ = core::system::xdg::userDataDir().completePath(
         options().programMode() == kSessionProgramModeDesktop ?
            kUserStateFileDesktop :
            kUserStateFileServer);

   if (!stateFile_.exists())
   {
      // if there's no state file yet, check for a state file left by an older version of RStudio 1.3
      FilePath oldStateFile = core::system::xdg::userDataDir().completePath("rstudio-state.json");
      if (oldStateFile.exists())
      {
          // found an old file; attempt to migrate it
          Error error = oldStateFile.move(stateFile_);
          if (error)
              LOG_ERROR(error);
      }
   }

   return loadPrefsFromFile(stateFile_, schemaFile);
}

core::Error UserStateLayer::writePrefs(const core::json::Object &prefs)
{
   if (stateFile_.isEmpty())
   {
      return fileNotFoundError(ERROR_LOCATION);
   }

   // ensure state file can only be read/written by this user
#ifndef _WIN32
   Error error = stateFile_.changeFileMode(FileMode::USER_READ_WRITE);
   if (error)
      LOG_ERROR(error);
#endif

   RECURSIVE_LOCK_MUTEX(mutex_)
   {
      *cache_ = prefs;
   }
   END_LOCK_MUTEX

   return writePrefsToFile(*cache_, stateFile_);
}

} // namespace prefs
} // namespace session
} // namespace rstudio

<|endoftext|>


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

#include "OrbitBase/Tracing.h"

#include <memory>
#include <vector>

#include "OrbitBase/Logging.h"
#include "OrbitBase/Profiling.h"
#include "OrbitBase/ThreadPool.h"

using orbit::tracing::Scope;
using orbit::tracing::ScopeType;
using orbit::tracing::TimerCallback;

ABSL_CONST_INIT static absl::Mutex global_callback_mutex(absl::kConstInit);
ABSL_CONST_INIT static std::unique_ptr<TimerCallback> global_callback = {};
ABSL_CONST_INIT static absl::Mutex global_thread_pool_mutex(absl::kConstInit);
ABSL_CONST_INIT static std::unique_ptr<ThreadPool> glolbal_thread_pool = {};

static std::vector<Scope>& GetThreadLocalScopes() {
  thread_local std::vector<Scope> thread_local_scopes;
  return thread_local_scopes;
}

static void CreateCallbackThreadPool() {
  constexpr size_t kMinNumThreads = 1;
  constexpr size_t kMaxNumThreads = 1;
  absl::MutexLock lock(&global_thread_pool_mutex);
  CHECK(glolbal_thread_pool == nullptr);
  glolbal_thread_pool = ThreadPool::Create(kMinNumThreads, kMaxNumThreads, absl::Milliseconds(500));
}

static void ShutdownCallbackThreadPool() {
  absl::MutexLock lock(&global_thread_pool_mutex);
  CHECK(glolbal_thread_pool != nullptr);
  glolbal_thread_pool->Shutdown();
  glolbal_thread_pool->Wait();
}

static void DeferScopeProcessing(const Scope& scope) {
  // User callback is called from a worker thread to
  // minimize contention on the instrumented threads.
  glolbal_thread_pool->Schedule([scope]() {
    absl::MutexLock lock(&global_callback_mutex);
    if (global_callback != nullptr) (*global_callback)(scope);
  });
}

namespace orbit::tracing {

Listener::Listener(std::unique_ptr<TimerCallback> callback) {
  CreateCallbackThreadPool();
  absl::MutexLock lock(&global_callback_mutex);
  // Only one listener is supported.
  CHECK(global_callback == nullptr);
  global_callback = std::move(callback);
}

Listener::~Listener() {
  {
    absl::MutexLock lock(&global_callback_mutex);
    global_callback = nullptr;
  }
  ShutdownCallbackThreadPool();
}

}  // namespace orbit::tracing

namespace orbit_api {

void Start(const char* name, uint8_t, orbit::Color color) {
  GetThreadLocalScopes().emplace_back(orbit::tracing::Scope());
  auto& scope = GetThreadLocalScopes().back();
  scope.name = name;
  scope.begin = MonotonicTimestampNs();
  scope.color = color;
}

void Stop() {
  auto& scope = GetThreadLocalScopes().back();
  scope.end = MonotonicTimestampNs();
  scope.depth = GetThreadLocalScopes().size() - 1;
  scope.tid = GetCurrentThreadId();
  scope.type = ScopeType::kScope;
  DeferScopeProcessing(scope);
  GetThreadLocalScopes().pop_back();
}

// Will be implemented shortly.
void StartAsync(const char*, uint64_t, orbit::Color) { CHECK(0); }
void StopAsync(uint64_t) { CHECK(0); }

void TrackScope(const char* name, uint64_t value, orbit::Color color, ScopeType type) {
  orbit::tracing::Scope scope;
  scope.begin = MonotonicTimestampNs();
  scope.name = name;
  scope.color = color;
  scope.tracked_value = value;
  scope.tid = GetCurrentThreadId();
  scope.type = type;
  DeferScopeProcessing(scope);
}

template <typename Dest, typename Source>
inline Dest Encode(const Source& source) {
  static_assert(sizeof(Source) <= sizeof(Dest));
  Dest dest = 0;
  std::memcpy(&dest, &source, sizeof(Source));
  return dest;
}

void TrackInt(const char* name, int32_t value, orbit::Color color) {
  TrackScope(name, Encode<uint64_t>(value), color, ScopeType::kTrackInt);
}

void TrackInt64(const char* name, int64_t value, orbit::Color color) {
  TrackScope(name, Encode<uint64_t>(value), color, ScopeType::kTrackInt64);
}

void TrackUint(const char* name, uint32_t value, orbit::Color color) {
  TrackScope(name, Encode<uint64_t>(value), color, ScopeType::kTrackUint);
}

void TrackUint64(const char* name, uint64_t value, orbit::Color color) {
  TrackScope(name, value, color, ScopeType::kTrackUint64);
}

void TrackFloat(const char* name, float value, orbit::Color color) {
  TrackScope(name, Encode<uint64_t>(value), color, ScopeType::kTrackFloatAsInt);
}

void TrackDouble(const char* name, double value, orbit::Color color) {
  TrackScope(name, Encode<uint64_t>(value), color, ScopeType::kTrackDoubleAsInt64);
}

}  // namespace orbit_api
<commit_msg>Fix glolbal_thread_pool typo<commit_after>// Copyright (c) 2020 The Orbit Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "OrbitBase/Tracing.h"

#include <memory>
#include <vector>

#include "OrbitBase/Logging.h"
#include "OrbitBase/Profiling.h"
#include "OrbitBase/ThreadPool.h"

using orbit::tracing::Scope;
using orbit::tracing::ScopeType;
using orbit::tracing::TimerCallback;

ABSL_CONST_INIT static absl::Mutex global_callback_mutex(absl::kConstInit);
ABSL_CONST_INIT static std::unique_ptr<TimerCallback> global_callback = {};
ABSL_CONST_INIT static absl::Mutex global_thread_pool_mutex(absl::kConstInit);
ABSL_CONST_INIT static std::unique_ptr<ThreadPool> global_thread_pool = {};

static std::vector<Scope>& GetThreadLocalScopes() {
  thread_local std::vector<Scope> thread_local_scopes;
  return thread_local_scopes;
}

static void CreateCallbackThreadPool() {
  constexpr size_t kMinNumThreads = 1;
  constexpr size_t kMaxNumThreads = 1;
  absl::MutexLock lock(&global_thread_pool_mutex);
  CHECK(global_thread_pool == nullptr);
  global_thread_pool = ThreadPool::Create(kMinNumThreads, kMaxNumThreads, absl::Milliseconds(500));
}

static void ShutdownCallbackThreadPool() {
  absl::MutexLock lock(&global_thread_pool_mutex);
  CHECK(global_thread_pool != nullptr);
  global_thread_pool->Shutdown();
  global_thread_pool->Wait();
}

static void DeferScopeProcessing(const Scope& scope) {
  // User callback is called from a worker thread to
  // minimize contention on the instrumented threads.
  global_thread_pool->Schedule([scope]() {
    absl::MutexLock lock(&global_callback_mutex);
    if (global_callback != nullptr) (*global_callback)(scope);
  });
}

namespace orbit::tracing {

Listener::Listener(std::unique_ptr<TimerCallback> callback) {
  CreateCallbackThreadPool();
  absl::MutexLock lock(&global_callback_mutex);
  // Only one listener is supported.
  CHECK(global_callback == nullptr);
  global_callback = std::move(callback);
}

Listener::~Listener() {
  {
    absl::MutexLock lock(&global_callback_mutex);
    global_callback = nullptr;
  }
  ShutdownCallbackThreadPool();
}

}  // namespace orbit::tracing

namespace orbit_api {

void Start(const char* name, uint8_t, orbit::Color color) {
  GetThreadLocalScopes().emplace_back(orbit::tracing::Scope());
  auto& scope = GetThreadLocalScopes().back();
  scope.name = name;
  scope.begin = MonotonicTimestampNs();
  scope.color = color;
}

void Stop() {
  auto& scope = GetThreadLocalScopes().back();
  scope.end = MonotonicTimestampNs();
  scope.depth = GetThreadLocalScopes().size() - 1;
  scope.tid = GetCurrentThreadId();
  scope.type = ScopeType::kScope;
  DeferScopeProcessing(scope);
  GetThreadLocalScopes().pop_back();
}

// Will be implemented shortly.
void StartAsync(const char*, uint64_t, orbit::Color) { CHECK(0); }
void StopAsync(uint64_t) { CHECK(0); }

void TrackScope(const char* name, uint64_t value, orbit::Color color, ScopeType type) {
  orbit::tracing::Scope scope;
  scope.begin = MonotonicTimestampNs();
  scope.name = name;
  scope.color = color;
  scope.tracked_value = value;
  scope.tid = GetCurrentThreadId();
  scope.type = type;
  DeferScopeProcessing(scope);
}

template <typename Dest, typename Source>
inline Dest Encode(const Source& source) {
  static_assert(sizeof(Source) <= sizeof(Dest));
  Dest dest = 0;
  std::memcpy(&dest, &source, sizeof(Source));
  return dest;
}

void TrackInt(const char* name, int32_t value, orbit::Color color) {
  TrackScope(name, Encode<uint64_t>(value), color, ScopeType::kTrackInt);
}

void TrackInt64(const char* name, int64_t value, orbit::Color color) {
  TrackScope(name, Encode<uint64_t>(value), color, ScopeType::kTrackInt64);
}

void TrackUint(const char* name, uint32_t value, orbit::Color color) {
  TrackScope(name, Encode<uint64_t>(value), color, ScopeType::kTrackUint);
}

void TrackUint64(const char* name, uint64_t value, orbit::Color color) {
  TrackScope(name, value, color, ScopeType::kTrackUint64);
}

void TrackFloat(const char* name, float value, orbit::Color color) {
  TrackScope(name, Encode<uint64_t>(value), color, ScopeType::kTrackFloatAsInt);
}

void TrackDouble(const char* name, double value, orbit::Color color) {
  TrackScope(name, Encode<uint64_t>(value), color, ScopeType::kTrackDoubleAsInt64);
}

}  // namespace orbit_api
<|endoftext|>


<commit_before>/*
   Source File : PDFDate.cpp

   Copyright 2011 Gal Kahana PDFWriter

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

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

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

*/
#include "PDFDate.h"
#include "SafeBufferMacrosDefs.h"
#include "Trace.h"
#include "BoxingBase.h"
#if defined (__MWERKS__)
	// MAC OSX methods for providing UTC difference
	#include <CoreFoundation/CFDate.h>
	#include <CoreFoundation/CFTimeZone.h>
#endif

#include <ctime>
#include <math.h>
#include <stdlib.h>

PDFDate::PDFDate(void)
{
	SetTime(-1);
}

PDFDate::~PDFDate(void)
{
}

void PDFDate::SetTime(	int inYear,
						int inMonth,
						int inDay,
						int inHour,
						int inMinute,
						int inSecond,
						EUTCRelation inUTC,
						int inHourFromUTC,
						int inMinuteFromUTC)
{
	Year = inYear;
	Month = inMonth;
	Day = inDay;
	Hour = inHour;
	Minute = inMinute;
	Second = inSecond;
	UTC = inUTC;
	HourFromUTC = inHourFromUTC;
	MinuteFromUTC = inMinuteFromUTC;
}

bool PDFDate::IsNull()
{
	return -1 == Year;
}

/*
	write a string represetnation of the date. undefined parameters will not
	have values in the string unless later values are defined. in that
	case the PDF specs defaults are used [See section 3.8.3 of PDF Reference, V1.7]

*/

static const std::string scEmpty = "";
std::string PDFDate::ToString()
{
	if(IsNull())
		return scEmpty;

	char buffer[24];
	bool wroteSomethingLater = false;

	// UTC info
	if(UTC != PDFDate::eUndefined)
	{
		if(PDFDate::eSame == UTC)
		{
			buffer[17] = '\0';
			buffer[16] = 'Z';
		}
		else
		{
			buffer[23] = '\0';
			buffer[22] = '\'';
			buffer[21] = '0' + ((-1 == MinuteFromUTC ? 0:MinuteFromUTC) % 10);
			buffer[20] = '0' + ((-1 == MinuteFromUTC ? 0:MinuteFromUTC) / 10);
			buffer[19] = '\'';
			buffer[18] = '0' + ((-1 == HourFromUTC ? 0:HourFromUTC) % 10);
			buffer[17] = '0' + ((-1 == HourFromUTC ? 0:HourFromUTC) / 10);
			buffer[16] = (PDFDate::eLater == UTC )? '+':'-';
		}
		wroteSomethingLater = true;
	}

	// Second
	if(Second != -1 || wroteSomethingLater)
	{
		if(!wroteSomethingLater)
		{
			wroteSomethingLater = true;
			buffer[16] = '\0';
		}
		buffer[15] = '0' + ((-1 == Second ? 0:Second) % 10);
		buffer[14] = '0' + ((-1 == Second ? 0:Second) / 10);
	}

	// Minute
	if(Minute != -1 || wroteSomethingLater)
	{
		if(!wroteSomethingLater)
		{
			wroteSomethingLater = true;
			buffer[14] = '\0';
		}
		buffer[13] = '0' + ((-1 == Minute ? 0:Minute) % 10);
		buffer[12] = '0' + ((-1 == Minute ? 0:Minute) / 10);
	}

	// Hour
	if(Hour != -1 || wroteSomethingLater)
	{
		if(!wroteSomethingLater)
		{
			wroteSomethingLater = true;
			buffer[12] = '\0';
		}
		buffer[11] = '0' + ((-1 == Hour ? 0:Hour) % 10);
		buffer[10] = '0' + ((-1 == Hour ? 0:Hour) / 10);
	}

	// Day
	if(Day != -1 || wroteSomethingLater)
	{
		if(!wroteSomethingLater)
		{
			wroteSomethingLater = true;
			buffer[10] = '\0';
		}
		buffer[9] = '0' + ((-1 == Day ? 1:Day) % 10);
		buffer[8] = '0' + ((-1 == Day ? 1:Day) / 10);
	}

	// Month
	if(Month != -1 || wroteSomethingLater)
	{
		if(!wroteSomethingLater)
		{
			wroteSomethingLater = true;
			buffer[8] = '\0';
		}
		buffer[7] = '0' + ((-1 == Month ? 1:Month) % 10);
		buffer[6] = '0' + ((-1 == Month ? 1:Month) / 10);
	}

	// Year [bug 10K waiting to happen!!!!111]
	if(!wroteSomethingLater)
		buffer[6] = '\0';
	buffer[5] = '0' + Year % 10;
	buffer[4] = '0' + (Year/10) % 10;
	buffer[3] = '0' + (Year/100) % 10;
	buffer[2] = '0' + (Year/1000) % 10;
	buffer[1] = ':';
	buffer[0] = 'D';

	return std::string(buffer);
}

void PDFDate::SetToCurrentTime()
{
	time_t currentTime;
	tm structuredLocalTime;
	long timeZoneSecondsDifference;

	time(&currentTime);
	SAFE_LOCAL_TIME(structuredLocalTime,currentTime);

	Year = structuredLocalTime.tm_year + 1900;
	Month = structuredLocalTime.tm_mon + 1;
	Day = structuredLocalTime.tm_mday;
	Hour = structuredLocalTime.tm_hour;
	Minute = structuredLocalTime.tm_min;
	Second = structuredLocalTime.tm_sec;

	// if unsuccesful or method unknown don't provide UTC info (currently only knows for WIN32 and OSX
#if defined (__MWERKS__) || defined (__GNUC__)  || defined(_AIX32) || defined(WIN32)
	int status;
#if !defined(__MWERKS__) && !defined(__MINGW32__) // (using MS methods)
	struct tm *gmTime;

	time_t localEpoch, gmEpoch;

	/*First get local epoch time*/
	localEpoch = time(NULL);

	/* Using local time epoch get the GM Time */
	gmTime = gmtime(&localEpoch);
	gmTime->tm_isdst = -1;
	/* Convert gm time in to epoch format */
	gmEpoch = mktime(gmTime);

	timeZoneSecondsDifference =difftime(gmEpoch, localEpoch);
	status = 0;
#else // __MWERKS__ (using OSX methods)
	CFTimeZoneRef tzRef = ::CFTimeZoneCopySystem();
	if (tzRef)
	{
		CFTimeInterval intervalFromGMT = ::CFTimeZoneGetSecondsFromGMT(tzRef, currentTime);
		::CFRelease(tzRef);
		timeZoneSecondsDifference = intervalFromGMT;
		status = 0;
	}
	else
		status = -1;
#endif

	if(0 == status)
	{
		if(0 == timeZoneSecondsDifference)
		{
			UTC = eSame;
		}
		else
		{
			UTC = timeZoneSecondsDifference > 0 ? eEarlier : eLater;
			HourFromUTC = (int)(labs(timeZoneSecondsDifference) / 3600);
			MinuteFromUTC = (int)((labs(timeZoneSecondsDifference) - (labs(timeZoneSecondsDifference) / 3600)*3600) / 60);
		}
	}
	else
	{
		UTC = eUndefined;
		TRACE_LOG("PDFDate::SetToCurrentTime, Couldn't get UTC.");
	}

#else
	UTC = eUndefined;
#endif
}

void PDFDate::ParseString(std::string inValue)
{
    if(inValue.length() < 2 || inValue[0] != 'D' || inValue[1] != ':')
    {
        Year = -1;
        return;
    }

    Year = Int(inValue.substr(2,4));
    Month = -1;
    Day = -1;
    Hour = -1;
    Minute = -1;
    Second = -1;
    UTC = eUndefined;
    HourFromUTC = -1;
    MinuteFromUTC = -1;

    if(inValue.length() < 7)
        return;

    Month = Int(inValue.substr(6,2));

    if(inValue.length() < 9)
        return;

    Day = Int(inValue.substr(8,2));

    if(inValue.length() < 11)
        return;

    Hour = Int(inValue.substr(10,2));

    if(inValue.length() < 13)
        return;

    Minute = Int(inValue.substr(12,2));

    if(inValue.length() < 15)
        return;

    Second = Int(inValue.substr(14,2));

    if(inValue.length() < 17)
        return;

    if(inValue[16] == 'Z')
    {
        UTC = eSame;
    }
    else if(inValue[16] == '-' || inValue[16] == '+')
    {
        UTC = (inValue[16] == '-') ? eEarlier:eLater;

        if(inValue.length() < 18)
            return;

        HourFromUTC = Int(inValue.substr(17,2));

        if(inValue.length() < 21) // skipping '
            return;

        MinuteFromUTC = Int(inValue.substr(20,2));
    }

}<commit_msg>mingw too<commit_after>/*
   Source File : PDFDate.cpp

   Copyright 2011 Gal Kahana PDFWriter

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

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

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

*/
#include "PDFDate.h"
#include "SafeBufferMacrosDefs.h"
#include "Trace.h"
#include "BoxingBase.h"
#if defined (__MWERKS__)
	// MAC OSX methods for providing UTC difference
	#include <CoreFoundation/CFDate.h>
	#include <CoreFoundation/CFTimeZone.h>
#endif

#include <ctime>
#include <math.h>
#include <stdlib.h>

PDFDate::PDFDate(void)
{
	SetTime(-1);
}

PDFDate::~PDFDate(void)
{
}

void PDFDate::SetTime(	int inYear,
						int inMonth,
						int inDay,
						int inHour,
						int inMinute,
						int inSecond,
						EUTCRelation inUTC,
						int inHourFromUTC,
						int inMinuteFromUTC)
{
	Year = inYear;
	Month = inMonth;
	Day = inDay;
	Hour = inHour;
	Minute = inMinute;
	Second = inSecond;
	UTC = inUTC;
	HourFromUTC = inHourFromUTC;
	MinuteFromUTC = inMinuteFromUTC;
}

bool PDFDate::IsNull()
{
	return -1 == Year;
}

/*
	write a string represetnation of the date. undefined parameters will not
	have values in the string unless later values are defined. in that
	case the PDF specs defaults are used [See section 3.8.3 of PDF Reference, V1.7]

*/

static const std::string scEmpty = "";
std::string PDFDate::ToString()
{
	if(IsNull())
		return scEmpty;

	char buffer[24];
	bool wroteSomethingLater = false;

	// UTC info
	if(UTC != PDFDate::eUndefined)
	{
		if(PDFDate::eSame == UTC)
		{
			buffer[17] = '\0';
			buffer[16] = 'Z';
		}
		else
		{
			buffer[23] = '\0';
			buffer[22] = '\'';
			buffer[21] = '0' + ((-1 == MinuteFromUTC ? 0:MinuteFromUTC) % 10);
			buffer[20] = '0' + ((-1 == MinuteFromUTC ? 0:MinuteFromUTC) / 10);
			buffer[19] = '\'';
			buffer[18] = '0' + ((-1 == HourFromUTC ? 0:HourFromUTC) % 10);
			buffer[17] = '0' + ((-1 == HourFromUTC ? 0:HourFromUTC) / 10);
			buffer[16] = (PDFDate::eLater == UTC )? '+':'-';
		}
		wroteSomethingLater = true;
	}

	// Second
	if(Second != -1 || wroteSomethingLater)
	{
		if(!wroteSomethingLater)
		{
			wroteSomethingLater = true;
			buffer[16] = '\0';
		}
		buffer[15] = '0' + ((-1 == Second ? 0:Second) % 10);
		buffer[14] = '0' + ((-1 == Second ? 0:Second) / 10);
	}

	// Minute
	if(Minute != -1 || wroteSomethingLater)
	{
		if(!wroteSomethingLater)
		{
			wroteSomethingLater = true;
			buffer[14] = '\0';
		}
		buffer[13] = '0' + ((-1 == Minute ? 0:Minute) % 10);
		buffer[12] = '0' + ((-1 == Minute ? 0:Minute) / 10);
	}

	// Hour
	if(Hour != -1 || wroteSomethingLater)
	{
		if(!wroteSomethingLater)
		{
			wroteSomethingLater = true;
			buffer[12] = '\0';
		}
		buffer[11] = '0' + ((-1 == Hour ? 0:Hour) % 10);
		buffer[10] = '0' + ((-1 == Hour ? 0:Hour) / 10);
	}

	// Day
	if(Day != -1 || wroteSomethingLater)
	{
		if(!wroteSomethingLater)
		{
			wroteSomethingLater = true;
			buffer[10] = '\0';
		}
		buffer[9] = '0' + ((-1 == Day ? 1:Day) % 10);
		buffer[8] = '0' + ((-1 == Day ? 1:Day) / 10);
	}

	// Month
	if(Month != -1 || wroteSomethingLater)
	{
		if(!wroteSomethingLater)
		{
			wroteSomethingLater = true;
			buffer[8] = '\0';
		}
		buffer[7] = '0' + ((-1 == Month ? 1:Month) % 10);
		buffer[6] = '0' + ((-1 == Month ? 1:Month) / 10);
	}

	// Year [bug 10K waiting to happen!!!!111]
	if(!wroteSomethingLater)
		buffer[6] = '\0';
	buffer[5] = '0' + Year % 10;
	buffer[4] = '0' + (Year/10) % 10;
	buffer[3] = '0' + (Year/100) % 10;
	buffer[2] = '0' + (Year/1000) % 10;
	buffer[1] = ':';
	buffer[0] = 'D';

	return std::string(buffer);
}

void PDFDate::SetToCurrentTime()
{
	time_t currentTime;
	tm structuredLocalTime;
	long timeZoneSecondsDifference;

	time(&currentTime);
	SAFE_LOCAL_TIME(structuredLocalTime,currentTime);

	Year = structuredLocalTime.tm_year + 1900;
	Month = structuredLocalTime.tm_mon + 1;
	Day = structuredLocalTime.tm_mday;
	Hour = structuredLocalTime.tm_hour;
	Minute = structuredLocalTime.tm_min;
	Second = structuredLocalTime.tm_sec;

	// if unsuccesful or method unknown don't provide UTC info (currently only knows for WIN32 and OSX
#if defined (__MWERKS__) || defined (__GNUC__)  || defined(_AIX32) || defined(WIN32)
	int status;
#if !defined(__MWERKS__) // (using c methods)
	struct tm *gmTime;

	time_t localEpoch, gmEpoch;

	/*First get local epoch time*/
	localEpoch = time(NULL);

	/* Using local time epoch get the GM Time */
	gmTime = gmtime(&localEpoch);
	gmTime->tm_isdst = -1;
	/* Convert gm time in to epoch format */
	gmEpoch = mktime(gmTime);

	timeZoneSecondsDifference =difftime(gmEpoch, localEpoch);
	status = 0;
#else // __MWERKS__ (using OSX methods)
	CFTimeZoneRef tzRef = ::CFTimeZoneCopySystem();
	if (tzRef)
	{
		CFTimeInterval intervalFromGMT = ::CFTimeZoneGetSecondsFromGMT(tzRef, currentTime);
		::CFRelease(tzRef);
		timeZoneSecondsDifference = intervalFromGMT;
		status = 0;
	}
	else
		status = -1;
#endif

	if(0 == status)
	{
		if(0 == timeZoneSecondsDifference)
		{
			UTC = eSame;
		}
		else
		{
			UTC = timeZoneSecondsDifference > 0 ? eEarlier : eLater;
			HourFromUTC = (int)(labs(timeZoneSecondsDifference) / 3600);
			MinuteFromUTC = (int)((labs(timeZoneSecondsDifference) - (labs(timeZoneSecondsDifference) / 3600)*3600) / 60);
		}
	}
	else
	{
		UTC = eUndefined;
		TRACE_LOG("PDFDate::SetToCurrentTime, Couldn't get UTC.");
	}

#else
	UTC = eUndefined;
#endif
}

void PDFDate::ParseString(std::string inValue)
{
    if(inValue.length() < 2 || inValue[0] != 'D' || inValue[1] != ':')
    {
        Year = -1;
        return;
    }

    Year = Int(inValue.substr(2,4));
    Month = -1;
    Day = -1;
    Hour = -1;
    Minute = -1;
    Second = -1;
    UTC = eUndefined;
    HourFromUTC = -1;
    MinuteFromUTC = -1;

    if(inValue.length() < 7)
        return;

    Month = Int(inValue.substr(6,2));

    if(inValue.length() < 9)
        return;

    Day = Int(inValue.substr(8,2));

    if(inValue.length() < 11)
        return;

    Hour = Int(inValue.substr(10,2));

    if(inValue.length() < 13)
        return;

    Minute = Int(inValue.substr(12,2));

    if(inValue.length() < 15)
        return;

    Second = Int(inValue.substr(14,2));

    if(inValue.length() < 17)
        return;

    if(inValue[16] == 'Z')
    {
        UTC = eSame;
    }
    else if(inValue[16] == '-' || inValue[16] == '+')
    {
        UTC = (inValue[16] == '-') ? eEarlier:eLater;

        if(inValue.length() < 18)
            return;

        HourFromUTC = Int(inValue.substr(17,2));

        if(inValue.length() < 21) // skipping '
            return;

        MinuteFromUTC = Int(inValue.substr(20,2));
    }

}<|endoftext|>


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

/* Author: Ioan Sucan */

#include <moveit/warehouse/planning_scene_storage.h>
#include <moveit/warehouse/state_storage.h>
#include <moveit/warehouse/constraints_storage.h>
#include <boost/program_options/cmdline.hpp>
#include <boost/program_options/variables_map.hpp>
#include <moveit/planning_scene_monitor/planning_scene_monitor.h>
#include <moveit/kinematic_state/conversions.h>
#include <ros/ros.h>

static const std::string ROBOT_DESCRIPTION="robot_description";

typedef std::pair<geometry_msgs::Point, geometry_msgs::Quaternion> LinkConstraintPair;
typedef std::map<std::string, LinkConstraintPair > LinkConstraintMap;

void collectLinkConstraints(const moveit_msgs::Constraints& constraints, LinkConstraintMap& lcmap )
{
  for(std::size_t i = 0; i < constraints.position_constraints.size(); ++i)
  {
    LinkConstraintPair lcp;
    const moveit_msgs::PositionConstraint &pc = constraints.position_constraints[i];
    lcp.first = pc.constraint_region.primitive_poses[0].position;
    lcmap[constraints.position_constraints[i].link_name] = lcp;
  }

  for(std::size_t i = 0; i < constraints.orientation_constraints.size(); ++i)
  {
    if(lcmap.count(constraints.orientation_constraints[i].link_name))
    {
      lcmap[constraints.orientation_constraints[i].link_name].second = constraints.orientation_constraints[i].orientation;
    } else{
      ROS_WARN("Orientation constraint for %s has no matching position constraint", constraints.orientation_constraints[i].link_name.c_str());
    }
  }
}

int main(int argc, char **argv)
{
  ros::init(argc, argv, "save_warehouse_as_text", ros::init_options::AnonymousName);

  boost::program_options::options_description desc;
  desc.add_options()
    ("help", "Show help message")
    ("host", boost::program_options::value<std::string>(), "Host for the MongoDB.")
    ("port", boost::program_options::value<std::size_t>(), "Port for the MongoDB.");

  boost::program_options::variables_map vm;
  boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
  boost::program_options::notify(vm);

  if (vm.count("help"))
  {
    std::cout << desc << std::endl;
    return 1;
  }

  ros::AsyncSpinner spinner(1);
  spinner.start();

  planning_scene_monitor::PlanningSceneMonitor psm(ROBOT_DESCRIPTION);

  moveit_warehouse::PlanningSceneStorage pss(vm.count("host") ? vm["host"].as<std::string>() : "",
                                             vm.count("port") ? vm["port"].as<std::size_t>() : 0);

  moveit_warehouse::RobotStateStorage rss(vm.count("host") ? vm["host"].as<std::string>() : "",
                                             vm.count("port") ? vm["port"].as<std::size_t>() : 0);

  moveit_warehouse::ConstraintsStorage cs(vm.count("host") ? vm["host"].as<std::string>() : "",
                                             vm.count("port") ? vm["port"].as<std::size_t>() : 0);

  std::vector<std::string> scene_names;
  pss.getPlanningSceneNames(scene_names);

  for (std::size_t i = 0 ; i < scene_names.size() ; ++i)
  {
    moveit_warehouse::PlanningSceneWithMetadata pswm;
    if (pss.getPlanningScene(pswm, scene_names[i]))
    {
      ROS_INFO("Saving scene '%s'", scene_names[i].c_str());
      psm.getPlanningScene()->setPlanningSceneMsg(static_cast<const moveit_msgs::PlanningScene&>(*pswm));
      std::ofstream fout((scene_names[i] + ".scene").c_str());
      psm.getPlanningScene()->saveGeometryToStream(fout);
      fout.close();

      std::vector<std::string> robotStateNames;
      kinematic_model::KinematicModelConstPtr km = psm.getKinematicModel();
      // Get start states for scene
      std::stringstream rsregex;
      rsregex << ".*" << scene_names[i] << ".*";
      rss.getKnownRobotStates(rsregex.str(), robotStateNames);

      // Get goal constraints for scene
      std::vector<std::string> constraintNames;

      std::stringstream csregex;
      csregex << ".*" << scene_names[i] << ".*";
      cs.getKnownConstraints(csregex.str(), constraintNames);

      if( !(robotStateNames.empty() && constraintNames.empty()) )
      {
        std::ofstream qfout((scene_names[i] + ".queries").c_str());
        qfout << scene_names[i] << std::endl;
        if(robotStateNames.size())
        {
          qfout << "start" << std::endl;
          qfout << robotStateNames.size() << std::endl;
          for(int k = 0; k < robotStateNames.size(); ++k)
          {
            ROS_INFO("Saving start state %s for scene %s", robotStateNames[k].c_str(), scene_names[i].c_str());
            qfout << robotStateNames[k] << std::endl;
            moveit_warehouse::RobotStateWithMetadata robotState;
            rss.getRobotState(robotState, robotStateNames[k]);
            kinematic_state::KinematicState ks(km);
            kinematic_state::robotStateToKinematicState(*robotState, ks, false);
            ks.printStateInfo(qfout);
            qfout << "." << std::endl;
          }
        }

        if(constraintNames.size())
        {
          qfout << "goal" << std::endl;
          qfout << constraintNames.size() << std::endl;
          for(int k = 0; k < constraintNames.size(); ++k)
          {
            ROS_INFO("Saving goal %s for scene %s", constraintNames[k].c_str(), scene_names[i].c_str());
            qfout << "link_constraint" << std::endl;
            qfout << constraintNames[k] << std::endl;
            moveit_warehouse::ConstraintsWithMetadata constraints;
            cs.getConstraints(constraints, constraintNames[k]);

            LinkConstraintMap lcmap;
            collectLinkConstraints(*constraints, lcmap);
            for(LinkConstraintMap::iterator iter = lcmap.begin(); iter != lcmap.end(); iter++)
            {
              std::string link_name = iter->first;
              LinkConstraintPair lcp = iter->second;
              qfout << link_name << std::endl;
              qfout << "xyz " << lcp.first.x << " " << lcp.first.y << " " << lcp.first.z << std::endl;
              Eigen::Quaterniond orientation(lcp.second.w, lcp.second.x, lcp.second.y, lcp.second.z);
              Eigen::Vector3d rpy = orientation.matrix().eulerAngles(0, 1, 2);
              qfout << "rpy " << rpy[0] << " " << rpy[1] << " " << rpy[2] << std::endl;

            }
            qfout << "." << std::endl;
          }
        }
        qfout.close();
      }
    }

  }

  ROS_INFO("Done.");

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

/* Author: Ioan Sucan */

#include <moveit/warehouse/planning_scene_storage.h>
#include <moveit/warehouse/state_storage.h>
#include <moveit/warehouse/constraints_storage.h>
#include <boost/program_options/cmdline.hpp>
#include <boost/program_options/variables_map.hpp>
#include <moveit/planning_scene_monitor/planning_scene_monitor.h>
#include <moveit/kinematic_state/conversions.h>
#include <ros/ros.h>

static const std::string ROBOT_DESCRIPTION="robot_description";

typedef std::pair<geometry_msgs::Point, geometry_msgs::Quaternion> LinkConstraintPair;
typedef std::map<std::string, LinkConstraintPair > LinkConstraintMap;

void collectLinkConstraints(const moveit_msgs::Constraints& constraints, LinkConstraintMap& lcmap )
{
  for(std::size_t i = 0; i < constraints.position_constraints.size(); ++i)
  {
    LinkConstraintPair lcp;
    const moveit_msgs::PositionConstraint &pc = constraints.position_constraints[i];
    lcp.first = pc.constraint_region.primitive_poses[0].position;
    lcmap[constraints.position_constraints[i].link_name] = lcp;
  }

  for(std::size_t i = 0; i < constraints.orientation_constraints.size(); ++i)
  {
    if(lcmap.count(constraints.orientation_constraints[i].link_name))
    {
      lcmap[constraints.orientation_constraints[i].link_name].second = constraints.orientation_constraints[i].orientation;
    } else{
      ROS_WARN("Orientation constraint for %s has no matching position constraint", constraints.orientation_constraints[i].link_name.c_str());
    }
  }
}

int main(int argc, char **argv)
{
  ros::init(argc, argv, "save_warehouse_as_text", ros::init_options::AnonymousName);

  boost::program_options::options_description desc;
  desc.add_options()
    ("help", "Show help message")
    ("host", boost::program_options::value<std::string>(), "Host for the MongoDB.")
    ("port", boost::program_options::value<std::size_t>(), "Port for the MongoDB.");

  boost::program_options::variables_map vm;
  boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
  boost::program_options::notify(vm);

  if (vm.count("help"))
  {
    std::cout << desc << std::endl;
    return 1;
  }

  ros::AsyncSpinner spinner(1);
  spinner.start();

  planning_scene_monitor::PlanningSceneMonitor psm(ROBOT_DESCRIPTION);

  moveit_warehouse::PlanningSceneStorage pss(vm.count("host") ? vm["host"].as<std::string>() : "",
                                             vm.count("port") ? vm["port"].as<std::size_t>() : 0);

  moveit_warehouse::RobotStateStorage rss(vm.count("host") ? vm["host"].as<std::string>() : "",
                                             vm.count("port") ? vm["port"].as<std::size_t>() : 0);

  moveit_warehouse::ConstraintsStorage cs(vm.count("host") ? vm["host"].as<std::string>() : "",
                                             vm.count("port") ? vm["port"].as<std::size_t>() : 0);

  std::vector<std::string> scene_names;
  pss.getPlanningSceneNames(scene_names);

  for (std::size_t i = 0 ; i < scene_names.size() ; ++i)
  {
    moveit_warehouse::PlanningSceneWithMetadata pswm;
    if (pss.getPlanningScene(pswm, scene_names[i]))
    {
      ROS_INFO("Saving scene '%s'", scene_names[i].c_str());
      psm.getPlanningScene()->setPlanningSceneMsg(static_cast<const moveit_msgs::PlanningScene&>(*pswm));
      std::ofstream fout((scene_names[i] + ".scene").c_str());
      psm.getPlanningScene()->saveGeometryToStream(fout);
      fout.close();

      std::vector<std::string> robotStateNames;
      kinematic_model::KinematicModelConstPtr km = psm.getKinematicModel();
      // Get start states for scene
      std::stringstream rsregex;
      rsregex << ".*" << scene_names[i] << ".*";
      rss.getKnownRobotStates(rsregex.str(), robotStateNames);

      // Get goal constraints for scene
      std::vector<std::string> constraintNames;

      std::stringstream csregex;
      csregex << ".*" << scene_names[i] << ".*";
      cs.getKnownConstraints(csregex.str(), constraintNames);

      if( !(robotStateNames.empty() && constraintNames.empty()) )
      {
        std::ofstream qfout((scene_names[i] + ".queries").c_str());
        qfout << scene_names[i] << std::endl;
        if(robotStateNames.size())
        {
          qfout << "start" << std::endl;
          qfout << robotStateNames.size() << std::endl;
          for(std::size_t k = 0; k < robotStateNames.size(); ++k)
          {
            ROS_INFO("Saving start state %s for scene %s", robotStateNames[k].c_str(), scene_names[i].c_str());
            qfout << robotStateNames[k] << std::endl;
            moveit_warehouse::RobotStateWithMetadata robotState;
            rss.getRobotState(robotState, robotStateNames[k]);
            kinematic_state::KinematicState ks(km);
            kinematic_state::robotStateToKinematicState(*robotState, ks, false);
            ks.printStateInfo(qfout);
            qfout << "." << std::endl;
          }
        }

        if(constraintNames.size())
        {
          qfout << "goal" << std::endl;
          qfout << constraintNames.size() << std::endl;
          for(std::size_t k = 0; k < constraintNames.size(); ++k)
          {
            ROS_INFO("Saving goal %s for scene %s", constraintNames[k].c_str(), scene_names[i].c_str());
            qfout << "link_constraint" << std::endl;
            qfout << constraintNames[k] << std::endl;
            moveit_warehouse::ConstraintsWithMetadata constraints;
            cs.getConstraints(constraints, constraintNames[k]);

            LinkConstraintMap lcmap;
            collectLinkConstraints(*constraints, lcmap);
            for(LinkConstraintMap::iterator iter = lcmap.begin(); iter != lcmap.end(); iter++)
            {
              std::string link_name = iter->first;
              LinkConstraintPair lcp = iter->second;
              qfout << link_name << std::endl;
              qfout << "xyz " << lcp.first.x << " " << lcp.first.y << " " << lcp.first.z << std::endl;
              Eigen::Quaterniond orientation(lcp.second.w, lcp.second.x, lcp.second.y, lcp.second.z);
              Eigen::Vector3d rpy = orientation.matrix().eulerAngles(0, 1, 2);
              qfout << "rpy " << rpy[0] << " " << rpy[1] << " " << rpy[2] << std::endl;

            }
            qfout << "." << std::endl;
          }
        }
        qfout.close();
      }
    }

  }

  ROS_INFO("Done.");

  return 0;
}
<|endoftext|>


<commit_before><commit_msg>Strat, modify orders (need to fix assert in TwsDL::placeOrder)<commit_after><|endoftext|>


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

#include <ostream>

#include <client.hpp>
#include <message.hpp>
#include <use.hpp>

#include <cassert>

namespace deepstream {
namespace client
{

std::ostream& operator<<(std::ostream& os, State state)
{
	os << static_cast<int>(state);
	return os;
}

State transition(State state, const Message& message, Sender sender)
{
	assert( state != State::ERROR );
	assert( state != State::DISCONNECTED );

	const Topic topic = message.topic();
	const Action action = message.action();
	const bool is_ack = message.is_ack();

	const auto expected_num_args = Message::num_arguments( message.header() );
	const std::size_t& num_args = message.num_arguments();

	use(expected_num_args);
	assert( num_args >= expected_num_args.first );
	assert( num_args <= expected_num_args.second );

	// ping/pong
	if( topic == Topic::CONNECTION &&
		action == Action::PING &&
		sender == Sender::SERVER )
	{
		assert( !is_ack );

		return state;
	}

	if( topic == Topic::CONNECTION &&
		action == Action::PONG &&
		sender == Sender::CLIENT )
	{
		assert( !is_ack );

		return state;
	}

	// actual state transitions
	if( state == State::AWAIT_CONNECTION &&
		topic == Topic::CONNECTION &&
		action == Action::CHALLENGE &&
		sender == Sender::SERVER )
	{
		assert( !is_ack );

		return State::CHALLENGING;
	}

	if( state == State::CHALLENGING &&
		topic == Topic::CONNECTION &&
		action == Action::CHALLENGE_RESPONSE &&
		sender == Sender::CLIENT )
	{
		assert( !is_ack );

		return State::CHALLENGING_WAIT;
	}

	if( state == State::CHALLENGING_WAIT &&
		topic == Topic::CONNECTION &&
		action == Action::CHALLENGE_RESPONSE &&
		sender == Sender::SERVER )
	{
		assert( is_ack );

		return State::AWAIT_AUTHENTICATION;
	}

	if( state == State::CHALLENGING_WAIT &&
		topic == Topic::CONNECTION &&
		action == Action::REDIRECT &&
		sender == Sender::SERVER )
	{
		assert( !is_ack );

		return State::AWAIT_CONNECTION;
	}

	if( state == State::CHALLENGING_WAIT &&
		topic == Topic::CONNECTION &&
		action == Action::REJECT &&
		sender == Sender::SERVER )
	{
		assert( !is_ack );

		return State::DISCONNECTED;
	}

	if( state == State::AWAIT_AUTHENTICATION &&
		topic == Topic::AUTH &&
		action == Action::REQUEST &&
		sender == Sender::CLIENT )
	{
		assert( !is_ack );

		return State::AUTHENTICATING;
	}

	if( state == State::AUTHENTICATING &&
		topic == Topic::AUTH &&
		action == Action::REQUEST &&
		sender == Sender::SERVER )
	{
		assert( is_ack );

		return State::CONNECTED;
	}

	if( state == State::AUTHENTICATING &&
		topic == Topic::AUTH &&
		action == Action::ERROR_TOO_MANY_AUTH_ATTEMPTS &&
		sender == Sender::SERVER )
	{
		assert( !is_ack );

		return State::DISCONNECTED;
	}

	if( state == State::AUTHENTICATING &&
		topic == Topic::AUTH &&
		action == Action::ERROR_INVALID_AUTH_DATA &&
		sender == Sender::SERVER )
	{
		assert( !is_ack );

		return State::AWAIT_AUTHENTICATION;
	}

	if( state == State::AUTHENTICATING &&
		topic == Topic::AUTH &&
		action == Action::ERROR_INVALID_AUTH_MSG &&
		sender == Sender::SERVER )
	{
		assert( !is_ack );

		return State::DISCONNECTED;
	}

	return State::ERROR;
}

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

#include <ostream>

#include <client.hpp>
#include <message.hpp>
#include <use.hpp>

#include <cassert>

namespace deepstream {
namespace client
{

std::ostream& operator<<(std::ostream& os, State state)
{
	os << static_cast<int>(state);
	return os;
}

State transition(State state, const Message& message, Sender sender)
{
	assert( state != State::ERROR );
	assert( state != State::DISCONNECTED );

	const Topic topic = message.topic();
	const Action action = message.action();
	const bool is_ack = message.is_ack();

	const auto expected_num_args = Message::num_arguments( message.header() );
	const std::size_t& num_args = message.num_arguments();

	use(expected_num_args);
	assert( num_args >= expected_num_args.first );
	assert( num_args <= expected_num_args.second );

	// ping/pong
	if( topic == Topic::CONNECTION &&
		action == Action::PING &&
		sender == Sender::SERVER )
	{
		assert( !is_ack );

		return state;
	}

	if( topic == Topic::CONNECTION &&
		action == Action::PONG &&
		sender == Sender::CLIENT )
	{
		assert( !is_ack );

		return state;
	}

	// actual state transitions
	if( state == State::AWAIT_CONNECTION &&
		topic == Topic::CONNECTION &&
		action == Action::CHALLENGE &&
		sender == Sender::SERVER )
	{
		assert( !is_ack );

		return State::CHALLENGING;
	}

	if( state == State::CHALLENGING &&
		topic == Topic::CONNECTION &&
		action == Action::CHALLENGE_RESPONSE &&
		sender == Sender::CLIENT )
	{
		assert( !is_ack );

		return State::CHALLENGING_WAIT;
	}

	if( state == State::CHALLENGING_WAIT &&
		topic == Topic::CONNECTION &&
		action == Action::CHALLENGE_RESPONSE &&
		sender == Sender::SERVER )
	{
		assert( is_ack );

		return State::AWAIT_AUTHENTICATION;
	}

	if( state == State::CHALLENGING_WAIT &&
		topic == Topic::CONNECTION &&
		action == Action::REDIRECT &&
		sender == Sender::SERVER )
	{
		assert( !is_ack );

		return State::AWAIT_CONNECTION;
	}

	if( state == State::CHALLENGING_WAIT &&
		topic == Topic::CONNECTION &&
		action == Action::REJECT &&
		sender == Sender::SERVER )
	{
		assert( !is_ack );

		return State::DISCONNECTED;
	}

	if( state == State::AWAIT_AUTHENTICATION &&
		topic == Topic::AUTH &&
		action == Action::REQUEST &&
		sender == Sender::CLIENT )
	{
		assert( !is_ack );

		return State::AUTHENTICATING;
	}

	if( state == State::AUTHENTICATING &&
		topic == Topic::AUTH &&
		action == Action::REQUEST &&
		sender == Sender::SERVER )
	{
		assert( is_ack );

		return State::CONNECTED;
	}

	if( state == State::AUTHENTICATING &&
		topic == Topic::AUTH &&
		action == Action::ERROR_TOO_MANY_AUTH_ATTEMPTS &&
		sender == Sender::SERVER )
	{
		assert( !is_ack );

		return State::DISCONNECTED;
	}

	if( state == State::AUTHENTICATING &&
		topic == Topic::AUTH &&
		action == Action::ERROR_INVALID_AUTH_DATA &&
		sender == Sender::SERVER )
	{
		assert( !is_ack );

		return State::AWAIT_AUTHENTICATION;
	}

	if( state == State::AUTHENTICATING &&
		topic == Topic::AUTH &&
		action == Action::ERROR_INVALID_AUTH_MSG &&
		sender == Sender::SERVER )
	{
		assert( !is_ack );

		return State::DISCONNECTED;
	}

	if( state == State::CONNECTED &&
		topic == Topic::EVENT )
	{
		if( action == Action::LISTEN ||
			action == Action::SUBSCRIBE ||
			action == Action::UNLISTEN ||
			action == Action::UNSUBSCRIBE )
		{
			if( (sender == Sender::CLIENT && !is_ack) ||
				(sender == Sender::SERVER && is_ack) )
				return state;
		}
		else if( action == Action::EVENT )
			return state;
	}

	return State::ERROR;
}

}
}
<|endoftext|>


<commit_before>#include <algorithm>
#include <cpr/cpr.h>
#include <utils.h>
#include "command.h"
#include "../CommandHandler.h"
#include "../OptionParser.h"
#include "../stringparse.h"

/* full name of the command */
CMDNAME("ge");
/* description of the command */
CMDDESCR("look up item prices");
/* command usage synopsis */
CMDUSAGE("$ge [-n AMT] ITEM");

static const std::string EXCHANGE_API =
	"https://api.rsbuddy.com/grandExchange?a=guidePrice&i=";

static int64_t extract_price(const std::string &resp);

/* ge: look up item prices */
std::string CommandHandler::ge(char *out, struct command *c)
{
	if (!m_GEReader.active())
		return CMDNAME + ": GE reader is inactive";

	std::string output, name;
	int64_t amt, price;
	cpr::Response resp;
	Json::Value item;

	int opt;
	OptionParser op(c->fullCmd, "n:");
	static struct OptionParser::option long_opts[] = {
		{ "amount", REQ_ARG, 'n' },
		{ "help", NO_ARG, 'h' },
		{ 0, 0, 0 }
	};

	amt = 1;
	while ((opt = op.getopt_long(long_opts)) != EOF) {
		switch (opt) {
		case 'h':
			return HELPMSG(CMDNAME, CMDUSAGE, CMDDESCR);
		case 'n':
			if (!parsenum_mult(op.optarg(), &amt))
				return CMDNAME + ": invalid number -- '"
					+ std::string(op.optarg()) + "'";
			break;
		case '?':
			return std::string(op.opterr());
		default:
			return "";
		}
	}

	if (op.optind() == c->fullCmd.length())
		return USAGEMSG(CMDNAME, CMDUSAGE);

	name = c->fullCmd.substr(op.optind());
	std::replace(name.begin(), name.end(), '_', ' ');

	/* find item in database */
	if ((item = m_GEReader.getItem(name)).empty())
		return CMDNAME + ": item not found: " + name;

	/* read ge api and extract data */
	resp = cpr::Get(cpr::Url(EXCHANGE_API + item["id"].asString()),
		cpr::Header{{ "Connection", "close" }});
	if ((price = extract_price(resp.text)) == -1)
		return CMDNAME + ": could not extract price";

	output = "[GE] ";
	if (amt != 1)
		output += utils::formatInteger(std::to_string(amt)) + "x ";
	output += item["name"].asString() + ": ";
	output += utils::formatInteger(std::to_string(amt * price)) + " gp";

	return output;
}

/* extract_price: return the price of the json data in resp */
static int64_t extract_price(const std::string &resp)
{
	Json::Reader reader;
	Json::Value item;
	if (reader.parse(resp, item))
		return item["overall"].asInt();
	else
		return -1;
}
<commit_msg>int64<commit_after>#include <algorithm>
#include <cpr/cpr.h>
#include <utils.h>
#include "command.h"
#include "../CommandHandler.h"
#include "../OptionParser.h"
#include "../stringparse.h"

/* full name of the command */
CMDNAME("ge");
/* description of the command */
CMDDESCR("look up item prices");
/* command usage synopsis */
CMDUSAGE("$ge [-n AMT] ITEM");

static const std::string EXCHANGE_API =
	"https://api.rsbuddy.com/grandExchange?a=guidePrice&i=";

static int64_t extract_price(const std::string &resp);

/* ge: look up item prices */
std::string CommandHandler::ge(char *out, struct command *c)
{
	if (!m_GEReader.active())
		return CMDNAME + ": GE reader is inactive";

	std::string output, name;
	int64_t amt, price;
	cpr::Response resp;
	Json::Value item;

	int opt;
	OptionParser op(c->fullCmd, "n:");
	static struct OptionParser::option long_opts[] = {
		{ "amount", REQ_ARG, 'n' },
		{ "help", NO_ARG, 'h' },
		{ 0, 0, 0 }
	};

	amt = 1;
	while ((opt = op.getopt_long(long_opts)) != EOF) {
		switch (opt) {
		case 'h':
			return HELPMSG(CMDNAME, CMDUSAGE, CMDDESCR);
		case 'n':
			if (!parsenum_mult(op.optarg(), &amt))
				return CMDNAME + ": invalid number -- '"
					+ std::string(op.optarg()) + "'";
			break;
		case '?':
			return std::string(op.opterr());
		default:
			return "";
		}
	}

	if (op.optind() == c->fullCmd.length())
		return USAGEMSG(CMDNAME, CMDUSAGE);

	name = c->fullCmd.substr(op.optind());
	std::replace(name.begin(), name.end(), '_', ' ');

	/* find item in database */
	if ((item = m_GEReader.getItem(name)).empty())
		return CMDNAME + ": item not found: " + name;

	/* read ge api and extract data */
	resp = cpr::Get(cpr::Url(EXCHANGE_API + item["id"].asString()),
		cpr::Header{{ "Connection", "close" }});
	if ((price = extract_price(resp.text)) == -1)
		return CMDNAME + ": could not extract price";

	output = "[GE] ";
	if (amt != 1)
		output += utils::formatInteger(std::to_string(amt)) + "x ";
	output += item["name"].asString() + ": ";
	output += utils::formatInteger(std::to_string(amt * price)) + " gp";

	return output;
}

/* extract_price: return the price of the json data in resp */
static int64_t extract_price(const std::string &resp)
{
	Json::Reader reader;
	Json::Value item;
	if (reader.parse(resp, item))
		return item["overall"].asInt64();
	else
		return -1;
}
<|endoftext|>