text:
/*
// Copyright (c) 2019 Intel Corporation
//
// 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.
*/
#pragma once

#include <boost/algorithm/string/predicate.hpp>
#include <boost/asio.hpp>
#include <sdbusplus/asio/object_server.hpp>

#include <string>

namespace pfr
{

enum class ImageType
{
    cpldActive,
    cpldRecovery,
    biosActive,
    biosRecovery,
    bmcActive,
    bmcRecovery,
    afmActive,
    afmRecovery
};

enum class ActionType
{
    recoveryCount,
    recoveryReason,
    panicCount,
    panicReason,
    majorError,
    minorError,
    readRoTRev
};

std::string toHexString(const uint8_t val);
std::string getFirmwareVersion(const ImageType& imgType);
int getProvisioningStatus(bool& ufmLocked, bool& ufmProvisioned,
                          bool& ufmSupport);
int readCpldReg(const ActionType& action, uint8_t& value);
std::string readCPLDVersion();
int setBMCBootCheckpoint(const uint8_t checkPoint);
void init(std::shared_ptr<sdbusplus::asio::connection> conn,
          bool& i2cConfigLoaded);

} // namespace pfr

max_stars_repo_name: openbmc/pfr-manager

max_issues_repo_name: openbmc/pfr-manager

max_forks_repo_name: openbmc/pfr-manager


text:
#include <openrave/openrave.h>
#include <openrave/plugin.h>
#include <boost/bind.hpp>
#include <iostream>
#include <cstdlib>
#include <stdio.h>
#include <stdlib.h>
#include "rrtHelper.h"

using namespace std;
using namespace OpenRAVE;

class MyNewModule : public ModuleBase
{
public:
    MyNewModule(EnvironmentBasePtr penv, std::istream& ss) : ModuleBase(penv) {

        penv_=penv;

        RegisterCommand("MyCommand",boost::bind(&MyNewModule::MyCommand,this,_1,_2),
                        "This is an example command");

        RegisterCommand("goal",boost::bind(&MyNewModule::SetGoal,this,_1,_2),
                        "goal %f %f %f %f %f %f %f;");

        RegisterCommand("bias",boost::bind(&MyNewModule::SetBias,this,_1,_2),
                        "bias %f;");

        RegisterCommand("step",boost::bind(&MyNewModule::SetStep,this,_1,_2),
                        "step %f;");

        RegisterCommand("isBiRRT",boost::bind(&MyNewModule::SetBiRRT,this,_1,_2),
                        "isBiRRT %d;");

        RegisterCommand("SetWeight",boost::bind(&MyNewModule::SetWeight,this,_1,_2),
                        "SetWeight ;");

        RegisterCommand("SetUpperBound",boost::bind(&MyNewModule::SetUpperBound,this,_1,_2),
                        "SetUpperBound %f %f %f %f %f %f %f;");

        RegisterCommand("SetLowerBound",boost::bind(&MyNewModule::SetLowerBound,this,_1,_2),
                        "SetLowerBound %f %f %f %f %f %f %f;");

        RegisterCommand("RRT",boost::bind(&MyNewModule::RRT,this,_1,_2),
                        "Run RRT");

        RegisterCommand("BiRRT",boost::bind(&MyNewModule::BiRRT,this,_1,_2),
                        "Run BiRRT");

        RegisterCommand("Smooth",boost::bind(&MyNewModule::Smooth,this,_1,_2),
                        "Smooth %d;");

        RegisterCommand("getRRTpath",boost::bind(&MyNewModule::GetRRTPath,this,_1,_2),
                        "Path %d;");

    }
    virtual ~MyNewModule() {}

    EnvironmentBasePtr penv_;
//    ParameterSet plannerSetup;

    configSet goalConfig;
    float goalBias = SAMPLEBIAS;
    float stepSize = STEPSIZE;
    int smooth = 0;
    int isBiRRT = 0;
    std::vector<RRTNode*> path;

