<commit_before>#include "PickItemAbility.h"
//#include <Animation/AnimationComponent.h>
//#include <Animation/AnimationController.h>
#include <Game/Interaction/AbilityInstance.h>
#include <Game/Interaction/Zone.h>
#include <Game/ECS/GameWorld.h>
#include <Physics/RigidBodyComponent.h>
#include <Character/StatsComponent.h>
//#include <Character/SkillsComponent.h>
#include <Items/ItemStackComponent.h>
#include <Scene/SceneComponent.h>
#include <Items/ItemUtils.h>
//#include <Objects/OwnedComponent.h>
//#include <Math/Math.h>

namespace DEM::RPG
{

CPickItemAbility::CPickItemAbility(std::string_view CursorImage)
{
	_Name = "PickItem";
	_CursorImage = CursorImage;
}
//---------------------------------------------------------------------

bool CPickItemAbility::IsAvailable(const Game::CGameSession& Session, const Game::CInteractionContext& Context) const
{
	auto pWorld = Session.FindFeature<Game::CGameWorld>();
	if (!pWorld) return false;

	// Need at least one capable actor with enough inventory space
	// TODO: check space!
	for (auto ActorID : Context.Actors)
		if (auto pStats = pWorld->FindComponent<Sh2::CStatsComponent>(ActorID))
			if (pStats->Capabilities & Sh2::ECapability::Interact) return true;

	return false;
}
//---------------------------------------------------------------------

bool CPickItemAbility::IsTargetValid(const Game::CGameSession& Session, U32 Index, const Game::CInteractionContext& Context) const
{
	// Ability accepts only one target
	if (Index != 0) return false;

	// Check for the item stack component
	const auto& Target = (Index == Context.Targets.size()) ? Context.CandidateTarget : Context.Targets[Index];
	if (!Target.Valid) return false;
	auto pWorld = Session.FindFeature<Game::CGameWorld>();
	return pWorld && pWorld->FindComponent<CItemStackComponent>(Target.Entity);
}
//---------------------------------------------------------------------

ESoftBool CPickItemAbility::NeedMoreTargets(const Game::CInteractionContext& Context) const
{
	return (Context.Targets.size() < 1) ? ESoftBool::True : ESoftBool::False;
}
//---------------------------------------------------------------------

bool CPickItemAbility::Execute(Game::CGameSession& Session, Game::CInteractionContext& Context, bool Enqueue, bool PushChild) const
{
	if (Context.Targets.empty() || !Context.Targets[0].Entity || Context.Actors.empty()) return false;

	Game::HEntity ActorID = Context.Actors[0];
	// TODO: choose the first actor with enough inventory space? Or no need?
	//if (Context.Actors.size() > 1)
	//{
	//}

	// Push standard action for the first actor only
	auto pWorld = Session.FindFeature<Game::CGameWorld>();
	return pWorld && PushStandardExecuteAction(*pWorld, ActorID, Context, Enqueue, PushChild);
}
//---------------------------------------------------------------------

bool CPickItemAbility::GetZones(const Game::CGameSession& Session, const Game::CAbilityInstance& Instance, std::vector<const Game::CZone*>& Out) const
{
	// If smart object provided zones, don't add a default one
	if (!Out.empty()) return true;

	//!!!FIXME: need some way to add zones! Store per-ability? May need unique zones. Use strong refs, not raw pointers?
	static Game::CZone Zone(vector3::Zero, 1.f);
	Out.push_back(&Zone);
	return true;
}
//---------------------------------------------------------------------

bool CPickItemAbility::GetFacingParams(const Game::CGameSession& Session, const Game::CAbilityInstance& Instance, Game::CFacingParams& Out) const
{
	// Simply face an object origin
	//???make this logic default???
	Out.Mode = Game::EFacingMode::Point;
	Out.Dir = vector3::Zero;
	Out.Tolerance = 1.5f;
	return true;
}
//---------------------------------------------------------------------

void CPickItemAbility::OnStart(Game::CGameSession& Session, Game::CAbilityInstance& Instance) const
{
}
//---------------------------------------------------------------------

Game::EActionStatus CPickItemAbility::OnUpdate(Game::CGameSession& Session, Game::CAbilityInstance& Instance) const
{
	return Game::EActionStatus::Succeeded;
}
//---------------------------------------------------------------------

void CPickItemAbility::OnEnd(Game::CGameSession& Session, Game::CAbilityInstance& Instance, Game::EActionStatus Status) const
{
	if (Status != Game::EActionStatus::Succeeded) return;

	auto pWorld = Session.FindFeature<Game::CGameWorld>();
	if (!pWorld) return;

	// TODO: if owned by another faction, create crime stimulus/signal based on Steal skill check,
	// it may even interrupt item picking (in OnStart()?)

	// TODO: check character inventory free weight and volume
	// TODO: merge with existing stack if possible
	// TODO: equip if a) default equipping makes sense, like for weapons b) inventory is full but equipment slot isn't
	// NB: equipped things ignore volume limitations, but not weight

	AddItemsIntoContainer(*pWorld, Instance.Actor, Instance.Targets[0].Entity);
}
//---------------------------------------------------------------------

}
<commit_msg>Old TODO removed<commit_after>#include "PickItemAbility.h"
//#include <Animation/AnimationComponent.h>
//#include <Animation/AnimationController.h>
#include <Game/Interaction/AbilityInstance.h>
#include <Game/Interaction/Zone.h>
#include <Game/ECS/GameWorld.h>
#include <Physics/RigidBodyComponent.h>
#include <Character/StatsComponent.h>
//#include <Character/SkillsComponent.h>
#include <Items/ItemStackComponent.h>
#include <Scene/SceneComponent.h>
#include <Items/ItemUtils.h>
//#include <Objects/OwnedComponent.h>
//#include <Math/Math.h>

namespace DEM::RPG
{

CPickItemAbility::CPickItemAbility(std::string_view CursorImage)
{
	_Name = "PickItem";
	_CursorImage = CursorImage;
}
//---------------------------------------------------------------------

bool CPickItemAbility::IsAvailable(const Game::CGameSession& Session, const Game::CInteractionContext& Context) const
{
	auto pWorld = Session.FindFeature<Game::CGameWorld>();
	if (!pWorld) return false;

	// Need at least one capable actor with enough inventory space
	// TODO: check space!
	for (auto ActorID : Context.Actors)
		if (auto pStats = pWorld->FindComponent<Sh2::CStatsComponent>(ActorID))
			if (pStats->Capabilities & Sh2::ECapability::Interact) return true;

	return false;
}
//---------------------------------------------------------------------

bool CPickItemAbility::IsTargetValid(const Game::CGameSession& Session, U32 Index, const Game::CInteractionContext& Context) const
{
	// Ability accepts only one target
	if (Index != 0) return false;

	// Check for the item stack component
	const auto& Target = (Index == Context.Targets.size()) ? Context.CandidateTarget : Context.Targets[Index];
	if (!Target.Valid) return false;
	auto pWorld = Session.FindFeature<Game::CGameWorld>();
	return pWorld && pWorld->FindComponent<CItemStackComponent>(Target.Entity);
}
//---------------------------------------------------------------------

ESoftBool CPickItemAbility::NeedMoreTargets(const Game::CInteractionContext& Context) const
{
	return (Context.Targets.size() < 1) ? ESoftBool::True : ESoftBool::False;
}
//---------------------------------------------------------------------

bool CPickItemAbility::Execute(Game::CGameSession& Session, Game::CInteractionContext& Context, bool Enqueue, bool PushChild) const
{
	if (Context.Targets.empty() || !Context.Targets[0].Entity || Context.Actors.empty()) return false;

	Game::HEntity ActorID = Context.Actors[0];
	// TODO: choose the first actor with enough inventory space? Or no need?
	//if (Context.Actors.size() > 1)
	//{
	//}

	// Push standard action for the first actor only
	auto pWorld = Session.FindFeature<Game::CGameWorld>();
	return pWorld && PushStandardExecuteAction(*pWorld, ActorID, Context, Enqueue, PushChild);
}
//---------------------------------------------------------------------

bool CPickItemAbility::GetZones(const Game::CGameSession& Session, const Game::CAbilityInstance& Instance, std::vector<const Game::CZone*>& Out) const
{
	// If smart object provided zones, don't add a default one
	if (!Out.empty()) return true;

	//!!!FIXME: need some way to add zones! Store per-ability? May need unique zones. Use strong refs, not raw pointers?
	static Game::CZone Zone(vector3::Zero, 1.f);
	Out.push_back(&Zone);
	return true;
}
//---------------------------------------------------------------------

bool CPickItemAbility::GetFacingParams(const Game::CGameSession& Session, const Game::CAbilityInstance& Instance, Game::CFacingParams& Out) const
{
	// Simply face an object origin
	//???make this logic default???
	Out.Mode = Game::EFacingMode::Point;
	Out.Dir = vector3::Zero;
	Out.Tolerance = 1.5f;
	return true;
}
//---------------------------------------------------------------------

void CPickItemAbility::OnStart(Game::CGameSession& Session, Game::CAbilityInstance& Instance) const
{
}
//---------------------------------------------------------------------

Game::EActionStatus CPickItemAbility::OnUpdate(Game::CGameSession& Session, Game::CAbilityInstance& Instance) const
{
	return Game::EActionStatus::Succeeded;
}
//---------------------------------------------------------------------

void CPickItemAbility::OnEnd(Game::CGameSession& Session, Game::CAbilityInstance& Instance, Game::EActionStatus Status) const
{
	if (Status != Game::EActionStatus::Succeeded) return;

	auto pWorld = Session.FindFeature<Game::CGameWorld>();
	if (!pWorld) return;

	// TODO: if owned by another faction, create crime stimulus/signal based on Steal skill check,
	// it may even interrupt item picking (in OnStart()?)

	// TODO: equip if a) default equipping makes sense, like for weapons b) inventory is full but equipment slot isn't
	// NB: equipped things ignore volume limitations, but not weight

	AddItemsIntoContainer(*pWorld, Instance.Actor, Instance.Targets[0].Entity);
}
//---------------------------------------------------------------------

}
<|endoftext|>


<commit_before>/** @file
 *
 * @ingroup dspLibrary
 *
 * @brief Container object that holds some audio in a chunk of memory.
 *
 * @see TTMatrix, TTAudioSignal
 *
 * @authors Timothy Place & Nathan Wolek
 *
 * @copyright Copyright © 2003-2012, Timothy Place & Nathan Wolek @n
 * This code is licensed under the terms of the "New BSD License" @n
 * http://creativecommons.org/licenses/BSD/
 */

#include "TTSampleMatrix.h"
#include "TTInterpolate.h"

#define thisTTClass			TTSampleMatrix
#define thisTTClassName		"samplematrix"
#define thisTTClassTags		"audio, buffer"

TTObjectBasePtr TTSampleMatrix::instantiate(TTSymbol& name, TTValue& arguments)
{
	return new TTSampleMatrix(arguments);
}

extern "C" void TTSampleMatrix::registerClass()
{
	TTClassRegister(thisTTClassName, thisTTClassTags, TTSampleMatrix::instantiate);
}

