<commit_before>/***************************************************************************\
**
**  tRunTimer.cpp: functions for tRunTimer objects.
**
**  tRunTimer objects are used to keep track of time in a time-evolving
**  simulation model. Their services include keeping track of when it's
**  time to write output, printing the current time to standard output if
**  desired, and writing the current time to a file every so often.
**
**  Version 1.0, Greg Tucker, November 1997
**
**  Potential additions/improvements:
**  - add functions to set output interval and time status notification
**    interval
**
**  $Id: tRunTimer.cpp,v 1.11 2000-06-05 22:13:27 daniel Exp $
\***************************************************************************/

#include <iostream.h>
#include <fstream.h>
#include <assert.h>

#include "../tInputFile/tInputFile.h"
#include "tRunTimer.h"

//****************************************************
// Constructors
//
// - A default constructor
// - A constructor that sets the run duration and
//   output interval (and if desired sets the option
//   to print time steps to stdout; default is 1,
//   see header file)
// - A constructor that reads run duration and
//   output interval from a tInputFile object (and
//   if desired sets the option
//   to print time steps to stdout; default is 1,
//   see header file)
//   NG changed this constructor so that if layering
//   info is read in, the start time is set to the
//   time which layers are read in.  Must have this
//   for the layering to make sense, but might also
//   want this if reading in any type of input other
//   than the standard parameters.  (OPTREADINPUT>0)
//   Wasn't changed because I don't know how other
//   people want this handled.  Bad practice to have
//   something about layering in here though.
//
// Note that the notifyInterval is always initialized
// at 1000, but of course this could be changed.
//****************************************************

tRunTimer::tRunTimer()
{
	currentTime = 0;
	endTime = 1;
	outputInterval = 1;
	nextOutputTime = 0;
	optPrintEachTime = 1;
	notifyInterval = 1000;
	nextNotify = 0;
	TSOutputInterval = 1;
	nextTSOutputTime = 0;
}

tRunTimer::tRunTimer( double duration, double opint, int optprint )
{
	currentTime = 0;
	endTime = duration;
	outputInterval = opint;
	nextOutputTime = 0;
	optPrintEachTime = optprint;
	notifyInterval = 1000;
	nextNotify = 0;
	nextTSOutputTime = 999999999
}

tRunTimer::tRunTimer( tInputFile &infile, int optprint )
{
	endTime = infile.ReadItem( endTime, "RUNTIME" );
	outputInterval = infile.ReadItem( outputInterval, "OPINTRVL" );
	optPrintEachTime = optprint;
	notifyInterval = 1000;
        optTSOutput = infile.ReadItem( optTSOutput, "OPTTSOUTPUT" );
	if( optTSOutput )
	  TSOutput = infile.ReadItem( TSOutputInterval, "TSOPINTRVL" );

  double help;

  //If you are reading in layering information, the timer should
  //be set to the time in which the layers were output, since
  //time is tracked in the layers and restarting at time zero
  //would make the layer times non-sensical.
  help = infile.ReadItem( help, "OPTREADINPUT" );
  if(help>0){
     help = infile.ReadItem( help, "INPUTTIME" );
     currentTime = help;
     endTime += help;
     nextOutputTime = help;
     nextNotify = help;
  }
  else{
     nextOutputTime = 0;
     nextNotify = 0;
     currentTime = 0;
  }

}

//****************************************************
// Start
//
// Sets the current time and run duration.
//****************************************************
void tRunTimer::Start( double start, double end )
{
   currentTime = start;
   if( end>0.0 ) endTime = end;
}

//****************************************************
// getCurrentTime
//
// Returns the current time.
//****************************************************
double tRunTimer::getCurrentTime()
{
	return currentTime;
}

//****************************************************
// RemainingTime
//
// Returns the remaining time.
//****************************************************
double tRunTimer::RemainingTime()
{
	return endTime - currentTime;
}

//****************************************************
// Advance
//
// Increments the current time by dt.
// Returns 1 if there is still time
// remaining, 0 if the time is up.
//****************************************************
int tRunTimer::Advance( double dt )
{
	currentTime += dt;
	return( currentTime < endTime );
}

//****************************************************
// ReportTimeStatus
//
// Reports the current time to a file and to
// standard output if desired. Output to file is
// only done at selected intervals.
// Compares currentTime with nextNotify to see
// whether it's time to update the time status file,
// and if so opens the file and writes the current
// time (overwriting any previous contents).
// Regardless of the status of nextNotify, if
// optPrintEachTime is selected, the current time is
// reported to cout.
//****************************************************
void tRunTimer::ReportTimeStatus()
{
	if( optPrintEachTime ) cout << currentTime << endl;
	if( currentTime >= nextNotify )
	{
		timeStatusFile.open( "run.time" );
		assert( timeStatusFile.good() );
		timeStatusFile << currentTime << endl;
		timeStatusFile.close();
		nextNotify += notifyInterval;
	}
}

//*************************************************
// CheckOutputTime
//
// Checks to see whether it's time to write output
// yet.
//*************************************************
int tRunTimer::CheckOutputTime()
{
	if( currentTime>=nextOutputTime )
	{
		nextOutputTime += outputInterval;
		return 1;
	}
	else return 0;
}

//*************************************************
// CheckTSOutputTime
//
// Checks to see weather it's time to write time
// series output yet.
//*************************************************
int tRunTimer::CheckTSOutputTime()
{
        if( currentTime >= nextTSOutputTime )
	{
	    	nextTSOutputTime += TSoutputInterval;
		return 1;
	}
	else return 0;
}

//*************************************************
// IsFinished
//
// Checks to see whether the run is finished.
//*************************************************
int tRunTimer::IsFinished()
{
	return( currentTime >= endTime );
}

<commit_msg>*** empty log message ***<commit_after>/***************************************************************************\
**
**  tRunTimer.cpp: functions for tRunTimer objects.
**
**  tRunTimer objects are used to keep track of time in a time-evolving
**  simulation model. Their services include keeping track of when it's
**  time to write output, printing the current time to standard output if
**  desired, and writing the current time to a file every so often.
**
**  Version 1.0, Greg Tucker, November 1997
**
**  Potential additions/improvements:
**  - add functions to set output interval and time status notification
**    interval
**
**  $Id: tRunTimer.cpp,v 1.12 2000-06-05 22:18:17 daniel Exp $
\***************************************************************************/

#include <iostream.h>
#include <fstream.h>
#include <assert.h>

#include "../tInputFile/tInputFile.h"
#include "tRunTimer.h"

//****************************************************
// Constructors
//
// - A default constructor
// - A constructor that sets the run duration and
//   output interval (and if desired sets the option
//   to print time steps to stdout; default is 1,
//   see header file)
// - A constructor that reads run duration and
//   output interval from a tInputFile object (and
//   if desired sets the option
//   to print time steps to stdout; default is 1,
//   see header file)
//   NG changed this constructor so that if layering
//   info is read in, the start time is set to the
//   time which layers are read in.  Must have this
//   for the layering to make sense, but might also
//   want this if reading in any type of input other
//   than the standard parameters.  (OPTREADINPUT>0)
//   Wasn't changed because I don't know how other
//   people want this handled.  Bad practice to have
//   something about layering in here though.
//
// Note that the notifyInterval is always initialized
// at 1000, but of course this could be changed.
//****************************************************

tRunTimer::tRunTimer()
{
	currentTime = 0;
	endTime = 1;
	outputInterval = 1;
	nextOutputTime = 0;
	optPrintEachTime = 1;
	notifyInterval = 1000;
	nextNotify = 0;
	TSOutputInterval = 1;
	nextTSOutputTime = 0;
}

tRunTimer::tRunTimer( double duration, double opint, int optprint )
{
	currentTime = 0;
	endTime = duration;
	outputInterval = opint;
	nextOutputTime = 0;
	optPrintEachTime = optprint;
	notifyInterval = 1000;
	nextNotify = 0;
	nextTSOutputTime = 999999999
}

tRunTimer::tRunTimer( tInputFile &infile, int optprint )
{
	endTime = infile.ReadItem( endTime, "RUNTIME" );
	outputInterval = infile.ReadItem( outputInterval, "OPINTRVL" );
	optPrintEachTime = optprint;
	notifyInterval = 1000;
        optTSOutput = infile.ReadItem( optTSOutput, "OPTTSOUTPUT" );
	if( optTSOutput )
	  TSOutput = infile.ReadItem( TSOutputInterval, "TSOPINTRVL" );

  double help;

  //If you are reading in layering information, the timer should
  //be set to the time in which the layers were output, since
  //time is tracked in the layers and restarting at time zero
  //would make the layer times non-sensical.
  help = infile.ReadItem( help, "OPTREADINPUT" );
  if(help>0){
     help = infile.ReadItem( help, "INPUTTIME" );
     currentTime = help;
     endTime += help;
     nextOutputTime = help;
     nextNotify = help;
  }
  else{
     nextOutputTime = 0;
     nextNotify = 0;
     currentTime = 0;
  }

}

//****************************************************
// Start
//
// Sets the current time and run duration.
//****************************************************
void tRunTimer::Start( double start, double end )
{
   currentTime = start;
   if( end>0.0 ) endTime = end;
}

//****************************************************
// getCurrentTime
//
// Returns the current time.
//****************************************************
double tRunTimer::getCurrentTime()
{
	return currentTime;
}

//****************************************************
// RemainingTime
//
// Returns the remaining time.
//****************************************************
double tRunTimer::RemainingTime()
{
	return endTime - currentTime;
}

//****************************************************
// Advance
//
// Increments the current time by dt.
// Returns 1 if there is still time
// remaining, 0 if the time is up.
//****************************************************
int tRunTimer::Advance( double dt )
{
	currentTime += dt;
	return( currentTime < endTime );
}

//****************************************************
// ReportTimeStatus
//
// Reports the current time to a file and to
// standard output if desired. Output to file is
// only done at selected intervals.
// Compares currentTime with nextNotify to see
// whether it's time to update the time status file,
// and if so opens the file and writes the current
// time (overwriting any previous contents).
// Regardless of the status of nextNotify, if
// optPrintEachTime is selected, the current time is
// reported to cout.
//****************************************************
void tRunTimer::ReportTimeStatus()
{
	if( optPrintEachTime ) cout << currentTime << endl;
	if( currentTime >= nextNotify )
	{
		timeStatusFile.open( "run.time" );
		assert( timeStatusFile.good() );
		timeStatusFile << currentTime << endl;
		timeStatusFile.close();
		nextNotify += notifyInterval;
	}
}

//*************************************************
// CheckOutputTime
//
// Checks to see whether it's time to write output
// yet.
//*************************************************
int tRunTimer::CheckOutputTime()
{
	if( currentTime>=nextOutputTime )
	{
		nextOutputTime += outputInterval;
		return 1;
	}
	else return 0;
}

//*************************************************
// CheckTSOutputTime
//
// Checks to see weather it's time to write time
// series output yet.
//*************************************************
int tRunTimer::CheckTSOutputTime()
{
        if( currentTime >= nextTSOutputTime )
	{
	    	nextTSOutputTime += TSOutputInterval;
		return 1;
	}
	else return 0;
}

//*************************************************
// IsFinished
//
// Checks to see whether the run is finished.
//*************************************************
int tRunTimer::IsFinished()
{
	return( currentTime >= endTime );
}

<|endoftext|>


<commit_before>// StdLib.cpp
// This file is part of the EScript programming language.
// See copyright notice in EScript.h
// ------------------------------------------------------
#include "StdLib.h"

#include "../EScript/EScript.h"
#include "../EScript/Objects/Callables/UserFunction.h"
#include "../EScript/Compiler/Compiler.h"
#include "../EScript/Compiler/Parser.h"
#include "../EScript/Utils/IO/IO.h"
#include "ext/JSON.h"

#include <sstream>
#include <stdlib.h>
#include <ctime>
#include <unistd.h>

#if defined(_WIN32)
#include <windows.h>
#endif

