<commit_before>/*
 * Copyright 2014 Matthew Harvey
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "time_log.hpp"
#include "stint.hpp"
#include "string_utilities.hpp"
#include "time_point.hpp"
#include <algorithm>
#include <cassert>
#include <chrono>
#include <cstddef>
#include <cstring>
#include <ctime>
#include <fstream>
#include <iomanip>
#include <ios>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>
#include <utility>
#include <vector>

using std::cerr;
using std::endl;
using std::getline;
using std::ifstream;
using std::isspace;
using std::ios;
using std::move;
using std::ofstream;
using std::ostringstream;
using std::remove;
using std::runtime_error;
using std::size_t;
using std::string;
using std::stringstream;
using std::tm;
using std::upper_bound;
using std::vector;

namespace chrono = std::chrono;

namespace swx
{

TimeLog::TimeLog(string const& p_filepath):
	m_is_loaded(false),
	m_filepath(p_filepath)
{
	assert (m_entries.empty());
	assert (m_activities.empty());
	assert (m_activity_map.empty());
}

void
TimeLog::append_entry
(	string const& p_activity,
	TimePoint const& p_time_point
)
{
	// TODO Make this atomic?
	mark_cache_as_stale();
	ofstream outfile(m_filepath.c_str(), ios::app);
	outfile << time_point_to_stamp(p_time_point)
	        << ' ' << p_activity << endl;
	return;
}

vector<Stint>
TimeLog::get_stints
(	string const* p_activity,
	TimePoint const* p_begin,
	TimePoint const* p_end
)
{
	load();
	vector<Stint> ret;
	auto const e = m_entries.end();
	auto it = (p_begin? find_entry_just_before(*p_begin): m_entries.begin());
	auto const n = now();
	for ( ; (it != e) && (!p_end || (it->time_point < *p_end)); ++it)
	{
		auto const activity = id_to_activity(it->activity_id);
		if (!p_activity || (*p_activity == activity))
		{
			auto tp = it->time_point;
			if (p_begin && (tp < *p_begin)) tp = *p_begin;
			auto const next_it = it + 1;
			auto const done = (next_it == e);
			auto default_next_tp = (n > tp? n: tp);
			auto next_tp = (done? default_next_tp: next_it->time_point);
			if (p_end && (next_tp > *p_end)) next_tp = *p_end;
			assert (!p_begin || (tp >= *p_begin));
			assert (!p_begin || (next_tp >= *p_begin));
			assert (!p_end || (next_tp <= *p_end));
			assert (next_tp >= tp);
			auto const seconds = chrono::duration_cast<Seconds>(next_tp - tp);
			Interval const interval(tp, seconds, done);
			ret.push_back(Stint(activity, interval));
		}
	}
	return ret;
}

void
TimeLog::clear_cache()
{
	m_entries.clear();
	m_activities.clear();
	m_activity_map.clear();
	return;
}

void
TimeLog::mark_cache_as_stale()
{
	m_is_loaded = false;
}

void
TimeLog::load()
{
	if (!m_is_loaded)
	{
		clear_cache();
		ifstream infile(m_filepath.c_str());
		string line;
		size_t line_number = 1;
		while (getline(infile, line))
		{
			load_entry(line, line_number);
			++line_number;
		}
		m_is_loaded = true;
	}
	return;
}

TimeLog::ActivityId
TimeLog::register_activity(string const& p_activity)
{
	auto const it = m_activity_map.find(p_activity);
	if (it == m_activity_map.end())
	{
		// TODO Make this atomic?
		auto const ret = m_activities.size();
		m_activities.push_back(p_activity);
		m_activity_map[p_activity] = ret;
		return ret;
	}
	return it->second;
}

void
TimeLog::load_entry(string const& p_entry_string, size_t p_line_number)
{
	static string const time_format("YYYY-MM-DDTHH:MM:SS");
	if (p_entry_string.size() < time_format.size())
	{
		ostringstream oss;
		oss << "TimeLog parsing error at line "
		    << p_line_number << '.';
		throw runtime_error(oss.str());
	}
	auto it = p_entry_string.begin() + time_format.size();
	assert (it > p_entry_string.begin());
	string const time_stamp(p_entry_string.begin(), it);
	string const activity = trim(string(it, p_entry_string.end()));
	auto const activity_id = register_activity(activity);
	auto const time_point = time_stamp_to_point(time_stamp);
	Entry entry(activity_id, time_point);
	if (!m_entries.empty())
	{
		auto const last_time_point = m_entries.back().time_point;
		if (entry.time_point < last_time_point)
		{
			ostringstream oss;
			oss << "TimeLog entries out of order at line "
			    << p_line_number << '.';
			throw runtime_error(oss.str());
		}
	}
	m_entries.push_back(entry);
	return;
}

string
TimeLog::id_to_activity(ActivityId p_activity_id)
{
	load();
	return m_activities.at(p_activity_id);
}

vector<TimeLog::Entry>::const_iterator
TimeLog::find_entry_just_before(TimePoint const& p_time_point)
{
	load();
	typedef vector<TimeLog::Entry>::const_iterator Iter;
	auto const comp = [](Entry const& lhs, Entry const& rhs)
	{
		return lhs.time_point < rhs.time_point;
	};
	Iter const b = m_entries.begin();
	Iter const e = m_entries.end();
	Entry const dummy(0, p_time_point);
	Iter it = upper_bound(b, e, dummy, comp);
	while ((it != b) && (it == e) || (it->time_point > p_time_point))
	{
		--it;
	}
	return it;

}

TimeLog::Entry::Entry(ActivityId p_activity_id, TimePoint const& p_time_point):
	activity_id(p_activity_id),
	time_point(p_time_point)
{
}

}  // namespace swx
<commit_msg>Improved efficiency of TimeLog::get_stints().<commit_after>/*
 * Copyright 2014 Matthew Harvey
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "time_log.hpp"
#include "stint.hpp"
#include "string_utilities.hpp"
#include "time_point.hpp"
#include <algorithm>
#include <cassert>
#include <chrono>
#include <cstddef>
#include <cstring>
#include <ctime>
#include <fstream>
#include <iomanip>
#include <ios>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>
#include <utility>
#include <vector>

using std::cerr;
using std::endl;
using std::getline;
using std::ifstream;
using std::isspace;
using std::ios;
using std::move;
using std::ofstream;
using std::ostringstream;
using std::remove;
using std::runtime_error;
using std::size_t;
using std::string;
using std::stringstream;
using std::tm;
using std::upper_bound;
using std::vector;

namespace chrono = std::chrono;

namespace swx
{

TimeLog::TimeLog(string const& p_filepath):
	m_is_loaded(false),
	m_filepath(p_filepath)
{
	assert (m_entries.empty());
	assert (m_activities.empty());
	assert (m_activity_map.empty());
}

void
TimeLog::append_entry
(	string const& p_activity,
	TimePoint const& p_time_point
)
{
	// TODO Make this atomic?
	mark_cache_as_stale();
	ofstream outfile(m_filepath.c_str(), ios::app);
	outfile << time_point_to_stamp(p_time_point)
	        << ' ' << p_activity << endl;
	return;
}

vector<Stint>
TimeLog::get_stints
(	string const* p_activity,
	TimePoint const* p_begin,
	TimePoint const* p_end
)
{
	load();
	vector<Stint> ret;
	auto const e = m_entries.end();
	auto it = (p_begin? find_entry_just_before(*p_begin): m_entries.begin());
	auto const n = now();
	ActivityId const sought_activity_id =
		(p_activity? register_activity(*p_activity): 0);
	for ( ; (it != e) && (!p_end || (it->time_point < *p_end)); ++it)
	{
		ActivityId const current_activity_id = it->activity_id;
		if (!p_activity || (sought_activity_id == current_activity_id))
		{
			auto tp = it->time_point;
			if (p_begin && (tp < *p_begin)) tp = *p_begin;
			auto const next_it = it + 1;
			auto const done = (next_it == e);
			auto default_next_tp = (n > tp? n: tp);
			auto next_tp = (done? default_next_tp: next_it->time_point);
			if (p_end && (next_tp > *p_end)) next_tp = *p_end;
			assert (!p_begin || (tp >= *p_begin));
			assert (!p_begin || (next_tp >= *p_begin));
			assert (!p_end || (next_tp <= *p_end));
			assert (next_tp >= tp);
			auto const seconds = chrono::duration_cast<Seconds>(next_tp - tp);
			Interval const interval(tp, seconds, done);
			ret.push_back(Stint(id_to_activity(current_activity_id), interval));
		}
	}
	return ret;
}

void
TimeLog::clear_cache()
{
	m_entries.clear();
	m_activities.clear();
	m_activity_map.clear();
	return;
}

void
TimeLog::mark_cache_as_stale()
{
	m_is_loaded = false;
}

void
TimeLog::load()
{
	if (!m_is_loaded)
	{
		clear_cache();
		ifstream infile(m_filepath.c_str());
		string line;
		size_t line_number = 1;
		while (getline(infile, line))
		{
			load_entry(line, line_number);
			++line_number;
		}
		m_is_loaded = true;
	}
	return;
}

TimeLog::ActivityId
TimeLog::register_activity(string const& p_activity)
{
	auto const it = m_activity_map.find(p_activity);
	if (it == m_activity_map.end())
	{
		// TODO Make this atomic?
		auto const ret = m_activities.size();
		m_activities.push_back(p_activity);
		m_activity_map[p_activity] = ret;
		return ret;
	}
	return it->second;
}

void
TimeLog::load_entry(string const& p_entry_string, size_t p_line_number)
{
	static string const time_format("YYYY-MM-DDTHH:MM:SS");
	if (p_entry_string.size() < time_format.size())
	{
		ostringstream oss;
		oss << "TimeLog parsing error at line "
		    << p_line_number << '.';
		throw runtime_error(oss.str());
	}
	auto it = p_entry_string.begin() + time_format.size();
	assert (it > p_entry_string.begin());
	string const time_stamp(p_entry_string.begin(), it);
	string const activity = trim(string(it, p_entry_string.end()));
	auto const activity_id = register_activity(activity);
	auto const time_point = time_stamp_to_point(time_stamp);
	Entry entry(activity_id, time_point);
	if (!m_entries.empty())
	{
		auto const last_time_point = m_entries.back().time_point;
		if (entry.time_point < last_time_point)
		{
			ostringstream oss;
			oss << "TimeLog entries out of order at line "
			    << p_line_number << '.';
			throw runtime_error(oss.str());
		}
	}
	m_entries.push_back(entry);
	return;
}

string
TimeLog::id_to_activity(ActivityId p_activity_id)
{
	load();
	return m_activities.at(p_activity_id);
}

vector<TimeLog::Entry>::const_iterator
TimeLog::find_entry_just_before(TimePoint const& p_time_point)
{
	load();
	typedef vector<TimeLog::Entry>::const_iterator Iter;
	auto const comp = [](Entry const& lhs, Entry const& rhs)
	{
		return lhs.time_point < rhs.time_point;
	};
	Iter const b = m_entries.begin();
	Iter const e = m_entries.end();
	Entry const dummy(0, p_time_point);
	Iter it = upper_bound(b, e, dummy, comp);
	while ((it != b) && (it == e) || (it->time_point > p_time_point))
	{
		--it;
	}
	return it;

}

TimeLog::Entry::Entry(ActivityId p_activity_id, TimePoint const& p_time_point):
	activity_id(p_activity_id),
	time_point(p_time_point)
{
}

}  // namespace swx
<|endoftext|>


<commit_before>// Copyright (c) 2014-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "timedata.h"

#include "netbase.h"
#include "sync.h"
#include "ui_interface.h"
#include "util.h"
#include "utilstrencodings.h"

#include <boost/foreach.hpp>

using namespace std;

static CCriticalSection cs_nTimeOffset;
static int64_t nTimeOffset = 0;

/**
 * "Never go to sea with two chronometers; take one or three."
 * Our three time sources are:
 *  - System clock
 *  - Median of other nodes clocks
 *  - The user (asking the user to fix the system clock if the first two disagree)
 */
