<commit_before>/*
** Author(s):
**  - Herve Cuche <hcuche@aldebaran-robotics.com>
**
** Copyright (C) 2012 Aldebaran Robotics
*/

#include <iostream>
#include <string>

#include <boost/program_options.hpp>

#include <qi/application.hpp>
#include <qi/os.hpp>
#include <qi/log.hpp>
#include <qimessaging/session.hpp>
#include <qitype/genericobject.hpp>
#include <qitype/genericobjectbuilder.hpp>

qiLogCategory("qiservice");

std::string reply(const std::string &msg) {
  qiLogInfo() << "Message recv:" << msg;
  return msg + "bim";
}

qi::GenericValue reply(const qi::GenericValue &myval) {
  static int i = 0;
  qi::GenericValuePtr val(myval);
  qiLogInfo() << i++ << " Message received with the signature: " << myval.signature(false) << " = " << qi::encodeJSON(val) << std::endl;
  return myval;
}

std::string reply(const int &msg) {
  qiLogInfo() << "Message recv:" << msg;
  std::stringstream ss;

  ss << msg << "bim";
  return ss.str();
}

std::string reply(const std::string &msg, const double &value) {
  qiLogInfo() << "Message recv:" << msg << " * " << value;
  std::stringstream ss;

  ss << msg << value;
  return ss.str();
}

std::string reply(const std::string &msg, const float &value) {
  qiLogInfo() << "Message recv:" << msg << " * " << value;
  std::stringstream ss;

  ss << msg << value;
  return ss.str();
}

bool slip(unsigned int seconds) {
  qi::os::sleep(seconds);
  return true;
}

namespace po = boost::program_options;

int main(int argc, char *argv[])
{
  const std::string serviceName = "serviceTest";

  qi::Application app(argc, argv);
  // declare the program options
  po::options_description desc("Usage:\n  qi-service masterAddress [options]\nOptions");
  desc.add_options()
      ("help", "Print this help.")
      ("master-address",
       po::value<std::string>()->default_value(std::string("tcp://127.0.0.1:5555")),
       "The master address");

  // allow master address to be specified as the first arg
  po::positional_options_description pos;
  pos.add("master-address", 1);

  // Test hostIPAddrs
  std::map<std::string, std::vector<std::string> > ifsMap = qi::os::hostIPAddrs();

  if (ifsMap.empty())
   qiLogInfo();

  if (ifsMap.empty() == false)
    for (std::map<std::string, std::vector<std::string> >::const_iterator adapter = ifsMap.begin();
         adapter != ifsMap.end();
         ++adapter)
    {
      for (std::vector<std::string>::const_iterator address = (*adapter).second.begin();
           address != (*adapter).second.end();
           ++address)
      {
        qiLogInfoF("%s : %s", (*adapter).first.c_str(), (*address).c_str());
      }
    }

  // parse and store
  po::variables_map vm;
  try
  {
    po::store(po::command_line_parser(argc, argv).
              options(desc).positional(pos).run(), vm);
    po::notify(vm);

    if (vm.count("help"))
    {
      qiLogInfo() << desc;
      return 0;
    }

    if (vm.count("master-address") == 1)
    {
      std::string masterAddress = vm["master-address"].as<std::string>();
      qi::Session       session;
      qi::GenericObjectBuilder ob;
      ob.advertiseMethod<std::string (const std::string&)>("reply", &reply);
      ob.advertiseMethod<std::string (const int&)>("reply", &reply);
      ob.advertiseMethod<std::string (const std::string&, const double &)>("reply", &reply);
      ob.advertiseMethod<std::string (const std::string&, const float &)>("reply", &reply);
      ob.advertiseMethod<qi::GenericValue (const qi::GenericValue&)>("reply", &reply);
      ob.advertiseEvent<void (const std::string&)>("testEvent");
      ob.advertiseMethod<bool (unsigned int)>("slip", &slip);
      qi::ObjectPtr obj(ob.object());

      session.connect(masterAddress);

      session.listen("tcp://0.0.0.0:0");
      session.setIdentity("tests/server.key", "tests/server.crt");
      try {
        session.listen("tcps://0.0.0.0:0");
      } catch (std::runtime_error &) {
        qiLogWarning() << "SSL desactivated.";
      }

      unsigned int id = session.registerService(serviceName, obj);

#if 0
      // test unregistration
      session.unregisterService(id);
      id = session.registerService("serviceTest", &obj);
#endif

      if (id)
      {
        qiLogInfo() << "Registered \"" << serviceName << "\" as service (#" << id << ") with the master";
      }
      else
      {
        qiLogError() << "Registration with master failed, aborting...";
        exit(1);
      }
      int i = 0;
      while (true) {
        std::stringstream ss;
        ss << "miam" << i++;
        obj->emitEvent("testEvent", ss.str());
        ss.str(std::string());
        qi::os::sleep(1);
      }

      session.unregisterService(id);
      session.close();
    }
    else
    {
      qiLogInfo() << desc;
    }
  }
  catch (const boost::program_options::error&)
  {
    qiLogInfo() << desc;
  }

  return 0;
}
<commit_msg>qi-service: added replyVector/replyMap/replyMap2<commit_after>/*
** Author(s):
**  - Herve Cuche <hcuche@aldebaran-robotics.com>
**
** Copyright (C) 2012 Aldebaran Robotics
*/

#include <iostream>
#include <string>

#include <boost/program_options.hpp>

#include <qi/application.hpp>
#include <qi/os.hpp>
#include <qi/log.hpp>
#include <qimessaging/session.hpp>
#include <qitype/genericobject.hpp>
#include <qitype/genericobjectbuilder.hpp>

qiLogCategory("qiservice");

std::string reply(const std::string &msg) {
  qiLogInfo() << "Message recv:" << msg;
  return msg + "bim";
}

qi::GenericValue reply(const qi::GenericValue &myval) {
  static int i = 0;
  qi::GenericValuePtr val(myval);
  qiLogInfo() << i++ << " Message received with the signature: " << myval.signature(false) << " = " << qi::encodeJSON(val) << std::endl;
  return myval;
}

std::string reply(const int &msg) {
  qiLogInfo() << "Message recv:" << msg;
  std::stringstream ss;

  ss << msg << "bim";
  return ss.str();
}

std::string reply(const std::string &msg, const double &value) {
  qiLogInfo() << "Message recv:" << msg << " * " << value;
  std::stringstream ss;

  ss << msg << value;
  return ss.str();
}

std::string reply(const std::string &msg, const float &value) {
  qiLogInfo() << "Message recv:" << msg << " * " << value;
  std::stringstream ss;

  ss << msg << value;
  return ss.str();
}

typedef std::vector<std::string> VS;
typedef std::map<std::string, VS> MSM;

VS replyVector() {
  VS ret;
  return ret;
  ret.push_back("titi");
  ret.push_back("tutu");
  return ret;
}

std::map<std::string, std::string> replyMap() {
  std::map<std::string, std::string> ret;
  return ret;
  ret["titi"] = "42";
  ret["tutu"] = "41";
  return ret;
}

MSM replyMap2() {
  MSM ret;
  VS v;

  return ret;
  v.push_back("titi");
  v.push_back("tutu");

  ret["titi"] = v;
  ret["tutu"] = v;
  return ret;
}

bool slip(unsigned int seconds) {
  qi::os::sleep(seconds);
  return true;
}

namespace po = boost::program_options;

int main(int argc, char *argv[])
{
  const std::string serviceName = "serviceTest";

  qi::Application app(argc, argv);
  // declare the program options
  po::options_description desc("Usage:\n  qi-service masterAddress [options]\nOptions");
  desc.add_options()
      ("help", "Print this help.")
      ("master-address",
       po::value<std::string>()->default_value(std::string("tcp://127.0.0.1:5555")),
       "The master address");

  // allow master address to be specified as the first arg
  po::positional_options_description pos;
  pos.add("master-address", 1);

  // Test hostIPAddrs
  std::map<std::string, std::vector<std::string> > ifsMap = qi::os::hostIPAddrs();

  if (ifsMap.empty())
   qiLogInfo();

  if (ifsMap.empty() == false)
    for (std::map<std::string, std::vector<std::string> >::const_iterator adapter = ifsMap.begin();
         adapter != ifsMap.end();
         ++adapter)
    {
      for (std::vector<std::string>::const_iterator address = (*adapter).second.begin();
           address != (*adapter).second.end();
           ++address)
      {
        qiLogInfoF("%s : %s", (*adapter).first.c_str(), (*address).c_str());
      }
    }

  // parse and store
  po::variables_map vm;
  try
  {
    po::store(po::command_line_parser(argc, argv).
              options(desc).positional(pos).run(), vm);
    po::notify(vm);

    if (vm.count("help"))
    {
      qiLogInfo() << desc;
      return 0;
    }

    if (vm.count("master-address") == 1)
    {
      std::string masterAddress = vm["master-address"].as<std::string>();
      qi::Session       session;
      qi::GenericObjectBuilder ob;
      ob.advertiseMethod<std::string (const std::string&)>("reply", &reply);
      ob.advertiseMethod<std::string (const int&)>("reply", &reply);
      ob.advertiseMethod<std::string (const std::string&, const double &)>("reply", &reply);
      ob.advertiseMethod<std::string (const std::string&, const float &)>("reply", &reply);
      ob.advertiseMethod("replyVector", &replyVector);
      ob.advertiseMethod("replyMap", &replyMap);
      ob.advertiseMethod("replyMap2", &replyMap2);
      ob.advertiseMethod<qi::GenericValue (const qi::GenericValue&)>("reply", &reply);
      ob.advertiseEvent<void (const std::string&)>("testEvent");
      ob.advertiseMethod<bool (unsigned int)>("slip", &slip);
      qi::ObjectPtr obj(ob.object());

      session.connect(masterAddress);

      session.listen("tcp://0.0.0.0:0");
      session.setIdentity("tests/server.key", "tests/server.crt");
      try {
        session.listen("tcps://0.0.0.0:0");
      } catch (std::runtime_error &) {
        qiLogWarning() << "SSL desactivated.";
      }

      unsigned int id = session.registerService(serviceName, obj);

#if 0
      // test unregistration
      session.unregisterService(id);
      id = session.registerService("serviceTest", &obj);
#endif

      if (id)
      {
        qiLogInfo() << "Registered \"" << serviceName << "\" as service (#" << id << ") with the master";
      }
      else
      {
        qiLogError() << "Registration with master failed, aborting...";
        exit(1);
      }
      int i = 0;
      while (true) {
        std::stringstream ss;
        ss << "miam" << i++;
        obj->emitEvent("testEvent", ss.str());
        ss.str(std::string());
        qi::os::sleep(1);
      }

      session.unregisterService(id);
      session.close();
    }
    else
    {
      qiLogInfo() << desc;
    }
  }
  catch (const boost::program_options::error&)
  {
    qiLogInfo() << desc;
  }

  return 0;
}
<|endoftext|>


