<commit_before>#ifdef _MSC_VER
#ifdef GEOS_DEBUG_MSVC_USE_VLD
#include <vld.h>
#endif
#endif

// TUT
#include <tut.h>
#include <tut_reporter.h>
// STL
#include <iostream>
// GEOS
#include <geos/unload.h>

namespace tut
{
    test_runner_singleton runner;
}

void usage()
{
    std::cout << "Usage: <geos_tut> [list] | [ group] [test]" << std::endl;
    std::cout << "       List all groups: geos_unit list" << std::endl;
    std::cout << "       Run all tests: geos_unit" << std::endl;
    std::cout << "       Run one group: geos_unit <group name>" << std::endl;
    std::cout << "       Run one test: geos_unit <group name> 3" << std::endl;
    std::cout << "\nGEOS homepage: http://geos.refractions.net" << std::endl;

}

int main(int argc,const char* argv[])
{
    tut::reporter visi;

    std::cout << "===========================\n"
			  << "GEOS Test Suite Application\n"
			  << "===========================\n";

    if ( (argc == 2 && std::string(argv[1]) == "--help") || argc > 3 )
    {
        usage();
        return 0;
    }

    tut::runner.get().set_callback(&visi);

    try
    {
        if ( argc == 1 )
        {
            tut::runner.get().run_tests();
        }
        else if ( argc == 2 && std::string(argv[1]) == "list" )
        {
            tut::groupnames gl = tut::runner.get().list_groups();
            tut::groupnames::const_iterator b = gl.begin();
            tut::groupnames::const_iterator e = gl.end();

            tut::groupnames::difference_type d = std::distance(b, e);

            std::cout << "Registered " << d << " test groups:\n" << std::endl;

            while ( b != e )
            {
                std::cout << "  " << *b << std::endl;
                ++b;
            }
        }
        else if ( argc == 2 && std::string(argv[1]) != "list" )
        {
            tut::runner.get().run_tests(argv[1]);
        }
        else if( argc == 3 )
        {
            // TODO - mloskot - check if test group with given name exists
            // TODO - mloskot - check if test case with given number exists

            tut::runner.get().run_test(argv[1], ::atoi(argv[2]));
        }
    }
    catch( const std::exception& ex )
    {
        std::cerr << "!!! GEOS Test Suite raised exception: " << ex.what() << std::endl;
    }

    // XXX - mloskot - this should be removed in future!
    geos::io::Unload::Release();
    return 0;
}
<commit_msg>New version of Unit Test runner. Now, it's more GNU style compatible<commit_after>#ifdef _MSC_VER
#ifdef GEOS_DEBUG_MSVC_USE_VLD
#include <vld.h>
#endif
#endif

// TUT
#include <tut.h>
#include <tut_reporter.h>
// STL
#include <iostream>
#include <iomanip>
// GEOS
#include <geos/unload.h>

namespace tut
{
    test_runner_singleton runner;
}

void usage()
{
	using std::cout;
	using std::endl;

	const std::string module("geos_unit");

	//[list] | [ group] [test]
	cout << "Usage: " << module << " [OPTION] [TARGET]\n"
		<< endl
		<< "Targets:\n"
		<< "  <none>                          run all tests in all groups\n"
		<< "  <group name>                    run all tests from given group\n"
		<< "  <group name> <test nr>          run single test with given number from given group\n"
		<< endl
		<< "Options:\n"
		<< "  --list                          list all registered test groups\n"
		<< "  --verbose                       run unit tests verbosely; displays non-error information\n"
		<< "  --version                       print version information and exit\n"
		<< "  --help                          print this message and exit\n"
		<< endl
		<< "Examples:\n"
		<< "  " << module << " -v\n"
		<< "  " << module << " list\n"
		<< "  " << module << " geos::geom::Envelope\n"
		<< "  " << module << " geos::geom::Envelope 2\n"
		<< endl
		<< "GEOS homepage: http://geos.refractions.net" << endl;
}

int main(int argc, const char* argv[])
{
    tut::reporter visi;

    if ( (argc == 2 && std::string(argv[1]) == "--help") || argc > 3 )
    {
        usage();
        return 0;
    }

    std::cout << "===============================\n"
			  << "  GEOS Test Suite Application\n"
			  << "===============================\n";

    tut::runner.get().set_callback(&visi);

    try
    {
        if ( argc == 1 )
        {
            tut::runner.get().run_tests();
        }
        else if ( argc == 2 && std::string(argv[1]) == "--list" )
        {
            tut::groupnames gl = tut::runner.get().list_groups();
            tut::groupnames::const_iterator b = gl.begin();
            tut::groupnames::const_iterator e = gl.end();

            tut::groupnames::difference_type d = std::distance(b, e);

            std::cout << "Registered " << d << " test groups:\n" << std::endl;

            while ( b != e )
            {
                std::cout << "  " << *b << std::endl;
                ++b;
            }
        }
        else if ( argc == 2 && std::string(argv[1]) != "--list" )
        {
            tut::runner.get().run_tests(argv[1]);
        }
        else if( argc == 3 )
        {
            // TODO - mloskot - check if test group with given name exists
            // TODO - mloskot - check if test case with given number exists

            tut::runner.get().run_test(argv[1], ::atoi(argv[2]));
        }
    }
    catch( const std::exception& ex )
    {
        std::cerr << "!!! GEOS Test Suite raised exception: " << ex.what() << std::endl;
    }

    // XXX - mloskot - this should be removed in future!
    geos::io::Unload::Release();
    return 0;
}
<|endoftext|>


<commit_before>/**
 * @file		driver.cpp
 * @brief		Component driver
 * @author		Byunghun Hwang<bhhwang@nsynapse.com>
 * @date 		2015. 6. 21
 * @details	Load components with driver
 */

#include "driver.hpp"
#include <dlfcn.h>

namespace cossb {
namespace driver {

component_driver::component_driver(const char* component_name)
:_component_name(component_name)
{
	if(load(component_name))
	{
		string profile_path = "./"+string(component_name)+".xml";
		if(!_ptr_component->set_profile(new profile::xmlprofile, profile_path.c_str()))
			unload();
	}
}

component_driver::~component_driver()
{
	unload();
}

bool component_driver::load(const char* component_name)
{
	string comp_path = "./"+string(component_name);

	_handle = dlopen(comp_path.c_str(), RTLD_LAZY|RTLD_GLOBAL);

	if(!_handle)
		return false;
	else
	{
		create_component pfcreate = (create_component)dlsym(_handle, "create");
		if(!pfcreate)
		{

			dlclose(_handle);
			_handle = nullptr;

			return false;
		}
		else
		{
			_ptr_component = pfcreate();
			return true;
		}
	}
}

void component_driver::unload()
{
	if(_ptr_component)
	{
		string comp_name = _ptr_component->get_name();

		destroy_component pfdestroy = (destroy_component)dlsym(_handle, "destroy");

		if(pfdestroy)
			pfdestroy();

		_ptr_component = nullptr;
	}

	if(_handle)
	{
		dlclose(_handle);
		_handle = nullptr;
	}
}

} /* namespace dirver */
} /* namespace cossb */
<commit_msg>add function for simple drive<commit_after>/**
 * @file		driver.cpp
 * @brief		Component driver
 * @author		Byunghun Hwang<bhhwang@nsynapse.com>
 * @date 		2015. 6. 21
 * @details	Load components with driver
 */

#include "driver.hpp"
#include <dlfcn.h>
#include "xmlprofile.hpp"

namespace cossb {
namespace driver {

component_driver::component_driver(const char* component_name)
:_component_name(component_name)
{
	if(load(component_name))
	{
		string profile_path = "./"+string(component_name)+".xml";
		if(!_ptr_component->set_profile(new profile::xmlprofile, profile_path.c_str()))
			unload();
	}
}

component_driver::~component_driver()
{
	unload();
}

bool component_driver::load(const char* component_name)
{
	string component_path = "./"+string(component_name);

	_handle = dlopen(component_path.c_str(), RTLD_LAZY|RTLD_GLOBAL);

	if(_handle)
	{
		create_component pfcreate = (create_component)dlsym(_handle, "create");
		if(!pfcreate)
		{
			dlclose(_handle);
			_handle = nullptr;

			return false;
		}
		else
		{
			_ptr_component = pfcreate();
			return true;
		}
	}

	return false;
}

void component_driver::unload()
{
	if(_ptr_component)
	{
		destroy_component pfdestroy = (destroy_component)dlsym(_handle, "destroy");

		if(pfdestroy)
			pfdestroy();

		_ptr_component = nullptr;
	}

	if(_handle)
	{
		dlclose(_handle);
		_handle = nullptr;
	}
}

void component_driver::run()
{
	if(_ptr_component)
	{
		_ptr_component->run();
	}
}

void component_driver::stop()
{
	if(_ptr_component)
	{
		_ptr_component->stop();
	}
}

} /* namespace dirver */
} /* namespace cossb */
<|endoftext|>


<commit_before>/********** tell emacs we use -*- c++ -*- style comments *******************
 $Revision: 1.1 $  $Author: trey $  $Date: 2007-03-23 00:25:55 $

 @file    MDPExec.cc
 @brief   No brief

 Copyright (c) 2006, Trey Smith. All rights reserved.

 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.

 ***************************************************************************/

/***************************************************************************
 * INCLUDES
 ***************************************************************************/

#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <getopt.h>

#include <iostream>

#include "MatrixUtils.h"
#include "BoundPairExec.h"
#include "zmdpMainConfig.h"

#include "zmdpMainConfig.cc" // embed default config file

using namespace std;
using namespace zmdp;

void doit(const char* modelFileName,
	  bool useFastModelParser,
	  const char* policyFileName)
{
  // seeds random number generator
  MatrixUtils::init_matrix_utils();

  ZMDPConfig* config = new ZMDPConfig();
  config->readFromString("<defaultConfig>", defaultConfig.data);

  BoundPairExec* em = new BoundPairExec();
  printf("initializing\n");
  em->initMaxPlanes(modelFileName, useFastModelParser, policyFileName, *config);

  MDPExec* e = em;

  for (int i=0; i < 3; i++) {
    printf("new simulation run\n");
    e->setToInitialState();
    printf("  reset to initial belief\n");
    while (1) {
      int a = e->chooseAction();
      printf("  chose action %d\n", a);
      int o = e->getRandomOutcome(a);
      printf("  simulated seeing random observation %d\n", o);
      e->advanceToNextState(a,o);
      printf("  updated belief\n");
      if (e->getStateIsTerminal()) {
	printf("  belief is terminal, ending run\n");
	break;
      }
    }
  }
}

void usage(const char* binaryName)
{
  cerr <<
    "usage: " << binaryName << " OPTIONS <foo.pomdp> <out.policy>\n"
    "  -h or --help   Display this help\n"
    "  -f or --fast   Use fast (but very picky) alternate model parser\n";
  exit(EXIT_FAILURE);
}

int main(int argc, char *argv[])
{
  static char shortOptions[] = "hf";
  static struct option longOptions[]={
    {"help",          0,NULL,'h'},
    {"fast",          0,NULL,'f'},
    {NULL,0,0,0}
  };

  bool useFastModelParser = false;
  while (1) {
    char optchar = getopt_long(argc,argv,shortOptions,longOptions,NULL);
    if (optchar == -1) break;

    switch (optchar) {
    case 'h': // help
      usage(argv[0]);
      break;

    case 'f': // help
      useFastModelParser = true;
      break;

    case '?': // unknown option
    case ':': // option with missing parameter
      // getopt() prints an informative error message
      cerr << endl;
      usage(argv[0]);
      break;
    default:
      abort(); // never reach this point
    }
  }
  if (2 != argc-optind) {
    cerr << "ERROR: wrong number of arguments (should be 2)" << endl << endl;
    usage(argv[0]);
  }

  const char* modelFileName = argv[optind++];
  const char* policyFileName = argv[optind++];

  doit(modelFileName, useFastModelParser, policyFileName);
}