int64_t GetTimeOffset()
{
    LOCK(cs_nTimeOffset);
    return nTimeOffset;
}

int64_t GetAdjustedTime()
{
    return GetTime() + GetTimeOffset();
}

static int64_t abs64(int64_t n)
{
    return (n >= 0 ? n : -n);
}

void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample)
{
    LOCK(cs_nTimeOffset);
    // Ignore duplicates
    static set<CNetAddr> setKnown;
    if (!setKnown.insert(ip).second)
        return;

    // Add data
    static CMedianFilter<int64_t> vTimeOffsets(200,0);
    vTimeOffsets.input(nOffsetSample);
    LogPrintf("Added time data, samples %d, offset %+d (%+d minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample/60);

    // There is a known issue here (see issue #4521):
    //
    // - The structure vTimeOffsets contains up to 200 elements, after which
    // any new element added to it will not increase its size, replacing the
    // oldest element.
    //
    // - The condition to update nTimeOffset includes checking whether the
    // number of elements in vTimeOffsets is odd, which will never happen after
    // there are 200 elements.
    //
    // But in this case the 'bug' is protective against some attacks, and may
    // actually explain why we've never seen attacks which manipulate the
    // clock offset.
    //
    // So we should hold off on fixing this and clean it up as part of
    // a timing cleanup that strengthens it in a number of other ways.
    //
    if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1)
    {
        int64_t nMedian = vTimeOffsets.median();
        std::vector<int64_t> vSorted = vTimeOffsets.sorted();
        // Only let other nodes change our time by so much
        if (abs64(nMedian) < 70 * 60)
        {
            nTimeOffset = nMedian;
        }
        else
        {
            nTimeOffset = 0;

            static bool fDone;
            if (!fDone)
            {
                // If nobody has a time different than ours but within 5 minutes of ours, give a warning
                bool fMatch = false;
                BOOST_FOREACH(int64_t nOffset, vSorted)
                    if (nOffset != 0 && abs64(nOffset) < 5 * 60)
                        fMatch = true;

                if (!fMatch)
                {
                    fDone = true;
                    string strMessage = _("Warning: Please check that your computer's date and time are correct! If your clock is wrong Unobtanium Core will not work properly.");
                    strMiscWarning = strMessage;
                    LogPrintf("*** %s\n", strMessage);
                    uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_WARNING);
                }
            }
        }
        if (fDebug) {
            BOOST_FOREACH(int64_t n, vSorted)
                LogPrintf("%+d  ", n);
            LogPrintf("|  ");
        }
        LogPrintf("nTimeOffset = %+d  (%+d minutes)\n", nTimeOffset, nTimeOffset/60);
    }
}
<commit_msg>Do not store more than 200 timedata samples.<commit_after>// Copyright (c) 2014-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "timedata.h"

#include "netbase.h"
#include "sync.h"
#include "ui_interface.h"
#include "util.h"
#include "utilstrencodings.h"

#include <boost/foreach.hpp>

using namespace std;

static CCriticalSection cs_nTimeOffset;
static int64_t nTimeOffset = 0;

/**
 * "Never go to sea with two chronometers; take one or three."
 * Our three time sources are:
 *  - System clock
 *  - Median of other nodes clocks
 *  - The user (asking the user to fix the system clock if the first two disagree)
 */
int64_t GetTimeOffset()
{
    LOCK(cs_nTimeOffset);
    return nTimeOffset;
}

int64_t GetAdjustedTime()
{
    return GetTime() + GetTimeOffset();
}

static int64_t abs64(int64_t n)
{
    return (n >= 0 ? n : -n);
}

#define BITCOIN_TIMEDATA_MAX_SAMPLES 200

void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample)
{
    LOCK(cs_nTimeOffset);
    // Ignore duplicates
    static set<CNetAddr> setKnown;
    if (setKnown.size() == BITCOIN_TIMEDATA_MAX_SAMPLES)
        return;
    if (!setKnown.insert(ip).second)
        return;

    // Add data
    static CMedianFilter<int64_t> vTimeOffsets(BITCOIN_TIMEDATA_MAX_SAMPLES, 0);
    vTimeOffsets.input(nOffsetSample);
    LogPrintf("Added time data, samples %d, offset %+d (%+d minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample/60);

    // There is a known issue here (see issue #4521):
    //
    // - The structure vTimeOffsets contains up to 200 elements, after which
    // any new element added to it will not increase its size, replacing the
    // oldest element.
    //
    // - The condition to update nTimeOffset includes checking whether the
    // number of elements in vTimeOffsets is odd, which will never happen after
    // there are 200 elements.
    //
    // But in this case the 'bug' is protective against some attacks, and may
    // actually explain why we've never seen attacks which manipulate the
    // clock offset.
    //
    // So we should hold off on fixing this and clean it up as part of
    // a timing cleanup that strengthens it in a number of other ways.
    //
    if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1)
    {
        int64_t nMedian = vTimeOffsets.median();
        std::vector<int64_t> vSorted = vTimeOffsets.sorted();
        // Only let other nodes change our time by so much
        if (abs64(nMedian) < 70 * 60)
        {
            nTimeOffset = nMedian;
        }
        else
        {
            nTimeOffset = 0;

            static bool fDone;
            if (!fDone)
            {
                // If nobody has a time different than ours but within 5 minutes of ours, give a warning
                bool fMatch = false;
                BOOST_FOREACH(int64_t nOffset, vSorted)
                    if (nOffset != 0 && abs64(nOffset) < 5 * 60)
                        fMatch = true;

                if (!fMatch)
                {
                    fDone = true;
                    string strMessage = _("Warning: Please check that your computer's date and time are correct! If your clock is wrong Unobtanium Core will not work properly.");
                    strMiscWarning = strMessage;
                    LogPrintf("*** %s\n", strMessage);
                    uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_WARNING);
                }
            }
        }
        if (fDebug) {
            BOOST_FOREACH(int64_t n, vSorted)
                LogPrintf("%+d  ", n);
            LogPrintf("|  ");
        }
        LogPrintf("nTimeOffset = %+d  (%+d minutes)\n", nTimeOffset, nTimeOffset/60);
    }
}
<|endoftext|>


<commit_before>/***************************************************************************
 * Copyright (C) The Apache Software Foundation. All rights reserved.      *
 *                                                                         *
 * This software is published under the terms of the Apache Software       *
 * License version 1.1, a copy of which has been included with this        *
 * distribution in the license.apl file.                                   *
 ***************************************************************************/

#include <log4cxx/helpers/timezone.h>
#include <locale>

int getYear(int64_t date)
{
	time_t d = (time_t)(date / 1000);
	return ::localtime(&d)->tm_year;
}

using namespace log4cxx;
using namespace log4cxx::helpers;

IMPLEMENT_LOG4CXX_OBJECT(TimeZone)

TimeZonePtr TimeZone::defaultTimeZone = new TimeZone(_T(""));

TimeZone::TimeZone(const String& ID)
: ID(ID), rawOffset(0), DSTSavings(0)
{
	String timeZoneEnv = _T("TZ=") + ID;

	USES_CONVERSION;
	::putenv((char *)T2A(timeZoneEnv.c_str()));
	tzset();

	time_t now = time(0);
	tm localNow = *::localtime(&now);
	tm utcNow = *::gmtime(&now);
	rawOffset = (int)::difftime(::mktime(&localNow), ::mktime(&utcNow)) * 1000;

	int year = localNow.tm_year;
	Rule * rule = new Rule(year);

	// we check if we found a daylight time
	if (rule->startDate != 0 && rule->endDate != 0)
	{
		// since we have computed a rule, we store it
		rules.insert(RuleMap::value_type(year, rule));
		DSTSavings = 3600 * 1000; // 1 hour
	}
	else
	{
		delete rule;
	}
}

TimeZone::~TimeZone()
{
	for (RuleMap::iterator it = rules.begin(); it != rules.end(); it++)
	{
		Rule * rule = it->second;
		delete rule;
	}
}

int TimeZone::getOffset(int64_t date) const
{
	if (inDaylightTime(date))
	{
		return rawOffset + DSTSavings;
	}
	else
	{
		return rawOffset;
	}
}

TimeZonePtr TimeZone::getDefault()
{
	return defaultTimeZone;
}

TimeZonePtr TimeZone::getTimeZone(const String& ID)
{
	return new TimeZone(_T("ID"));
}

bool TimeZone::inDaylightTime(int64_t date) const
{
	if (!useDaylightTime())
	{
		return false;
	}

	time_t d = (time_t)(date / 1000);
	int year = ::localtime(&d)->tm_year;

	RuleMap::iterator it = rules.find(year);
	if (it == rules.end())
	{
		synchronized sync(this);

		it = rules.find(year);
		if (it == rules.end())
		{
			it = rules.insert(RuleMap::value_type(
				year, new Rule(year))).first;
		}
	}

	Rule * rule = it->second;
	return (date >= rule->startDate && date <= rule->endDate);
}