<commit_before>
#include "snep.h"
#include "PN532_debug.h"

int8_t SNEP::write(const uint8_t *buf, uint8_t len, uint16_t timeout)
{
	if (0 >= llcp.activate(timeout)) {
		DMSG("failed to activate PN532 as a target\n");
		return -1;
	}

	if (0 >= llcp.connect(timeout)) {
		DMSG("failed to set up a connection\n");
		return -2;
	}

	// response a success SNEP message
	headerBuf[0] = SNEP_DEFAULT_VERSION;
	headerBuf[1] = SNEP_REQUEST_PUT;
	headerBuf[2] = 0;
	headerBuf[3] = 0;
	headerBuf[4] = 0;
	headerBuf[5] = len;
	if (0 >= llcp.write(headerBuf, 6, buf, len)) {
		return -3;
	}

	uint8_t rbuf[16];
	if (6 > llcp.read(rbuf, sizeof(rbuf))) {
		return -4;
	}

	// check SNEP version
	if (SNEP_DEFAULT_VERSION != rbuf[0]) {
		DMSG("The received SNEP message's major version is different\n");
		// To-do: send Unsupported Version response
		return -4;
	}

	// expect a put request
	if (SNEP_RESPONSE_SUCCESS != rbuf[1]) {
		DMSG("Expect a success response\n");
		return -4;
	}

	llcp.disconnect(timeout);

	return 1;
}

int16_t SNEP::read(uint8_t *buf, uint8_t len, uint16_t timeout)
{
	if (0 >= llcp.activate(timeout)) {
		DMSG("failed to activate PN532 as a target\n");
		return -1;
	}

	if (0 >= llcp.waitForConnection(timeout)) {
		DMSG("failed to set up a connection\n");
		return -2;
	}

	uint16_t status = llcp.read(buf, len);
	if (6 > status) {
		return -3;
	}

	// check SNEP version
	if (SNEP_DEFAULT_VERSION != buf[0]) {
		DMSG("The received SNEP message's major version is different\n");
		// To-do: send Unsupported Version response
		return -4;
	}

	// expect a put request
	if (SNEP_REQUEST_PUT != buf[1]) {
		DMSG("Expect a put request\n");
		return -4;
	}

	// check message's length
	uint32_t length = (buf[2] << 24) + (buf[3] << 16) + (buf[4] << 8) + buf[5];
	// length should not be more than 244 (header + body < 255, header = 6 + 3 + 2)
	if (length > (status - 6)) {
		DMSG("The SNEP message is too large: ");
        DMSG_INT(length);
        DMSG_INT(status - 6);
		DMSG("\n");
		return -4;
	}
	for (uint8_t i = 0; i < length; i++) {
		buf[i] = buf[i + 6];
	}

	// response a success SNEP message
	headerBuf[0] = SNEP_DEFAULT_VERSION;
	headerBuf[1] = SNEP_RESPONSE_SUCCESS;
	headerBuf[2] = 0;
	headerBuf[3] = 0;
	headerBuf[4] = 0;
	headerBuf[5] = 0;
	llcp.write(headerBuf, 6);

	return length;
}
<commit_msg>Bug fix: Cannot read SNEP data from Android, always got: "The received SNEP message's major version is different".<commit_after>
#include "snep.h"
#include "PN532_debug.h"

int8_t SNEP::write(const uint8_t *buf, uint8_t len, uint16_t timeout)
{
	if (0 >= llcp.activate(timeout)) {
		DMSG("failed to activate PN532 as a target\n");
		return -1;
	}

	if (0 >= llcp.connect(timeout)) {
		DMSG("failed to set up a connection\n");
		return -2;
	}

	// response a success SNEP message
	headerBuf[0] = SNEP_DEFAULT_VERSION;
	headerBuf[1] = SNEP_REQUEST_PUT;
	headerBuf[2] = 0;
	headerBuf[3] = 0;
	headerBuf[4] = 0;
	headerBuf[5] = len;
	if (0 >= llcp.write(headerBuf, 6, buf, len)) {
		return -3;
	}

	uint8_t rbuf[16];
	if (6 > llcp.read(rbuf, sizeof(rbuf))) {
		return -4;
	}

	// check SNEP version
	if (SNEP_DEFAULT_VERSION != rbuf[0]) {
		DMSG(F("The received SNEP message's major version is different, me: "));
		DMSG(SNEP_DEFAULT_VERSION);
		DMSG(", their: ");
		DMSG(rbuf[0]);
		DMSG("\n");
		// To-do: send Unsupported Version response
		return -4;
	}

	// expect a put request
	if (SNEP_RESPONSE_SUCCESS != rbuf[1]) {
		DMSG("Expect a success response\n");
		return -4;
	}

	llcp.disconnect(timeout);

	return 1;
}

int16_t SNEP::read(uint8_t *buf, uint8_t len, uint16_t timeout)
{
	if (0 >= llcp.activate(timeout)) {
		DMSG("failed to activate PN532 as a target\n");
		return -1;
	}

	if (0 >= llcp.waitForConnection(timeout)) {
		DMSG("failed to set up a connection\n");
		return -2;
	}

	uint16_t status = llcp.read(buf, len);
	if (6 > status) {
		return -3;
	}

	// check SNEP version

	// in case of platform specific bug, shift SNEP message for 4 bytes.
	// tested on Nexus 5, Android 5.1
	if (SNEP_DEFAULT_VERSION != buf[0] && SNEP_DEFAULT_VERSION == buf[4]) {
		for (uint8_t i = 0; i < len - 4; i++) {
			buf[i] = buf[i + 4];
		}
	}

	if (SNEP_DEFAULT_VERSION != buf[0]) {
		DMSG(F("SNEP->read: The received SNEP message's major version is different, me: "));
		DMSG(SNEP_DEFAULT_VERSION);
		DMSG(", their: ");
		DMSG(buf[0]);
		DMSG("\n");
		// To-do: send Unsupported Version response
		return -4;
	}

	// expect a put request
	if (SNEP_REQUEST_PUT != buf[1]) {
		DMSG("Expect a put request\n");
		return -4;
	}

	// check message's length
	uint32_t length = (buf[2] << 24) + (buf[3] << 16) + (buf[4] << 8) + buf[5];
	// length should not be more than 244 (header + body < 255, header = 6 + 3 + 2)
	if (length > (status - 6)) {
		DMSG("The SNEP message is too large: ");
		DMSG_INT(length);
		DMSG_INT(status - 6);
		DMSG("\n");
		return -4;
	}
	for (uint8_t i = 0; i < length; i++) {
		buf[i] = buf[i + 6];
	}

	// response a success SNEP message
	headerBuf[0] = SNEP_DEFAULT_VERSION;
	headerBuf[1] = SNEP_RESPONSE_SUCCESS;
	headerBuf[2] = 0;
	headerBuf[3] = 0;
	headerBuf[4] = 0;
	headerBuf[5] = 0;
	llcp.write(headerBuf, 6);

	return length;
}
<|endoftext|>


<commit_before>#include "evo/World.h"
#include "mancala.h"

#include <functional>
#include <fstream>
#include <vector>
#include <valarray>
#include <set>

#include "../push-3.1.0/src/CodeUtils.h"
#include "../push-3.1.0/src/RNG.h"
#include "../push-3.1.0/src/GeneticOps.h"
#include "../push-3.1.0/src/Instruction.h"
#include "../push-3.1.0/src/Literal.h"

#include "config/ArgManager.h"
#include "../handcoded_AI/Mancala/mancala/AI-Trivial.hh"
// #include "../handcoded_AI/mancala/mancala/contest/AI-Thelen.hh"
#include "play_mancala.h"
#include "MancalaResource.h"

EMP_BUILD_CONFIG( EcoEaConfig,
  GROUP(DEFAULT, "Default settings for NK model"),
  VALUE(TRIALS, uint32_t, 10, "Level of epistasis in the NK model"),
  VALUE(SEED, int, 0, "Random number seed (0 for based on time)"),
  VALUE(POP_SIZE, uint32_t, 100, "Number of organisms in the popoulation."),
  VALUE(TOURNAMENT_SIZE, uint32_t, 5, "Number of organisms in the popoulation."),
  VALUE(MAX_GENS, uint32_t, 2000, "How many generations should we process?"),
  VALUE(SELECTION_TYPE, std::string, "eco", "What type of selection? eco, tournament, or lexicase")
)

template <typename WORLD>
void init(WORLD & world, const push::Env& env, int POP_SIZE) {
    static push::Env workEnv(1000);
    static push::Code rnd = push::parse("CODE.RAND");

    for (int i = 0; i < POP_SIZE; ++i) {
        workEnv = env;
        (*rnd)(workEnv);
        if (not push::has_elements<push::Code>(workEnv,1)) { --i; continue; }
    	push::Code code = push::pop<push::Code>(workEnv); // get random program
        // std::cout << "About to insert " << i << std::endl;
        world.Insert(code);
    }

}

std::string print_code(push::Code code, push::Env& env) {

    if (code->size() == 1) {
	std::string result = code->to_string();

	// check if it's a name
	push::Literal<push::name_t>* name = dynamic_cast< push::Literal<push::name_t>* >(code.get());
	if (name) {
	    result += std::string(":") + get_code(name->get())->to_string();
	}

	return result;
    }

    std::string result = "( ";
    const push::CodeArray& pieces = code->get_stack();
    for (int i = pieces.size()-1; i >= 0; --i) {
	result += print_code(pieces[i], env);
	result += " ";
    }
    return result + " )";
}