TTSampleMatrix::TTSampleMatrix(TTValue& arguments) :
	TTMatrix(arguments),
	mSampleRate(44100.0)
{
	this->setTypeWithoutResize(kTypeFloat64);
	this->setElementCountWithoutResize(1);
	this->resize();
	this->mUserCount = 0;
	this->mBufferPoolStage = kSM_Idle;

	addAttributeWithGetterAndSetter(NumChannels,		kTypeInt32);
	addAttributeWithGetterAndSetter(Length,				kTypeFloat64);
	addAttributeWithGetterAndSetter(LengthInSamples,	kTypeInt32);
	addAttribute(SampleRate,							kTypeFloat64);
	addAttribute(				UserCount,				kTypeUInt16);
		addAttributeProperty(	UserCount, 				readOnly, kTTBoolYes);

	addMessage(normalize);
	addMessageWithArguments(fill);

	addMessageWithArguments(getValueAtIndex);
	registerMessage("peek", (TTMethod)&TTSampleMatrix::getValueAtIndex);
	registerMessage("peeki", (TTMethod)&TTSampleMatrix::getValueAtIndex);

	addMessageWithArguments(setValueAtIndex);
	registerMessage("poke", (TTMethod)&TTSampleMatrix::setValueAtIndex);

	// TODO: more messages to implement
	//	"readFile"   (requires libsndfile straightening-out)
	//	"writeFile"  (requires libsndfile straightening-out)
	//	a way to query attributes: for example what is the sr and bpm of an AIFF file?
}

TTSampleMatrix::~TTSampleMatrix()
{
	;
}

TTErr TTSampleMatrix::setNumChannels(const TTValue& newNumChannels)
{
	return setColumnCount(newNumChannels);
}

TTErr TTSampleMatrix::getNumChannels(TTValue& returnedChannelCount)
{
	returnedChannelCount = (int)mNumChannels;
	return kTTErrNone;
}

TTErr TTSampleMatrix::setLength(const TTValue& newLength)
{
	TTValue newLengthInSamples = TTFloat64(newLength) * mSampleRate * 0.001;
	return setRowCount(newLengthInSamples);
}

TTErr TTSampleMatrix::getLength(TTValue& returnedLength)
{
	returnedLength = (mLengthInSamples / mSampleRate) * 1000.0;
	return kTTErrNone;
}

TTErr TTSampleMatrix::setLengthInSamples(const TTValue& newLengthInSamples)
{
	return setRowCount(newLengthInSamples);
}

TTErr TTSampleMatrix::getLengthInSamples(TTValue& returnedLengthInSamples)
{
	returnedLengthInSamples = (int)mLengthInSamples;
	return kTTErrNone;
}

TTErr TTSampleMatrix::incrementUserCount()
{
	// could technically exceed 65,535 maximum, but we'll take the chance for now
	this->mUserCount++;
	return kTTErrNone;
}

TTErr TTSampleMatrix::decrementUserCount()
{
	if (this->mUserCount > 0)
	{
		this->mUserCount--;
		return kTTErrNone;
	} else {
		return kTTErrGeneric;
	}

}

TTErr TTSampleMatrix::getValueAtIndex(const TTValue& index, TTValue &output)
{
	TTUInt32		sampleIndex;
	TTUInt16		sampleChannel = 0;
	TTSampleValue	sampleValue;
	TTUInt8			i = 0;
	TTErr			err;

	index.get(i++, sampleIndex);
	if (index.size() > 2)		// TODO: sure would be nice to change the name of this method to "size" or something...
		index.get(i++, sampleChannel);

	err = peek(sampleIndex, sampleChannel, sampleValue);
	if (!err)
		output.set(i++, sampleValue);
	return err;
}

TTErr TTSampleMatrix::peek(const TTUInt64 index, const TTUInt16 channel, TTSampleValue& value)
{
	TTSampleID p_index = index;
	TTChannelID p_channel = channel;

	TTBoolean weAreNotInBounds = makeInBounds(p_index, p_channel); // out of range values are wrapped
	get2d(p_index, p_channel, value);

	if (weAreNotInBounds)
	{
		return kTTErrOutOfBounds;
	} else {
		return kTTErrNone;
	}
}

// a first attempt at interpolation for the SampleMatrix. should be viewed as temporary.
// needs to be fleshed out with different options...
TTErr TTSampleMatrix::peeki(const TTFloat64 index, const TTUInt16 channel, TTSampleValue& value)
{
	// variables needed
    TTChannelID p_channel = channel;
	TTFloat64 indexIntegralPart = 0;
	TTFloat64 indexFractionalPart = modf(index, &indexIntegralPart); // before makeInBounds to get the right value!
	TTSampleID indexThisInteger = TTSampleID(indexIntegralPart);

	TTBoolean weAreNotInBounds = makeInBounds(indexThisInteger, p_channel);  // out of range values are wrapped

	if (weAreNotInBounds)
	{
		// no reason to interpolate, just use the first or last value
		get2d(indexThisInteger, p_channel, value);
		return kTTErrOutOfBounds; // and report an error (is that what we want?)
	} else {
		TTSampleID indexNextInteger = indexThisInteger + 1;
		makeRowIDInBounds(indexNextInteger); //does not allow interpolation between first and last sample
			//  (is that what we want? if not, insert outOfBoundsWrap)

		TTSampleValue valueThisInteger, valueNextInteger;

		get2d(indexThisInteger, p_channel, valueThisInteger);
		get2d(indexNextInteger, p_channel, valueNextInteger);

		// simple linear interpolation adapted from TTDelay
		value = TTInterpolateLinear(valueThisInteger, valueNextInteger, indexFractionalPart);

		return kTTErrNone;
	}
}

/**	Set the sample value for a given index.
	The first number passed in the index parameter will be interpreted as the sample index.
	If there are three numbers passed, then the second number, if passed, will designate the channel index (defaults to zero).
	The final value will be used as the sample value that will be copied to the designated index.
*/
TTErr TTSampleMatrix::setValueAtIndex(const TTValue& index, TTValue& unusedOutput)
{
	TTUInt32		sampleIndex;
	TTUInt16		sampleChannel = 0;
	TTSampleValue	sampleValue;
	TTUInt8			i = 0;

	index.get(i++, sampleIndex);
	if (index.size() > 2)
		index.get(i++, sampleChannel);
	index.get(i++, sampleValue);

	return poke(sampleIndex, sampleChannel, sampleValue);
}

TTErr TTSampleMatrix::poke(const TTUInt64 index, const TTUInt16 channel, const TTSampleValue value)
{
	TTSampleID p_index = index;
	TTChannelID p_channel = channel;

	TTBoolean weAreNotInBounds = makeInBounds(p_index,p_channel); // out of range values are wrapped

	if (weAreNotInBounds)
	{
		// don't go poking around out of bounds
		return kTTErrOutOfBounds;
	} else {
		set2d(p_index, p_channel, value);
		return kTTErrNone;
	}
}

TTErr TTSampleMatrix::fill(const TTValue& value, TTValue& unusedOutput)
{
	TTSymbol		fillAlgorithm = value;
	TTSampleValue	tempSample = 0.;
	TTUInt32		tempIndex = 0;

	if (fillAlgorithm == kTTSym_sine) {
		for (TTUInt16 channel=0; channel<mNumChannels; channel++) {
			for (TTUInt64 i=0; i<mLengthInSamples; i++)
				set2d(i, channel, sin(kTTTwoPi * (i / (TTFloat64(mLengthInSamples) - 1.0))));
		}
	}
	else if (fillAlgorithm == kTTSym_sineMod) {							// (modulator version: ranges from 0.0 to 1.0, rather than -1.0 to 1.0)
		for (TTUInt16 channel=0; channel<mNumChannels; channel++) {
			for (TTUInt64 i=0; i<mLengthInSamples; i++)
				set2d(i, channel, 0.5 + (0.5 * sin(kTTTwoPi * (i / (TTFloat64(mLengthInSamples) - 1.0)))));
		}
	}
	else if (fillAlgorithm == kTTSym_cosine) {
		for (TTUInt16 channel=0; channel<mNumChannels; channel++) {
			for (TTUInt64 i=0; i<mLengthInSamples; i++)
				set2d(i, channel, cos(kTTTwoPi * (i / (TTFloat64(mLengthInSamples) - 1.0))));
		}
	}
	else if (fillAlgorithm == kTTSym_cosineMod) {
		for (TTUInt16 channel=0; channel<mNumChannels; channel++) {
			for (TTUInt64 i=0; i<mLengthInSamples; i++)
				set2d(i, channel, 0.5 + (0.5 * cos(kTTTwoPi * (i / (TTFloat64(mLengthInSamples) - 1.0)))));
		}
	}
	else if (fillAlgorithm == kTTSym_ramp) {
		for (TTUInt16 channel=0; channel<mNumChannels; channel++) {
			for (TTUInt64 i=0; i<mLengthInSamples; i++)
				set2d(i, channel, -1.0 + (2.0 * (float(i) / mLengthInSamples)));
		}
	}
	else if (fillAlgorithm == kTTSym_rampMod) {
		for (TTUInt16 channel=0; channel<mNumChannels; channel++) {
			for (TTUInt64 i=0; i<mLengthInSamples; i++)
				set2d(i, channel, float(i) / mLengthInSamples);
		}
	}
	else if (fillAlgorithm == kTTSym_sawtooth) {
		for (TTUInt16 channel=0; channel<mNumChannels; channel++) {
			for (TTUInt64 i=0; i<mLengthInSamples; i++)
				set2d(mLengthInSamples-i, channel, -1.0 + (2.0 * (float(i) / mLengthInSamples)));
		}
	}
	else if (fillAlgorithm == kTTSym_sawtoothMod) {
		for (TTUInt16 channel=0; channel<mNumChannels; channel++) {
			for (TTUInt64 i=0; i<mLengthInSamples; i++)
				set2d(mLengthInSamples-i, channel, float(i) / mLengthInSamples);
		}
	}
	else if (fillAlgorithm == kTTSym_triangle) {
		for (TTUInt16 channel=0; channel<mNumChannels; channel++) {
			tempIndex = 3*mLengthInSamples/4;
			for (TTUInt32 i=0; i < mLengthInSamples/4; i++) {
				tempSample = -1.0 + (4.0 * (float(i) / mLengthInSamples));
				set2d(i+tempIndex, channel, tempSample);
				set2d(tempIndex-i, channel, tempSample);
			}
			tempIndex = mLengthInSamples/2;
			for (TTUInt32 i=0; i < mLengthInSamples/4; i++) {
				tempSample = 4.0 * (float(i) / mLengthInSamples);
				set2d(i, channel, tempSample);
				set2d(tempIndex-i, channel, tempSample);
			}
		}
	}
	else if (fillAlgorithm == kTTSym_triangleMod) {
		for (TTUInt16 channel=0; channel<mNumChannels; channel++) {
			for (TTUInt32 i=0; i < mLengthInSamples/2; i++) {
				set2d(i, channel, -1.0 + (4.0 * (float(i) / mLengthInSamples)));
				set2d(mLengthInSamples-i, channel, -1.0 + (4.0 * (float(i) / mLengthInSamples)));
			}
		}
	}

	return kTTErrNone;
}

TTErr TTSampleMatrix::normalize(const TTValue& aValue)
{
	TTFloat64			normalizeTo = 1.0;
	TTSampleID			m = mLengthInSamples; // mFrameLength
	TTChannelID			n = mNumChannels; // mNumChannels
	TTSampleValuePtr	samples = (TTSampleValuePtr)getLockedPointer();
	TTFloat64			peakValue = 0.0;
	TTFloat64			scalar;

	if (aValue.size() && TTFloat64(aValue) > 0.0)
		normalizeTo = aValue;

	for (int k=0; k<m*n; k++) {
		TTFloat64 magnitude = abs(samples[k]);

		if (magnitude > peakValue)
			peakValue = magnitude;
	}

	scalar = normalizeTo / peakValue;

	for (int k=0; k<m*n; k++)
		samples[k] *= scalar;

	releaseLockedPointer();
	return kTTErrNone;
}
<commit_msg>redo commit #f0fab40, but more slowly PART 3<commit_after>/** @file
 *
 * @ingroup dspLibrary
 *
 * @brief Container object that holds some audio in a chunk of memory.
 *
 * @see TTMatrix, TTAudioSignal
 *
 * @authors Timothy Place & Nathan Wolek
 *
 * @copyright Copyright © 2003-2012, Timothy Place & Nathan Wolek @n
 * This code is licensed under the terms of the "New BSD License" @n
 * http://creativecommons.org/licenses/BSD/
 */