TimeZone::Rule::Rule(int year)
: startDate(0), endDate(0)
{
	tm tm;
	memset (&tm, 0, sizeof (tm));
	tm.tm_mday = 1;
	tm.tm_year = year;

	time_t t = ::mktime(&tm);
	int isDST, day, hour, min;

	for (day = 0; day < 365; day++)
	{
		t += 60 * 60 * 24;

		isDST = ::localtime(&t)->tm_isdst;
		if (startDate == 0)
		{
			if (isDST > 0)
			{
				t -= 60 * 60 * 24;

				for (hour = 0; hour < 24; hour++)
				{
					t += 60 * 60;

					isDST = ::localtime(&t)->tm_isdst;
					if (isDST > 0)
					{
						t -= 60 * 60;
						for (min = 0; min < 60; min++)
						{
							t += 60;
							isDST = ::localtime(&t)->tm_isdst;
							if (isDST > 0)
							{
								startDate = (int64_t)t * 1000;
								break;
							}
						}

						break;
					}
				}
			}
		}
		else if (isDST == 0)
		{
			t -= 60 * 60 * 24;

			for (hour = 0; hour < 24; hour++)
			{
				t += 60 * 60;

				isDST = ::localtime(&t)->tm_isdst;
				if (isDST == 0)
				{
					t -= 60 * 60;
					for (min = 0; min < 60; min++)
					{
						t += 60;
						isDST = ::localtime(&t)->tm_isdst;
						if (isDST == 0)
						{
							endDate = (int64_t)t * 1000;
							break;
						}
					}

					break;
				}
			}

			if (endDate != 0)
			{
				break;
			}
		}
	}
}

<commit_msg>fixed daylight management and timezone instanciation<commit_after>/***************************************************************************
 * Copyright (C) The Apache Software Foundation. All rights reserved.      *
 *                                                                         *
 * This software is published under the terms of the Apache Software       *
 * License version 1.1, a copy of which has been included with this        *
 * distribution in the license.apl file.                                   *
 ***************************************************************************/

#include <log4cxx/helpers/timezone.h>
#include <locale>

int getYear(int64_t date)
{
	time_t d = (time_t)(date / 1000);
	return ::localtime(&d)->tm_year;
}

using namespace log4cxx;
using namespace log4cxx::helpers;

IMPLEMENT_LOG4CXX_OBJECT(TimeZone)

TimeZonePtr TimeZone::defaultTimeZone = new TimeZone(_T(""));

TimeZone::TimeZone(const String& ID)
: ID(ID), rawOffset(0), DSTSavings(0)
{
	String timeZoneEnv = _T("TZ=") + ID;

	USES_CONVERSION;
	::putenv((char *)T2A(timeZoneEnv.c_str()));
	tzset();

	time_t now = time(0);
	tm localNow = *::localtime(&now);
	tm utcNow = *::gmtime(&now);
	rawOffset = (int)::difftime(::mktime(&localNow), ::mktime(&utcNow)) * 1000;

	int year = localNow.tm_year;
	Rule * rule = new Rule(year);

	// we check if we found a daylight time
	if (rule->startDate != 0 && rule->endDate != 0)
	{
		// since we have computed a rule, we store it
		rules.insert(RuleMap::value_type(year, rule));
		DSTSavings = 3600 * 1000; // 1 hour
	}
	else
	{
		delete rule;
	}
}

TimeZone::~TimeZone()
{
	for (RuleMap::iterator it = rules.begin(); it != rules.end(); it++)
	{
		Rule * rule = it->second;
		delete rule;
	}
}

int TimeZone::getOffset(int64_t date) const
{
	if (inDaylightTime(date))
	{
		return rawOffset + DSTSavings;
	}
	else
	{
		return rawOffset;
	}
}

TimeZonePtr TimeZone::getDefault()
{
	return defaultTimeZone;
}

TimeZonePtr TimeZone::getTimeZone(const String& ID)
{
	return new TimeZone(ID);
}

bool TimeZone::inDaylightTime(int64_t date) const
{
	if (!useDaylightTime())
	{
		return false;
	}

	time_t d = (time_t)(date / 1000);
	int year = ::localtime(&d)->tm_year;

	RuleMap::iterator it = rules.find(year);
	if (it == rules.end())
	{
		synchronized sync(this);

		it = rules.find(year);
		if (it == rules.end())
		{
			it = rules.insert(RuleMap::value_type(
				year, new Rule(year))).first;
		}
	}

	Rule * rule = it->second;
	return (date >= rule->startDate && date < rule->endDate);
}

TimeZone::Rule::Rule(int year)
: startDate(0), endDate(0)
{
	tm tm;
	memset (&tm, 0, sizeof (tm));
	tm.tm_mday = 1;
	tm.tm_year = year;

	time_t t = ::mktime(&tm);
	int isDST, day, hour, min;

	for (day = 0; day < 365; day++)
	{
		t += 60 * 60 * 24;

		isDST = ::localtime(&t)->tm_isdst;
		if (startDate == 0)
		{
			if (isDST > 0)
			{
				t -= 60 * 60 * 24;

				for (hour = 0; hour < 24; hour++)
				{
					t += 60 * 60;

					isDST = ::localtime(&t)->tm_isdst;
					if (isDST > 0)
					{
						t -= 60 * 60;
						for (min = 0; min < 60; min++)
						{
							t += 60;
							isDST = ::localtime(&t)->tm_isdst;
							if (isDST > 0)
							{
								startDate = (int64_t)t * 1000;
								break;
							}
						}

						break;
					}
				}
			}
		}
		else if (isDST == 0)
		{
			t -= 60 * 60 * 24;

			for (hour = 0; hour < 24; hour++)
			{
				t += 60 * 60;

				isDST = ::localtime(&t)->tm_isdst;
				if (isDST == 0)
				{
					t -= 60 * 60;
					for (min = 0; min < 60; min++)
					{
						t += 60;
						isDST = ::localtime(&t)->tm_isdst;
						if (isDST == 0)
						{
							endDate = (int64_t)t * 1000;
							break;
						}
					}

					break;
				}
			}

			if (endDate != 0)
			{
				break;
			}
		}
	}
}

<|endoftext|>


<commit_before>#line 2 "togo/app.cpp"
/**
@copyright MIT license; see @ref index or the accompanying LICENSE file.
*/

#include <togo/config.hpp>
#include <togo/app_type.hpp>
#include <togo/log.hpp>
#include <togo/system.hpp>
#include <togo/memory.hpp>
#include <togo/gfx/init.hpp>
#include <togo/gfx/display.hpp>
#include <togo/input_buffer.hpp>

namespace togo {

AppBase::~AppBase() {}

AppBase::AppBase(
	init_func_type func_init,
	shutdown_func_type func_shutdown,
	update_func_type func_update,
	render_func_type func_render,
	unsigned num_args,
	char const* args[],
	float update_freq
)
	: _func_init(func_init)
	, _func_shutdown(func_shutdown)
	, _func_update(func_update)
	, _func_render(func_render)
	, _num_args(num_args)
	, _args(args)
	, _display(nullptr)
	, _input_buffer(memory::default_allocator())
	, _task_manager(
		system::num_cores() - 1u,
		memory::default_allocator()
	)
	, _update_freq(update_freq)
	, _quit(false)
{}

namespace app {

void core_quit(AppBase& app_base);
void core_run(AppBase& app_base);

static void core_init(AppBase& app_base);
static void core_shutdown(AppBase& app_base);
static void core_update(AppBase& app_base, float dt);
static void core_render(AppBase& app_base);

static void core_init(AppBase& app_base) {
	TOGO_LOG("App: initializing\n");
	gfx::init(3, 2);
	gfx::Config config{};
	config.color_bits = {8, 8, 8, 0};
	config.depth_bits = 16;
	config.stencil_bits = 0;
	config.msaa_num_buffers = 0;
	config.msaa_num_samples = 0;
	config.flags = gfx::ConfigFlags::double_buffered;
	app_base._display = gfx::display::create(
		"togo display",
		1024, 768,
		gfx::DisplayFlags::borderless |
		gfx::DisplayFlags::resizable,
		config
	);
	input_buffer::add_display(app_base._input_buffer, app_base._display);
	gfx::display::set_mouse_lock(app_base._display, false);
	app_base._quit = false;
	app_base._func_init(app_base);
}

static void core_shutdown(AppBase& app_base) {
	TOGO_LOG("App: shutting down\n");
	app_base._func_shutdown(app_base);
	input_buffer::remove_display(app_base._input_buffer, app_base._display);
	gfx::display::destroy(app_base._display);
	gfx::shutdown();
}

static void core_update(AppBase& app_base, float dt) {
	InputEventType event_type{};
	InputEvent const* event = nullptr;
	while (input_buffer::poll(app_base._input_buffer, event_type, event)) {
		if (
			event_type == InputEventType::display_close_request &&
			event->display == app_base._display
		) {
			app::core_quit(app_base);
		}
	}
	app_base._func_update(app_base, dt);
}

static void core_render(AppBase& app_base) {
	app_base._func_render(app_base);
	gfx::display::swap_buffers(app_base._display);
}

void core_run(AppBase& app_base) {
	app::core_init(app_base);
	float const update_freq = app_base._update_freq;
	float time_prev = system::time_monotonic();
	float time_next;
	float time_delta;
	float time_accum = 0.0f;
	while (!app_base._quit) {
		time_next = system::time_monotonic();
		time_delta = time_next - time_prev;
		time_prev = time_next;
		time_accum += time_delta;
		while (time_accum >= update_freq) {
			time_accum -= update_freq;
			app::core_update(app_base, update_freq);
		}
		app::core_render(app_base);
		system::sleep_ms(1);
	}
	app::core_shutdown(app_base);
}

void core_quit(AppBase& app_base) {
	TOGO_LOG("App: quitting\n");
	app_base._quit = true;
}

} // namespace app
} // namespace togo
<commit_msg>app::run: update immediately and only render when an update occurs.<commit_after>#line 2 "togo/app.cpp"
/**
@copyright MIT license; see @ref index or the accompanying LICENSE file.
*/

#include <togo/config.hpp>
#include <togo/app_type.hpp>
#include <togo/log.hpp>
#include <togo/system.hpp>
#include <togo/memory.hpp>
#include <togo/gfx/init.hpp>
#include <togo/gfx/display.hpp>
#include <togo/input_buffer.hpp>