    bool MyCommand(std::ostream& sout, std::istream& sinput)
    {
/*
        vector<OpenRAVE::RobotBasePtr> robots;
        penv_->GetRobots(robots);
        std::vector<KinBody::LinkPtr> LPtr = (robots.at(0)->GetLinks());
        Transform trans = (LPtr.at(6))->GetTransform();
        OpenRAVE::Vector pos = trans.trans;
        double x = pos.x;
*/

        plannerSetup.weight.clear();
        plannerSetup.lowerBound.clear();
        plannerSetup.upperBound.clear();

        plannerSetup.weight.push_back(1.0);
        plannerSetup.weight.push_back(1.0);
        plannerSetup.weight.push_back(1.0);

        plannerSetup.weight.push_back(0.0);
        plannerSetup.weight.push_back(0.0);
        plannerSetup.weight.push_back(0.0);

        plannerSetup.lowerBound.push_back(-2.0);
        plannerSetup.lowerBound.push_back(-2.0);
        plannerSetup.lowerBound.push_back(0.0);

        plannerSetup.lowerBound.push_back(-PI);
        plannerSetup.lowerBound.push_back(-PI);   // 10000.0
        plannerSetup.lowerBound.push_back(-PI);

        plannerSetup.upperBound.push_back(2.0);
        plannerSetup.upperBound.push_back(2.0);
        plannerSetup.upperBound.push_back(2.5);

        plannerSetup.upperBound.push_back(PI);
        plannerSetup.upperBound.push_back(PI);  // 10000
        plannerSetup.upperBound.push_back(PI);

        plannerSetup.numGrippers=2;

        configuration ini1;
        configuration ini2;
        ini1.push_back(0.5);
        ini1.push_back(0.0);
        ini1.push_back(2.0);
        ini1.push_back(0.5);
        ini1.push_back(0.0);
        ini1.push_back(0.0);

        ini2.push_back(0.5);
        ini2.push_back(0.2);
        ini2.push_back(2.0);
        ini2.push_back(0.0);
        ini2.push_back(0.0);
        ini2.push_back(0.0);

        configSet setConfig;
        setConfig.push_back(ini1);
        setConfig.push_back(ini2);
        plannerSetup.InitGeodesic(setConfig);

//        configSet A = SampleSet(plannerSetup.numGrippers);

//        configSet B;
//        B.push_back(ini1);
//        B.push_back(ini2);
//        SetOutBound(A);
//        std::vector<std::vector<double> > Avec = SetConfigToVec(A);
//        SetVecToConfig(Avec);
//        SetWeightedDis(A,B);
//        OpenRAVE::Vector raveA = ConfigToRaveVec(A.at(0));

        cout << "Comment sent to robot before entering function-------" << endl;

        /*
        for (int i =0; i<robots.size();i++)
        {
            robots.at(i)->SetActiveDOFValues(ConfigToVec(ScaleConfig(A.at(i),(1+i)*2)));
            ConfigPrintHelp(ScaleConfig(A.at(i),(1+i)*2));
        }
        */
//        ConstraintViolation(SetSumConfig(A,B), robots, penv_);
//        SetCollisionCheck(robots,penv_);

//        path = RRTPlanning(penv_,B,0.11,0.4);
        path = RRTPlanning(penv_,goalConfig,goalBias,stepSize);

        return true;
    }

    bool SetGoal(std::ostream& sout, std::istream& sinput)
    {
        /*
        std::string input;
        sinput >> input;
        int g_ind;
        g_ind = std::atoi(input.c_str());
        */

        configuration goal;
        for (int i=0; i<DOFCONFIG; i++)
        {
            std::string input;
            sinput >> input;
            goal.push_back(std::strtof(input.c_str(),0));
        }
        goalConfig.push_back(goal);
        sout << "Get Goal Configuration!";
        return true;
    }

    bool SetBias(std::ostream& sout, std::istream& sinput)
    {
        std::string input;
        sinput >> input;
        goalBias = std::strtof(input.c_str(),0);
        sout << "Get Bias !";

        return true;
    }

    bool SetStep(std::ostream& sout, std::istream& sinput)
    {
        std::string input;
        sinput >> input;
        stepSize = std::strtof(input.c_str(),0);
        sout << "Get Step !";

        return true;
    }

    bool SetBiRRT(std::ostream& sout, std::istream& sinput)
    {
        std::string input;
        sinput >> input;
        isBiRRT = std::atoi(input.c_str());;
        sout << "Get BiRRT Flag !";

        return true;
    }

    bool SetWeight(std::ostream& sout, std::istream& sinput)
    {
        plannerSetup.weight.clear();

        plannerSetup.weight.push_back(1.0);
        plannerSetup.weight.push_back(1.0);
        plannerSetup.weight.push_back(1.0);

        plannerSetup.weight.push_back(0.0);
        plannerSetup.weight.push_back(0.0);
        plannerSetup.weight.push_back(0.0);

        return true;
    }