int main(int argc, char* argv[] ) {
    EcoEaConfig config;

    config.Read("EcoEAPush.cfg");

    auto args = emp::cl::ArgManager(argc, argv);
    if (args.ProcessConfigOptions(config, std::cout, "EcoEAPush.cfg", "EcoEAPush-macros.h") == false) {
      exit(0);
    }
    if (args.TestUnknown() == false) exit(0);  // If there are leftover args, throw an error.

    const uint32_t POP_SIZE = config.POP_SIZE();
    const uint32_t MAX_GENS = config.MAX_GENS();
    const uint32_t TRIALS = config.TRIALS();
    const uint32_t TOURNAMENT_SIZE = config.TOURNAMENT_SIZE();

    push::init_push();
    // std::string config_file = "test.config";
    // std::ifstream push_config( config_file.c_str() );
    emp::Random random(config.SEED());
    emp::evo::World<push::Code, emp::evo::DefaultStats> world(random);
    world.fitM.Resize(POP_SIZE);
    Mancala game;
    push::Env env;

    // env.configure(push::parse(push_config));
    env = env.next();
    push::Code test = push::parse("( CODE.FROMFLOAT ( EXEC.STACKDEPTH 6 ( CODE.POSITION FLOAT.= CODE.DO  ) ( NAME.QUOTE  )  ) ( () EXEC.STACKDEPTH CODE.CONS ( ( CODE.EXTRACT EXEC.POP ( _3:(NAME.QUOTE _3) () () _1:TRUE ( ( ( CODE.CONS CODE.NTHCDR  ) ENV.RANDOM-SEED ( ( INTEGER.FROMBOOLEAN  ) CODE.NTH  )  ) ( ( INTEGER./ NAME.STACKDEPTH  ) 0  ) ( CODE.QUOTE ( EXEC.ROT BOOLEAN.POP : FLOAT.MAX  )  ) NAME.DUP ( EXEC.DEFINE  ) BOOLEAN.SWAP  )  )  ) ( EXEC.YANK  ) ENV.MAX-RANDOM-FLOAT  )  ) ( CODE.DEFINE CODE.POP  )  )");

    push::Env workEnv(env);

    // std::cout << "Loaded: " << print_code(test, env.next()) << std::endl;

    // std::cout << "about to initialize" << std::endl;
    init(world, env, POP_SIZE);
    // std::cout << "Initialize" << std::endl;

    // workEnv = env;

    MancalaResource ExtraMoveResource("extra_move_testcases.csv", &random, workEnv);
    MancalaResource CaptureResource("capture_testcases.csv", &random, workEnv);
    MancalaResource ELDResource("ELD_mancala_records.csv", &random, workEnv);

    std::function<double(push::Code*)> fitness_func = [TRIALS, &game, &workEnv, &test](push::Code * genome) {
        int sum = 0;
        // std::cout << "In fit fun" << std::endl;
        for (int t = 0; t < TRIALS; t++) {
            game.Reset();
            while (!game.IsOver()) {
                if (game.GetCurrPlayer()) {

                    if (t%2 == 0) {
                        emp::array<int, 14> flipped = game.GetFlippedBoard();
                        int choice = PlayMancala(&test, flipped, 0, workEnv);
                        if (choice == -1) {
                            game.ChooseCell(TrivialMove(game.GetBoard(), game.GetCurrPlayer()));
                        } else {
                            emp_assert(game.IsMoveValid(game.GetCounterpart(choice)), game.GetCounterpart(choice), choice);
                            game.ChooseCell(game.GetCounterpart(choice));
                        }
                    } else {
                        game.ChooseCell(TrivialMove(game.GetBoard(), game.GetCurrPlayer()));
                    }

                    // game.ChooseCell(thelen::ThelenMove(game, game.GetCurrPlayer()));
                } else {
                    // std::cout << "Player 0 turn" << std::endl;
                    int choice = PlayMancala(genome, game.GetBoard(), game.GetCurrPlayer(), workEnv);
                    // std::cout << "Making move " << choice << std::endl;
                    if (choice == -1) {
                        // std::cout << "Forfiting " << std::endl;
                        game.Forfeit();
                    } else {
                        // std::cout << "Not Forfiting " << std::endl;
                        game.ChooseCell(choice);
                    }
                }
                // game.PrintBoard();
            }
            // std::cout << "Score: " << game.ScoreDiff(0) << std::endl;
            sum += game.ScoreDiff(0)+48;
        }
        return sum/TRIALS;
    };

    // For EcoSelect
    emp::vector<std::function<double(push::Code*)> > extra_funs(3);
    extra_funs[0] = [&ExtraMoveResource](push::Code* org){return ExtraMoveResource.Fitness(org);};
    extra_funs[1] = [&CaptureResource](push::Code* org){return CaptureResource.Fitness(org);};
    extra_funs[2] = [&ELDResource](push::Code* org){return ELDResource.Fitness(org);};

    // std::cout << "Fitness of test: " << fitness_func(&test) << std::endl;
    // return 0;

    // For tournament select
    emp::vector<std::function<double(push::Code *)> > no_extra_funs(0);

    // For Lexicase select
    emp::vector<std::function<double(push::Code *)> > all_fit_funs(4);
    all_fit_funs[0] = fitness_func;
    all_fit_funs[1] = [&ExtraMoveResource](push::Code* org){return ExtraMoveResource.Fitness(org);};
    all_fit_funs[2] = [&CaptureResource](push::Code* org){return CaptureResource.Fitness(org);};
    all_fit_funs[3] = [&ELDResource](push::Code* org){return ELDResource.Fitness(org);};

    push::CodeBase& swapcode = *push::parse("CODE.SWAP");

    std::function<bool(push::Code*, emp::Random&)> mut_func = [&env, &swapcode](push::Code* genome, emp::Random & r) {
        push::Env workEnv(env);
        workEnv.clear_stacks();
        push::push(workEnv, *genome);

        if (r.P(0.05)) { // should be a parameter
          if (r.P(0.5)) {
              push::subtree_mutation(workEnv);
          } else {
              push::deletion_mutation(workEnv);
          }
        } else {
          swapcode(workEnv);
        //   push::subtree_xover(workEnv);
      }

      push::Code old = *genome;
      *genome = push::pop<push::Code>(workEnv);
      return old == *genome;
    };

    world.SetDefaultFitnessFun(fitness_func);
    world.SetDefaultMutateFun(mut_func);
    world.OnOffspringReady([&world, &mut_func](push::Code * org){mut_func(org, *(world.random_ptr));});

    workEnv = env.next();

    std::cout << "Starting loop" << std::endl;
    for (int ud = 0; ud < MAX_GENS; ud++) {
        if (config.SELECTION_TYPE() == "eco") {
            world.EcoSelect(fitness_func, extra_funs, 100.0, TOURNAMENT_SIZE, POP_SIZE);
        } else if (config.SELECTION_TYPE() == "tournament") {
            world.EcoSelect(fitness_func,  no_extra_funs, 100.0, TOURNAMENT_SIZE, POP_SIZE);
        } else if (config.SELECTION_TYPE() == "lexicase") {
            world.LexicaseSelect(all_fit_funs, POP_SIZE);
        } else {
            std::cout << "Invalid selection type " << config.SELECTION_TYPE() << std::endl;
            exit(1);
        }
        // std::cout << "Average fitness: "  << std::endl;
        world.Update();
        // world.MutatePop();
    }

    double sum_fitness = 0;
    double max_fitness = 0;
    push::Code fittest;
    for (auto org : world) {
        double fitness = fitness_func(org);
        // std::cout << "Fitness: " << fitness << /*" Code: " << print_code(*org, env.next()) <<*/std::endl;
        sum_fitness += fitness;
        if (fitness > max_fitness) {
            max_fitness = fitness;
            fittest = *org;
        }
        // static push::Env env(1000);
        // int sum = 0;
        // game.Reset();
        // // std::cout << "In fit fun" << std::endl;
        // while (!game.IsOver()) {
        //     if (game.GetCurrPlayer()) {
        //         game.ChooseCell(TrivialMove(game.GetBoard(), game.GetCurrPlayer()));
        //     } else {
        //         // std::cout << "Player 0 turn" << std::endl;
        //         env = workEnv;
        //         env.clear_stacks();
        //
        //
        //         for (int count : game.GetBoard()) {
        //             push::push<int>(env, count);
        //         }
        //         // std::cout << "Booard initialized" << std::endl;
        //         push::push_call(env, *org);
        //         env.go(1000);
        //         // std::cout << "Code called" << std::endl;
        //         int choice = -1;
        //         if (push::has_elements<int>(env,1)) {
        //             choice = push::pop<int>(env);
        //         }
        //         // std::cout << "Validating move" << std::endl;
        //         while (!game.IsMoveValid(choice)) {
        //             if (push::has_elements<int>(env,1)) {
        //                 choice = push::pop<int>(env);
        //             } else {
        //                 choice = TrivialMove(game.GetBoard(), game.GetCurrPlayer());
        //             }
        //         }
        //
        //         // std::cout << "Making move " << choice << std::endl;
        //
        //         game.ChooseCell(choice);
        //     }
        //     game.PrintBoard();
        // }
        // std::cout << "Score: " << game.ScoreDiff(0) << std::endl;

    }
    std::cout << "Average fitness: " << sum_fitness/POP_SIZE << " Max fitness: " << max_fitness << std::endl;
    workEnv = env;
    std::cout << print_code(fittest, workEnv) << std::endl;

}
<commit_msg>Play against random<commit_after>#include "evo/World.h"
#include "mancala.h"

#include <functional>
#include <fstream>
#include <vector>
#include <valarray>
#include <set>

#include "../push-3.1.0/src/CodeUtils.h"
#include "../push-3.1.0/src/RNG.h"
#include "../push-3.1.0/src/GeneticOps.h"
#include "../push-3.1.0/src/Instruction.h"
#include "../push-3.1.0/src/Literal.h"

#include "config/ArgManager.h"
#include "../handcoded_AI/Mancala/mancala/AI-Trivial.hh"
// #include "../handcoded_AI/mancala/mancala/contest/AI-Thelen.hh"
#include "play_mancala.h"
#include "MancalaResource.h"

EMP_BUILD_CONFIG( EcoEaConfig,
  GROUP(DEFAULT, "Default settings for NK model"),
  VALUE(TRIALS, uint32_t, 10, "Level of epistasis in the NK model"),
  VALUE(SEED, int, 0, "Random number seed (0 for based on time)"),
  VALUE(POP_SIZE, uint32_t, 100, "Number of organisms in the popoulation."),
  VALUE(TOURNAMENT_SIZE, uint32_t, 5, "Number of organisms in the popoulation."),
  VALUE(MAX_GENS, uint32_t, 2000, "How many generations should we process?"),
  VALUE(SELECTION_TYPE, std::string, "eco", "What type of selection? eco, tournament, or lexicase")
)