#include "TTSampleMatrix.h"
#include "TTInterpolate.h"

#define thisTTClass			TTSampleMatrix
#define thisTTClassName		"samplematrix"
#define thisTTClassTags		"audio, buffer"

TTObjectBasePtr TTSampleMatrix::instantiate(TTSymbol& name, TTValue& arguments)
{
	return new TTSampleMatrix(arguments);
}

extern "C" void TTSampleMatrix::registerClass()
{
	TTClassRegister(thisTTClassName, thisTTClassTags, TTSampleMatrix::instantiate);
}

TTSampleMatrix::TTSampleMatrix(TTValue& arguments) :
	TTMatrix(arguments),
	mSampleRate(44100.0)
{
	this->setTypeWithoutResize(kTypeFloat64);
	this->setElementCountWithoutResize(1);
	this->resize();
	this->mUserCount = 0;
	this->mBufferPoolStage = kSM_Idle;

	addAttributeWithGetterAndSetter(NumChannels,		kTypeInt32);
	addAttributeWithGetterAndSetter(Length,				kTypeFloat64);
	addAttributeWithGetterAndSetter(LengthInSamples,	kTypeInt32);
	addAttribute(SampleRate,							kTypeFloat64);
	addAttribute(				UserCount,				kTypeUInt16);
		addAttributeProperty(	UserCount, 				readOnly, kTTBoolYes);

	addMessage(normalize);
	addMessageWithArguments(fill);

	addMessageWithArguments(getValueAtIndex);
	registerMessage("peek", (TTMethod)&TTSampleMatrix::getValueAtIndex);
	registerMessage("peeki", (TTMethod)&TTSampleMatrix::getValueAtIndex);

	addMessageWithArguments(setValueAtIndex);
	registerMessage("poke", (TTMethod)&TTSampleMatrix::setValueAtIndex);

	// TODO: more messages to implement
	//	"readFile"   (requires libsndfile straightening-out)
	//	"writeFile"  (requires libsndfile straightening-out)
	//	a way to query attributes: for example what is the sr and bpm of an AIFF file?
}

TTSampleMatrix::~TTSampleMatrix()
{
	;
}

TTErr TTSampleMatrix::setNumChannels(const TTValue& newNumChannels)
{
	return setColumnCount(newNumChannels);
}

TTErr TTSampleMatrix::getNumChannels(TTValue& returnedChannelCount)
{
	returnedChannelCount = (int)mNumChannels;
	return kTTErrNone;
}

TTErr TTSampleMatrix::setLength(const TTValue& newLength)
{
	TTValue newLengthInSamples = TTFloat64(newLength) * mSampleRate * 0.001;
	return setRowCount(newLengthInSamples);
}

TTErr TTSampleMatrix::getLength(TTValue& returnedLength)
{
	returnedLength = (mLengthInSamples / mSampleRate) * 1000.0;
	return kTTErrNone;
}

TTErr TTSampleMatrix::setLengthInSamples(const TTValue& newLengthInSamples)
{
	return setRowCount(newLengthInSamples);
}

TTErr TTSampleMatrix::getLengthInSamples(TTValue& returnedLengthInSamples)
{
	returnedLengthInSamples = (int)mLengthInSamples;
	return kTTErrNone;
}

TTErr TTSampleMatrix::incrementUserCount()
{
	// could technically exceed 65,535 maximum, but we'll take the chance for now
	this->mUserCount++;
	return kTTErrNone;
}

TTErr TTSampleMatrix::decrementUserCount()
{
	if (this->mUserCount > 0)
	{
		this->mUserCount--;
		return kTTErrNone;
	} else {
		return kTTErrGeneric;
	}

}

TTErr TTSampleMatrix::getValueAtIndex(const TTValue& index, TTValue &output)
{
	TTUInt32		sampleIndex;
	TTUInt16		sampleChannel = 0;
	TTSampleValue	sampleValue;
	TTUInt8			i = 0;
	TTErr			err;

	index.get(i++, sampleIndex);
	if (index.size() > 2)		// TODO: sure would be nice to change the name of this method to "size" or something...
		index.get(i++, sampleChannel);

	err = peek(sampleIndex, sampleChannel, sampleValue);
	if (!err)
		output.set(i++, sampleValue);
	return err;
}

TTErr TTSampleMatrix::peek(const TTUInt64 index, const TTUInt16 channel, TTSampleValue& value)
{
	TTSampleID p_index = index;
	TTChannelID p_channel = channel;

	TTBoolean weAreNotInBounds = makeInBounds(p_index, p_channel); // out of range values are wrapped
	get2d(p_index, p_channel, value);

	if (weAreNotInBounds)
	{
		return kTTErrOutOfBounds;
	} else {
		return kTTErrNone;
	}
}

// a first attempt at interpolation for the SampleMatrix. should be viewed as temporary.
// needs to be fleshed out with different options...
TTErr TTSampleMatrix::peeki(const TTFloat64 index, const TTUInt16 channel, TTSampleValue& value)
{
	// variables needed
    TTChannelID p_channel = channel;
	TTFloat64 indexIntegralPart = 0;
	TTFloat64 indexFractionalPart = modf(index, &indexIntegralPart); // before makeInBounds to get the right value!
	TTSampleID indexThisInteger = TTSampleID(indexIntegralPart);

	TTBoolean weAreNotInBounds = makeInBounds(indexThisInteger, p_channel);  // out of range values are wrapped

	if (weAreNotInBounds)
	{
		// no reason to interpolate, just use the first or last value
		get2d(indexThisInteger, p_channel, value);
		return kTTErrOutOfBounds; // and report an error (is that what we want?)
	} else {
		TTSampleID indexNextInteger = indexThisInteger + 1;
		makeRowIDInBounds(indexNextInteger); //does not allow interpolation between first and last sample
			//  (is that what we want? if not, insert outOfBoundsWrap)

		TTSampleValue valueThisInteger, valueNextInteger;

		get2d(indexThisInteger, p_channel, valueThisInteger);
		get2d(indexNextInteger, p_channel, valueNextInteger);

		// simple linear interpolation adapted from TTDelay
		value = TTInterpolateLinear(valueThisInteger, valueNextInteger, indexFractionalPart);

		return kTTErrNone;
	}
}

/**	Set the sample value for a given index.
	The first number passed in the index parameter will be interpreted as the sample index.
	If there are three numbers passed, then the second number, if passed, will designate the channel index (defaults to zero).
	The final value will be used as the sample value that will be copied to the designated index.
*/
TTErr TTSampleMatrix::setValueAtIndex(const TTValue& index, TTValue& unusedOutput)
{
	TTUInt32		sampleIndex;
	TTUInt16		sampleChannel = 0;
	TTSampleValue	sampleValue;
	TTUInt8			i = 0;

	index.get(i++, sampleIndex);
	if (index.size() > 2)
		index.get(i++, sampleChannel);
	index.get(i++, sampleValue);

	return poke(sampleIndex, sampleChannel, sampleValue);
}

TTErr TTSampleMatrix::poke(const TTUInt64 index, const TTUInt16 channel, const TTSampleValue value)
{
	TTSampleID p_index = index;
	TTChannelID p_channel = channel;

	TTBoolean weAreNotInBounds = makeInBounds(p_index,p_channel); // out of range values are wrapped

	if (weAreNotInBounds)
	{
		// don't go poking around out of bounds
		return kTTErrOutOfBounds;
	} else {
		set2d(p_index, p_channel, value);
		return kTTErrNone;
	}
}

TTErr TTSampleMatrix::fill(const TTValue& value, TTValue& unusedOutput)
{
	TTSymbol		fillAlgorithm = value;
	TTSampleValue	tempSample = 0.;
	TTSampleID		tempIndex = 0;

	if (fillAlgorithm == kTTSym_sine) {
		for (TTChannelID channel=0; channel<mNumChannels; channel++) {
			for (TTSampleID i=0; i<mLengthInSamples; i++)
				set2d(i, channel, sin(kTTTwoPi * (i / (TTFloat64(mLengthInSamples) - 1.0))));
		}
	}
	else if (fillAlgorithm == kTTSym_sineMod) {							// (modulator version: ranges from 0.0 to 1.0, rather than -1.0 to 1.0)
		for (TTChannelID channel=0; channel<mNumChannels; channel++) {
			for (TTSampleID i=0; i<mLengthInSamples; i++)
				set2d(i, channel, 0.5 + (0.5 * sin(kTTTwoPi * (i / (TTFloat64(mLengthInSamples) - 1.0)))));
		}
	}
	else if (fillAlgorithm == kTTSym_cosine) {
		for (TTChannelID channel=0; channel<mNumChannels; channel++) {
			for (TTSampleID i=0; i<mLengthInSamples; i++)
				set2d(i, channel, cos(kTTTwoPi * (i / (TTFloat64(mLengthInSamples) - 1.0))));
		}
	}
	else if (fillAlgorithm == kTTSym_cosineMod) {
		for (TTChannelID channel=0; channel<mNumChannels; channel++) {
			for (TTSampleID i=0; i<mLengthInSamples; i++)
				set2d(i, channel, 0.5 + (0.5 * cos(kTTTwoPi * (i / (TTFloat64(mLengthInSamples) - 1.0)))));
		}
	}
	else if (fillAlgorithm == kTTSym_ramp) {
		for (TTChannelID channel=0; channel<mNumChannels; channel++) {
			for (TTSampleID i=0; i<mLengthInSamples; i++)
				set2d(i, channel, -1.0 + (2.0 * (float(i) / mLengthInSamples)));
		}
	}
	else if (fillAlgorithm == kTTSym_rampMod) {
		for (TTChannelID channel=0; channel<mNumChannels; channel++) {
			for (TTSampleID i=0; i<mLengthInSamples; i++)
				set2d(i, channel, float(i) / mLengthInSamples);
		}
	}
	else if (fillAlgorithm == kTTSym_sawtooth) {
		for (TTChannelID channel=0; channel<mNumChannels; channel++) {
			for (TTSampleID i=0; i<mLengthInSamples; i++)
				set2d(mLengthInSamples-i, channel, -1.0 + (2.0 * (float(i) / mLengthInSamples)));
		}
	}
	else if (fillAlgorithm == kTTSym_sawtoothMod) {
		for (TTChannelID channel=0; channel<mNumChannels; channel++) {
			for (TTSampleID i=0; i<mLengthInSamples; i++)
				set2d(mLengthInSamples-i, channel, float(i) / mLengthInSamples);
		}
	}
	else if (fillAlgorithm == kTTSym_triangle) {
		for (TTChannelID channel=0; channel<mNumChannels; channel++) {
			tempIndex = 3*mLengthInSamples/4;
			for (TTSampleID i=0; i < mLengthInSamples/4; i++) {
				tempSample = -1.0 + (4.0 * (float(i) / mLengthInSamples));
				set2d(i+tempIndex, channel, tempSample);
				set2d(tempIndex-i, channel, tempSample);
			}
			tempIndex = mLengthInSamples/2;
			for (TTSampleID i=0; i < mLengthInSamples/4; i++) {
				tempSample = 4.0 * (float(i) / mLengthInSamples);
				set2d(i, channel, tempSample);
				set2d(tempIndex-i, channel, tempSample);
			}
		}
	}
	else if (fillAlgorithm == kTTSym_triangleMod) {
		for (TTChannelID channel=0; channel<mNumChannels; channel++) {
			for (TTSampleID i=0; i < mLengthInSamples/2; i++) {
				set2d(i, channel, -1.0 + (4.0 * (float(i) / mLengthInSamples)));
				set2d(mLengthInSamples-i, channel, -1.0 + (4.0 * (float(i) / mLengthInSamples)));
			}
		}
	}

	return kTTErrNone;
}