namespace EScript{

std::string StdLib::getOS(){
	#if defined(_WIN32) || defined(_WIN64)
	return std::string("WINDOWS");
	#elif defined(__APPLE__)
	return std::string("MAC OS");
	#elif defined(__linux__)
	return std::string("LINUX");
	#elif defined(__unix__)
	return std::string("UNIX");
	#else
	return std::string("UNKNOWN");
	#endif
}

//! (static)
void StdLib::print_r(Object * o,int maxLevel,int level) {
	if (!o) return;
	if (level>maxLevel) {
		std::cout << " ... \n";
		return;
	}

	if (Array * a=dynamic_cast<Array *>(o)) {
		std::cout << "[\n";
		ERef<Iterator> itRef=a->getIterator();
		int nr=0;
		while (!itRef->end()) {
			ObjRef valueRef=itRef->value();
			ObjRef keyRef=itRef->key();
			if (nr++>0)std::cout << ",\n";
			if (!valueRef.isNull()) {
				for (int i=0;i<level;i++)
					std::cout << "\t";
				std::cout << "["<<keyRef.toString() <<"] : ";
				print_r(valueRef.get(),maxLevel,level+1);

			}
			itRef->next();
		}
		std::cout << "\n";
		for (int i=0;i<level-1;i++)
			std::cout << "\t";
		std::cout << "]";
	} else if (Map * m=dynamic_cast<Map *>(o)) {
		std::cout << "{\n";
		ERef<Iterator> itRef=m->getIterator();
		int nr=0;
		while (!itRef->end()) {
			ObjRef valueRef=itRef->value();
			ObjRef keyRef=itRef->key();
			if (nr++>0)
				std::cout << ",\n";
			if (!valueRef.isNull()) {
				for (int i=0;i<level;i++)
					std::cout << "\t";
				std::cout << "["<<keyRef.toString() <<"] : ";
				print_r(valueRef.get(),maxLevel,level+1);

			}

			itRef->next();
		}
		std::cout << "\n";
		for (int i=0;i<level-1;i++)
			std::cout << "\t";
		std::cout << "}";
	} else {
		if (dynamic_cast<String *>(o))
			std::cout << "\""<<o->toString()<<"\"";
		else std::cout << o->toString();
	}
}

/*! Tries to locate the given __filename__ with the current searchPath set in the runtime.
	@return the path to the file or the original __filename__ if the file could not be found.	*/
static std::string findFile(Runtime & runtime, const std::string & filename){
	static const StringId seachPathsId("__searchPaths");

	std::string file(IO::condensePath(filename));
	if( IO::getEntryType(file)!=IO::TYPE_FILE ){
		if(Array * searchPaths = dynamic_cast<Array*>(runtime.getAttribute(seachPathsId).getValue())){
			for(ERef<Iterator> itRef=searchPaths->getIterator();!itRef->end();itRef->next()){
				ObjRef valueRef = itRef->value();
				std::string s(IO::condensePath(valueRef.toString()+'/'+filename));
				if( IO::getEntryType(s)==IO::TYPE_FILE ){
					file = s;
					break;
				}
			}
		}
	}
	return file;
}

//! (static)
ObjRef StdLib::loadOnce(Runtime & runtime,const std::string & filename){
	static const StringId mapId("__loadOnce_loadedFiles");

	std::string condensedFilename( IO::condensePath(findFile(runtime,filename)) );
	Map * m=dynamic_cast<Map*>(runtime.getAttribute(mapId).getValue());
	if(m==nullptr){
		m=Map::create();
		runtime.setAttribute(mapId, Attribute(m));
	}
	ObjRef obj=m->getValue(condensedFilename);
	if(obj.toBool()){ // already loaded?
		return nullptr;
	}
	m->setValue(String::create(condensedFilename),Bool::create(true));
	return _loadAndExecute(runtime,condensedFilename);
}

#if defined(_WIN32)
static LARGE_INTEGER _getPerformanceCounter();

// execute this as soon as possible (when the global static variables are initialized)
static LARGE_INTEGER _clockStart = _getPerformanceCounter();

// wrapper for the windows high performance timer.
LARGE_INTEGER _getPerformanceCounter(){
	LARGE_INTEGER c;
	QueryPerformanceCounter(&c);
	return c;
}

#endif

// -------------------------------------------------------------
//! init  (globals)
void StdLib::init(EScript::Namespace * globals) {

	/*!	[ESF] void addSearchPath(path)
		Adds a search path which is used for load(...) and loadOnce(...)	*/
	ES_FUNCTION_DECLARE(globals,"addSearchPath",1,1,{
		static const StringId seachPathsId("__searchPaths");
		Array * searchPaths = dynamic_cast<Array*>(runtime.getAttribute(seachPathsId).getValue());
		if(searchPaths == nullptr){
			searchPaths = Array::create();
			runtime.setAttribute(seachPathsId, Attribute(searchPaths));
		}
		searchPaths->pushBack(String::create(parameter[0].toString()));
		return Void::get();
	})

	//! [ESF] void assert( expression[,text])
	ES_FUNCTION_DECLARE(globals,"assert",1,2, {
		assertParamCount(runtime,parameter.count(),1,2);
		if(!parameter[0]->toBool()){
			runtime.setException(parameter.count()>1?parameter[1]->toString():"Assert failed.");
		}
		return nullptr;
	})

	//! [ESF]  string chr(number)
	ES_FUNCTION_DECLARE(globals,"chr",1,1,{
		std::ostringstream s;
		s<< static_cast<char>(parameter[0]->toInt());
		return String::create(s.str());
	})

	// clock
	{
	#if defined(_WIN32)
	typedef LARGE_INTEGER timer_t;
	static timer_t frequency;
	if(!QueryPerformanceFrequency(&frequency)) {
		std::cout <<("QueryPerformanceFrequency failed, timer will not work properly!");
	}

	//! [ESF]  number clock()
	ES_FUNCTION_DECLARE(globals,"clock",0,0,{
		LARGE_INTEGER time = _getPerformanceCounter();
		return Number::create( static_cast<double>(time.QuadPart-_clockStart.QuadPart) / static_cast<double>(frequency.QuadPart) );
	})

	#else
	//! [ESF]  number clock()
	ESF_DECLARE(globals,"clock",0,0,Number::create( static_cast<double>(clock())/CLOCKS_PER_SEC))
	#endif
	}

	//!	[ESF]  Object eval(string)
	ESF_DECLARE(globals,"eval",1,1,
				_eval(runtime,CodeFragment(Consts::FILENAME_INLINE, StringData(parameter[0].toString()))).detachAndDecrease())

	/*!	[ESF]  Map getDate([time])
		like http://de3.php.net/manual/de/function.getdate.php	*/
	ES_FUNCTION_DECLARE(globals,"getDate",0,1,{
		time_t t=(parameter.count()==0)?time(nullptr):static_cast<time_t>(parameter[0]->toInt());
		tm d;
		localtime_r(&t, &d);
		Map * m=Map::create();
		m->setValue(String::create("seconds"),Number::create(d.tm_sec));
		m->setValue(String::create("minutes"),Number::create(d.tm_min));
		m->setValue(String::create("hours"),Number::create(d.tm_hour));
		m->setValue(String::create("mday"),Number::create(d.tm_mday));
		m->setValue(String::create("mon"),Number::create(d.tm_mon+1));
		m->setValue(String::create("year"),Number::create(d.tm_year+1900));
		m->setValue(String::create("wday"),Number::create(d.tm_wday));
		m->setValue(String::create("yday"),Number::create(d.tm_yday));
		m->setValue(String::create("isdst"),Number::create(d.tm_isdst));
		return m;
	})

	//! [ESF]  string getOS()
	ESF_DECLARE(globals,"getOS",0,0,String::create(StdLib::getOS()))

	//! [ESF] Runtime getRuntime( )
	ESF_DECLARE(globals,"getRuntime",0,0, &runtime)

	//!	[ESF] mixed load(string filename)
	ESF_DECLARE(globals,"load",1,1,_loadAndExecute(runtime,findFile(runtime,parameter[0].toString())).detachAndDecrease())

	//!	[ESF] mixed loadOnce(string filename)
	ESF_DECLARE(globals,"loadOnce",1,1,StdLib::loadOnce(runtime,parameter[0].toString()).detachAndDecrease())

	//! [ESF] void out(...)
	ES_FUNCTION_DECLARE(globals,"out",0,-1, {
		for(const auto & param : parameter) {
			std::cout << param.toString();
		}
		std::cout.flush();
		return nullptr;
	})

	//! [ESF] void outln(...)
	ES_FUNCTION_DECLARE(globals,"outln",0,-1, {
		for(const auto & param : parameter) {
			std::cout << param.toString();
		}
		std::cout << std::endl;
		return nullptr;
	})

	//!	[ESF]  BlockStatement parse(string) @deprecated
	ES_FUNCTION_DECLARE(globals,"parse",1,1, {
		ERef<UserFunction> script;

		Compiler compiler(runtime.getLogger());
		script = compiler.compile(CodeFragment(Consts::FILENAME_INLINE, StringData(parameter[0].toString())));

		return script.detachAndDecrease();
	})
	//! [ESF]  obj parseJSON(string)
	ESF_DECLARE(globals,"parseJSON",1,1,JSON::parseJSON(parameter[0].toString()))

	//! [ESF] void print_r(...)
	ES_FUNCTION_DECLARE(globals,"print_r",0,-1, {
		std::cout << "\n";
		for(const auto & param : parameter) {
			if(!param.isNull()) {
				print_r(param.get());
			}
		}
		return nullptr;
	})

	//!	[ESF]  number system(command)
	ESF_DECLARE(globals,"system",1,1,Number::create(system(parameter[0]->toString().c_str())))

	//!	[ESF] Number exec(String path, Array argv)
	ES_FUNCTION_DECLARE(globals, "exec", 2, 2, {
		Array * array = assertType<Array>(runtime, parameter[1]);
		uint32_t argc = array->size();

		char ** argv  = new char *[argc + 1];
		for(uint_fast32_t i = 0; i < argc; ++i) {
			 std::string arg = array->get(i)->toString();
			 argv[i] = new char[arg.length() + 1];
			 std::copy(arg.begin(), arg.end(), argv[i]);
			 argv[i][arg.length()] = '\0';
		}
		argv[argc] = nullptr;

		Number * result = Number::create(execv(parameter[0]->toString().c_str(), argv));

		for(uint_fast32_t i = 0; i < argc; ++i) {
			delete [] argv[i];
		}
		delete [] argv;

		return result;
	})

	//! [ESF]  number time()
	ESF_DECLARE(globals,"time",0,0,Number::create(static_cast<double>(time(nullptr))))

	//! [ESF]  string toJSON(obj[,formatted=true])
	ESF_DECLARE(globals,"toJSON",1,2,String::create(JSON::toJSON(parameter[0].get(),parameter[1].toBool(true))))

}

}
<commit_msg>Revert changeset 405 (localtime_r is not available on all platforms)<commit_after>// StdLib.cpp
// This file is part of the EScript programming language.
// See copyright notice in EScript.h
// ------------------------------------------------------
#include "StdLib.h"

#include "../EScript/EScript.h"
#include "../EScript/Objects/Callables/UserFunction.h"
#include "../EScript/Compiler/Compiler.h"
#include "../EScript/Compiler/Parser.h"
#include "../EScript/Utils/IO/IO.h"
#include "ext/JSON.h"

#include <sstream>
#include <stdlib.h>
#include <ctime>
#include <unistd.h>

#if defined(_WIN32)
#include <windows.h>
#endif