namespace togo {

AppBase::~AppBase() {}

AppBase::AppBase(
	init_func_type func_init,
	shutdown_func_type func_shutdown,
	update_func_type func_update,
	render_func_type func_render,
	unsigned num_args,
	char const* args[],
	float update_freq
)
	: _func_init(func_init)
	, _func_shutdown(func_shutdown)
	, _func_update(func_update)
	, _func_render(func_render)
	, _num_args(num_args)
	, _args(args)
	, _display(nullptr)
	, _input_buffer(memory::default_allocator())
	, _task_manager(
		system::num_cores() - 1u,
		memory::default_allocator()
	)
	, _update_freq(update_freq)
	, _quit(false)
{}

namespace app {

void core_quit(AppBase& app_base);
void core_run(AppBase& app_base);

static void core_init(AppBase& app_base);
static void core_shutdown(AppBase& app_base);
static void core_update(AppBase& app_base, float dt);
static void core_render(AppBase& app_base);

static void core_init(AppBase& app_base) {
	TOGO_LOG("App: initializing\n");
	gfx::init(3, 2);
	gfx::Config config{};
	config.color_bits = {8, 8, 8, 0};
	config.depth_bits = 16;
	config.stencil_bits = 0;
	config.msaa_num_buffers = 0;
	config.msaa_num_samples = 0;
	config.flags = gfx::ConfigFlags::double_buffered;
	app_base._display = gfx::display::create(
		"togo display",
		1024, 768,
		gfx::DisplayFlags::borderless |
		gfx::DisplayFlags::resizable,
		config
	);
	input_buffer::add_display(app_base._input_buffer, app_base._display);
	gfx::display::set_mouse_lock(app_base._display, false);
	app_base._quit = false;
	app_base._func_init(app_base);
}

static void core_shutdown(AppBase& app_base) {
	TOGO_LOG("App: shutting down\n");
	app_base._func_shutdown(app_base);
	input_buffer::remove_display(app_base._input_buffer, app_base._display);
	gfx::display::destroy(app_base._display);
	gfx::shutdown();
}

static void core_update(AppBase& app_base, float dt) {
	InputEventType event_type{};
	InputEvent const* event = nullptr;
	while (input_buffer::poll(app_base._input_buffer, event_type, event)) {
		if (
			event_type == InputEventType::display_close_request &&
			event->display == app_base._display
		) {
			app::core_quit(app_base);
		}
	}
	app_base._func_update(app_base, dt);
}

static void core_render(AppBase& app_base) {
	app_base._func_render(app_base);
	gfx::display::swap_buffers(app_base._display);
}

void core_run(AppBase& app_base) {
	app::core_init(app_base);
	float const update_freq = app_base._update_freq;
	float time_prev = system::time_monotonic();
	float time_next;
	float time_delta;
	float time_accum = update_freq;
	bool do_render = false;
	while (!app_base._quit) {
		time_next = system::time_monotonic();
		time_delta = time_next - time_prev;
		time_prev = time_next;
		time_accum += time_delta;
		do_render = time_accum >= update_freq;
		while (time_accum >= update_freq) {
			time_accum -= update_freq;
			app::core_update(app_base, update_freq);
		}
		if (do_render) {
			app::core_render(app_base);
		}
		system::sleep_ms(1);
	}
	app::core_shutdown(app_base);
}

void core_quit(AppBase& app_base) {
	TOGO_LOG("App: quitting\n");
	app_base._quit = true;
}

} // namespace app
} // namespace togo
<|endoftext|>


<commit_before>/*
Highly Optimized Object-oriented Many-particle Dynamics -- Blue Edition
(HOOMD-blue) Open Source Software License Copyright 2009-2015 The Regents of
the University of Michigan All rights reserved.

HOOMD-blue may contain modifications ("Contributions") provided, and to which
copyright is held, by various Contributors who have granted The Regents of the
University of Michigan the right to modify and/or distribute such Contributions.

You may redistribute, use, and create derivate works of HOOMD-blue, in source
and binary forms, provided you abide by the following conditions:

* Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer both in the code and
prominently in any materials provided with the distribution.

* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions, and the following disclaimer in the documentation and/or
other materials provided with the distribution.

* All publications and presentations based on HOOMD-blue, including any reports
or published results obtained, in whole or in part, with HOOMD-blue, will
acknowledge its use according to the terms posted at the time of submission on:
http://codeblue.umich.edu/hoomd-blue/citations.html

* Any electronic documents citing HOOMD-Blue will link to the HOOMD-Blue website:
http://codeblue.umich.edu/hoomd-blue/

* Apart from the above required attributions, neither the name of the copyright
holder nor the names of HOOMD-blue's contributors may be used to endorse or
promote products derived from this software without specific prior written
permission.

Disclaimer

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND/OR ANY
WARRANTIES THAT THIS SOFTWARE IS FREE OF INFRINGEMENT ARE DISCLAIMED.

IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

// Maintainer: csadorf,samnola

/*! \file CallbackAnalyzer.cc
    \brief Defines the CallbackAnalyzer class
*/

#include "CallbackAnalyzer.h"
#include "HOOMDInitializer.h"

#ifdef ENABLE_MPI
#include "Communicator.h"
#endif

#include <boost/python.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/convenience.hpp>
using namespace boost::python;
using namespace boost::filesystem;

#include <iomanip>
using namespace std;

/*! \param sysdef SystemDefinition containing the Particle data to analyze
    \param fname File name to write output to
    \param header_prefix String to print before the file header
    \param overwrite Will overwite an exiting file if true (default is to append)

    analyze()
*/
CallbackAnalyzer::CallbackAnalyzer(boost::shared_ptr<SystemDefinition> sysdef,
                         boost::python::object callback)
    : Analyzer(sysdef), callback(callback)
    {
    m_exec_conf->msg->notice(5) << "Constructing CallbackAnalyzer" << endl;
    }

CallbackAnalyzer::~CallbackAnalyzer()
    {
    m_exec_conf->msg->notice(5) << "Destroying CallbackAnalyzer" << endl;
    }

/*!\param timestep Current time step of the simulation

    analyze() will call the callback
*/
void CallbackAnalyzer::analyze(unsigned int timestep)
    {
      callback(timestep);
    }

void export_CallbackAnalyzer()
    {
    class_<CallbackAnalyzer, boost::shared_ptr<CallbackAnalyzer>, bases<Analyzer>, boost::noncopyable>
    ("CallbackAnalyzer", init< boost::shared_ptr<SystemDefinition>, boost::python::object>())
    ;
    }
<commit_msg>Fixed doxygen documentation.<commit_after>/*
Highly Optimized Object-oriented Many-particle Dynamics -- Blue Edition
(HOOMD-blue) Open Source Software License Copyright 2009-2015 The Regents of
the University of Michigan All rights reserved.

HOOMD-blue may contain modifications ("Contributions") provided, and to which
copyright is held, by various Contributors who have granted The Regents of the
University of Michigan the right to modify and/or distribute such Contributions.

You may redistribute, use, and create derivate works of HOOMD-blue, in source
and binary forms, provided you abide by the following conditions:

* Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer both in the code and
prominently in any materials provided with the distribution.

* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions, and the following disclaimer in the documentation and/or
other materials provided with the distribution.

* All publications and presentations based on HOOMD-blue, including any reports
or published results obtained, in whole or in part, with HOOMD-blue, will
acknowledge its use according to the terms posted at the time of submission on:
http://codeblue.umich.edu/hoomd-blue/citations.html

* Any electronic documents citing HOOMD-Blue will link to the HOOMD-Blue website:
http://codeblue.umich.edu/hoomd-blue/

* Apart from the above required attributions, neither the name of the copyright
holder nor the names of HOOMD-blue's contributors may be used to endorse or
promote products derived from this software without specific prior written
permission.

Disclaimer

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND/OR ANY
WARRANTIES THAT THIS SOFTWARE IS FREE OF INFRINGEMENT ARE DISCLAIMED.

IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

// Maintainer: csadorf,samnola

/*! \file CallbackAnalyzer.cc
    \brief Defines the CallbackAnalyzer class
*/

#include "CallbackAnalyzer.h"
#include "HOOMDInitializer.h"

#ifdef ENABLE_MPI
#include "Communicator.h"
#endif

#include <boost/python.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/convenience.hpp>
using namespace boost::python;
using namespace boost::filesystem;

#include <iomanip>
using namespace std;

/*! \param sysdef SystemDefinition containing the Particle data to analyze
    \param callback A python functor object to be used as callback
*/
CallbackAnalyzer::CallbackAnalyzer(boost::shared_ptr<SystemDefinition> sysdef,
                         boost::python::object callback)
    : Analyzer(sysdef), callback(callback)
    {
    m_exec_conf->msg->notice(5) << "Constructing CallbackAnalyzer" << endl;
    }

CallbackAnalyzer::~CallbackAnalyzer()
    {
    m_exec_conf->msg->notice(5) << "Destroying CallbackAnalyzer" << endl;
    }

/*!\param timestep Current time step of the simulation

    analyze() will call the callback
*/
void CallbackAnalyzer::analyze(unsigned int timestep)
    {
      callback(timestep);
    }

void export_CallbackAnalyzer()
    {
    class_<CallbackAnalyzer, boost::shared_ptr<CallbackAnalyzer>, bases<Analyzer>, boost::noncopyable>
    ("CallbackAnalyzer", init< boost::shared_ptr<SystemDefinition>, boost::python::object>())
    ;
    }
<|endoftext|>


<commit_before>#include "mbed.h"
#include "test_env.h"

class DevNull : public Stream {

public:
    DevNull(const char *name = NULL) : Stream(name) {}

protected:
    virtual int _getc()      {return 0;}
    virtual int _putc(int c) {return c;}
};

DevNull null("null");

int main() {
    printf("MBED: re-routing stdout to /null\n");
    freopen("/null", "w", stdout);
    printf("MBED: printf redirected to /null\n");   // This shouldn't appear
    // If failure message can be seen test should fail :)
    notify_completion(false);   // This is 'false' on purpose
    return 0;
}
<commit_msg>Indented using AStyle<commit_after>#include "mbed.h"
#include "test_env.h"

class DevNull : public Stream
{
public:
    DevNull(const char *name = NULL) : Stream(name) {}

protected:
    virtual int _getc() {
        return 0;
    }
    virtual int _putc(int c) {
        return c;
    }
};

DevNull null("null");

int main()
{
    printf("MBED: re-routing stdout to /null\n");
    freopen("/null", "w", stdout);
    printf("MBED: printf redirected to /null\n");   // This shouldn't appear
    // If failure message can be seen test should fail :)
    notify_completion(false);   // This is 'false' on purpose
    return 0;
}
<|endoftext|>