TTErr TTSampleMatrix::normalize(const TTValue& aValue)
{
	TTFloat64			normalizeTo = 1.0;
	TTSampleID			m = mLengthInSamples; // mFrameLength
	TTChannelID			n = mNumChannels; // mNumChannels
	TTSampleValuePtr	samples = (TTSampleValuePtr)getLockedPointer();
	TTFloat64			peakValue = 0.0;
	TTFloat64			scalar;

	if (aValue.size() && TTFloat64(aValue) > 0.0)
		normalizeTo = aValue;

	for (int k=0; k<m*n; k++) {
		TTFloat64 magnitude = abs(samples[k]);

		if (magnitude > peakValue)
			peakValue = magnitude;
	}

	scalar = normalizeTo / peakValue;

	for (int k=0; k<m*n; k++)
		samples[k] *= scalar;

	releaseLockedPointer();
	return kTTErrNone;
}
<|endoftext|>


<commit_before>#include <string.h>
#include <stdlib.h>
#include <gtk/gtk.h>
#include <iostream>

#include <bot_vis/bot_vis.h>
#include <lcm/lcm.h>
#include <bot_core/bot_core.h>

#include <path_util/path_util.h>

#include <bot_frames/bot_frames_renderers.h>

//imported renderers
#include <bot_lcmgl_render/lcmgl_bot_renderer.h>
#include <laser_utils/renderer_laser.h>
#include <image_utils/renderer_cam_thumb.h>
#include <visualization/collections_renderer.hpp>
#include <octomap_utils/renderer_octomap.h>

// local renderers
#include <renderer_drc/renderer_humanoid.hpp>
#include <renderer_drc/renderer_robot_plan.hpp>
//#include <renderer_drc/renderer_localize.hpp>
#include <renderer_drc/renderer_navigation.hpp>
#include <renderer_drc/renderer_end_effector_goal.hpp>
#include "udp_util.h"

using namespace std;

static int
logplayer_remote_on_key_press(BotViewer *viewer, BotEventHandler *ehandler,
        const GdkEventKey *event)
{
    int keyval = event->keyval;

    switch (keyval)
    {
    case 'P':
    case 'p':
        udp_send_string("127.0.0.1", 53261, "PLAYPAUSETOGGLE");
        break;
    case 'N':
    case 'n':
        udp_send_string("127.0.0.1", 53261, "STEP");
        break;
    case '=':
    case '+':
        udp_send_string("127.0.0.1", 53261, "FASTER");
        break;
    case '_':
    case '-':
        udp_send_string("127.0.0.1", 53261, "SLOWER");
        break;
    case '[':
        udp_send_string("127.0.0.1", 53261, "BACK5");
        break;
    case ']':
        udp_send_string("127.0.0.1", 53261, "FORWARD5");
        break;
    default:
        return 0;
    }

    return 1;
}

int main(int argc, char *argv[])
{
  //todo: comment this section
  gtk_init(&argc, &argv);
  glutInit(&argc, argv);
  g_thread_init(NULL);

  lcm_t * lcm = bot_lcm_get_global(NULL);
  bot_glib_mainloop_attach_lcm(lcm);

  std::string config_name;
  config_name = std::string(getConfigPath()) + "/../../../config/drc_robot.cfg";
  BotParam* bot_param = bot_param_new_from_file(config_name.c_str());
  if (bot_param == NULL) {
    std::cerr << "Couldn't get bot param from file %s\n" << config_name << std::endl;
    exit(-1);
  }
  BotFrames* bot_frames = bot_frames_new(lcm, bot_param);

  BotViewer* viewer = bot_viewer_new("MIT DRC Viewer");

//  BotParam * param;

  //die cleanly for control-c etc :-)
  bot_gtk_quit_on_interrupt();

  // logplayer controls
  BotEventHandler *ehandler = (BotEventHandler*) calloc(1, sizeof(BotEventHandler));
  ehandler->name = "LogPlayer Remote";
  ehandler->enabled = 1;
  ehandler->key_press = logplayer_remote_on_key_press;
  bot_viewer_add_event_handler(viewer, ehandler, 0);

  // setup renderers
  bot_viewer_add_stock_renderer(viewer, BOT_VIEWER_STOCK_RENDERER_GRID, 1);
  bot_lcmgl_add_renderer_to_viewer(viewer, lcm, 1);
  laser_util_add_renderer_to_viewer(viewer, 1, lcm, bot_param, bot_frames);
  bot_frames_add_renderer_to_viewer(viewer, 1, bot_frames );
  add_cam_thumb_renderer_to_viewer(viewer, 0, lcm, bot_param, bot_frames);
  setup_renderer_humanoid(viewer, 0, lcm);
  collections_add_renderer_to_viewer(viewer, 1);
  add_octomap_renderer_to_viewer(viewer, 1, lcm);
   //setup_renderer_localize(viewer, 0,lcm);
   setup_renderer_navigation(viewer, 0,lcm);
   setup_renderer_robot_plan(viewer, 0, lcm);
  setup_renderer_end_effector_goal(viewer, 0, lcm);

  // load the renderer params from the config file.
  char *fname = g_build_filename(g_get_user_config_dir(), ".bot-plugin-viewerrc", NULL);
  bot_viewer_load_preferences(viewer, fname);

  gtk_main();

  //save the renderer params to the config file.
  bot_viewer_save_preferences(viewer, fname);

  bot_viewer_unref(viewer);
}
<commit_msg>fixed a header file issue in viewer/main.cpp <commit_after>#include <string.h>
#include <stdlib.h>
#include <gtk/gtk.h>
#include <iostream>

#include <bot_vis/bot_vis.h>
#include <lcm/lcm.h>
#include <bot_core/bot_core.h>

#include <path_util/path_util.h>

#include <bot_frames/bot_frames_renderers.h>

//imported renderers
#include <bot_lcmgl_render/lcmgl_bot_renderer.h>
#include <laser_utils/renderer_laser.h>
#include <image_utils/renderer_cam_thumb.h>
#include <visualization/collections_renderer.hpp>
#include <octomap_utils/renderer_octomap.h>

// local renderers
#include <renderer_drc/renderer_humanoid.hpp>
#include <renderer_drc/renderer_robot_plan.hpp>
//#include <renderer_drc/renderer_localize.hpp>
#include <renderer_drc/renderer_navigation.hpp>
#include <renderer_drc/end_effector_goal_renderer/renderer_end_effector_goal.hpp>
#include "udp_util.h"

using namespace std;

static int
logplayer_remote_on_key_press(BotViewer *viewer, BotEventHandler *ehandler,
        const GdkEventKey *event)
{
    int keyval = event->keyval;

    switch (keyval)
    {
    case 'P':
    case 'p':
        udp_send_string("127.0.0.1", 53261, "PLAYPAUSETOGGLE");
        break;
    case 'N':
    case 'n':
        udp_send_string("127.0.0.1", 53261, "STEP");
        break;
    case '=':
    case '+':
        udp_send_string("127.0.0.1", 53261, "FASTER");
        break;
    case '_':
    case '-':
        udp_send_string("127.0.0.1", 53261, "SLOWER");
        break;
    case '[':
        udp_send_string("127.0.0.1", 53261, "BACK5");
        break;
    case ']':
        udp_send_string("127.0.0.1", 53261, "FORWARD5");
        break;
    default:
        return 0;
    }

    return 1;
}