    bool SetUpperBound(std::ostream& sout, std::istream& sinput)
    {
        plannerSetup.upperBound.clear();
        for (int i=0; i<DOFCONFIG; i++)
        {
            std::string input;
            sinput >> input;
            plannerSetup.upperBound.push_back(std::strtof(input.c_str(),0));
        }
        sout << "Get UpperBound!";
        return true;

        /*
        plannerSetup.lowerBound.clear();
        plannerSetup.upperBound.clear();

        plannerSetup.lowerBound.push_back(-7.0);
        plannerSetup.lowerBound.push_back(-7.0);
        plannerSetup.lowerBound.push_back(0.0);

        plannerSetup.lowerBound.push_back(-PI);
        plannerSetup.lowerBound.push_back(-PI);   // 10000.0
        plannerSetup.lowerBound.push_back(-PI);

        plannerSetup.upperBound.push_back(7.0);
        plannerSetup.upperBound.push_back(7.0);
        plannerSetup.upperBound.push_back(7);

        plannerSetup.upperBound.push_back(PI);
        plannerSetup.upperBound.push_back(PI);  // 10000
        plannerSetup.upperBound.push_back(PI);

        return true;
        */
    }

    bool SetLowerBound(std::ostream& sout, std::istream& sinput)
    {
        plannerSetup.lowerBound.clear();
        for (int i=0; i<DOFCONFIG; i++)
        {
            std::string input;
            sinput >> input;
            plannerSetup.lowerBound.push_back(std::strtof(input.c_str(),0));
        }
        sout << "Get LowerBound!";
        return true;
    }

    bool RRT(std::ostream& sout, std::istream& sinput)
    {
//        RRTPlanning(penv_, goalConfig, goalBias, stepSize);
        SetConfigPrintHelp(goalConfig);

        plannerSetup.numGrippers = goalConfig.size();

        /*
        configuration ini1;
        configuration ini2;
        ini1.push_back(0.5);
        ini1.push_back(0.0);
        ini1.push_back(2.0);
        ini1.push_back(0.5);
        ini1.push_back(0.0);
        ini1.push_back(0.0);

        ini2.push_back(0.5);
        ini2.push_back(0.2);
        ini2.push_back(2.0);
        ini2.push_back(0.0);
        ini2.push_back(0.0);
        ini2.push_back(0.0);

        configSet setConfig;
        setConfig.push_back(ini1);
        setConfig.push_back(ini2);
        */

        vector<OpenRAVE::RobotBasePtr> robots;
        penv_->GetRobots(robots);
        std::vector<std::vector<double> > startSet;

        for (int i =0; i<plannerSetup.numGrippers; i++)
        {
            std::vector<double> startVec;
            robots.at(i)->GetActiveDOFValues(startVec);
            startSet.push_back(startVec);
        }

        plannerSetup.InitGeodesic(SetVecToConfig(startSet));

        path = RRTPlanning(penv_, goalConfig, goalBias, stepSize);

        // print geodesic
        cout << "************ Geodesic Alongside ******" <<endl;
        for (int i=0; i<path.size();i++)
        {
            configSet config = path.at(i)->GetConfig();
            cout<<WeightedDis(config.at(0),config.at(1))<<endl;
        }

        cout << "The line after Path = " << endl;
        sout << "RRT Planning";
        return true;
    }

    bool BiRRT(std::ostream& sout, std::istream& sinput)
    {
        SetConfigPrintHelp(goalConfig);

        plannerSetup.numGrippers = goalConfig.size();

        vector<OpenRAVE::RobotBasePtr> robots;
        penv_->GetRobots(robots);
        std::vector<std::vector<double> > startSet;

        for (int i =0; i<plannerSetup.numGrippers; i++)
        {
            std::vector<double> startVec;
            robots.at(i)->GetActiveDOFValues(startVec);
            startSet.push_back(startVec);
        }

        plannerSetup.InitGeodesic(SetVecToConfig(startSet));

        path = RRTPlanning(penv_, goalConfig, goalBias, stepSize);

        // print geodesic
        cout << "************ Geodesic Alongside ******" <<endl;
        for (int i=0; i<path.size();i++)
        {
            configSet config = path.at(i)->GetConfig();
            cout<<WeightedDis(config.at(0),config.at(1))<<endl;
        }

        sout << "BiRRT Planning";
        return true;
    }

    bool Smooth(std::ostream& sout, std::istream& sinput)
    {
        std::string input;
        sinput >> input;
        smooth = std::atoi(input.c_str());;
        sout << "Get BiRRT Flag !";

        path = SmoothPath(penv_, path,stepSize,smooth);

        sout << "Path Smooth!" ;

        return true;
    }