template <typename WORLD>
void init(WORLD & world, const push::Env& env, int POP_SIZE) {
    static push::Env workEnv(1000);
    static push::Code rnd = push::parse("CODE.RAND");

    for (int i = 0; i < POP_SIZE; ++i) {
        workEnv = env;
        (*rnd)(workEnv);
        if (not push::has_elements<push::Code>(workEnv,1)) { --i; continue; }
    	push::Code code = push::pop<push::Code>(workEnv); // get random program
        // std::cout << "About to insert " << i << std::endl;
        world.Insert(code);
    }

}

std::string print_code(push::Code code, push::Env& env) {

    if (code->size() == 1) {
	std::string result = code->to_string();

	// check if it's a name
	push::Literal<push::name_t>* name = dynamic_cast< push::Literal<push::name_t>* >(code.get());
	if (name) {
	    result += std::string(":") + get_code(name->get())->to_string();
	}

	return result;
    }

    std::string result = "( ";
    const push::CodeArray& pieces = code->get_stack();
    for (int i = pieces.size()-1; i >= 0; --i) {
	result += print_code(pieces[i], env);
	result += " ";
    }
    return result + " )";
}

int main(int argc, char* argv[] ) {
    EcoEaConfig config;

    config.Read("EcoEAPush.cfg");

    auto args = emp::cl::ArgManager(argc, argv);
    if (args.ProcessConfigOptions(config, std::cout, "EcoEAPush.cfg", "EcoEAPush-macros.h") == false) {
      exit(0);
    }
    if (args.TestUnknown() == false) exit(0);  // If there are leftover args, throw an error.

    const uint32_t POP_SIZE = config.POP_SIZE();
    const uint32_t MAX_GENS = config.MAX_GENS();
    const uint32_t TRIALS = config.TRIALS();
    const uint32_t TOURNAMENT_SIZE = config.TOURNAMENT_SIZE();

    push::init_push();
    // std::string config_file = "test.config";
    // std::ifstream push_config( config_file.c_str() );
    emp::Random random(config.SEED());
    emp::evo::World<push::Code, emp::evo::DefaultStats> world(random);
    world.fitM.Resize(POP_SIZE);
    Mancala game;
    push::Env env;

    // env.configure(push::parse(push_config));
    env = env.next();
    push::Code test = push::parse("( CODE.FROMFLOAT ( EXEC.STACKDEPTH 6 ( CODE.POSITION FLOAT.= CODE.DO  ) ( NAME.QUOTE  )  ) ( () EXEC.STACKDEPTH CODE.CONS ( ( CODE.EXTRACT EXEC.POP ( _3:(NAME.QUOTE _3) () () _1:TRUE ( ( ( CODE.CONS CODE.NTHCDR  ) ENV.RANDOM-SEED ( ( INTEGER.FROMBOOLEAN  ) CODE.NTH  )  ) ( ( INTEGER./ NAME.STACKDEPTH  ) 0  ) ( CODE.QUOTE ( EXEC.ROT BOOLEAN.POP : FLOAT.MAX  )  ) NAME.DUP ( EXEC.DEFINE  ) BOOLEAN.SWAP  )  )  ) ( EXEC.YANK  ) ENV.MAX-RANDOM-FLOAT  )  ) ( CODE.DEFINE CODE.POP  )  )");

    push::Env workEnv(env);

    // std::cout << "Loaded: " << print_code(test, env.next()) << std::endl;

    // std::cout << "about to initialize" << std::endl;
    init(world, env, POP_SIZE);
    // std::cout << "Initialize" << std::endl;

    // workEnv = env;

    MancalaResource ExtraMoveResource("extra_move_testcases.csv", &random, workEnv);
    MancalaResource CaptureResource("capture_testcases.csv", &random, workEnv);
    MancalaResource ELDResource("ELD_mancala_records.csv", &random, workEnv);

    std::function<double(push::Code*)> fitness_func = [TRIALS, &game, &workEnv, &test](push::Code * genome) {
        int sum = 0;
        // std::cout << "In fit fun" << std::endl;
        for (int t = 0; t < TRIALS; t++) {
            game.Reset();
            while (!game.IsOver()) {
                if (game.GetCurrPlayer()) {

                    // if (t%2 == 0) {
                    //     emp::array<int, 14> flipped = game.GetFlippedBoard();
                    //     int choice = PlayMancala(&test, flipped, 0, workEnv);
                    //     if (choice == -1) {
                    //         game.ChooseCell(TrivialMove(game.GetBoard(), game.GetCurrPlayer()));
                    //     } else {
                    //         emp_assert(game.IsMoveValid(game.GetCounterpart(choice)), game.GetCounterpart(choice), choice);
                    //         game.ChooseCell(game.GetCounterpart(choice));
                    //     }
                    // } else {
                        game.ChooseCell(TrivialMove(game.GetBoard(), game.GetCurrPlayer()));
                    // }

                    // game.ChooseCell(thelen::ThelenMove(game, game.GetCurrPlayer()));
                } else {
                    // std::cout << "Player 0 turn" << std::endl;
                    int choice = PlayMancala(genome, game.GetBoard(), game.GetCurrPlayer(), workEnv);
                    // std::cout << "Making move " << choice << std::endl;
                    if (choice == -1) {
                        // std::cout << "Forfiting " << std::endl;
                        game.Forfeit();
                    } else {
                        // std::cout << "Not Forfiting " << std::endl;
                        game.ChooseCell(choice);
                    }
                }
                // game.PrintBoard();
            }
            // std::cout << "Score: " << game.ScoreDiff(0) << std::endl;
            sum += game.ScoreDiff(0)+48;
        }
        return sum/TRIALS;
    };

    // For EcoSelect
    emp::vector<std::function<double(push::Code*)> > extra_funs(3);
    extra_funs[0] = [&ExtraMoveResource](push::Code* org){return ExtraMoveResource.Fitness(org);};
    extra_funs[1] = [&CaptureResource](push::Code* org){return CaptureResource.Fitness(org);};
    extra_funs[2] = [&ELDResource](push::Code* org){return ELDResource.Fitness(org);};

    // std::cout << "Fitness of test: " << fitness_func(&test) << std::endl;
    // return 0;

    // For tournament select
    emp::vector<std::function<double(push::Code *)> > no_extra_funs(0);

    // For Lexicase select
    emp::vector<std::function<double(push::Code *)> > all_fit_funs(4);
    all_fit_funs[0] = fitness_func;
    all_fit_funs[1] = [&ExtraMoveResource](push::Code* org){return ExtraMoveResource.Fitness(org);};
    all_fit_funs[2] = [&CaptureResource](push::Code* org){return CaptureResource.Fitness(org);};
    all_fit_funs[3] = [&ELDResource](push::Code* org){return ELDResource.Fitness(org);};

    push::CodeBase& swapcode = *push::parse("CODE.SWAP");

    std::function<bool(push::Code*, emp::Random&)> mut_func = [&env, &swapcode](push::Code* genome, emp::Random & r) {
        push::Env workEnv(env);
        workEnv.clear_stacks();
        push::push(workEnv, *genome);

        if (r.P(0.05)) { // should be a parameter
          if (r.P(0.5)) {
              push::subtree_mutation(workEnv);
          } else {
              push::deletion_mutation(workEnv);
          }
        } else {
          swapcode(workEnv);
        //   push::subtree_xover(workEnv);
      }

      push::Code old = *genome;
      *genome = push::pop<push::Code>(workEnv);
      return old == *genome;
    };

    world.SetDefaultFitnessFun(fitness_func);
    world.SetDefaultMutateFun(mut_func);
    world.OnOffspringReady([&world, &mut_func](push::Code * org){mut_func(org, *(world.random_ptr));});

    workEnv = env.next();

    std::cout << "Starting loop" << std::endl;
    for (int ud = 0; ud < MAX_GENS; ud++) {
        if (config.SELECTION_TYPE() == "eco") {
            world.EcoSelect(fitness_func, extra_funs, 100.0, TOURNAMENT_SIZE, POP_SIZE);
        } else if (config.SELECTION_TYPE() == "tournament") {
            world.EcoSelect(fitness_func,  no_extra_funs, 100.0, TOURNAMENT_SIZE, POP_SIZE);
        } else if (config.SELECTION_TYPE() == "lexicase") {
            world.LexicaseSelect(all_fit_funs, POP_SIZE);
        } else {
            std::cout << "Invalid selection type " << config.SELECTION_TYPE() << std::endl;
            exit(1);
        }
        // std::cout << "Average fitness: "  << std::endl;
        world.Update();
        // world.MutatePop();
    }

    double sum_fitness = 0;
    double max_fitness = 0;
    push::Code fittest;
    for (auto org : world) {
        double fitness = fitness_func(org);
        // std::cout << "Fitness: " << fitness << /*" Code: " << print_code(*org, env.next()) <<*/std::endl;
        sum_fitness += fitness;
        if (fitness > max_fitness) {
            max_fitness = fitness;
            fittest = *org;
        }
        // static push::Env env(1000);
        // int sum = 0;
        // game.Reset();
        // // std::cout << "In fit fun" << std::endl;
        // while (!game.IsOver()) {
        //     if (game.GetCurrPlayer()) {
        //         game.ChooseCell(TrivialMove(game.GetBoard(), game.GetCurrPlayer()));
        //     } else {
        //         // std::cout << "Player 0 turn" << std::endl;
        //         env = workEnv;
        //         env.clear_stacks();
        //
        //
        //         for (int count : game.GetBoard()) {
        //             push::push<int>(env, count);
        //         }
        //         // std::cout << "Booard initialized" << std::endl;
        //         push::push_call(env, *org);
        //         env.go(1000);
        //         // std::cout << "Code called" << std::endl;
        //         int choice = -1;
        //         if (push::has_elements<int>(env,1)) {
        //             choice = push::pop<int>(env);
        //         }
        //         // std::cout << "Validating move" << std::endl;
        //         while (!game.IsMoveValid(choice)) {
        //             if (push::has_elements<int>(env,1)) {
        //                 choice = push::pop<int>(env);
        //             } else {
        //                 choice = TrivialMove(game.GetBoard(), game.GetCurrPlayer());
        //             }
        //         }
        //
        //         // std::cout << "Making move " << choice << std::endl;
        //
        //         game.ChooseCell(choice);
        //     }
        //     game.PrintBoard();
        // }
        // std::cout << "Score: " << game.ScoreDiff(0) << std::endl;

    }
    std::cout << "Average fitness: " << sum_fitness/POP_SIZE << " Max fitness: " << max_fitness << std::endl;
    workEnv = env;
    std::cout << print_code(fittest, workEnv) << std::endl;

}
<|endoftext|>