namespace EScript{

std::string StdLib::getOS(){
	#if defined(_WIN32) || defined(_WIN64)
	return std::string("WINDOWS");
	#elif defined(__APPLE__)
	return std::string("MAC OS");
	#elif defined(__linux__)
	return std::string("LINUX");
	#elif defined(__unix__)
	return std::string("UNIX");
	#else
	return std::string("UNKNOWN");
	#endif
}

//! (static)
void StdLib::print_r(Object * o,int maxLevel,int level) {
	if (!o) return;
	if (level>maxLevel) {
		std::cout << " ... \n";
		return;
	}

	if (Array * a=dynamic_cast<Array *>(o)) {
		std::cout << "[\n";
		ERef<Iterator> itRef=a->getIterator();
		int nr=0;
		while (!itRef->end()) {
			ObjRef valueRef=itRef->value();
			ObjRef keyRef=itRef->key();
			if (nr++>0)std::cout << ",\n";
			if (!valueRef.isNull()) {
				for (int i=0;i<level;i++)
					std::cout << "\t";
				std::cout << "["<<keyRef.toString() <<"] : ";
				print_r(valueRef.get(),maxLevel,level+1);

			}
			itRef->next();
		}
		std::cout << "\n";
		for (int i=0;i<level-1;i++)
			std::cout << "\t";
		std::cout << "]";
	} else if (Map * m=dynamic_cast<Map *>(o)) {
		std::cout << "{\n";
		ERef<Iterator> itRef=m->getIterator();
		int nr=0;
		while (!itRef->end()) {
			ObjRef valueRef=itRef->value();
			ObjRef keyRef=itRef->key();
			if (nr++>0)
				std::cout << ",\n";
			if (!valueRef.isNull()) {
				for (int i=0;i<level;i++)
					std::cout << "\t";
				std::cout << "["<<keyRef.toString() <<"] : ";
				print_r(valueRef.get(),maxLevel,level+1);

			}

			itRef->next();
		}
		std::cout << "\n";
		for (int i=0;i<level-1;i++)
			std::cout << "\t";
		std::cout << "}";
	} else {
		if (dynamic_cast<String *>(o))
			std::cout << "\""<<o->toString()<<"\"";
		else std::cout << o->toString();
	}
}

/*! Tries to locate the given __filename__ with the current searchPath set in the runtime.
	@return the path to the file or the original __filename__ if the file could not be found.	*/
static std::string findFile(Runtime & runtime, const std::string & filename){
	static const StringId seachPathsId("__searchPaths");

	std::string file(IO::condensePath(filename));
	if( IO::getEntryType(file)!=IO::TYPE_FILE ){
		if(Array * searchPaths = dynamic_cast<Array*>(runtime.getAttribute(seachPathsId).getValue())){
			for(ERef<Iterator> itRef=searchPaths->getIterator();!itRef->end();itRef->next()){
				ObjRef valueRef = itRef->value();
				std::string s(IO::condensePath(valueRef.toString()+'/'+filename));
				if( IO::getEntryType(s)==IO::TYPE_FILE ){
					file = s;
					break;
				}
			}
		}
	}
	return file;
}

//! (static)
ObjRef StdLib::loadOnce(Runtime & runtime,const std::string & filename){
	static const StringId mapId("__loadOnce_loadedFiles");

	std::string condensedFilename( IO::condensePath(findFile(runtime,filename)) );
	Map * m=dynamic_cast<Map*>(runtime.getAttribute(mapId).getValue());
	if(m==nullptr){
		m=Map::create();
		runtime.setAttribute(mapId, Attribute(m));
	}
	ObjRef obj=m->getValue(condensedFilename);
	if(obj.toBool()){ // already loaded?
		return nullptr;
	}
	m->setValue(String::create(condensedFilename),Bool::create(true));
	return _loadAndExecute(runtime,condensedFilename);
}

#if defined(_WIN32)
static LARGE_INTEGER _getPerformanceCounter();

// execute this as soon as possible (when the global static variables are initialized)
static LARGE_INTEGER _clockStart = _getPerformanceCounter();

// wrapper for the windows high performance timer.
LARGE_INTEGER _getPerformanceCounter(){
	LARGE_INTEGER c;
	QueryPerformanceCounter(&c);
	return c;
}

#endif

// -------------------------------------------------------------
//! init  (globals)
void StdLib::init(EScript::Namespace * globals) {

	/*!	[ESF] void addSearchPath(path)
		Adds a search path which is used for load(...) and loadOnce(...)	*/
	ES_FUNCTION_DECLARE(globals,"addSearchPath",1,1,{
		static const StringId seachPathsId("__searchPaths");
		Array * searchPaths = dynamic_cast<Array*>(runtime.getAttribute(seachPathsId).getValue());
		if(searchPaths == nullptr){
			searchPaths = Array::create();
			runtime.setAttribute(seachPathsId, Attribute(searchPaths));
		}
		searchPaths->pushBack(String::create(parameter[0].toString()));
		return Void::get();
	})

	//! [ESF] void assert( expression[,text])
	ES_FUNCTION_DECLARE(globals,"assert",1,2, {
		assertParamCount(runtime,parameter.count(),1,2);
		if(!parameter[0]->toBool()){
			runtime.setException(parameter.count()>1?parameter[1]->toString():"Assert failed.");
		}
		return nullptr;
	})

	//! [ESF]  string chr(number)
	ES_FUNCTION_DECLARE(globals,"chr",1,1,{
		std::ostringstream s;
		s<< static_cast<char>(parameter[0]->toInt());
		return String::create(s.str());
	})

	// clock
	{
	#if defined(_WIN32)
	typedef LARGE_INTEGER timer_t;
	static timer_t frequency;
	if(!QueryPerformanceFrequency(&frequency)) {
		std::cout <<("QueryPerformanceFrequency failed, timer will not work properly!");
	}

	//! [ESF]  number clock()
	ES_FUNCTION_DECLARE(globals,"clock",0,0,{
		LARGE_INTEGER time = _getPerformanceCounter();
		return Number::create( static_cast<double>(time.QuadPart-_clockStart.QuadPart) / static_cast<double>(frequency.QuadPart) );
	})

	#else
	//! [ESF]  number clock()
	ESF_DECLARE(globals,"clock",0,0,Number::create( static_cast<double>(clock())/CLOCKS_PER_SEC))
	#endif
	}

	//!	[ESF]  Object eval(string)
	ESF_DECLARE(globals,"eval",1,1,
				_eval(runtime,CodeFragment(Consts::FILENAME_INLINE, StringData(parameter[0].toString()))).detachAndDecrease())

	/*!	[ESF]  Map getDate([time])
		like http://de3.php.net/manual/de/function.getdate.php	*/
	ES_FUNCTION_DECLARE(globals,"getDate",0,1,{
		time_t t=(parameter.count()==0)?time(nullptr):static_cast<time_t>(parameter[0]->toInt());
		tm *d=localtime (& t );
		Map * m=Map::create();
		m->setValue(String::create("seconds"),Number::create(d->tm_sec));
		m->setValue(String::create("minutes"),Number::create(d->tm_min));
		m->setValue(String::create("hours"),Number::create(d->tm_hour));
		m->setValue(String::create("mday"),Number::create(d->tm_mday));
		m->setValue(String::create("mon"),Number::create(d->tm_mon+1));
		m->setValue(String::create("year"),Number::create(d->tm_year+1900));
		m->setValue(String::create("wday"),Number::create(d->tm_wday));
		m->setValue(String::create("yday"),Number::create(d->tm_yday));
		m->setValue(String::create("isdst"),Number::create(d->tm_isdst));
		return m;
	})

	//! [ESF]  string getOS()
	ESF_DECLARE(globals,"getOS",0,0,String::create(StdLib::getOS()))

	//! [ESF] Runtime getRuntime( )
	ESF_DECLARE(globals,"getRuntime",0,0, &runtime)

	//!	[ESF] mixed load(string filename)
	ESF_DECLARE(globals,"load",1,1,_loadAndExecute(runtime,findFile(runtime,parameter[0].toString())).detachAndDecrease())

	//!	[ESF] mixed loadOnce(string filename)
	ESF_DECLARE(globals,"loadOnce",1,1,StdLib::loadOnce(runtime,parameter[0].toString()).detachAndDecrease())

	//! [ESF] void out(...)
	ES_FUNCTION_DECLARE(globals,"out",0,-1, {
		for(const auto & param : parameter) {
			std::cout << param.toString();
		}
		std::cout.flush();
		return nullptr;
	})

	//! [ESF] void outln(...)
	ES_FUNCTION_DECLARE(globals,"outln",0,-1, {
		for(const auto & param : parameter) {
			std::cout << param.toString();
		}
		std::cout << std::endl;
		return nullptr;
	})

	//!	[ESF]  BlockStatement parse(string) @deprecated
	ES_FUNCTION_DECLARE(globals,"parse",1,1, {
		ERef<UserFunction> script;

		Compiler compiler(runtime.getLogger());
		script = compiler.compile(CodeFragment(Consts::FILENAME_INLINE, StringData(parameter[0].toString())));

		return script.detachAndDecrease();
	})
	//! [ESF]  obj parseJSON(string)
	ESF_DECLARE(globals,"parseJSON",1,1,JSON::parseJSON(parameter[0].toString()))

	//! [ESF] void print_r(...)
	ES_FUNCTION_DECLARE(globals,"print_r",0,-1, {
		std::cout << "\n";
		for(const auto & param : parameter) {
			if(!param.isNull()) {
				print_r(param.get());
			}
		}
		return nullptr;
	})

	//!	[ESF]  number system(command)
	ESF_DECLARE(globals,"system",1,1,Number::create(system(parameter[0]->toString().c_str())))

	//!	[ESF] Number exec(String path, Array argv)
	ES_FUNCTION_DECLARE(globals, "exec", 2, 2, {
		Array * array = assertType<Array>(runtime, parameter[1]);
		uint32_t argc = array->size();

		char ** argv  = new char *[argc + 1];
		for(uint_fast32_t i = 0; i < argc; ++i) {
			 std::string arg = array->get(i)->toString();
			 argv[i] = new char[arg.length() + 1];
			 std::copy(arg.begin(), arg.end(), argv[i]);
			 argv[i][arg.length()] = '\0';
		}
		argv[argc] = nullptr;

		Number * result = Number::create(execv(parameter[0]->toString().c_str(), argv));

		for(uint_fast32_t i = 0; i < argc; ++i) {
			delete [] argv[i];
		}
		delete [] argv;

		return result;
	})

	//! [ESF]  number time()
	ESF_DECLARE(globals,"time",0,0,Number::create(static_cast<double>(time(nullptr))))

	//! [ESF]  string toJSON(obj[,formatted=true])
	ESF_DECLARE(globals,"toJSON",1,2,String::create(JSON::toJSON(parameter[0].get(),parameter[1].toBool(true))))

}

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: Eservices.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 06:02:07 $
 *
 *  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
 *
 ************************************************************************/

#ifndef _CONNECTIVITY_FLAT_EDRIVER_HXX_
#include "flat/EDriver.hxx"
#endif
#ifndef _CPPUHELPER_FACTORY_HXX_
#include <cppuhelper/factory.hxx>
#endif
#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif

using namespace connectivity::flat;
using ::rtl::OUString;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::registry::XRegistryKey;
using ::com::sun::star::lang::XSingleServiceFactory;
using ::com::sun::star::lang::XMultiServiceFactory;

typedef Reference< XSingleServiceFactory > (SAL_CALL *createFactoryFunc)
        (
            const Reference< XMultiServiceFactory > & rServiceManager,
            const OUString & rComponentName,
            ::cppu::ComponentInstantiation pCreateFunction,
            const Sequence< OUString > & rServiceNames,
            rtl_ModuleCount* _pT
        );

//***************************************************************************************
//
// Die vorgeschriebene C-Api muss erfuellt werden!
// Sie besteht aus drei Funktionen, die von dem Modul exportiert werden muessen.
//

//---------------------------------------------------------------------------------------
void REGISTER_PROVIDER(
        const OUString& aServiceImplName,
        const Sequence< OUString>& Services,
        const Reference< ::com::sun::star::registry::XRegistryKey > & xKey)
{
    OUString aMainKeyName;
    aMainKeyName = OUString::createFromAscii("/");
    aMainKeyName += aServiceImplName;
    aMainKeyName += OUString::createFromAscii("/UNO/SERVICES");

    Reference< ::com::sun::star::registry::XRegistryKey >  xNewKey( xKey->createKey(aMainKeyName) );
    OSL_ENSURE(xNewKey.is(), "FILE::component_writeInfo : could not create a registry key !");

    for (sal_Int32 i=0; i<Services.getLength(); ++i)
        xNewKey->createKey(Services[i]);
}

//---------------------------------------------------------------------------------------
struct ProviderRequest
{
    Reference< XSingleServiceFactory > xRet;
    Reference< XMultiServiceFactory > const xServiceManager;
    OUString const sImplementationName;