    bool GetRRTPath(std::ostream& sout, std::istream& sinput)
    {
        std::string input;
        sinput >> input;
        int g_ind;
        g_ind = std::atoi(input.c_str());

        configSet nodeConfig;
        configuration config;
        float value;
        for (int i=0; i<path.size(); i++)
        {
            nodeConfig = (path.at(i))->GetConfig();
            config = nodeConfig.at(g_ind);
            for(int j=0; j<DOFCONFIG ; j++)
            {
                value = config.at(j);
                sout<< value;
                if (j==(config.size()-1)) { sout<<endl; }
                else { sout<<","; }
            }
        }
        return true;
    }

};

// called to create a new plugin
InterfaceBasePtr CreateInterfaceValidated(InterfaceType type, const std::string& interfacename, std::istream& sinput, EnvironmentBasePtr penv)
{
    if( type == PT_Module && interfacename == "mynewmodule" ) {
        return InterfaceBasePtr(new MyNewModule(penv,sinput));
    }

    return InterfaceBasePtr();
}

// called to query available plugins
void GetPluginAttributesValidated(PLUGININFO& info)
{
info.interfacenames[PT_Module].push_back("MyNewModule");

}

// called before plugin is terminated
OPENRAVE_PLUGIN_API void DestroyPlugin()
{
}

ext: cpp


text:
/***
* Copyright 2017 Marc Stevens <marc@marc-stevens.nl>, Dan Shumow <danshu@microsoft.com>
* Distributed under the MIT Software License.
* See accompanying file LICENSE.txt or copy at
* https://opensource.org/licenses/MIT
***/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <iostream>

#include <boost/cstdint.hpp>

using namespace std;
using boost::uint32_t;

#include "ubc_check_test.h"
#include "test_simd.h"

extern "C" {
#include "../../lib/ubc_check_verify.c"
}

char*	usage_str = "%s usage:\n"
					"\t--all      - Run all tests.\n"
#ifdef INCLUDE_BASIC_TEST
					"\t--basic    - Run unavoidable bit condition check tests (default true.)\n"
#endif
#ifdef INCLUDE_MMX64_TEST
					"\t--mmx64    - Run unavoidable bit condition check tests with sse128 improvements.\n"
#endif
#ifdef INCLUDE_SSE128_TEST
					"\t--sse128   - Run unavoidable bit condition check tests with sse128 improvements.\n"
#endif
#ifdef INCLUDE_AVX256_TEST
					"\t--avx256   - Run UBC tests with avx256 improvements.\n"
#endif
#ifdef INCLUDE_NEON128_TEST
					"\t--neon128  - Run unavoidable bit condition check tests with neon128 improvements.\n"
#endif
					"-p,--nocheck - Supress correctness checks.\n"
					"-c,--noperf  - Supress performance tests.\n"
					"\t-h,--help  - Print this help message\n"
					"\n";

bool run_all_test = false;
#define TEST_ALL_ARG_STR	"--all"

typedef int(*TestUBCFunction)();

typedef struct {
	TestUBCFunction fn_test_ubc_check;
	bool run_test;
	char* arg_str;
} TestConfigEntry;

TestConfigEntry testConfig[] =
{
#ifdef INCLUDE_BASIC_TEST
	{
		test_ubc_check,
		true,
		"--basic"
	},
#endif
#ifdef INCLUDE_MMX64_TEST
	{
		test_ubc_check_mmx64,
		false,
		"--mmx64"
	},
#endif
#ifdef INCLUDE_SSE128_TEST
	{
		test_ubc_check_sse128,
		false,
		"--sse128"
	},
#endif
#ifdef INCLUDE_AVX256_TEST
	{
		test_ubc_check_avx256,
		false,
		"--avx256"
	},
#endif
#ifdef INCLUDE_NEON128_TEST
	{
		test_ubc_check_neon128,
		false,
		"--neon128"
	}
#endif
};

const size_t cntTestConfig = sizeof(testConfig) / sizeof(TestConfigEntry);

bool run_correctness_checks = true;
bool run_perf_tests = true;

void usage(char* program_name)
{
	printf(usage_str, program_name);
}