<commit_before>/* <x0/mod_dirlisting.cpp>
 *
 * This file is part of the x0 web server project and is released under LGPL-3.
 *
 * (c) 2009 Chrisitan Parpart <trapni@gentoo.org>
 */

#include <x0/server.hpp>
#include <x0/request.hpp>
#include <x0/response.hpp>
#include <x0/header.hpp>
#include <x0/strutils.hpp>
#include <x0/types.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/bind.hpp>
#include <cstring>
#include <cerrno>
#include <cstddef>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>

/**
 * \ingroup plugins
 * \brief implements automatic content generation for raw directories
 */
class dirlisting_plugin :
	public x0::plugin
{
private:
	x0::handler::connection c;

	struct context
	{
		bool enabled;
		std::string xsluri;
	};

public:
	dirlisting_plugin(x0::server& srv, const std::string& name) :
		x0::plugin(srv, name)
	{
		c = server_.generate_content.connect(boost::bind(&dirlisting_plugin::dirlisting, this, _1, _2));
	}

	~dirlisting_plugin()
	{
		server_.generate_content.disconnect(c);
	}

	virtual void configure()
	{
		std::string default_uri;
		server_.config()["DirectoryListing"]["XslUri"].load(default_uri);

		auto hosts = server_.config()["Hosts"].keys<std::string>();
		for (auto i = hosts.begin(), e = hosts.end(); i != e; ++i)
		{
			bool enabled;

			if (server_.config()["Hosts"][*i]["DirectoryListing"]["Enabled"].load(enabled)
			 || server_.config()["DirectoryListing"]["Enabled"].load(enabled))
			{
				context& ctx = server_.create_context<context>(this, *i);
				ctx.enabled = enabled;
				ctx.xsluri = server_.config()["Hosts"][*i]["DirectoryListing"]["XslUri"].get(default_uri);
			}
		}
	}

private:
	bool dirlisting(x0::request& in, x0::response& out)
	{
		try
		{
			context& ctx = server_.context<context>(this, in.hostid());

			if (!ctx.enabled)
				return false;

			if (!in.fileinfo->is_directory())
				return false;

			if (DIR *dir = opendir(in.fileinfo->filename().c_str()))
			{
				bool xml = !ctx.xsluri.empty();
				std::string result(xml ? mkxml(dir, ctx, in) : mkplain(dir, in));

				out *= x0::response_header("Content-Type", xml ? "text/xml" : "text/html");
				out *= x0::response_header("Content-Length", boost::lexical_cast<std::string>(result.size()));

				out.write(result);

				out.flush();
				closedir(dir);

				return true;
			}
		}
		catch (const x0::context::not_found_error&)
		{
			// eat up and default to `unhandled`
		}
		return false;
	}

	std::string mkplain(DIR *dir, x0::request& in)
	{
		std::list<std::string> listing;
		listing.push_back("..");

		int len = offsetof(dirent, d_name) + pathconf(in.fileinfo->filename().c_str(), _PC_NAME_MAX);
		dirent *dep = (dirent *)new unsigned char[len + 1];
		dirent *res = 0;

		while (readdir_r(dir, dep, &res) == 0 && res)
		{
			std::string name(dep->d_name);

			if (name[0] != '.')
			{
				if (x0::fileinfo_ptr fi = in.connection.server().fileinfo(in.fileinfo->filename() + "/" + name))
				{
					if (fi->is_directory())
						name += "/";

					listing.push_back(name);
				}
			}
		}

		delete[] dep;

		std::stringstream sstr;
		sstr << "<title>Directory: "
			 << in.path
			 << "</title>\n\n";

		sstr << "
Index of " << in.path << "
\n";
		sstr << "

\n";

		for (std::list<std::string>::iterator i = listing.begin(), e = listing.end(); i != e; ++i)
		{
			sstr << "
<a href='" << *i << "'>" << *i << "
\n";
		}

		sstr << "
\n";

		sstr << "
\n";
		sstr << "" << in.connection.server().tag() << "
\n";

		sstr << "\n";

		return sstr.str();
	}

	std::string mkxml(DIR *dir, context& ctx, x0::request& in)
	{
		std::stringstream xml;

		xml << "<?xml version='1.0' encoding='" << "utf-8" << "'?>\n";

		if (!ctx.xsluri.empty())
			xml << "<?xml-stylesheet type='text/xsl' href='" << ctx.xsluri << "'?>\n";

		xml << "<dirlisting path='" << in.path << "' tag='" << server_.tag() << "'>\n";

		int len = offsetof(dirent, d_name) + pathconf(in.fileinfo->filename().c_str(), _PC_NAME_MAX);
		dirent *dep = (dirent *)new unsigned char[len + 1];
		dirent *res = 0;

		while (readdir_r(dir, dep, &res) == 0 && res)
		{
			std::string name(dep->d_name);

			if (name[0] == '.')
				continue;

			if (x0::fileinfo_ptr fi = in.connection.server().fileinfo(in.fileinfo->filename() + "/" + name))
			{
				if (fi->is_directory())
					name += "/";

				xml << "<item name='" << name
					<< "' size='" << fi->size()
					<< "' mtime='" << fi->last_modified()
					<< "' mimetype='" << fi->mimetype()
					<< "' />\n";
			}
		}

		xml << "</dirlisting>\n";

		return xml.str();
	}
};

X0_EXPORT_PLUGIN(dirlisting);
<commit_msg>dirlisting: fix xml output (request path accidentally converted to bool)<commit_after>/* <x0/mod_dirlisting.cpp>
 *
 * This file is part of the x0 web server project and is released under LGPL-3.
 *
 * (c) 2009 Chrisitan Parpart <trapni@gentoo.org>
 */

#include <x0/server.hpp>
#include <x0/request.hpp>
#include <x0/response.hpp>
#include <x0/header.hpp>
#include <x0/strutils.hpp>
#include <x0/types.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/bind.hpp>
#include <cstring>
#include <cerrno>
#include <cstddef>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>

/**
 * \ingroup plugins
 * \brief implements automatic content generation for raw directories
 */
class dirlisting_plugin :
	public x0::plugin
{
private:
	x0::handler::connection c;

	struct context
	{
		bool enabled;
		std::string xsluri;
	};

public:
	dirlisting_plugin(x0::server& srv, const std::string& name) :
		x0::plugin(srv, name)
	{
		c = server_.generate_content.connect(boost::bind(&dirlisting_plugin::dirlisting, this, _1, _2));
	}

	~dirlisting_plugin()
	{
		server_.generate_content.disconnect(c);
	}

	virtual void configure()
	{
		std::string default_uri;
		server_.config()["DirectoryListing"]["XslUri"].load(default_uri);

		auto hosts = server_.config()["Hosts"].keys<std::string>();
		for (auto i = hosts.begin(), e = hosts.end(); i != e; ++i)
		{
			bool enabled;

			if (server_.config()["Hosts"][*i]["DirectoryListing"]["Enabled"].load(enabled)
			 || server_.config()["DirectoryListing"]["Enabled"].load(enabled))
			{
				context& ctx = server_.create_context<context>(this, *i);
				ctx.enabled = enabled;
				ctx.xsluri = server_.config()["Hosts"][*i]["DirectoryListing"]["XslUri"].get(default_uri);
			}
		}
	}

private:
	bool dirlisting(x0::request& in, x0::response& out)
	{
		try
		{
			context& ctx = server_.context<context>(this, in.hostid());

			if (!ctx.enabled)
				return false;

			if (!in.fileinfo->is_directory())
				return false;

			if (DIR *dir = opendir(in.fileinfo->filename().c_str()))
			{
				bool xml = !ctx.xsluri.empty();
				std::string result(xml ? mkxml(dir, ctx, in) : mkplain(dir, in));

				out *= x0::response_header("Content-Type", xml ? "text/xml" : "text/html");
				out *= x0::response_header("Content-Length", boost::lexical_cast<std::string>(result.size()));

				out.write(result);

				out.flush();
				closedir(dir);

				return true;
			}
		}
		catch (const x0::context::not_found_error&)
		{
			// eat up and default to `unhandled`
		}
		return false;
	}

	std::string mkplain(DIR *dir, x0::request& in)
	{
		std::list<std::string> listing;
		listing.push_back("..");

		int len = offsetof(dirent, d_name) + pathconf(in.fileinfo->filename().c_str(), _PC_NAME_MAX);
		dirent *dep = (dirent *)new unsigned char[len + 1];
		dirent *res = 0;

		while (readdir_r(dir, dep, &res) == 0 && res)
		{
			std::string name(dep->d_name);

			if (name[0] != '.')
			{
				if (x0::fileinfo_ptr fi = in.connection.server().fileinfo(in.fileinfo->filename() + "/" + name))
				{
					if (fi->is_directory())
						name += "/";

					listing.push_back(name);
				}
			}
		}

		delete[] dep;

		std::stringstream sstr;
		sstr << "<title>Directory: "
			 << in.path
			 << "</title>\n\n";

		sstr << "
Index of " << in.path << "
\n";
		sstr << "

\n";

		for (std::list<std::string>::iterator i = listing.begin(), e = listing.end(); i != e; ++i)
		{
			sstr << "
<a href='" << *i << "'>" << *i << "
\n";
		}

		sstr << "
\n";

		sstr << "
\n";
		sstr << "" << in.connection.server().tag() << "
\n";

		sstr << "\n";

		return sstr.str();
	}

	std::string mkxml(DIR *dir, context& ctx, x0::request& in)
	{
		std::stringstream xml;

		xml << "<?xml version='1.0' encoding='" << "utf-8" << "'?>\n";

		if (!ctx.xsluri.empty())
			xml << "<?xml-stylesheet type='text/xsl' href='" << ctx.xsluri << "'?>\n";

		xml << "<dirlisting path='" << in.path.str() << "' tag='" << server_.tag() << "'>\n";

		int len = offsetof(dirent, d_name) + pathconf(in.fileinfo->filename().c_str(), _PC_NAME_MAX);
		dirent *dep = (dirent *)new unsigned char[len + 1];
		dirent *res = 0;

		while (readdir_r(dir, dep, &res) == 0 && res)
		{
			std::string name(dep->d_name);

			if (name[0] == '.')
				continue;

			if (x0::fileinfo_ptr fi = in.connection.server().fileinfo(in.fileinfo->filename() + "/" + name))
			{
				if (fi->is_directory())
					name += "/";

				xml << "<item name='" << name
					<< "' size='" << fi->size()
					<< "' mtime='" << fi->last_modified()
					<< "' mimetype='" << fi->mimetype()
					<< "' />\n";
			}
		}

		xml << "</dirlisting>\n";

		return xml.str();
	}
};