<commit_before>AliGenerator *AddMCGenAmpt(
			   Double_t Energy      = 2760.,   // CM energy
			   Double_t bmin        = 0.0,     // minimum impact parameter
			   Double_t bmax        = 20.0,    // maximum impact parameter
			   Bool_t stringMelting = kTRUE,   // string melting option
			   Bool_t useART        = kTRUE,   // use hadronic rescattering phase (ART)
			   )
{
  // User defined generator

  gSystem->Load("libampt.so");
  gSystem->Load("libTAmpt.so");

  AliGenAmpt *genAMPT = new AliGenAmpt(-1);
  //=========================================================================

  // User settings
  Int_t Flag_SM    = 4;       // flag for string melting: 1 = default, 4 = String Melting
  Int_t NTmax      = 150;     // NTMAX: number of timesteps (Default = 150), to turn off ART set it to 3
  Double_t mu      = 3.2264;  // parton screening mass in fm^(-1) (Default = 3.2264)
  Double_t alpha_s = 1./3.;   // change mu and alpha_s (Default = 1./3.) to vary scattering cross-section
                              // mu = 3.2 fm^-1 and alpha_s = 0.33 ==> sigma_{partonic} = 1.5mb
  if(!stringMelting)
    Flag_SM = 1;

  if(!useART)
    NTmax = 3;
  //=========================================================================

  // Decayer
  AliDecayer *decayer = new AliDecayerPythia();
  genAMPT->SetForceDecay( kHadronicD );
  genAMPT->SetDecayer( decayer );
  //=========================================================================

  // Collision system
  genAMPT->SetEnergyCMS(Energy);
  genAMPT->SetReferenceFrame("CMS");
  genAMPT->SetProjectile("A", 208, 82);
  genAMPT->SetTarget    ("A", 208, 82);
  genAMPT->SetPtHardMin (2);
  genAMPT->SetImpactParameterRange(0.00,20.00);
  //=========================================================================

  // options
  genAMPT->SetJetQuenching(0);     // enable jet quenching
  genAMPT->SetShadowing(1);        // enable shadowing
  genAMPT->SetDecaysOff(1);        // neutral pion and heavy particle decays switched off
  genAMPT->SetSpectators(0);       // track spectators
  genAMPT->SetIsoft(Flag_SM);      // 4=string melting, 1=standard AMPT
  genAMPT->SetXmu(mu);             // parton xsection
  genAMPT->SetNtMax(NTmax);        // time bins
  genAMPT->SetAlpha(alpha_s);      // alpha =0.333
  genAMPT->SetStringFrag(0.5,0.9); // string fragmentation parameters
  genAMPT->SetIpop(1);             // enable popcorn mechanism (net-baryon stopping)
  //=========================================================================

  // Boost into LHC lab frame
  genAMPT->SetBoostLHC(1);

  // randomize reaction plane
  genAMPT->SetRandomReactionPlane(kTRUE);

 return genAMPT;

}
<commit_msg>Small fix: - adding impact parameter range as optional<commit_after>AliGenerator *AddMCGenAmpt(
			   Double_t Energy      = 2760.,   // CM energy
			   Double_t bmin        = 0.0,     // minimum impact parameter
			   Double_t bmax        = 20.0,    // maximum impact parameter
			   Bool_t stringMelting = kTRUE,   // string melting option
			   Bool_t useART        = kTRUE,   // use hadronic rescattering phase (ART)
			   )
{
  // User defined generator

  gSystem->Load("libampt.so");
  gSystem->Load("libTAmpt.so");

  AliGenAmpt *genAMPT = new AliGenAmpt(-1);
  //=========================================================================

  // User settings
  Int_t Flag_SM    = 4;       // flag for string melting: 1 = default, 4 = String Melting
  Int_t NTmax      = 150;     // NTMAX: number of timesteps (Default = 150), to turn off ART set it to 3
  Double_t mu      = 3.2264;  // parton screening mass in fm^(-1) (Default = 3.2264)
  Double_t alpha_s = 1./3.;   // change mu and alpha_s (Default = 1./3.) to vary scattering cross-section
                              // mu = 3.2 fm^-1 and alpha_s = 0.33 ==> sigma_{partonic} = 1.5mb
  if(!stringMelting)
    Flag_SM = 1;

  if(!useART)
    NTmax = 3;
  //=========================================================================

  // Decayer
  AliDecayer *decayer = new AliDecayerPythia();
  genAMPT->SetForceDecay( kHadronicD );
  genAMPT->SetDecayer( decayer );
  //=========================================================================

  // Collision system
  genAMPT->SetEnergyCMS(Energy);
  genAMPT->SetReferenceFrame("CMS");
  genAMPT->SetProjectile("A", 208, 82);
  genAMPT->SetTarget    ("A", 208, 82);
  genAMPT->SetPtHardMin (2);
  genAMPT->SetImpactParameterRange(bmin,bmax);
  //=========================================================================

  // options
  genAMPT->SetJetQuenching(0);     // enable jet quenching
  genAMPT->SetShadowing(1);        // enable shadowing
  genAMPT->SetDecaysOff(1);        // neutral pion and heavy particle decays switched off
  genAMPT->SetSpectators(0);       // track spectators
  genAMPT->SetIsoft(Flag_SM);      // 4=string melting, 1=standard AMPT
  genAMPT->SetXmu(mu);             // parton xsection
  genAMPT->SetNtMax(NTmax);        // time bins
  genAMPT->SetAlpha(alpha_s);      // alpha =0.333
  genAMPT->SetStringFrag(0.5,0.9); // string fragmentation parameters
  genAMPT->SetIpop(1);             // enable popcorn mechanism (net-baryon stopping)
  //=========================================================================

  // Boost into LHC lab frame
  genAMPT->SetBoostLHC(1);

  // randomize reaction plane
  genAMPT->SetRandomReactionPlane(kTRUE);

 return genAMPT;

}
<|endoftext|>


<commit_before>#include <cmath>
#include <fstream>
#include <map>
#include <sstream>
#include <stdexcept>

#include "cvrp.h"
#include "tsplib_format.h"

namespace VrpSolver {

    unsigned int Cvrp::demand(unsigned int node_id) const {
        if ((1 > node_id) || (node_id > dimension_))
            throw std::out_of_range("error: in Cvrp::demand");
        return demands_[node_id];
    }

    int Cvrp::distance(unsigned int from, unsigned int to) const {
        if ((1 > from) || (from > dimension_) ||
            (1 > to) || (to > dimension_))
            throw std::out_of_range("error: in Cvrp::distance");

        const int index = (to > from) ? ((to-2)*(to-1)/2+(from-1)) :
                                        ((from-2)*(from-1)/2+(to-1));
        return distances_[index];
    }

    // 文字列strからtrim_char文字列に含まれている文字を削除
    void trim(std::string& str, const std::string& trim_char) {
        size_t pos;
        while ((pos = str.find_first_of(trim_char)) != std::string::npos)
            str.erase(pos, 1);
    }

    // セミコロン以後の文字列(空白の直前まで)を読み取る
    std::string get_parameter(std::ifstream& ifs) {
        std::string param;
        ifs >> param;
        while (param == ":") ifs >> param; // ":"は読み飛ばす
        return param;
    }

    enum TsplibKeyword {
        NAME, TYPE, COMMENT, DIMENSION, CAPACITY,
        EDGE_WEIGHT_TYPE, EDGE_WEIGHT_FORMAT, EDGE_DATA_FORMAT,
        NODE_COORD_TYPE, DISPLAY_DATA_TYPE,
        NODE_COORD_SECTION, DEPOT_SECTION, DEMAND_SECTION,
        EDGE_DATA_SECTION, EDGE_WEIGHT_SECTION,
        END_OF_FILE
    };

    std::map<std::string, TsplibKeyword> keyword_map = {
        // The specification part
        { "NAME",                NAME },
        { "TYPE",                TYPE },
        { "COMMENT",             COMMENT },
        { "DIMENSION",           DIMENSION },
        { "CAPACITY",            CAPACITY },
        { "EDGE_WEIGHT_TYPE",    EDGE_WEIGHT_TYPE },
        { "EDGE_WEIGHT_FORMAT",  EDGE_WEIGHT_FORMAT },
        { "EDGE_DATA_FORMAT",    EDGE_DATA_FORMAT },
        { "NODE_COORD_TYPE",     NODE_COORD_TYPE },
        { "DISPLAY_DATA_TYPE",   DISPLAY_DATA_TYPE },
        { "EOF",                 END_OF_FILE },

        // The data part
        { "NODE_COORD_SECTION",  NODE_COORD_SECTION },
        { "DEPOT_SECTION",       DEPOT_SECTION },
        { "DEMAND_SECTION",      DEMAND_SECTION },
        { "EDGE_DATA_SECTION",   EDGE_DATA_SECTION },
        { "EDGE_WEIGHT_SECTION", EDGE_WEIGHT_SECTION }
    };