int main(int argc, char** argv)
{
	for (size_t i = 1; i < argc; i++)
	{
		bool fTestArgStrFound = false;
		// loop through and set the config to run based on
		for (size_t j = 0; (j < cntTestConfig) && !fTestArgStrFound; j++)
		{
			if (0 == strcmp(argv[i], testConfig[j].arg_str))
			{
				testConfig[j].run_test = true;
				fTestArgStrFound = true;
			}
		}

		if (0 == strcmp(argv[i], TEST_ALL_ARG_STR))
		{
			run_all_test = true;
		}
		else if ((0 == strcmp(argv[i], "-p")) ||
			     (0 == strcmp(argv[i], "--nocheck")))
		{
			run_correctness_checks = false;
		}
		else if ((0 == strcmp(argv[i], "-c")) ||
			     (0 == strcmp(argv[i], "--noperf")))
		{
			run_perf_tests = false;
		}
		else if ((0 == strcmp(argv[i], "-h")) ||
				 (0 == strcmp(argv[i], "--help")))
		{
			usage(argv[0]);
			exit(0);
		}
		else if (fTestArgStrFound)
		{
		}
		else
		{
			printf("Unknown argument: %s\n", argv[i]);
			usage(argv[0]);
			exit(-1);
		}
	}

	for (size_t j = 0; j < cntTestConfig; j++)
	{
		if (run_all_test || testConfig[j].run_test)
		{
			cout << "=====================================================================" << endl;
			testConfig[j].fn_test_ubc_check();
			cout << "=====================================================================" << endl << endl << endl;
		}
	}
}


text:
// (C) Copyright 2015 by Autodesk, Inc.

//=============================================================================
//
//  namespace COMISO::DOcloud IMPLEMENTATION
//
//=============================================================================

#include "DOCloudJob.hh"
#if COMISO_DOCLOUD_AVAILABLE
#include "DOCloudConfig.hh"
#include "CoMISo/Utils/CoMISoError.hh"

#include <Base/Code/Quality.hh>
#include <Base/Debug/DebUtils.hh>

// Suppress warning: "decorated name length exceeded, name was truncated".
// This can not happen inside a LOW_CODE_QUALITY_SECTION because the warning is
// issued at the end of the unit module compilation.
// The problem is caused by boost property tree.
#pragma warning (disable: 4503)

LOW_CODE_QUALITY_SECTION_BEGIN
  // Suppress warning:not all control paths return a value in
  // property_tree::..standard_callbacks<..>::new_tree
#pragma warning (disable: 4715)
#include <boost/property_tree/json_parser.hpp>
LOW_CODE_QUALITY_SECTION_END

#include <iostream>
#include <thread>

DEB_module("DOcloud")

namespace COMISO {
namespace DOcloud {

//////////////////////////////////////////////////////////////////////////
// Config
static const char* json_app_type__ = "Content-Type: application/json";
static const char* gen_app_type__ = "Content-Type: application/octet-stream";

Config::Config()
  : root_url_("https://api-oaas.docloud.ibmcloud.com/job_manager/rest/v1/jobs"),
    infs_time_(300), fsbl_time_(15)
{
  const char* env_cache_dir = getenv("ReFormCacheDir");
  if (env_cache_dir != nullptr && env_cache_dir[0] != 0)
  {
    cache_loc_ = env_cache_dir;
    if (cache_loc_.back() != '\\')
      cache_loc_ += '\\'; // Eventually add '\' to the directory string.
  }
}

Config& Config::object()
{
  // TODO: implement MT-lock
  static Config config;
  return config;
}

void Config::set_root_url(const char* const _root_url)
{
  COMISO_THROW_if(_root_url == nullptr, DOCLOUD_CONFIG_SET_VALUE_INVALID);
  root_url_ = _root_url;
}

void Config::set_api_key(const char* _api_key)
{
  COMISO_THROW_if(_api_key == nullptr, DOCLOUD_CONFIG_SET_VALUE_INVALID);
  api_key_ = std::string("X-IBM-Client-Id: ") + _api_key;
}

void Config::set_infeasible_timeout(const int _infs_time)
{
  COMISO_THROW_if(_infs_time < 1, DOCLOUD_CONFIG_SET_VALUE_INVALID);
  infs_time_ = _infs_time;
}

void Config::set_feasible_timeout(const int _fsbl_time)
{
  COMISO_THROW_if(_fsbl_time < 0, DOCLOUD_CONFIG_SET_VALUE_INVALID);
  fsbl_time_ = _fsbl_time;
}

void Config::set_cache_location(const char* const _cache_loc)
{
  if (_cache_loc == nullptr)
    cache_loc_.clear();
  else
    cache_loc_ = _cache_loc;
}

//////////////////////////////////////////////////////////////////////////
// Config
const Config& Config::query() { return object(); }
Config& Config::modify() { return object(); }

class HeaderTokens
{
public:
  HeaderTokens(const std::string& _hdr)
  {
    // TODO: Performance can be improved by indexing, strtok_r(), etc ...
    //  ... but probably not worth the effort
    std::istringstream strm(_hdr);
    typedef std::istream_iterator<std::string> Iter;
    std::copy(Iter(strm), Iter(), std::back_inserter(tkns_));
  }

  const std::string& operator[](const size_t _idx) const
  {
    return tkns_[_idx];
  }