int main(int argc, char *argv[])
{
  //todo: comment this section
  gtk_init(&argc, &argv);
  glutInit(&argc, argv);
  g_thread_init(NULL);

  lcm_t * lcm = bot_lcm_get_global(NULL);
  bot_glib_mainloop_attach_lcm(lcm);

  std::string config_name;
  config_name = std::string(getConfigPath()) + "/../../../config/drc_robot.cfg";
  BotParam* bot_param = bot_param_new_from_file(config_name.c_str());
  if (bot_param == NULL) {
    std::cerr << "Couldn't get bot param from file %s\n" << config_name << std::endl;
    exit(-1);
  }
  BotFrames* bot_frames = bot_frames_new(lcm, bot_param);

  BotViewer* viewer = bot_viewer_new("MIT DRC Viewer");

//  BotParam * param;

  //die cleanly for control-c etc :-)
  bot_gtk_quit_on_interrupt();

  // logplayer controls
  BotEventHandler *ehandler = (BotEventHandler*) calloc(1, sizeof(BotEventHandler));
  ehandler->name = "LogPlayer Remote";
  ehandler->enabled = 1;
  ehandler->key_press = logplayer_remote_on_key_press;
  bot_viewer_add_event_handler(viewer, ehandler, 0);

  // setup renderers
  bot_viewer_add_stock_renderer(viewer, BOT_VIEWER_STOCK_RENDERER_GRID, 1);
  bot_lcmgl_add_renderer_to_viewer(viewer, lcm, 1);
  laser_util_add_renderer_to_viewer(viewer, 1, lcm, bot_param, bot_frames);
  bot_frames_add_renderer_to_viewer(viewer, 1, bot_frames );
  add_cam_thumb_renderer_to_viewer(viewer, 0, lcm, bot_param, bot_frames);
  setup_renderer_humanoid(viewer, 0, lcm);
  collections_add_renderer_to_viewer(viewer, 1);
  add_octomap_renderer_to_viewer(viewer, 1, lcm);
   //setup_renderer_localize(viewer, 0,lcm);
   setup_renderer_navigation(viewer, 0,lcm);
   setup_renderer_robot_plan(viewer, 0, lcm);
  setup_renderer_end_effector_goal(viewer, 0, lcm);

  // load the renderer params from the config file.
  char *fname = g_build_filename(g_get_user_config_dir(), ".bot-plugin-viewerrc", NULL);
  bot_viewer_load_preferences(viewer, fname);

  gtk_main();

  //save the renderer params to the config file.
  bot_viewer_save_preferences(viewer, fname);

  bot_viewer_unref(viewer);
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013-2015 Cisco Systems, Inc. and others.  All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 *
 */
#include "KafkaPeerPartitionerCallback.h"
#include <string>
#include <ctime>

KafkaPeerPartitionerCallback::KafkaPeerPartitionerCallback()
            : RdKafka::PartitionerCb() {
}

int32_t KafkaPeerPartitionerCallback::partitioner_cb (const RdKafka::Topic *topic,
                                                  const std::string *key,
                                                  int32_t partition_cnt,
                                                  void *msg_opaque) {

    return (key->front() + key->back()) % partition_cnt;
}<commit_msg>Fix centos6 build.<commit_after>/*
 * Copyright (c) 2013-2015 Cisco Systems, Inc. and others.  All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 *
 */
#include "KafkaPeerPartitionerCallback.h"
#include <string>
#include <ctime>

KafkaPeerPartitionerCallback::KafkaPeerPartitionerCallback()
            : RdKafka::PartitionerCb() {
}

int32_t KafkaPeerPartitionerCallback::partitioner_cb (const RdKafka::Topic *topic,
                                                  const std::string *key,
                                                  int32_t partition_cnt,
                                                  void *msg_opaque) {

    return (key->at(0) + key->at(key->size() - 1)) % partition_cnt;
}<|endoftext|>


<commit_before>// @(#)root/tmva $Id$
// Author: Attila Krasznahorkay, Andreas Hoecker, Joerg Stelzer, Eckhard von Toerne

/**********************************************************************************
 * Project: TMVA - a Root-integrated toolkit for multivariate data analysis       *
 * Package: TMVA                                                                  *
 * Class  : MsgLogger                                                             *
 * Web    : http://tmva.sourceforge.net                                           *
 *                                                                                *
 * Description:                                                                   *
 *      Implementation (see header for description)                               *
 *                                                                                *
 * Author:                                                                        *
 *      Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch> - CERN, Switzerland   *
 *      Andreas Hoecker       <Andreas.Hocker@cern.ch> - CERN, Switzerland        *
 *      Joerg Stelzer         <stelzer@cern.ch>        - DESY, Germany            *
 *      Eckhard v. Toerne     <evt@uni-bonn.de>        - U of Bonn, Germany       *
 *                                                                                *
 * Copyright (c) 2005-2011:                                                       *
 *      CERN, Switzerland                                                         *
 *      U. of Victoria, Canada                                                    *
 *      MPI-K Heidelberg, Germany                                                 *
 *      U. of Bonn, Germany                                                       *
 *                                                                                *
 * Redistribution and use in source and binary forms, with or without             *
 * modification, are permitted according to the terms listed in LICENSE           *
 * (http://tmva.sourceforge.net/LICENSE)                                          *
 **********************************************************************************/

// Local include(s):
#include "TMVA/MsgLogger.h"
#include "TMVA/Config.h"

#include "Riostream.h"

// STL include(s):
#include <iomanip>

#include <cstdlib>

#include <assert.h>

// ROOT include(s):

ClassImp(TMVA::MsgLogger)

// declaration of global variables
// this is the hard-coded maximum length of the source names
UInt_t                                 TMVA::MsgLogger::fgMaxSourceSize = 25;
Bool_t                                 TMVA::MsgLogger::fgInhibitOutput = kFALSE;

const std::string                      TMVA::MsgLogger::fgPrefix = "--- ";
const std::string                      TMVA::MsgLogger::fgSuffix = ": ";
std::map<TMVA::EMsgType, std::string>* TMVA::MsgLogger::fgTypeMap  = 0;
std::map<TMVA::EMsgType, std::string>* TMVA::MsgLogger::fgColorMap = 0;
Int_t                                  TMVA::MsgLogger::fgInstanceCounter = 0;

void   TMVA::MsgLogger::InhibitOutput() { fgInhibitOutput = kTRUE;  }
void   TMVA::MsgLogger::EnableOutput()  { fgInhibitOutput = kFALSE; }
//_______________________________________________________________________
TMVA::MsgLogger::MsgLogger( const TObject* source, EMsgType minType )
   : fObjSource ( source ),
     fStrSource ( "" ),
     fActiveType( kINFO ),
     fMinType   ( minType )
{
   // constructor
   fgInstanceCounter++;
   InitMaps();
}

//_______________________________________________________________________
TMVA::MsgLogger::MsgLogger( const std::string& source, EMsgType minType )
   : fObjSource ( 0 ),
     fStrSource ( source ),
     fActiveType( kINFO ),
     fMinType   ( minType )
{
   // constructor
   fgInstanceCounter++;
   InitMaps();
}

//_______________________________________________________________________
TMVA::MsgLogger::MsgLogger( EMsgType minType )
   : fObjSource ( 0 ),
     fStrSource ( "Unknown" ),
     fActiveType( kINFO ),
     fMinType   ( minType )
{
   // constructor
   fgInstanceCounter++;
   InitMaps();
}

//_______________________________________________________________________
TMVA::MsgLogger::MsgLogger( const MsgLogger& parent )
   : std::basic_ios<MsgLogger::char_type, MsgLogger::traits_type>(),
     std::ostringstream(),
     TObject()
{
   // copy constructor
   fgInstanceCounter++;
   InitMaps();
   *this = parent;
}

//_______________________________________________________________________
TMVA::MsgLogger::~MsgLogger()
{
   // destructor
   fgInstanceCounter--;
   if (fgInstanceCounter == 0) {
      // last MsgLogger instance has been deleted, can also delete the maps
      delete fgTypeMap;  fgTypeMap  = 0;
      delete fgColorMap; fgColorMap = 0;
   }
}

//_______________________________________________________________________
TMVA::MsgLogger& TMVA::MsgLogger::operator= ( const MsgLogger& parent )
{
   // assingment operator
   if (&parent != this) {
      fObjSource  = parent.fObjSource;
      fStrSource  = parent.fStrSource;
      fActiveType = parent.fActiveType;
      fMinType    = parent.fMinType;
   }

   return *this;
}

//_______________________________________________________________________
std::string TMVA::MsgLogger::GetFormattedSource() const
{
   // make sure the source name is no longer than fgMaxSourceSize:
   std::string source_name;
   if (fObjSource) source_name = fObjSource->GetName();
   else            source_name = fStrSource;

   if (source_name.size() > fgMaxSourceSize) {
      source_name = source_name.substr( 0, fgMaxSourceSize - 3 );
      source_name += "...";
   }

   return source_name;
}

//_______________________________________________________________________
std::string TMVA::MsgLogger::GetPrintedSource() const
{
   // the full logger prefix
   std::string source_name = GetFormattedSource();
   if (source_name.size() < fgMaxSourceSize)
      for (std::string::size_type i=source_name.size(); i<fgMaxSourceSize; i++) source_name.push_back( ' ' );

   return fgPrefix + source_name + fgSuffix;
}

//_______________________________________________________________________
void TMVA::MsgLogger::Send()
{
   // activates the logger writer

   // make sure the source name is no longer than fgMaxSourceSize:
   std::string source_name = GetFormattedSource();

   std::string message = this->str();
   std::string::size_type previous_pos = 0, current_pos = 0;

   // slice the message into lines:
   while (kTRUE) {
      current_pos = message.find( '\n', previous_pos );
      std::string line = message.substr( previous_pos, current_pos - previous_pos );

      std::ostringstream message_to_send;
      // must call the modifiers like this, otherwise g++ get's confused with the operators...
      message_to_send.setf( std::ios::adjustfield, std::ios::left );
      message_to_send.width( fgMaxSourceSize );
      message_to_send << source_name << fgSuffix << line;
      this->WriteMsg( fActiveType, message_to_send.str() );

      if (current_pos == message.npos) break;
      previous_pos = current_pos + 1;
   }

   // reset the stream buffer:
   this->str( "" );
   fActiveType = kINFO; // To always print messages that have no level specified...
   return;
}

//_______________________________________________________________________
void TMVA::MsgLogger::WriteMsg( EMsgType type, const std::string& line ) const
{
   // putting the output string, the message type, and the color
   // switcher together into a single string

   if ( (type < fMinType || fgInhibitOutput) && type!=kFATAL ) return; // no output

   std::map<EMsgType, std::string>::const_iterator stype;

   if ((stype = fgTypeMap->find( type )) != fgTypeMap->end()) {
      if (!gConfig().IsSilent() || type==kFATAL) {
         if (gConfig().UseColor()) {
            // no text for INFO or VERBOSE
            if (type == kINFO || type == kVERBOSE)
               std::cout << fgPrefix << line << std::endl; // no color for info
            else
               std::cout << fgColorMap->find( type )->second << fgPrefix << "<"
                         << stype->second << "> " << line  << "\033[0m" << std::endl;
         }
         else {
            if (type == kINFO) std::cout << fgPrefix << line << std::endl;
            else               std::cout << fgPrefix << "<" << stype->second << "> " << line << std::endl;
         }
      }
   }

   // take decision to stop if fatal error
   if (type == kFATAL) {
      std::cout << "***> abort program execution" << std::endl;
      std::exit(1);
      assert(false);
   }
}

//_______________________________________________________________________
TMVA::MsgLogger& TMVA::MsgLogger::Endmsg( MsgLogger& logger )
{
   // end line
   logger.Send();
   return logger;
}

//_______________________________________________________________________
void TMVA::MsgLogger::InitMaps()
{
   // Create the message type and color maps
   if (fgTypeMap != 0 && fgColorMap != 0) return;

   fgTypeMap  = new std::map<TMVA::EMsgType, std::string>();
   fgColorMap = new std::map<TMVA::EMsgType, std::string>();

   (*fgTypeMap)[kVERBOSE]  = std::string("VERBOSE");
   (*fgTypeMap)[kDEBUG]    = std::string("DEBUG");
   (*fgTypeMap)[kINFO]     = std::string("INFO");
   (*fgTypeMap)[kWARNING]  = std::string("WARNING");
   (*fgTypeMap)[kERROR]    = std::string("ERROR");
   (*fgTypeMap)[kFATAL]    = std::string("FATAL");
   (*fgTypeMap)[kSILENT]   = std::string("SILENT");

   (*fgColorMap)[kVERBOSE] = std::string("");
   (*fgColorMap)[kDEBUG]   = std::string("\033[34m");
   (*fgColorMap)[kINFO]    = std::string("");
   (*fgColorMap)[kWARNING] = std::string("\033[1;31m");
   (*fgColorMap)[kERROR]   = std::string("\033[31m");
   (*fgColorMap)[kFATAL]   = std::string("\033[37;41;1m");
   (*fgColorMap)[kSILENT]  = std::string("\033[30m");
}
<commit_msg>fix coverity issues 36761<commit_after>// @(#)root/tmva $Id$
// Author: Attila Krasznahorkay, Andreas Hoecker, Joerg Stelzer, Eckhard von Toerne

/**********************************************************************************
 * Project: TMVA - a Root-integrated toolkit for multivariate data analysis       *
 * Package: TMVA                                                                  *
 * Class  : MsgLogger                                                             *
 * Web    : http://tmva.sourceforge.net                                           *
 *                                                                                *
 * Description:                                                                   *
 *      Implementation (see header for description)                               *
 *                                                                                *
 * Author:                                                                        *
 *      Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch> - CERN, Switzerland   *
 *      Andreas Hoecker       <Andreas.Hocker@cern.ch> - CERN, Switzerland        *
 *      Joerg Stelzer         <stelzer@cern.ch>        - DESY, Germany            *
 *      Eckhard v. Toerne     <evt@uni-bonn.de>        - U of Bonn, Germany       *
 *                                                                                *
 * Copyright (c) 2005-2011:                                                       *
 *      CERN, Switzerland                                                         *
 *      U. of Victoria, Canada                                                    *
 *      MPI-K Heidelberg, Germany                                                 *
 *      U. of Bonn, Germany                                                       *
 *                                                                                *
 * Redistribution and use in source and binary forms, with or without             *
 * modification, are permitted according to the terms listed in LICENSE           *
 * (http://tmva.sourceforge.net/LICENSE)                                          *
 **********************************************************************************/

// Local include(s):
#include "TMVA/MsgLogger.h"
#include "TMVA/Config.h"

#include "Riostream.h"

// STL include(s):
#include <iomanip>

#include <cstdlib>

#include <assert.h>

// ROOT include(s):

ClassImp(TMVA::MsgLogger)

// declaration of global variables
// this is the hard-coded maximum length of the source names
UInt_t                                 TMVA::MsgLogger::fgMaxSourceSize = 25;
Bool_t                                 TMVA::MsgLogger::fgInhibitOutput = kFALSE;

const std::string                      TMVA::MsgLogger::fgPrefix = "--- ";
const std::string                      TMVA::MsgLogger::fgSuffix = ": ";
std::map<TMVA::EMsgType, std::string>* TMVA::MsgLogger::fgTypeMap  = 0;
std::map<TMVA::EMsgType, std::string>* TMVA::MsgLogger::fgColorMap = 0;
Int_t                                  TMVA::MsgLogger::fgInstanceCounter = 0;

void   TMVA::MsgLogger::InhibitOutput() { fgInhibitOutput = kTRUE;  }
void   TMVA::MsgLogger::EnableOutput()  { fgInhibitOutput = kFALSE; }
//_______________________________________________________________________
TMVA::MsgLogger::MsgLogger( const TObject* source, EMsgType minType )
   : fObjSource ( source ),
     fStrSource ( "" ),
     fActiveType( kINFO ),
     fMinType   ( minType )
{
   // constructor
   fgInstanceCounter++;
   InitMaps();
}

//_______________________________________________________________________
TMVA::MsgLogger::MsgLogger( const std::string& source, EMsgType minType )
   : fObjSource ( 0 ),
     fStrSource ( source ),
     fActiveType( kINFO ),
     fMinType   ( minType )
{
   // constructor
   fgInstanceCounter++;
   InitMaps();
}

//_______________________________________________________________________
TMVA::MsgLogger::MsgLogger( EMsgType minType )
   : fObjSource ( 0 ),
     fStrSource ( "Unknown" ),
     fActiveType( kINFO ),
     fMinType   ( minType )
{
   // constructor
   fgInstanceCounter++;
   InitMaps();
}

//_______________________________________________________________________
TMVA::MsgLogger::MsgLogger( const MsgLogger& parent )
   : std::basic_ios<MsgLogger::char_type, MsgLogger::traits_type>(),
     std::ostringstream(),
     TObject(),
     fObjSource(0);
{
   // copy constructor
   fgInstanceCounter++;
   InitMaps();
   *this = parent;
}

//_______________________________________________________________________
TMVA::MsgLogger::~MsgLogger()
{
   // destructor
   fgInstanceCounter--;
   if (fgInstanceCounter == 0) {
      // last MsgLogger instance has been deleted, can also delete the maps
      delete fgTypeMap;  fgTypeMap  = 0;
      delete fgColorMap; fgColorMap = 0;
   }
}

//_______________________________________________________________________
TMVA::MsgLogger& TMVA::MsgLogger::operator= ( const MsgLogger& parent )
{
   // assingment operator
   if (&parent != this) {
      fObjSource  = parent.fObjSource;
      fStrSource  = parent.fStrSource;
      fActiveType = parent.fActiveType;
      fMinType    = parent.fMinType;
   }

   return *this;
}

//_______________________________________________________________________
std::string TMVA::MsgLogger::GetFormattedSource() const
{
   // make sure the source name is no longer than fgMaxSourceSize:
   std::string source_name;
   if (fObjSource) source_name = fObjSource->GetName();
   else            source_name = fStrSource;

   if (source_name.size() > fgMaxSourceSize) {
      source_name = source_name.substr( 0, fgMaxSourceSize - 3 );
      source_name += "...";
   }

   return source_name;
}

//_______________________________________________________________________
std::string TMVA::MsgLogger::GetPrintedSource() const
{
   // the full logger prefix
   std::string source_name = GetFormattedSource();
   if (source_name.size() < fgMaxSourceSize)
      for (std::string::size_type i=source_name.size(); i<fgMaxSourceSize; i++) source_name.push_back( ' ' );

   return fgPrefix + source_name + fgSuffix;
}

//_______________________________________________________________________
void TMVA::MsgLogger::Send()
{
   // activates the logger writer

   // make sure the source name is no longer than fgMaxSourceSize:
   std::string source_name = GetFormattedSource();

   std::string message = this->str();
   std::string::size_type previous_pos = 0, current_pos = 0;

   // slice the message into lines:
   while (kTRUE) {
      current_pos = message.find( '\n', previous_pos );
      std::string line = message.substr( previous_pos, current_pos - previous_pos );

      std::ostringstream message_to_send;
      // must call the modifiers like this, otherwise g++ get's confused with the operators...
      message_to_send.setf( std::ios::adjustfield, std::ios::left );
      message_to_send.width( fgMaxSourceSize );
      message_to_send << source_name << fgSuffix << line;
      this->WriteMsg( fActiveType, message_to_send.str() );

      if (current_pos == message.npos) break;
      previous_pos = current_pos + 1;
   }

   // reset the stream buffer:
   this->str( "" );
   fActiveType = kINFO; // To always print messages that have no level specified...
   return;
}

//_______________________________________________________________________
void TMVA::MsgLogger::WriteMsg( EMsgType type, const std::string& line ) const
{
   // putting the output string, the message type, and the color
   // switcher together into a single string

   if ( (type < fMinType || fgInhibitOutput) && type!=kFATAL ) return; // no output

   std::map<EMsgType, std::string>::const_iterator stype;

   if ((stype = fgTypeMap->find( type )) != fgTypeMap->end()) {
      if (!gConfig().IsSilent() || type==kFATAL) {
         if (gConfig().UseColor()) {
            // no text for INFO or VERBOSE
            if (type == kINFO || type == kVERBOSE)
               std::cout << fgPrefix << line << std::endl; // no color for info
            else
               std::cout << fgColorMap->find( type )->second << fgPrefix << "<"
                         << stype->second << "> " << line  << "\033[0m" << std::endl;
         }
         else {
            if (type == kINFO) std::cout << fgPrefix << line << std::endl;
            else               std::cout << fgPrefix << "<" << stype->second << "> " << line << std::endl;
         }
      }
   }

   // take decision to stop if fatal error
   if (type == kFATAL) {
      std::cout << "***> abort program execution" << std::endl;
      std::exit(1);
      assert(false);
   }
}

//_______________________________________________________________________
TMVA::MsgLogger& TMVA::MsgLogger::Endmsg( MsgLogger& logger )
{
   // end line
   logger.Send();
   return logger;
}

//_______________________________________________________________________
void TMVA::MsgLogger::InitMaps()
{
   // Create the message type and color maps
   if (fgTypeMap != 0 && fgColorMap != 0) return;

   fgTypeMap  = new std::map<TMVA::EMsgType, std::string>();
   fgColorMap = new std::map<TMVA::EMsgType, std::string>();

   (*fgTypeMap)[kVERBOSE]  = std::string("VERBOSE");
   (*fgTypeMap)[kDEBUG]    = std::string("DEBUG");
   (*fgTypeMap)[kINFO]     = std::string("INFO");
   (*fgTypeMap)[kWARNING]  = std::string("WARNING");
   (*fgTypeMap)[kERROR]    = std::string("ERROR");
   (*fgTypeMap)[kFATAL]    = std::string("FATAL");
   (*fgTypeMap)[kSILENT]   = std::string("SILENT");

   (*fgColorMap)[kVERBOSE] = std::string("");
   (*fgColorMap)[kDEBUG]   = std::string("\033[34m");
   (*fgColorMap)[kINFO]    = std::string("");
   (*fgColorMap)[kWARNING] = std::string("\033[1;31m");
   (*fgColorMap)[kERROR]   = std::string("\033[31m");
   (*fgColorMap)[kFATAL]   = std::string("\033[37;41;1m");
   (*fgColorMap)[kSILENT]  = std::string("\033[30m");
}
<|endoftext|>


<commit_before>#define BOOST_TEST_MODULE "test_serialize_file"
#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST
#include <boost/test/unit_test.hpp>
#else
#define BOOST_TEST_NO_LIB
#include <boost/test/included/unit_test.hpp>
#endif
#include <toml.hpp>
#include <iostream>
#include <fstream>

BOOST_AUTO_TEST_CASE(test_example)
{
    const auto data = toml::parse("toml/tests/example.toml");
    {
        std::ofstream ofs("tmp1.toml");
        ofs << std::setw(80) << data;
    }

    auto serialized = toml::parse("tmp1.toml");
    {
        auto& owner = toml::get<toml::table>(serialized.at("owner"));
        auto& bio   = toml::get<std::string>(owner.at("bio"));
        const auto CR = std::find(bio.begin(), bio.end(), '\r');
        if(CR != bio.end())
        {
            bio.erase(CR);
        }
    }
    BOOST_CHECK(data == serialized);
}

BOOST_AUTO_TEST_CASE(test_fruit)
{
    const auto data = toml::parse("toml/tests/fruit.toml");
    {
        std::ofstream ofs("tmp2.toml");
        ofs << std::setw(80) << data;
    }
    const auto serialized = toml::parse("tmp2.toml");
    BOOST_CHECK(data == serialized);
}

BOOST_AUTO_TEST_CASE(test_hard_example)
{
    const auto data = toml::parse("toml/tests/hard_example.toml");
    {
        std::ofstream ofs("tmp3.toml");
        ofs << std::setw(80) << data;
    }
    const auto serialized = toml::parse("tmp3.toml");
    BOOST_CHECK(data == serialized);
}
<commit_msg>test: use find instead of get<T>(v.at(""))<commit_after>#define BOOST_TEST_MODULE "test_serialize_file"
#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST
#include <boost/test/unit_test.hpp>
#else
#define BOOST_TEST_NO_LIB
#include <boost/test/included/unit_test.hpp>
#endif
#include <toml.hpp>
#include <iostream>
#include <fstream>

BOOST_AUTO_TEST_CASE(test_example)
{
    const auto data = toml::parse("toml/tests/example.toml");
    {
        std::ofstream ofs("tmp1.toml");
        ofs << std::setw(80) << data;
    }

    auto serialized = toml::parse("tmp1.toml");
    {
        auto& owner = toml::find<toml::table>(serialized, "owner");
        auto& bio   = toml::get<std::string>(owner.at("bio"));
        const auto CR = std::find(bio.begin(), bio.end(), '\r');
        if(CR != bio.end())
        {
            bio.erase(CR);
        }
    }
    BOOST_CHECK(data == serialized);
}

BOOST_AUTO_TEST_CASE(test_fruit)
{
    const auto data = toml::parse("toml/tests/fruit.toml");
    {
        std::ofstream ofs("tmp2.toml");
        ofs << std::setw(80) << data;
    }
    const auto serialized = toml::parse("tmp2.toml");
    BOOST_CHECK(data == serialized);
}

BOOST_AUTO_TEST_CASE(test_hard_example)
{
    const auto data = toml::parse("toml/tests/hard_example.toml");
    {
        std::ofstream ofs("tmp3.toml");
        ofs << std::setw(80) << data;
    }
    const auto serialized = toml::parse("tmp3.toml");
    BOOST_CHECK(data == serialized);
}
<|endoftext|>


<commit_before>#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <iostream>

using namespace std;

#pragma comment(lib, "Ws2_32.lib")

int main()
{
	int i;
	cin >> i;
	return 0;
}
<commit_msg>ADDED: Core - Initializing WinSoch and echoing incoming messages.<commit_after>#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <iostream>

using namespace std;

#pragma comment(lib, "Ws2_32.lib")

#define PINNED_DOWN_SERVER_PORT "27015"
#define DEFAULT_BUFLEN 512

int main()
{
	WSADATA wsaData;

	int result;

	// Initialize Winsock.
	result = WSAStartup(MAKEWORD(2,2), &wsaData);

	if (result != 0)
	{
		printf("WSAStartup failed: %d\n", result);

		int i;
		cin >> i;
		return 1;
	}
	else
	{
		printf("Winsock initialized.\n");
	}

	addrinfo hints;
	addrinfo* addressInfo;

	ZeroMemory(&hints, sizeof (hints));
	hints.ai_family = AF_INET;			// IPv4 address family
	hints.ai_socktype = SOCK_STREAM;	// Stream socket.
	hints.ai_protocol = IPPROTO_TCP;	// TCP protocol.
	hints.ai_flags = AI_PASSIVE;		// Returned socket address structure will be used in a call to the bind function.

	// Resolve the local address and port to be used by the server
	result = getaddrinfo(NULL, PINNED_DOWN_SERVER_PORT, &hints, &addressInfo);
	if (result != 0)
	{
		printf("getaddrinfo failed: %d\n", result);
		WSACleanup();

		int i;
		cin >> i;
		return 1;
	}
	else
	{
		printf("Local address resolved.\n");
	}

	// Create a SOCKET for the server to listen for client connections.
	SOCKET listenSocket = INVALID_SOCKET;
	listenSocket = socket(addressInfo->ai_family, addressInfo->ai_socktype, addressInfo->ai_protocol);

	if (listenSocket == INVALID_SOCKET)
	{
		printf("Error at socket(): %ld\n", WSAGetLastError());
		freeaddrinfo(addressInfo);
		WSACleanup();

		int i;
		cin >> i;
		return 1;
	}

	// Setup the TCP listening socket.
    result = bind( listenSocket, addressInfo->ai_addr, (int)addressInfo->ai_addrlen);

    if (result == SOCKET_ERROR)
	{
        printf("bind failed with error: %d\n", WSAGetLastError());
        freeaddrinfo(addressInfo);
        closesocket(listenSocket);
        WSACleanup();

		int i;
		cin >> i;
		return 1;
    }
	else
	{
		printf("TCP socket created.\n");
		freeaddrinfo(addressInfo);
	}

	// Listen for maximum number of connections.
	result = listen(listenSocket, SOMAXCONN);

	if (result == SOCKET_ERROR)
	{
		printf("Listen failed with error: %ld\n", WSAGetLastError());
		closesocket(listenSocket);
		WSACleanup();

		int i;
		cin >> i;
		return 1;
	}
	else
	{
		printf("Listening for %d connections.\n", SOMAXCONN);
	}

	// Accept a single client socket.
	SOCKET clientSocket = accept(listenSocket, NULL, NULL);

	if (clientSocket == INVALID_SOCKET)
	{
		printf("accept failed: %d\n", WSAGetLastError());
		closesocket(listenSocket);
		WSACleanup();

		int i;
		cin >> i;
		return 1;
	}

	char recvbuf[DEFAULT_BUFLEN];
	int sendResult;
	int recvbuflen = DEFAULT_BUFLEN;

	// Receive until the peer shuts down the connection.
	do
	{
		result = recv(clientSocket, recvbuf, recvbuflen, 0);

		if (result > 0)
		{
			printf("Bytes received: %d\n", result);

			// Echo the buffer back to the sender.
			sendResult = send(clientSocket, recvbuf, result, 0);

			if (sendResult == SOCKET_ERROR)
			{
				printf("send failed: %d\n", WSAGetLastError());
				closesocket(clientSocket);
				WSACleanup();

				int i;
				cin >> i;
				return 1;
			}

			printf("Bytes sent: %d\n", sendResult);
		}
		else if (result == 0)
		{
			printf("Connection closing...\n");
		}
		else
		{
			printf("recv failed: %d\n", WSAGetLastError());
			closesocket(clientSocket);
			WSACleanup();

			int i;
			cin >> i;
			return 1;
		}
	}
	while (result > 0);

	// Shutdown the send half of the connection since no more data will be sent.
	result = shutdown(clientSocket, SD_SEND);
	if (result == SOCKET_ERROR)
	{
		printf("shutdown failed: %d\n", WSAGetLastError());
		closesocket(clientSocket);
		WSACleanup();

		int i;
		cin >> i;
		return 1;
	}
	else
	{
		printf("Client socket shut down.");
		closesocket(clientSocket);
		WSACleanup();
	}

	int i;
	cin >> i;
	return 0;
}
<|endoftext|>


<commit_before>#ifndef GUARD_reader_hpp
#define GUARD_reader_hpp

#include "general_typedefs.hpp"
#include "sqloxx_exceptions.hpp"
#include "sql_statement.hpp"
#include <boost/noncopyable.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <cassert>
#include <list>
#include <memory>
#include <string>
#include <vector>

namespace sqloxx
{

// READER

/**
 * @todo Update documentation and tests given new container-like
 * interface. Note the increased opportunities for undefined behaviour
 * now that the internal list is wholly created on construction - stuff
 * may be deleted, added or modified between when we create the Reader
 * and when we iterate over it.
 *
 * Class template each instantiation of which represents a container of
 * objects loaded from a database by an SQL "select" statement,
 * where the field being selected is the primary key field for type T as
 * it is stored in the database.
 *
 * Reader classes provide a higher-level, cleaner interface for
 * client code wishing to traverse a database table without having to
 * use SQL directly.
 * Each instantiation of Reader represents wraps a particular "select"
 * statement that is used to traverse a table or view in the database.
 *
 * Client code may use the Reader class in one of two ways:\n
 * (1) Use the Reader class as is, instantiating for a particular
 * type T and database connection type Connection. A Reader can be
 * constructed using the default constructor, or by passing a
 * different string to the p_selector parameter of the constructor;\n or
 * (2) Inherit from Reader<T, Connection>, but provide an alternative
 * constructor, that takes a Connection parameter, which it passes up to
 * the base Reader constructor, along with a custom string for p_selector
 * that is fixed for that derived class. This enables a given derived Reader
 * class to use a fixed selection statement for all instances of
 * that class.
 *
 * Parameter templates:\n
 * T should be a class
 * which is persisted in the database with a
 * primary key is of type sqloxx::Id, and which has a
 * static function of the form:\n
 * T create_unchecked(Connection, sqloxx::Id).
 * Connection should be a class inheriting from DatabaseConnection,
 * for which identity_map<T, Connection>() is defined to return
 * a reference to the IdentityMap for that type T for that
 * Connection.
 */
template <typename T, typename Connection>
class Reader:
	private boost::noncopyable
{
public:

	typedef typename std::list<T> Container;
	typedef typename Container::const_iterator const_iterator;
	typedef typename Container::iterator iterator;
	typedef typename Container::size_type size_type;
	typedef typename Container::difference_type difference_type;
	typedef T value_type;
	typedef typename Container::const_reverse_iterator const_reverse_iterator;
	typedef typename Container::reverse_iterator reverse_iterator;

	// TODO Figure out whether the these typedefs are necessary
	typedef typename Container::allocator_type allocator_type;
	typedef typename Container::const_pointer const_pointer;
	typedef typename Container::pointer pointer;

	/**
	 * Construct a Reader from a database connection of type
	 * Connection.
	 *
	 * @param p_selector SQL statement string that will select records
	 * representing instances of type T, from the database.
	 * The default string can be seen in the function signature. If a
	 * different string is provided, it should be such that it selects
	 * only a single column, such that that column is the primary
	 * key for class T, from which instances of Handle<T> can be
	 * constructed.
	 *
	 * @param p_database_connection instance of Connection.
	 *
	 * @throws InvalidConnection if p_database_connection is an
	 * invalid database connection (i.e. if p_database_connection.is_valid()
	 * returns false).
	 *
	 * @throws SQLiteException, or an exception derived therefrom, if there
	 * is some problem in constructing the underlying SQL statement,
	 * that results
	 * in a SQLite error code being returned.
	 *
	 * @throws std::bad_alloc in the unlikely event of a memory allocation
	 * error in constructing the underlying SQL statement.
	 *
	 * @throws TooManyStatements if the first purported SQL statement
	 * in p_selector is syntactically acceptable to SQLite, but there
	 * are characters in p_selector after this statement,
	 * other than ';' and ' '.
	 * This includes the case where there are further syntactically
	 * acceptable SQL statements after the first one.
	 *
	 * Exception safety: strong guarantee.
	 */
	explicit Reader
	(	Connection& p_database_connection,
		std::string const& p_selector =
		(	"select " + T::primary_key_name() +
			" from " + T::primary_table_name()
		)
	);

	/**
	 * @todo Document and test.
	 */
	size_type size() const;

	/**
	 * @todo Document and test.
	 */
	const_iterator begin() const;

	/**
	 * @todo Document and test.
	 */
	iterator begin();

	/**
	 * @todo Document and test.
	 */
	const_iterator end() const;

	/**
	 * @todo Document and test.
	 */
	iterator end();

private:
	/**
	 * Advances the Reader to the next row into the result set.
	 * When the Reader
	 * is first constructed, it is notionally positioned just \e before
	 * the first result row. The first call to read() moves it "onto" the
	 * first result row (if there is one). Etc. Once it is on the final
	 * result row, calling
	 * read() again will result in it moving notionally one beyond the result
	 * row, and false will be returned.
	 * Calling read yet again will then result in the reader
	 * cycling back to the
	 * first row, and returning true again (assuming there is a first row).
	 *
	 * @returns true if, on calling read(), the Reader moves onto a result
	 * row; otherwise, returns false.
	 *
	 * @throws InvalidConnection is thrown if the database connection is
	 * invalid. If this occurs, the state of the Reader
	 * will be the same as just before the throwing call to read() was
	 * made.
	 *
	 * @throws SQLiteException or some exception deriving
	 * therefrom, if an error occurs that results in a SQLite error
	 * code. This should almost never occur. If it does occur, the
	 * Reader will be reset to the state it was in just after
	 * construction - i.e. just before it read the first result row.
	 *
	 * Exception safety: basic guarantee.
	 */
	bool read();

	/**
	 * Preconditions:\n
	 * The constructor of T should offer the strong guarantee; and\n
	 * The destructor of T should never throw; and\n
	 * T should have a static method of the form
	 * T create_unchecked(Connection&, Id, char).
	 * Typically, T will be
	 * an instantiation of sqloxx::Handle - but it need not
	 * be.
	 *
	 * @returns an instance of T created by calling static method
	 * T::create_unchecked(Connection&, Id), where the Connection passed to
	 * the Reader's constructor is passed to the Connection&
	 * parameter, and the single field being read by the
	 * Reader from the database (which should be the primary
	 * key field for type T) is passed to the Id parameter.
	 *
	 * @throws ResultIndexOutOfRange if there is an error extracting
	 * the result of the underlying SQL statement. This would
	 * generally only occur if an invalid SQL statement was not
	 * passed to the constructor of the Reader, or if the database
	 * is corrupt.
	 *
	 * @throws ValueTypeException if the type of the column being
	 * selected by the underlying SQL statement is not compatible
	 * with the Id type required to initialize a Handle<T>. If a
	 * suitable SQL statement string is passed to the constructor
	 * of the Reader, this should never occur.
	 *
	 * @throws InvalidReader if the Reader is not currently positioned
	 * over a result row.
	 *
	 * @throws std::bad_alloc if the object (instance of T to which we
	 * want a Handle) is not already loaded in the IdentityMap (cache),
	 * and there is a memory allocation failure in the process of loading
	 * and caching the object.
	 *
	 * @throws InvalidConnection if the database connection is invalid.
	 *
	 * @throws SQLiteException, of a derivative thereof,
	 * in the event of an error during execution thrown up by the
	 * underlying SQLite API. Assuming the Reader was initialized with
	 * a valid SQL statement string, this should almost never occur.
	 *
	 * Exception safety: strong guarantee.
	 */
	T item() const;

	Container m_container;
	Connection& m_database_connection;
	SQLStatement mutable m_statement;
	bool m_is_valid;

};  // Reader

template <typename T, typename Connection>
Reader<T, Connection>::Reader
(	Connection& p_database_connection,
	std::string const& p_selector
):
	m_database_connection(p_database_connection),
	m_statement(p_database_connection, p_selector),
	m_is_valid(false)
{
	assert (m_container.empty());
	while (this->read())
	{
		m_container.push_back(this->item());
	}
}

template <typename T, typename Connection>
inline
typename Reader<T, Connection>::size_type
Reader<T, Connection>::size() const
{
	return m_container.size();
}

template <typename T, typename Connection>
typename Reader<T, Connection>::const_iterator
Reader<T, Connection>::begin() const
{
	return m_container.begin();
}

template <typename T, typename Connection>
inline
typename Reader<T, Connection>::iterator
Reader<T, Connection>::begin()
{
	return m_container.begin();
}

template <typename T, typename Connection>
inline
typename Reader<T, Connection>::const_iterator
Reader<T, Connection>::end() const
{
	return m_container.end();
}

template <typename T, typename Connection>
inline
typename Reader<T, Connection>::iterator
Reader<T, Connection>::end()
{
	return m_container.end();
}

template <typename T, typename Connection>
bool
Reader<T, Connection>::read()
{
		try
		{
			// Assignment is intentional
			return m_is_valid = m_statement.step();
		}
		catch (SQLiteException&)
		{
			m_is_valid = false;
			throw;
		}
}

template <typename T, typename Connection>
T
Reader<T, Connection>::item() const
{
	if (m_is_valid)
	{
		return T::create_unchecked
		(	m_database_connection, m_statement.extract<Id>(0)
		);
	}
	assert (!m_is_valid);
	throw InvalidReader("Reader is not at a result row.");
}

}  // namespace sqloxx

#endif  // GUARD_reader_hpp
<commit_msg>Added functions to allow classes derived from Reader to make parameter bindings to the SQLStatement inside in the Reader.<commit_after>#ifndef GUARD_reader_hpp
#define GUARD_reader_hpp

#include "general_typedefs.hpp"
#include "sqloxx_exceptions.hpp"
#include "sql_statement.hpp"
#include <boost/cstdint.hpp>
#include <boost/noncopyable.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <cassert>
#include <list>
#include <memory>
#include <string>
#include <vector>

namespace sqloxx
{

// READER

/**
 * @todo Update documentation and tests given new container-like
 * interface. Note the increased opportunities for undefined behaviour
 * now that the internal list is wholly created on construction - stuff
 * may be deleted, added or modified between when we create the Reader
 * and when we iterate over it.
 *
 * Class template each instantiation of which represents a container of
 * objects loaded from a database by an SQL "select" statement,
 * where the field being selected is the primary key field for type T as
 * it is stored in the database.
 *
 * Reader classes provide a higher-level, cleaner interface for
 * client code wishing to traverse a database table without having to
 * use SQL directly.
 * Each instantiation of Reader represents wraps a particular "select"
 * statement that is used to traverse a table or view in the database.
 *
 * Client code may use the Reader class in one of two ways:\n
 * (1) Use the Reader class as is, instantiating for a particular
 * type T and database connection type Connection. A Reader can be
 * constructed using the default constructor, or by passing a
 * different string to the p_selector parameter of the constructor;\n or
 * (2) Inherit from Reader<T, Connection>, but provide an alternative
 * constructor, that takes a Connection parameter, which it passes up to
 * the base Reader constructor, along with a custom string for p_selector
 * that is fixed for that derived class. This enables a given derived Reader
 * class to use a fixed selection statement for all instances of
 * that class.
 *
 * Parameter templates:\n
 * T should be a class
 * which is persisted in the database with a
 * primary key is of type sqloxx::Id, and which has a
 * static function of the form:\n
 * T create_unchecked(Connection, sqloxx::Id).
 * Connection should be a class inheriting from DatabaseConnection,
 * for which identity_map<T, Connection>() is defined to return
 * a reference to the IdentityMap for that type T for that
 * Connection.
 */
template <typename T, typename Connection>
class Reader:
	private boost::noncopyable
{
public:

	typedef typename std::list<T> Container;
	typedef typename Container::const_iterator const_iterator;
	typedef typename Container::iterator iterator;
	typedef typename Container::size_type size_type;
	typedef typename Container::difference_type difference_type;
	typedef T value_type;
	typedef typename Container::const_reverse_iterator const_reverse_iterator;
	typedef typename Container::reverse_iterator reverse_iterator;

	// TODO Figure out whether the these typedefs are necessary
	typedef typename Container::allocator_type allocator_type;
	typedef typename Container::const_pointer const_pointer;
	typedef typename Container::pointer pointer;

	/**
	 * Construct a Reader from a database connection of type
	 * Connection.
	 *
	 * @param p_selector SQL statement string that will select records
	 * representing instances of type T, from the database.
	 * The default string can be seen in the function signature. If a
	 * different string is provided, it should be such that it selects
	 * only a single column, such that that column is the primary
	 * key for class T, from which instances of Handle<T> can be
	 * constructed.
	 *
	 * @param p_database_connection instance of Connection.
	 *
	 * @throws InvalidConnection if p_database_connection is an
	 * invalid database connection (i.e. if p_database_connection.is_valid()
	 * returns false).
	 *
	 * @throws SQLiteException, or an exception derived therefrom, if there
	 * is some problem in constructing the underlying SQL statement,
	 * that results
	 * in a SQLite error code being returned.
	 *
	 * @throws std::bad_alloc in the unlikely event of a memory allocation
	 * error in constructing the underlying SQL statement.
	 *
	 * @throws TooManyStatements if the first purported SQL statement
	 * in p_selector is syntactically acceptable to SQLite, but there
	 * are characters in p_selector after this statement,
	 * other than ';' and ' '.
	 * This includes the case where there are further syntactically
	 * acceptable SQL statements after the first one.
	 *
	 * Exception safety: strong guarantee.
	 */
	explicit Reader
	(	Connection& p_database_connection,
		std::string const& p_selector =
		(	"select " + T::primary_key_name() +
			" from " + T::primary_table_name()
		)
	);

	/**
	 * @todo Document and test.
	 */
	size_type size() const;

	/**
	 * @todo Document and test.
	 */
	const_iterator begin() const;

	/**
	 * @todo Document and test.
	 */
	iterator begin();

	/**
	 * @todo Document and test.
	 */
	const_iterator end() const;

	/**
	 * @todo Document and test.
	 */
	iterator end();

protected:

	/**
	 * Bind \e x to the parameter named \e x in the SQLStatement
	 * within the Reader.
	 *
	 * @todo Document and test.
	 */
	void bind(std::string const& parameter_name, int x);
	void bind(std::string const& parameter_name, boost::int64_t x);
	void bind(std::string const& parameter_name, double x);
	void bind(std::string const& parameter_name, std::string const& x);

private:

	// Deliberately unimplemented, to capture types not explicitly catered
	// for by the proteced \e bind functions.
	template <typename ParameterType>
	void bind(std::string const& parameter_name, ParameterType x);

	/**
	 * Advances the Reader to the next row into the result set.
	 * When the Reader
	 * is first constructed, it is notionally positioned just \e before
	 * the first result row. The first call to read() moves it "onto" the
	 * first result row (if there is one). Etc. Once it is on the final
	 * result row, calling
	 * read() again will result in it moving notionally one beyond the result
	 * row, and false will be returned.
	 * Calling read yet again will then result in the reader
	 * cycling back to the
	 * first row, and returning true again (assuming there is a first row).
	 *
	 * @returns true if, on calling read(), the Reader moves onto a result
	 * row; otherwise, returns false.
	 *
	 * @throws InvalidConnection is thrown if the database connection is
	 * invalid. If this occurs, the state of the Reader
	 * will be the same as just before the throwing call to read() was
	 * made.
	 *
	 * @throws SQLiteException or some exception deriving
	 * therefrom, if an error occurs that results in a SQLite error
	 * code. This should almost never occur. If it does occur, the
	 * Reader will be reset to the state it was in just after
	 * construction - i.e. just before it read the first result row.
	 *
	 * Exception safety: basic guarantee.
	 */
	bool read();

	/**
	 * Preconditions:\n
	 * The constructor of T should offer the strong guarantee; and\n
	 * The destructor of T should never throw; and\n
	 * T should have a static method of the form
	 * T create_unchecked(Connection&, Id, char).
	 * Typically, T will be
	 * an instantiation of sqloxx::Handle - but it need not
	 * be.
	 *
	 * @returns an instance of T created by calling static method
	 * T::create_unchecked(Connection&, Id), where the Connection passed to
	 * the Reader's constructor is passed to the Connection&
	 * parameter, and the single field being read by the
	 * Reader from the database (which should be the primary
	 * key field for type T) is passed to the Id parameter.
	 *
	 * @throws ResultIndexOutOfRange if there is an error extracting
	 * the result of the underlying SQL statement. This would
	 * generally only occur if an invalid SQL statement was not
	 * passed to the constructor of the Reader, or if the database
	 * is corrupt.
	 *
	 * @throws ValueTypeException if the type of the column being
	 * selected by the underlying SQL statement is not compatible
	 * with the Id type required to initialize a Handle<T>. If a
	 * suitable SQL statement string is passed to the constructor
	 * of the Reader, this should never occur.
	 *
	 * @throws InvalidReader if the Reader is not currently positioned
	 * over a result row.
	 *
	 * @throws std::bad_alloc if the object (instance of T to which we
	 * want a Handle) is not already loaded in the IdentityMap (cache),
	 * and there is a memory allocation failure in the process of loading
	 * and caching the object.
	 *
	 * @throws InvalidConnection if the database connection is invalid.
	 *
	 * @throws SQLiteException, of a derivative thereof,
	 * in the event of an error during execution thrown up by the
	 * underlying SQLite API. Assuming the Reader was initialized with
	 * a valid SQL statement string, this should almost never occur.
	 *
	 * Exception safety: strong guarantee.
	 */
	T item() const;

	Container m_container;
	Connection& m_database_connection;
	SQLStatement mutable m_statement;
	bool m_is_valid;

};  // Reader

template <typename T, typename Connection>
Reader<T, Connection>::Reader
(	Connection& p_database_connection,
	std::string const& p_selector
):
	m_database_connection(p_database_connection),
	m_statement(p_database_connection, p_selector),
	m_is_valid(false)
{
	assert (m_container.empty());
	while (this->read())
	{
		m_container.push_back(this->item());
	}
}

template <typename T, typename Connection>
inline
typename Reader<T, Connection>::size_type
Reader<T, Connection>::size() const
{
	return m_container.size();
}

template <typename T, typename Connection>
typename Reader<T, Connection>::const_iterator
Reader<T, Connection>::begin() const
{
	return m_container.begin();
}

template <typename T, typename Connection>
inline
typename Reader<T, Connection>::iterator
Reader<T, Connection>::begin()
{
	return m_container.begin();
}

template <typename T, typename Connection>
inline
typename Reader<T, Connection>::const_iterator
Reader<T, Connection>::end() const
{
	return m_container.end();
}

template <typename T, typename Connection>
inline
typename Reader<T, Connection>::iterator
Reader<T, Connection>::end()
{
	return m_container.end();
}

template <typename T, typename Connection>
void
SQLStatement::bind(string const& parameter_name, int x)
{
	m_statement->bind(parameter_name, x);
	return;
}

template <typename T, typename Connection>
void
SQLStatement::bind(string const& parameter_name, boost::int64_t x)
{
	m_statement->bind(parameter_name, x);
	return;
}

template <typename T, typename Connection>
void
SQLStatement::bind(string const& parameter_name, double x)
{
	m_statement->bind(parameter_name, x);
}

template <typename T, typename Connection>
void
SQLStatement::bind(string const& parameter_name, string const& x)
{
	m_statement->bind(parameter_name, x);
	return;
}

template <typename T, typename Connection>
bool
Reader<T, Connection>::read()
{
		try
		{
			// Assignment is intentional
			return m_is_valid = m_statement.step();
		}
		catch (SQLiteException&)
		{
			m_is_valid = false;
			throw;
		}
}

template <typename T, typename Connection>
T
Reader<T, Connection>::item() const
{
	if (m_is_valid)
	{
		return T::create_unchecked
		(	m_database_connection, m_statement.extract<Id>(0)
		);
	}
	assert (!m_is_valid);
	throw InvalidReader("Reader is not at a result row.");
}

}  // namespace sqloxx

#endif  // GUARD_reader_hpp
<|endoftext|>