<commit_before>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 *
 * 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 "stdafx.h"
#include <vector>
#include <iostream>
#include <sstream>

#include <zorba/singleton_item_sequence.h>
#include <zorba/empty_sequence.h>
#include <api/unmarshaller.h>
#include "http_util.h"
#include "error_util.h"

namespace zorba {

  HttpStream::HttpStream(const zstring& aUri)
  : theDidInit(false), theUri(aUri)
  {
  }

  HttpStream::~HttpStream()
  {
    if (theIterator)
    {
      theIterator->close();
    }
  }

  void HttpStream::init()
  {
    Zorba* lInstance = Zorba::getInstance(0);
    theStaticContext = lInstance->createStaticContext();
    ItemFactory* lFactory = lInstance->getItemFactory();
    Item lNodeName = lFactory->createQName("http://expath.org/ns/http-client", "http", "request");
    Item lEmptyItem;
    std::vector<std::pair<String, String> > nsPairs;
    nsPairs.push_back(std::make_pair(String("xs"), String("http://www.w3.org/2001/XMLSchema")));
    Item lRequestElement = lFactory->createElementNode(lEmptyItem, lNodeName,
                                                       lFactory->createQName("http://www.w3.org/2001/XMLSchema",
                                                                             "xs", "untyped"),
                                                       true, false, nsPairs);
    lFactory->createAttributeNode(lRequestElement, lFactory->createQName("", "method"), Item(), lFactory->createString("GET"));
    lFactory->createAttributeNode(lRequestElement, lFactory->createQName("", "href"), Item(), lFactory->createString(theUri.c_str()));
    lFactory->createAttributeNode(lRequestElement, lFactory->createQName("", "override-media-type"), Item(), lFactory->createString("text/plain"));
    lFactory->createAttributeNode(lRequestElement, lFactory->createQName("", "follow-redirect"), Item(), lFactory->createString("false"));
    Zorba_CompilerHints_t lHints;
    lHints.opt_level = ZORBA_OPT_LEVEL_O1;
    theStaticContext->loadProlog("import module namespace httpc = \"http://www.zorba-xquery.com/modules/http-client\";",
                                 lHints);
    Item lQName = lFactory->createQName("http://www.zorba-xquery.com/modules/http-client",
                                        "httpc", "send-request");
    std::vector<ItemSequence_t> lArgs;
    lArgs.push_back(new SingletonItemSequence(lRequestElement));
    lArgs.push_back(new EmptySequence());
    lArgs.push_back(new EmptySequence());
    theItemSequence = theStaticContext->invoke(lQName, lArgs);
    theIterator = theItemSequence->getIterator();
    theIterator->open();
    Item lItem;
    theIterator->next(lItem);
    Iterator_t lIter = lItem.getAttributes();
    lIter->open();
    Item lAttr;
    bool succeed = true;
    while (lIter->next(lAttr)) {
      Item lName;
      lAttr.getNodeName(lName);
      String lNameString = lName.getStringValue();
      if (lNameString == "status") {
        std::stringstream lStream(lAttr.getStringValue().c_str());
        int status;
        lStream >> status;
        succeed = status < 400;
        break;
      }
    }
    lIter->close();
    if (!succeed)
      throw os_error::exception("", theUri.c_str(), "Could not create stream resource");
    theIterator->next(theStreamableString);
  }

  std::istream& HttpStream::getStream()
  {
    return theStreamableString.getStream();
  }

  StreamReleaser HttpStream::getStreamReleaser()
  {
    store::Item* lItem = Unmarshaller::getInternalItem(theStreamableString);
    return lItem->getStreamReleaser();
  }

  void HttpStream::setStreamReleaser(StreamReleaser aReleaser)
  {
    store::Item* lItem = Unmarshaller::getInternalItem(theStreamableString);
    lItem->setStreamReleaser(aReleaser);
  }
}
<commit_msg>Following redirects when resolving URLs. Mostly used when importing modules or schemas.<commit_after>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 *
 * 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 "stdafx.h"
#include <vector>
#include <iostream>
#include <sstream>

#include <zorba/singleton_item_sequence.h>
#include <zorba/empty_sequence.h>
#include <api/unmarshaller.h>
#include "http_util.h"
#include "error_util.h"

namespace zorba {

  HttpStream::HttpStream(const zstring& aUri)
  : theDidInit(false), theUri(aUri)
  {
  }

  HttpStream::~HttpStream()
  {
    if (theIterator)
    {
      theIterator->close();
    }
  }

  void HttpStream::init()
  {
    Zorba* lInstance = Zorba::getInstance(0);
    theStaticContext = lInstance->createStaticContext();
    ItemFactory* lFactory = lInstance->getItemFactory();
    Item lNodeName = lFactory->createQName("http://expath.org/ns/http-client", "http", "request");
    Item lEmptyItem;
    std::vector<std::pair<String, String> > nsPairs;
    nsPairs.push_back(std::make_pair(String("xs"), String("http://www.w3.org/2001/XMLSchema")));
    Item lRequestElement = lFactory->createElementNode(lEmptyItem, lNodeName,
                                                       lFactory->createQName("http://www.w3.org/2001/XMLSchema",
                                                                             "xs", "untyped"),
                                                       true, false, nsPairs);
    lFactory->createAttributeNode(lRequestElement, lFactory->createQName("", "method"), Item(), lFactory->createString("GET"));
    lFactory->createAttributeNode(lRequestElement, lFactory->createQName("", "href"), Item(), lFactory->createString(theUri.c_str()));
    lFactory->createAttributeNode(lRequestElement, lFactory->createQName("", "override-media-type"), Item(), lFactory->createString("text/plain"));
    lFactory->createAttributeNode(lRequestElement, lFactory->createQName("", "follow-redirect"), Item(), lFactory->createString("true"));
    Zorba_CompilerHints_t lHints;
    lHints.opt_level = ZORBA_OPT_LEVEL_O1;
    theStaticContext->loadProlog("import module namespace httpc = \"http://www.zorba-xquery.com/modules/http-client\";",
                                 lHints);
    Item lQName = lFactory->createQName("http://www.zorba-xquery.com/modules/http-client",
                                        "httpc", "send-request");
    std::vector<ItemSequence_t> lArgs;
    lArgs.push_back(new SingletonItemSequence(lRequestElement));
    lArgs.push_back(new EmptySequence());
    lArgs.push_back(new EmptySequence());
    theItemSequence = theStaticContext->invoke(lQName, lArgs);
    theIterator = theItemSequence->getIterator();
    theIterator->open();
    Item lItem;
    theIterator->next(lItem);
    Iterator_t lIter = lItem.getAttributes();
    lIter->open();
    Item lAttr;
    bool succeed = true;
    while (lIter->next(lAttr)) {
      Item lName;
      lAttr.getNodeName(lName);
      String lNameString = lName.getStringValue();
      if (lNameString == "status") {
        std::stringstream lStream(lAttr.getStringValue().c_str());
        int status;
        lStream >> status;
        succeed = status < 400;
        break;
      }
    }
    lIter->close();
    if (!succeed)
      throw os_error::exception("", theUri.c_str(), "Could not create stream resource");
    theIterator->next(theStreamableString);
  }

  std::istream& HttpStream::getStream()
  {
    return theStreamableString.getStream();
  }

  StreamReleaser HttpStream::getStreamReleaser()
  {
    store::Item* lItem = Unmarshaller::getInternalItem(theStreamableString);
    return lItem->getStreamReleaser();
  }

  void HttpStream::setStreamReleaser(StreamReleaser aReleaser)
  {
    store::Item* lItem = Unmarshaller::getInternalItem(theStreamableString);
    lItem->setStreamReleaser(aReleaser);
  }
}
<|endoftext|>


<commit_before>
#include "CReportDefinition.h"
#include "CReportBody.h"
#include "CReport.h"
#include "CCopasiContainer.h"

//////////////////////////////////////////////////
//
//class CReport
//
//////////////////////////////////////////////////
CReport::CReport():
    CCopasiObject("Report", NULL, "Report", CCopasiObject::Container),
    ostream(NULL),
    mpReportDef(NULL),
    mTarget(""),
    mAppend(true)
    //,mKey(CKeyFactory::add("Report", this))
{}

CReport::~CReport()
{cleanup();}

void CReport::cleanup()
{
  // Please Dont clear the objectList, as all pointers are also referred swh else
  unsigned C_INT32 i;
  for (i = 0; i < headerObjectList.size(); i++)
    headerObjectList[i] = NULL;

  for (i = 0; i < bodyObjectList.size(); i++)
    bodyObjectList[i] = NULL;

  for (i = 0; i < footerObjectList.size(); i++)
    footerObjectList[i] = NULL;

  headerObjectList.clear();
  bodyObjectList.clear();
  footerObjectList.clear();
  //  CKeyFactory::remove(mKey);
  // mpReportDef pointer shall be dealt outside, where it is created
  //  pdelete(mpReportDef);
}

CReportDefinition* CReport::getReportDefinition()
{return mpReportDef;}

void CReport::setReportDefinition(CReportDefinition* reportDef)
{mpReportDef = reportDef;}

const std::string& CReport::getTarget()
{return mTarget;}

void CReport::setTarget(std::string target)
{mTarget = target;}

bool CReport::append()
{return mAppend;}

void CReport::setAppend(bool append)
{mAppend = append;}

void CReport::printHeader()
{
  // for loop print out mpReportDef->getHeader()
  unsigned C_INT32 i;
  for (i = 0; i < headerObjectList.size(); i++)
    headerObjectList[i]->print(*ostream);
}

void CReport::printBody()
{
  // for loop print out mpReportDef->getBody()
  unsigned C_INT32 i;
  for (i = 0; i < bodyObjectList.size(); i++)
    bodyObjectList[i]->print(*ostream);
}

void CReport::printFooter()
{
  // for loop print out mpReportDef->getFooter()
  unsigned C_INT32 i;
  for (i = 0; i < footerObjectList.size(); i++)
    footerObjectList[i]->print(*ostream);
}

// Compile the List of Report Objects;
// Support Parellel

void CReport::compile(const std::vector< CCopasiContainer * > * pListOfContainer)
{
  generateObjectsFromName(pListOfContainer, headerObjectList, mpReportDef->getHeaderAddr());
  generateObjectsFromName(pListOfContainer, bodyObjectList, mpReportDef->getBodyAddr());
  generateObjectsFromName(pListOfContainer, footerObjectList, mpReportDef->getFooterAddr());
}

void CReport::printBody(CReport * pReport)
{
  if (pReport)
    pReport->printBody();
}