    // infileから情報を読み取りCvrpクラスをセットアップする
    void read_vrp(Cvrp& cvrp, const std::string &infile) {
        std::ifstream ifs(infile.c_str());
        if (!ifs)
            throw std::runtime_error("error: can't open file " + infile);

        std::string edge_weight_type,
                    edge_weight_format,
                    display_data_type;

        while (ifs) {
            std::string tsp_keyword;
            ifs >> tsp_keyword;
            if (ifs.eof()) break;
            trim(tsp_keyword, " :");
            switch (keyword_map[tsp_keyword]) {

                // The specification part
                case NAME :
                    cvrp.name_ = get_parameter(ifs);
                    break;
                case TYPE :
                    {
                        std::string not_use;
                        getline(ifs, not_use);
                    }
                    break;
                case COMMENT :
                    {
                        std::string not_use;
                        getline(ifs, not_use);
                    }
                    break;
                case DIMENSION :
                    cvrp.dimension_ = stoi(get_parameter(ifs));
                    break;
                case CAPACITY :
                    cvrp.capacity_ = stoi(get_parameter(ifs));
                    break;
                case EDGE_WEIGHT_TYPE :
                    edge_weight_type = get_parameter(ifs);
                    break;
                case EDGE_WEIGHT_FORMAT :
                    edge_weight_format = get_parameter(ifs);
                    break;
                case EDGE_DATA_FORMAT :
                    {
                        std::string not_use;
                        getline(ifs, not_use);
                    }
                    break;
                case NODE_COORD_TYPE :
                    {
                        std::string not_use;
                        getline(ifs, not_use);
                    }
                    break;
                case DISPLAY_DATA_TYPE :
                    display_data_type = get_parameter(ifs);
                    break;
                case END_OF_FILE :
                    // do nothing
                    break;

                // The data part
                case NODE_COORD_SECTION :
                    {
                        int n=0, m, x, y; // m do not use
                        for (int i=0; i != cvrp.dimension_; i++) {
                            ifs >> m >> x >> y;
                            std::pair<int,int> c(x,y);
                            cvrp.coords_.push_back(c);
                        }
                    }
                    break;
                case DEPOT_SECTION :
                    {
                        cvrp.depot_ = stoi(get_parameter(ifs));
                        if (stoi(get_parameter(ifs)) != -1)
                            throw std::runtime_error("error:"
                                    "can't handle multiple depots");
                    }
                    break;
                case DEMAND_SECTION :
                    {
                        cvrp.demands_.push_back(0); // 0要素目は0にしておく
                        for (int i=1; i <= cvrp.dimension_; i++) {
                            unsigned int node_id, demand;
                            ifs >> node_id >> demand;
                            if (node_id != i)
                                throw std::runtime_error("error:"
                                        "DEMAND_SECTION format may be different");
                            cvrp.demands_.push_back(demand);
                        }
                    }
                    break;
                case EDGE_DATA_SECTION :
                    throw std::runtime_error("Sorry, can not handle 'EDGE_DATA_SECTION'");
                    break;
                case EDGE_WEIGHT_SECTION :
                    {
                        if (edge_weight_format != "LOWER_ROW")
                            throw std::runtime_error("Sorry, can not handle except EDGE_WEIGHT_FORMAT == LOWER_ROW");
                        for (int i=0; i < cvrp.dimension_; i++) {
                            for (int j=0; j < i; j++) {
                                int distance;
                                ifs >> distance;
                                cvrp.distances_.push_back(distance);
                            }
                        }
                    }
                    break;

                default :
                    throw std::runtime_error("error: unknown keyword '" + tsp_keyword + "'");
                    break;
            }
        }

        // distancesの設定
        if (edge_weight_type != Tsplib::EdgeWeightType::EXPLICIT) {
            auto& distances = cvrp.distances_;
            auto& coords    = cvrp.coords_;
            for (int i=0; i < cvrp.dimension_; i++) {
                for (int j=0; j < i; j++) {
                    int dx = coords[j].first  - coords[i].first;
                    int dy = coords[j].second - coords[i].second;
                    distances.push_back(floor(sqrt(dx*dx + dy*dy)+0.5));
                }
            }
        }
    }

} // namespace VrpSolver
<commit_msg>if文中のリテラル文字列をenumで置き換えた<commit_after>#include <cmath>
#include <fstream>
#include <map>
#include <sstream>
#include <stdexcept>

#include "cvrp.h"
#include "tsplib_format.h"

namespace VrpSolver {

    unsigned int Cvrp::demand(unsigned int node_id) const {
        if ((1 > node_id) || (node_id > dimension_))
            throw std::out_of_range("error: in Cvrp::demand");
        return demands_[node_id];
    }

    int Cvrp::distance(unsigned int from, unsigned int to) const {
        if ((1 > from) || (from > dimension_) ||
            (1 > to) || (to > dimension_))
            throw std::out_of_range("error: in Cvrp::distance");

        const int index = (to > from) ? ((to-2)*(to-1)/2+(from-1)) :
                                        ((from-2)*(from-1)/2+(to-1));
        return distances_[index];
    }

    // 文字列strからtrim_char文字列に含まれている文字を削除
    void trim(std::string& str, const std::string& trim_char) {
        size_t pos;
        while ((pos = str.find_first_of(trim_char)) != std::string::npos)
            str.erase(pos, 1);
    }

    // セミコロン以後の文字列(空白の直前まで)を読み取る
    std::string get_parameter(std::ifstream& ifs) {
        std::string param;
        ifs >> param;
        while (param == ":") ifs >> param; // ":"は読み飛ばす
        return param;
    }

    enum TsplibKeyword {
        NAME, TYPE, COMMENT, DIMENSION, CAPACITY,
        EDGE_WEIGHT_TYPE, EDGE_WEIGHT_FORMAT, EDGE_DATA_FORMAT,
        NODE_COORD_TYPE, DISPLAY_DATA_TYPE,
        NODE_COORD_SECTION, DEPOT_SECTION, DEMAND_SECTION,
        EDGE_DATA_SECTION, EDGE_WEIGHT_SECTION,
        END_OF_FILE
    };

    std::map<std::string, TsplibKeyword> keyword_map = {
        // The specification part
        { "NAME",                NAME },
        { "TYPE",                TYPE },
        { "COMMENT",             COMMENT },
        { "DIMENSION",           DIMENSION },
        { "CAPACITY",            CAPACITY },
        { "EDGE_WEIGHT_TYPE",    EDGE_WEIGHT_TYPE },
        { "EDGE_WEIGHT_FORMAT",  EDGE_WEIGHT_FORMAT },
        { "EDGE_DATA_FORMAT",    EDGE_DATA_FORMAT },
        { "NODE_COORD_TYPE",     NODE_COORD_TYPE },
        { "DISPLAY_DATA_TYPE",   DISPLAY_DATA_TYPE },
        { "EOF",                 END_OF_FILE },

        // The data part
        { "NODE_COORD_SECTION",  NODE_COORD_SECTION },
        { "DEPOT_SECTION",       DEPOT_SECTION },
        { "DEMAND_SECTION",      DEMAND_SECTION },
        { "EDGE_DATA_SECTION",   EDGE_DATA_SECTION },
        { "EDGE_WEIGHT_SECTION", EDGE_WEIGHT_SECTION }
    };

    enum EdgeWeightType {
        EXPLICIT, EUC_2D
    };

    std::map<std::string, EdgeWeightType> ew_type_map = {
        { "EXPLICIT", EXPLICIT },
        { "EUC_2D",   EUC_2D }
    };

    enum EdgeWeightFormat {
        LOWER_ROW
    };

    std::map<std::string, EdgeWeightFormat> ew_format_map = {
        { "LOWER_ROW", LOWER_ROW }
    };

    // infileから情報を読み取りCvrpクラスをセットアップする
    void read_vrp(Cvrp& cvrp, const std::string &infile) {
        std::ifstream ifs(infile.c_str());
        if (!ifs)
            throw std::runtime_error("error: can't open file " + infile);

        std::string      display_data_type;
        EdgeWeightType   edge_weight_type;
        EdgeWeightFormat edge_weight_format;

        while (ifs) {
            std::string tsp_keyword;
            ifs >> tsp_keyword;
            if (ifs.eof()) break;
            trim(tsp_keyword, " :");
            switch (keyword_map[tsp_keyword]) {

                // The specification part
                case NAME :
                    cvrp.name_ = get_parameter(ifs);
                    break;
                case TYPE :
                    {
                        std::string not_use;
                        getline(ifs, not_use);
                    }
                    break;
                case COMMENT :
                    {
                        std::string not_use;
                        getline(ifs, not_use);
                    }
                    break;
                case DIMENSION :
                    cvrp.dimension_ = stoi(get_parameter(ifs));
                    break;
                case CAPACITY :
                    cvrp.capacity_ = stoi(get_parameter(ifs));
                    break;
                case EDGE_WEIGHT_TYPE :
                    edge_weight_type = ew_type_map[get_parameter(ifs)];
                    break;
                case EDGE_WEIGHT_FORMAT :
                    edge_weight_format = ew_format_map[get_parameter(ifs)];
                    break;
                case EDGE_DATA_FORMAT :
                    {
                        std::string not_use;
                        getline(ifs, not_use);
                    }
                    break;
                case NODE_COORD_TYPE :
                    {
                        std::string not_use;
                        getline(ifs, not_use);
                    }
                    break;
                case DISPLAY_DATA_TYPE :
                    display_data_type = get_parameter(ifs);
                    break;
                case END_OF_FILE :
                    // do nothing
                    break;

                // The data part
                case NODE_COORD_SECTION :
                    {
                        int n=0, m, x, y; // m do not use
                        for (int i=0; i != cvrp.dimension_; i++) {
                            ifs >> m >> x >> y;
                            std::pair<int,int> c(x,y);
                            cvrp.coords_.push_back(c);
                        }
                    }
                    break;
                case DEPOT_SECTION :
                    {
                        cvrp.depot_ = stoi(get_parameter(ifs));
                        if (stoi(get_parameter(ifs)) != -1)
                            throw std::runtime_error("error:"
                                    "can't handle multiple depots");
                    }
                    break;
                case DEMAND_SECTION :
                    {
                        cvrp.demands_.push_back(0); // 0要素目は0にしておく
                        for (int i=1; i <= cvrp.dimension_; i++) {
                            unsigned int node_id, demand;
                            ifs >> node_id >> demand;
                            if (node_id != i)
                                throw std::runtime_error("error:"
                                        "DEMAND_SECTION format may be different");
                            cvrp.demands_.push_back(demand);
                        }
                    }
                    break;
                case EDGE_DATA_SECTION :
                    throw std::runtime_error("Sorry, can not handle 'EDGE_DATA_SECTION'");
                    break;
                case EDGE_WEIGHT_SECTION :
                    {
                        if (edge_weight_format != LOWER_ROW)
                            throw std::runtime_error("Sorry, can not handle except EDGE_WEIGHT_FORMAT == LOWER_ROW");
                        for (int i=0; i < cvrp.dimension_; i++) {
                            for (int j=0; j < i; j++) {
                                int distance;
                                ifs >> distance;
                                cvrp.distances_.push_back(distance);
                            }
                        }
                    }
                    break;

                default :
                    throw std::runtime_error("error: unknown keyword '" + tsp_keyword + "'");
                    break;
            }
        }

        // distancesの設定
        if (edge_weight_type != EXPLICIT) {
            auto& distances = cvrp.distances_;
            auto& coords    = cvrp.coords_;
            for (int i=0; i < cvrp.dimension_; i++) {
                for (int j=0; j < i; j++) {
                    int dx = coords[j].first  - coords[i].first;
                    int dy = coords[j].second - coords[i].second;
                    distances.push_back(floor(sqrt(dx*dx + dy*dy)+0.5));
                }
            }
        }
    }

} // namespace VrpSolver
<|endoftext|>


<commit_before><commit_msg>INTEGRATION: CWS vgbugs07 (1.47.70); FILE MERGED 2007/06/04 13:34:37 vg 1.47.70.1: #i76605# Remove -I .../inc/module hack introduced by hedaburemove01<commit_after><|endoftext|>