X0_EXPORT_PLUGIN(dirlisting);
<|endoftext|>


<commit_before>// Copyright (C) 2011 Oliver Schulz <oliver.schulz@tu-dortmund.de>

// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

#include "Selector.h"

#include <iostream>
#include <sstream>
#include <cassert>
#include <cassert>

#include <TFile.h>
#include <TObjArray.h>
#include <TChainElement.h>
#include <TPRegexp.h>

#include "util.h"
#include "File.h"

ClassImp(froast::Selector)

using namespace std;

using namespace std;

namespace froast {

void Selector::copyObject(TDirectory *tdir, const TString &objName) {
	TObject *keepObj = 0;
	tdir->GetObject(objName.Data(), keepObj);
	if (keepObj != 0) {
		TTree *keepTree = dynamic_cast<TTree*>(keepObj);
		if (keepTree != 0) {
			TTree *cloned = keepTree->CloneTree();
			cloned->Write();
		}
	} else {
		throw runtime_error(string("Object ") + objName.Data() + " not found in TDirectory");
	}
}

void Selector::mapMulti(TChain *chain, const TString &selector, const TString &tag, const TString &keep) {
	TObjArray *chainElems = chain->GetListOfFiles();
	for (int chainEntry = 0; chainEntry < chainElems->GetEntriesFast(); ++chainEntry) {
		TChainElement *e = dynamic_cast<TChainElement*>(chainElems->At(chainEntry));
		string treeName = e->GetName();
		string inFileName = e->GetTitle();

		string outFileName = (File(inFileName).base() % tag.Data()).path();
		cerr << "Mapping " << inFileName << ":" << treeName << " to " << outFileName << endl;

		TFile inFile(inFileName.c_str(), "read");
		TTree *inTree; inFile.GetObject(treeName.c_str(), inTree);

		TFile outFile(outFileName.c_str(), "recreate");

		TSelector *sel = TSelector::GetSelector(selector.Data());
		if (sel == 0) throw runtime_error(string("Cannot load selector ") + selector.Data());
		inTree->Process(sel);
		delete sel;

		TObjArray* keeps = keep.Tokenize(",");
		for (int i = 0; i < keeps->GetEntriesFast(); ++i) {
			TString keepObjName = dynamic_cast<TObjString*>(keeps->At(i))->GetString().Strip(TString::kBoth);
			cerr << "Copying object " << keepObjName << " to output" << endl;
			copyObject(&inFile, keepObjName);
		}
		delete keeps;

		Settings::writeToGDirectory();
		outFile.Write();
		outFile.Close();
		inFile.Close();
	}
}

void Selector::mapSingle(const TString &inFileName, const TString &mappers, const TString &outFileName, bool noRecompile) {
	TFile inFile(inFileName.Data(), "read");
	TFile outFile(outFileName.Data(), "recreate");

	TPRegexp mapperSpecExpr("^(.*)\\((.*)\\)$");
	TPRegexp xxExp("\\+\\+$");

	TObjArray* mapperNames = mappers.Tokenize(",");
	for (int mapperEntry = 0; mapperEntry < mapperNames->GetEntriesFast(); ++mapperEntry) {
		TString mapper = dynamic_cast<TObjString*>(mapperNames->At(mapperEntry))->GetString().Strip(TString::kBoth);
		TObjArray* matches = mapperSpecExpr.MatchS(mapper);
		if (matches->GetEntriesFast() == 3) {
			TString fctName = dynamic_cast<TObjString*>(matches->At(1))->GetString();
			if (noRecompile) xxExp.Substitute(fctName, "+");
			TString objName = dynamic_cast<TObjString*>(matches->At(2))->GetString();
			assert ((fctName != 0) && (objName != 0));
			delete matches;

			cerr << "Applying " << fctName << "(" << objName << ")" << endl;

			TObject *inObj; inFile.GetObject(objName.Data(), inObj);
			if (inObj != 0) {
				TTree *inTree = dynamic_cast<TTree*>(inObj);
				if (inTree != 0) {
					if (fctName == "copy") {
						TTree *copied = inTree->CloneTree();
						copied->Write();
					} else {
						TSelector *sel = TSelector::GetSelector(fctName.Data());
						if (sel == 0) throw runtime_error(string("Cannot load selector ") + fctName.Data());
						inTree->Process(sel);
						delete sel;
					}
				} else throw invalid_argument(string("Objects of type ") + inObj->Class()->GetName() + " not supported yet");
			} else {
				delete matches;
				throw runtime_error(string("Object ") + objName.Data() + " not found in TDirectory");
			}
		} else {
			delete matches;
			throw invalid_argument(string("Invalid mapper specification: \"") + mapper.Data() + "\"");
		}
	}
	delete mapperNames;

	Settings::writeToGDirectory();
	outFile.Write();
	outFile.Close();
	inFile.Close();
}

void Selector::mapMulti(const TString &fileName, const TString &mappers, const TString &tag, bool noRecompile) {
	cerr << TString::Format("Selector::map(%s, %s, %s)", fileName.Data(), mappers.Data(), tag.Data()) << endl;

	TChain chain("");
	chain.Add(fileName.Data());
	TObjArray *chainElems = chain.GetListOfFiles();
	for (int chainEntry = 0; chainEntry < chainElems->GetEntriesFast(); ++chainEntry) {
		TChainElement *e = dynamic_cast<TChainElement*>(chainElems->At(chainEntry));
		string inFileName = e->GetTitle();

		string outFileName = (File(inFileName).base() % tag.Data()).path();
		cerr << "Mapping " << inFileName << " to " << outFileName << endl;
		// Don't recompile even if fct ends with "++" after first run:
		mapSingle(inFileName, mappers, outFileName, (chainEntry > 0) || noRecompile);
	}
	cerr << "Selector::map(...) finished" << endl;
}

} // namespace froast
<commit_msg>Added setting "froast.tfile.compression.level"<commit_after>// Copyright (C) 2011 Oliver Schulz <oliver.schulz@tu-dortmund.de>

// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

#include "Selector.h"

#include <iostream>
#include <sstream>
#include <cassert>
#include <cassert>

#include <TFile.h>
#include <TObjArray.h>
#include <TChainElement.h>
#include <TPRegexp.h>

#include "util.h"
#include "File.h"

ClassImp(froast::Selector)

using namespace std;

using namespace std;

namespace froast {

void Selector::copyObject(TDirectory *tdir, const TString &objName) {
	TObject *keepObj = 0;
	tdir->GetObject(objName.Data(), keepObj);
	if (keepObj != 0) {
		TTree *keepTree = dynamic_cast<TTree*>(keepObj);
		if (keepTree != 0) {
			TTree *cloned = keepTree->CloneTree();
			cloned->Write();
		}
	} else {
		throw runtime_error(string("Object ") + objName.Data() + " not found in TDirectory");
	}
}

void Selector::mapMulti(TChain *chain, const TString &selector, const TString &tag, const TString &keep) {
	TObjArray *chainElems = chain->GetListOfFiles();
	for (int chainEntry = 0; chainEntry < chainElems->GetEntriesFast(); ++chainEntry) {
		TChainElement *e = dynamic_cast<TChainElement*>(chainElems->At(chainEntry));
		string treeName = e->GetName();
		string inFileName = e->GetTitle();

		string outFileName = (File(inFileName).base() % tag.Data()).path();
		cerr << "Mapping " << inFileName << ":" << treeName << " to " << outFileName << endl;

		TFile inFile(inFileName.c_str(), "read");
		TTree *inTree; inFile.GetObject(treeName.c_str(), inTree);

		TFile outFile(outFileName.c_str(), "recreate");
		outFile.SetCompressionLevel(Settings::get("froast.tfile.compression.level", 1));

		TSelector *sel = TSelector::GetSelector(selector.Data());
		if (sel == 0) throw runtime_error(string("Cannot load selector ") + selector.Data());
		inTree->Process(sel);
		delete sel;

		TObjArray* keeps = keep.Tokenize(",");
		for (int i = 0; i < keeps->GetEntriesFast(); ++i) {
			TString keepObjName = dynamic_cast<TObjString*>(keeps->At(i))->GetString().Strip(TString::kBoth);
			cerr << "Copying object " << keepObjName << " to output" << endl;
			copyObject(&inFile, keepObjName);
		}
		delete keeps;

		Settings::writeToGDirectory();
		outFile.Write();
		outFile.Close();
		inFile.Close();
	}
}

void Selector::mapSingle(const TString &inFileName, const TString &mappers, const TString &outFileName, bool noRecompile) {
	TFile inFile(inFileName.Data(), "read");
	TFile outFile(outFileName.Data(), "recreate");
	outFile.SetCompressionLevel(Settings::get("froast.tfile.compression.level", 1));

	TPRegexp mapperSpecExpr("^(.*)\\((.*)\\)$");
	TPRegexp xxExp("\\+\\+$");

	TObjArray* mapperNames = mappers.Tokenize(",");
	for (int mapperEntry = 0; mapperEntry < mapperNames->GetEntriesFast(); ++mapperEntry) {
		TString mapper = dynamic_cast<TObjString*>(mapperNames->At(mapperEntry))->GetString().Strip(TString::kBoth);
		TObjArray* matches = mapperSpecExpr.MatchS(mapper);
		if (matches->GetEntriesFast() == 3) {
			TString fctName = dynamic_cast<TObjString*>(matches->At(1))->GetString();
			if (noRecompile) xxExp.Substitute(fctName, "+");
			TString objName = dynamic_cast<TObjString*>(matches->At(2))->GetString();
			assert ((fctName != 0) && (objName != 0));
			delete matches;

			cerr << "Applying " << fctName << "(" << objName << ")" << endl;

			TObject *inObj; inFile.GetObject(objName.Data(), inObj);
			if (inObj != 0) {
				TTree *inTree = dynamic_cast<TTree*>(inObj);
				if (inTree != 0) {
					if (fctName == "copy") {
						TTree *copied = inTree->CloneTree();
						copied->Write();
					} else {
						TSelector *sel = TSelector::GetSelector(fctName.Data());
						if (sel == 0) throw runtime_error(string("Cannot load selector ") + fctName.Data());
						inTree->Process(sel);
						delete sel;
					}
				} else throw invalid_argument(string("Objects of type ") + inObj->Class()->GetName() + " not supported yet");
			} else {
				delete matches;
				throw runtime_error(string("Object ") + objName.Data() + " not found in TDirectory");
			}
		} else {
			delete matches;
			throw invalid_argument(string("Invalid mapper specification: \"") + mapper.Data() + "\"");
		}
	}
	delete mapperNames;

	Settings::writeToGDirectory();
	outFile.Write();
	outFile.Close();
	inFile.Close();
}

void Selector::mapMulti(const TString &fileName, const TString &mappers, const TString &tag, bool noRecompile) {
	cerr << TString::Format("Selector::map(%s, %s, %s)", fileName.Data(), mappers.Data(), tag.Data()) << endl;

	TChain chain("");
	chain.Add(fileName.Data());
	TObjArray *chainElems = chain.GetListOfFiles();
	for (int chainEntry = 0; chainEntry < chainElems->GetEntriesFast(); ++chainEntry) {
		TChainElement *e = dynamic_cast<TChainElement*>(chainElems->At(chainEntry));
		string inFileName = e->GetTitle();

		string outFileName = (File(inFileName).base() % tag.Data()).path();
		cerr << "Mapping " << inFileName << " to " << outFileName << endl;
		// Don't recompile even if fct ends with "++" after first run:
		mapSingle(inFileName, mappers, outFileName, (chainEntry > 0) || noRecompile);
	}
	cerr << "Selector::map(...) finished" << endl;
}

} // namespace froast
<|endoftext|>