// make to support parallel tasks
void CReport::generateObjectsFromName(const std::vector< CCopasiContainer * > * pListOfContainer,
                                      std::vector<CCopasiObject*> & objectList,
                                      std::vector<CCopasiObjectName>* nameVector)
{
  unsigned C_INT32 i;
  CCopasiObject* pSelected;

  // if no specified container list
  if (!pListOfContainer)
    for (i = 0; i < nameVector->size(); i++)
      {
        pSelected = NULL;
        pSelected =
          (CCopasiObject*)CCopasiContainer::Root->getObject((*(nameVector))[i]);
        if (pSelected)
          objectList.push_back(pSelected);
      }
  else
    {
      CCopasiContainer* pCopasiObject;
      unsigned C_INT32 containerIndex;
      for (i = 0; i < nameVector->size(); i++)
        {
          //favor to search the list of container first
          pSelected = NULL;
          for (containerIndex = 0; containerIndex < pListOfContainer->size(); containerIndex++)
            {
              pCopasiObject = (*pListOfContainer)[containerIndex];
              pSelected =
                (CCopasiObject*)pCopasiObject->getObject((*(nameVector))[i]);
              if (pSelected)
                {
                  objectList.push_back(pSelected);
                  break;
                }
            }
          // if not find search the root
          if (!pSelected)
            {
              pSelected =
                (CCopasiObject*)CCopasiContainer::Root->getObject((*(nameVector))[i]);
              // has been deleted all where
              if (pSelected)
                objectList.push_back(pSelected);
            }
        }
    }
}

void CReport::getObjectFromName(
  const std::vector< CCopasiContainer * > * pListOfContainer,
  CCopasiObject* pObject,
  const CCopasiObjectName& objName)
{
  // if no specified container list
  if (!pListOfContainer)
    {
      pObject = NULL;
      pObject =
        (CCopasiObject*)CCopasiContainer::Root->getObject(objName);
    }
  else
    {
      CCopasiContainer* pCopasiObject;
      unsigned C_INT32 containerIndex;
      //favor to search the list of container first
      pObject = NULL;
      for (containerIndex = 0; containerIndex < pListOfContainer->size(); containerIndex++)
        {
          pCopasiObject = (*pListOfContainer)[containerIndex];
          pObject =
            (CCopasiObject*)pCopasiObject->getObject(objName);
        }
      // if not find search the root
      if (!pObject)
        pObject =
          (CCopasiObject*)CCopasiContainer::Root->getObject(objName);
      // has been deleted all where
    }
}
<commit_msg>if there is NULL ostream, do nothing,<commit_after>
#include "CReportDefinition.h"
#include "CReportBody.h"
#include "CReport.h"
#include "CCopasiContainer.h"

//////////////////////////////////////////////////
//
//class CReport
//
//////////////////////////////////////////////////
CReport::CReport():
    CCopasiObject("Report", NULL, "Report", CCopasiObject::Container),
    ostream(NULL),
    mpReportDef(NULL),
    mTarget(""),
    mAppend(true)
    //,mKey(CKeyFactory::add("Report", this))
{}

CReport::~CReport()
{cleanup();}

void CReport::cleanup()
{
  // Please Dont clear the objectList, as all pointers are also referred swh else
  unsigned C_INT32 i;
  for (i = 0; i < headerObjectList.size(); i++)
    headerObjectList[i] = NULL;

  for (i = 0; i < bodyObjectList.size(); i++)
    bodyObjectList[i] = NULL;

  for (i = 0; i < footerObjectList.size(); i++)
    footerObjectList[i] = NULL;

  headerObjectList.clear();
  bodyObjectList.clear();
  footerObjectList.clear();
  //  CKeyFactory::remove(mKey);
  // mpReportDef pointer shall be dealt outside, where it is created
  //  pdelete(mpReportDef);
}

CReportDefinition* CReport::getReportDefinition()
{return mpReportDef;}

void CReport::setReportDefinition(CReportDefinition* reportDef)
{mpReportDef = reportDef;}

const std::string& CReport::getTarget()
{return mTarget;}

void CReport::setTarget(std::string target)
{mTarget = target;}

bool CReport::append()
{return mAppend;}

void CReport::setAppend(bool append)
{mAppend = append;}

void CReport::printHeader()
{
  // check if there is a target defined,
  if (!ostream)
    return;
  // for loop print out mpReportDef->getHeader()
  unsigned C_INT32 i;
  for (i = 0; i < headerObjectList.size(); i++)
    headerObjectList[i]->print(*ostream);
}

void CReport::printBody()
{
  // check if there is a target defined,
  if (!ostream)
    return;
  // for loop print out mpReportDef->getBody()
  unsigned C_INT32 i;
  for (i = 0; i < bodyObjectList.size(); i++)
    bodyObjectList[i]->print(*ostream);
}

void CReport::printFooter()
{
  // check if there is a target defined,
  if (!ostream)
    return;
  // for loop print out mpReportDef->getFooter()
  unsigned C_INT32 i;
  for (i = 0; i < footerObjectList.size(); i++)
    footerObjectList[i]->print(*ostream);
}

// Compile the List of Report Objects;
// Support Parellel

void CReport::compile(const std::vector< CCopasiContainer * > * pListOfContainer)
{
  generateObjectsFromName(pListOfContainer, headerObjectList, mpReportDef->getHeaderAddr());
  generateObjectsFromName(pListOfContainer, bodyObjectList, mpReportDef->getBodyAddr());
  generateObjectsFromName(pListOfContainer, footerObjectList, mpReportDef->getFooterAddr());
}

void CReport::printBody(CReport * pReport)
{
  if (pReport)
    pReport->printBody();
}

// make to support parallel tasks
void CReport::generateObjectsFromName(const std::vector< CCopasiContainer * > * pListOfContainer,
                                      std::vector<CCopasiObject*> & objectList,
                                      std::vector<CCopasiObjectName>* nameVector)
{
  unsigned C_INT32 i;
  CCopasiObject* pSelected;

  // if no specified container list
  if (!pListOfContainer)
    for (i = 0; i < nameVector->size(); i++)
      {
        pSelected = NULL;
        pSelected =
          (CCopasiObject*)CCopasiContainer::Root->getObject((*(nameVector))[i]);
        if (pSelected)
          objectList.push_back(pSelected);
      }
  else
    {
      CCopasiContainer* pCopasiObject;
      unsigned C_INT32 containerIndex;
      for (i = 0; i < nameVector->size(); i++)
        {
          //favor to search the list of container first
          pSelected = NULL;
          for (containerIndex = 0; containerIndex < pListOfContainer->size(); containerIndex++)
            {
              pCopasiObject = (*pListOfContainer)[containerIndex];
              pSelected =
                (CCopasiObject*)pCopasiObject->getObject((*(nameVector))[i]);
              if (pSelected)
                {
                  objectList.push_back(pSelected);
                  break;
                }
            }
          // if not find search the root
          if (!pSelected)
            {
              pSelected =
                (CCopasiObject*)CCopasiContainer::Root->getObject((*(nameVector))[i]);
              // has been deleted all where
              if (pSelected)
                objectList.push_back(pSelected);
            }
        }
    }
}

void CReport::getObjectFromName(
  const std::vector< CCopasiContainer * > * pListOfContainer,
  CCopasiObject* pObject,
  const CCopasiObjectName& objName)
{
  // if no specified container list
  if (!pListOfContainer)
    {
      pObject = NULL;
      pObject =
        (CCopasiObject*)CCopasiContainer::Root->getObject(objName);
    }
  else
    {
      CCopasiContainer* pCopasiObject;
      unsigned C_INT32 containerIndex;
      //favor to search the list of container first
      pObject = NULL;
      for (containerIndex = 0; containerIndex < pListOfContainer->size(); containerIndex++)
        {
          pCopasiObject = (*pListOfContainer)[containerIndex];
          pObject =
            (CCopasiObject*)pCopasiObject->getObject(objName);
        }
      // if not find search the root
      if (!pObject)
        pObject =
          (CCopasiObject*)CCopasiContainer::Root->getObject(objName);
      // has been deleted all where
    }
}
<|endoftext|>


<commit_before>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/scan/CScanTask.cpp,v $
   $Revision: 1.51 $
   $Name:  $
   $Author: shoops $
   $Date: 2005/04/25 18:16:13 $
   End CVS Header */

/**
 * CScanTask class.
 *
 * This class implements a scan task which is comprised of a
 * of a problem and a method.
 *
 */
#include "copasi.h"
#include "CScanTask.h"
#include "CScanProblem.h"
#include "CScanMethod.h"
#include "utilities/CReadConfig.h"
#include "report/CKeyFactory.h"
#include "report/CReport.h"

#include "model/CModel.h"
#include "model/CState.h"

#include "trajectory/CTrajectoryTask.h"
#include "trajectory/CTrajectoryProblem.h"
#include "steadystate/CSteadyStateTask.h"
#include "steadystate/CSteadyStateProblem.h"
#include "utilities/COutputHandler.h"
#include "utilities/CProcessReport.h"
#include "CopasiDataModel/CCopasiDataModel.h"

CScanTask::CScanTask(const CCopasiContainer * pParent):
    CCopasiTask(CCopasiTask::scan, pParent)
{
  mpProblem = new CScanProblem(this);
  mpMethod = CScanMethod::createMethod();
  this->add(mpMethod, true);
  //  mpMethod->setObjectParent(this);
  ((CScanMethod *) mpMethod)->setProblem((CScanProblem *) mpProblem);
}

CScanTask::CScanTask(const CScanTask & src,
                     const CCopasiContainer * pParent):
    CCopasiTask(src, pParent)
{
  mpProblem = new CScanProblem(* (CScanProblem *) src.mpProblem, this);
  mpMethod = CScanMethod::createMethod();
  this->add(mpMethod, true);
  //  mpMethod->setObjectParent(this);
  ((CScanMethod *) mpMethod)->setProblem((CScanProblem *) mpProblem);
}

CScanTask::~CScanTask()
{cleanup();}

void CScanTask::cleanup()
{
  //pdelete(mpProblem);
  //pdelete(mpMethod);
  //  pdelete(mpOutEnd);
  //-pdelete(mReport);
}

bool CScanTask::initialize(std::ostream * out)
{
  CScanProblem* pProblem =
    dynamic_cast<CScanProblem *>(mpProblem);

  bool success = true;

  if (!pProblem->getModel()->compileIfNecessary()) success = false;

  //  pdelete(mpOutEnd);
  //mpOut = & out;
  // added by Liang for Scan Report
  //mReport.open(mpOut);
  //mReport.compile();

  assert(pProblem);

  // for Steadystate Report
  //  if (pProblem->processSteadyState())
  //    pProblem->getSteadyStateTask()->initialize(mpOut);

  // for Trajectory Report
  //  if (pProblem->processTrajectory())
  //    pProblem->getTrajectoryTask()->initialize(mpOut);
  return success;
}