/***************************************************************************
 * REVISION HISTORY:
 * $Log: not supported by cvs2svn $
 * Revision 1.4  2007/03/23 00:01:04  trey
 * fixed to reflect migration from PomdpExec to MDPExec base class
 *
 * Revision 1.3  2006/11/08 16:40:15  trey
 * renamed useFastParser to useFastModelParser
 *
 * Revision 1.2  2006/06/27 18:20:18  trey
 * turned PomdpExec into an abstract class; most of the original implementation is now in the derived class MaxPlanesLowerBoundExec
 *
 * Revision 1.1  2006/06/24 16:25:28  trey
 * initial check-in
 *
 *
 ***************************************************************************/
<commit_msg>brought testMDPExec up to date with new BoundPairExec interface<commit_after>/********** tell emacs we use -*- c++ -*- style comments *******************
 $Revision: 1.2 $  $Author: trey $  $Date: 2007-04-19 22:08:55 $

 @file    MDPExec.cc
 @brief   No brief

 Copyright (c) 2006, Trey Smith. All rights reserved.

 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.

 ***************************************************************************/

/***************************************************************************
 * INCLUDES
 ***************************************************************************/

#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <getopt.h>

#include <iostream>

#include "MatrixUtils.h"
#include "BoundPairExec.h"
#include "zmdpMainConfig.h"

#include "zmdpMainConfig.cc" // embed default config file

using namespace std;
using namespace zmdp;

void doit(const char* modelFileName,
	  bool useFastModelParser,
	  const char* policyFileName)
{
  // seeds random number generator
  MatrixUtils::init_matrix_utils();

  ZMDPConfig* config = new ZMDPConfig();
  config->readFromString("<defaultConfig>", defaultConfig.data);

  BoundPairExec* em = new BoundPairExec();
  printf("initializing\n");
  em->initReadFiles(modelFileName, policyFileName, *config);

  MDPExec* e = em;

  for (int i=0; i < 3; i++) {
    printf("new simulation run\n");
    e->setToInitialState();
    printf("  reset to initial belief\n");
    while (1) {
      int a = e->chooseAction();
      printf("  chose action %d\n", a);
      int o = e->getRandomOutcome(a);
      printf("  simulated seeing random observation %d\n", o);
      e->advanceToNextState(a,o);
      printf("  updated belief\n");
      if (e->getStateIsTerminal()) {
	printf("  belief is terminal, ending run\n");
	break;
      }
    }
  }
}

void usage(const char* binaryName)
{
  cerr <<
    "usage: " << binaryName << " OPTIONS <foo.pomdp> <out.policy>\n"
    "  -h or --help   Display this help\n"
    "  -f or --fast   Use fast (but very picky) alternate model parser\n";
  exit(EXIT_FAILURE);
}

int main(int argc, char *argv[])
{
  static char shortOptions[] = "hf";
  static struct option longOptions[]={
    {"help",          0,NULL,'h'},
    {"fast",          0,NULL,'f'},
    {NULL,0,0,0}
  };

  bool useFastModelParser = false;
  while (1) {
    char optchar = getopt_long(argc,argv,shortOptions,longOptions,NULL);
    if (optchar == -1) break;

    switch (optchar) {
    case 'h': // help
      usage(argv[0]);
      break;

    case 'f': // help
      useFastModelParser = true;
      break;

    case '?': // unknown option
    case ':': // option with missing parameter
      // getopt() prints an informative error message
      cerr << endl;
      usage(argv[0]);
      break;
    default:
      abort(); // never reach this point
    }
  }
  if (2 != argc-optind) {
    cerr << "ERROR: wrong number of arguments (should be 2)" << endl << endl;
    usage(argv[0]);
  }

  const char* modelFileName = argv[optind++];
  const char* policyFileName = argv[optind++];

  doit(modelFileName, useFastModelParser, policyFileName);
}

/***************************************************************************
 * REVISION HISTORY:
 * $Log: not supported by cvs2svn $
 * Revision 1.1  2007/03/23 00:25:55  trey
 * renamed testPomdpExec to testMDPExec
 *
 * Revision 1.4  2007/03/23 00:01:04  trey
 * fixed to reflect migration from PomdpExec to MDPExec base class
 *
 * Revision 1.3  2006/11/08 16:40:15  trey
 * renamed useFastParser to useFastModelParser
 *
 * Revision 1.2  2006/06/27 18:20:18  trey
 * turned PomdpExec into an abstract class; most of the original implementation is now in the derived class MaxPlanesLowerBoundExec
 *
 * Revision 1.1  2006/06/24 16:25:28  trey
 * initial check-in
 *
 *
 ***************************************************************************/
<|endoftext|>


<commit_before>/*
The OpenTRV project licenses this file to you
under the Apache Licence, Version 2.0 (the "Licence");
you may not use this file except in compliance
with the Licence. You may obtain a copy of the Licence at

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

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

Author(s) / Copyright (s): Damon Hart-Davis 2016
*/

/*
 * OTRadValve ModelledRadValve tests.
 */

#include <stdint.h>
#include <gtest/gtest.h>
#include <OTV0p2Base.h>
#include "OTRadValve_ModelledRadValve.h"

// Test for general sanity of computation of desired valve position.
// In particular test the logic in ModelledRadValveState for starting from extreme positions.
// Adapted 2016/10/16 from test_VALVEMODEL.ino testMRVSExtremes().
TEST(ModelledRadValve,MRVSExtremes)
{
    // If true then be more verbose.
    const static bool verbose = false;

    // Test that if the real temperature is zero
    // and the initial valve position is anything less than 100%
    // that after one tick (with mainly defaults)
    // that the valve is being opened (and more than glacially),
    // ie that when below any possible legal target FROST/WARM/BAKE temperature the valve will open monotonically,
    // and also test that the fully-open state is reached in a bounded number of ticks ie bounded time.
    static const int maxFullTravelMins = 25;
    if(verbose) { fprintf(stderr, "open...\n"); }
    OTRadValve::ModelledRadValveInputState is0(0);
    is0.targetTempC = OTV0P2BASE::randRNG8NextBoolean() ? 5 : 25;
    OTRadValve::ModelledRadValveState rs0;
    const uint8_t valvePCOpenInitial0 = OTV0P2BASE::randRNG8() % 100;
    volatile uint8_t valvePCOpen = valvePCOpenInitial0;
    for(int i = maxFullTravelMins; --i >= 0; ) // Must fully open in reasonable time.
        {
        // Simulates one minute on each iteration.
        // Futz some input parameters that should not matter.
        is0.widenDeadband = OTV0P2BASE::randRNG8NextBoolean();
        is0.hasEcoBias = OTV0P2BASE::randRNG8NextBoolean();
        const uint8_t oldValvePos = valvePCOpen;
        rs0.tick(valvePCOpen, is0);
        const uint8_t newValvePos = valvePCOpen;
        ASSERT_TRUE(newValvePos > 0);
        ASSERT_TRUE(newValvePos <= 100);
        ASSERT_TRUE(newValvePos > oldValvePos);
        if(oldValvePos < is0.minPCOpen) { ASSERT_TRUE(is0.minPCOpen <= newValvePos); } // Should open to at least minimum-really-open-% on first step.
        ASSERT_TRUE(rs0.valveMoved == (oldValvePos != newValvePos));
        if(100 == newValvePos) { break; }
        }
    ASSERT_EQ(100, valvePCOpen);
    ASSERT_EQ(100 - valvePCOpenInitial0, rs0.cumulativeMovementPC);
    // Equally test that if the temperature is much higher than any legit target
    // the valve will monotonically close to 0% in bounded time.
    // Check for superficially correct linger behaviour:
    //   * minPCOpen-1 % must be hit (lingering close) if starting anywhere above that.
    //   * Once in linger all reductions should be by 1% until possible final jump to 0.
    //   * Check that linger was long enough (if linger threshold is higher enough to allow it).
    // Also check for some correct initialisation and 'velocity'/smoothing behaviour.
    if(verbose) { fprintf(stderr, "close...\n"); }
    OTRadValve::ModelledRadValveInputState is1(100<<4);
    is1.targetTempC = OTV0P2BASE::randRNG8NextBoolean() ? 5 : 25;
    OTRadValve::ModelledRadValveState rs1;
    ASSERT_TRUE(!rs1.initialised); // Initialisation not yet complete.
    const uint8_t valvePCOpenInitial1 = 1 + (OTV0P2BASE::randRNG8() % 100);
    valvePCOpen = valvePCOpenInitial1;
    const bool lookForLinger = (valvePCOpenInitial1 >= is1.minPCOpen);
    bool hitLinger = false; // True if the linger value was hit.
    uint8_t lingerMins = 0; // Approx mins spent in linger.
    for(int i = maxFullTravelMins; --i >= 0; ) // Must fully close in reasonable time.
        {
        // Simulates one minute on each iteration.
        // Futz some input parameters that should not matter.
        is1.widenDeadband = OTV0P2BASE::randRNG8NextBoolean();
        is1.hasEcoBias = OTV0P2BASE::randRNG8NextBoolean();
        const uint8_t oldValvePos = valvePCOpen;
        rs1.tick(valvePCOpen, is1);
        const uint8_t newValvePos = valvePCOpen;
        ASSERT_TRUE(rs1.initialised); // Initialisation must have completed.
        ASSERT_TRUE(newValvePos < 100);
        //    AssertIsTrue(newValvePos >= 0);
        ASSERT_TRUE(newValvePos < oldValvePos);
        if(hitLinger) { ++lingerMins; }
        if(hitLinger && (0 != newValvePos)) { ASSERT_EQ(oldValvePos - 1, newValvePos); }
        if(newValvePos == is1.minPCOpen-1) { hitLinger = true; }
        ASSERT_TRUE(rs1.valveMoved == (oldValvePos != newValvePos));
        if(0 == newValvePos) { break; }
        }
    ASSERT_EQ(0, valvePCOpen);
    ASSERT_EQ(valvePCOpenInitial1, rs1.cumulativeMovementPC);
    ASSERT_TRUE(hitLinger == lookForLinger);
    if(lookForLinger) { ASSERT_TRUE(lingerMins >= OTV0P2BASE::fnmin(is1.minPCOpen, OTRadValve::DEFAULT_MAX_RUN_ON_TIME_M)); }
    // Filtering should not have been engaged and velocity should be zero (temperature is flat).
    for(int i = OTRadValve::ModelledRadValveState::filterLength; --i >= 0; ) { ASSERT_EQ(100<<4, rs1.prevRawTempC16[i]); }
    ASSERT_EQ(100<<4, rs1.getSmoothedRecent());
    //  AssertIsEqual(0, rs1.getVelocityC16PerTick());
    ASSERT_TRUE(!rs1.isFiltering);
    // Some tests of basic velocity computation.
    //  ModelledRadValveState rs2;
    //  // Test with steady rising/falling value.
    //  const int step2C16 = (randRNG8() & 0x1f) - 16;
    //V0P2BASE_DEBUG_SERIAL_PRINT(step2C16);
    //V0P2BASE_DEBUG_SERIAL_PRINTLN();
    //  const int base2C16 = (FROST + (randRNG8() % (WARM - FROST))) << 16;
    //  rs2.prevRawTempC16[0] = base2C16;
    //  for(int i = 1; i < ModelledRadValveState::filterLength; ++i)
    //    { rs2.prevRawTempC16[i] = rs2.prevRawTempC16[i-1] - step2C16; }
    ////V0P2BASE_DEBUG_SERIAL_PRINT(rs2.getVelocityC16PerTick());
    ////V0P2BASE_DEBUG_SERIAL_PRINTLN();
    //  AssertIsEqualWithDelta(step2C16, rs2.getVelocityC16PerTick(), 2);
    // Test that soft setback works as expected to support dark-based quick setback.
    // ENERGY SAVING RULE TEST (TODO-442 2a: "Setback in WARM mode must happen in dark (quick response) or long vacant room.")
    // ENERGY SAVING RULE TEST (TODO-442 2a: "Setback in WARM mode must happen in dark (quick response) or long vacant room.")
    OTRadValve::ModelledRadValveInputState is3(100<<4);
    is3.targetTempC = 25;
    // Try a range of (whole-degree) offsets...
    for(int offset = -2; offset <= +2; ++offset)
        {
        // Try soft setback off and on.
        for(int s = 0; s < 2; ++s)
            {
            // Other than in the proportional range, valve should unconditionally be driven off/on by gross temperature error.
            if(0 != offset)
                {
                is3.refTempC16 = (is3.targetTempC + offset) << 4;
                // Where adjusted reference temperature is (well) below target, valve should be driven on.
                OTRadValve::ModelledRadValveState rs3a;
                valvePCOpen = 0;
                rs3a.tick(valvePCOpen, is3);
                //V0P2BASE_DEBUG_SERIAL_PRINT('@');
                //V0P2BASE_DEBUG_SERIAL_PRINT(offset);
                //V0P2BASE_DEBUG_SERIAL_PRINT(' ');
                //V0P2BASE_DEBUG_SERIAL_PRINT(valvePCOpen);
                //V0P2BASE_DEBUG_SERIAL_PRINTLN();
                ASSERT_TRUE((offset < 0) ? (valvePCOpen > 0) : (0 == valvePCOpen));
                // Where adjusted reference temperature is (well) above target, valve should be driven off.
                OTRadValve::ModelledRadValveState rs3b;
                valvePCOpen = 100;
                rs3b.tick(valvePCOpen, is3);
                ASSERT_TRUE((offset < 0) ? (100 == valvePCOpen) : (valvePCOpen < 100));
                }
            else
                {
                // Below the half way mark the valve should always be opened (from off), soft setback or not.
                is3.refTempC16 = (is3.targetTempC << 4) + 0x4;
                OTRadValve::ModelledRadValveState rs3c;
                valvePCOpen = 0;
                rs3c.tick(valvePCOpen, is3);
                ASSERT_TRUE(valvePCOpen > 0);
                // Above the half way mark the valve should only be opened without soft setback.
                is3.refTempC16 = (is3.targetTempC << 4) + 0xc;
                OTRadValve::ModelledRadValveState rs3d;
                valvePCOpen = 0;
                rs3d.tick(valvePCOpen, is3);
                ASSERT_TRUE(0 == valvePCOpen);
                }
            }
        }
}
<commit_msg>TODO-1003: tidyup<commit_after>/*
The OpenTRV project licenses this file to you
under the Apache Licence, Version 2.0 (the "Licence");
you may not use this file except in compliance
with the Licence. You may obtain a copy of the Licence at

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

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

Author(s) / Copyright (s): Damon Hart-Davis 2016
*/