  size_t number() const { return tkns_.size(); }

  // Find a token equal to the label and return its value (next token)
  bool find_value(const std::string& _lbl, std::string& _val) const
  {
    auto it = std::find(tkns_.begin(), tkns_.end(), _lbl);
    if (it == tkns_.end() || ++it == tkns_.end())
      return false;

    _val = *it;
    return true;
  }

  typedef std::vector<std::string>::const_iterator const_iterator;

  const_iterator begin() const { return tkns_.begin(); }
  const_iterator end() const { return tkns_.end(); }

private:
  std::vector<std::string> tkns_;
};

class JsonTokens
{
public:
  JsonTokens() {}
  JsonTokens(const std::string& _bdy) { set(_bdy); }

  void set(const std::string& _bdy)
  {
    ptree_.clear();
    if (_bdy.empty())
      return;
    std::istringstream strm(_bdy);
    boost::property_tree::json_parser::read_json(strm, ptree_);
  }

  //size_t number() const { return tkns_.size(); }

  // Find a token equal to the label and return its value
  bool find_value(const std::string& _lbl, std::string& _val) const
  {
    auto it = ptree_.find(_lbl);
    if (it == ptree_.not_found())
      return false;

    _val = it->second.get_value<std::string>();
    return true;
  }

  typedef boost::property_tree::ptree PTree;

  const PTree& ptree() const { return ptree_; }

private:
  PTree ptree_;
};

Base::IOutputStream& operator<<(Base::IOutputStream& _ds, const JsonTokens::PTree& _ptree)
{
  std::stringstream os;
  boost::property_tree::json_parser::write_json(os, _ptree);
  _ds << os.str();
  return _ds;
}

Base::IOutputStream& operator<<(Base::IOutputStream& _ds, const JsonTokens& _json_tkns)
{
  return _ds << _json_tkns.ptree();
}

void throw_http_error(const int _err_code, const std::string& _bdy)
{
  DEB_enter_func;

  std::string err_msg;
  JsonTokens bdy_tkns(_bdy);
  bdy_tkns.find_value("message", err_msg);
  DEB_warning(1, "HTTP Status Code: " << _err_code << "; Message: " << err_msg);

  switch (_err_code)
  {
  case 400 : COMISO_THROW(DOCLOUD_JOB_DATA_INVALID);
  case 403 : COMISO_THROW(DOCLOUD_SUBSCRIPTION_LIMIT);
  case 404 : COMISO_THROW(DOCLOUD_JOB_NOT_FOUND);
  default : COMISO_THROW(DOCLOUD_JOB_UNRECOGNIZED_FAILURE);
  }
}

class HttpStatus
{
public:
  HttpStatus(const cURLpp::Request& _rqst)
    : rqst_(_rqst), hdr_tkns_(_rqst.header()), code_(0)
  {
    const std::string http_lbl = "HTTP/1.1";
    const int code_cntn = 100; // continue code, ignore

    for (auto it = hdr_tkns_.begin(), it_end = hdr_tkns_.end(); it != it_end; ++it)
    {
      if (*it != http_lbl) // search for the http label token
        continue;
      COMISO_THROW_if(++it == it_end, DOCLOUD_JOB_HTTP_CODE_NOT_FOUND);
      code_ = atoi(it->data());
      if (code_ != code_cntn)
        return;
    }
    COMISO_THROW(DOCLOUD_JOB_HTTP_CODE_NOT_FOUND); // final http code not found
  }

  void check(int _code_ok) const
  {
    if (code_ != _code_ok)  // another code found, throw an error
      throw_http_error(code_, rqst_.body());
  }

  const int& code() const { return code_; }