void CScanTask::load(CReadConfig & C_UNUSED(configBuffer))
{
  CScanProblem* pProblem =
    dynamic_cast<CScanProblem *>(mpProblem);
  assert(pProblem);

  //pProblem->load(configBuffer);
}

bool CScanTask::process()
{
  if (!mpProblem) fatalError();
  if (!mpMethod) fatalError();

  CScanProblem * pProblem = dynamic_cast<CScanProblem *>(mpProblem);
  if (!pProblem) fatalError();
  CScanMethod * pMethod = dynamic_cast<CScanMethod *>(mpMethod);
  if (!pMethod) fatalError();

  bool success = true;

  initSubtask();

  pMethod->setProblem(pProblem);

  //TODO: reports

  //initialize the method (parsing the ScanItems)
  if (!pMethod->init()) return false;

  //init progress bar
  mProgress = 0;
  /*
    if (mpProgressHandler)
      mpProgressHandler->init(pMethod->getTotalNumberOfSteps(),
                              "performing parameter scan...",
                              true);
  */

  if (mpProgressHandler)
    {
      mpProgressHandler->setName("performing parameter scan...");

      unsigned C_INT32 totalSteps = pMethod->getTotalNumberOfSteps();
      mpProgressHandler->addItem("Number of Steps",
                                 CCopasiParameter::UINT,
                                 &mProgress,
                                 &totalSteps);
    }
  //init output handler (plotting)
  if (mpOutputHandler) mpOutputHandler->init();

  //calling the scanner, output is done in the callback
  if (!pMethod->scan()) success = false;

  //finishing progress bar and output
  if (mpProgressHandler) mpProgressHandler->finish();
  if (mpOutputHandler) mpOutputHandler->finish();

  return success;
}

bool CScanTask::processCallback()
{
  //do tasks
  CSteadyStateProblem * ssProblem = dynamic_cast<CSteadyStateProblem*>(mpSubtask->getProblem());
  if (ssProblem)
  {ssProblem->setInitialState(CCopasiDataModel::Global->getModel()->getInitialState());}
  CTrajectoryProblem * ttProblem = dynamic_cast<CTrajectoryProblem*>(mpSubtask->getProblem());
  if (ttProblem)
  {ttProblem->setInitialState(CCopasiDataModel::Global->getModel()->getInitialState());}
  mpSubtask->processForScan(!mAdjustInitialConditions, mOutputInSubtask);

  //do output
  if (mpOutputHandler && (!mOutputInSubtask)) mpOutputHandler->doOutput();

  //do progress bar
  ++mProgress;
  if (mpProgressHandler) return !mpProgressHandler->progress();

  return true;
}

bool CScanTask::outputSeparatorCallback(bool isLast)
{
  if ((!isLast) || mOutputInSubtask)
    if (mpOutputHandler) return mpOutputHandler->doSeparator();
  return true;
}

bool CScanTask::initSubtask()
{
  if (!mpProblem) fatalError();
  CScanProblem * pProblem = dynamic_cast<CScanProblem *>(mpProblem);
  if (!pProblem) fatalError();

  //get the parameters from the problem
  CCopasiTask::Type type = *(CCopasiTask::Type*)(pProblem->getValue("Subtask"));

  CTrajectoryProblem* trajProblem;
  CSteadyStateProblem* ssProblem;
  switch (type)
    {
    case CCopasiTask::steadyState:
      mpSubtask = dynamic_cast<CCopasiTask*>
                  ((*CCopasiDataModel::Global->getTaskList())["Steady-State"]);
      ssProblem = dynamic_cast<CSteadyStateProblem*>(mpSubtask->getProblem());
      ssProblem->setInitialState(CCopasiDataModel::Global->getModel()->getInitialState());
      break;

    case CCopasiTask::timeCourse:
      mpSubtask = dynamic_cast<CCopasiTask*>
                  ((*CCopasiDataModel::Global->getTaskList())["Time-Course"]);
      trajProblem = dynamic_cast<CTrajectoryProblem*>(mpSubtask->getProblem());
      trajProblem->setInitialState(CCopasiDataModel::Global->getModel()->getInitialState());
      break;

    default:
      mpSubtask = NULL;
    }

  /*
  if (type == CCopasiTask::steadyState)
    {
      mpSubtask=const_cast<CCopasiTask*>
                   (dynamic_cast<const CCopasiTask*>
                     (CCopasiContainer::Root->getObject(CCopasiObjectName("Task=Steady-State"))));
    }
  else
    {mpSubtask=NULL;}*/

  if (!mpSubtask) return false;

  mpSubtask->getProblem()->setModel(CCopasiDataModel::Global->getModel());
  mpSubtask->setProgressHandler(NULL);
  mpSubtask->initialize();

  mOutputInSubtask = *(bool*)(pProblem->getValue("Output in subtask"));
  if (type != CCopasiTask::timeCourse)
    mOutputInSubtask = false;

  mAdjustInitialConditions = *(bool*)(pProblem->getValue("Adjust initial conditions"));

  return true;
}
<commit_msg>adapted to changes in the semantics of the progress bar handler<commit_after>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/scan/CScanTask.cpp,v $
   $Revision: 1.52 $
   $Name:  $
   $Author: ssahle $
   $Date: 2005/05/24 12:37:23 $
   End CVS Header */

/**
 * CScanTask class.
 *
 * This class implements a scan task which is comprised of a
 * of a problem and a method.
 *
 */
#include "copasi.h"
#include "CScanTask.h"
#include "CScanProblem.h"
#include "CScanMethod.h"
#include "utilities/CReadConfig.h"
#include "report/CKeyFactory.h"
#include "report/CReport.h"

#include "model/CModel.h"
#include "model/CState.h"

#include "trajectory/CTrajectoryTask.h"
#include "trajectory/CTrajectoryProblem.h"
#include "steadystate/CSteadyStateTask.h"
#include "steadystate/CSteadyStateProblem.h"
#include "utilities/COutputHandler.h"
#include "utilities/CProcessReport.h"
#include "CopasiDataModel/CCopasiDataModel.h"

CScanTask::CScanTask(const CCopasiContainer * pParent):
    CCopasiTask(CCopasiTask::scan, pParent)
{
  mpProblem = new CScanProblem(this);
  mpMethod = CScanMethod::createMethod();
  this->add(mpMethod, true);
  //  mpMethod->setObjectParent(this);
  ((CScanMethod *) mpMethod)->setProblem((CScanProblem *) mpProblem);
}

CScanTask::CScanTask(const CScanTask & src,
                     const CCopasiContainer * pParent):
    CCopasiTask(src, pParent)
{
  mpProblem = new CScanProblem(* (CScanProblem *) src.mpProblem, this);
  mpMethod = CScanMethod::createMethod();
  this->add(mpMethod, true);
  //  mpMethod->setObjectParent(this);
  ((CScanMethod *) mpMethod)->setProblem((CScanProblem *) mpProblem);
}

CScanTask::~CScanTask()
{cleanup();}

void CScanTask::cleanup()
{
  //pdelete(mpProblem);
  //pdelete(mpMethod);
  //  pdelete(mpOutEnd);
  //-pdelete(mReport);
}

bool CScanTask::initialize(std::ostream * out)
{
  CScanProblem* pProblem =
    dynamic_cast<CScanProblem *>(mpProblem);

  bool success = true;

  if (!pProblem->getModel()->compileIfNecessary()) success = false;

  //  pdelete(mpOutEnd);
  //mpOut = & out;
  // added by Liang for Scan Report
  //mReport.open(mpOut);
  //mReport.compile();

  assert(pProblem);

  // for Steadystate Report
  //  if (pProblem->processSteadyState())
  //    pProblem->getSteadyStateTask()->initialize(mpOut);

  // for Trajectory Report
  //  if (pProblem->processTrajectory())
  //    pProblem->getTrajectoryTask()->initialize(mpOut);
  return success;
}

void CScanTask::load(CReadConfig & C_UNUSED(configBuffer))
{
  CScanProblem* pProblem =
    dynamic_cast<CScanProblem *>(mpProblem);
  assert(pProblem);

  //pProblem->load(configBuffer);
}

bool CScanTask::process()
{
  if (!mpProblem) fatalError();
  if (!mpMethod) fatalError();

  CScanProblem * pProblem = dynamic_cast<CScanProblem *>(mpProblem);
  if (!pProblem) fatalError();
  CScanMethod * pMethod = dynamic_cast<CScanMethod *>(mpMethod);
  if (!pMethod) fatalError();

  bool success = true;

  initSubtask();

  pMethod->setProblem(pProblem);

  //TODO: reports

  //initialize the method (parsing the ScanItems)
  if (!pMethod->init()) return false;

  //init progress bar
  mProgress = 0;
  /*
    if (mpProgressHandler)
      mpProgressHandler->init(pMethod->getTotalNumberOfSteps(),
                              "performing parameter scan...",
                              true);
  */

  if (mpProgressHandler)
    {
      mpProgressHandler->setName("performing parameter scan...");

      unsigned C_INT32 totalSteps = pMethod->getTotalNumberOfSteps();
      mpProgressHandler->addItem("Number of Steps",
                                 CCopasiParameter::UINT,
                                 &mProgress,
                                 &totalSteps);
    }
  //init output handler (plotting)
  if (mpOutputHandler) mpOutputHandler->init();

  //calling the scanner, output is done in the callback
  if (!pMethod->scan()) success = false;

  //finishing progress bar and output
  if (mpProgressHandler) mpProgressHandler->finish();
  if (mpOutputHandler) mpOutputHandler->finish();

  return success;
}

bool CScanTask::processCallback()
{
  //do tasks
  CSteadyStateProblem * ssProblem = dynamic_cast<CSteadyStateProblem*>(mpSubtask->getProblem());
  if (ssProblem)
  {ssProblem->setInitialState(CCopasiDataModel::Global->getModel()->getInitialState());}
  CTrajectoryProblem * ttProblem = dynamic_cast<CTrajectoryProblem*>(mpSubtask->getProblem());
  if (ttProblem)
  {ttProblem->setInitialState(CCopasiDataModel::Global->getModel()->getInitialState());}
  mpSubtask->processForScan(!mAdjustInitialConditions, mOutputInSubtask);

  //do output
  if (mpOutputHandler && (!mOutputInSubtask)) mpOutputHandler->doOutput();

  //do progress bar
  ++mProgress;
  if (mpProgressHandler) return mpProgressHandler->progress();

  return true;
}