<commit_before><commit_msg>INTEGRATION: CWS toolbars2 (1.64.4); FILE MERGED 2004/08/30 09:26:19 mav 1.64.4.1: #i26282# replace all filter variable<commit_after><|endoftext|>


<commit_before><commit_msg>dAllocDontReport() system<commit_after><|endoftext|>


<commit_before>#include <gtest/gtest.h>

int main(int Fargc, char **argv)
{
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}
<commit_msg>Fix typo<commit_after>#include <gtest/gtest.h>

int main(int argc, char **argv)
{
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>
<commit_msg>Delete nada.cpp<commit_after><|endoftext|>


<commit_before>#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <cstring>
#include <string>
#include <vector>
#include <iomanip>
#include <cmath>
#include <list>
#include <bitset>

using namespace std;

#define ll long long
#define lson l,mid,id<<1
#define rson mid+1,r,id<<1|1

typedef pair<int, int>pii;
typedef pair<ll, ll>pll;
typedef pair<double, double>pdd;

const double eps = 1e-6;
const ll  LINF = 0x3f3f3f3f3f3f3f3fLL;
const int INF = 0x3f3f3f3f;
const double FINF = 1e18;

#define x first
#define y second

#define REP(i,j,k) for(int i =(j);i<=(k);i++)
#define REPD(i,j,k) for(int i =(j);i>=(k);i--)
#define print(x) cout<<(x)<<endl;
#define IOS ios::sync_with_stdio(0);cin.tie(0);

int len;
char str[50];
void Init(){

	cin>>len;
	scanf("%s",str);
	sort(str,str+len);
	return ;
}

void Solve(){
	int c=0;
	do{
		printf("%d %s",c++,str);
	}while(next_permutation(str,str+len));

	return ;
}

int main(){

	freopen("uoj17086.in","r",stdin);

	Init(),Solve();
	return 0;
}<commit_msg>update uoj17086<commit_after>#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <cstring>
#include <string>
#include <vector>
#include <iomanip>
#include <cmath>
#include <list>
#include <bitset>

using namespace std;

#define ll long long
#define lson l,mid,id<<1
#define rson mid+1,r,id<<1|1

typedef pair<int, int>pii;
typedef pair<ll, ll>pll;
typedef pair<double, double>pdd;

const double eps = 1e-6;
const ll  LINF = 0x3f3f3f3f3f3f3f3fLL;
const int INF = 0x3f3f3f3f;
const double FINF = 1e18;

#define x first
#define y second

#define REP(i,j,k) for(int i =(j);i<=(k);i++)
#define REPD(i,j,k) for(int i =(j);i>=(k);i--)
#define print(x) cout<<(x)<<endl;
#define IOS ios::sync_with_stdio(0);cin.tie(0);

int len;
char str[50];
void Init(){

	cin>>len;
	scanf("%s",str);
	sort(str,str+len);
	return ;
}

void Solve(){
	int c=0;
	do{
		printf("%d %s",c++,str);

	}while(next_permutation(str,str+len));

	return ;
}

int main(){

	freopen("uoj17086.in","r",stdin);

	Init(),Solve();
	return 0;
}<|endoftext|>


<commit_before>/***********************************************************************
 util.cpp - Utility functions required by several of the example
 	programs.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ 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 MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "util.h"

#include <iostream>
#include <iomanip>
#include <stdlib.h>

using namespace std;

const char* kpcSampleDatabase = "mysql_cpp_data";

//// utf8_to_win32_ansi ////////////////////////////////////////////////
// Converts a Unicode string encoded in UTF-8 form (which the MySQL
// database uses) to Win32's ANSI character encoding using the current
// code page.  A small modification to this function will turn it into
// a UTF-8 to UCS-2 function, since that's an intermediate form within
// this function.  The Unicode chapter in the user manual explains why
// that double conversion is necessary.

#ifdef MYSQLPP_PLATFORM_WINDOWS
static bool
utf8_to_win32_ansi(const char* utf8_str, char* ansi_str,
		int ansi_len)
{
	wchar_t ucs2_buf[100];
	static const int ub_chars = sizeof(ucs2_buf) / sizeof(ucs2_buf[0]);

	int err = MultiByteToWideChar(CP_UTF8, 0, utf8_str, -1,
			ucs2_buf, ub_chars);
	if (err == 0) {
		cerr << "Unknown error in Unicode translation: " <<
				GetLastError() << endl;
		return false;
	}
	else if (err == ERROR_NO_UNICODE_TRANSLATION) {
		cerr << "Bad data in UTF-8 string" << endl;
		return false;
	}
	else {
		CPINFOEX cpi;
		GetCPInfoEx(CP_OEMCP, 0, &cpi);
		WideCharToMultiByte(cpi.CodePage, 0, ucs2_buf, -1,
				ansi_str, ansi_len, 0, 0);
		cout << ':' << ansi_str[0] << ':' << endl;
		return true;
	}
}
#endif

//// print_stock_header ////////////////////////////////////////////////
// Display a header suitable for use with print_stock_rows().

void
print_stock_header(int rows)
{
	cout << "Records found: " << rows << endl << endl;
	cout.setf(ios::left);
	cout << setw(21) << "Item" <<
			setw(10) << "Num" <<
			setw(10) << "Weight" <<
			setw(10) << "Price" <<
			"Date" << endl << endl;
}

//// print_stock_row ///////////////////////////////////////////////////
// Print out a row of data from the stock table, in a format compatible
// with the header printed out in the previous function.

void
print_stock_row(const std::string& item, mysqlpp::longlong num,
		double weight, double price, const mysqlpp::Date& date)
{
	// Output item field.  We treat it separately because there is
	// Unicode data in this field in the sample database.
#ifdef MYSQLPP_PLATFORM_WINDOWS
	// We're running on Windows, so convert the first column from UTF-8
	// to UCS-2, and then to the local ANSI code page.  The user manual
	// explains why this double conversion is required.
	char item_ansi[100];
	if (utf8_to_win32_ansi(item.c_str(), item_ansi, sizeof(item_ansi))) {
		cout << setw(20) << item_ansi << ' ';
	}
#else
	// Just send string to console.  On modern Unices, the terminal code
	// interprets UTF-8 directly, so no special handling is required.
	cout << setw(20) << item << ' ';
#endif

	// Output remaining columns
	cout << setw(9) << num << ' ' <<
			setw(9) << weight << ' ' <<
			setw(9) << price << ' ' <<
			date << endl;
}

//// print_stock_row ///////////////////////////////////////////////////
// Take a Row from the example 'stock' table, break it up into fields,
// and call the above version of this function.

void
print_stock_row(const mysqlpp::Row& row)
{
	// Notice that only the string conversion has to be handled
	// specially.  (See Row::operator[]'s documentation for the reason.)
	// As for the rest of the fields, Row::operator[] returns a ColData
	// object, which can convert itself to any standard C type.
	//
	// We index the row by field name to demonstrate the feature, and
	// also because it makes the code more robust in the face of schema
	// changes.  Use Row::at() instead if efficiency is paramount.  To
	// maintain efficiency while keeping robustness, use the SSQLS
	// feature, demoed in the custom* examples.
	string item(row["item"]);
	print_stock_row(item, row["num"], row["weight"], row["price"],
			row["sdate"]);
}

//// print_stock_rows //////////////////////////////////////////////////
// Print out a number of rows from the example 'stock' table.

void
print_stock_rows(mysqlpp::Result& res)
{
	print_stock_header(res.size());

	// Use the Result class's read-only random access iterator to walk
	// through the query results.
	mysqlpp::Result::iterator i;
	for (i = res.begin(); i != res.end(); ++i) {
		// Notice that a dereferenced result iterator can be converted
		// to a Row object, which makes for easier element access.
		print_stock_row(*i);
	}
}

//// get_stock_table ///////////////////////////////////////////////////
// Retreive the entire contents of the example 'stock' table.

void
get_stock_table(mysqlpp::Query& query, mysqlpp::Result& res)
{
	// Reset the query object, in case we're re-using it.
	query.reset();

	// You can write to the query object like you would any ostream.
	query << "select * from stock";

	// Show the query string.  If you call preview(), it must be before
	// you call execute() or store() or use().
	cout << "Query: " << query.preview() << endl;

	// Execute the query, storing the results in memory.
	res = query.store();
}

//// connect_to_db /////////////////////////////////////////////////////
// Establishes a connection to a MySQL database server, optionally
// attaching to database kdb.  This is basically a command-line parser
// for the examples, since the example programs' arguments give us the
// information we need to establish the server connection.

bool
connect_to_db(int argc, char *argv[], mysqlpp::Connection& con,
		const char *kdb)
{
	if (argc < 1) {
		cerr << "Bad argument count: " << argc << '!' << endl;
		return false;
	}

	if (!kdb) {
		kdb = kpcSampleDatabase;
	}

	if ((argc > 1) && (argv[1][0] == '-')) {
		cout << "usage: " << argv[0] <<
				" [host] [user] [password] [port]" << endl;
		cout << endl << "\tConnects to database ";
		if (strlen(kdb) > 0) {
			cout << '"' << kdb << '"';
		}
		else {
			cout << "server";
		}
		cout << " on localhost using your user" << endl;
		cout << "\tname and no password by default." << endl << endl;
		return false;
	}

	if (argc == 1) {
		con.connect(kdb);
	}
	else if (argc == 2) {
		con.connect(kdb, argv[1]);
	}
	else if (argc == 3) {
		con.connect(kdb, argv[1], argv[2]);
	}
	else if (argc == 4) {
		con.connect(kdb, argv[1], argv[2], argv[3]);
	}
	else if (argc >= 5) {
		con.connect(kdb, argv[1], argv[2], argv[3], atoi(argv[4]));
	}

	if (con) {
		return true;
	}
	else {
		cerr << "Database connection failed: " << con.error() << endl;
		return false;
	}
}
<commit_msg>utf8_to_win32_ansi() in util module was printing first char of line between colons before returning converted string for some strange reason.  It was probably debug code that made it into the checkin... goes to show how popular the VC++ port is, I guess....<commit_after>/***********************************************************************
 util.cpp - Utility functions required by several of the example
 	programs.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ 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 MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "util.h"

#include <iostream>
#include <iomanip>
#include <stdlib.h>

using namespace std;

const char* kpcSampleDatabase = "mysql_cpp_data";

//// utf8_to_win32_ansi ////////////////////////////////////////////////
// Converts a Unicode string encoded in UTF-8 form (which the MySQL
// database uses) to Win32's ANSI character encoding using the current
// code page.  A small modification to this function will turn it into
// a UTF-8 to UCS-2 function, since that's an intermediate form within
// this function.  The Unicode chapter in the user manual explains why
// that double conversion is necessary.

#ifdef MYSQLPP_PLATFORM_WINDOWS
static bool
utf8_to_win32_ansi(const char* utf8_str, char* ansi_str,
		int ansi_len)
{
	wchar_t ucs2_buf[100];
	static const int ub_chars = sizeof(ucs2_buf) / sizeof(ucs2_buf[0]);

	int err = MultiByteToWideChar(CP_UTF8, 0, utf8_str, -1,
			ucs2_buf, ub_chars);
	if (err == 0) {
		cerr << "Unknown error in Unicode translation: " <<
				GetLastError() << endl;
		return false;
	}
	else if (err == ERROR_NO_UNICODE_TRANSLATION) {
		cerr << "Bad data in UTF-8 string" << endl;
		return false;
	}
	else {
		CPINFOEX cpi;
		GetCPInfoEx(CP_OEMCP, 0, &cpi);
		WideCharToMultiByte(cpi.CodePage, 0, ucs2_buf, -1,
				ansi_str, ansi_len, 0, 0);
		return true;
	}
}
#endif

//// print_stock_header ////////////////////////////////////////////////
// Display a header suitable for use with print_stock_rows().

void
print_stock_header(int rows)
{
	cout << "Records found: " << rows << endl << endl;
	cout.setf(ios::left);
	cout << setw(21) << "Item" <<
			setw(10) << "Num" <<
			setw(10) << "Weight" <<
			setw(10) << "Price" <<
			"Date" << endl << endl;
}

//// print_stock_row ///////////////////////////////////////////////////
// Print out a row of data from the stock table, in a format compatible
// with the header printed out in the previous function.

void
print_stock_row(const std::string& item, mysqlpp::longlong num,
		double weight, double price, const mysqlpp::Date& date)
{
	// Output item field.  We treat it separately because there is
	// Unicode data in this field in the sample database.
#ifdef MYSQLPP_PLATFORM_WINDOWS
	// We're running on Windows, so convert the first column from UTF-8
	// to UCS-2, and then to the local ANSI code page.  The user manual
	// explains why this double conversion is required.
	char item_ansi[100];
	if (utf8_to_win32_ansi(item.c_str(), item_ansi, sizeof(item_ansi))) {
		cout << setw(20) << item_ansi << ' ';
	}
#else
	// Just send string to console.  On modern Unices, the terminal code
	// interprets UTF-8 directly, so no special handling is required.
	cout << setw(20) << item << ' ';
#endif

	// Output remaining columns
	cout << setw(9) << num << ' ' <<
			setw(9) << weight << ' ' <<
			setw(9) << price << ' ' <<
			date << endl;
}

//// print_stock_row ///////////////////////////////////////////////////
// Take a Row from the example 'stock' table, break it up into fields,
// and call the above version of this function.

void
print_stock_row(const mysqlpp::Row& row)
{
	// Notice that only the string conversion has to be handled
	// specially.  (See Row::operator[]'s documentation for the reason.)
	// As for the rest of the fields, Row::operator[] returns a ColData
	// object, which can convert itself to any standard C type.
	//
	// We index the row by field name to demonstrate the feature, and
	// also because it makes the code more robust in the face of schema
	// changes.  Use Row::at() instead if efficiency is paramount.  To
	// maintain efficiency while keeping robustness, use the SSQLS
	// feature, demoed in the custom* examples.
	string item(row["item"]);
	print_stock_row(item, row["num"], row["weight"], row["price"],
			row["sdate"]);
}

//// print_stock_rows //////////////////////////////////////////////////
// Print out a number of rows from the example 'stock' table.

void
print_stock_rows(mysqlpp::Result& res)
{
	print_stock_header(res.size());

	// Use the Result class's read-only random access iterator to walk
	// through the query results.
	mysqlpp::Result::iterator i;
	for (i = res.begin(); i != res.end(); ++i) {
		// Notice that a dereferenced result iterator can be converted
		// to a Row object, which makes for easier element access.
		print_stock_row(*i);
	}
}

//// get_stock_table ///////////////////////////////////////////////////
// Retreive the entire contents of the example 'stock' table.

void
get_stock_table(mysqlpp::Query& query, mysqlpp::Result& res)
{
	// Reset the query object, in case we're re-using it.
	query.reset();

	// You can write to the query object like you would any ostream.
	query << "select * from stock";

	// Show the query string.  If you call preview(), it must be before
	// you call execute() or store() or use().
	cout << "Query: " << query.preview() << endl;

	// Execute the query, storing the results in memory.
	res = query.store();
}

//// connect_to_db /////////////////////////////////////////////////////
// Establishes a connection to a MySQL database server, optionally
// attaching to database kdb.  This is basically a command-line parser
// for the examples, since the example programs' arguments give us the
// information we need to establish the server connection.

bool
connect_to_db(int argc, char *argv[], mysqlpp::Connection& con,
		const char *kdb)
{
	if (argc < 1) {
		cerr << "Bad argument count: " << argc << '!' << endl;
		return false;
	}

	if (!kdb) {
		kdb = kpcSampleDatabase;
	}

	if ((argc > 1) && (argv[1][0] == '-')) {
		cout << "usage: " << argv[0] <<
				" [host] [user] [password] [port]" << endl;
		cout << endl << "\tConnects to database ";
		if (strlen(kdb) > 0) {
			cout << '"' << kdb << '"';
		}
		else {
			cout << "server";
		}
		cout << " on localhost using your user" << endl;
		cout << "\tname and no password by default." << endl << endl;
		return false;
	}

	if (argc == 1) {
		con.connect(kdb);
	}
	else if (argc == 2) {
		con.connect(kdb, argv[1]);
	}
	else if (argc == 3) {
		con.connect(kdb, argv[1], argv[2]);
	}
	else if (argc == 4) {
		con.connect(kdb, argv[1], argv[2], argv[3]);
	}
	else if (argc >= 5) {
		con.connect(kdb, argv[1], argv[2], argv[3], atoi(argv[4]));
	}

	if (con) {
		return true;
	}
	else {
		cerr << "Database connection failed: " << con.error() << endl;
		return false;
	}
}
<|endoftext|>


<commit_before>/*****************************************************************************
 * Exception.h++
 *****************************************************************************
 * Base class for all exceptions thrown by me, DAC.
 *****************************************************************************/

// Include guard.
#if !defined(EXCEPTION_tubu848xo9i)
  #define EXCEPTION_tubu848xo9i

// STL includes
  #include <exception>
  #include <string>
  #include <iostream>

// System includes.
  #include <demangle.h++>

// Namespace wrapper.
namespace DAC {

  /***************************************************************************
   * Exception
   ***************************************************************************
   * Base class for all exceptions thrown.
   ***************************************************************************/
  class Exception : public std::exception {

    /*
     * Public members.
     */
    public:

      /***********************************************************************/
      // Function members.

      // Constructor.
      Exception () throw();

      // Destructor.
      virtual ~Exception () throw();

      // Get the cause of this error.
      virtual char const* what () const throw();

      // Get the type of this error.
      std::string type () const throw();

      // Reset to just-constructed state.
      virtual Exception& clear () throw();

  };

/*****************************************************************************
 * Operators.
 *****************************************************************************/
}

// Stream output operator.
std::ostream& operator << (std::ostream& left, DAC::Exception const& right);

namespace DAC {

  /***************************************************************************
  * Inline and template definitions.
  ****************************************************************************/

  /***************************************************************************/
  // Function members.

  inline Exception::Exception () throw() { clear(); }

  inline Exception::~Exception () throw() { /* Nothing. */ }

  inline char const* Exception::what () const throw() { return "Undefined error."; }

  inline std::string Exception::type() const throw() { return demangle(*this); }

  inline Exception& Exception::clear() throw() { return *this; }

}

// Stream output operator.
inline std::ostream& operator << (std::ostream& left, DAC::Exception const& right) { left << right.what(); return left; }

// End include guard.
#endif
<commit_msg>About to try something dangerous.<commit_after>/*****************************************************************************
 * Exception.h++
 *****************************************************************************
 * Base class for all exceptions thrown by me, DAC.
 *****************************************************************************/

// Include guard.
#if !defined(EXCEPTION_tubu848xo9i)
  #define EXCEPTION_tubu848xo9i

// STL includes
  #include <exception>
  #include <string>
  #include <iostream>

// System includes.
  #include <demangle.h++>

// Namespace wrapper.
namespace DAC {

  /***************************************************************************
   * Exception
   ***************************************************************************
   * Base class for all exceptions thrown.
   ***************************************************************************/
  class Exception : public std::exception {

    /*
     * Public members.
     */
    public:

      /***********************************************************************/
      // Function members.

      // Constructor.
      Exception () throw();

      // Destructor.
      virtual ~Exception () throw();

      // Get the cause of this error.
      virtual char const* what () const throw();

      // Get the type of this error.
      std::string type () const throw();

      // Reset to just-constructed state.
      virtual Exception& clear () throw();

      // Buffer a temporary string.
      char const* buffer_message (std::string const& message);

    /*
     * Private members.
     */
    private:

      /***********************************************************************/
      // Data members.

      // Buffer for constructed error messages.
      std::string _buffer;

  };

/*****************************************************************************
 * Operators.
 *****************************************************************************/
}

// Stream output operator.
std::ostream& operator << (std::ostream& left, DAC::Exception const& right);

namespace DAC {

  /***************************************************************************
  * Inline and template definitions.
  ****************************************************************************/

  /***************************************************************************/
  // Function members.

  inline Exception::Exception () throw() { clear(); }

  inline Exception::~Exception () throw() { /* Nothing. */ }

  inline char const* Exception::what () const throw() { return "Undefined error."; }

  inline std::string Exception::type() const throw() { return demangle(*this); }

  inline Exception& Exception::clear() throw() { return *this; }

  /*
   * Buffer a temporary string.
   */
  inline char const* buffer_message (std::string const& message) {

    // Swap the contents of the message with the buffer.
    _buffer.swap(message);

    // Return a pointer to the char array.
    return _buffer.c_str();

  }

}

// Stream output operator.
inline std::ostream& operator << (std::ostream& left, DAC::Exception const& right) { left << right.what(); return left; }

// End include guard.
#endif
<|endoftext|>