  const HeaderTokens& header_tokens() const { return hdr_tkns_; }

private:
  const cURLpp::Request& rqst_;
  HeaderTokens hdr_tkns_;
  int code_;
};

Job::~Job()
{
  delete stts_;

  if (url_.empty()) // not setup
    return;
  cURLpp::Delete del;
  del.set_url(url_.data());
  del.add_http_header(Config::query().api_key());
  del.perform();
  // no point in checking the return value, we can't do much if the
  // delete request has failed
}

void Job::make()
{
  DEB_enter_func;
  const auto post_loc = "{\"attachments\" : [{\"name\" :\"" +
    std::string(filename_) + "\"}]}";
  cURLpp::Post post(post_loc);
  post.set_url(Config::query().root_url());
  post.add_http_header(Config::query().api_key());
  post.add_http_header(json_app_type__);
  post.perform();

  HttpStatus http_stat(post);
  http_stat.check(201);
  // TODO: DOcloud header is successful but no location value
  COMISO_THROW_if(!http_stat.header_tokens().find_value("Location:", url_),
    DOCLOUD_JOB_LOCATION_NOT_FOUND);

  if (stts_ == nullptr)
    stts_ = new JsonTokens;
}

void Job::upload(cURLpp::Upload& _upld)
{
  auto url = url_ + "/attachments/" + filename_ + "/blob";
  _upld.set_url(url.data());
  _upld.add_http_header(Config::query().api_key());
  _upld.add_http_header(gen_app_type__);
  _upld.perform();
  HttpStatus http_stat(_upld);
  http_stat.check(204);
}

void Job::upload()
{
  if (file_buf_.empty())
  {// file is not buffered into memory
    cURLpp::UploadFile upld(filename_);
    upload(upld);
  }
  else
  {
    cURLpp::UploadData upld(file_buf_);
    upload(upld);
  }
}

void Job::start()
{
  cURLpp::Post post("");
  const auto url = url_ + "/execute";
  post.set_url(url.data());
  post.add_http_header(Config::query().api_key());
  post.add_http_header(json_app_type__);
  post.perform();
  HttpStatus http_stat(post);
  http_stat.check(204);

  log_seq_idx_ = sol_nmbr_ = sol_sec_nmbr_ = stld_sec_nmbr_ = 0;
  stop_wtch_.start();
}

void Job::sync_status()
{
  DEB_enter_func;

  cURLpp::Get get;
  get.set_url(url_.data());
  get.add_http_header(Config::query().api_key());
  get.perform();
  HttpStatus http_stat(get);
  http_stat.check(200);

  stts_->set(get.body());
/*
  // The code below attempted to analyse the status data to find out the
  // progress of the solver. This is an undocumented use and does not seem to
  // work so far. Achieved here for potential use in the future.

  DEB_line(2, stts_);

  const auto& details = stts_->ptree().get_child_optional("details");
  if (!details)
    return;

  DEB_line(2, details.get());

  const auto& prg_gap =
    details.get().get_child("PROGRESS_GAP").get_value<std::string>();
  std::string mip_gap;
  const auto mip_gap_it = details.get().find("cplex.mipabsgap");
  if (mip_gap_it != details.get().not_found())
    mip_gap = mip_gap_it->second.get_value<std::string>();

  DEB_line(2, "Status, MIP gap: " << mip_gap << "; Progress gap: " << prg_gap);
*/
}

void Job::sync_log()
{
  DEB_enter_func;

  cURLpp::Get get;
  const auto url = url_ + "/log/items?start=" + std::to_string(log_seq_idx_) +
    "&continuous=true";
  get.set_url(url.data());
  get.add_http_header(Config::query().api_key());
  get.perform();
  HttpStatus http_stat(get);
  http_stat.check(200);

  JsonTokens log(get.body());

  bool got_time_data = false;
  // iterate the log items, deb_out messages and analyze for solutions #
  for (const auto& log_item : log.ptree())
  {
    DEB_line_if(log_seq_idx_ == 0, 2, "**** DOcloud log ****");
    const auto& records = log_item.second.get_child("records");
    for (const auto& record : records)
    {// the message ends with \n
      const std::string msg = record.second.get_child("message").
        get_value<std::string>();
      DEB_out(2, record.second.get_child("level").get_value<std::string>() <<
        ": " << msg);

      const int time_str_len = 15;
      const char time_str[time_str_len + 1] = "Elapsed time = ";
      const auto time_str_idx = msg.find(time_str);
      if (time_str_idx == std::string::npos)
        continue;

      const int sec_nmbr = atoi(msg.data() + time_str_idx + time_str_len);
      //DEB_line(1, "# seconds elapsed : " << sec_nmbr);

      const int sol_str_len = 12;
      const char sol_str[sol_str_len + 1] = "solutions = ";
      const auto sol_str_idx = msg.find(sol_str);
      if (sol_str_idx == std::string::npos)
        continue;

      got_time_data = true;
      const int sol_nmbr = atoi(msg.data() + sol_str_idx + sol_str_len);
      //DEB_line(1, "# solutions found so far: " << sol_nmbr);
      if (sol_nmbr > sol_nmbr_) // new solution(s) found
      {// update the number of solutions and the time of the last solution found
        sol_nmbr_ = sol_nmbr;
        sol_sec_nmbr_ = sec_nmbr;
      }
      stld_sec_nmbr_ = sec_nmbr - sol_sec_nmbr_;
      stop_wtch_.restart();
    }
    log_seq_idx_ = log_item.second.get_child("seqid").get_value<int>() + 1;
  }
  if (!got_time_data)
  {
    DEB_warning(2, "DOCloud did not provide time and solutions number-"
                   "using internal time counter.");
    stld_sec_nmbr_ += stop_wtch_.restart() / 1000;
  }
}

bool Job::active() const
{
  std::string exct_stts;
  stts_->find_value("executionStatus", exct_stts);

  // assume the job is not active if the status is not recognized
  return exct_stts == "CREATED" || exct_stts == "NOT_STARTED" ||
    exct_stts == "RUNNING" || exct_stts == "INTERRUPTING";

  /*
  Backup of old code converting execution status strings to enum value
  enum StatusType { ST_CREATED, ST_NOT_STARTED, ST_RUNNING, ST_INTERRUPTING,
    ST_INTERRUPTED, ST_FAILED, ST_PROCESSED, ST_UNKNOWN };

  const int n_stts = (int)ST_UNKNOWN;
  const char stts_tbl[n_stts][16] = { "CREATED", "NOT_STARTED", "RUNNING",
    "INTERRUPTING", "INTERRUPTED", "FAILED", "PROCESSED" };

  for (int i = 0; i < n_stts; ++i)
  {
    if (stts == stts_tbl[i])
      return (StatusType)i;
  }
  return ST_UNKNOWN;
  while (stts == ST_CREATED || stts == ST_NOT_STARTED || stts == ST_RUNNING ||
      stts == ST_INTERRUPTING);
  */
}

bool Job::stalled() const
{
  // exit quick if we have a solution, or wait if we don't have one
  const auto& config = Config::query();
  return (sol_nmbr_ > 0 && stld_sec_nmbr_ >= config.feasible_timeout())
    || (sol_nmbr_ == 0 && stld_sec_nmbr_ >= config.infeasible_timeout());
}

void Job::abort()
{
  std::string exct_stts;
  stts_->find_value("executionStatus", exct_stts);
  if (exct_stts != "RUNNING" && exct_stts != "NOT_STARTED")
    return; // already aborted or aborting

  cURLpp::Delete del;
  const auto url = url_ + "/execute";
  del.set_url(url.data());
  del.add_http_header(Config::query().api_key());
  del.perform();

  HttpStatus http_stat(del);
  http_stat.check(204);
}

void Job::wait()
{
  do
  {
    std::this_thread::sleep_for(std::chrono::seconds(1));
    sync_status();
    sync_log();
    if (stalled())
      abort(); // The waiting loop must continue until the timer request has been
               // processed by the server.
  } while (active());
}

double Job::solution(std::vector<double>& _x) const
{
  DEB_enter_func;

  // check the solution status (assume it's synchronized already)

  // What are the possible values for this??
  std::string slv_stts;
  stts_->find_value("solveStatus", slv_stts);
  DEB_line(2, "solveStatus=" << slv_stts);

  cURLpp::Get get;
  const auto url = url_ + "/attachments/solution.json/blob";
  get.set_url(url.data());
  get.add_http_header(Config::query().api_key());
  get.perform();

  HttpStatus http_stat(get);
  if (http_stat.code() == 404 &&
      get.body().find("CIVOC5102E") != std::string::npos)
  {
    // The mixed integer optimization has not found any solution.
    _x.clear();
    return 0;
  }
  http_stat.check(200);

  JsonTokens bdy_tkns(get.body());
  DEB_line(7, bdy_tkns);

  const auto& vrbls = bdy_tkns.ptree().get_child("CPLEXSolution.variables");
  const auto n_vrbls = vrbls.size();
  COMISO_THROW_if(n_vrbls != _x.size(), DOCLOUD_CPLEX_SOLUTION_MISMATCH);

  size_t i = 0;
  for (const auto& v : vrbls)
  {
    // TODO: this way of conversion is rather hacky
    const std::string name =
      v.second.get_child("name").get_value<std::string>(); // this is x#IDX
    const int idx = atoi(name.data() + 1);
    COMISO_THROW_if(idx < 0 || idx > n_vrbls, DOCLOUD_CPLEX_SOLUTION_MISMATCH);
    _x[idx] = v.second.get_child("value").get_value<double>();

    DEB_out(7, "#" << idx << "=" <<
      v.second.get_child("value").get_value<std::string>() << "; ");
  }
  const auto obj_val =
    bdy_tkns.ptree().get_child("CPLEXSolution.header.objectiveValue").get_value<double>();

  DEB_line(3, "X=" << _x);
  return obj_val;
}

} // namespace DOcloud
} // namespace COMISO

#endif // COMISO_DOCLOUD_AVAILABLE

ext: cc