    ProviderRequest(
        void* pServiceManager,
        sal_Char const* pImplementationName
    )
    : xServiceManager(reinterpret_cast<XMultiServiceFactory*>(pServiceManager))
    , sImplementationName(OUString::createFromAscii(pImplementationName))
    {
    }

    inline
    sal_Bool CREATE_PROVIDER(
                const OUString& Implname,
                const Sequence< OUString > & Services,
                ::cppu::ComponentInstantiation Factory,
                createFactoryFunc creator
            )
    {
        if (!xRet.is() && (Implname == sImplementationName))
        try
        {
            xRet = creator( xServiceManager, sImplementationName,Factory, Services,0);
        }
        catch(...)
        {
        }
        return xRet.is();
    }

    void* getProvider() const { return xRet.get(); }
};

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

extern "C" void SAL_CALL component_getImplementationEnvironment(
                const sal_Char  **ppEnvTypeName,
                uno_Environment **ppEnv
            )
{
    *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}

//---------------------------------------------------------------------------------------
extern "C" sal_Bool SAL_CALL component_writeInfo(
                void* pServiceManager,
                void* pRegistryKey
            )
{
    if (pRegistryKey)
    try
    {
        Reference< ::com::sun::star::registry::XRegistryKey > xKey(reinterpret_cast< ::com::sun::star::registry::XRegistryKey*>(pRegistryKey));

        REGISTER_PROVIDER(
            ODriver::getImplementationName_Static(),
            ODriver::getSupportedServiceNames_Static(), xKey);

        return sal_True;
    }
    catch (::com::sun::star::registry::InvalidRegistryException& )
    {
        OSL_ENSURE(sal_False, "FILE::component_writeInfo : could not create a registry key ! ## InvalidRegistryException !");
    }

    return sal_False;
}

//---------------------------------------------------------------------------------------
extern "C" void* SAL_CALL component_getFactory(
                    const sal_Char* pImplementationName,
                    void* pServiceManager,
                    void* pRegistryKey)
{
    void* pRet = 0;
    if (pServiceManager)
    {
        ProviderRequest aReq(pServiceManager,pImplementationName);

        aReq.CREATE_PROVIDER(
            ODriver::getImplementationName_Static(),
            ODriver::getSupportedServiceNames_Static(),
            ODriver_CreateInstance, ::cppu::createSingleFactory)
        ;

        if(aReq.xRet.is())
            aReq.xRet->acquire();

        pRet = aReq.getProvider();
    }

    return pRet;
};

<commit_msg>INTEGRATION: CWS warnings01 (1.5.30); FILE MERGED 2005/12/22 11:44:47 fs 1.5.30.2: #i57457# warning-free code 2005/11/16 12:59:05 fs 1.5.30.1: #i57457# warning free code<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: Eservices.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-20 01:29:04 $
 *
 *  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
 *
 ************************************************************************/

#ifndef _CONNECTIVITY_FLAT_EDRIVER_HXX_
#include "flat/EDriver.hxx"
#endif
#ifndef _CPPUHELPER_FACTORY_HXX_
#include <cppuhelper/factory.hxx>
#endif
#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif

using namespace connectivity::flat;
using ::rtl::OUString;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::registry::XRegistryKey;
using ::com::sun::star::lang::XSingleServiceFactory;
using ::com::sun::star::lang::XMultiServiceFactory;

typedef Reference< XSingleServiceFactory > (SAL_CALL *createFactoryFunc)
        (
            const Reference< XMultiServiceFactory > & rServiceManager,
            const OUString & rComponentName,
            ::cppu::ComponentInstantiation pCreateFunction,
            const Sequence< OUString > & rServiceNames,
            rtl_ModuleCount* _pT
        );

//***************************************************************************************
//
// Die vorgeschriebene C-Api muss erfuellt werden!
// Sie besteht aus drei Funktionen, die von dem Modul exportiert werden muessen.
//

//---------------------------------------------------------------------------------------
void REGISTER_PROVIDER(
        const OUString& aServiceImplName,
        const Sequence< OUString>& Services,
        const Reference< ::com::sun::star::registry::XRegistryKey > & xKey)
{
    OUString aMainKeyName;
    aMainKeyName = OUString::createFromAscii("/");
    aMainKeyName += aServiceImplName;
    aMainKeyName += OUString::createFromAscii("/UNO/SERVICES");

    Reference< ::com::sun::star::registry::XRegistryKey >  xNewKey( xKey->createKey(aMainKeyName) );
    OSL_ENSURE(xNewKey.is(), "FILE::component_writeInfo : could not create a registry key !");

    for (sal_Int32 i=0; i<Services.getLength(); ++i)
        xNewKey->createKey(Services[i]);
}

//---------------------------------------------------------------------------------------
struct ProviderRequest
{
    Reference< XSingleServiceFactory > xRet;
    Reference< XMultiServiceFactory > const xServiceManager;
    OUString const sImplementationName;

    ProviderRequest(
        void* pServiceManager,
        sal_Char const* pImplementationName
    )
    : xServiceManager(reinterpret_cast<XMultiServiceFactory*>(pServiceManager))
    , sImplementationName(OUString::createFromAscii(pImplementationName))
    {
    }

    inline
    sal_Bool CREATE_PROVIDER(
                const OUString& Implname,
                const Sequence< OUString > & Services,
                ::cppu::ComponentInstantiation Factory,
                createFactoryFunc creator
            )
    {
        if (!xRet.is() && (Implname == sImplementationName))
        try
        {
            xRet = creator( xServiceManager, sImplementationName,Factory, Services,0);
        }
        catch(...)
        {
        }
        return xRet.is();
    }

    void* getProvider() const { return xRet.get(); }
};

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

extern "C" void SAL_CALL component_getImplementationEnvironment(
                const sal_Char  **ppEnvTypeName,
                uno_Environment ** /*ppEnv*/
            )
{
    *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}

//---------------------------------------------------------------------------------------
extern "C" sal_Bool SAL_CALL component_writeInfo(
                void* /*pServiceManager*/,
                void* pRegistryKey
            )
{
    if (pRegistryKey)
    try
    {
        Reference< ::com::sun::star::registry::XRegistryKey > xKey(reinterpret_cast< ::com::sun::star::registry::XRegistryKey*>(pRegistryKey));

        REGISTER_PROVIDER(
            ODriver::getImplementationName_Static(),
            ODriver::getSupportedServiceNames_Static(), xKey);

        return sal_True;
    }
    catch (::com::sun::star::registry::InvalidRegistryException& )
    {
        OSL_ENSURE(sal_False, "FILE::component_writeInfo : could not create a registry key ! ## InvalidRegistryException !");
    }

    return sal_False;
}

//---------------------------------------------------------------------------------------
extern "C" void* SAL_CALL component_getFactory(
                    const sal_Char* pImplementationName,
                    void* pServiceManager,
                    void* /*pRegistryKey*/)
{
    void* pRet = 0;
    if (pServiceManager)
    {
        ProviderRequest aReq(pServiceManager,pImplementationName);

        aReq.CREATE_PROVIDER(
            ODriver::getImplementationName_Static(),
            ODriver::getSupportedServiceNames_Static(),
            ODriver_CreateInstance, ::cppu::createSingleFactory)
        ;

        if(aReq.xRet.is())
            aReq.xRet->acquire();

        pRet = aReq.getProvider();
    }

    return pRet;
};

<|endoftext|>


<commit_before>/*!
 * \file vectors.hpp
 * \author Nathan Eloe
 * \brief array template specializations
 */

#include "../typeinfo.h"
#include "convert_utils.h"
#include "../element.h"
#include <string>
#include <vector>

namespace bson
{
  template<>
  TypeInfo default_type<array>()
  {
    return ARRAY;
  }

  template<>
  std::string to_string<array>()
  {
    return "std::vector<bson::Element>";
  }

  template<>
  bool Element::check_convert<array>() const
  {
    return m_type == ARRAY;
  }

  template<>
  unsigned Element::deserialize_bytes<array>(const unsigned char* bytes)
  {
    Document d;
    TypeInfo ti;
    Element e;
    int32_t size, consumed = 4;
    memcpy(&size, bytes, 4);
    size --;
    m_data = std::shared_ptr<array>(new array);
    while (consumed < size)
    {
      ti = static_cast<TypeInfo>(*(bytes + consumed));
      std::string name((char*)bytes + (++consumed));
      consumed += name.size() + 1;
      consumed  += e.decode(bytes + consumed, ti);
      std::static_pointer_cast<array>(m_data) -> push_back(e);
    }
    return consumed + 1;
  }

  template<>
  void Element::serialize_bson<array>(std::ostringstream& oss) const
  {
    int size = std::static_pointer_cast<array>(m_data) -> size();
    int index = 0;
    std::ostringstream data_ser;
    for (const Element & e: *(std::static_pointer_cast<array>(m_data)))
    {
      data_ser << to_char(e.m_type) << itos(index++) << X00;
      e.encode(data_ser);
    }
    _to_stream(oss, static_cast<int>(5 + data_ser.tellp()));
    oss << data_ser.str() << X00;
    return;
  }

  template <>
  std::string Element::_to_std_str<array>() const
  {
    std::ostringstream oss;
    int size = std::static_pointer_cast<array>(m_data) -> size();
    oss << "[ ";
    if (size > 0)
      oss << static_cast<std::string>((*(std::static_pointer_cast<array>(m_data)))[0]);
    for (int i=0; i < size; i++)
    {
      oss << ", " << static_cast<std::string>((*(std::static_pointer_cast<array>(m_data)))[i]);
    }
    oss << " ]";
    return oss.str();
  }
}<commit_msg>silly bug in outputting an array to a string<commit_after>/*!
 * \file vectors.hpp
 * \author Nathan Eloe
 * \brief array template specializations
 */

#include "../typeinfo.h"
#include "convert_utils.h"
#include "../element.h"
#include <string>
#include <vector>

namespace bson
{
  template<>
  TypeInfo default_type<array>()
  {
    return ARRAY;
  }

  template<>
  std::string to_string<array>()
  {
    return "std::vector<bson::Element>";
  }

  template<>
  bool Element::check_convert<array>() const
  {
    return m_type == ARRAY;
  }

  template<>
  unsigned Element::deserialize_bytes<array>(const unsigned char* bytes)
  {
    Document d;
    TypeInfo ti;
    Element e;
    int32_t size, consumed = 4;
    memcpy(&size, bytes, 4);
    size --;
    m_data = std::shared_ptr<array>(new array);
    while (consumed < size)
    {
      ti = static_cast<TypeInfo>(*(bytes + consumed));
      std::string name((char*)bytes + (++consumed));
      consumed += name.size() + 1;
      consumed  += e.decode(bytes + consumed, ti);
      std::static_pointer_cast<array>(m_data) -> push_back(e);
    }
    return consumed + 1;
  }

  template<>
  void Element::serialize_bson<array>(std::ostringstream& oss) const
  {
    int size = std::static_pointer_cast<array>(m_data) -> size();
    int index = 0;
    std::ostringstream data_ser;
    for (const Element & e: *(std::static_pointer_cast<array>(m_data)))
    {
      data_ser << to_char(e.m_type) << itos(index++) << X00;
      e.encode(data_ser);
    }
    _to_stream(oss, static_cast<int>(5 + data_ser.tellp()));
    oss << data_ser.str() << X00;
    return;
  }