<commit_before>#pragma ident "$Id: ANSITime.cpp 1162 2008-03-27 21:18:13Z snelsen $"

//============================================================================
//
//  This file is part of GPSTk, the GPS Toolkit.
//
//  The GPSTk is free software; you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License as published
//  by the Free Software Foundation; either version 2.1 of the License, or
//  any later version.
//
//  The GPSTk 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 GPSTk; if not, write to the Free Software Foundation,
//  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Copyright 2004, The University of Texas at Austin
//
//============================================================================

#include <cmath>
#include "ANSITime.hpp"
#include "TimeConstants.hpp"

using namespace gpstk;

namespace Rinex3
{
   ANSITime& ANSITime::operator=( const ANSITime& right )
      throw()
   {
      time = right.time;
      return *this;
   }

   CommonTime ANSITime::convertToCommonTime() const
      throw(InvalidRequest)
   {
      try
      {
         return CommonTime( ( MJD_JDAY + UNIX_MJD + time / SEC_PER_DAY ),
                            ( time % SEC_PER_DAY ),
                            0.,
                            timeSystem );
      }
      catch (InvalidParameter& ip)
      {
         InvalidRequest ir(ip);
         GPSTK_THROW(ir);
      }
   }

   void ANSITime::convertFromCommonTime( const CommonTime& ct )
      throw(InvalidRequest)
   {
         /// This is the earliest CommonTime for which ANSITimes are valid.
     static const CommonTime MIN_CT = ANSITime(0, Any);
         /// This is the latest CommonTime for which ANSITimes are valid.
         /// 2^31 - 1 seconds
       static const CommonTime MAX_CT = ANSITime(2147483647, Any);

      if ( ct < MIN_CT || ct > MAX_CT )
      {
         InvalidRequest ir("Unable to convert given CommonTime to ANSITime.");
         GPSTK_THROW(ir);
      }

      long jday, sod;
      double fsod;
      TimeSystem timeSys;
      ct.get( jday, sod, fsod, timeSys );

      time =
         static_cast<time_t>((jday - MJD_JDAY - UNIX_MJD) * SEC_PER_DAY + sod);

      timeSystem = timeSys;
   }

   std::string ANSITime::printf( const std::string& fmt) const
      throw( gpstk::StringUtils::StringException )
   {
      try
      {
         using gpstk::StringUtils::formattedPrint;
         std::string rv( fmt );

         rv = formattedPrint( rv, getFormatPrefixInt() + "K",
                              "Klu", time );
         rv = formattedPrint( rv, getFormatPrefixInt() + "P",
                              "Pu", timeSystem );
         return rv;
      }
      catch( gpstk::StringUtils::StringException& se )
      {
         GPSTK_RETHROW( se );
      }
   }

   std::string ANSITime::printError( const std::string& fmt) const
      throw( gpstk::StringUtils::StringException )
   {
      try
      {
         using gpstk::StringUtils::formattedPrint;
         std::string rv( fmt );

         rv = formattedPrint( rv, getFormatPrefixInt() + "K",
                              "Ks", getError().c_str() );
         rv = formattedPrint( rv, getFormatPrefixInt() + "P",
                              "Ps", getError().c_str() );
         return rv;
      }
      catch( gpstk::StringUtils::StringException& se )
      {
         GPSTK_RETHROW( se );
      }
   }

   bool ANSITime::setFromInfo( const IdToValue& info )
      throw()
   {
      using namespace gpstk::StringUtils;

      for( IdToValue::const_iterator i = info.begin(); i != info.end(); i++ )
      {
         switch( i->first )
         {
            case 'K':
               time = asInt( i->second );
               break;

            case 'P':
               timeSystem = (TimeSystem) asInt( i->second );
               break;

            default:
                  // do nothing
               break;
         };
      }

      return true;
   }

   bool ANSITime::isValid() const
      throw()
   {
      ANSITime temp;
      temp.convertFromCommonTime( convertToCommonTime() );
      if( *this == temp )
      {
         return true;
      }
      return false;
   }

   void ANSITime::reset()
      throw()
   {
      time = 0;
      timeSystem = Unknown;
   }

   bool ANSITime::operator==( const ANSITime& right ) const
      throw()
   {
     /// Any (wildcard) type exception allowed, otherwise must be same time systems
      if ((timeSystem != Any && right.timeSystem != Any) &&
           timeSystem != right.timeSystem)
         return false;

      if( fabs(double(time - right.time)) < CommonTime::eps )
      {
         return true;
      }
      return false;
   }

   bool ANSITime::operator!=( const ANSITime& right ) const
      throw()
   {
      return ( !operator==( right ) );
   }

   bool ANSITime::operator<( const ANSITime& right ) const
      throw(InvalidRequest)
   {
     /// Any (wildcard) type exception allowed, otherwise must be same time systems
      if ((timeSystem != Any && right.timeSystem != Any) &&
           timeSystem != right.timeSystem)
         throw InvalidRequest("CommonTime objects not in same time system, cannot be compared");

      return ( time < right.time );
   }

   bool ANSITime::operator>( const ANSITime& right ) const
      throw()
   {
      return ( !operator<=( right ) );
   }

   bool ANSITime::operator<=( const ANSITime& right ) const
      throw()
   {
      return ( operator<( right ) ||
               operator==( right ) );
   }

   bool ANSITime::operator>=( const ANSITime& right ) const
      throw()
   {
      return ( !operator<( right ) );
   }

} // namespace
<commit_msg>Test for updating the Id tags<commit_after>#pragma ident "$Id$"

//============================================================================
//
//  This file is part of GPSTk, the GPS Toolkit.
//
//  The GPSTk is free software; you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License as published
//  by the Free Software Foundation; either version 2.1 of the License, or
//  any later version.
//
//  The GPSTk 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 GPSTk; if not, write to the Free Software Foundation,
//  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Copyright 2004, The University of Texas at Austin
//
//============================================================================

#include <cmath>
#include "ANSITime.hpp"
#include "TimeConstants.hpp"

using namespace gpstk;

namespace Rinex3
{
   ANSITime& ANSITime::operator=( const ANSITime& right )
      throw()
   {
      time = right.time;
      return *this;
   }

   CommonTime ANSITime::convertToCommonTime() const
      throw(InvalidRequest)
   {
      try
      {
         return CommonTime( ( MJD_JDAY + UNIX_MJD + time / SEC_PER_DAY ),
                            ( time % SEC_PER_DAY ),
                            0.,
                            timeSystem );
      }
      catch (InvalidParameter& ip)
      {
         InvalidRequest ir(ip);
         GPSTK_THROW(ir);
      }
   }

   void ANSITime::convertFromCommonTime( const CommonTime& ct )
      throw(InvalidRequest)
   {
         /// This is the earliest CommonTime for which ANSITimes are valid.
     static const CommonTime MIN_CT = ANSITime(0, Any);
         /// This is the latest CommonTime for which ANSITimes are valid.
         /// 2^31 - 1 seconds
       static const CommonTime MAX_CT = ANSITime(2147483647, Any);

      if ( ct < MIN_CT || ct > MAX_CT )
      {
         InvalidRequest ir("Unable to convert given CommonTime to ANSITime.");
         GPSTK_THROW(ir);
      }

      long jday, sod;
      double fsod;
      TimeSystem timeSys;
      ct.get( jday, sod, fsod, timeSys );

      time =
         static_cast<time_t>((jday - MJD_JDAY - UNIX_MJD) * SEC_PER_DAY + sod);

      timeSystem = timeSys;
   }

   std::string ANSITime::printf( const std::string& fmt) const
      throw( gpstk::StringUtils::StringException )
   {
      try
      {
         using gpstk::StringUtils::formattedPrint;
         std::string rv( fmt );

         rv = formattedPrint( rv, getFormatPrefixInt() + "K",
                              "Klu", time );
         rv = formattedPrint( rv, getFormatPrefixInt() + "P",
                              "Pu", timeSystem );
         return rv;
      }
      catch( gpstk::StringUtils::StringException& se )
      {
         GPSTK_RETHROW( se );
      }
   }

   std::string ANSITime::printError( const std::string& fmt) const
      throw( gpstk::StringUtils::StringException )
   {
      try
      {
         using gpstk::StringUtils::formattedPrint;
         std::string rv( fmt );

         rv = formattedPrint( rv, getFormatPrefixInt() + "K",
                              "Ks", getError().c_str() );
         rv = formattedPrint( rv, getFormatPrefixInt() + "P",
                              "Ps", getError().c_str() );
         return rv;
      }
      catch( gpstk::StringUtils::StringException& se )
      {
         GPSTK_RETHROW( se );
      }
   }

   bool ANSITime::setFromInfo( const IdToValue& info )
      throw()
   {
      using namespace gpstk::StringUtils;

      for( IdToValue::const_iterator i = info.begin(); i != info.end(); i++ )
      {
         switch( i->first )
         {
            case 'K':
               time = asInt( i->second );
               break;

            case 'P':
               timeSystem = (TimeSystem) asInt( i->second );
               break;

            default:
                  // do nothing
               break;
         };
      }

      return true;
   }

   bool ANSITime::isValid() const
      throw()
   {
      ANSITime temp;
      temp.convertFromCommonTime( convertToCommonTime() );
      if( *this == temp )
      {
         return true;
      }
      return false;
   }