/*
 * OTRadValve ModelledRadValve tests.
 */

#include <gtest/gtest.h>
#include <OTRadValve_ModelledRadValve.h>
#include <OTV0P2BASE_QuickPRNG.h>
#include <OTV0P2BASE_Util.h>
#include <cstdint>
#include <cstdio>

// Test for general sanity of computation of desired valve position.
// In particular test the logic in ModelledRadValveState for starting from extreme positions.
// Adapted 2016/10/16 from test_VALVEMODEL.ino testMRVSExtremes().
TEST(ModelledRadValve,MRVSExtremes)
{
    // If true then be more verbose.
    const static bool verbose = false;

    // Test that if the real temperature is zero
    // and the initial valve position is anything less than 100%
    // that after one tick (with mainly defaults)
    // that the valve is being opened (and more than glacially),
    // ie that when below any possible legal target FROST/WARM/BAKE temperature the valve will open monotonically,
    // and also test that the fully-open state is reached in a bounded number of ticks ie bounded time.
    static const int maxFullTravelMins = 25;
    if(verbose) { fprintf(stderr, "open...\n"); }
    OTRadValve::ModelledRadValveInputState is0(0);
    is0.targetTempC = OTV0P2BASE::randRNG8NextBoolean() ? 5 : 25;
    OTRadValve::ModelledRadValveState rs0;
    const uint8_t valvePCOpenInitial0 = OTV0P2BASE::randRNG8() % 100;
    volatile uint8_t valvePCOpen = valvePCOpenInitial0;
    for(int i = maxFullTravelMins; --i >= 0; ) // Must fully open in reasonable time.
        {
        // Simulates one minute on each iteration.
        // Futz some input parameters that should not matter.
        is0.widenDeadband = OTV0P2BASE::randRNG8NextBoolean();
        is0.hasEcoBias = OTV0P2BASE::randRNG8NextBoolean();
        const uint8_t oldValvePos = valvePCOpen;
        rs0.tick(valvePCOpen, is0);
        const uint8_t newValvePos = valvePCOpen;
        ASSERT_TRUE(newValvePos > 0);
        ASSERT_TRUE(newValvePos <= 100);
        ASSERT_TRUE(newValvePos > oldValvePos);
        if(oldValvePos < is0.minPCOpen) { ASSERT_TRUE(is0.minPCOpen <= newValvePos); } // Should open to at least minimum-really-open-% on first step.
        ASSERT_TRUE(rs0.valveMoved == (oldValvePos != newValvePos));
        if(100 == newValvePos) { break; }
        }
    ASSERT_EQ(100, valvePCOpen);
    ASSERT_EQ(100 - valvePCOpenInitial0, rs0.cumulativeMovementPC);
    // Equally test that if the temperature is much higher than any legit target
    // the valve will monotonically close to 0% in bounded time.
    // Check for superficially correct linger behaviour:
    //   * minPCOpen-1 % must be hit (lingering close) if starting anywhere above that.
    //   * Once in linger all reductions should be by 1% until possible final jump to 0.
    //   * Check that linger was long enough (if linger threshold is higher enough to allow it).
    // Also check for some correct initialisation and 'velocity'/smoothing behaviour.
    if(verbose) { fprintf(stderr, "close...\n"); }
    OTRadValve::ModelledRadValveInputState is1(100<<4);
    is1.targetTempC = OTV0P2BASE::randRNG8NextBoolean() ? 5 : 25;
    OTRadValve::ModelledRadValveState rs1;
    ASSERT_TRUE(!rs1.initialised); // Initialisation not yet complete.
    const uint8_t valvePCOpenInitial1 = 1 + (OTV0P2BASE::randRNG8() % 100);
    valvePCOpen = valvePCOpenInitial1;
    const bool lookForLinger = (valvePCOpenInitial1 >= is1.minPCOpen);
    bool hitLinger = false; // True if the linger value was hit.
    uint8_t lingerMins = 0; // Approx mins spent in linger.
    for(int i = maxFullTravelMins; --i >= 0; ) // Must fully close in reasonable time.
        {
        // Simulates one minute on each iteration.
        // Futz some input parameters that should not matter.
        is1.widenDeadband = OTV0P2BASE::randRNG8NextBoolean();
        is1.hasEcoBias = OTV0P2BASE::randRNG8NextBoolean();
        const uint8_t oldValvePos = valvePCOpen;
        ASSERT_TRUE(valvePCOpen >= 0); // Nominally never false because unsigned type.
        rs1.tick(valvePCOpen, is1);
        const uint8_t newValvePos = valvePCOpen;
        ASSERT_TRUE(valvePCOpen >= 0); // Nominally never false because unsigned type.
        ASSERT_TRUE(rs1.initialised); // Initialisation must have completed.
        ASSERT_TRUE(newValvePos < 100);
        ASSERT_TRUE(newValvePos < oldValvePos);
        if(hitLinger) { ++lingerMins; }
        if(hitLinger && (0 != newValvePos)) { ASSERT_EQ(oldValvePos - 1, newValvePos); }
        if(newValvePos == is1.minPCOpen-1) { hitLinger = true; }
        ASSERT_TRUE(rs1.valveMoved == (oldValvePos != newValvePos));
        if(0 == newValvePos) { break; }
        }
    ASSERT_EQ(0, valvePCOpen);
    ASSERT_EQ(valvePCOpenInitial1, rs1.cumulativeMovementPC);
    ASSERT_TRUE(hitLinger == lookForLinger);
    if(lookForLinger) { ASSERT_TRUE(lingerMins >= OTV0P2BASE::fnmin(is1.minPCOpen, OTRadValve::DEFAULT_MAX_RUN_ON_TIME_M)); }
    // Filtering should not have been engaged and velocity should be zero (temperature is flat).
    for(int i = OTRadValve::ModelledRadValveState::filterLength; --i >= 0; ) { ASSERT_EQ(100<<4, rs1.prevRawTempC16[i]); }
    ASSERT_EQ(100<<4, rs1.getSmoothedRecent());
    //  AssertIsEqual(0, rs1.getVelocityC16PerTick());
    ASSERT_TRUE(!rs1.isFiltering);

    // Test that soft setback works as expected to support dark-based quick setback.
    // ENERGY SAVING RULE TEST (TODO-442 2a: "Setback in WARM mode must happen in dark (quick response) or long vacant room.")
    OTRadValve::ModelledRadValveInputState is3(100<<4);
    is3.targetTempC = 25;
    // Try a range of (whole-degree) offsets...
    for(int offset = -2; offset <= +2; ++offset)
        {
        // Try soft setback off and on.
        for(int s = 0; s < 2; ++s)
            {
            // Other than in the proportional range, valve should unconditionally be driven off/on by gross temperature error.
            if(0 != offset)
                {
                is3.refTempC16 = (is3.targetTempC + offset) << 4;
                // Where adjusted reference temperature is (well) below target, valve should be driven on.
                OTRadValve::ModelledRadValveState rs3a;
                valvePCOpen = 0;
                rs3a.tick(valvePCOpen, is3);
if(verbose) { fprintf(stderr, "@ %d %d\n", offset, valvePCOpen); }
                ASSERT_TRUE((offset < 0) ? (valvePCOpen > 0) : (0 == valvePCOpen));
                // Where adjusted reference temperature is (well) above target, valve should be driven off.
                OTRadValve::ModelledRadValveState rs3b;
                valvePCOpen = 100;
                rs3b.tick(valvePCOpen, is3);
                ASSERT_TRUE((offset < 0) ? (100 == valvePCOpen) : (valvePCOpen < 100));
                }
            else
                {
                // Below the half way mark the valve should always be opened (from off), soft setback or not.
                is3.refTempC16 = (is3.targetTempC << 4) + 0x4;
                OTRadValve::ModelledRadValveState rs3c;
                valvePCOpen = 0;
                rs3c.tick(valvePCOpen, is3);
                ASSERT_TRUE(valvePCOpen > 0);
                // Above the half way mark the valve should only be opened without soft setback.
                is3.refTempC16 = (is3.targetTempC << 4) + 0xc;
                OTRadValve::ModelledRadValveState rs3d;
                valvePCOpen = 0;
                rs3d.tick(valvePCOpen, is3);
                ASSERT_TRUE(0 == valvePCOpen);
                }
            }
        }
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * 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 "src/trace_processor/forwarding_trace_parser.h"

#include "perfetto/base/logging.h"
#include "perfetto/ext/base/string_utils.h"
#include "src/trace_processor/importers/common/process_tracker.h"
#include "src/trace_processor/importers/ninja/ninja_log_parser.h"
#include "src/trace_processor/importers/proto/proto_trace_parser.h"
#include "src/trace_processor/importers/proto/proto_trace_reader.h"
#include "src/trace_processor/trace_sorter.h"

namespace perfetto {
namespace trace_processor {
namespace {

const char kNoZlibErr[] =
    "Cannot open compressed trace. zlib not enabled in the build config";

inline bool isspace(unsigned char c) {
  return ::isspace(c);
}

std::string RemoveWhitespace(std::string str) {
  str.erase(std::remove_if(str.begin(), str.end(), isspace), str.end());
  return str;
}

TraceSorter::SortingMode ConvertSortingMode(SortingMode sorting_mode) {
  switch (sorting_mode) {
    case SortingMode::kDefaultHeuristics:
    case SortingMode::kForceFlushPeriodWindowedSort:
      return TraceSorter::SortingMode::kDefault;
    case SortingMode::kForceFullSort:
      return TraceSorter::SortingMode::kFullSort;
  }
  PERFETTO_FATAL("For GCC");
}

// Fuchsia traces have a magic number as documented here:
// https://fuchsia.googlesource.com/fuchsia/+/HEAD/docs/development/tracing/trace-format/README.md#magic-number-record-trace-info-type-0
constexpr uint64_t kFuchsiaMagicNumber = 0x0016547846040010;

}  // namespace

ForwardingTraceParser::ForwardingTraceParser(TraceProcessorContext* context)
    : context_(context) {}

ForwardingTraceParser::~ForwardingTraceParser() {}

util::Status ForwardingTraceParser::Parse(TraceBlobView blob) {
  // If this is the first Parse() call, guess the trace type and create the
  // appropriate parser.
  if (!reader_) {
    TraceType trace_type;
    {
      auto scoped_trace = context_->storage->TraceExecutionTimeIntoStats(
          stats::guess_trace_type_duration_ns);
      trace_type = GuessTraceType(blob.data(), blob.size());
    }
    switch (trace_type) {
      case kJsonTraceType: {
        PERFETTO_DLOG("JSON trace detected");
        if (context_->json_trace_tokenizer && context_->json_trace_parser) {
          reader_ = std::move(context_->json_trace_tokenizer);

          // JSON traces have no guarantees about the order of events in them.
          context_->sorter.reset(
              new TraceSorter(context_, std::move(context_->json_trace_parser),
                              TraceSorter::SortingMode::kFullSort));
        } else {
          return util::ErrStatus("JSON support is disabled");
        }
        break;
      }
      case kProtoTraceType: {
        PERFETTO_DLOG("Proto trace detected");
        auto sorting_mode = ConvertSortingMode(context_->config.sorting_mode);
        reader_.reset(new ProtoTraceReader(context_));
        context_->sorter.reset(new TraceSorter(
            context_,
            std::unique_ptr<TraceParser>(new ProtoTraceParser(context_)),
            sorting_mode));
        context_->process_tracker->SetPidZeroIsUpidZeroIdleProcess();
        break;
      }
      case kNinjaLogTraceType: {
        PERFETTO_DLOG("Ninja log detected");
        reader_.reset(new NinjaLogParser(context_));
        break;
      }
      case kFuchsiaTraceType: {
        PERFETTO_DLOG("Fuchsia trace detected");
        if (context_->fuchsia_trace_parser &&
            context_->fuchsia_trace_tokenizer) {
          reader_ = std::move(context_->fuchsia_trace_tokenizer);

          // Fuschia traces can have massively out of order events.
          context_->sorter.reset(new TraceSorter(
              context_, std::move(context_->fuchsia_trace_parser),
              TraceSorter::SortingMode::kFullSort));
        } else {
          return util::ErrStatus("Fuchsia support is disabled");
        }
        break;
      }
      case kSystraceTraceType:
        PERFETTO_DLOG("Systrace trace detected");
        context_->process_tracker->SetPidZeroIsUpidZeroIdleProcess();
        if (context_->systrace_trace_parser) {
          reader_ = std::move(context_->systrace_trace_parser);
          break;
        } else {
          return util::ErrStatus("Systrace support is disabled");
        }
      case kGzipTraceType:
      case kCtraceTraceType:
        if (trace_type == kGzipTraceType) {
          PERFETTO_DLOG("gzip trace detected");
        } else {
          PERFETTO_DLOG("ctrace trace detected");
        }
        if (context_->gzip_trace_parser) {
          reader_ = std::move(context_->gzip_trace_parser);
          break;
        } else {
          return util::ErrStatus(kNoZlibErr);
        }
      case kUnknownTraceType:
        // If renaming this error message don't remove the "(ERR:fmt)" part.
        // The UI's error_dialog.ts uses it to make the dialog more graceful.
        return util::ErrStatus("Unknown trace type provided (ERR:fmt)");
    }
  }

  return reader_->Parse(std::move(blob));
}

void ForwardingTraceParser::NotifyEndOfFile() {
  reader_->NotifyEndOfFile();
}

TraceType GuessTraceType(const uint8_t* data, size_t size) {
  if (size == 0)
    return kUnknownTraceType;
  std::string start(reinterpret_cast<const char*>(data),
                    std::min<size_t>(size, kGuessTraceMaxLookahead));
  if (size >= 8) {
    uint64_t first_word;
    memcpy(&first_word, data, sizeof(first_word));
    if (first_word == kFuchsiaMagicNumber)
      return kFuchsiaTraceType;
  }
  std::string start_minus_white_space = RemoveWhitespace(start);
  if (base::StartsWith(start_minus_white_space, "{\""))
    return kJsonTraceType;
  if (base::StartsWith(start_minus_white_space, "[{\""))
    return kJsonTraceType;

  // Systrace with header but no leading HTML.
  if (base::Contains(start, "# tracer"))
    return kSystraceTraceType;

  // Systrace with leading HTML.
  if (base::StartsWith(start, "<!DOCTYPE html>") ||
      base::StartsWith(start, "<html>"))
    return kSystraceTraceType;

  // Traces obtained from atrace -z (compress).
  // They all have the string "TRACE:" followed by 78 9C which is a zlib header
  // for "deflate, default compression, window size=32K" (see b/208691037)
  if (base::Contains(start, "TRACE:\n\x78\x9c"))
    return kCtraceTraceType;

  // Traces obtained from atrace without -z (no compression).
  if (base::Contains(start, "TRACE:\n"))
    return kSystraceTraceType;

  // Ninja's buils log (.ninja_log).
  if (base::StartsWith(start, "# ninja log"))
    return kNinjaLogTraceType;

  // Systrace with no header or leading HTML.
  if (base::StartsWith(start, " "))
    return kSystraceTraceType;

  // gzip'ed trace containing one of the other formats.
  if (base::StartsWith(start, "\x1f\x8b"))
    return kGzipTraceType;

  if (base::StartsWith(start, "\x0a"))
    return kProtoTraceType;

  return kUnknownTraceType;
}

}  // namespace trace_processor
}  // namespace perfetto
<commit_msg>Typo buils -> build<commit_after>/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * 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 "src/trace_processor/forwarding_trace_parser.h"

#include "perfetto/base/logging.h"
#include "perfetto/ext/base/string_utils.h"
#include "src/trace_processor/importers/common/process_tracker.h"
#include "src/trace_processor/importers/ninja/ninja_log_parser.h"
#include "src/trace_processor/importers/proto/proto_trace_parser.h"
#include "src/trace_processor/importers/proto/proto_trace_reader.h"
#include "src/trace_processor/trace_sorter.h"

namespace perfetto {
namespace trace_processor {
namespace {

const char kNoZlibErr[] =
    "Cannot open compressed trace. zlib not enabled in the build config";

inline bool isspace(unsigned char c) {
  return ::isspace(c);
}

std::string RemoveWhitespace(std::string str) {
  str.erase(std::remove_if(str.begin(), str.end(), isspace), str.end());
  return str;
}

TraceSorter::SortingMode ConvertSortingMode(SortingMode sorting_mode) {
  switch (sorting_mode) {
    case SortingMode::kDefaultHeuristics:
    case SortingMode::kForceFlushPeriodWindowedSort:
      return TraceSorter::SortingMode::kDefault;
    case SortingMode::kForceFullSort:
      return TraceSorter::SortingMode::kFullSort;
  }
  PERFETTO_FATAL("For GCC");
}

// Fuchsia traces have a magic number as documented here:
// https://fuchsia.googlesource.com/fuchsia/+/HEAD/docs/development/tracing/trace-format/README.md#magic-number-record-trace-info-type-0
constexpr uint64_t kFuchsiaMagicNumber = 0x0016547846040010;

}  // namespace

ForwardingTraceParser::ForwardingTraceParser(TraceProcessorContext* context)
    : context_(context) {}

ForwardingTraceParser::~ForwardingTraceParser() {}

util::Status ForwardingTraceParser::Parse(TraceBlobView blob) {
  // If this is the first Parse() call, guess the trace type and create the
  // appropriate parser.
  if (!reader_) {
    TraceType trace_type;
    {
      auto scoped_trace = context_->storage->TraceExecutionTimeIntoStats(
          stats::guess_trace_type_duration_ns);
      trace_type = GuessTraceType(blob.data(), blob.size());
    }
    switch (trace_type) {
      case kJsonTraceType: {
        PERFETTO_DLOG("JSON trace detected");
        if (context_->json_trace_tokenizer && context_->json_trace_parser) {
          reader_ = std::move(context_->json_trace_tokenizer);

          // JSON traces have no guarantees about the order of events in them.
          context_->sorter.reset(
              new TraceSorter(context_, std::move(context_->json_trace_parser),
                              TraceSorter::SortingMode::kFullSort));
        } else {
          return util::ErrStatus("JSON support is disabled");
        }
        break;
      }
      case kProtoTraceType: {
        PERFETTO_DLOG("Proto trace detected");
        auto sorting_mode = ConvertSortingMode(context_->config.sorting_mode);
        reader_.reset(new ProtoTraceReader(context_));
        context_->sorter.reset(new TraceSorter(
            context_,
            std::unique_ptr<TraceParser>(new ProtoTraceParser(context_)),
            sorting_mode));
        context_->process_tracker->SetPidZeroIsUpidZeroIdleProcess();
        break;
      }
      case kNinjaLogTraceType: {
        PERFETTO_DLOG("Ninja log detected");
        reader_.reset(new NinjaLogParser(context_));
        break;
      }
      case kFuchsiaTraceType: {
        PERFETTO_DLOG("Fuchsia trace detected");
        if (context_->fuchsia_trace_parser &&
            context_->fuchsia_trace_tokenizer) {
          reader_ = std::move(context_->fuchsia_trace_tokenizer);

          // Fuschia traces can have massively out of order events.
          context_->sorter.reset(new TraceSorter(
              context_, std::move(context_->fuchsia_trace_parser),
              TraceSorter::SortingMode::kFullSort));
        } else {
          return util::ErrStatus("Fuchsia support is disabled");
        }
        break;
      }
      case kSystraceTraceType:
        PERFETTO_DLOG("Systrace trace detected");
        context_->process_tracker->SetPidZeroIsUpidZeroIdleProcess();
        if (context_->systrace_trace_parser) {
          reader_ = std::move(context_->systrace_trace_parser);
          break;
        } else {
          return util::ErrStatus("Systrace support is disabled");
        }
      case kGzipTraceType:
      case kCtraceTraceType:
        if (trace_type == kGzipTraceType) {
          PERFETTO_DLOG("gzip trace detected");
        } else {
          PERFETTO_DLOG("ctrace trace detected");
        }
        if (context_->gzip_trace_parser) {
          reader_ = std::move(context_->gzip_trace_parser);
          break;
        } else {
          return util::ErrStatus(kNoZlibErr);
        }
      case kUnknownTraceType:
        // If renaming this error message don't remove the "(ERR:fmt)" part.
        // The UI's error_dialog.ts uses it to make the dialog more graceful.
        return util::ErrStatus("Unknown trace type provided (ERR:fmt)");
    }
  }

  return reader_->Parse(std::move(blob));
}

void ForwardingTraceParser::NotifyEndOfFile() {
  reader_->NotifyEndOfFile();
}

TraceType GuessTraceType(const uint8_t* data, size_t size) {
  if (size == 0)
    return kUnknownTraceType;
  std::string start(reinterpret_cast<const char*>(data),
                    std::min<size_t>(size, kGuessTraceMaxLookahead));
  if (size >= 8) {
    uint64_t first_word;
    memcpy(&first_word, data, sizeof(first_word));
    if (first_word == kFuchsiaMagicNumber)
      return kFuchsiaTraceType;
  }
  std::string start_minus_white_space = RemoveWhitespace(start);
  if (base::StartsWith(start_minus_white_space, "{\""))
    return kJsonTraceType;
  if (base::StartsWith(start_minus_white_space, "[{\""))
    return kJsonTraceType;

  // Systrace with header but no leading HTML.
  if (base::Contains(start, "# tracer"))
    return kSystraceTraceType;

  // Systrace with leading HTML.
  if (base::StartsWith(start, "<!DOCTYPE html>") ||
      base::StartsWith(start, "<html>"))
    return kSystraceTraceType;

  // Traces obtained from atrace -z (compress).
  // They all have the string "TRACE:" followed by 78 9C which is a zlib header
  // for "deflate, default compression, window size=32K" (see b/208691037)
  if (base::Contains(start, "TRACE:\n\x78\x9c"))
    return kCtraceTraceType;

  // Traces obtained from atrace without -z (no compression).
  if (base::Contains(start, "TRACE:\n"))
    return kSystraceTraceType;

  // Ninja's build log (.ninja_log).
  if (base::StartsWith(start, "# ninja log"))
    return kNinjaLogTraceType;

  // Systrace with no header or leading HTML.
  if (base::StartsWith(start, " "))
    return kSystraceTraceType;

  // gzip'ed trace containing one of the other formats.
  if (base::StartsWith(start, "\x1f\x8b"))
    return kGzipTraceType;

  if (base::StartsWith(start, "\x0a"))
    return kProtoTraceType;

  return kUnknownTraceType;
}

}  // namespace trace_processor
}  // namespace perfetto
<|endoftext|>


<commit_before>#include "job.h"
#include "debug.h"
#include "utils.h"

#include <TSettings.h>

Job::Job(QObject *parent)
    : QObject(parent),
      _optionScheduledEnabled(JobSchedule::Disabled),
      _optionPreservePaths(DEFAULT_PRESERVE_PATHNAMES),
      _optionTraverseMount(DEFAULT_TRAVERSE_MOUNT),
      _optionFollowSymLinks(DEFAULT_FOLLOW_SYMLINKS),
      _optionSkipFilesSize(DEFAULT_SKIP_FILES_SIZE),
      _optionSkipFiles(DEFAULT_SKIP_SYSTEM_ENABLED),
      _optionSkipFilesPatterns(DEFAULT_SKIP_SYSTEM_FILES),
      _optionSkipNoDump(DEFAULT_SKIP_NODUMP),
      _settingShowHidden(false),
      _settingShowSystem(false),
      _settingHideSymlinks(false)
{
    // Load values from settings.
    TSettings settings;
    setOptionPreservePaths(
        settings.value("tarsnap/preserve_pathnames", optionPreservePaths())
            .toBool());
    setOptionTraverseMount(
        settings.value("tarsnap/traverse_mount", optionTraverseMount()).toBool());
    setOptionFollowSymLinks(
        settings.value("tarsnap/follow_symlinks", optionFollowSymLinks()).toBool());
    setOptionSkipNoDump(
        settings.value("app/skip_nodump", optionSkipNoDump()).toBool());
    setOptionSkipFilesSize(
        settings.value("app/skip_files_size", optionSkipFilesSize()).toInt());
    setOptionSkipFiles(
        settings.value("app/skip_system_enabled", optionSkipFiles()).toBool());
    setOptionSkipFilesPatterns(
        settings.value("app/skip_system_files", optionSkipFilesPatterns())
            .toString());
}

Job::~Job()
{
}

QString Job::name() const
{
    return _name;
}

void Job::setName(const QString &name)
{
    _name = name;
}

QString Job::archivePrefix()
{
    return JOB_NAME_PREFIX + name();
}

QList<QUrl> Job::urls() const
{
    return _urls;
}

void Job::setUrls(const QList<QUrl> &urls)
{
    _urls = urls;
}

bool Job::validateUrls()
{
    // Check that _urls is not empty.
    if(_urls.isEmpty())
        return false;
    // Check that every file exists.
    for(const QUrl &url : _urls)
    {
        QFileInfo file(url.toLocalFile());
        if(!file.exists())
            return false;
    }
    return true;
}

void Job::installWatcher()
{
    connect(&_fsWatcher, &QFileSystemWatcher::directoryChanged, this,
            &Job::fsEvent);
    connect(&_fsWatcher, &QFileSystemWatcher::fileChanged, this, &Job::fsEvent);

    for(const QUrl &url : _urls)
    {
        // Emit a signal if a file has changed.
        QFileInfo file(url.toLocalFile());
        _fsWatcher.addPath(file.absoluteFilePath());
        // Emit a signal if a directory or any of its ancestors has changed.
        QDir dir(file.absoluteDir());
        while(dir != QDir::root())
        {
            _fsWatcher.addPath(dir.absolutePath());
            dir.cdUp();
        }
    }
}

void Job::removeWatcher()
{
    disconnect(&_fsWatcher, &QFileSystemWatcher::directoryChanged, this,
               &Job::fsEvent);
    disconnect(&_fsWatcher, &QFileSystemWatcher::fileChanged, this,
               &Job::fsEvent);

    QStringList watching = _fsWatcher.files() + _fsWatcher.directories();
    if(!watching.isEmpty())
        _fsWatcher.removePaths(watching);
}

QList<ArchivePtr> Job::archives() const
{
    return _archives;
}

void Job::setArchives(const QList<ArchivePtr> &archives)
{
    _archives.clear();
    _archives = archives;
    // Sort archives based on timestamp using an anonymous sorting function.
    std::sort(_archives.begin(), _archives.end(),
              [](const ArchivePtr &a, const ArchivePtr &b) {
                  return (a->timestamp() > b->timestamp());
              });
    // If any Archive is deleted, reload the list.
    for(const ArchivePtr &archive : _archives)
    {
        connect(archive.data(), &Archive::purged, this, &Job::loadArchives,
                QUEUED);
    }
    emit changed();
}

JobSchedule Job::optionScheduledEnabled() const
{
    return static_cast<JobSchedule>(_optionScheduledEnabled);
}

void Job::setOptionScheduledEnabled(JobSchedule schedule)
{
    _optionScheduledEnabled = schedule;
}

bool Job::optionPreservePaths() const
{
    return _optionPreservePaths;
}

void Job::setOptionPreservePaths(bool optionPreservePaths)
{
    _optionPreservePaths = optionPreservePaths;
}

bool Job::optionFollowSymLinks() const
{
    return _optionFollowSymLinks;
}

void Job::setOptionFollowSymLinks(bool optionFollowSymLinks)
{
    _optionFollowSymLinks = optionFollowSymLinks;
}

bool Job::optionTraverseMount() const
{
    return _optionTraverseMount;
}

void Job::setOptionTraverseMount(bool optionTraverseMount)
{
    _optionTraverseMount = optionTraverseMount;
}

int Job::optionSkipFilesSize() const
{
    return _optionSkipFilesSize;
}

void Job::setOptionSkipFilesSize(const int &optionSkipFilesSize)
{
    _optionSkipFilesSize = optionSkipFilesSize;
}

bool Job::optionSkipFiles() const
{
    return _optionSkipFiles;
}

void Job::setOptionSkipFiles(bool optionSkipFiles)
{
    _optionSkipFiles = optionSkipFiles;
}

QString Job::optionSkipFilesPatterns() const
{
    return _optionSkipFilesPatterns;
}

void Job::setOptionSkipFilesPatterns(const QString &optionSkipFilesPatterns)
{
    _optionSkipFilesPatterns = optionSkipFilesPatterns;
}

bool Job::optionSkipNoDump() const
{
    return _optionSkipNoDump;
}

void Job::setOptionSkipNoDump(bool optionSkipNoDump)
{
    _optionSkipNoDump = optionSkipNoDump;
}

bool Job::settingShowHidden() const
{
    return _settingShowHidden;
}

void Job::setSettingShowHidden(bool settingShowHidden)
{
    _settingShowHidden = settingShowHidden;
}

bool Job::settingShowSystem() const
{
    return _settingShowSystem;
}

void Job::setSettingShowSystem(bool settingShowSystem)
{
    _settingShowSystem = settingShowSystem;
}

bool Job::settingHideSymlinks() const
{
    return _settingHideSymlinks;
}

void Job::setSettingHideSymlinks(bool settingHideSymlinks)
{
    _settingHideSymlinks = settingHideSymlinks;
}

BackupTaskPtr Job::createBackupTask()
{
    BackupTaskPtr backup(new BackupTask);
    backup->setName(
        JOB_NAME_PREFIX + name()
        + QDateTime::currentDateTime().toString(ARCHIVE_TIMESTAMP_FORMAT));
    backup->setJobRef(objectKey());
    backup->setUrls(urls());
    backup->setOptionPreservePaths(optionPreservePaths());
    backup->setOptionTraverseMount(optionTraverseMount());
    backup->setOptionFollowSymLinks(optionFollowSymLinks());
    backup->setOptionSkipFilesSize(optionSkipFilesSize());
    backup->setOptionSkipSystem(optionSkipFiles());
    backup->setOptionSkipSystemFiles(optionSkipFilesPatterns());
    backup->setOptionSkipNoDump(optionSkipNoDump());
    return backup;
}

void Job::save()
{
    bool exists = doesKeyExist(_name);

    // Prepare query: either updating or creating an entry.
    QString queryString;
    if(exists)
        queryString = QLatin1String(
            "update jobs set name=?, urls=?, optionScheduledEnabled=?,"
            " optionPreservePaths=?,"
            " optionTraverseMount=?, optionFollowSymLinks=?,"
            " optionSkipFilesSize=?,"
            " optionSkipFiles=?, optionSkipFilesPatterns=?, optionSkipNoDump=?,"
            " settingShowHidden=?, settingShowSystem=?, settingHideSymlinks=?"
            " where name=?");
    else
        queryString = QLatin1String(
            "insert into jobs(name, urls, optionScheduledEnabled,"
            " optionPreservePaths, optionTraverseMount,"
            " optionFollowSymLinks, optionSkipFilesSize, optionSkipFiles,"
            " optionSkipFilesPatterns, optionSkipNoDump, settingShowHidden,"
            " settingShowSystem, settingHideSymlinks)"
            " values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");

    // Get database instance and create query object.
    PersistentStore &store = getStore();
    QSqlQuery        query = store.createQuery();
    if(!query.prepare(queryString))
    {
        DEBUG << query.lastError().text();
        return;
    }
    // Fill in missing value in query string.
    query.addBindValue(_name);
    QStringList urls;
    foreach(QUrl url, _urls)
        urls << url.toString(QUrl::FullyEncoded);
    query.addBindValue(urls.join('\n'));
    query.addBindValue(_optionScheduledEnabled);
    query.addBindValue(_optionPreservePaths);
    query.addBindValue(_optionTraverseMount);
    query.addBindValue(_optionFollowSymLinks);
    query.addBindValue(_optionSkipFilesSize);
    query.addBindValue(_optionSkipFiles);
    query.addBindValue(_optionSkipFilesPatterns);
    query.addBindValue(_optionSkipNoDump);
    query.addBindValue(_settingShowHidden);
    query.addBindValue(_settingShowSystem);
    query.addBindValue(_settingHideSymlinks);
    if(exists)
        query.addBindValue(_name);

    // Run query.
    if(!store.runQuery(query))
        DEBUG << "Failed to save Job entry.";
    setObjectKey(_name);
}

void Job::load()
{
    // Sanity checks.
    if(_name.isEmpty())
    {
        DEBUG << "Attempting to load Job object with empty _name key.";
        return;
    }
    // Get database instance and prepare query.
    PersistentStore &store = getStore();
    QSqlQuery        query = store.createQuery();
    if(!query.prepare(QLatin1String("select * from jobs where name = ?")))
    {
        DEBUG << query.lastError().text();
        return;
    }
    // Fill in missing value in query string.
    query.addBindValue(_name);
    // Run query.
    if(store.runQuery(query) && query.next())
    {
        _urls = QUrl::fromStringList(query.value(query.record().indexOf("urls"))
                                         .toString()
                                         .split('\n', QString::SkipEmptyParts));
        _optionScheduledEnabled =
            query.value(query.record().indexOf("optionScheduledEnabled")).toInt();
        _optionPreservePaths =
            query.value(query.record().indexOf("optionPreservePaths")).toBool();
        _optionTraverseMount =
            query.value(query.record().indexOf("optionTraverseMount")).toBool();
        _optionFollowSymLinks =
            query.value(query.record().indexOf("optionFollowSymLinks")).toBool();
        _optionSkipFilesSize =
            query.value(query.record().indexOf("optionSkipFilesSize")).toInt();
        _optionSkipFiles =
            query.value(query.record().indexOf("optionSkipFiles")).toBool();
        _optionSkipFilesPatterns =
            query.value(query.record().indexOf("optionSkipFilesPatterns"))
                .toString();
        _optionSkipNoDump =
            query.value(query.record().indexOf("optionSkipNoDump")).toBool();
        _settingShowHidden =
            query.value(query.record().indexOf("settingShowHidden")).toBool();
        _settingShowSystem =
            query.value(query.record().indexOf("settingShowSystem")).toBool();
        _settingHideSymlinks =
            query.value(query.record().indexOf("settingHideSymlinks")).toBool();
        setObjectKey(_name);
        emit loadArchives();
    }
    else
    {
        DEBUG << "Job object with key " << _name << " not found.";
    }
}

void Job::purge()
{
    // Sanity checks.
    if(_name.isEmpty())
    {
        DEBUG << "Attempting to delete Job object with empty _name key.";
        return;
    }
    if(!doesKeyExist(_name))
    {
        DEBUG << "No Job object with key " << _name;
        return;
    }
    // Get database instance and prepare query.
    PersistentStore &store = getStore();
    QSqlQuery        query = store.createQuery();
    if(!query.prepare(QLatin1String("delete from jobs where name = ?")))
    {
        DEBUG << query.lastError().text();
        return;
    }
    // Fill in missing value in query string.
    query.addBindValue(_name);
    // Run query.
    if(!store.runQuery(query))
        DEBUG << "Failed to remove Job entry.";
    setObjectKey("");
    emit purged();
}

bool Job::doesKeyExist(QString key)
{
    bool found = false;
    // Sanity check.
    if(key.isEmpty())
    {
        DEBUG << "doesKeyExist method called with empty args";
        return found;
    }
    // Get database instance and prepare query.
    PersistentStore &store = getStore();
    QSqlQuery        query = store.createQuery();
    if(!query.prepare(QLatin1String("select name from jobs where name = ?")))
    {
        DEBUG << query.lastError().text();
        return found;
    }
    // Fill in missing value in query string.
    query.addBindValue(key);
    // Run query.
    if(store.runQuery(query))
    {
        if(query.next())
        {
            found = true;
        }
    }
    else
    {
        DEBUG << "Failed to run doesKeyExist query for a Job.";
    }
    return found;
}
<commit_msg>Job: rename minor variable for clarity<commit_after>#include "job.h"
#include "debug.h"
#include "utils.h"

#include <TSettings.h>

Job::Job(QObject *parent)
    : QObject(parent),
      _optionScheduledEnabled(JobSchedule::Disabled),
      _optionPreservePaths(DEFAULT_PRESERVE_PATHNAMES),
      _optionTraverseMount(DEFAULT_TRAVERSE_MOUNT),
      _optionFollowSymLinks(DEFAULT_FOLLOW_SYMLINKS),
      _optionSkipFilesSize(DEFAULT_SKIP_FILES_SIZE),
      _optionSkipFiles(DEFAULT_SKIP_SYSTEM_ENABLED),
      _optionSkipFilesPatterns(DEFAULT_SKIP_SYSTEM_FILES),
      _optionSkipNoDump(DEFAULT_SKIP_NODUMP),
      _settingShowHidden(false),
      _settingShowSystem(false),
      _settingHideSymlinks(false)
{
    // Load values from settings.
    TSettings settings;
    setOptionPreservePaths(
        settings.value("tarsnap/preserve_pathnames", optionPreservePaths())
            .toBool());
    setOptionTraverseMount(
        settings.value("tarsnap/traverse_mount", optionTraverseMount()).toBool());
    setOptionFollowSymLinks(
        settings.value("tarsnap/follow_symlinks", optionFollowSymLinks()).toBool());
    setOptionSkipNoDump(
        settings.value("app/skip_nodump", optionSkipNoDump()).toBool());
    setOptionSkipFilesSize(
        settings.value("app/skip_files_size", optionSkipFilesSize()).toInt());
    setOptionSkipFiles(
        settings.value("app/skip_system_enabled", optionSkipFiles()).toBool());
    setOptionSkipFilesPatterns(
        settings.value("app/skip_system_files", optionSkipFilesPatterns())
            .toString());
}

Job::~Job()
{
}

QString Job::name() const
{
    return _name;
}

void Job::setName(const QString &name)
{
    _name = name;
}

QString Job::archivePrefix()
{
    return JOB_NAME_PREFIX + name();
}

QList<QUrl> Job::urls() const
{
    return _urls;
}

void Job::setUrls(const QList<QUrl> &urls)
{
    _urls = urls;
}

bool Job::validateUrls()
{
    // Check that _urls is not empty.
    if(_urls.isEmpty())
        return false;
    // Check that every file exists.
    for(const QUrl &url : _urls)
    {
        QFileInfo file(url.toLocalFile());
        if(!file.exists())
            return false;
    }
    return true;
}

void Job::installWatcher()
{
    connect(&_fsWatcher, &QFileSystemWatcher::directoryChanged, this,
            &Job::fsEvent);
    connect(&_fsWatcher, &QFileSystemWatcher::fileChanged, this, &Job::fsEvent);

    for(const QUrl &url : _urls)
    {
        // Emit a signal if a file has changed.
        QFileInfo file(url.toLocalFile());
        _fsWatcher.addPath(file.absoluteFilePath());
        // Emit a signal if a directory or any of its ancestors has changed.
        QDir dir(file.absoluteDir());
        while(dir != QDir::root())
        {
            _fsWatcher.addPath(dir.absolutePath());
            dir.cdUp();
        }
    }
}

void Job::removeWatcher()
{
    disconnect(&_fsWatcher, &QFileSystemWatcher::directoryChanged, this,
               &Job::fsEvent);
    disconnect(&_fsWatcher, &QFileSystemWatcher::fileChanged, this,
               &Job::fsEvent);

    QStringList watching = _fsWatcher.files() + _fsWatcher.directories();
    if(!watching.isEmpty())
        _fsWatcher.removePaths(watching);
}

QList<ArchivePtr> Job::archives() const
{
    return _archives;
}

void Job::setArchives(const QList<ArchivePtr> &archives)
{
    _archives.clear();
    _archives = archives;
    // Sort archives based on timestamp using an anonymous sorting function.
    std::sort(_archives.begin(), _archives.end(),
              [](const ArchivePtr &a, const ArchivePtr &b) {
                  return (a->timestamp() > b->timestamp());
              });
    // If any Archive is deleted, reload the list.
    for(const ArchivePtr &archive : _archives)
    {
        connect(archive.data(), &Archive::purged, this, &Job::loadArchives,
                QUEUED);
    }
    emit changed();
}

JobSchedule Job::optionScheduledEnabled() const
{
    return static_cast<JobSchedule>(_optionScheduledEnabled);
}

void Job::setOptionScheduledEnabled(JobSchedule schedule)
{
    _optionScheduledEnabled = schedule;
}

bool Job::optionPreservePaths() const
{
    return _optionPreservePaths;
}

void Job::setOptionPreservePaths(bool optionPreservePaths)
{
    _optionPreservePaths = optionPreservePaths;
}

bool Job::optionFollowSymLinks() const
{
    return _optionFollowSymLinks;
}

void Job::setOptionFollowSymLinks(bool optionFollowSymLinks)
{
    _optionFollowSymLinks = optionFollowSymLinks;
}

bool Job::optionTraverseMount() const
{
    return _optionTraverseMount;
}

void Job::setOptionTraverseMount(bool optionTraverseMount)
{
    _optionTraverseMount = optionTraverseMount;
}

int Job::optionSkipFilesSize() const
{
    return _optionSkipFilesSize;
}

void Job::setOptionSkipFilesSize(const int &optionSkipFilesSize)
{
    _optionSkipFilesSize = optionSkipFilesSize;
}

bool Job::optionSkipFiles() const
{
    return _optionSkipFiles;
}

void Job::setOptionSkipFiles(bool optionSkipFiles)
{
    _optionSkipFiles = optionSkipFiles;
}

QString Job::optionSkipFilesPatterns() const
{
    return _optionSkipFilesPatterns;
}

void Job::setOptionSkipFilesPatterns(const QString &optionSkipFilesPatterns)
{
    _optionSkipFilesPatterns = optionSkipFilesPatterns;
}

bool Job::optionSkipNoDump() const
{
    return _optionSkipNoDump;
}

void Job::setOptionSkipNoDump(bool optionSkipNoDump)
{
    _optionSkipNoDump = optionSkipNoDump;
}

bool Job::settingShowHidden() const
{
    return _settingShowHidden;
}

void Job::setSettingShowHidden(bool settingShowHidden)
{
    _settingShowHidden = settingShowHidden;
}

bool Job::settingShowSystem() const
{
    return _settingShowSystem;
}

void Job::setSettingShowSystem(bool settingShowSystem)
{
    _settingShowSystem = settingShowSystem;
}

bool Job::settingHideSymlinks() const
{
    return _settingHideSymlinks;
}

void Job::setSettingHideSymlinks(bool settingHideSymlinks)
{
    _settingHideSymlinks = settingHideSymlinks;
}

BackupTaskPtr Job::createBackupTask()
{
    BackupTaskPtr backup(new BackupTask);
    backup->setName(
        JOB_NAME_PREFIX + name()
        + QDateTime::currentDateTime().toString(ARCHIVE_TIMESTAMP_FORMAT));
    backup->setJobRef(objectKey());
    backup->setUrls(urls());
    backup->setOptionPreservePaths(optionPreservePaths());
    backup->setOptionTraverseMount(optionTraverseMount());
    backup->setOptionFollowSymLinks(optionFollowSymLinks());
    backup->setOptionSkipFilesSize(optionSkipFilesSize());
    backup->setOptionSkipSystem(optionSkipFiles());
    backup->setOptionSkipSystemFiles(optionSkipFilesPatterns());
    backup->setOptionSkipNoDump(optionSkipNoDump());
    return backup;
}

void Job::save()
{
    bool exists = doesKeyExist(_name);

    // Prepare query: either updating or creating an entry.
    QString queryString;
    if(exists)
        queryString = QLatin1String(
            "update jobs set name=?, urls=?, optionScheduledEnabled=?,"
            " optionPreservePaths=?,"
            " optionTraverseMount=?, optionFollowSymLinks=?,"
            " optionSkipFilesSize=?,"
            " optionSkipFiles=?, optionSkipFilesPatterns=?, optionSkipNoDump=?,"
            " settingShowHidden=?, settingShowSystem=?, settingHideSymlinks=?"
            " where name=?");
    else
        queryString = QLatin1String(
            "insert into jobs(name, urls, optionScheduledEnabled,"
            " optionPreservePaths, optionTraverseMount,"
            " optionFollowSymLinks, optionSkipFilesSize, optionSkipFiles,"
            " optionSkipFilesPatterns, optionSkipNoDump, settingShowHidden,"
            " settingShowSystem, settingHideSymlinks)"
            " values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");

    // Get database instance and create query object.
    PersistentStore &store = getStore();
    QSqlQuery        query = store.createQuery();
    if(!query.prepare(queryString))
    {
        DEBUG << query.lastError().text();
        return;
    }
    // Fill in missing value in query string.
    query.addBindValue(_name);
    QStringList query_urls;
    foreach(QUrl url, _urls)
        query_urls << url.toString(QUrl::FullyEncoded);
    query.addBindValue(query_urls.join('\n'));
    query.addBindValue(_optionScheduledEnabled);
    query.addBindValue(_optionPreservePaths);
    query.addBindValue(_optionTraverseMount);
    query.addBindValue(_optionFollowSymLinks);
    query.addBindValue(_optionSkipFilesSize);
    query.addBindValue(_optionSkipFiles);
    query.addBindValue(_optionSkipFilesPatterns);
    query.addBindValue(_optionSkipNoDump);
    query.addBindValue(_settingShowHidden);
    query.addBindValue(_settingShowSystem);
    query.addBindValue(_settingHideSymlinks);
    if(exists)
        query.addBindValue(_name);

    // Run query.
    if(!store.runQuery(query))
        DEBUG << "Failed to save Job entry.";
    setObjectKey(_name);
}

void Job::load()
{
    // Sanity checks.
    if(_name.isEmpty())
    {
        DEBUG << "Attempting to load Job object with empty _name key.";
        return;
    }
    // Get database instance and prepare query.
    PersistentStore &store = getStore();
    QSqlQuery        query = store.createQuery();
    if(!query.prepare(QLatin1String("select * from jobs where name = ?")))
    {
        DEBUG << query.lastError().text();
        return;
    }
    // Fill in missing value in query string.
    query.addBindValue(_name);
    // Run query.
    if(store.runQuery(query) && query.next())
    {
        _urls = QUrl::fromStringList(query.value(query.record().indexOf("urls"))
                                         .toString()
                                         .split('\n', QString::SkipEmptyParts));
        _optionScheduledEnabled =
            query.value(query.record().indexOf("optionScheduledEnabled")).toInt();
        _optionPreservePaths =
            query.value(query.record().indexOf("optionPreservePaths")).toBool();
        _optionTraverseMount =
            query.value(query.record().indexOf("optionTraverseMount")).toBool();
        _optionFollowSymLinks =
            query.value(query.record().indexOf("optionFollowSymLinks")).toBool();
        _optionSkipFilesSize =
            query.value(query.record().indexOf("optionSkipFilesSize")).toInt();
        _optionSkipFiles =
            query.value(query.record().indexOf("optionSkipFiles")).toBool();
        _optionSkipFilesPatterns =
            query.value(query.record().indexOf("optionSkipFilesPatterns"))
                .toString();
        _optionSkipNoDump =
            query.value(query.record().indexOf("optionSkipNoDump")).toBool();
        _settingShowHidden =
            query.value(query.record().indexOf("settingShowHidden")).toBool();
        _settingShowSystem =
            query.value(query.record().indexOf("settingShowSystem")).toBool();
        _settingHideSymlinks =
            query.value(query.record().indexOf("settingHideSymlinks")).toBool();
        setObjectKey(_name);
        emit loadArchives();
    }
    else
    {
        DEBUG << "Job object with key " << _name << " not found.";
    }
}

void Job::purge()
{
    // Sanity checks.
    if(_name.isEmpty())
    {
        DEBUG << "Attempting to delete Job object with empty _name key.";
        return;
    }
    if(!doesKeyExist(_name))
    {
        DEBUG << "No Job object with key " << _name;
        return;
    }
    // Get database instance and prepare query.
    PersistentStore &store = getStore();
    QSqlQuery        query = store.createQuery();
    if(!query.prepare(QLatin1String("delete from jobs where name = ?")))
    {
        DEBUG << query.lastError().text();
        return;
    }
    // Fill in missing value in query string.
    query.addBindValue(_name);
    // Run query.
    if(!store.runQuery(query))
        DEBUG << "Failed to remove Job entry.";
    setObjectKey("");
    emit purged();
}

bool Job::doesKeyExist(QString key)
{
    bool found = false;
    // Sanity check.
    if(key.isEmpty())
    {
        DEBUG << "doesKeyExist method called with empty args";
        return found;
    }
    // Get database instance and prepare query.
    PersistentStore &store = getStore();
    QSqlQuery        query = store.createQuery();
    if(!query.prepare(QLatin1String("select name from jobs where name = ?")))
    {
        DEBUG << query.lastError().text();
        return found;
    }
    // Fill in missing value in query string.
    query.addBindValue(key);
    // Run query.
    if(store.runQuery(query))
    {
        if(query.next())
        {
            found = true;
        }
    }
    else
    {
        DEBUG << "Failed to run doesKeyExist query for a Job.";
    }
    return found;
}
<|endoftext|>


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

#include "ipc/ipc_message.h"

#include "base/atomic_sequence_num.h"
#include "base/logging.h"
#include "build/build_config.h"

#if defined(OS_POSIX)
#include "ipc/file_descriptor_set_posix.h"
#endif

namespace {

base::StaticAtomicSequenceNumber g_ref_num;

// Create a reference number for identifying IPC messages in traces. The return
// values has the reference number stored in the upper 24 bits, leaving the low
// 8 bits set to 0 for use as flags.
inline uint32 GetRefNumUpper24() {
  base::debug::TraceLog* trace_log = base::debug::TraceLog::GetInstance();
  int32 pid = trace_log ? trace_log->process_id() : 0;
  int32 count = g_ref_num.GetNext();
  // The 24 bit hash is composed of 14 bits of the count and 10 bits of the
  // Process ID. With the current trace event buffer cap, the 14-bit count did
  // not appear to wrap during a trace. Note that it is not a big deal if
  // collisions occur, as this is only used for debugging and trace analysis.
  return ((pid << 14) | (count & 0x3fff)) << 8;
}

}  // namespace

namespace IPC {

//------------------------------------------------------------------------------

Message::~Message() {
}

Message::Message()
    : Pickle(sizeof(Header)) {
  header()->routing = header()->type = 0;
  header()->flags = GetRefNumUpper24();
#if defined(OS_POSIX)
  header()->num_fds = 0;
  header()->pad = 0;
#endif
  InitLoggingVariables();
}

Message::Message(int32 routing_id, uint32 type, PriorityValue priority)
    : Pickle(sizeof(Header)) {
  header()->routing = routing_id;
  header()->type = type;
  DCHECK((priority & 0xffffff00) == 0);
  header()->flags = priority | GetRefNumUpper24();
#if defined(OS_POSIX)
  header()->num_fds = 0;
  header()->pad = 0;
#endif
  InitLoggingVariables();
}

Message::Message(const char* data, int data_len) : Pickle(data, data_len) {
  InitLoggingVariables();
}

Message::Message(const Message& other) : Pickle(other) {
  InitLoggingVariables();
#if defined(OS_POSIX)
  file_descriptor_set_ = other.file_descriptor_set_;
#endif
}

void Message::InitLoggingVariables() {
#ifdef IPC_MESSAGE_LOG_ENABLED
  received_time_ = 0;
  dont_log_ = false;
  log_data_ = NULL;
#endif
}

Message& Message::operator=(const Message& other) {
  *static_cast<Pickle*>(this) = other;
  // TODO(vtl): Remove once bug resolved.
  CHECK(header()) << "crbug.com/357915";
#if defined(OS_POSIX)
  file_descriptor_set_ = other.file_descriptor_set_;
#endif
  return *this;
}

void Message::SetHeaderValues(int32 routing, uint32 type, uint32 flags) {
  // This should only be called when the message is already empty.
  DCHECK(payload_size() == 0);

  header()->routing = routing;
  header()->type = type;
  header()->flags = flags;
}

#ifdef IPC_MESSAGE_LOG_ENABLED
void Message::set_sent_time(int64 time) {
  DCHECK((header()->flags & HAS_SENT_TIME_BIT) == 0);
  header()->flags |= HAS_SENT_TIME_BIT;
  WriteInt64(time);
}

int64 Message::sent_time() const {
  if ((header()->flags & HAS_SENT_TIME_BIT) == 0)
    return 0;

  const char* data = end_of_payload();
  data -= sizeof(int64);
  return *(reinterpret_cast<const int64*>(data));
}

void Message::set_received_time(int64 time) const {
  received_time_ = time;
}
#endif

#if defined(OS_POSIX)
bool Message::WriteFileDescriptor(const base::FileDescriptor& descriptor) {
  // We write the index of the descriptor so that we don't have to
  // keep the current descriptor as extra decoding state when deserialising.
  WriteInt(file_descriptor_set()->size());
  if (descriptor.auto_close) {
    return file_descriptor_set()->AddAndAutoClose(descriptor.fd);
  } else {
    return file_descriptor_set()->Add(descriptor.fd);
  }
}

bool Message::ReadFileDescriptor(PickleIterator* iter,
                                 base::FileDescriptor* descriptor) const {
  int descriptor_index;
  if (!ReadInt(iter, &descriptor_index))
    return false;

  FileDescriptorSet* file_descriptor_set = file_descriptor_set_.get();
  if (!file_descriptor_set)
    return false;

  descriptor->fd = file_descriptor_set->GetDescriptorAt(descriptor_index);
  descriptor->auto_close = true;

  return descriptor->fd >= 0;
}

bool Message::HasFileDescriptors() const {
  return file_descriptor_set_.get() && !file_descriptor_set_->empty();
}

void Message::EnsureFileDescriptorSet() {
  if (file_descriptor_set_.get() == NULL)
    file_descriptor_set_ = new FileDescriptorSet;
}

#endif

}  // namespace IPC
<commit_msg>Revert 260416 "Merge 260408 "Another temporary CHECK to help tra..."<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ipc/ipc_message.h"

#include "base/atomic_sequence_num.h"
#include "base/logging.h"
#include "build/build_config.h"

#if defined(OS_POSIX)
#include "ipc/file_descriptor_set_posix.h"
#endif

namespace {

base::StaticAtomicSequenceNumber g_ref_num;

// Create a reference number for identifying IPC messages in traces. The return
// values has the reference number stored in the upper 24 bits, leaving the low
// 8 bits set to 0 for use as flags.
inline uint32 GetRefNumUpper24() {
  base::debug::TraceLog* trace_log = base::debug::TraceLog::GetInstance();
  int32 pid = trace_log ? trace_log->process_id() : 0;
  int32 count = g_ref_num.GetNext();
  // The 24 bit hash is composed of 14 bits of the count and 10 bits of the
  // Process ID. With the current trace event buffer cap, the 14-bit count did
  // not appear to wrap during a trace. Note that it is not a big deal if
  // collisions occur, as this is only used for debugging and trace analysis.
  return ((pid << 14) | (count & 0x3fff)) << 8;
}

}  // namespace

namespace IPC {

//------------------------------------------------------------------------------

Message::~Message() {
}

Message::Message()
    : Pickle(sizeof(Header)) {
  header()->routing = header()->type = 0;
  header()->flags = GetRefNumUpper24();
#if defined(OS_POSIX)
  header()->num_fds = 0;
  header()->pad = 0;
#endif
  InitLoggingVariables();
}

Message::Message(int32 routing_id, uint32 type, PriorityValue priority)
    : Pickle(sizeof(Header)) {
  header()->routing = routing_id;
  header()->type = type;
  DCHECK((priority & 0xffffff00) == 0);
  header()->flags = priority | GetRefNumUpper24();
#if defined(OS_POSIX)
  header()->num_fds = 0;
  header()->pad = 0;
#endif
  InitLoggingVariables();
}

Message::Message(const char* data, int data_len) : Pickle(data, data_len) {
  InitLoggingVariables();
}

Message::Message(const Message& other) : Pickle(other) {
  InitLoggingVariables();
#if defined(OS_POSIX)
  file_descriptor_set_ = other.file_descriptor_set_;
#endif
}

void Message::InitLoggingVariables() {
#ifdef IPC_MESSAGE_LOG_ENABLED
  received_time_ = 0;
  dont_log_ = false;
  log_data_ = NULL;
#endif
}

Message& Message::operator=(const Message& other) {
  *static_cast<Pickle*>(this) = other;
#if defined(OS_POSIX)
  file_descriptor_set_ = other.file_descriptor_set_;
#endif
  return *this;
}

void Message::SetHeaderValues(int32 routing, uint32 type, uint32 flags) {
  // This should only be called when the message is already empty.
  DCHECK(payload_size() == 0);

  header()->routing = routing;
  header()->type = type;
  header()->flags = flags;
}

#ifdef IPC_MESSAGE_LOG_ENABLED
void Message::set_sent_time(int64 time) {
  DCHECK((header()->flags & HAS_SENT_TIME_BIT) == 0);
  header()->flags |= HAS_SENT_TIME_BIT;
  WriteInt64(time);
}

int64 Message::sent_time() const {
  if ((header()->flags & HAS_SENT_TIME_BIT) == 0)
    return 0;

  const char* data = end_of_payload();
  data -= sizeof(int64);
  return *(reinterpret_cast<const int64*>(data));
}

void Message::set_received_time(int64 time) const {
  received_time_ = time;
}
#endif

#if defined(OS_POSIX)
bool Message::WriteFileDescriptor(const base::FileDescriptor& descriptor) {
  // We write the index of the descriptor so that we don't have to
  // keep the current descriptor as extra decoding state when deserialising.
  WriteInt(file_descriptor_set()->size());
  if (descriptor.auto_close) {
    return file_descriptor_set()->AddAndAutoClose(descriptor.fd);
  } else {
    return file_descriptor_set()->Add(descriptor.fd);
  }
}

bool Message::ReadFileDescriptor(PickleIterator* iter,
                                 base::FileDescriptor* descriptor) const {
  int descriptor_index;
  if (!ReadInt(iter, &descriptor_index))
    return false;

  FileDescriptorSet* file_descriptor_set = file_descriptor_set_.get();
  if (!file_descriptor_set)
    return false;

  descriptor->fd = file_descriptor_set->GetDescriptorAt(descriptor_index);
  descriptor->auto_close = true;

  return descriptor->fd >= 0;
}

bool Message::HasFileDescriptors() const {
  return file_descriptor_set_.get() && !file_descriptor_set_->empty();
}

void Message::EnsureFileDescriptorSet() {
  if (file_descriptor_set_.get() == NULL)
    file_descriptor_set_ = new FileDescriptorSet;
}

#endif

}  // namespace IPC
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ChainablePropertySetInfo.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 17:16:47 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_comphelper.hxx"
#ifndef _COMPHELPER_CHAINABLEPROPERTYSETINFO_HXX_
#include <comphelper/ChainablePropertySetInfo.hxx>
#endif
#ifndef _COMPHELPER_TYPEGENERATION_HXX_
#include <comphelper/TypeGeneration.hxx>
#endif

using ::rtl::OUString;
using ::comphelper::PropertyInfo;
using ::comphelper::GenerateCppuType;
using ::comphelper::ChainablePropertySetInfo;
using ::com::sun::star::uno::Any;
using ::com::sun::star::uno::Type;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::XInterface;
using ::com::sun::star::uno::RuntimeException;
using ::com::sun::star::beans::Property;
using ::com::sun::star::beans::XPropertySetInfo;
using ::com::sun::star::beans::UnknownPropertyException;

ChainablePropertySetInfo::ChainablePropertySetInfo()
    throw()
{
}

ChainablePropertySetInfo::ChainablePropertySetInfo( PropertyInfo* pMap )
    throw()
{
    add ( pMap );
}

ChainablePropertySetInfo::~ChainablePropertySetInfo()
    throw()
{
}

void ChainablePropertySetInfo::add( PropertyInfo* pMap, sal_Int32 nCount )
    throw()
{
    // nCount < 0   => add all
    // nCount == 0  => add nothing
    // nCount > 0   => add at most nCount entries
    if( maProperties.getLength() )
        maProperties.realloc( 0 );

    while( pMap->mpName && ( ( nCount < 0) || ( nCount-- > 0 ) ) )
    {
        OUString aName( pMap->mpName, pMap->mnNameLen, RTL_TEXTENCODING_ASCII_US );

#ifndef PRODUCT
        PropertyInfoHash::iterator aIter = maMap.find( aName );
        if( aIter != maMap.end() )
            OSL_ENSURE( sal_False, "Warning: PropertyInfo added twice, possible error!");
#endif
        maMap[aName] = pMap++;
    }
}

void ChainablePropertySetInfo::remove( const rtl::OUString& aName )
    throw()
{
    maMap.erase ( aName );
    if ( maProperties.getLength() )
         maProperties.realloc( 0 );
}

Sequence< ::Property > SAL_CALL ChainablePropertySetInfo::getProperties()
    throw(::com::sun::star::uno::RuntimeException)
{
    sal_Int32 nSize = maMap.size();
    if( maProperties.getLength() != nSize )
    {
        maProperties.realloc ( nSize );
        Property* pProperties = maProperties.getArray();

        PropertyInfoHash::iterator aIter = maMap.begin();
        const PropertyInfoHash::iterator aEnd = maMap.end();
        for ( ; aIter != aEnd; ++aIter, ++pProperties)
        {
            PropertyInfo* pInfo = (*aIter).second;

            pProperties->Name = OUString( pInfo->mpName, pInfo->mnNameLen, RTL_TEXTENCODING_ASCII_US );
            pProperties->Handle = pInfo->mnHandle;
            const Type* pType;
            GenerateCppuType ( pInfo->meCppuType, pType);
            pProperties->Type = *pType;
            pProperties->Attributes = pInfo->mnAttributes;
        }
    }
    return maProperties;
}

Property SAL_CALL ChainablePropertySetInfo::getPropertyByName( const ::rtl::OUString& rName )
    throw(::UnknownPropertyException, ::com::sun::star::uno::RuntimeException)
{
    PropertyInfoHash::iterator aIter = maMap.find( rName );

    if ( maMap.end() == aIter )
        throw UnknownPropertyException();

    PropertyInfo *pInfo = (*aIter).second;
    Property aProperty;
    aProperty.Name   = OUString( pInfo->mpName, pInfo->mnNameLen, RTL_TEXTENCODING_ASCII_US );
    aProperty.Handle = pInfo->mnHandle;
    const Type* pType = &aProperty.Type;
    GenerateCppuType ( pInfo->meCppuType, pType );
    aProperty.Type = *pType;
    aProperty.Attributes = pInfo->mnAttributes;
    return aProperty;
}

sal_Bool SAL_CALL ChainablePropertySetInfo::hasPropertyByName( const ::rtl::OUString& rName )
    throw(::com::sun::star::uno::RuntimeException)
{
    return static_cast < sal_Bool > ( maMap.find ( rName ) != maMap.end() );
}
<commit_msg>INTEGRATION: CWS changefileheader (1.7.160); FILE MERGED 2008/04/01 12:26:32 thb 1.7.160.2: #i85898# Stripping all external header guards 2008/03/31 12:19:35 rt 1.7.160.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: ChainablePropertySetInfo.cxx,v $
 * $Revision: 1.8 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_comphelper.hxx"
#include <comphelper/ChainablePropertySetInfo.hxx>
#include <comphelper/TypeGeneration.hxx>

using ::rtl::OUString;
using ::comphelper::PropertyInfo;
using ::comphelper::GenerateCppuType;
using ::comphelper::ChainablePropertySetInfo;
using ::com::sun::star::uno::Any;
using ::com::sun::star::uno::Type;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::XInterface;
using ::com::sun::star::uno::RuntimeException;
using ::com::sun::star::beans::Property;
using ::com::sun::star::beans::XPropertySetInfo;
using ::com::sun::star::beans::UnknownPropertyException;

ChainablePropertySetInfo::ChainablePropertySetInfo()
    throw()
{
}

ChainablePropertySetInfo::ChainablePropertySetInfo( PropertyInfo* pMap )
    throw()
{
    add ( pMap );
}

ChainablePropertySetInfo::~ChainablePropertySetInfo()
    throw()
{
}

void ChainablePropertySetInfo::add( PropertyInfo* pMap, sal_Int32 nCount )
    throw()
{
    // nCount < 0   => add all
    // nCount == 0  => add nothing
    // nCount > 0   => add at most nCount entries
    if( maProperties.getLength() )
        maProperties.realloc( 0 );

    while( pMap->mpName && ( ( nCount < 0) || ( nCount-- > 0 ) ) )
    {
        OUString aName( pMap->mpName, pMap->mnNameLen, RTL_TEXTENCODING_ASCII_US );

#ifndef PRODUCT
        PropertyInfoHash::iterator aIter = maMap.find( aName );
        if( aIter != maMap.end() )
            OSL_ENSURE( sal_False, "Warning: PropertyInfo added twice, possible error!");
#endif
        maMap[aName] = pMap++;
    }
}

void ChainablePropertySetInfo::remove( const rtl::OUString& aName )
    throw()
{
    maMap.erase ( aName );
    if ( maProperties.getLength() )
         maProperties.realloc( 0 );
}

Sequence< ::Property > SAL_CALL ChainablePropertySetInfo::getProperties()
    throw(::com::sun::star::uno::RuntimeException)
{
    sal_Int32 nSize = maMap.size();
    if( maProperties.getLength() != nSize )
    {
        maProperties.realloc ( nSize );
        Property* pProperties = maProperties.getArray();

        PropertyInfoHash::iterator aIter = maMap.begin();
        const PropertyInfoHash::iterator aEnd = maMap.end();
        for ( ; aIter != aEnd; ++aIter, ++pProperties)
        {
            PropertyInfo* pInfo = (*aIter).second;

            pProperties->Name = OUString( pInfo->mpName, pInfo->mnNameLen, RTL_TEXTENCODING_ASCII_US );
            pProperties->Handle = pInfo->mnHandle;
            const Type* pType;
            GenerateCppuType ( pInfo->meCppuType, pType);
            pProperties->Type = *pType;
            pProperties->Attributes = pInfo->mnAttributes;
        }
    }
    return maProperties;
}

Property SAL_CALL ChainablePropertySetInfo::getPropertyByName( const ::rtl::OUString& rName )
    throw(::UnknownPropertyException, ::com::sun::star::uno::RuntimeException)
{
    PropertyInfoHash::iterator aIter = maMap.find( rName );

    if ( maMap.end() == aIter )
        throw UnknownPropertyException();

    PropertyInfo *pInfo = (*aIter).second;
    Property aProperty;
    aProperty.Name   = OUString( pInfo->mpName, pInfo->mnNameLen, RTL_TEXTENCODING_ASCII_US );
    aProperty.Handle = pInfo->mnHandle;
    const Type* pType = &aProperty.Type;
    GenerateCppuType ( pInfo->meCppuType, pType );
    aProperty.Type = *pType;
    aProperty.Attributes = pInfo->mnAttributes;
    return aProperty;
}

sal_Bool SAL_CALL ChainablePropertySetInfo::hasPropertyByName( const ::rtl::OUString& rName )
    throw(::com::sun::star::uno::RuntimeException)
{
    return static_cast < sal_Bool > ( maMap.find ( rName ) != maMap.end() );
}
<|endoftext|>


<commit_before>// Copyright © 2017 Dmitriy Khaustov
//
// 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.
//
// Author: Dmitriy Khaustov aka xDimon
// Contacts: khaustov.dm@gmail.com
// File created on: 2017.02.25

// Options.cpp

#include "Options.hpp"

Options::Options(int argc, char **argv)
#ifdef PROJECT_NAME
	#define HELPER4QUOTE(N) #N
	: cxxopts::Options(HELPER4QUOTE(PROJECT_NAME), "Description of program (?)")
	#undef HELPER4QUOTE
#else
	#error "PROJECT_NAME undefined"
#endif
{
	_configFile = "etc/config.conf";
}

Options::~Options()
{
}

const std::string& Options::getConfig() const
{
	return _configFile;
}
<commit_msg>Implement getting of path to config file by argument<commit_after>// Copyright © 2017 Dmitriy Khaustov
//
// 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.
//
// Author: Dmitriy Khaustov aka xDimon
// Contacts: khaustov.dm@gmail.com
// File created on: 2017.02.25

// Options.cpp

#include "Options.hpp"

Options::Options(int argc, char **argv)
#ifdef PROJECT_NAME
	#define HELPER4QUOTE(N) #N
	: cxxopts::Options(HELPER4QUOTE(PROJECT_NAME), "Description of program (?)")
	#undef HELPER4QUOTE
#else
	#error "PROJECT_NAME undefined"
#endif
{
	add_options()
	("c,config", "Path to config file", cxxopts::value<std::string>(_configFile), "[config] helper (?)")
	;

	parse(argc, argv);
}

Options::~Options()
{
}

const std::string& Options::getConfig() const
{
	return _configFile;
}
<|endoftext|>