  template <>
  std::string Element::_to_std_str<array>() const
  {
    std::ostringstream oss;
    int size = std::static_pointer_cast<array>(m_data) -> size();
    oss << "[ ";
    if (size > 0)
      oss << static_cast<std::string>((*(std::static_pointer_cast<array>(m_data)))[0]);
    for (int i=1; i < size; i++)
    {
      oss << ", " << static_cast<std::string>((*(std::static_pointer_cast<array>(m_data)))[i]);
    }
    oss << " ]";
    return oss.str();
  }
}<|endoftext|>


<commit_before>// @(#)root/base:$Name:  $:$Id: TStopwatch.cxx,v 1.4 2000/12/13 15:13:46 brun Exp $
// Author: Fons Rademakers   11/10/95

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TStopwatch                                                           //
//                                                                      //
// Stopwatch class. This class returns the real and cpu time between    //
// the start and stop events.                                           //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TStopwatch.h"
#include "TString.h"

#if defined(R__MAC)
#   include <time.h>
static clock_t gTicks = CLOCKS_PER_SEC;
#elif defined(R__UNIX)
#   include <sys/times.h>
#   include <unistd.h>
static clock_t gTicks = 0;
#elif defined(R__VMS)
#   include <time.h>
#   include <unistd.h>
static clock_t gTicks = 1000;
#elif defined(WIN32)
#   include "TError.h"
    const Double_t gTicks = 1.0e-7;
#   include "Windows4Root.h"
#endif

ClassImp(TStopwatch)

//______________________________________________________________________________
TStopwatch::TStopwatch()
{
   // Create a stopwatch and start it.

#ifdef R__UNIX
   if (!gTicks) gTicks = (clock_t)sysconf(_SC_CLK_TCK);
#endif
   fState         = kUndefined;
   fTotalCpuTime  = 0;
   fTotalRealTime = 0;
   fCounter       = 0;
   Start();
}

//______________________________________________________________________________
void TStopwatch::Start(Bool_t reset)
{
   // Start the stopwatch. If reset is kTRUE reset the stopwatch before
   // starting it (including the stopwatch counter).
   // Use kFALSE to continue timing after a Stop() without
   // resetting the stopwatch.

   if (reset) {
      fTotalCpuTime  = 0;
      fTotalRealTime = 0;
      fCounter       = 0;
   }
   if (fState != kRunning) {
#ifndef R__UNIX
      fStartRealTime = GetRealTime();
      fStartCpuTime  = GetCPUTime();
#else
      struct tms cpt;
      fStartRealTime = (Double_t)times(&cpt) / gTicks;
      fStartCpuTime  = (Double_t)(cpt.tms_utime+cpt.tms_stime) / gTicks;
#endif
   }
   fState = kRunning;
   fCounter++;
}

//______________________________________________________________________________
void TStopwatch::Stop()
{
   // Stop the stopwatch.

#ifndef R__UNIX
   fStopRealTime = GetRealTime();
   fStopCpuTime  = GetCPUTime();
#else
   struct tms cpt;
   fStopRealTime = (Double_t)times(&cpt) / gTicks;
   fStopCpuTime  = (Double_t)(cpt.tms_utime+cpt.tms_stime) / gTicks;
#endif
   if (fState == kRunning) {
      fTotalCpuTime  += fStopCpuTime  - fStartCpuTime;
      fTotalRealTime += fStopRealTime - fStartRealTime;
   }
   fState = kStopped;
}

//______________________________________________________________________________
void TStopwatch::Continue()
{
   // Resume a stopped stopwatch. The stopwatch continues counting from the last
   // Start() onwards (this is like the laptimer function).

   if (fState == kUndefined)
      Error("Continue", "stopwatch not started");

   if (fState == kStopped) {
      fTotalCpuTime  -= fStopCpuTime  - fStartCpuTime;
      fTotalRealTime -= fStopRealTime - fStartRealTime;
   }

   fState = kRunning;
}

//______________________________________________________________________________
Double_t TStopwatch::RealTime()
{
   // Return the realtime passed between the start and stop events. If the
   // stopwatch was still running stop it first.

   if (fState == kUndefined)
      Error("RealTime", "stopwatch not started");

   if (fState == kRunning)
      Stop();

   return fTotalRealTime;
}

//______________________________________________________________________________
Double_t TStopwatch::CpuTime()
{
   // Return the cputime passed between the start and stop events. If the
   // stopwatch was still running stop it first.

   if (fState == kUndefined)
      Error("RealTime", "stopwatch not started");

   if (fState == kRunning)
      Stop();

   return fTotalCpuTime;
}

//______________________________________________________________________________
Double_t TStopwatch::GetRealTime()
{
   // Private static method returning system realtime.

#if defined(R__MAC)
   return (Double_t)clock() / gTicks;
#elif defined(R__UNIX)
   struct tms cpt;
   Double_t trt = (Double_t)times(&cpt);
   return trt / (Double_t) gTicks;
#elif defined(R__VMS)
   return (Double_t)clock() / gTicks;
#elif defined(WIN32)
   union {
      FILETIME ftFileTime;
      __int64  ftInt64;
   } ftRealTime; // time the process has spent in kernel mode
   SYSTEMTIME st;
   GetSystemTime(&st);
   SystemTimeToFileTime(&st,&ftRealTime.ftFileTime);
   return (Double_t)ftRealTime.ftInt64 * gTicks;
#endif
}

//______________________________________________________________________________
Double_t TStopwatch::GetCPUTime()
{
   // Private static method returning system CPU time.

#if defined(R__MAC)
   return (Double_t)clock() / gTicks;
#elif defined(R__UNIX)
   struct tms cpt;
   times(&cpt);
   return (Double_t)(cpt.tms_utime+cpt.tms_stime) / gTicks;
#elif defined(R__VMS)
   return (Double_t)clock() / gTicks;
#elif defined(WIN32)

   OSVERSIONINFO OsVersionInfo;

   //         Value                      Platform
   //----------------------------------------------------
   //  VER_PLATFORM_WIN32s          Win32s on Windows 3.1
   //  VER_PLATFORM_WIN32_WINDOWS   Win32 on Windows 95
   //  VER_PLATFORM_WIN32_NT        Windows NT
   //
   OsVersionInfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
   GetVersionEx(&OsVersionInfo);
   if (OsVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {
      DWORD       ret;
      FILETIME    ftCreate,       // when the process was created
                  ftExit;         // when the process exited

      union {
         FILETIME ftFileTime;
         __int64  ftInt64;
      } ftKernel; // time the process has spent in kernel mode

      union {
         FILETIME ftFileTime;
         __int64  ftInt64;
      } ftUser;   // time the process has spent in user mode

      HANDLE hProcess = GetCurrentProcess();
      ret = GetProcessTimes (hProcess, &ftCreate, &ftExit,
                                       &ftKernel.ftFileTime,
                                       &ftUser.ftFileTime);
      if (ret != TRUE) {
         ret = GetLastError ();
         ::Error ("GetCPUTime", " Error on GetProcessTimes 0x%lx", (int)ret);
      }

      // Process times are returned in a 64-bit structure, as the number of
      // 100 nanosecond ticks since 1 January 1601.  User mode and kernel mode
      // times for this process are in separate 64-bit structures.
      // To convert to floating point seconds, we will:
      //
      // Convert sum of high 32-bit quantities to 64-bit int

      return (Double_t) (ftKernel.ftInt64 + ftUser.ftInt64) * gTicks;
  } else
      return GetRealTime();
#endif
}

//______________________________________________________________________________
void TStopwatch::Print(Option_t *) const
{
   // Print the real and cpu time passed between the start and stop events.
   // and the number of times (slices) this TStopwatch was called
   // (if this number > 1)

   Double_t  realt = ((TStopwatch*)this)->RealTime();

   Int_t  hours = Int_t(realt / 3600);
   realt -= hours * 3600;
   Int_t  min   = Int_t(realt / 60);
   realt -= min * 60;
   Int_t  sec   = Int_t(realt);
   Int_t counter = Counter();
   if (counter <= 1 )
      Printf("Real time %d:%d:%d, CP time %.3f", hours, min, sec, ((TStopwatch*)this)->CpuTime());
   else
      Printf("Real time %d:%d:%d, CP time %.3f, %d slices", hours, min, sec, ((TStopwatch*)this)->CpuTime(),counter);
}

<commit_msg>added option "m" to Print() to allow millisecond precision in the real time reporting. By Maarten.<commit_after>// @(#)root/base:$Name:  $:$Id: TStopwatch.cxx,v 1.5 2002/06/13 13:42:55 rdm Exp $
// Author: Fons Rademakers   11/10/95

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TStopwatch                                                           //
//                                                                      //
// Stopwatch class. This class returns the real and cpu time between    //
// the start and stop events.                                           //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TStopwatch.h"
#include "TString.h"

#if defined(R__MAC)
#   include <time.h>
static clock_t gTicks = CLOCKS_PER_SEC;
#elif defined(R__UNIX)
#   include <sys/times.h>
#   include <unistd.h>
static clock_t gTicks = 0;
#elif defined(R__VMS)
#   include <time.h>
#   include <unistd.h>
static clock_t gTicks = 1000;
#elif defined(WIN32)
#   include "TError.h"
    const Double_t gTicks = 1.0e-7;
#   include "Windows4Root.h"
#endif

ClassImp(TStopwatch)

//______________________________________________________________________________
TStopwatch::TStopwatch()
{
   // Create a stopwatch and start it.

#ifdef R__UNIX
   if (!gTicks) gTicks = (clock_t)sysconf(_SC_CLK_TCK);
#endif
   fState         = kUndefined;
   fTotalCpuTime  = 0;
   fTotalRealTime = 0;
   fCounter       = 0;
   Start();
}

//______________________________________________________________________________
void TStopwatch::Start(Bool_t reset)
{
   // Start the stopwatch. If reset is kTRUE reset the stopwatch before
   // starting it (including the stopwatch counter).
   // Use kFALSE to continue timing after a Stop() without
   // resetting the stopwatch.

   if (reset) {
      fTotalCpuTime  = 0;
      fTotalRealTime = 0;
      fCounter       = 0;
   }
   if (fState != kRunning) {
#ifndef R__UNIX
      fStartRealTime = GetRealTime();
      fStartCpuTime  = GetCPUTime();
#else
      struct tms cpt;
      fStartRealTime = (Double_t)times(&cpt) / gTicks;
      fStartCpuTime  = (Double_t)(cpt.tms_utime+cpt.tms_stime) / gTicks;
#endif
   }
   fState = kRunning;
   fCounter++;
}

//______________________________________________________________________________
void TStopwatch::Stop()
{
   // Stop the stopwatch.

#ifndef R__UNIX
   fStopRealTime = GetRealTime();
   fStopCpuTime  = GetCPUTime();
#else
   struct tms cpt;
   fStopRealTime = (Double_t)times(&cpt) / gTicks;
   fStopCpuTime  = (Double_t)(cpt.tms_utime+cpt.tms_stime) / gTicks;
#endif
   if (fState == kRunning) {
      fTotalCpuTime  += fStopCpuTime  - fStartCpuTime;
      fTotalRealTime += fStopRealTime - fStartRealTime;
   }
   fState = kStopped;
}

//______________________________________________________________________________
void TStopwatch::Continue()
{
   // Resume a stopped stopwatch. The stopwatch continues counting from the last
   // Start() onwards (this is like the laptimer function).

   if (fState == kUndefined)
      Error("Continue", "stopwatch not started");

   if (fState == kStopped) {
      fTotalCpuTime  -= fStopCpuTime  - fStartCpuTime;
      fTotalRealTime -= fStopRealTime - fStartRealTime;
   }

   fState = kRunning;
}

//______________________________________________________________________________
Double_t TStopwatch::RealTime()
{
   // Return the realtime passed between the start and stop events. If the
   // stopwatch was still running stop it first.

   if (fState == kUndefined)
      Error("RealTime", "stopwatch not started");

   if (fState == kRunning)
      Stop();

   return fTotalRealTime;
}

//______________________________________________________________________________
Double_t TStopwatch::CpuTime()
{
   // Return the cputime passed between the start and stop events. If the
   // stopwatch was still running stop it first.

   if (fState == kUndefined)
      Error("CpuTime", "stopwatch not started");

   if (fState == kRunning)
      Stop();

   return fTotalCpuTime;
}

//______________________________________________________________________________
Double_t TStopwatch::GetRealTime()
{
   // Private static method returning system realtime.

#if defined(R__MAC)
   return (Double_t)clock() / gTicks;
#elif defined(R__UNIX)
   struct tms cpt;
   Double_t trt = (Double_t)times(&cpt);
   return trt / (Double_t) gTicks;
#elif defined(R__VMS)
   return (Double_t)clock() / gTicks;
#elif defined(WIN32)
   union {
      FILETIME ftFileTime;
      __int64  ftInt64;
   } ftRealTime; // time the process has spent in kernel mode
   SYSTEMTIME st;
   GetSystemTime(&st);
   SystemTimeToFileTime(&st,&ftRealTime.ftFileTime);
   return (Double_t)ftRealTime.ftInt64 * gTicks;
#endif
}

//______________________________________________________________________________
Double_t TStopwatch::GetCPUTime()
{
   // Private static method returning system CPU time.

#if defined(R__MAC)
   return (Double_t)clock() / gTicks;
#elif defined(R__UNIX)
   struct tms cpt;
   times(&cpt);
   return (Double_t)(cpt.tms_utime+cpt.tms_stime) / gTicks;
#elif defined(R__VMS)
   return (Double_t)clock() / gTicks;
#elif defined(WIN32)

   OSVERSIONINFO OsVersionInfo;

   //         Value                      Platform
   //----------------------------------------------------
   //  VER_PLATFORM_WIN32s          Win32s on Windows 3.1
   //  VER_PLATFORM_WIN32_WINDOWS   Win32 on Windows 95
   //  VER_PLATFORM_WIN32_NT        Windows NT
   //
   OsVersionInfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
   GetVersionEx(&OsVersionInfo);
   if (OsVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {
      DWORD       ret;
      FILETIME    ftCreate,       // when the process was created
                  ftExit;         // when the process exited

      union {
         FILETIME ftFileTime;
         __int64  ftInt64;
      } ftKernel; // time the process has spent in kernel mode

      union {
         FILETIME ftFileTime;
         __int64  ftInt64;
      } ftUser;   // time the process has spent in user mode

      HANDLE hProcess = GetCurrentProcess();
      ret = GetProcessTimes (hProcess, &ftCreate, &ftExit,
                                       &ftKernel.ftFileTime,
                                       &ftUser.ftFileTime);
      if (ret != TRUE) {
         ret = GetLastError ();
         ::Error ("GetCPUTime", " Error on GetProcessTimes 0x%lx", (int)ret);
      }

      // Process times are returned in a 64-bit structure, as the number of
      // 100 nanosecond ticks since 1 January 1601.  User mode and kernel mode
      // times for this process are in separate 64-bit structures.
      // To convert to floating point seconds, we will:
      //
      // Convert sum of high 32-bit quantities to 64-bit int

      return (Double_t) (ftKernel.ftInt64 + ftUser.ftInt64) * gTicks;
  } else
      return GetRealTime();
#endif
}

//______________________________________________________________________________
void TStopwatch::Print(Option_t *opt) const
{
   // Print the real and cpu time passed between the start and stop events.
   // and the number of times (slices) this TStopwatch was called
   // (if this number > 1). If opt="m" printout realtime in milli second
   // precision.

   Double_t  realt = const_cast<TStopwatch*>(this)->RealTime();
   Double_t  cput  = const_cast<TStopwatch*>(this)->CpuTime();

   Int_t  hours = Int_t(realt / 3600);
   realt -= hours * 3600;
   Int_t  min   = Int_t(realt / 60);
   realt -= min * 60;
   Int_t  sec   = Int_t(realt);

   realt = TMath::Max(realt, 0.);
   cput  = TMath::Max(cput, 0.);

   if (opt && *opt == 'm') {
      if (Counter() > 1) {
         Printf("Real time %d:%02d:%06.3f, CP time %.3f, %d slices", hours, min, realt, cput, Counter());
      } else {
         Printf("Real time %d:%02d:%06.3f, CP time %.3f", hours, min, realt, cput);
      }
   } else {
      if (Counter() > 1) {
         Printf("Real time %d:%02d:%02d, CP time %.3f, %d slices", hours, min, sec, cput, Counter());
      } else {
         Printf("Real time %d:%02d:%02d, CP time %.3f", hours, min, sec, cput);
      }
   }
}
<|endoftext|>


<commit_before>#include "Session.h"

#include <string>

#include <SmurffCpp/Version.h>

#include <SmurffCpp/Utils/omp_util.h>
#include <SmurffCpp/Utils/Distribution.h>
#include <SmurffCpp/Utils/MatrixUtils.h>
#include <SmurffCpp/Utils/counters.h>
#include <SmurffCpp/Utils/Error.h>

#include <SmurffCpp/DataMatrices/DataCreator.h>
#include <SmurffCpp/Priors/PriorFactory.h>

#include <SmurffCpp/result.h>

using namespace smurff;

void Session::setFromRootPath(std::string rootPath)
{
   // assign config

   m_rootFile = std::make_shared<RootFile>(rootPath);
   m_rootFile->restoreConfig(m_config);

   m_config.validate();

   //base functionality
   setFromBase();
}

void Session::setFromConfig(const Config& cfg)
{
   // assign config

   cfg.validate();
   m_config = cfg;

   m_rootFile = std::make_shared<RootFile>(m_config.getSavePrefix(), m_config.getSaveExtension());
   m_rootFile->saveConfig(m_config);

   //base functionality
   setFromBase();

   //flush record about options.ini
   m_rootFile->flushLast();
}

void Session::setFromBase()
{
   std::shared_ptr<Session> this_session = shared_from_this();

   // initialize pred

   if (m_config.getClassify())
      m_pred->setThreshold(m_config.getThreshold());

   if (m_config.getTest())
      m_pred->set(m_config.getTest());

   // initialize data

   data_ptr = m_config.getTrain()->create(std::make_shared<DataCreator>(this_session));

   // initialize priors

   std::shared_ptr<IPriorFactory> priorFactory = this->create_prior_factory();
   for (std::size_t i = 0; i < m_config.getPriorTypes().size(); i++)
      this->addPrior(priorFactory->create_prior(this_session, i));
}

void Session::init()
{
   //init omp
   threads_init();

   //initialize random generator
   initRng();

   //initialize train matrix (centring and noise model)
   data()->init();

   //initialize model (samples)
   m_model->init(m_config.getNumLatent(), data()->dim(), m_config.getModelInitType());

   //initialize priors
   for(auto &p : m_priors)
      p->init();

   //write header to status file
   if (m_config.getCsvStatus().size())
   {
      auto f = fopen(m_config.getCsvStatus().c_str(), "w");
      fprintf(f, "phase;iter;phase_len;globmean_rmse;colmean_rmse;rmse_avg;rmse_1samp;train_rmse;auc_avg;auc_1samp;U0;U1;elapsed\n");
      fclose(f);
   }

   //write info to console
   if (m_config.getVerbose())
      info(std::cout, "");

   //restore session (model, priors)
   bool resume = restore(m_iter);

   //print session status to console
   if (m_config.getVerbose())
   {
      printStatus(0, resume, m_iter);
      printf(" ====== Sampling (burning phase) ====== \n");
   }

   //restore will either start from initial iteration (-1) that should be printed with printStatus
   //or it will start with last iteration that was previously saved
   //in any case - we have to move to next iteration
   m_iter++; //go to next iteration

   is_init = true;
}

void Session::run()
{
   init();

   while (m_iter < m_config.getBurnin() + m_config.getNSamples())
      step();
}

void Session::step()
{
   THROWERROR_ASSERT(is_init);

   if (m_config.getVerbose() && m_iter == m_config.getBurnin())
   {
      printf(" ====== Burn-in complete, averaging samples ====== \n");
   }

   auto starti = tick();
   BaseSession::step();
   auto endi = tick();

   //WARNING: update is an expensive operation because of sort (when calculating AUC)
   m_pred->update(m_model, m_iter < m_config.getBurnin());

   printStatus(endi - starti, false, m_iter);

   save(m_iter);

   m_iter++;
}

std::ostream& Session::info(std::ostream &os, std::string indent)
{
   os << indent << name << " {\n";

   BaseSession::info(os, indent);

   os << indent << "  Version: " << smurff::SMURFF_VERSION << "\n" ;
   os << indent << "  Iterations: " << m_config.getBurnin() << " burnin + " << m_config.getNSamples() << " samples\n";

   if (m_config.getSaveFreq() != 0)
   {
      if (m_config.getSaveFreq() > 0)
      {
          os << indent << "  Save model: every " << m_config.getSaveFreq() << " iteration\n";
      }
      else
      {
          os << indent << "  Save model after last iteration\n";
      }

      os << indent << "  Save prefix: " << m_config.getSavePrefix() << "\n";
      os << indent << "  Save extension: " << m_config.getSaveExtension() << "\n";
   }
   else
   {
      os << indent << "  Save model: never\n";
   }

   os << indent << "}\n";
   return os;
}

void Session::save(int iteration) const
{
   //do not save if 'never save' mode is selected
   if (!m_config.getSaveFreq())
      return;

   std::int32_t isample = iteration - m_config.getBurnin() + 1;

   //save if burnin
   if (isample <= 0)
   {
      std::int32_t iburninPrev = iteration;
      if (iburninPrev > 0)
      {
         //remove previous iteration
         m_rootFile->removeBurninStepFile(iburninPrev);

         //flush last item in a root file
         m_rootFile->flushLast();
      }

      std::int32_t iburnin = iteration + 1;

      //save this iteration
      std::shared_ptr<StepFile> stepFile = m_rootFile->createBurninStepFile(iburnin);
      saveInternal(stepFile);
   }
   else
   {
      //save_freq > 0: check modulo - do not save if not a save iteration
      if (m_config.getSaveFreq() > 0 && (isample % m_config.getSaveFreq()) != 0)
         return;

      //save_freq < 0: save last iter - do not save if (final model) mode is selected and not a final iteration
      if (m_config.getSaveFreq() < 0 && isample < m_config.getNSamples())
         return;

      //save this iteration
      std::shared_ptr<StepFile> stepFile = m_rootFile->createSampleStepFile(isample);
      saveInternal(stepFile);
   }
}

void Session::saveInternal(std::shared_ptr<StepFile> stepFile) const
{
   if (m_config.getVerbose())
      printf("-- Saving model, predictions,... into '%s'.\n", stepFile->getStepFileName().c_str());

   BaseSession::save(stepFile);

   //flush last item in a root file
   m_rootFile->flushLast();
}

bool Session::restore(int& iteration)
{
   std::shared_ptr<StepFile> stepFile = m_rootFile->openLastStepFile();
   if (!stepFile)
   {
      //if there is nothing to restore - start from initial iteration
      iteration = -1;
      return false;
   }
   else
   {
      if (m_config.getVerbose())
         printf("-- Restoring model, predictions,... from '%s'.\n", stepFile->getStepFileName().c_str());

      BaseSession::restore(stepFile);

      //restore last iteration index
      if (stepFile->getBurnin())
      {
         iteration = stepFile->getIsample() - 1; //restore original state
      }
      else
      {
         iteration = stepFile->getIsample() + m_config.getBurnin() - 1; //restore original state
      }

      return true;
   }
}

void Session::printStatus(double elapsedi, bool resume, int iteration)
{
   if(!m_config.getVerbose())
      return;

   double snorm0 = m_model->U(0).norm();
   double snorm1 = m_model->U(1).norm();

   auto nnz_per_sec = (data()->nnz()) / elapsedi;
   auto samples_per_sec = (m_model->nsamples()) / elapsedi;

   std::string resumeString = resume ? "Continue from " : std::string();

   std::string phase;
   int i, from;
   if (iteration < 0)
   {
      phase = "Initial";
      i = iteration + 1;
      from = 0;
   }
   else if (iteration < m_config.getBurnin())
   {
      phase = "Burnin";
      i = iteration + 1;
      from = m_config.getBurnin();
   }
   else
   {
      phase = "Sample";
      i = iteration - m_config.getBurnin() + 1;
      from = m_config.getNSamples();
   }

   printf("%s%s %3d/%3d: RMSE: %.4f (1samp: %.4f)", resumeString.c_str(), phase.c_str(), i, from, m_pred->rmse_avg, m_pred->rmse_1sample);

   if (m_config.getClassify())
      printf(" AUC:%.4f (1samp: %.4f)", m_pred->auc_avg, m_pred->auc_1sample);

   printf("  U:[%1.2e, %1.2e] [took: %0.1fs]\n", snorm0, snorm1, elapsedi);

   // avoid computing train_rmse twice
   double train_rmse = NAN;

   if (m_config.getVerbose() > 1)
   {
      train_rmse = data()->train_rmse(m_model);
      printf("  RMSE train: %.4f\n", train_rmse);
      printf("  Priors:\n");

      for(const auto &p : m_priors)
         p->status(std::cout, "     ");

      printf("  Model:\n");
      m_model->status(std::cout, "    ");
      printf("  Noise:\n");
      data()->status(std::cout, "    ");
   }

   if (m_config.getVerbose() > 2)
   {
      printf("  Compute Performance: %.0f samples/sec, %.0f nnz/sec\n", samples_per_sec, nnz_per_sec);
   }

   if (m_config.getCsvStatus().size())
   {
      // train_rmse is printed as NAN, unless verbose > 1
      auto f = fopen(m_config.getCsvStatus().c_str(), "a");
      fprintf(f, "%s;%d;%d;%.4f;%.4f;%.4f;%.4f;:%.4f;%1.2e;%1.2e;%0.1f\n",
                  phase.c_str(), i, from,
                  m_pred->rmse_avg, m_pred->rmse_1sample, train_rmse, m_pred->auc_1sample, m_pred->auc_avg, snorm0, snorm1, elapsedi);
      fclose(f);
   }
}

void Session::initRng()
{
   //init random generator
   if (m_config.getRandomSeedSet())
      init_bmrng(m_config.getRandomSeed());
   else
      init_bmrng();
}

std::shared_ptr<IPriorFactory> Session::create_prior_factory() const
{
   return std::make_shared<PriorFactory>();
}<commit_msg>Write CsvStatus file, even if verbose == 0<commit_after>#include "Session.h"

#include <string>

#include <SmurffCpp/Version.h>

#include <SmurffCpp/Utils/omp_util.h>
#include <SmurffCpp/Utils/Distribution.h>
#include <SmurffCpp/Utils/MatrixUtils.h>
#include <SmurffCpp/Utils/counters.h>
#include <SmurffCpp/Utils/Error.h>

#include <SmurffCpp/DataMatrices/DataCreator.h>
#include <SmurffCpp/Priors/PriorFactory.h>

#include <SmurffCpp/result.h>

using namespace smurff;

void Session::setFromRootPath(std::string rootPath)
{
   // assign config

   m_rootFile = std::make_shared<RootFile>(rootPath);
   m_rootFile->restoreConfig(m_config);

   m_config.validate();

   //base functionality
   setFromBase();
}

void Session::setFromConfig(const Config& cfg)
{
   // assign config

   cfg.validate();
   m_config = cfg;

   m_rootFile = std::make_shared<RootFile>(m_config.getSavePrefix(), m_config.getSaveExtension());
   m_rootFile->saveConfig(m_config);

   //base functionality
   setFromBase();

   //flush record about options.ini
   m_rootFile->flushLast();
}

void Session::setFromBase()
{
   std::shared_ptr<Session> this_session = shared_from_this();

   // initialize pred

   if (m_config.getClassify())
      m_pred->setThreshold(m_config.getThreshold());

   if (m_config.getTest())
      m_pred->set(m_config.getTest());

   // initialize data

   data_ptr = m_config.getTrain()->create(std::make_shared<DataCreator>(this_session));

   // initialize priors

   std::shared_ptr<IPriorFactory> priorFactory = this->create_prior_factory();
   for (std::size_t i = 0; i < m_config.getPriorTypes().size(); i++)
      this->addPrior(priorFactory->create_prior(this_session, i));
}

void Session::init()
{
   //init omp
   threads_init();

   //initialize random generator
   initRng();

   //initialize train matrix (centring and noise model)
   data()->init();

   //initialize model (samples)
   m_model->init(m_config.getNumLatent(), data()->dim(), m_config.getModelInitType());

   //initialize priors
   for(auto &p : m_priors)
      p->init();

   //write header to status file
   if (m_config.getCsvStatus().size())
   {
      auto f = fopen(m_config.getCsvStatus().c_str(), "w");
      fprintf(f, "phase;iter;phase_len;globmean_rmse;colmean_rmse;rmse_avg;rmse_1samp;train_rmse;auc_avg;auc_1samp;U0;U1;elapsed\n");
      fclose(f);
   }

   //write info to console
   if (m_config.getVerbose())
      info(std::cout, "");

   //restore session (model, priors)
   bool resume = restore(m_iter);

   //print session status to console
   if (m_config.getVerbose())
   {
      printStatus(0, resume, m_iter);
      printf(" ====== Sampling (burning phase) ====== \n");
   }

   //restore will either start from initial iteration (-1) that should be printed with printStatus
   //or it will start with last iteration that was previously saved
   //in any case - we have to move to next iteration
   m_iter++; //go to next iteration

   is_init = true;
}

void Session::run()
{
   init();

   while (m_iter < m_config.getBurnin() + m_config.getNSamples())
      step();
}

void Session::step()
{
   THROWERROR_ASSERT(is_init);

   if (m_config.getVerbose() && m_iter == m_config.getBurnin())
   {
      printf(" ====== Burn-in complete, averaging samples ====== \n");
   }

   auto starti = tick();
   BaseSession::step();
   auto endi = tick();

   //WARNING: update is an expensive operation because of sort (when calculating AUC)
   m_pred->update(m_model, m_iter < m_config.getBurnin());

   printStatus(endi - starti, false, m_iter);

   save(m_iter);

   m_iter++;
}

std::ostream& Session::info(std::ostream &os, std::string indent)
{
   os << indent << name << " {\n";

   BaseSession::info(os, indent);

   os << indent << "  Version: " << smurff::SMURFF_VERSION << "\n" ;
   os << indent << "  Iterations: " << m_config.getBurnin() << " burnin + " << m_config.getNSamples() << " samples\n";

   if (m_config.getSaveFreq() != 0)
   {
      if (m_config.getSaveFreq() > 0)
      {
          os << indent << "  Save model: every " << m_config.getSaveFreq() << " iteration\n";
      }
      else
      {
          os << indent << "  Save model after last iteration\n";
      }

      os << indent << "  Save prefix: " << m_config.getSavePrefix() << "\n";
      os << indent << "  Save extension: " << m_config.getSaveExtension() << "\n";
   }
   else
   {
      os << indent << "  Save model: never\n";
   }

   os << indent << "}\n";
   return os;
}

void Session::save(int iteration) const
{
   //do not save if 'never save' mode is selected
   if (!m_config.getSaveFreq() && !m_config.getCsvStatus().size())
      return;

   std::int32_t isample = iteration - m_config.getBurnin() + 1;

   //save if burnin
   if (isample <= 0)
   {
      std::int32_t iburninPrev = iteration;
      if (iburninPrev > 0)
      {
         //remove previous iteration
         m_rootFile->removeBurninStepFile(iburninPrev);

         //flush last item in a root file
         m_rootFile->flushLast();
      }

      std::int32_t iburnin = iteration + 1;

      //save this iteration
      std::shared_ptr<StepFile> stepFile = m_rootFile->createBurninStepFile(iburnin);
      saveInternal(stepFile);
   }
   else
   {
      //save_freq > 0: check modulo - do not save if not a save iteration
      if (m_config.getSaveFreq() > 0 && (isample % m_config.getSaveFreq()) != 0)
         return;

      //save_freq < 0: save last iter - do not save if (final model) mode is selected and not a final iteration
      if (m_config.getSaveFreq() < 0 && isample < m_config.getNSamples())
         return;

      //save this iteration
      std::shared_ptr<StepFile> stepFile = m_rootFile->createSampleStepFile(isample);
      saveInternal(stepFile);
   }
}

void Session::saveInternal(std::shared_ptr<StepFile> stepFile) const
{
   if (m_config.getVerbose())
      printf("-- Saving model, predictions,... into '%s'.\n", stepFile->getStepFileName().c_str());

   BaseSession::save(stepFile);

   //flush last item in a root file
   m_rootFile->flushLast();
}

bool Session::restore(int& iteration)
{
   std::shared_ptr<StepFile> stepFile = m_rootFile->openLastStepFile();
   if (!stepFile)
   {
      //if there is nothing to restore - start from initial iteration
      iteration = -1;
      return false;
   }
   else
   {
      if (m_config.getVerbose())
         printf("-- Restoring model, predictions,... from '%s'.\n", stepFile->getStepFileName().c_str());

      BaseSession::restore(stepFile);

      //restore last iteration index
      if (stepFile->getBurnin())
      {
         iteration = stepFile->getIsample() - 1; //restore original state
      }
      else
      {
         iteration = stepFile->getIsample() + m_config.getBurnin() - 1; //restore original state
      }

      return true;
   }
}

void Session::printStatus(double elapsedi, bool resume, int iteration)
{
   if(!m_config.getVerbose())
      return;

   double snorm0 = m_model->U(0).norm();
   double snorm1 = m_model->U(1).norm();

   auto nnz_per_sec = (data()->nnz()) / elapsedi;
   auto samples_per_sec = (m_model->nsamples()) / elapsedi;

   std::string resumeString = resume ? "Continue from " : std::string();

   std::string phase;
   int i, from;
   if (iteration < 0)
   {
      phase = "Initial";
      i = iteration + 1;
      from = 0;
   }
   else if (iteration < m_config.getBurnin())
   {
      phase = "Burnin";
      i = iteration + 1;
      from = m_config.getBurnin();
   }
   else
   {
      phase = "Sample";
      i = iteration - m_config.getBurnin() + 1;
      from = m_config.getNSamples();
   }

   printf("%s%s %3d/%3d: RMSE: %.4f (1samp: %.4f)", resumeString.c_str(), phase.c_str(), i, from, m_pred->rmse_avg, m_pred->rmse_1sample);

   if (m_config.getClassify())
      printf(" AUC:%.4f (1samp: %.4f)", m_pred->auc_avg, m_pred->auc_1sample);

   printf("  U:[%1.2e, %1.2e] [took: %0.1fs]\n", snorm0, snorm1, elapsedi);

   // avoid computing train_rmse twice
   double train_rmse = NAN;

   if (m_config.getVerbose() > 1)
   {
      train_rmse = data()->train_rmse(m_model);
      printf("  RMSE train: %.4f\n", train_rmse);
      printf("  Priors:\n");

      for(const auto &p : m_priors)
         p->status(std::cout, "     ");

      printf("  Model:\n");
      m_model->status(std::cout, "    ");
      printf("  Noise:\n");
      data()->status(std::cout, "    ");
   }

   if (m_config.getVerbose() > 2)
   {
      printf("  Compute Performance: %.0f samples/sec, %.0f nnz/sec\n", samples_per_sec, nnz_per_sec);
   }

   if (m_config.getCsvStatus().size())
   {
      // train_rmse is printed as NAN, unless verbose > 1
      auto f = fopen(m_config.getCsvStatus().c_str(), "a");
      fprintf(f, "%s;%d;%d;%.4f;%.4f;%.4f;%.4f;:%.4f;%1.2e;%1.2e;%0.1f\n",
                  phase.c_str(), i, from,
                  m_pred->rmse_avg, m_pred->rmse_1sample, train_rmse, m_pred->auc_1sample, m_pred->auc_avg, snorm0, snorm1, elapsedi);
      fclose(f);
   }
}

void Session::initRng()
{
   //init random generator
   if (m_config.getRandomSeedSet())
      init_bmrng(m_config.getRandomSeed());
   else
      init_bmrng();
}

std::shared_ptr<IPriorFactory> Session::create_prior_factory() const
{
   return std::make_shared<PriorFactory>();
}<|endoftext|>


<commit_before>/**
 * @file   Zip.cpp
 * @brief  Zip class implementation.
 * @author zer0
 * @date   2016-11-17
 */

#include <libtbag/archive/Zip.hpp>
#include <libtbag/filesystem/Path.hpp>
#include <libtbag/filesystem/details/FsCommon.hpp>

#include <cassert>
#include <cstring>

#include <fstream>
#include <iostream>

#include <zlib.h>
#include <zip.h>
#include <unzip.h>

// -------------------
NAMESPACE_LIBTBAG_OPEN
// -------------------

namespace archive {

Zip::Zip()
{
    // EMPTY.
}

Zip::~Zip()
{
    // EMPTY.
}

Zip::ResultCode Zip::coding(Buffer & output, uint8_t const * input, std::size_t size, int level)
{
    bool const ENCODE = (level != DECODE_LEVEL);

    z_stream stream = {0,};
    stream.zalloc   = Z_NULL;
    stream.zfree    = Z_NULL;
    stream.opaque   = Z_NULL;

    int result = Z_OK;
    if (ENCODE) {
        result = deflateInit(&stream, level);
    } else {
        result = inflateInit(&stream);
    }

    if (result != Z_OK) {
        return ResultCode::FAILURE;
    }

    std::size_t const BUFFER_SIZE = 2048; // TODO: CHANGE PAGE SIZE.

    Bytef  in[BUFFER_SIZE] = {0,};
    Bytef out[BUFFER_SIZE] = {0,};

    std::size_t read_index = 0;
    int flush = Z_NO_FLUSH;

    do {
        // Update input buffer.
        stream.next_in = in;
        if (size - read_index > BUFFER_SIZE) {
            stream.avail_in = BUFFER_SIZE;
            flush = Z_NO_FLUSH;
        } else {
            stream.avail_in = static_cast<uInt>(size - read_index);
            flush = Z_FINISH; // EOF.
        }

        memcpy(in, input + read_index, stream.avail_in);
        read_index += stream.avail_in;

        do {
            // Update output buffer.
            stream.avail_out = BUFFER_SIZE;
            stream.next_out  = out;

            if (ENCODE) {
                result = deflate(&stream, flush);
            } else {
                result = inflate(&stream, flush);
            }
            assert(result != Z_STREAM_ERROR);

            std::size_t dsize = BUFFER_SIZE - stream.avail_out;
            output.insert(output.end(), out, out + dsize);
        } while (stream.avail_out == 0);
        assert(stream.avail_in == 0);

    } while (flush != Z_FINISH);
    assert(result == Z_STREAM_END);

    if (ENCODE) {
        deflateEnd(&stream);
    } else {
        inflateEnd(&stream);
    }

    return ResultCode::SUCCESS;
}

Zip::ResultCode Zip::encode(Buffer & output, uint8_t const * input, std::size_t size, int level)
{
    if (level < MIN_ENCODE_LEVEL || level > MAX_ENCODE_LEVEL) {
        level = Z_DEFAULT_COMPRESSION;
    }
    return coding(output, input, size, level);
}

Zip::ResultCode Zip::decode(Buffer & output, uint8_t const * input, std::size_t size)
{
    return coding(output, input, size, DECODE_LEVEL);
}

Zip::ResultCode Zip::zip(std::string const & file, std::string const & dir)
{
    return ResultCode::FAILURE;
}

Zip::ResultCode Zip::unzip(std::string const & file, std::string const & dir)
{
    using Path = filesystem::Path;

    unzFile uf = unzOpen(file.c_str());
    if (uf == nullptr) {
        return ResultCode::OPEN_ERROR;
    }

    if (unzGoToFirstFile(uf) != UNZ_OK) {
        unzClose(uf);
        return ResultCode::GO_TO_FIRST_FILE_ERROR;
    }

    std::size_t const MAX_PATH    = 256;
    std::size_t const MAX_COMMENT = 256;

    char filename[MAX_PATH] = {0,};
    char  comment[MAX_COMMENT] = {0,};

    std::size_t const INPUT_BUFFER = 2048;
    Bytef in[INPUT_BUFFER] = {0,};

    unz_file_info info;

    do {
        unzGetCurrentFileInfo(uf, &info, filename, MAX_PATH, nullptr, 0, comment, MAX_COMMENT);

         //std::cout << "NAME("        << filename
         //          << ") COMP_SIZE(" << info.compressed_size
         //          << ") ORI_SIZE("  << info.uncompressed_size
         //          << ")\n";

        std::string const OUTPUT_NODE_PATH = dir + filesystem::details::PATH_SEPARATOR + filename;

        if (info.compressed_size == 0 && info.uncompressed_size == 0) {
            // Directory.
            //OUTPUT_NODE_PATH.createDirWithRecursive();
            libtbag::filesystem::details::createDirectory(OUTPUT_NODE_PATH);

        } else {
            // Regular file.

            if (unzOpenCurrentFile(uf) == UNZ_OK) {
                std::ofstream op(OUTPUT_NODE_PATH, std::ios_base::binary);
                int readsize = 0;

                do {
                    readsize = unzReadCurrentFile(uf, (void*)in, INPUT_BUFFER);
                    op.write((char const *) in, readsize);
                } while (readsize != 0);

                op.close();
            }

            unzCloseCurrentFile(uf);
        }
    } while (unzGoToNextFile(uf) == UNZ_OK);

    unzClose(uf);

    return ResultCode::SUCCESS;
}

} // namespace archive

// --------------------
NAMESPACE_LIBTBAG_CLOSE
// --------------------

<commit_msg>Trivial commit.<commit_after>/**
 * @file   Zip.cpp
 * @brief  Zip class implementation.
 * @author zer0
 * @date   2016-11-17
 */

#include <libtbag/archive/Zip.hpp>
#include <libtbag/filesystem/Path.hpp>
#include <libtbag/filesystem/details/FsCommon.hpp>

#include <cassert>
#include <cstring>

#include <fstream>
#include <iostream>

#include <zlib.h>
#include <zip.h>
#include <unzip.h>

// -------------------
NAMESPACE_LIBTBAG_OPEN
// -------------------

namespace archive {

Zip::Zip()
{
    // EMPTY.
}

Zip::~Zip()
{
    // EMPTY.
}

Zip::ResultCode Zip::coding(Buffer & output, uint8_t const * input, std::size_t size, int level)
{
    bool const ENCODE = (level != DECODE_LEVEL);

    z_stream stream = {0,};
    stream.zalloc   = Z_NULL;
    stream.zfree    = Z_NULL;
    stream.opaque   = Z_NULL;

    int result = Z_OK;
    if (ENCODE) {
        result = deflateInit(&stream, level);
    } else {
        result = inflateInit(&stream);
    }

    if (result != Z_OK) {
        return ResultCode::FAILURE;
    }

    std::size_t const BUFFER_SIZE = 2048; // TODO: CHANGE PAGE SIZE.

    Bytef  in[BUFFER_SIZE] = {0,};
    Bytef out[BUFFER_SIZE] = {0,};

    std::size_t read_index = 0;
    int flush = Z_NO_FLUSH;

    do {
        // Update input buffer.
        stream.next_in = in;
        if (size - read_index > BUFFER_SIZE) {
            stream.avail_in = BUFFER_SIZE;
            flush = Z_NO_FLUSH;
        } else {
            stream.avail_in = static_cast<uInt>(size - read_index);
            flush = Z_FINISH; // EOF.
        }

        memcpy(in, input + read_index, stream.avail_in);
        read_index += stream.avail_in;

        do {
            // Update output buffer.
            stream.avail_out = BUFFER_SIZE;
            stream.next_out  = out;

            if (ENCODE) {
                result = deflate(&stream, flush);
            } else {
                result = inflate(&stream, flush);
            }
            assert(result != Z_STREAM_ERROR);

            std::size_t dsize = BUFFER_SIZE - stream.avail_out;
            output.insert(output.end(), out, out + dsize);
        } while (stream.avail_out == 0);
        assert(stream.avail_in == 0);

    } while (flush != Z_FINISH);
    assert(result == Z_STREAM_END);

    if (ENCODE) {
        deflateEnd(&stream);
    } else {
        inflateEnd(&stream);
    }

    return ResultCode::SUCCESS;
}

Zip::ResultCode Zip::encode(Buffer & output, uint8_t const * input, std::size_t size, int level)
{
    if (level < MIN_ENCODE_LEVEL || level > MAX_ENCODE_LEVEL) {
        level = Z_DEFAULT_COMPRESSION;
    }
    return coding(output, input, size, level);
}

Zip::ResultCode Zip::decode(Buffer & output, uint8_t const * input, std::size_t size)
{
    return coding(output, input, size, DECODE_LEVEL);
}

Zip::ResultCode Zip::zip(std::string const & file, std::string const & dir)
{
    return ResultCode::FAILURE;
}

Zip::ResultCode Zip::unzip(std::string const & file, std::string const & dir)
{
    using Path = filesystem::Path;

    unzFile uf = unzOpen(file.c_str());
    if (uf == nullptr) {
        return ResultCode::OPEN_ERROR;
    }

    if (unzGoToFirstFile(uf) != UNZ_OK) {
        unzClose(uf);
        return ResultCode::GO_TO_FIRST_FILE_ERROR;
    }

    std::size_t const MAX_PATH_LENGTH = 256;
    std::size_t const MAX_COMMENT     = 256;

    char filename[MAX_PATH_LENGTH] = {0,};
    char  comment[MAX_COMMENT] = {0,};

    std::size_t const INPUT_BUFFER = 2048;
    Bytef in[INPUT_BUFFER] = {0,};

    unz_file_info info;

    do {
        unzGetCurrentFileInfo(uf, &info, filename, MAX_PATH_LENGTH, nullptr, 0, comment, MAX_COMMENT);

         //std::cout << "NAME("        << filename
         //          << ") COMP_SIZE(" << info.compressed_size
         //          << ") ORI_SIZE("  << info.uncompressed_size
         //          << ")\n";

        std::string const OUTPUT_NODE_PATH = dir + filesystem::details::PATH_SEPARATOR + filename;

        if (info.compressed_size == 0 && info.uncompressed_size == 0) {
            // Directory.
            //OUTPUT_NODE_PATH.createDirWithRecursive();
            libtbag::filesystem::details::createDirectory(OUTPUT_NODE_PATH);

        } else {
            // Regular file.

            if (unzOpenCurrentFile(uf) == UNZ_OK) {
                std::ofstream op(OUTPUT_NODE_PATH, std::ios_base::binary);
                int readsize = 0;

                do {
                    readsize = unzReadCurrentFile(uf, (void*)in, INPUT_BUFFER);
                    op.write((char const *) in, readsize);
                } while (readsize != 0);

                op.close();
            }

            unzCloseCurrentFile(uf);
        }
    } while (unzGoToNextFile(uf) == UNZ_OK);

    unzClose(uf);

    return ResultCode::SUCCESS;
}

} // namespace archive

// --------------------
NAMESPACE_LIBTBAG_CLOSE
// --------------------

<|endoftext|>