   void ANSITime::reset()
      throw()
   {
      time = 0;
      timeSystem = Unknown;
   }

   bool ANSITime::operator==( const ANSITime& right ) const
      throw()
   {
     /// Any (wildcard) type exception allowed, otherwise must be same time systems
      if ((timeSystem != Any && right.timeSystem != Any) &&
           timeSystem != right.timeSystem)
         return false;

      if( fabs(double(time - right.time)) < CommonTime::eps )
      {
         return true;
      }
      return false;
   }

   bool ANSITime::operator!=( const ANSITime& right ) const
      throw()
   {
      return ( !operator==( right ) );
   }

   bool ANSITime::operator<( const ANSITime& right ) const
      throw(InvalidRequest)
   {
     /// Any (wildcard) type exception allowed, otherwise must be same time systems
      if ((timeSystem != Any && right.timeSystem != Any) &&
           timeSystem != right.timeSystem)
         throw InvalidRequest("CommonTime objects not in same time system, cannot be compared");

      return ( time < right.time );
   }

   bool ANSITime::operator>( const ANSITime& right ) const
      throw()
   {
      return ( !operator<=( right ) );
   }

   bool ANSITime::operator<=( const ANSITime& right ) const
      throw()
   {
      return ( operator<( right ) ||
               operator==( right ) );
   }

   bool ANSITime::operator>=( const ANSITime& right ) const
      throw()
   {
      return ( !operator<( right ) );
   }

} // namespace
<|endoftext|>


<commit_before>///
/// @file  CpuInfo.cpp
/// @brief Get the CPUs cache sizes in bytes.
///
/// Copyright (C) 2017 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primesieve/CpuInfo.hpp>
#include <cstddef>

#if defined(__APPLE__) && \
  (!defined(__has_include) || \
  (__has_include(<sys/types.h>) && \
   __has_include(<sys/sysctl.h>)))

#define APPLE_SYSCTL

#endif

#if defined(_WIN32)

#include <windows.h>
#include <vector>

#elif defined(APPLE_SYSCTL)

#include <sys/types.h>
#include <sys/sysctl.h>

#else // all other OSes

#include <array>
#include <cstdio>
#include <memory>
#include <string>

using namespace std;

namespace {

string getCacheStr(const char* filename)
{
  shared_ptr<FILE> file(
      fopen(filename, "r"), fclose);
  array<char, 64> buffer;
  string cacheStr;

  if (file)
  {
    while (!feof(file.get()))
    {
      if (fgets(buffer.data(), buffer.size(), file.get()))
        cacheStr += buffer.data();
    }
  }

  return cacheStr;
}

size_t getCacheSize(const char* filename)
{
  size_t cacheSize = 0;
  string cacheStr = getCacheStr(filename);
  size_t pos = cacheStr.find_first_of("0123456789");

  if (pos != string::npos)
  {
    // first character after number
    size_t idx = 0;
    cacheSize = stol(cacheStr.substr(pos), &idx);

    if (idx < cacheStr.size())
    {
      // Last character may be:
      // 'K' = kilobytes
      // 'M' = megabytes
      // 'G' = gigabytes

      if (cacheStr[idx] == 'K')
        cacheSize *= 1024;
      if (cacheStr[idx] == 'M')
        cacheSize *= 1024 * 1024;
      if (cacheStr[idx] == 'G')
        cacheSize *= 1024 * 1024 * 1024;
    }
  }

  return cacheSize;
}

} // namespace

#endif

using namespace std;

namespace primesieve {

CpuInfo::CpuInfo()
  : l1CacheSize_(0),
    l2CacheSize_(0),
    l3CacheSize_(0)
{
  initCache();
}

size_t CpuInfo::l1CacheSize() const
{
  return l1CacheSize_;
}

size_t CpuInfo::l2CacheSize() const
{
  return l2CacheSize_;
}

size_t CpuInfo::l3CacheSize() const
{
  return l3CacheSize_;
}

#if defined(APPLE_SYSCTL)

void CpuInfo::initCache()
{
  size_t l1Length = sizeof(l1CacheSize_);
  size_t l2Length = sizeof(l2CacheSize_);
  size_t l3Length = sizeof(l3CacheSize_);

  sysctlbyname("hw.l1dcachesize", &l1CacheSize_, &l1Length, NULL, 0);
  sysctlbyname("hw.l2cachesize" , &l2CacheSize_, &l2Length, NULL, 0);
  sysctlbyname("hw.l3cachesize" , &l3CacheSize_, &l3Length, NULL, 0);
}

#elif defined(_WIN32)

typedef BOOL (WINAPI *LPFN_GLPI)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD);

void CpuInfo::initCache()
{
  LPFN_GLPI glpi = (LPFN_GLPI) GetProcAddress(GetModuleHandle(TEXT("kernel32")), "GetLogicalProcessorInformation");

  if (glpi)
  {
    DWORD bytes = 0;
    glpi(0, &bytes);
    size_t size = bytes / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
    vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> info(size);
    glpi(info.data(), &bytes);

    for (size_t i = 0; i < size; i++)
    {
      if (info[i].Relationship == RelationCache)
      {
        if (info[i].Cache.Level == 1)
          l1CacheSize_ = info[i].Cache.Size;
        if (info[i].Cache.Level == 2)
          l2CacheSize_ = info[i].Cache.Size;
        if (info[i].Cache.Level == 3)
          l3CacheSize_ = info[i].Cache.Size;
      }
    }
  }
}

#else

/// This works on Linux, we also use this for
/// all unkown OSes, it might work.
///
void CpuInfo::initCache()
{
  l1CacheSize_ = getCacheSize("/sys/devices/system/cpu/cpu0/cache/index0/size");
  l2CacheSize_ = getCacheSize("/sys/devices/system/cpu/cpu0/cache/index2/size");
  l3CacheSize_ = getCacheSize("/sys/devices/system/cpu/cpu0/cache/index3/size");
}

#endif

/// Singleton
const CpuInfo cpuInfo;

} // namespace
<commit_msg>Use local typedef<commit_after>///
/// @file  CpuInfo.cpp
/// @brief Get the CPUs cache sizes in bytes.
///
/// Copyright (C) 2017 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primesieve/CpuInfo.hpp>
#include <cstddef>

#if defined(__APPLE__) && \
  (!defined(__has_include) || \
  (__has_include(<sys/types.h>) && \
   __has_include(<sys/sysctl.h>)))

#define APPLE_SYSCTL

#endif

#if defined(_WIN32)

#include <windows.h>
#include <vector>

#elif defined(APPLE_SYSCTL)

#include <sys/types.h>
#include <sys/sysctl.h>

#else // all other OSes

#include <array>
#include <cstdio>
#include <memory>
#include <string>

using namespace std;

namespace {

string getCacheStr(const char* filename)
{
  shared_ptr<FILE> file(
      fopen(filename, "r"), fclose);
  array<char, 64> buffer;
  string cacheStr;

  if (file)
  {
    while (!feof(file.get()))
    {
      if (fgets(buffer.data(), buffer.size(), file.get()))
        cacheStr += buffer.data();
    }
  }

  return cacheStr;
}

size_t getCacheSize(const char* filename)
{
  size_t cacheSize = 0;
  string cacheStr = getCacheStr(filename);
  size_t pos = cacheStr.find_first_of("0123456789");

  if (pos != string::npos)
  {
    // first character after number
    size_t idx = 0;
    cacheSize = stol(cacheStr.substr(pos), &idx);

    if (idx < cacheStr.size())
    {
      // Last character may be:
      // 'K' = kilobytes
      // 'M' = megabytes
      // 'G' = gigabytes

      if (cacheStr[idx] == 'K')
        cacheSize *= 1024;
      if (cacheStr[idx] == 'M')
        cacheSize *= 1024 * 1024;
      if (cacheStr[idx] == 'G')
        cacheSize *= 1024 * 1024 * 1024;
    }
  }

  return cacheSize;
}

} // namespace

#endif

using namespace std;

namespace primesieve {

CpuInfo::CpuInfo()
  : l1CacheSize_(0),
    l2CacheSize_(0),
    l3CacheSize_(0)
{
  initCache();
}

size_t CpuInfo::l1CacheSize() const
{
  return l1CacheSize_;
}

size_t CpuInfo::l2CacheSize() const
{
  return l2CacheSize_;
}

size_t CpuInfo::l3CacheSize() const
{
  return l3CacheSize_;
}

#if defined(APPLE_SYSCTL)

void CpuInfo::initCache()
{
  size_t l1Length = sizeof(l1CacheSize_);
  size_t l2Length = sizeof(l2CacheSize_);
  size_t l3Length = sizeof(l3CacheSize_);

  sysctlbyname("hw.l1dcachesize", &l1CacheSize_, &l1Length, NULL, 0);
  sysctlbyname("hw.l2cachesize" , &l2CacheSize_, &l2Length, NULL, 0);
  sysctlbyname("hw.l3cachesize" , &l3CacheSize_, &l3Length, NULL, 0);
}

#elif defined(_WIN32)

void CpuInfo::initCache()
{
  typedef BOOL (WINAPI *LPFN_GLPI)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD);

  LPFN_GLPI glpi = (LPFN_GLPI) GetProcAddress(GetModuleHandle(TEXT("kernel32")), "GetLogicalProcessorInformation");

  if (glpi)
  {
    DWORD bytes = 0;
    glpi(0, &bytes);
    size_t size = bytes / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
    vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> info(size);
    glpi(info.data(), &bytes);

    for (size_t i = 0; i < size; i++)
    {
      if (info[i].Relationship == RelationCache)
      {
        if (info[i].Cache.Level == 1)
          l1CacheSize_ = info[i].Cache.Size;
        if (info[i].Cache.Level == 2)
          l2CacheSize_ = info[i].Cache.Size;
        if (info[i].Cache.Level == 3)
          l3CacheSize_ = info[i].Cache.Size;
      }
    }
  }
}

#else

/// This works on Linux, we also use this for
/// all unkown OSes, it might work.
///
void CpuInfo::initCache()
{
  l1CacheSize_ = getCacheSize("/sys/devices/system/cpu/cpu0/cache/index0/size");
  l2CacheSize_ = getCacheSize("/sys/devices/system/cpu/cpu0/cache/index2/size");
  l3CacheSize_ = getCacheSize("/sys/devices/system/cpu/cpu0/cache/index3/size");
}

#endif

/// Singleton
const CpuInfo cpuInfo;

} // namespace
<|endoftext|>