bool CScanTask::outputSeparatorCallback(bool isLast)
{
  if ((!isLast) || mOutputInSubtask)
    if (mpOutputHandler) return mpOutputHandler->doSeparator();
  return true;
}

bool CScanTask::initSubtask()
{
  if (!mpProblem) fatalError();
  CScanProblem * pProblem = dynamic_cast<CScanProblem *>(mpProblem);
  if (!pProblem) fatalError();

  //get the parameters from the problem
  CCopasiTask::Type type = *(CCopasiTask::Type*)(pProblem->getValue("Subtask"));

  CTrajectoryProblem* trajProblem;
  CSteadyStateProblem* ssProblem;
  switch (type)
    {
    case CCopasiTask::steadyState:
      mpSubtask = dynamic_cast<CCopasiTask*>
                  ((*CCopasiDataModel::Global->getTaskList())["Steady-State"]);
      ssProblem = dynamic_cast<CSteadyStateProblem*>(mpSubtask->getProblem());
      ssProblem->setInitialState(CCopasiDataModel::Global->getModel()->getInitialState());
      break;

    case CCopasiTask::timeCourse:
      mpSubtask = dynamic_cast<CCopasiTask*>
                  ((*CCopasiDataModel::Global->getTaskList())["Time-Course"]);
      trajProblem = dynamic_cast<CTrajectoryProblem*>(mpSubtask->getProblem());
      trajProblem->setInitialState(CCopasiDataModel::Global->getModel()->getInitialState());
      break;

    default:
      mpSubtask = NULL;
    }

  /*
  if (type == CCopasiTask::steadyState)
    {
      mpSubtask=const_cast<CCopasiTask*>
                   (dynamic_cast<const CCopasiTask*>
                     (CCopasiContainer::Root->getObject(CCopasiObjectName("Task=Steady-State"))));
    }
  else
    {mpSubtask=NULL;}*/

  if (!mpSubtask) return false;

  mpSubtask->getProblem()->setModel(CCopasiDataModel::Global->getModel());
  mpSubtask->setProgressHandler(NULL);
  mpSubtask->initialize();

  mOutputInSubtask = *(bool*)(pProblem->getValue("Output in subtask"));
  if (type != CCopasiTask::timeCourse)
    mOutputInSubtask = false;

  mAdjustInitialConditions = *(bool*)(pProblem->getValue("Adjust initial conditions"));

  return true;
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2008-2012 J-P Nurmi <jpnurmi@gmail.com>
 *
 * This test is free, and not covered by LGPL license. There is no
 * restriction applied to their modification, redistribution, using and so on.
 * You can study them, modify them, use them in your own program - either
 * completely or partially. By using it you may give me some credits in your
 * program, but you don't have to.
 */

#include "irccommand.h"
#include <QtTest/QtTest>

class tst_IrcCommand : public QObject
{
    Q_OBJECT

private slots:
    void testDefaults();

    void testAway();
    void testCtcpAction();
    void testCtcpReply();
    void testCtcpRequest();
    void testInvite();
    void testJoin();
    void testKick();
    void testList();
    void testMessage();
    void testMode();
    void testNames();
    void testNick();
    void testNotice();
    void testPart();
    void testPing();
    void testPong();
    void testQuit();
    void testQuote();
    void testTopic();
    void testWho();
    void testWhois();
    void testWhowas();
};

void tst_IrcCommand::testDefaults()
{
    IrcCommand cmd;
    QVERIFY(cmd.type() == IrcCommand::Custom);
    QVERIFY(cmd.parameters().isEmpty());
}

void tst_IrcCommand::testAway()
{
}

void tst_IrcCommand::testCtcpAction()
{
}

void tst_IrcCommand::testCtcpReply()
{
}

void tst_IrcCommand::testCtcpRequest()
{
}

void tst_IrcCommand::testInvite()
{
}

void tst_IrcCommand::testJoin()
{
}

void tst_IrcCommand::testKick()
{
}

void tst_IrcCommand::testList()
{
}

void tst_IrcCommand::testMessage()
{
}

void tst_IrcCommand::testMode()
{
}

void tst_IrcCommand::testNames()
{
}

void tst_IrcCommand::testNick()
{
}

void tst_IrcCommand::testNotice()
{
}

void tst_IrcCommand::testPart()
{
}

void tst_IrcCommand::testPing()
{
}

void tst_IrcCommand::testPong()
{
}

void tst_IrcCommand::testQuit()
{
}

void tst_IrcCommand::testQuote()
{
}

void tst_IrcCommand::testTopic()
{
}

void tst_IrcCommand::testWho()
{
}

void tst_IrcCommand::testWhois()
{
}

void tst_IrcCommand::testWhowas()
{
}

QTEST_MAIN(tst_IrcCommand)

#include "tst_irccommand.moc"
<commit_msg>Update tst_irccommand with very basic tests<commit_after>/*
 * Copyright (C) 2008-2012 J-P Nurmi <jpnurmi@gmail.com>
 *
 * This test is free, and not covered by LGPL license. There is no
 * restriction applied to their modification, redistribution, using and so on.
 * You can study them, modify them, use them in your own program - either
 * completely or partially. By using it you may give me some credits in your
 * program, but you don't have to.
 */

#include "irccommand.h"
#include <QtTest/QtTest>

class tst_IrcCommand : public QObject
{
    Q_OBJECT

private slots:
    void testDefaults();

    void testAdmin();
    void testAway();
    void testCapability();
    void testCtcpAction();
    void testCtcpReply();
    void testCtcpRequest();
    void testInfo();
    void testInvite();
    void testJoin();
    void testKick();
    void testKnock();
    void testList();
    void testMessage();
    void testMode();
    void testMotd();
    void testNames();
    void testNick();
    void testNotice();
    void testPart();
    void testQuit();
    void testQuote();
    void testStats();
    void testTime();
    void testTopic();
    void testTrace();
    void testUsers();
    void testVersion();
    void testWho();
    void testWhois();
    void testWhowas();
};

void tst_IrcCommand::testDefaults()
{
    IrcCommand cmd;
    QVERIFY(cmd.type() == IrcCommand::Custom);
    QVERIFY(cmd.parameters().isEmpty());
}

void tst_IrcCommand::testAdmin()
{
    IrcCommand* cmd = IrcCommand::createAdmin();
    QVERIFY(cmd->type() == IrcCommand::Admin);
    QVERIFY(cmd->toString().contains(QRegExp("\\bADMIN\\b")));
    delete cmd;
}

void tst_IrcCommand::testAway()
{
    IrcCommand* cmd = IrcCommand::createAway();
    QVERIFY(cmd->type() == IrcCommand::Away);
    QVERIFY(cmd->toString().contains(QRegExp("\\bAWAY\\b")));
    delete cmd;
}

void tst_IrcCommand::testCapability()
{
    IrcCommand* cmd = IrcCommand::createCapability("sub");
    QVERIFY(cmd->type() == IrcCommand::Capability);
    QVERIFY(cmd->toString().contains(QRegExp("\\bCAP\\b")));
    delete cmd;
}

void tst_IrcCommand::testCtcpAction()
{
    IrcCommand* cmd = IrcCommand::createCtcpAction("tgt", "act");
    QVERIFY(cmd->type() == IrcCommand::CtcpAction);
    QVERIFY(cmd->toString().contains(QRegExp("\\bPRIVMSG\\b")));
    delete cmd;
}

void tst_IrcCommand::testCtcpReply()
{
    IrcCommand* cmd = IrcCommand::createCtcpReply("tgt", "rpl");
    QVERIFY(cmd->type() == IrcCommand::CtcpReply);
    QVERIFY(cmd->toString().contains(QRegExp("\\bNOTICE\\b")));
    delete cmd;
}

void tst_IrcCommand::testCtcpRequest()
{
    IrcCommand* cmd = IrcCommand::createCtcpRequest("tgt", "req");
    QVERIFY(cmd->type() == IrcCommand::CtcpRequest);
    QVERIFY(cmd->toString().contains(QRegExp("\\bPRIVMSG\\b")));
    delete cmd;
}

void tst_IrcCommand::testInfo()
{
    IrcCommand* cmd = IrcCommand::createInfo();
    QVERIFY(cmd->type() == IrcCommand::Info);
    QVERIFY(cmd->toString().contains(QRegExp("\\bINFO\\b")));
    delete cmd;
}

void tst_IrcCommand::testInvite()
{
    IrcCommand* cmd = IrcCommand::createInvite("usr", "chan");
    QVERIFY(cmd->type() == IrcCommand::Invite);
    QVERIFY(cmd->toString().contains(QRegExp("\\bINVITE\\b")));
    delete cmd;
}

void tst_IrcCommand::testJoin()
{
    IrcCommand* cmd = IrcCommand::createJoin("chan");
    QVERIFY(cmd->type() == IrcCommand::Join);
    QVERIFY(cmd->toString().contains(QRegExp("\\bJOIN\\b")));
    delete cmd;
}

void tst_IrcCommand::testKick()
{
    IrcCommand* cmd = IrcCommand::createKick("chan", "usr");
    QVERIFY(cmd->type() == IrcCommand::Kick);
    QVERIFY(cmd->toString().contains(QRegExp("\\bKICK\\b")));
    delete cmd;
}

void tst_IrcCommand::testKnock()
{
    IrcCommand* cmd = IrcCommand::createKnock("chan");
    QVERIFY(cmd->type() == IrcCommand::Knock);
    QVERIFY(cmd->toString().contains(QRegExp("\\bKNOCK\\b")));
    delete cmd;
}

void tst_IrcCommand::testList()
{
    IrcCommand* cmd = IrcCommand::createList();
    QVERIFY(cmd->type() == IrcCommand::List);
    QVERIFY(cmd->toString().contains(QRegExp("\\bLIST\\b")));
    delete cmd;
}

void tst_IrcCommand::testMessage()
{
    IrcCommand* cmd = IrcCommand::createMessage("tgt", "msg");
    QVERIFY(cmd->type() == IrcCommand::Message);
    QVERIFY(cmd->toString().contains(QRegExp("\\bPRIVMSG\\b")));
    delete cmd;
}

void tst_IrcCommand::testMode()
{
    IrcCommand* cmd = IrcCommand::createMode("tgt", "mode");
    QVERIFY(cmd->type() == IrcCommand::Mode);
    QVERIFY(cmd->toString().contains(QRegExp("\\bMODE\\b")));
    delete cmd;
}

void tst_IrcCommand::testMotd()
{
    IrcCommand* cmd = IrcCommand::createMotd();
    QVERIFY(cmd->type() == IrcCommand::Motd);
    QVERIFY(cmd->toString().contains(QRegExp("\\bMOTD\\b")));
    delete cmd;
}

void tst_IrcCommand::testNames()
{
    IrcCommand* cmd = IrcCommand::createNames();
    QVERIFY(cmd->type() == IrcCommand::Names);
    QVERIFY(cmd->toString().contains(QRegExp("\\bNAMES\\b")));
    delete cmd;
}

void tst_IrcCommand::testNick()
{
    IrcCommand* cmd = IrcCommand::createNick("nick");
    QVERIFY(cmd->type() == IrcCommand::Nick);
    QVERIFY(cmd->toString().contains(QRegExp("\\bNICK\\b")));
    delete cmd;
}

void tst_IrcCommand::testNotice()
{
    IrcCommand* cmd = IrcCommand::createNotice("tgt", "msg");
    QVERIFY(cmd->type() == IrcCommand::Notice);
    QVERIFY(cmd->toString().contains(QRegExp("\\bNOTICE\\b")));
    delete cmd;
}

void tst_IrcCommand::testPart()
{
    IrcCommand* cmd = IrcCommand::createPart("chan");
    QVERIFY(cmd->type() == IrcCommand::Part);
    QVERIFY(cmd->toString().contains(QRegExp("\\bPART\\b")));
    delete cmd;
}

void tst_IrcCommand::testQuit()
{
    IrcCommand* cmd = IrcCommand::createQuit();
    QVERIFY(cmd->type() == IrcCommand::Quit);
    QVERIFY(cmd->toString().contains(QRegExp("\\bQUIT\\b")));
    delete cmd;
}

void tst_IrcCommand::testQuote()
{
    IrcCommand* cmd = IrcCommand::createQuote("CUSTOM");
    QVERIFY(cmd->type() == IrcCommand::Quote);
    QVERIFY(cmd->toString().contains(QRegExp("\\bCUSTOM\\b")));
    delete cmd;
}

void tst_IrcCommand::testStats()
{
    IrcCommand* cmd = IrcCommand::createStats("qry");
    QVERIFY(cmd->type() == IrcCommand::Stats);
    QVERIFY(cmd->toString().contains(QRegExp("\\bSTATS\\b")));
    delete cmd;
}

void tst_IrcCommand::testTime()
{
    IrcCommand* cmd = IrcCommand::createTime();
    QVERIFY(cmd->type() == IrcCommand::Time);
    QVERIFY(cmd->toString().contains(QRegExp("\\bTIME\\b")));
    delete cmd;
}

void tst_IrcCommand::testTopic()
{
    IrcCommand* cmd = IrcCommand::createTopic("chan");
    QVERIFY(cmd->type() == IrcCommand::Topic);
    QVERIFY(cmd->toString().contains(QRegExp("\\bTOPIC\\b")));
    delete cmd;
}

void tst_IrcCommand::testTrace()
{
    IrcCommand* cmd = IrcCommand::createTrace();
    QVERIFY(cmd->type() == IrcCommand::Trace);
    QVERIFY(cmd->toString().contains(QRegExp("\\bTRACE\\b")));
    delete cmd;
}

void tst_IrcCommand::testUsers()
{
    IrcCommand* cmd = IrcCommand::createUsers();
    QVERIFY(cmd->type() == IrcCommand::Users);
    QVERIFY(cmd->toString().contains(QRegExp("\\bUSERS\\b")));
    delete cmd;
}

void tst_IrcCommand::testVersion()
{
    IrcCommand* cmd = IrcCommand::createVersion();
    QVERIFY(cmd->type() == IrcCommand::Version);
    QVERIFY(cmd->toString().contains(QRegExp("\\bVERSION\\b")));
    delete cmd;
}

void tst_IrcCommand::testWho()
{
    IrcCommand* cmd = IrcCommand::createWho("msk");
    QVERIFY(cmd->type() == IrcCommand::Who);
    QVERIFY(cmd->toString().contains(QRegExp("\\bWHO\\b")));
    delete cmd;
}

void tst_IrcCommand::testWhois()
{
    IrcCommand* cmd = IrcCommand::createWhois("usr");
    QVERIFY(cmd->type() == IrcCommand::Whois);
    QVERIFY(cmd->toString().contains(QRegExp("\\bWHOIS\\b")));
    delete cmd;
}

void tst_IrcCommand::testWhowas()
{
    IrcCommand* cmd = IrcCommand::createWhowas("usr");
    QVERIFY(cmd->type() == IrcCommand::Whowas);
    QVERIFY(cmd->toString().contains(QRegExp("\\bWHOWAS\\b")));
    delete cmd;
}

QTEST_MAIN(tst_IrcCommand)

#include "tst_irccommand.moc"
<|endoftext|>


<commit_before>/*
The MIT License (MIT)

Copyright (c) 2015-2021 Ivan Gagis <igagis@gmail.com>

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

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

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

/* ================ LICENSE END ================ */

#pragma once

#include <exception>
#include <string>

namespace utki{

/**
 * @brief Generic exception.
 *
 * This class allows throwing an std::exception-derived exception with text message.
 * This exception class is to be mainly used for adding additional text message to already
 * thrown exception via std::throw_with_nested.
 */
class exception : public std::exception{
	std::string message;
public:

	/**
	 * @brief Constructor.
	 *
	 * @param message - text message to be stored in the exception object.
	 */
	exception(std::string&& message) :
			message(message)
	{}

	const char* what()const noexcept override{
		return this->message.c_str();
	}
};

}
<commit_msg>change exception class description<commit_after>/*
The MIT License (MIT)

Copyright (c) 2015-2021 Ivan Gagis <igagis@gmail.com>

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

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

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

/* ================ LICENSE END ================ */

#pragma once

#include <exception>
#include <string>

namespace utki{

/**
 * @brief Generic exception.
 *
 * This class allows throwing an std::exception-derived exception with text message.
 * This class is for the cases when none of the std::logic_error nor the std::runtime_error suits.
 */
class exception : public std::exception{
	std::string message;
public:

	/**
	 * @brief Constructor.
	 *
	 * @param message - text message to be stored in the exception object.
	 */
	exception(std::string&& message) :
			message(message)
	{}

	const char* what()const noexcept override{
		return this->message.c_str();
	}
};

}
<|endoftext|>


<commit_before>// Copyright (c) 2014, German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.

#include <nix/valid/validator.hpp>
#include <nix/valid/checks.hpp>
#include <nix/valid/conditions.hpp>
#include <nix/valid/result.hpp>

#include <nix.hpp>

namespace nix {
namespace valid {

// ---------------------------------------------------------------------
// Templated, hidden validation utils that are only here in the cpp,
// not in the header (hides them from user)
// ---------------------------------------------------------------------

/**
  * @brief base entity validator
  *
  * Function taking a base entity and returning {@link Result} object
  *
  * @param entity base entity
  *
  * @returns The validation results as {@link Result} object
  */
template<typename T>
Result validate_entity(const base::Entity<T> &entity) {
    return validator({
        must(entity, &base::Entity<T>::id, notEmpty(), "id is not set!"),
        must(entity, &base::Entity<T>::createdAt, notFalse(), "date is not set!")
    });
}

/**
  * @brief base named entity validator
  *
  * Function taking a base named entity and returning {@link Result}
  * object
  *
  * @param named_entity base named entity
  *
  * @returns The validation results as {@link Result} object
  */
template<typename T>
Result validate_named_entity(const base::NamedEntity<T> &named_entity) {
    Result result_base = validate_entity<T>(named_entity);
    Result result = validator({
        must(named_entity, &base::NamedEntity<T>::name, notEmpty(), "no name set!"),
        must(named_entity, &base::NamedEntity<T>::type, notEmpty(), "no type set!")
    });

    return result.concat(result_base);
}

/**
  * @brief base entity with metadata validator
  *
  * Function taking a base entity with metadata and returning
  * {@link Result} object
  *
  * @param entity_with_metadata base entity with metadata
  *
  * @returns The validation results as {@link Result} object
  */
template<typename T>
Result validate_entity_with_metadata(const base::EntityWithMetadata<T> &entity_with_metadata) {
    return validate_named_entity<T>(entity_with_metadata);
}

/**
  * @brief base entity with sources validator
  *
  * Function taking a base entity with sources and returning
  * {@link Result} object
  *
  * @param entity_with_sources base entity with sources
  *
  * @returns The validation results as {@link Result} object
  */
template<typename T>
Result validate_entity_with_sources(const base::EntityWithSources<T> &entity_with_sources) {
    return validate_entity_with_metadata<T>(entity_with_sources);
}

// ---------------------------------------------------------------------
// Regular validaton utils split in header & cpp part
// ---------------------------------------------------------------------

Result validate(const Block &block) {
    return validate_entity_with_metadata(block);
}

Result validate(const DataArray &data_array) {
    Result result_base = validate_entity_with_sources(data_array);
    Result result = validator({
        must(data_array, &DataArray::dataType, notEqual<DataType>(DataType::Nothing), "data type is not set!"),
        must(data_array, &DataArray::dimensionCount, isEqual<size_t>(data_array.dataExtent().size()), "data dimensionality does not match number of defined dimensions!", {
            could(data_array, &DataArray::dimensions, notEmpty(), {
                should(data_array, &DataArray::dimensions, dimTicksMatchData(data_array), "in some of the Range dimensions the number of ticks differs from the number of data entries along the corresponding data dimension!"),
                must(data_array, &DataArray::dimensions, dimLabelsMatchData(data_array), "in some of the Set dimensions the number of labels differs from the number of data entries along the corresponding data dimension!") }) }),
        could(data_array, &DataArray::unit, notFalse(), {
            must(data_array, &DataArray::unit, isValidUnit(), "Unit is not SI or composite of SI units.") }),
        could(data_array, &DataArray::polynomCoefficients, notEmpty(), {
            should(data_array, &DataArray::expansionOrigin, notFalse(), "polynomial coefficients for calibration are set, but expansion origin is missing!") }),
        could(data_array, &DataArray::expansionOrigin, notFalse(), {
            should(data_array, &DataArray::polynomCoefficients, notEmpty(), "expansion origin for calibration is set, but polynomial coefficients are missing!") })
    });

    return result.concat(result_base);
}

Result validate(const Tag &tag) {
    Result result_base = validate_entity_with_sources(tag);
    Result result = validator({
        must(tag, &Tag::position, notEmpty(), "position is not set!"),
        could(tag, &Tag::references, notEmpty(), {
            must(tag, &Tag::position, positionsMatchRefs(tag.references()),
                "number of entries in position does not match number of dimensions in all referenced DataArrays!"),
            could(tag, &Tag::extent, notEmpty(), {
                must(tag, &Tag::extent, extentsMatchRefs(tag.references()),
                    "number of entries in extent does not match number of dimensions in all referenced DataArrays!") })
        }),
        // check units for validity
        could(tag, &Tag::units, notEmpty(), {
            must(tag, &Tag::units, isValidUnit(), "Unit is invalid: not an atomic SI. Note: So far composite units are not supported!"),
            must(tag, &Tag::references, tagRefsHaveUnits(tag.units()), "Some of the referenced DataArrays' dimensions don't have units where the tag has. Make sure that all references have the same number of dimensions as the tag has units and that each dimension has a unit set."),
                must(tag, &Tag::references, tagUnitsMatchRefsUnits(tag.units()), "Some of the referenced DataArrays' dimensions have units that are not convertible to the units set in tag. Note: So far composite SI units are not supported!")}),
        // check positions & extents
        could(tag, &Tag::extent, notEmpty(), {
            must(tag, &Tag::position, extentsMatchPositions(tag.extent()), "Number of entries in position and extent do not match!"),
            must(tag, &Tag::extent, extentsMatchRefs(tag.references()), "number of entries in extent does not match number of dimensions in all referenced DataArrays!") })
    });

    return result.concat(result_base);
}

Result validate(const Property &property) {
    Result result_base = validate_entity(property);
    Result result = validator({
        must(property, &Property::name, notEmpty(), "name is not set!"),
        could(property, &Property::valueCount, notFalse(), {
            should(property, &Property::unit, notFalse(), "values are set, but unit is missing!") }),
        could(property, &Property::unit, notFalse(), {
            must(property, &Property::unit, isValidUnit(), "Unit is not SI or composite of SI units.") })
        // TODO: dataType to be tested too?
    });

    return result.concat(result_base);
}

Result validate(const MultiTag &multi_tag) {
    Result result_base = validate_entity_with_sources(multi_tag);
    Result result = validator({
        must(multi_tag, &MultiTag::positions, notFalse(), "positions are not set!"),
        // since extents & positions DataArray stores a vector of position / extent vectors it has to be 2-dim
        could(multi_tag, &MultiTag::positions, notFalse(), {
            must(multi_tag, &MultiTag::positions, dimEquals(2), "dimensionality of positions DataArray must be two!") }),
        could(multi_tag, &MultiTag::extents, notFalse(), {
            must(multi_tag, &MultiTag::extents, dimEquals(2), "dimensionality of extents DataArray must be two!") }),
        // check units for validity
        could(multi_tag, &MultiTag::units, notEmpty(), {
            must(multi_tag, &MultiTag::units, isValidUnit(), "Some of the units in tag are invalid: not an atomic SI. Note: So far composite SI units are not supported!"),
            must(multi_tag, &MultiTag::references, tagUnitsMatchRefsUnits(multi_tag.units()), "Some of the referenced DataArrays' dimensions have units that are not convertible to the units set in tag. Note: So far composite SI units are not supported!")}),
        // check positions & extents
        could(multi_tag, &MultiTag::extents, notFalse(), {
            must(multi_tag, &MultiTag::positions, extentsMatchPositions(multi_tag.extents()), "Number of entries in positions and extents do not match!") }),
        could(multi_tag, &MultiTag::references, notEmpty(), {
            could(multi_tag, &MultiTag::extents, notFalse(), {
                must(multi_tag, &MultiTag::extents, extentsMatchRefs(multi_tag.references()), "number of entries (in 2nd dim) in extents does not match number of dimensions in all referenced DataArrays!") }),
            must(multi_tag, &MultiTag::positions, positionsMatchRefs(multi_tag.references()), "number of entries (in 2nd dim) in positions does not match number of dimensions in all referenced DataArrays!") })
    });

    return result.concat(result_base);
}

Result validate(const Dimension &dim) {
    return validator({
        must(dim, &Dimension::index, notSmaller(1), "index is not set to valid value (> 0)!")
    });
}

Result validate(const RangeDimension &range_dim) {
    return validator({
        must(range_dim, &RangeDimension::index, notSmaller(1), "index is not set to valid value (size_t > 0)!"),
        must(range_dim, &RangeDimension::ticks, notEmpty(), "ticks are not set!"),
        must(range_dim, &RangeDimension::dimensionType, isEqual<DimensionType>(DimensionType::Range), "dimension type is not correct!"),
        could(range_dim, &RangeDimension::unit, notFalse(), {
            must(range_dim, &RangeDimension::unit, isAtomicUnit(), "Unit is set but not an atomic SI. Note: So far composite units are not supported!") }),
        must(range_dim, &RangeDimension::ticks, isSorted(), "Ticks are not sorted!")
    });
}

Result validate(const SampledDimension &sampled_dim) {
    return validator({
        must(sampled_dim, &SampledDimension::index, notSmaller(1), "index is not set to valid value (size_t > 0)!"),
        must(sampled_dim, &SampledDimension::samplingInterval, isGreater(0), "samplingInterval is not set to valid value (> 0)!"),
        must(sampled_dim, &SampledDimension::dimensionType, isEqual<DimensionType>(DimensionType::Sample), "dimension type is not correct!"),
        could(sampled_dim, &SampledDimension::offset, notFalse(), {
            should(sampled_dim, &SampledDimension::unit, isAtomicUnit(), "offset is set, but no valid unit set!") }),
        could(sampled_dim, &SampledDimension::unit, notFalse(), {
            must(sampled_dim, &SampledDimension::unit, isAtomicUnit(), "Unit is set but not an atomic SI. Note: So far composite units are not supported!") })
    });
}

Result validate(const SetDimension &set_dim) {
    return validator({
        must(set_dim, &SetDimension::index, notSmaller(1), "index is not set to valid value (size_t > 0)!"),
        must(set_dim, &SetDimension::dimensionType, isEqual<DimensionType>(DimensionType::Set), "dimension type is not correct!")
    });
}

Result validate(const Feature &feature) {
    Result result_base = validate_entity(feature);
    Result result = validator({
        must(feature, &Feature::data, notFalse(), "data is not set!"),
        must(feature, &Feature::linkType, notSmaller(0), "linkType is not set!")
    });

    return result.concat(result_base);
}

Result validate(const Section &section) {
    return validate_named_entity(section);
}

Result validate(const Source &source) {
    return validate_entity_with_metadata(source);
}

Result validate(const File &file) {
    return validator({
        could(file, &File::isOpen, notFalse(), {
            must(file, &File::createdAt, notFalse(), "date is not set!"),
            should(file, &File::version, notEmpty(), "version is not set!"),
            should(file, &File::format, notEmpty(), "format is not set!"),
            should(file, &File::location, notEmpty(), "location is not set!") })
    });
}

} // namespace valid
} // namespace nix
<commit_msg>[validate] the number of ticks **must** match the number of entries!<commit_after>// Copyright (c) 2014, German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.

#include <nix/valid/validator.hpp>
#include <nix/valid/checks.hpp>
#include <nix/valid/conditions.hpp>
#include <nix/valid/result.hpp>

#include <nix.hpp>

namespace nix {
namespace valid {

// ---------------------------------------------------------------------
// Templated, hidden validation utils that are only here in the cpp,
// not in the header (hides them from user)
// ---------------------------------------------------------------------

/**
  * @brief base entity validator
  *
  * Function taking a base entity and returning {@link Result} object
  *
  * @param entity base entity
  *
  * @returns The validation results as {@link Result} object
  */
template<typename T>
Result validate_entity(const base::Entity<T> &entity) {
    return validator({
        must(entity, &base::Entity<T>::id, notEmpty(), "id is not set!"),
        must(entity, &base::Entity<T>::createdAt, notFalse(), "date is not set!")
    });
}

/**
  * @brief base named entity validator
  *
  * Function taking a base named entity and returning {@link Result}
  * object
  *
  * @param named_entity base named entity
  *
  * @returns The validation results as {@link Result} object
  */
template<typename T>
Result validate_named_entity(const base::NamedEntity<T> &named_entity) {
    Result result_base = validate_entity<T>(named_entity);
    Result result = validator({
        must(named_entity, &base::NamedEntity<T>::name, notEmpty(), "no name set!"),
        must(named_entity, &base::NamedEntity<T>::type, notEmpty(), "no type set!")
    });

    return result.concat(result_base);
}

/**
  * @brief base entity with metadata validator
  *
  * Function taking a base entity with metadata and returning
  * {@link Result} object
  *
  * @param entity_with_metadata base entity with metadata
  *
  * @returns The validation results as {@link Result} object
  */
template<typename T>
Result validate_entity_with_metadata(const base::EntityWithMetadata<T> &entity_with_metadata) {
    return validate_named_entity<T>(entity_with_metadata);
}

/**
  * @brief base entity with sources validator
  *
  * Function taking a base entity with sources and returning
  * {@link Result} object
  *
  * @param entity_with_sources base entity with sources
  *
  * @returns The validation results as {@link Result} object
  */
template<typename T>
Result validate_entity_with_sources(const base::EntityWithSources<T> &entity_with_sources) {
    return validate_entity_with_metadata<T>(entity_with_sources);
}

// ---------------------------------------------------------------------
// Regular validaton utils split in header & cpp part
// ---------------------------------------------------------------------

Result validate(const Block &block) {
    return validate_entity_with_metadata(block);
}

Result validate(const DataArray &data_array) {
    Result result_base = validate_entity_with_sources(data_array);
    Result result = validator({
        must(data_array, &DataArray::dataType, notEqual<DataType>(DataType::Nothing), "data type is not set!"),
        must(data_array, &DataArray::dimensionCount, isEqual<size_t>(data_array.dataExtent().size()), "data dimensionality does not match number of defined dimensions!", {
            could(data_array, &DataArray::dimensions, notEmpty(), {
                must(data_array, &DataArray::dimensions, dimTicksMatchData(data_array), "in some of the Range dimensions the number of ticks differs from the number of data entries along the corresponding data dimension!"),
                must(data_array, &DataArray::dimensions, dimLabelsMatchData(data_array), "in some of the Set dimensions the number of labels differs from the number of data entries along the corresponding data dimension!") }) }),
        could(data_array, &DataArray::unit, notFalse(), {
            must(data_array, &DataArray::unit, isValidUnit(), "Unit is not SI or composite of SI units.") }),
        could(data_array, &DataArray::polynomCoefficients, notEmpty(), {
            should(data_array, &DataArray::expansionOrigin, notFalse(), "polynomial coefficients for calibration are set, but expansion origin is missing!") }),
        could(data_array, &DataArray::expansionOrigin, notFalse(), {
            should(data_array, &DataArray::polynomCoefficients, notEmpty(), "expansion origin for calibration is set, but polynomial coefficients are missing!") })
    });

    return result.concat(result_base);
}

Result validate(const Tag &tag) {
    Result result_base = validate_entity_with_sources(tag);
    Result result = validator({
        must(tag, &Tag::position, notEmpty(), "position is not set!"),
        could(tag, &Tag::references, notEmpty(), {
            must(tag, &Tag::position, positionsMatchRefs(tag.references()),
                "number of entries in position does not match number of dimensions in all referenced DataArrays!"),
            could(tag, &Tag::extent, notEmpty(), {
                must(tag, &Tag::extent, extentsMatchRefs(tag.references()),
                    "number of entries in extent does not match number of dimensions in all referenced DataArrays!") })
        }),
        // check units for validity
        could(tag, &Tag::units, notEmpty(), {
            must(tag, &Tag::units, isValidUnit(), "Unit is invalid: not an atomic SI. Note: So far composite units are not supported!"),
            must(tag, &Tag::references, tagRefsHaveUnits(tag.units()), "Some of the referenced DataArrays' dimensions don't have units where the tag has. Make sure that all references have the same number of dimensions as the tag has units and that each dimension has a unit set."),
                must(tag, &Tag::references, tagUnitsMatchRefsUnits(tag.units()), "Some of the referenced DataArrays' dimensions have units that are not convertible to the units set in tag. Note: So far composite SI units are not supported!")}),
        // check positions & extents
        could(tag, &Tag::extent, notEmpty(), {
            must(tag, &Tag::position, extentsMatchPositions(tag.extent()), "Number of entries in position and extent do not match!"),
            must(tag, &Tag::extent, extentsMatchRefs(tag.references()), "number of entries in extent does not match number of dimensions in all referenced DataArrays!") })
    });

    return result.concat(result_base);
}

Result validate(const Property &property) {
    Result result_base = validate_entity(property);
    Result result = validator({
        must(property, &Property::name, notEmpty(), "name is not set!"),
        could(property, &Property::valueCount, notFalse(), {
            should(property, &Property::unit, notFalse(), "values are set, but unit is missing!") }),
        could(property, &Property::unit, notFalse(), {
            must(property, &Property::unit, isValidUnit(), "Unit is not SI or composite of SI units.") })
        // TODO: dataType to be tested too?
    });

    return result.concat(result_base);
}

Result validate(const MultiTag &multi_tag) {
    Result result_base = validate_entity_with_sources(multi_tag);
    Result result = validator({
        must(multi_tag, &MultiTag::positions, notFalse(), "positions are not set!"),
        // since extents & positions DataArray stores a vector of position / extent vectors it has to be 2-dim
        could(multi_tag, &MultiTag::positions, notFalse(), {
            must(multi_tag, &MultiTag::positions, dimEquals(2), "dimensionality of positions DataArray must be two!") }),
        could(multi_tag, &MultiTag::extents, notFalse(), {
            must(multi_tag, &MultiTag::extents, dimEquals(2), "dimensionality of extents DataArray must be two!") }),
        // check units for validity
        could(multi_tag, &MultiTag::units, notEmpty(), {
            must(multi_tag, &MultiTag::units, isValidUnit(), "Some of the units in tag are invalid: not an atomic SI. Note: So far composite SI units are not supported!"),
            must(multi_tag, &MultiTag::references, tagUnitsMatchRefsUnits(multi_tag.units()), "Some of the referenced DataArrays' dimensions have units that are not convertible to the units set in tag. Note: So far composite SI units are not supported!")}),
        // check positions & extents
        could(multi_tag, &MultiTag::extents, notFalse(), {
            must(multi_tag, &MultiTag::positions, extentsMatchPositions(multi_tag.extents()), "Number of entries in positions and extents do not match!") }),
        could(multi_tag, &MultiTag::references, notEmpty(), {
            could(multi_tag, &MultiTag::extents, notFalse(), {
                must(multi_tag, &MultiTag::extents, extentsMatchRefs(multi_tag.references()), "number of entries (in 2nd dim) in extents does not match number of dimensions in all referenced DataArrays!") }),
            must(multi_tag, &MultiTag::positions, positionsMatchRefs(multi_tag.references()), "number of entries (in 2nd dim) in positions does not match number of dimensions in all referenced DataArrays!") })
    });

    return result.concat(result_base);
}

Result validate(const Dimension &dim) {
    return validator({
        must(dim, &Dimension::index, notSmaller(1), "index is not set to valid value (> 0)!")
    });
}

Result validate(const RangeDimension &range_dim) {
    return validator({
        must(range_dim, &RangeDimension::index, notSmaller(1), "index is not set to valid value (size_t > 0)!"),
        must(range_dim, &RangeDimension::ticks, notEmpty(), "ticks are not set!"),
        must(range_dim, &RangeDimension::dimensionType, isEqual<DimensionType>(DimensionType::Range), "dimension type is not correct!"),
        could(range_dim, &RangeDimension::unit, notFalse(), {
            must(range_dim, &RangeDimension::unit, isAtomicUnit(), "Unit is set but not an atomic SI. Note: So far composite units are not supported!") }),
        must(range_dim, &RangeDimension::ticks, isSorted(), "Ticks are not sorted!")
    });
}

Result validate(const SampledDimension &sampled_dim) {
    return validator({
        must(sampled_dim, &SampledDimension::index, notSmaller(1), "index is not set to valid value (size_t > 0)!"),
        must(sampled_dim, &SampledDimension::samplingInterval, isGreater(0), "samplingInterval is not set to valid value (> 0)!"),
        must(sampled_dim, &SampledDimension::dimensionType, isEqual<DimensionType>(DimensionType::Sample), "dimension type is not correct!"),
        could(sampled_dim, &SampledDimension::offset, notFalse(), {
            should(sampled_dim, &SampledDimension::unit, isAtomicUnit(), "offset is set, but no valid unit set!") }),
        could(sampled_dim, &SampledDimension::unit, notFalse(), {
            must(sampled_dim, &SampledDimension::unit, isAtomicUnit(), "Unit is set but not an atomic SI. Note: So far composite units are not supported!") })
    });
}

Result validate(const SetDimension &set_dim) {
    return validator({
        must(set_dim, &SetDimension::index, notSmaller(1), "index is not set to valid value (size_t > 0)!"),
        must(set_dim, &SetDimension::dimensionType, isEqual<DimensionType>(DimensionType::Set), "dimension type is not correct!")
    });
}

Result validate(const Feature &feature) {
    Result result_base = validate_entity(feature);
    Result result = validator({
        must(feature, &Feature::data, notFalse(), "data is not set!"),
        must(feature, &Feature::linkType, notSmaller(0), "linkType is not set!")
    });

    return result.concat(result_base);
}

Result validate(const Section &section) {
    return validate_named_entity(section);
}

Result validate(const Source &source) {
    return validate_entity_with_metadata(source);
}

Result validate(const File &file) {
    return validator({
        could(file, &File::isOpen, notFalse(), {
            must(file, &File::createdAt, notFalse(), "date is not set!"),
            should(file, &File::version, notEmpty(), "version is not set!"),
            should(file, &File::format, notEmpty(), "format is not set!"),
            should(file, &File::location, notEmpty(), "location is not set!") })
    });
}

} // namespace valid
} // namespace nix
<|endoftext|>


<commit_before>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium
team <http://www.bh107.org>.

Bohrium 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 3
of the License, or (at your option) any later version.

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

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/

#include <string>
#include <algorithm>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include <boost/property_tree/exceptions.hpp>
#include <boost/algorithm/string.hpp>
#include <cstdlib>
#include <dlfcn.h>
#include <limits.h>
#include <bh_config_parser.hpp>

#define HOME_INI_PATH "~/.bohrium/config.ini"
#define SYSTEM_INI_PATH_1 "/usr/local/etc/bohrium/config.ini"
#define SYSTEM_INI_PATH_2 "/usr/etc/bohrium/config.ini"

using namespace std;
using namespace boost;

namespace bohrium {

namespace {
// Path to the config file e.g. ~/.bohrium/config.ini
string get_config_path() {

    const char *homepath = HOME_INI_PATH;
    const char *syspath1 = SYSTEM_INI_PATH_1;
    const char *syspath2 = SYSTEM_INI_PATH_2;

    //
    // Find the configuration file
    //

    // Start by looking a path set via environment variable.
    const char *env = getenv("BH_CONFIG");
    if (env != NULL) {
        FILE *fp = fopen(env, "r");
        if (fp)
            fclose(fp);
        else
            env = NULL;//Did not exist.
    }

    // Then the home directory.
    if (env == NULL) {
#if _WIN32
        char _expand_buffer[MAX_PATH];
        DWORD result = ExpandEnvironmentStrings(
            homepath,
            _expand_buffer,
            MAX_PATH-1
        );

        if (result != 0)
        {
            homepath = _expand_buffer;
        }
#else
        char *h = getenv("HOME");
        if (h != NULL) {
            char _expand_buffer[PATH_MAX];
            snprintf(_expand_buffer, PATH_MAX, "%s/%s", h, homepath + 1);
            homepath = _expand_buffer;
        }
#endif
        FILE *fp = fopen(homepath, "r");
        if (fp) {
            env = homepath;
            fclose(fp);
        }
    }

    //And then system-wide.
    if (env == NULL) {
#if _WIN32
        char _expand_buffer[MAX_PATH];
        DWORD result = ExpandEnvironmentStrings(
            syspath1,
            _expand_buffer,
            MAX_PATH-1
        );

        if(result != 0)
        {
            syspath1 = _expand_buffer;
        }
#endif
        FILE *fp = fopen(syspath1, "r");
        if (fp) {
            env = syspath1;
            fclose(fp);
        }
    }

    //And then system-wide.
    if (env == NULL) {
#if _WIN32
        char _expand_buffer[MAX_PATH];
        DWORD result = ExpandEnvironmentStrings(
            syspath2,
            _expand_buffer,
            MAX_PATH-1
        );

        if(result != 0)
        {
            syspath2 = _expand_buffer;
        }
#endif
        FILE *fp = fopen(syspath2, "r");
        if (fp) {
            env = syspath2;
            fclose(fp);
        }
    }
    // We could not find the configuration file anywhere
    if (env == NULL) {
        fprintf(stderr, "Error: Bohrium could not find the config file.\n"
                        " The search is:\n"
                        "\t* The environment variable BH_CONFIG.\n"
                        "\t* The home directory \"%s\".\n"
                        "\t* The local directory \"%s\".\n"
                        "\t* And system-wide \"%s\".\n", homepath, syspath1, syspath2);
        throw invalid_argument("No config file");
    }
    return string(env);
}

// Return section/option as an environment variable
// or the empty string if the environment variable wasn't found
string lookup_env(const string &section, const string &option) {
    string s = "BH_" + section + "_" + option;
    to_upper(s);
    std::replace(s.begin(), s.end(), '-', '_'); // replace all '-' to '_'
    std::replace(s.begin(), s.end(), ' ', '_'); // replace all ' ' to '_'
    const char *env = getenv(s.c_str());

    if (env == NULL) {
        return string();
    } else {
        return string(env);
    }
}

}// namespace unnamed

string ConfigParser::lookup(const string &section, const string &option) const {
    //Check environment variable
    string ret = lookup_env(section, option);
    if (not ret.empty())
        return ret;

    //Check config file
    ret = _config.get<string>(section + "." + option);

    //Remove quotes "" or '' and return
    if (ret.find_first_of("\"'") == 0 and ret.find_last_of("\"'") == ret.size() - 1) {
        return ret.substr(1, ret.size() - 2);
    } else {
        return ret;
    }
}

ConfigParser::ConfigParser(int stack_level) : file_path(get_config_path()),
                                              file_dir(boost::filesystem::path(file_path).remove_filename()),
                                              stack_level(stack_level) {

    // Load the bohrium configuration file
    property_tree::ini_parser::read_ini(file_path.string(), _config);

    // Find the stack name specified by 'BH_STACK'
    const char *env = getenv("BH_STACK");
    string stack_name;
    if (env == nullptr) {
        stack_name = "default";
    } else {
        stack_name = env;
    }
    // Read stack, which is a comma separated list of component names,
    // into a vector of component names.
    _stack_list = getList("stacks", stack_name);
    if (stack_level >= static_cast<int>(_stack_list.size()) or stack_level < -1) {
        throw ConfigError("ConfigParser: stack level is out of bound");
    }
    if (stack_level == -1) {
        _default_section = "bridge";
    } else {
        _default_section = _stack_list[stack_level];
    }
}

boost::filesystem::path ConfigParser::expand(boost::filesystem::path path) const {
    if (path.empty())
        return path;

    string s = path.string();
    if (s[0] == '~') {
        const char *home = getenv("HOME");
        if (home == nullptr) {
            throw std::invalid_argument("Couldn't expand `~` since $HOME environment variable not set.");
        }
        return boost::filesystem::path(home) / boost::filesystem::path(s.substr(1));
    } else {
        return path;
    }
}

vector<string> ConfigParser::getList(const std::string &section,
                                     const std::string &option) const {
    vector<string> ret;
    string s = get<string>(section, option);
    algorithm::split(ret, s, is_any_of("\t, "), token_compress_on);
    return ret;
}

vector<boost::filesystem::path> ConfigParser::getListOfPaths(const std::string &section,
                                                             const std::string &option) const {
    vector<boost::filesystem::path> ret;
    for (const string &path_str: getList(section, option)) {
        const auto path = expand(boost::filesystem::path(path_str));
        if (path.is_absolute() or path.empty()) {
            ret.push_back(path);
        } else {
            ret.push_back(file_dir / path);
        }
    }
    return ret;
}

string ConfigParser::getChildLibraryPath() const {
    // Do we have a child?
    if (static_cast<int>(_stack_list.size()) <= stack_level + 1) {
        return string();
    }
    // Our child is our stack level plus one
    const string child_name = _stack_list[stack_level + 1];
    return get<boost::filesystem::path>(child_name, "impl").string();
}

} //namespace bohrium
<commit_msg>config parser: clean up<commit_after>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium
team <http://www.bh107.org>.

Bohrium 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 3
of the License, or (at your option) any later version.

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

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/

#include <string>
#include <algorithm>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include <boost/property_tree/exceptions.hpp>
#include <boost/algorithm/string.hpp>
#include <cstdlib>
#include <dlfcn.h>
#include <limits.h>
#include <bh_config_parser.hpp>

#define HOME_INI_PATH "~/.bohrium/config.ini"
#define SYSTEM_INI_PATH_1 "/usr/local/etc/bohrium/config.ini"
#define SYSTEM_INI_PATH_2 "/usr/etc/bohrium/config.ini"

using namespace std;
using namespace boost;

namespace bohrium {

namespace {
/// Path to the config file e.g. ~/.bohrium/config.ini
string get_config_path() {

    const char *homepath = HOME_INI_PATH;
    const char *syspath1 = SYSTEM_INI_PATH_1;
    const char *syspath2 = SYSTEM_INI_PATH_2;

    //
    // Find the configuration file
    //

    // Start by looking a path set via environment variable.
    const char *env = getenv("BH_CONFIG");
    if (env != nullptr) {
        FILE *fp = fopen(env, "r");
        if (fp)
            fclose(fp);
        else
            env = nullptr;//Did not exist.
    }

    // Then the home directory.
    if (env == nullptr) {
#if _WIN32
        char _expand_buffer[MAX_PATH];
        DWORD result = ExpandEnvironmentStrings(
            homepath,
            _expand_buffer,
            MAX_PATH-1
        );

        if (result != 0)
        {
            homepath = _expand_buffer;
        }
#else
        char *h = getenv("HOME");
        if (h != nullptr) {
            char _expand_buffer[PATH_MAX];
            snprintf(_expand_buffer, PATH_MAX, "%s/%s", h, homepath + 1);
            homepath = _expand_buffer;
        }
#endif
        FILE *fp = fopen(homepath, "r");
        if (fp) {
            env = homepath;
            fclose(fp);
        }
    }

    //And then system-wide.
    if (env == nullptr) {
#if _WIN32
        char _expand_buffer[MAX_PATH];
        DWORD result = ExpandEnvironmentStrings(
            syspath1,
            _expand_buffer,
            MAX_PATH-1
        );

        if(result != 0)
        {
            syspath1 = _expand_buffer;
        }
#endif
        FILE *fp = fopen(syspath1, "r");
        if (fp) {
            env = syspath1;
            fclose(fp);
        }
    }

    //And then system-wide.
    if (env == nullptr) {
#if _WIN32
        char _expand_buffer[MAX_PATH];
        DWORD result = ExpandEnvironmentStrings(
            syspath2,
            _expand_buffer,
            MAX_PATH-1
        );

        if(result != 0)
        {
            syspath2 = _expand_buffer;
        }
#endif
        FILE *fp = fopen(syspath2, "r");
        if (fp) {
            env = syspath2;
            fclose(fp);
        }
    }
    // We could not find the configuration file anywhere
    if (env == nullptr) {
        fprintf(stderr, "Error: Bohrium could not find the config file.\n"
                        " The search is:\n"
                        "\t* The environment variable BH_CONFIG.\n"
                        "\t* The home directory \"%s\".\n"
                        "\t* The local directory \"%s\".\n"
                        "\t* And system-wide \"%s\".\n", homepath, syspath1, syspath2);
        throw invalid_argument("No config file");
    }
    return string(env);
}

/// Return section/option as an environment variable
/// or the empty string if the environment variable wasn't found
string lookup_env(const string &section, const string &option) {
    string s = "BH_" + section + "_" + option;
    to_upper(s);
    std::replace(s.begin(), s.end(), '-', '_'); // replace all '-' to '_'
    std::replace(s.begin(), s.end(), ' ', '_'); // replace all ' ' to '_'
    const char *env = getenv(s.c_str());

    if (env == nullptr) {
        return string();
    } else {
        return string(env);
    }
}

}// namespace unnamed

string ConfigParser::lookup(const string &section, const string &option) const {
    //Check environment variable
    string ret = lookup_env(section, option);
    if (not ret.empty())
        return ret;

    //Check config file
    ret = _config.get<string>(section + "." + option);

    //Remove quotes "" or '' and return
    if (ret.find_first_of("\"'") == 0 and ret.find_last_of("\"'") == ret.size() - 1) {
        return ret.substr(1, ret.size() - 2);
    } else {
        return ret;
    }
}

ConfigParser::ConfigParser(int stack_level) : file_path(get_config_path()),
                                              file_dir(boost::filesystem::path(file_path).remove_filename()),
                                              stack_level(stack_level) {

    // Load the bohrium configuration file
    property_tree::ini_parser::read_ini(file_path.string(), _config);

    // Find the stack name specified by 'BH_STACK'
    const char *env = getenv("BH_STACK");
    string stack_name;
    if (env == nullptr) {
        stack_name = "default";
    } else {
        stack_name = env;
    }
    // Read stack, which is a comma separated list of component names,
    // into a vector of component names.
    _stack_list = getList("stacks", stack_name);
    if (stack_level >= static_cast<int>(_stack_list.size()) or stack_level < -1) {
        throw ConfigError("ConfigParser: stack level is out of bound");
    }
    if (stack_level == -1) {
        _default_section = "bridge";
    } else {
        _default_section = _stack_list[stack_level];
    }
}

boost::filesystem::path ConfigParser::expand(boost::filesystem::path path) const {
    if (path.empty())
        return path;

    string s = path.string();
    if (s[0] == '~') {
        const char *home = getenv("HOME");
        if (home == nullptr) {
            throw std::invalid_argument("Couldn't expand `~` since $HOME environment variable not set.");
        }
        return boost::filesystem::path(home) / boost::filesystem::path(s.substr(1));
    } else {
        return path;
    }
}

vector<string> ConfigParser::getList(const std::string &section,
                                     const std::string &option) const {
    vector<string> ret;
    string s = get<string>(section, option);
    algorithm::split(ret, s, is_any_of("\t, "), token_compress_on);
    return ret;
}

vector<boost::filesystem::path> ConfigParser::getListOfPaths(const std::string &section,
                                                             const std::string &option) const {
    vector<boost::filesystem::path> ret;
    for (const string &path_str: getList(section, option)) {
        const auto path = expand(boost::filesystem::path(path_str));
        if (path.is_absolute() or path.empty()) {
            ret.push_back(path);
        } else {
            ret.push_back(file_dir / path);
        }
    }
    return ret;
}

string ConfigParser::getChildLibraryPath() const {
    // Do we have a child?
    if (static_cast<int>(_stack_list.size()) <= stack_level + 1) {
        return string();
    }
    // Our child is our stack level plus one
    const string child_name = _stack_list[stack_level + 1];
    return get<boost::filesystem::path>(child_name, "impl").string();
}

} //namespace bohrium
<|endoftext|>