<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2011, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * 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.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
//
//////////////////////////////////////////////////////////////////////////

#include "tbb/tbb.h"

#include "IECore/CompoundParameter.h"
#include "IECore/FaceAreaOp.h"
#include "IECore/PointDistribution.h"
#include "IECore/PointsPrimitive.h"
#include "IECore/MeshPrimitive.h"
#include "IECore/TriangulateOp.h"
#include "IECore/TriangleAlgo.h"

#include "IECore/PointDistributionOp.h"

using namespace IECore;

IE_CORE_DEFINERUNTIMETYPED( PointDistributionOp );

PointDistributionOp::PointDistributionOp()
	: Op(
		"The PointDistributionOp distributes points over a mesh using IECore::PointDistribution in UV space and mapping it to 3d space.",
		new PointsPrimitiveParameter(
			"result",
			"Resulting points distributed over mesh.",
			new PointsPrimitive()
		)
	)
{
	m_meshParameter = new MeshPrimitiveParameter(
		"mesh",
		"The mesh to distribute points over.",
		new MeshPrimitive()
	);

	m_densityParameter = new FloatParameter(
		"density",
		"The density of the distributed points.",
		100.0
	);

	m_offsetParameter = new V2fParameter(
		"offset",
		"A UV offset for the PointDistribution",
		Imath::V2f( 0, 0 )
	);

	m_densityPrimVarNameParameter = new StringParameter(
		"densityPrimVarName",
		"The primitive variable to use as a density threshold.",
		"density"
	);

	m_pRefPrimVarNameParameter = new StringParameter(
		"pRefPrimVarName",
		"The primitive variable that holds the reference positions.",
		"Pref"
	);

	m_uPrimVarNameParameter = new StringParameter(
		"uPrimVarName",
		"The primitive variable for u coordinates.",
		"s"
	);

	m_vPrimVarNameParameter = new StringParameter(
		"vPrimVarName",
		"The primitive variable for v coordinates.",
		"t"
	);

	parameters()->addParameter( m_meshParameter );
	parameters()->addParameter( m_densityParameter );
	parameters()->addParameter( m_offsetParameter );
	parameters()->addParameter( m_densityPrimVarNameParameter );
	parameters()->addParameter( m_pRefPrimVarNameParameter );
	parameters()->addParameter( m_uPrimVarNameParameter );
	parameters()->addParameter( m_vPrimVarNameParameter );
}

PointDistributionOp::~PointDistributionOp()
{
}

MeshPrimitiveParameter * PointDistributionOp::meshParameter()
{
	return m_meshParameter;
}

const MeshPrimitiveParameter * PointDistributionOp::meshParameter() const
{
	return m_meshParameter;
}

FloatParameter *PointDistributionOp::densityParameter()
{
	return m_densityParameter;
}

const FloatParameter *PointDistributionOp::densityParameter() const
{
	return m_densityParameter;
}

void PointDistributionOp::processMesh( const IECore::MeshPrimitive *mesh )
{
	if ( !mesh )
	{
		throw InvalidArgumentException( "PointDistributionOp: The input mesh is not valid" );
	}

	const V3fVectorData *positions = mesh->variableData<const V3fVectorData>( "P" );
	if ( !positions )
	{
		throw InvalidArgumentException( "PointDistributionOp: The input mesh has no 'P' data" );
	}

	TriangulateOpPtr op = new TriangulateOp();
	op->inputParameter()->setValue( const_cast<MeshPrimitive *>( mesh ) );
	op->throwExceptionsParameter()->setTypedValue( false );
	m_mesh = runTimeCast<MeshPrimitive>( op->operate() );
	if ( !m_mesh || !m_mesh->arePrimitiveVariablesValid() )
	{
		throw InvalidArgumentException( "PointDistributionOp: The input mesh could not be triangulated" );
	}

	FaceAreaOpPtr faceAreaOp = new FaceAreaOp();
	faceAreaOp->inputParameter()->setValue( m_mesh );
	faceAreaOp->copyParameter()->setTypedValue( false );

	// use reference positions if they exist
	std::string pRefPrimVarName = m_pRefPrimVarNameParameter->getTypedValue();
	if( m_mesh->variables.find( pRefPrimVarName ) != m_mesh->variables.end() )
	{
		faceAreaOp->parameters()->parameter<StringParameter>( "pointPrimVar" )->setTypedValue( pRefPrimVarName );
	}

	// use specified s and t parameters
	faceAreaOp->parameters()->parameter<StringParameter>( "sPrimVar" )->setTypedValue( m_uPrimVarNameParameter->getTypedValue() );
	faceAreaOp->parameters()->parameter<StringParameter>( "tPrimVar" )->setTypedValue( m_vPrimVarNameParameter->getTypedValue() );

	faceAreaOp->operate();

	// add a constant density if it doesn't exist already
	std::string densityPrimVarName = m_densityPrimVarNameParameter->getTypedValue();
	if ( m_mesh->variables.find( densityPrimVarName ) == m_mesh->variables.end() )
	{
		m_mesh->variables[densityPrimVarName] = PrimitiveVariable( PrimitiveVariable::Constant, new FloatData( 1.0 ) );
	}

	m_meshEvaluator = new IECore::MeshPrimitiveEvaluator( m_mesh );

	assert( m_mesh );
	assert( m_meshEvaluator );

}

struct PointDistributionOp::Emitter
{
	public :

		Emitter( MeshPrimitiveEvaluator *evaluator, const PrimitiveVariable &densityVar, std::vector<Imath::V3f> &positions, size_t triangleIndex, const Imath::V2f &v0, const Imath::V2f &v1, const Imath::V2f &v2 )
			: m_meshEvaluator( evaluator ), m_densityVar( densityVar ), m_p( positions ), m_triangleIndex( triangleIndex ), m_v0( v0 ), m_v1( v1 ), m_v2( v2 )
		{
			m_evaluatorResult = staticPointerCast<MeshPrimitiveEvaluator::Result>( m_meshEvaluator->createResult() );
		}

		void operator() ( const Imath::V2f pos, float densityThreshold )
		{
			Imath::V3f bary;
			if( triangleContainsPoint( m_v0, m_v1, m_v2, pos, bary ) )
			{
				m_meshEvaluator->barycentricPosition( m_triangleIndex, bary, m_evaluatorResult );
				if ( m_evaluatorResult->floatPrimVar( m_densityVar ) >= densityThreshold )
				{
					m_p.push_back( m_evaluatorResult->point() );
				}
			}
		}

	private :

		MeshPrimitiveEvaluator *m_meshEvaluator;
		const PrimitiveVariable &m_densityVar;
		std::vector<Imath::V3f> &m_p;
		size_t m_triangleIndex;
		Imath::V2f m_v0;
		Imath::V2f m_v1;
		Imath::V2f m_v2;

		MeshPrimitiveEvaluator::ResultPtr m_evaluatorResult;

};

struct PointDistributionOp::Generator
{
	public :

		Generator( MeshPrimitiveEvaluator *evaluator, const std::vector<float> &s, const std::vector<float> &t, const std::vector<float> &faceArea, const std::vector<float> &textureArea, float density, const PrimitiveVariable &densityVar, Imath::V2f offset )
			: m_positions(), m_meshEvaluator( evaluator ), m_s( s ), m_t( t ), m_faceArea( faceArea ), m_textureArea( textureArea ), m_density( density ), m_densityVar( densityVar ), m_offset( offset )
		{
		}

		Generator( Generator &that, tbb::split )
			: m_positions(), m_meshEvaluator( that.m_meshEvaluator ), m_s( that.m_s ), m_t( that.m_t ), m_faceArea( that.m_faceArea ), m_textureArea( that.m_textureArea ), m_density( that.m_density ), m_densityVar( that.m_densityVar ), m_offset( that.m_offset )
		{
		}

		void operator()( const tbb::blocked_range<size_t> &r )
		{
			for ( size_t i=r.begin(); i!=r.end(); ++i )
			{
				float textureDensity = m_density * m_faceArea[i] / m_textureArea[i];

				size_t v0I = i * 3;
				size_t v1I = v0I + 1;
				size_t v2I = v1I + 1;

				Imath::V2f st0( m_s[v0I], m_t[v0I] );
				Imath::V2f st1( m_s[v1I], m_t[v1I] );
				Imath::V2f st2( m_s[v2I], m_t[v2I] );

				st0 += m_offset;
				st1 += m_offset;
				st2 += m_offset;

				Imath::Box2f stBounds;
				stBounds.extendBy( st0 );
				stBounds.extendBy( st1 );
				stBounds.extendBy( st2 );

				Emitter emitter( m_meshEvaluator, m_densityVar, m_positions, i, st0, st1, st2 );
				PointDistribution::defaultInstance()( stBounds, textureDensity, emitter );
			}
		}

		void join( Generator &that )
		{
			size_t numThisPoints = this->m_positions.size();
			this->m_positions.resize( numThisPoints + that.m_positions.size() );
			std::copy( that.m_positions.begin(), that.m_positions.end(), this->m_positions.begin() + numThisPoints );
		}

		std::vector<Imath::V3f> &positions()
		{
			return m_positions;
		}

	private :

		MeshPrimitiveEvaluator *m_meshEvaluator;
		const std::vector<float> &m_s;
		const std::vector<float> &m_t;
		const std::vector<float> &m_faceArea;
		const std::vector<float> &m_textureArea;
		float m_density;
		const PrimitiveVariable &m_densityVar;
		Imath::V2f m_offset;

		std::vector<Imath::V3f> m_positions;

};

ObjectPtr PointDistributionOp::doOperation( const CompoundObject * operands )
{
	processMesh( m_meshParameter->getTypedValue<MeshPrimitive>() );

	float density = m_densityParameter->getNumericValue();
	/// \todo: densityMask could optionally come from an image primitive
	const PrimitiveVariable &densityVar = m_mesh->variables.find( m_densityPrimVarNameParameter->getTypedValue() )->second;

	Imath::V2f offset = m_offsetParameter->getTypedValue();

	const std::vector<float> &s = m_mesh->variableData<FloatVectorData>( m_uPrimVarNameParameter->getTypedValue(), PrimitiveVariable::FaceVarying )->readable();
	const std::vector<float> &t = m_mesh->variableData<FloatVectorData>( m_vPrimVarNameParameter->getTypedValue(), PrimitiveVariable::FaceVarying )->readable();
	const std::vector<float> &faceArea = m_mesh->variableData<FloatVectorData>( "faceArea", PrimitiveVariable::Uniform )->readable();
	const std::vector<float> &textureArea = m_mesh->variableData<FloatVectorData>( "textureArea", PrimitiveVariable::Uniform )->readable();

	size_t numFaces = m_mesh->verticesPerFace()->readable().size();
	Generator gen( m_meshEvaluator, s, t, faceArea, textureArea, density, densityVar, offset );
	tbb::parallel_reduce( tbb::blocked_range<size_t>( 0, numFaces ), gen );

	V3fVectorDataPtr pData = new V3fVectorData();
	std::vector<Imath::V3f> &positions = pData->writable();
	std::vector<Imath::V3f> &generatedPositions = gen.positions();
	positions.resize( generatedPositions.size() );
	std::copy( generatedPositions.begin(), generatedPositions.end(), positions.begin() );

	return new PointsPrimitive( pData );
}
<commit_msg>using swap to avoid unnecessary copying<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2011, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * 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.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
//
//////////////////////////////////////////////////////////////////////////

#include "tbb/tbb.h"

#include "IECore/CompoundParameter.h"
#include "IECore/FaceAreaOp.h"
#include "IECore/PointDistribution.h"
#include "IECore/PointsPrimitive.h"
#include "IECore/MeshPrimitive.h"
#include "IECore/TriangulateOp.h"
#include "IECore/TriangleAlgo.h"

#include "IECore/PointDistributionOp.h"

using namespace IECore;

IE_CORE_DEFINERUNTIMETYPED( PointDistributionOp );

PointDistributionOp::PointDistributionOp()
	: Op(
		"The PointDistributionOp distributes points over a mesh using IECore::PointDistribution in UV space and mapping it to 3d space.",
		new PointsPrimitiveParameter(
			"result",
			"Resulting points distributed over mesh.",
			new PointsPrimitive()
		)
	)
{
	m_meshParameter = new MeshPrimitiveParameter(
		"mesh",
		"The mesh to distribute points over.",
		new MeshPrimitive()
	);

	m_densityParameter = new FloatParameter(
		"density",
		"The density of the distributed points.",
		100.0
	);

	m_offsetParameter = new V2fParameter(
		"offset",
		"A UV offset for the PointDistribution",
		Imath::V2f( 0, 0 )
	);

	m_densityPrimVarNameParameter = new StringParameter(
		"densityPrimVarName",
		"The primitive variable to use as a density threshold.",
		"density"
	);

	m_pRefPrimVarNameParameter = new StringParameter(
		"pRefPrimVarName",
		"The primitive variable that holds the reference positions.",
		"Pref"
	);

	m_uPrimVarNameParameter = new StringParameter(
		"uPrimVarName",
		"The primitive variable for u coordinates.",
		"s"
	);

	m_vPrimVarNameParameter = new StringParameter(
		"vPrimVarName",
		"The primitive variable for v coordinates.",
		"t"
	);

	parameters()->addParameter( m_meshParameter );
	parameters()->addParameter( m_densityParameter );
	parameters()->addParameter( m_offsetParameter );
	parameters()->addParameter( m_densityPrimVarNameParameter );
	parameters()->addParameter( m_pRefPrimVarNameParameter );
	parameters()->addParameter( m_uPrimVarNameParameter );
	parameters()->addParameter( m_vPrimVarNameParameter );
}

PointDistributionOp::~PointDistributionOp()
{
}

MeshPrimitiveParameter * PointDistributionOp::meshParameter()
{
	return m_meshParameter;
}

const MeshPrimitiveParameter * PointDistributionOp::meshParameter() const
{
	return m_meshParameter;
}

FloatParameter *PointDistributionOp::densityParameter()
{
	return m_densityParameter;
}

const FloatParameter *PointDistributionOp::densityParameter() const
{
	return m_densityParameter;
}

void PointDistributionOp::processMesh( const IECore::MeshPrimitive *mesh )
{
	if ( !mesh )
	{
		throw InvalidArgumentException( "PointDistributionOp: The input mesh is not valid" );
	}

	const V3fVectorData *positions = mesh->variableData<const V3fVectorData>( "P" );
	if ( !positions )
	{
		throw InvalidArgumentException( "PointDistributionOp: The input mesh has no 'P' data" );
	}

	TriangulateOpPtr op = new TriangulateOp();
	op->inputParameter()->setValue( const_cast<MeshPrimitive *>( mesh ) );
	op->throwExceptionsParameter()->setTypedValue( false );
	m_mesh = runTimeCast<MeshPrimitive>( op->operate() );
	if ( !m_mesh || !m_mesh->arePrimitiveVariablesValid() )
	{
		throw InvalidArgumentException( "PointDistributionOp: The input mesh could not be triangulated" );
	}

	FaceAreaOpPtr faceAreaOp = new FaceAreaOp();
	faceAreaOp->inputParameter()->setValue( m_mesh );
	faceAreaOp->copyParameter()->setTypedValue( false );

	// use reference positions if they exist
	std::string pRefPrimVarName = m_pRefPrimVarNameParameter->getTypedValue();
	if( m_mesh->variables.find( pRefPrimVarName ) != m_mesh->variables.end() )
	{
		faceAreaOp->parameters()->parameter<StringParameter>( "pointPrimVar" )->setTypedValue( pRefPrimVarName );
	}

	// use specified s and t parameters
	faceAreaOp->parameters()->parameter<StringParameter>( "sPrimVar" )->setTypedValue( m_uPrimVarNameParameter->getTypedValue() );
	faceAreaOp->parameters()->parameter<StringParameter>( "tPrimVar" )->setTypedValue( m_vPrimVarNameParameter->getTypedValue() );

	faceAreaOp->operate();

	// add a constant density if it doesn't exist already
	std::string densityPrimVarName = m_densityPrimVarNameParameter->getTypedValue();
	if ( m_mesh->variables.find( densityPrimVarName ) == m_mesh->variables.end() )
	{
		m_mesh->variables[densityPrimVarName] = PrimitiveVariable( PrimitiveVariable::Constant, new FloatData( 1.0 ) );
	}

	m_meshEvaluator = new IECore::MeshPrimitiveEvaluator( m_mesh );

	assert( m_mesh );
	assert( m_meshEvaluator );

}

struct PointDistributionOp::Emitter
{
	public :

		Emitter( MeshPrimitiveEvaluator *evaluator, const PrimitiveVariable &densityVar, std::vector<Imath::V3f> &positions, size_t triangleIndex, const Imath::V2f &v0, const Imath::V2f &v1, const Imath::V2f &v2 )
			: m_meshEvaluator( evaluator ), m_densityVar( densityVar ), m_p( positions ), m_triangleIndex( triangleIndex ), m_v0( v0 ), m_v1( v1 ), m_v2( v2 )
		{
			m_evaluatorResult = staticPointerCast<MeshPrimitiveEvaluator::Result>( m_meshEvaluator->createResult() );
		}

		void operator() ( const Imath::V2f pos, float densityThreshold )
		{
			Imath::V3f bary;
			if( triangleContainsPoint( m_v0, m_v1, m_v2, pos, bary ) )
			{
				m_meshEvaluator->barycentricPosition( m_triangleIndex, bary, m_evaluatorResult );
				if ( m_evaluatorResult->floatPrimVar( m_densityVar ) >= densityThreshold )
				{
					m_p.push_back( m_evaluatorResult->point() );
				}
			}
		}

	private :

		MeshPrimitiveEvaluator *m_meshEvaluator;
		const PrimitiveVariable &m_densityVar;
		std::vector<Imath::V3f> &m_p;
		size_t m_triangleIndex;
		Imath::V2f m_v0;
		Imath::V2f m_v1;
		Imath::V2f m_v2;

		MeshPrimitiveEvaluator::ResultPtr m_evaluatorResult;

};

struct PointDistributionOp::Generator
{
	public :

		Generator( MeshPrimitiveEvaluator *evaluator, const std::vector<float> &s, const std::vector<float> &t, const std::vector<float> &faceArea, const std::vector<float> &textureArea, float density, const PrimitiveVariable &densityVar, Imath::V2f offset )
			: m_positions(), m_meshEvaluator( evaluator ), m_s( s ), m_t( t ), m_faceArea( faceArea ), m_textureArea( textureArea ), m_density( density ), m_densityVar( densityVar ), m_offset( offset )
		{
		}

		Generator( Generator &that, tbb::split )
			: m_positions(), m_meshEvaluator( that.m_meshEvaluator ), m_s( that.m_s ), m_t( that.m_t ), m_faceArea( that.m_faceArea ), m_textureArea( that.m_textureArea ), m_density( that.m_density ), m_densityVar( that.m_densityVar ), m_offset( that.m_offset )
		{
		}

		void operator()( const tbb::blocked_range<size_t> &r )
		{
			for ( size_t i=r.begin(); i!=r.end(); ++i )
			{
				float textureDensity = m_density * m_faceArea[i] / m_textureArea[i];

				size_t v0I = i * 3;
				size_t v1I = v0I + 1;
				size_t v2I = v1I + 1;

				Imath::V2f st0( m_s[v0I], m_t[v0I] );
				Imath::V2f st1( m_s[v1I], m_t[v1I] );
				Imath::V2f st2( m_s[v2I], m_t[v2I] );

				st0 += m_offset;
				st1 += m_offset;
				st2 += m_offset;

				Imath::Box2f stBounds;
				stBounds.extendBy( st0 );
				stBounds.extendBy( st1 );
				stBounds.extendBy( st2 );

				Emitter emitter( m_meshEvaluator, m_densityVar, m_positions, i, st0, st1, st2 );
				PointDistribution::defaultInstance()( stBounds, textureDensity, emitter );
			}
		}

		void join( Generator &that )
		{
			size_t numThisPoints = this->m_positions.size();
			this->m_positions.resize( numThisPoints + that.m_positions.size() );
			std::copy( that.m_positions.begin(), that.m_positions.end(), this->m_positions.begin() + numThisPoints );
		}

		std::vector<Imath::V3f> &positions()
		{
			return m_positions;
		}

	private :

		MeshPrimitiveEvaluator *m_meshEvaluator;
		const std::vector<float> &m_s;
		const std::vector<float> &m_t;
		const std::vector<float> &m_faceArea;
		const std::vector<float> &m_textureArea;
		float m_density;
		const PrimitiveVariable &m_densityVar;
		Imath::V2f m_offset;

		std::vector<Imath::V3f> m_positions;

};

ObjectPtr PointDistributionOp::doOperation( const CompoundObject * operands )
{
	processMesh( m_meshParameter->getTypedValue<MeshPrimitive>() );

	float density = m_densityParameter->getNumericValue();
	/// \todo: densityMask could optionally come from an image primitive
	const PrimitiveVariable &densityVar = m_mesh->variables.find( m_densityPrimVarNameParameter->getTypedValue() )->second;

	Imath::V2f offset = m_offsetParameter->getTypedValue();

	const std::vector<float> &s = m_mesh->variableData<FloatVectorData>( m_uPrimVarNameParameter->getTypedValue(), PrimitiveVariable::FaceVarying )->readable();
	const std::vector<float> &t = m_mesh->variableData<FloatVectorData>( m_vPrimVarNameParameter->getTypedValue(), PrimitiveVariable::FaceVarying )->readable();
	const std::vector<float> &faceArea = m_mesh->variableData<FloatVectorData>( "faceArea", PrimitiveVariable::Uniform )->readable();
	const std::vector<float> &textureArea = m_mesh->variableData<FloatVectorData>( "textureArea", PrimitiveVariable::Uniform )->readable();

	size_t numFaces = m_mesh->verticesPerFace()->readable().size();
	Generator gen( m_meshEvaluator, s, t, faceArea, textureArea, density, densityVar, offset );
	tbb::parallel_reduce( tbb::blocked_range<size_t>( 0, numFaces ), gen );

	V3fVectorDataPtr pData = new V3fVectorData();
	pData->writable().swap( gen.positions() );

	return new PointsPrimitive( pData );
}
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#if !defined(SOLARISDEFINITIONS_HEADER_GUARD_1357924680)
#define SOLARISDEFINITIONS_HEADER_GUARD_1357924680

// ---------------------------------------------------------------------------
//  A define in the build for each project is also used to control whether
//  the export keyword is from the project's viewpoint or the client's.
//  These defines provide the platform specific keywords that they need
//  to do this.
// ---------------------------------------------------------------------------
#define XALAN_PLATFORM_EXPORT
#define XALAN_PLATFORM_IMPORT
#define XALAN_PLATFORM_EXPORT_FUNCTION(T) T XALAN_PLATFORM_EXPORT
#define XALAN_PLATFORM_IMPORT_FUNCTION(T) T XALAN_PLATFORM_IMPORT

// Sun Workshop 4.2 _does_ support new cast syntax, but it's
// broken with extra cv-qualifiers, so we'll use old-style casts.
#define XALAN_OLD_STYLE_CASTS

// Standard allocators don't seem to work correctly with STLport.
// I don't know if this is their bug, or ours...
#define XALAN_NO_STD_ALLOCATORS

#define XALAN_OLD_STREAMS
#define XALAN_NO_NAMESPACES
#define XALAN_NO_MUTABLE
#define XALAN_SGI_BASED_STL
#define XALAN_NO_MEMBER_TEMPLATES
#define XALAN_CANNOT_DELETE_CONST
#define XALAN_BOOL_AS_INT
#define XALAN_NO_DEFAULT_TEMPLATE_ARGUMENTS
#define XALAN_NO_COVARIANT_RETURN_TYPE
#define XALAN_XALANDOMCHAR_USHORT_MISMATCH
#define XALAN_BIG_ENDIAN
#define XALAN_STLPORT_STL
#define XALAN_NO_DEFAULT_BUILTIN_ARRAY_INITIALIZATION
#define XALAN_POSIX2_AVAILABLE

#define XALAN_UNALIGNED

#if __SUNPRO_CC_COMPAT < 5
// STL Port Definitions
#define __STL_NO_SGI_IOSTREAMS
#include <stl/_config.h>
#endif

#endif	// SOLARISDEFINITIONS_HEADER_GUARD_1357924680
<commit_msg>Fixes for newer Sun Workshop compilers.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#if !defined(SOLARISDEFINITIONS_HEADER_GUARD_1357924680)
#define SOLARISDEFINITIONS_HEADER_GUARD_1357924680

// ---------------------------------------------------------------------------
//  A define in the build for each project is also used to control whether
//  the export keyword is from the project's viewpoint or the client's.
//  These defines provide the platform specific keywords that they need
//  to do this.
// ---------------------------------------------------------------------------
#define XALAN_PLATFORM_EXPORT
#define XALAN_PLATFORM_IMPORT
#define XALAN_PLATFORM_EXPORT_FUNCTION(T) T XALAN_PLATFORM_EXPORT
#define XALAN_PLATFORM_IMPORT_FUNCTION(T) T XALAN_PLATFORM_IMPORT

// Sun Workshop 4.2 _does_ support new cast syntax, but it's
// broken with extra cv-qualifiers, so we'll use old-style casts.
#define XALAN_OLD_STYLE_CASTS

// Standard allocators don't seem to work correctly with STLport.
// I don't know if this is their bug, or ours...
#define XALAN_NO_STD_ALLOCATORS

#if __SUNPRO_CC_COMPAT >= 5

#define XALAN_SIZE_T_IN_NAMESPACE_STD

#else

#define XALAN_STLPORT_STL
#define XALAN_NO_DEFAULT_BUILTIN_ARRAY_INITIALIZATION
#define XALAN_OLD_STREAMS
#define XALAN_NO_NAMESPACES
#define XALAN_NO_MUTABLE
#define XALAN_SGI_BASED_STL
#define XALAN_NO_MEMBER_TEMPLATES
//#define XALAN_CANNOT_DELETE_CONST
#define XALAN_BOOL_AS_INT
#define XALAN_NO_DEFAULT_TEMPLATE_ARGUMENTS
#define XALAN_NO_COVARIANT_RETURN_TYPE

// STL Port Definitions
#define __STL_NO_SGI_IOSTREAMS
#include <stl/_config.h>

#endif

#define XALAN_XALANDOMCHAR_USHORT_MISMATCH
#define XALAN_BIG_ENDIAN
#define XALAN_POSIX2_AVAILABLE

#define XALAN_UNALIGNED

#endif	// SOLARISDEFINITIONS_HEADER_GUARD_1357924680
<|endoftext|>


<commit_before>/*
	This file is part of cpp-ethereum.

	cpp-ethereum is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	cpp-ethereum is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file state.cpp
 * @author Gav Wood <i@gavwood.com>
 * @date 2014
 * State test functions.
 */

#include <boost/filesystem/operations.hpp>
#include <secp256k1/secp256k1.h>
#include <libethereum/BlockChain.h>
#include <libethereum/State.h>
#include <libethereum/Defaults.h>
using namespace std;
using namespace eth;

int stateTest()
{
	cnote << "Testing State...";

	KeyPair me = sha3("Gav Wood");
	KeyPair myMiner = sha3("Gav's Miner");
//	KeyPair you = sha3("123");

	Defaults::setDBPath(boost::filesystem::temp_directory_path().string());

	OverlayDB stateDB = State::openDB();
	BlockChain bc;
	State s(myMiner.address(), stateDB);

	cout << bc;

	// Sync up - this won't do much until we use the last state.
	s.sync(bc);

	cout << s;

	// Mine to get some ether!
	s.commitToMine(bc);
	while (s.mine(100).completed) {}
	bc.attemptImport(s.blockData(), stateDB);

	cout << bc;

	s.sync(bc);

	cout << s;

	// Inject a transaction to transfer funds from miner to me.
	bytes tx;
	{
		Transaction t;
		t.nonce = s.transactionsFrom(myMiner.address());
		t.value = 1000;			// 1e3 wei.
		t.receiveAddress = me.address();
		t.sign(myMiner.secret());
		assert(t.sender() == myMiner.address());
		tx = t.rlp();
	}
	s.execute(tx);

	cout << s;

	// Mine to get some ether and set in stone.
	s.commitToMine(bc);
	while (s.mine(100).completed) {}
	bc.attemptImport(s.blockData(), stateDB);

	cout << bc;

	s.sync(bc);

	cout << s;

	return 0;
}

<commit_msg>Fix for state race condition.<commit_after>/*
	This file is part of cpp-ethereum.

	cpp-ethereum is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	cpp-ethereum is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file state.cpp
 * @author Gav Wood <i@gavwood.com>
 * @date 2014
 * State test functions.
 */

#include <boost/filesystem/operations.hpp>
#include <secp256k1/secp256k1.h>
#include <libethereum/BlockChain.h>
#include <libethereum/State.h>
#include <libethereum/Defaults.h>
using namespace std;
using namespace eth;

int stateTest()
{
	cnote << "Testing State...";

	KeyPair me = sha3("Gav Wood");
	KeyPair myMiner = sha3("Gav's Miner");
//	KeyPair you = sha3("123");

	Defaults::setDBPath(boost::filesystem::temp_directory_path().string());

	OverlayDB stateDB = State::openDB();
	BlockChain bc;
	State s(myMiner.address(), stateDB);

	cout << bc;

	// Sync up - this won't do much until we use the last state.
	s.sync(bc);

	cout << s;

	// Mine to get some ether!
	s.commitToMine(bc);
	while (!s.mine(100).completed) {}
	s.completeMine();
	bc.attemptImport(s.blockData(), stateDB);

	cout << bc;

	s.sync(bc);

	cout << s;

	// Inject a transaction to transfer funds from miner to me.
	bytes tx;
	{
		Transaction t;
		t.nonce = s.transactionsFrom(myMiner.address());
		t.value = 1000;			// 1e3 wei.
		t.receiveAddress = me.address();
		t.sign(myMiner.secret());
		assert(t.sender() == myMiner.address());
		tx = t.rlp();
	}
	s.execute(tx);

	cout << s;

	// Mine to get some ether and set in stone.
	s.commitToMine(bc);
	while (!s.mine(100).completed) {}
	s.completeMine();
	bc.attemptImport(s.blockData(), stateDB);

	cout << bc;

	s.sync(bc);

	cout << s;

	return 0;
}

<|endoftext|>


<commit_before>/** @file
 *
 * @ingroup modularMIDI
 *
 * @brief a MIDI input
 *
 * @details
 *
 * @author Theo Delahogue
 *
 * @copyright © 2014, GMEA (http://www.gmea.net) @n
 * This code is licensed under the terms of the "New BSD License" @n
 * http://creativecommons.org/licenses/BSD/
 */

#include "MIDIInput.h"

MIDIInput::MIDIInput(MIDIPtr protocol, TTSymbol& application) :
mProtocol(protocol),
mStream(NULL),
mPollingThread(NULL),
mRunning(NO),
mApplication(application)
{
    ;
}

MIDIInput::~MIDIInput()
{
	mRunning = NO;

    if (mStream) {
        Pm_Close(mStream);
        mStream = NULL;
    }

	if (mPollingThread)
		mPollingThread->wait();
	delete mPollingThread;
}

TTErr MIDIInput::setDevice(TTSymbol& newDevice)
{
	const PmDeviceInfo*	deviceInfo;
    int					deviceCount;
	PmError				err = pmNoError;

	if (newDevice != mDevice) {

		if (newDevice == TTSymbol("default")) {
			mID = Pm_GetDefaultInputDeviceID();
			mDeviceInfo = Pm_GetDeviceInfo(mID);
		}
		else {

			int i;

			deviceCount = Pm_CountDevices();
			for (i=0; i<deviceCount; i++) {
				deviceInfo = Pm_GetDeviceInfo(i);
				if (newDevice == TT(deviceInfo->name)) {
					mDeviceInfo = deviceInfo;
					mID = i;
					break;
				}
			}
			if (i == deviceCount)
				return kTTErrGeneric;
		}

		mDevice = newDevice;

        setRunning(NO);

		if (mStream) {
			Pm_Close(mStream);
			mStream = NULL;
		}

		err = Pm_OpenInput(&mStream, mID, NULL, kMidiBufferSize, NULL, NULL);
		if (err) {

			TTLogError("MIDIInput::setDevice : can't open the %s device\n", mDevice.c_str());
            return kTTErrGeneric;
        }
	}

	return kTTErrNone;
}

TTErr MIDIInput::setRunning(TTBoolean running)
{
    if (running != mRunning) {

        mRunning = running;

        if (mRunning) {

            mPollingThread = new TTThread(TTThreadCallbackType(MidiPoll), this);
        }
        else {

            if (mPollingThread)
                mPollingThread->wait();
            delete mPollingThread;
        }
    }

    return kTTErrNone;
}

void editAddress(TTString format, TTUInt8 i, TTAddress& returnedAddress)
{
    char *s_num;
    TTUInt8 len;

    if (i > 0) {
        len = format.size() + (TTInt32)log10((TTFloat32)i); // note : %d (lenght = 2) is replaced by 1 character (0::9), 2 charecters (10 :: 99), 3 char...
        s_num = (char *)malloc(sizeof(char)*len);
        snprintf(s_num, len, format.c_str(), i);
        returnedAddress = TTAddress(s_num);
        free(s_num);
    }
}

void* MidiPoll(MIDIInput* self)
{
	PmEvent	buffer[64];
	int		result;

	while (self->mRunning) {

		if (Pm_Poll(self->mStream)) {

			result = Pm_Read(self->mStream, buffer, 64);

            // result is an error number
			if (result < 0) {

				TTLogError("MidiPoll error\n");
			}
            // result is the number of midi events
			else {

				for (TTInt32 i = 0; i < result; i++) {

					char statusByte = Pm_MessageStatus(buffer[i].message);
					char dataByte1 = Pm_MessageData1(buffer[i].message);
					char dataByte2 = Pm_MessageData2(buffer[i].message);

                    // edit channel address part
                    TTUInt8     channel = (statusByte & 0x0F) + 1;
                    TTAddress   channelPart;
                    editAddress("/channel.%ld", channel, channelPart);

                    // edit command address part and value
                    TTUInt8     command = statusByte & 0xF0;
                    TTAddress   commandPart;
                    TTValue     value;
                    switch (command) {

                        case 128 :  // NOTE OFF : dataByte1 = pitch, dataByte2 = velocity (always 0)
                        {
                            editAddress("note.%ld", dataByte1, commandPart);
                            value = TTUInt32(dataByte2);
                            break;
                        }
                        case 144 :  // NOTE ON : dataByte1 = pitch, dataByte2 = velocity (always > 0)
                        {
                            editAddress("note.%ld", dataByte1, commandPart);
                            value = TTUInt32(dataByte2);
                            break;
                        }
                        case 160 :  // POLY PRESSURE : dataByte1 = pitch, dataByte2 = pressure
                        {
                            editAddress("pressure.%ld", dataByte1, commandPart);
                            value = TTUInt32(dataByte2);
                            break;
                        }
                        case 176 :  // CONTROL CHANGE : dataByte1 = control type, dataByte2 = control value
                        {
                            editAddress("control.%ld", dataByte1, commandPart);
                            value = TTUInt32(dataByte2);
                            break;
                        }
                        case 192 :  // PROGRAM CHANGE : dataByte1 = program number, dataByte2 not used
                        {
                            editAddress("program.%ld", dataByte1, commandPart);
                            value.clear();
                            break;
                        }
                        case 208 :  // CHANNEL PRESSURE : dataByte1 = pressure, dataByte2 not used
                        {
                            commandPart = TTAddress("pressure");
                            value = TTUInt32(dataByte1);
                            break;
                        }
                        case 224 :  // PITCH WHELL ?
                        {

                            break;
                        }
                        default :   // ?
                        {

                            break;
                        }
                    }

                    // edit /channel/command address + value
                    TTAddress address = channelPart.appendAddress(commandPart);

                    self->mProtocol->receivedMessage(self->mApplication, address, value);

                    // TODO ? edit /raw statusByte dataByte1 dataByte2
                    // TODO ? return buffer[i].timestamp
                }
            }
        }

        self->mPollingThread->sleep(1);
    }

    return NULL;
}<commit_msg>Handling more MIDI messages<commit_after>/** @file
 *
 * @ingroup modularMIDI
 *
 * @brief a MIDI input
 *
 * @details
 *
 * @author Theo Delahogue
 *
 * @copyright © 2014, GMEA (http://www.gmea.net) @n
 * This code is licensed under the terms of the "New BSD License" @n
 * http://creativecommons.org/licenses/BSD/
 */

#include "MIDIInput.h"

MIDIInput::MIDIInput(MIDIPtr protocol, TTSymbol& application) :
mProtocol(protocol),
mStream(NULL),
mPollingThread(NULL),
mRunning(NO),
mApplication(application)
{
    ;
}

MIDIInput::~MIDIInput()
{
	mRunning = NO;

    if (mStream) {
        Pm_Close(mStream);
        mStream = NULL;
    }

	if (mPollingThread)
		mPollingThread->wait();
	delete mPollingThread;
}

TTErr MIDIInput::setDevice(TTSymbol& newDevice)
{
	const PmDeviceInfo*	deviceInfo;
    int					deviceCount;
	PmError				err = pmNoError;

	if (newDevice != mDevice) {

		if (newDevice == TTSymbol("default")) {
			mID = Pm_GetDefaultInputDeviceID();
			mDeviceInfo = Pm_GetDeviceInfo(mID);
		}
		else {

			int i;

			deviceCount = Pm_CountDevices();
			for (i=0; i<deviceCount; i++) {
				deviceInfo = Pm_GetDeviceInfo(i);
				if (newDevice == TT(deviceInfo->name)) {
					mDeviceInfo = deviceInfo;
					mID = i;
					break;
				}
			}
			if (i == deviceCount)
				return kTTErrGeneric;
		}

		mDevice = newDevice;

        setRunning(NO);

		if (mStream) {
			Pm_Close(mStream);
			mStream = NULL;
		}

		err = Pm_OpenInput(&mStream, mID, NULL, kMidiBufferSize, NULL, NULL);
		if (err) {

			TTLogError("MIDIInput::setDevice : can't open the %s device\n", mDevice.c_str());
            return kTTErrGeneric;
        }
	}

	return kTTErrNone;
}

TTErr MIDIInput::setRunning(TTBoolean running)
{
    if (running != mRunning) {

        mRunning = running;

        if (mRunning) {

            mPollingThread = new TTThread(TTThreadCallbackType(MidiPoll), this);
        }
        else {

            if (mPollingThread)
                mPollingThread->wait();
            delete mPollingThread;
        }
    }

    return kTTErrNone;
}

void editAddress(TTString format, TTUInt8 i, TTAddress& returnedAddress)
{
    char *s_num;
    TTUInt8 len;

    if (i > 0) {
        len = format.size() + (TTInt32)log10((TTFloat32)i); // note : %d (lenght = 2) is replaced by 1 character (0::9), 2 charecters (10 :: 99), 3 char...
        s_num = (char *)malloc(sizeof(char)*len);
        snprintf(s_num, len, format.c_str(), i);
        returnedAddress = TTAddress(s_num);
        free(s_num);
    }
}

void* MidiPoll(MIDIInput* self)
{
	PmEvent	buffer[64];
	int		result;

	while (self->mRunning) {

		if (Pm_Poll(self->mStream)) {

			result = Pm_Read(self->mStream, buffer, 64);

            // result is an error number
			if (result < 0) {

				TTLogError("MidiPoll error\n");
			}
            // result is the number of midi events
			else {

                TTAddress   address;
                TTValue     value;
                TTBoolean   sysex = NO;

				for (TTInt32 i = 0; i < result; i++) {

					char statusByte = Pm_MessageStatus(buffer[i].message);
					char dataByte1 = Pm_MessageData1(buffer[i].message);
					char dataByte2 = Pm_MessageData2(buffer[i].message);

                    // parse command and channel
                    TTUInt8 command = statusByte & 0xF0;
                    TTUInt8 channel = (statusByte & 0x0F) + 1;

                    // SYSTEM EXCLUSIVE starts : dataByte1 = id code then any number of byte
                    if (!sysex && command == 240 && channel == 1) {

                        sysex = YES;
                        address = TTAddress("/sysex");
                        value = TTValue(TTUInt32(dataByte1), TTUInt32(dataByte2));
                        continue;
                    }

                    if (sysex) {

                        // SYSTEM EXCLUSIVE ends
                        if (command == 247 && channel == 1) {
                            sysex = NO;
                            self->mProtocol->receivedMessage(self->mApplication, address, value);
                            continue;
                        }

                        value.append(TTUInt32(statusByte));

                        // SYSTEM EXCLUSIVE ends
                        if (TTUInt8(dataByte1) == 247) {
                            sysex = NO;
                            self->mProtocol->receivedMessage(self->mApplication, address, value);
                            continue;
                        }

                        value.append(TTUInt32(dataByte1));

                        // SYSTEM EXCLUSIVE ends
                        if (TTUInt8(dataByte2) == 247) {
                            sysex = NO;
                            self->mProtocol->receivedMessage(self->mApplication, address, value);
                            continue;
                        }

                        value.append(TTUInt32(dataByte2));

                        continue;
                    }
                    else {

                        // edit channel address part
                        TTAddress channelPart;
                        editAddress("/channel.%ld", channel, channelPart);

                        // edit command address part and value
                        TTAddress commandPart;

                        switch (command) {

                            case 128 :  // NOTE OFF : dataByte1 = pitch, dataByte2 = velocity (always 0)
                            {
                                editAddress("note.%ld", dataByte1, commandPart);
                                value = TTUInt32(dataByte2);
                                break;
                            }
                            case 144 :  // NOTE ON : dataByte1 = pitch, dataByte2 = velocity (always > 0)
                            {
                                editAddress("note.%ld", dataByte1, commandPart);
                                value = TTUInt32(dataByte2);
                                break;
                            }
                            case 160 :  // POLY PRESSURE : dataByte1 = pitch, dataByte2 = pressure
                            {
                                editAddress("pressure.%ld", dataByte1, commandPart);
                                value = TTUInt32(dataByte2);
                                break;
                            }
                            case 176 :  // CONTROL CHANGE : dataByte1 = control type, dataByte2 = control value
                            {
                                editAddress("control.%ld", dataByte1, commandPart);
                                value = TTUInt32(dataByte2);
                                break;
                            }
                            case 192 :  // PROGRAM CHANGE : dataByte1 = program number, dataByte2 not used
                            {
                                editAddress("program.%ld", dataByte1, commandPart);
                                value.clear();
                                break;
                            }
                            case 208 :  // CHANNEL PRESSURE : dataByte1 = pressure, dataByte2 not used
                            {
                                commandPart = TTAddress("pressure");
                                value = TTUInt32(dataByte1);
                                break;
                            }
                            case 224 :  // PITCH WHEEL ? dataByte1 = LSB, dataByte2 = MSB
                            {
                                commandPart = TTAddress("wheel");

                                TTUInt16 LSB = dataByte1;
                                TTUInt16 MSB = TTUInt16(dataByte2) << 8;
                                value = TTUInt32(MSB + LSB);
                                break;
                            }
                            case 240 :
                            {
                                channelPart = kTTAdrsRoot;
                                commandPart = TTAddress("system_exclusive");
                                value.clear();
                                break;
                            }
                            case 241 :  // UNDEFINED ? dataByte1 not used, dataByte2 not used
                            {
                                channelPart = kTTAdrsRoot;
                                editAddress("undefined.%ld", command, commandPart);
                                value = TTValue(TTUInt32(dataByte1), TTUInt32(dataByte2));
                                break;
                            }
                            case 242 :  // SONG POSITION ? dataByte1 = LSB, dataByte2 = MSB
                            {
                                channelPart = kTTAdrsRoot;
                                commandPart = TTAddress("song/position");

                                TTUInt16 LSB = dataByte1;
                                TTUInt16 MSB = TTUInt16(dataByte2) << 8;
                                value = TTUInt32(MSB + LSB);
                                break;
                            }
                            case 243 :  // SONG SELECT ? dataByte1 = song, dataByte2 not used
                            {
                                channelPart = kTTAdrsRoot;
                                commandPart = TTAddress("song/select");
                                value = TTUInt32(dataByte1);
                                break;
                            }
                            case 244 :  // UNDEFINED ? dataByte1 not used, dataByte2 not used
                            {
                                channelPart = kTTAdrsRoot;
                                editAddress("undefined.%ld", command, commandPart);
                                value = TTValue(TTUInt32(dataByte1), TTUInt32(dataByte2));
                                break;
                            }
                            case 245 :  // UNDEFINED ? dataByte1 not used, dataByte2 not used
                            {
                                channelPart = kTTAdrsRoot;
                                editAddress("undefined.%ld", command, commandPart);
                                value = TTValue(TTUInt32(dataByte1), TTUInt32(dataByte2));
                                break;
                            }
                            case 246 :  // TUNE REQUEST ? dataByte1 not used, dataByte2 not used
                            {
                                commandPart = TTAddress("tune_request");
                                value.clear();
                                break;
                            }
                            case 247 :  // END OF EXCLUSIVE ? dataByte1 not used, dataByte2 not used
                            {
                                commandPart = TTAddress("end_of_exclusive");
                                value.clear();
                                break;
                            }
                            case 248 :  // TIMING CLOCK ? dataByte1 not used, dataByte2 not used
                            {
                                commandPart = TTAddress("clock");
                                value.clear();
                                break;
                            }
                            case 249 :  // UNDEFINED ? dataByte1 not used, dataByte2 not used
                            {
                                channelPart = kTTAdrsRoot;
                                editAddress("undefined.%ld", command, commandPart);
                                value = TTValue(TTUInt32(dataByte1), TTUInt32(dataByte2));
                                break;
                            }
                            case 250 :  // START ? dataByte1 not used, dataByte2 not used
                            {
                                commandPart = TTAddress("start");
                                value.clear();
                                break;
                            }
                            case 251 :  // CONTINUE ? dataByte1 not used, dataByte2 not used
                            {
                                commandPart = TTAddress("continue");
                                value.clear();
                                break;
                            }
                            case 252 :  // STOP ? dataByte1 not used, dataByte2 not used
                            {
                                commandPart = TTAddress("stop");
                                value.clear();
                                break;
                            }
                            case 253 :  // UNDEFINED ? dataByte1 not used, dataByte2 not used
                            {
                                channelPart = kTTAdrsRoot;
                                editAddress("undefined.%ld", command, commandPart);
                                value = TTValue(TTUInt32(dataByte1), TTUInt32(dataByte2));
                                break;
                            }
                            case 254 :  // ACTIVE SENSING ? dataByte1 not used, dataByte2 not used
                            {
                                commandPart = TTAddress("active_sensing");
                                value.clear();
                                break;
                            }
                            case 255 :  // SYSTEM RESET ? dataByte1 not used, dataByte2 not used
                            {
                                commandPart = TTAddress("reset");
                                value.clear();
                                break;
                            }
                            default :   // UNDEFINED ? dataByte1 not used, dataByte2 not used
                            {
                                channelPart = kTTAdrsRoot;
                                editAddress("undefined.%ld", command, commandPart);
                                value = TTValue(TTUInt32(dataByte1), TTUInt32(dataByte2));
                                break;
                            }
                        }

                        // edit /channelPart/commandPart address
                        address = channelPart.appendAddress(commandPart);
                    }

                    self->mProtocol->receivedMessage(self->mApplication, address, value);

                    // TODO ? edit /raw statusByte dataByte1 dataByte2
                    // TODO ? return buffer[i].timestamp
                }
            }
        }

        self->mPollingThread->sleep(1);
    }

    return NULL;
}<|endoftext|>


<commit_before>/*!
	@file
	@author		Evmenov Georgiy
	@date		03/2008
*/
/*
	This file is part of MyGUI.

	MyGUI 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 3 of the License, or
	(at your option) any later version.

	MyGUI 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 MyGUI.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "MyGUI_Precompiled.h"
#include "MyGUI_ControllerEdgeHide.h"
#include "MyGUI_Gui.h"
#include "MyGUI_InputManager.h"
#include "MyGUI_WidgetManager.h"
#include "MyGUI_Widget.h"

namespace MyGUI
{

#ifndef M_PI
	const float M_PI = 3.141593f;
#endif

	ControllerEdgeHide::ControllerEdgeHide() :
		mTime(1.0),
		mRemainPixels(0),
		mShadowSize(0),
		mElapsedTime(0)
	{
	}

	ControllerEdgeHide::~ControllerEdgeHide()
	{
	}

	void ControllerEdgeHide::prepareItem(Widget* _widget)
	{
		recalculateTime(_widget);
		// вызываем пользовательский делегат для подготовки
		eventPreAction(_widget);
	}

	bool ControllerEdgeHide::addTime(Widget* _widget, float _time)
	{
		Widget* keyFocus = InputManager::getInstance().getKeyFocusWidget();
		Widget* mouseFocus = InputManager::getInstance().getMouseFocusWidget();

		while ((keyFocus != nullptr) && (_widget != keyFocus))
			keyFocus = keyFocus->getParent();
		while ((mouseFocus != nullptr) && (_widget != mouseFocus))
			mouseFocus = mouseFocus->getParent();

		// if our widget or its children have focus
		bool haveFocus = ((keyFocus != nullptr) || (mouseFocus != nullptr)) || (_widget->getVisible() == false);

		mElapsedTime += haveFocus ? -_time : _time;

		if (mElapsedTime >= mTime)
		{
			mElapsedTime = mTime;
		}
		if (mElapsedTime <= 0)
		{
			mElapsedTime = 0.0f;
			return true;
		}

		float k = sin(M_PI * mElapsedTime / mTime - M_PI / 2);
		if (k < 0) k = (-pow(-k, 0.7f) + 1) / 2;
		else k = (pow(k, 0.7f) + 1) / 2;

		MyGUI::IntCoord coord = _widget->getCoord();
		// if widget was moved
		if (coord != mLastCoord)
		{
			// if still moving - leave it alone
			if (haveFocus)
				return true;
			else
				recalculateTime(_widget);
		}

		const IntSize& view_size = _widget->getParentSize();

		bool nearBorder = false;

		if ((coord.left <= 0) && !(coord.right() >= view_size.width - 1))
		{
			coord.left = - int( float(coord.width - mRemainPixels - mShadowSize) * k);
			nearBorder = true;
		}
		if ((coord.top <= 0) && !(coord.bottom() >= view_size.height - 1))
		{
			coord.top = - int( float(coord.height - mRemainPixels - mShadowSize) * k);
			nearBorder = true;
		}
		if ((coord.right() >= view_size.width - 1) && !(coord.left <= 0))
		{
			coord.left = int(float(view_size.width - 1) - float(mRemainPixels) * k - float(coord.width) * (1.f - k));
			nearBorder = true;
		}
		if ((coord.bottom() >= view_size.height - 1) && !(coord.top <= 0))
		{
			coord.top = int(float(view_size.height - 1) - float(mRemainPixels) * k - float(coord.height) * (1.f - k));
			nearBorder = true;
		}

		if (nearBorder)
		{
			_widget->setCoord(coord);
		}
		else
		{
			mElapsedTime = 0;
		}
		mLastCoord = coord;

		eventUpdateAction(_widget);

		return true;
	}

	void ControllerEdgeHide::setProperty(const std::string& _key, const std::string& _value)
	{
		if (_key == "Time")
			setTime(utility::parseValue<float>(_value));
		else if (_key == "RemainPixels")
			setRemainPixels(utility::parseValue<int>(_value));
		else if (_key == "ShadowSize")
			setShadowSize(utility::parseValue<int>(_value));
	}

	void ControllerEdgeHide::recalculateTime(Widget* _widget)
	{
		float k = 0;
		const MyGUI::IntCoord& coord = _widget->getCoord();
		const MyGUI::IntSize& view_size = _widget->getParentSize();

		// check if widget is near any border and not near opposite borders at same time
		if ((coord.left <= 0) && !(coord.right() >= view_size.width - 1))
		{
			k = - (float) coord.left / (coord.width - mRemainPixels - mShadowSize);
		}
		else if ((coord.top <= 0) && !(coord.bottom() >= view_size.height - 1))
		{
			k = - (float)coord.top / (coord.height - mRemainPixels - mShadowSize);
		}
		else if ((coord.right() >= view_size.width - 1) && !(coord.left <= 0))
		{
			k = (float)(coord.right() - view_size.width + 1 ) / (coord.width - mRemainPixels);
		}
		else if ((coord.bottom() >= view_size.height - 1) && !(coord.top <= 0))
		{
			k = (float)(coord.bottom() - view_size.height + 1 ) / (coord.height - mRemainPixels);
		}

		//mElapsedTime = (asin(k)/M_PI + 1./2) * mTime;
		// this is reversed formula from ControllerEdgeHide::addTime k calculation
		if (k > 0.5f)
			mElapsedTime = (asin( pow( 2 * k - 1, 1 / 0.7f)) / M_PI + 1.f / 2) * mTime;
		else
			mElapsedTime = (asin(-pow(-2 * k + 1, 1 / 0.7f)) / M_PI + 1.f / 2) * mTime;
	}

	void ControllerEdgeHide::setTime(float _value)
	{
		mTime = _value;
	}

	void ControllerEdgeHide::setRemainPixels(int _value)
	{
		mRemainPixels = _value;
	}

	void ControllerEdgeHide::setShadowSize(int _value)
	{
		mShadowSize = _value;
	}

} // namespace MyGUI
<commit_msg>do nothing in ControllerEdgeHide when window is minimized<commit_after>/*!
	@file
	@author		Evmenov Georgiy
	@date		03/2008
*/
/*
	This file is part of MyGUI.

	MyGUI 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 3 of the License, or
	(at your option) any later version.

	MyGUI 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 MyGUI.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "MyGUI_Precompiled.h"
#include "MyGUI_ControllerEdgeHide.h"
#include "MyGUI_Gui.h"
#include "MyGUI_InputManager.h"
#include "MyGUI_WidgetManager.h"
#include "MyGUI_Widget.h"

namespace MyGUI
{

#ifndef M_PI
	const float M_PI = 3.141593f;
#endif

	ControllerEdgeHide::ControllerEdgeHide() :
		mTime(1.0),
		mRemainPixels(0),
		mShadowSize(0),
		mElapsedTime(0)
	{
	}

	ControllerEdgeHide::~ControllerEdgeHide()
	{
	}

	void ControllerEdgeHide::prepareItem(Widget* _widget)
	{
		recalculateTime(_widget);
		// вызываем пользовательский делегат для подготовки
		eventPreAction(_widget);
	}

	bool ControllerEdgeHide::addTime(Widget* _widget, float _time)
	{
		const IntSize& view_size = _widget->getParentSize();
		// do nothing if we have minimized window
		if (view_size.width <= 1 && view_size.height <= 1)
			return true;

		Widget* keyFocus = InputManager::getInstance().getKeyFocusWidget();
		Widget* mouseFocus = InputManager::getInstance().getMouseFocusWidget();

		while ((keyFocus != nullptr) && (_widget != keyFocus))
			keyFocus = keyFocus->getParent();
		while ((mouseFocus != nullptr) && (_widget != mouseFocus))
			mouseFocus = mouseFocus->getParent();

		// if our widget or its children have focus
		bool haveFocus = ((keyFocus != nullptr) || (mouseFocus != nullptr)) || (_widget->getVisible() == false);

		mElapsedTime += haveFocus ? -_time : _time;

		if (mElapsedTime >= mTime)
		{
			mElapsedTime = mTime;
		}
		if (mElapsedTime <= 0)
		{
			mElapsedTime = 0.0f;
			return true;
		}

		float k = sin(M_PI * mElapsedTime / mTime - M_PI / 2);
		if (k < 0) k = (-pow(-k, 0.7f) + 1) / 2;
		else k = (pow(k, 0.7f) + 1) / 2;

		MyGUI::IntCoord coord = _widget->getCoord();
		// if widget was moved
		if (coord != mLastCoord)
		{
			// if still moving - leave it alone
			if (haveFocus)
				return true;
			else
				recalculateTime(_widget);
		}

		bool nearBorder = false;

		if ((coord.left <= 0) && !(coord.right() >= view_size.width - 1))
		{
			coord.left = - int( float(coord.width - mRemainPixels - mShadowSize) * k);
			nearBorder = true;
		}
		if ((coord.top <= 0) && !(coord.bottom() >= view_size.height - 1))
		{
			coord.top = - int( float(coord.height - mRemainPixels - mShadowSize) * k);
			nearBorder = true;
		}
		if ((coord.right() >= view_size.width - 1) && !(coord.left <= 0))
		{
			coord.left = int(float(view_size.width - 1) - float(mRemainPixels) * k - float(coord.width) * (1.f - k));
			nearBorder = true;
		}
		if ((coord.bottom() >= view_size.height - 1) && !(coord.top <= 0))
		{
			coord.top = int(float(view_size.height - 1) - float(mRemainPixels) * k - float(coord.height) * (1.f - k));
			nearBorder = true;
		}

		if (nearBorder)
		{
			_widget->setCoord(coord);
		}
		else
		{
			mElapsedTime = 0;
		}
		mLastCoord = coord;

		eventUpdateAction(_widget);

		return true;
	}

	void ControllerEdgeHide::setProperty(const std::string& _key, const std::string& _value)
	{
		if (_key == "Time")
			setTime(utility::parseValue<float>(_value));
		else if (_key == "RemainPixels")
			setRemainPixels(utility::parseValue<int>(_value));
		else if (_key == "ShadowSize")
			setShadowSize(utility::parseValue<int>(_value));
	}

	void ControllerEdgeHide::recalculateTime(Widget* _widget)
	{
		float k = 0;
		const MyGUI::IntCoord& coord = _widget->getCoord();
		const MyGUI::IntSize& view_size = _widget->getParentSize();

		// check if widget is near any border and not near opposite borders at same time
		if ((coord.left <= 0) && !(coord.right() >= view_size.width - 1))
		{
			k = - (float) coord.left / (coord.width - mRemainPixels - mShadowSize);
		}
		else if ((coord.top <= 0) && !(coord.bottom() >= view_size.height - 1))
		{
			k = - (float)coord.top / (coord.height - mRemainPixels - mShadowSize);
		}
		else if ((coord.right() >= view_size.width - 1) && !(coord.left <= 0))
		{
			k = (float)(coord.right() - view_size.width + 1 ) / (coord.width - mRemainPixels);
		}
		else if ((coord.bottom() >= view_size.height - 1) && !(coord.top <= 0))
		{
			k = (float)(coord.bottom() - view_size.height + 1 ) / (coord.height - mRemainPixels);
		}

		//mElapsedTime = (asin(k)/M_PI + 1./2) * mTime;
		// this is reversed formula from ControllerEdgeHide::addTime k calculation
		if (k > 0.5f)
			mElapsedTime = (asin( pow( 2 * k - 1, 1 / 0.7f)) / M_PI + 1.f / 2) * mTime;
		else
			mElapsedTime = (asin(-pow(-2 * k + 1, 1 / 0.7f)) / M_PI + 1.f / 2) * mTime;
	}

	void ControllerEdgeHide::setTime(float _value)
	{
		mTime = _value;
	}

	void ControllerEdgeHide::setRemainPixels(int _value)
	{
		mRemainPixels = _value;
	}

	void ControllerEdgeHide::setShadowSize(int _value)
	{
		mShadowSize = _value;
	}

} // namespace MyGUI
<|endoftext|>


<commit_before>#include <map>
//leaving this here to try when there is a way around
//the unique keys requirement for boost::bimaps:
#include <boost/bimap.hpp>

std::map <char, char> trnscrb;
trnscrb['A'] = 'A';
trnscrb['G'] = 'G';
trnscrb['T'] = 'U';
trnscrb['C'] = 'C';

std::map <char, char> revtrnscrb;
revtrnscrb['A'] = 'A';
revtrnscrb['G'] = 'G';
revtrnscrb['U'] = 'T';
revtrnscrb['C'] = 'C';
<commit_msg>add rna->peptide translation map<commit_after>#include <map>
//leaving this here to try when there is a way around
//the unique keys requirement for boost::bimaps:
#include <boost/bimap.hpp>

std::map <char, char> trnscrb;
trnscrb['A'] = 'A';
trnscrb['G'] = 'G';
trnscrb['T'] = 'U';
trnscrb['C'] = 'C';

std::map <char, char> revtrnscrb;
revtrnscrb['A'] = 'A';
revtrnscrb['G'] = 'G';
revtrnscrb['U'] = 'T';
revtrnscrb['C'] = 'C';

std::map <char, char> trnslt;
trnslt['UUU'] = 'Phe'
trnslt['UCU'] = 'Ser'
trnslt['UAU'] = 'Tyr'
trnslt['UGU'] = 'Cys'
trnslt['UUC'] = 'Phe'
trnslt['UCC'] = 'Ser'
trnslt['UAC'] = 'Tyr'
trnslt['UGC'] = 'Cys'
trnslt['UUA'] = 'Leu'
trnslt['UCA'] = 'Ser'
trnslt['UAA'] = 'STOP'
trnslt['UGA'] = 'STOP'
trnslt['UUG'] = 'Leu'
trnslt['UCG'] = 'Ser'
trnslt['UAG'] = 'STOP'
trnslt['UGG'] = 'Trp'
trnslt['CUU'] = 'Leu'
trnslt['CCU'] = 'Pro'
trnslt['CAU'] = 'His'
trnslt['CGU'] = 'Arg'
trnslt['CUC'] = 'Leu'
trnslt['CCC'] = 'Pro'
trnslt['CAC'] = 'His'
trnslt['CGC'] = 'Arg '
trnslt['CUA'] = 'Leu'
trnslt['CCA'] = 'Pro'
trnslt['CAA'] = 'Gln'
trnslt['CGA'] = 'Arg '
trnslt['CUG'] = 'Leu'
trnslt['CCG'] = 'Pro'
trnslt['CAG'] = 'Gln'
trnslt['CGG'] = 'Arg '
trnslt['AUU'] = 'Ile'
trnslt['ACU'] = 'Thr'
trnslt['AAU'] = 'Asn'
trnslt['AGU'] = 'Ser'
trnslt['AUC'] = 'Ile'
trnslt['ACC'] = 'Thr'
trnslt['AAC'] = 'Asn'
trnslt['AGC'] = 'Ser '
trnslt['AUA'] = 'Ile'
trnslt['ACA'] = 'Thr'
trnslt['AAA'] = 'Lys'
trnslt['AGA'] = 'Arg'
trnslt['AUG'] = 'Met'
trnslt['ACG'] = 'Thr'
trnslt['AAG'] = 'Lys'
trnslt['AGG'] = 'Arg '
trnslt['GUU'] = 'Val'
trnslt['GCU'] = 'Ala'
trnslt['GAU'] = 'Asp'
trnslt['GGU'] = 'Gly'
trnslt['GUC'] = 'Val'
trnslt['GCC'] = 'Ala'
trnslt['GAC'] = 'Asp'
trnslt['GGC'] = 'Gly'
trnslt['GUA'] = 'Val'
trnslt['GCA'] = 'Ala'
trnslt['GAA'] = 'Glu'
trnslt['GGA'] = 'Gly'
trnslt['GUG'] = 'Val'
trnslt['GCG'] = 'Ala'
trnslt['GAG'] = 'Glu'
trnslt['GGG'] = 'Gly'
<|endoftext|>


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

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_xmloff.hxx"

#ifndef _XMLOFF_FORMS_ATTRIBLISTMERGE_HXX_
#include "attriblistmerge.hxx"
#endif

//.........................................................................
namespace xmloff
{
//.........................................................................

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::xml;

    //=====================================================================
    //= OAttribListMerger
    //=====================================================================
    //---------------------------------------------------------------------
    void OAttribListMerger::addList(const Reference< sax::XAttributeList >& _rxList)
    {
        OSL_ENSURE(_rxList.is(), "OAttribListMerger::addList: invalid list!");
        if (_rxList.is())
            m_aLists.push_back(_rxList);
    }

    //---------------------------------------------------------------------
    sal_Bool OAttribListMerger::seekToIndex(sal_Int16 _nGlobalIndex, Reference< sax::XAttributeList >& _rSubList, sal_Int16& _rLocalIndex)
    {
        sal_Int16 nLeftOver = _nGlobalIndex;
        ConstAttributeListArrayIterator aLookupSublist = m_aLists.begin();

        for ( ; (aLookupSublist != m_aLists.end()) && (nLeftOver >= (*aLookupSublist)->getLength());
                ++aLookupSublist
            )
            nLeftOver = nLeftOver - (*aLookupSublist)->getLength();

        if (aLookupSublist == m_aLists.end())
        {
            OSL_ENSURE(sal_False, "OAttribListMerger::seekToIndex: invalid index!");
            return sal_False;
        }
        _rSubList = *aLookupSublist;
        _rLocalIndex = nLeftOver;
        return sal_True;
    }

    //---------------------------------------------------------------------
    sal_Bool OAttribListMerger::seekToName(const ::rtl::OUString& _rName, Reference< sax::XAttributeList >& _rSubList, sal_Int16& _rLocalIndex)
    {
        for (   ConstAttributeListArrayIterator aLookupSublist = m_aLists.begin();
                aLookupSublist != m_aLists.end();
                ++aLookupSublist
            )
            for (sal_Int16 i=0; i<(*aLookupSublist)->getLength(); ++i)
                if ((*aLookupSublist)->getNameByIndex(i) == _rName)
                {
                    _rSubList = *aLookupSublist;
                    _rLocalIndex = i;
                    return sal_True;
                }

        OSL_ENSURE(sal_False, "OAttribListMerger::seekToName: did not find the name!");
        return sal_False;
    }

    //---------------------------------------------------------------------
    sal_Int16 SAL_CALL OAttribListMerger::getLength(  ) throw(RuntimeException)
    {
        sal_Int16 nCount = 0;
        for (   ConstAttributeListArrayIterator aAccumulate = m_aLists.begin();
                aAccumulate != m_aLists.end();
                ++aAccumulate
            )
            nCount = nCount + (*aAccumulate)->getLength();
        return nCount;
    }

    //---------------------------------------------------------------------
    ::rtl::OUString SAL_CALL OAttribListMerger::getNameByIndex( sal_Int16 i ) throw(RuntimeException)
    {
        Reference< sax::XAttributeList > xSubList;
        sal_Int16 nLocalIndex;

        if (!seekToIndex(i, xSubList, nLocalIndex))
            return ::rtl::OUString();

        return xSubList->getNameByIndex(nLocalIndex);
    }

    //---------------------------------------------------------------------
    ::rtl::OUString SAL_CALL OAttribListMerger::getTypeByIndex( sal_Int16 i ) throw(RuntimeException)
    {
        Reference< sax::XAttributeList > xSubList;
        sal_Int16 nLocalIndex;

        if (!seekToIndex(i, xSubList, nLocalIndex))
            return ::rtl::OUString();

        return xSubList->getTypeByIndex(nLocalIndex);
    }

    //---------------------------------------------------------------------
    ::rtl::OUString SAL_CALL OAttribListMerger::getTypeByName( const ::rtl::OUString& _rName ) throw(RuntimeException)
    {
        Reference< sax::XAttributeList > xSubList;
        sal_Int16 nLocalIndex;

        if (!seekToName(_rName, xSubList, nLocalIndex))
            return ::rtl::OUString();

        // though we're in getTypeByName here, we reroute this to the getTypeByIndex of the sub list,
        // assuming that this is faster
        return xSubList->getTypeByIndex(nLocalIndex);
    }

    //---------------------------------------------------------------------
    ::rtl::OUString SAL_CALL OAttribListMerger::getValueByIndex( sal_Int16 i ) throw(RuntimeException)
    {
        Reference< sax::XAttributeList > xSubList;
        sal_Int16 nLocalIndex;

        if (!seekToIndex(i, xSubList, nLocalIndex))
            return ::rtl::OUString();

        return xSubList->getValueByIndex(nLocalIndex);
    }

    //---------------------------------------------------------------------
    ::rtl::OUString SAL_CALL OAttribListMerger::getValueByName( const ::rtl::OUString& _rName ) throw(RuntimeException)
    {
        Reference< sax::XAttributeList > xSubList;
        sal_Int16 nLocalIndex;

        if (!seekToName(_rName, xSubList, nLocalIndex))
            return ::rtl::OUString();

        // though we're in getValueByName here, we reroute this to the getValueByIndex of the sub list,
        // assuming that this is faster
        return xSubList->getValueByIndex(nLocalIndex);
    }

//.........................................................................
}   // namespace xmloff
//.........................................................................

<commit_msg>INTEGRATION: CWS changefileheader (1.6.290); FILE MERGED 2008/04/01 13:04:48 thb 1.6.290.2: #i85898# Stripping all external header guards 2008/03/31 16:28:11 rt 1.6.290.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: attriblistmerge.cxx,v $
 * $Revision: 1.7 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_xmloff.hxx"
#include "attriblistmerge.hxx"

//.........................................................................
namespace xmloff
{
//.........................................................................

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::xml;

    //=====================================================================
    //= OAttribListMerger
    //=====================================================================
    //---------------------------------------------------------------------
    void OAttribListMerger::addList(const Reference< sax::XAttributeList >& _rxList)
    {
        OSL_ENSURE(_rxList.is(), "OAttribListMerger::addList: invalid list!");
        if (_rxList.is())
            m_aLists.push_back(_rxList);
    }

    //---------------------------------------------------------------------
    sal_Bool OAttribListMerger::seekToIndex(sal_Int16 _nGlobalIndex, Reference< sax::XAttributeList >& _rSubList, sal_Int16& _rLocalIndex)
    {
        sal_Int16 nLeftOver = _nGlobalIndex;
        ConstAttributeListArrayIterator aLookupSublist = m_aLists.begin();

        for ( ; (aLookupSublist != m_aLists.end()) && (nLeftOver >= (*aLookupSublist)->getLength());
                ++aLookupSublist
            )
            nLeftOver = nLeftOver - (*aLookupSublist)->getLength();

        if (aLookupSublist == m_aLists.end())
        {
            OSL_ENSURE(sal_False, "OAttribListMerger::seekToIndex: invalid index!");
            return sal_False;
        }
        _rSubList = *aLookupSublist;
        _rLocalIndex = nLeftOver;
        return sal_True;
    }

    //---------------------------------------------------------------------
    sal_Bool OAttribListMerger::seekToName(const ::rtl::OUString& _rName, Reference< sax::XAttributeList >& _rSubList, sal_Int16& _rLocalIndex)
    {
        for (   ConstAttributeListArrayIterator aLookupSublist = m_aLists.begin();
                aLookupSublist != m_aLists.end();
                ++aLookupSublist
            )
            for (sal_Int16 i=0; i<(*aLookupSublist)->getLength(); ++i)
                if ((*aLookupSublist)->getNameByIndex(i) == _rName)
                {
                    _rSubList = *aLookupSublist;
                    _rLocalIndex = i;
                    return sal_True;
                }

        OSL_ENSURE(sal_False, "OAttribListMerger::seekToName: did not find the name!");
        return sal_False;
    }

    //---------------------------------------------------------------------
    sal_Int16 SAL_CALL OAttribListMerger::getLength(  ) throw(RuntimeException)
    {
        sal_Int16 nCount = 0;
        for (   ConstAttributeListArrayIterator aAccumulate = m_aLists.begin();
                aAccumulate != m_aLists.end();
                ++aAccumulate
            )
            nCount = nCount + (*aAccumulate)->getLength();
        return nCount;
    }

    //---------------------------------------------------------------------
    ::rtl::OUString SAL_CALL OAttribListMerger::getNameByIndex( sal_Int16 i ) throw(RuntimeException)
    {
        Reference< sax::XAttributeList > xSubList;
        sal_Int16 nLocalIndex;

        if (!seekToIndex(i, xSubList, nLocalIndex))
            return ::rtl::OUString();

        return xSubList->getNameByIndex(nLocalIndex);
    }

    //---------------------------------------------------------------------
    ::rtl::OUString SAL_CALL OAttribListMerger::getTypeByIndex( sal_Int16 i ) throw(RuntimeException)
    {
        Reference< sax::XAttributeList > xSubList;
        sal_Int16 nLocalIndex;

        if (!seekToIndex(i, xSubList, nLocalIndex))
            return ::rtl::OUString();

        return xSubList->getTypeByIndex(nLocalIndex);
    }

    //---------------------------------------------------------------------
    ::rtl::OUString SAL_CALL OAttribListMerger::getTypeByName( const ::rtl::OUString& _rName ) throw(RuntimeException)
    {
        Reference< sax::XAttributeList > xSubList;
        sal_Int16 nLocalIndex;

        if (!seekToName(_rName, xSubList, nLocalIndex))
            return ::rtl::OUString();

        // though we're in getTypeByName here, we reroute this to the getTypeByIndex of the sub list,
        // assuming that this is faster
        return xSubList->getTypeByIndex(nLocalIndex);
    }

    //---------------------------------------------------------------------
    ::rtl::OUString SAL_CALL OAttribListMerger::getValueByIndex( sal_Int16 i ) throw(RuntimeException)
    {
        Reference< sax::XAttributeList > xSubList;
        sal_Int16 nLocalIndex;

        if (!seekToIndex(i, xSubList, nLocalIndex))
            return ::rtl::OUString();

        return xSubList->getValueByIndex(nLocalIndex);
    }

    //---------------------------------------------------------------------
    ::rtl::OUString SAL_CALL OAttribListMerger::getValueByName( const ::rtl::OUString& _rName ) throw(RuntimeException)
    {
        Reference< sax::XAttributeList > xSubList;
        sal_Int16 nLocalIndex;

        if (!seekToName(_rName, xSubList, nLocalIndex))
            return ::rtl::OUString();

        // though we're in getValueByName here, we reroute this to the getValueByIndex of the sub list,
        // assuming that this is faster
        return xSubList->getValueByIndex(nLocalIndex);
    }

//.........................................................................
}   // namespace xmloff
//.........................................................................

<|endoftext|>


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

#define main __XX_main
#include "wpantund.cpp"

#include <poll.h>
#include <sys/select.h>
#include <sys/cdefs.h>
#include <unistd.h>
#include "util/SocketWrapper.h"

#define HDLC_BYTE_FLAG             0x7E
#define HDLC_BYTE_ESC              0x7D
#define HDLC_BYTE_XON              0x11
#define HDLC_BYTE_XOFF             0x13
#define HDLC_BYTE_SPECIAL          0xF8
#define HDLC_ESCAPE_XFORM          0x20

int
ConfigFileFuzzTarget(const uint8_t *data, size_t size) {
	std::map<std::string, std::string> settings;
	FILE *file = tmpfile();
	fwrite(data, 1, size, file);
	fflush(file);
	rewind(file);
	fread_config(file, &add_to_map, &settings);
	if (!settings.empty()) {
		std::map<std::string, std::string>::const_iterator iter;

		for(iter = settings.begin(); iter != settings.end(); iter++) {
			set_config_param(NULL, iter->first.c_str(), iter->second.c_str());
		}

		MainLoop main_loop(settings);
	}
	fclose(file);

	return 0;
}

void fuzz_trap() {
	sleep(1);
	abort();
}

#define FUZZ_SPECIAL_WAIT_FOR_FRAME			0
#define FUZZ_SPECIAL_FF_DECISECONDS			1

int
NCPInputFuzzTarget(const uint8_t *data, size_t size) {
	std::map<std::string, std::string> settings;

	int fd[2] = { -1, -1 };
	uint8_t data_out[100];
	uint32_t i = 0;
	const uint32_t max_iterations = 10000000;
	static const uint8_t hdlc_flag = HDLC_BYTE_FLAG;

	gRet = 0;

	if (socketpair(PF_UNIX, SOCK_STREAM, 0, fd) < 0) {
		syslog(LOG_ERR, "Call to socketpair() failed: %s (%d)", strerror(errno), errno);
		fuzz_trap();
	}

	{
		char *fd_string = NULL;

		if (0 >= asprintf(&fd_string, "fd:%d", fd[1])) {
			syslog(LOG_ERR, "Call to asprintf() failed: %s (%d)", strerror(errno), errno);
			fuzz_trap();
		}

		assert(fd_string != NULL);

		settings[kWPANTUNDProperty_ConfigNCPSocketPath] = fd_string;

		free(fd_string);
	}

	try {

#if VERBOSE_DEBUG
	settings[kWPANTUNDProperty_DaemonSyslogMask] = "all";
#elif DEBUG
	settings[kWPANTUNDProperty_DaemonSyslogMask] = "all -debug";
#endif

	MainLoop main_loop(settings);

	// wpantund dup'd the file descriptor we gave it,
	// so we should close this one here.
	close(fd[1]);
	fd[1] = -1;

	for (i = 0; (i < 10) && main_loop.block_until_ready(); i++) {
		main_loop.process();
	}
	main_loop.process();

	while (size > 0 && gRet == 0) {
		uint8_t c = *data++;
		size--;

		// Special command.
		if ((size > 0) && (c == HDLC_BYTE_SPECIAL)) {
			c = *data++;
			size--;

			if (c == FUZZ_SPECIAL_WAIT_FOR_FRAME) {
				for (i = 0; i < 5 && checkpoll(fd[0], POLLIN|POLLERR|POLLHUP) == 0; i++) {
					if (main_loop.block_until_ready()) {
						main_loop.process();
					} else {
						break;
					}
				}

				while (checkpoll(fd[0], POLLIN|POLLERR|POLLHUP) != 0 && gRet == 0) {
					ssize_t bytesread = read(fd[0], data_out, sizeof(data_out));
					if (bytesread <= 0) {
						syslog(LOG_WARNING, "Call to read() failed: %s (%d)", strerror(errno), errno);
						goto bail;
					}

					if (main_loop.block_until_ready()) {
						main_loop.process();
					} else {
						break;
					}
#if DEBUG
					fprintf(stderr, "NCPInputFuzzTarget: Got %lu bytes from wpantund\n", bytesread);
#endif
				}
				continue;
			} else if ((c == FUZZ_SPECIAL_FF_DECISECONDS) && (size > 0)) {
				c = *data++;
				size--;
				// Fast forward the given number of deciseconds
				fuzz_ff_cms(c * (MSEC_PER_SEC/10));
			}
		}

		while (checkpoll(fd[0], POLLOUT|POLLERR|POLLHUP) == 0 && gRet == 0) {
			main_loop.block_until_ready();
			main_loop.process();
		}

		ssize_t byteswritten = write(fd[0], &c, 1);
		if (byteswritten <= 0) {
			syslog(LOG_WARNING, "Call to write() failed: %s (%d)", strerror(errno), errno);
			goto bail;;
		}

		main_loop.block_until_ready();
		main_loop.process();
	}

	for (i = 0; (i < 10) && main_loop.block_until_ready(); i++) {
		main_loop.process();
	}
	main_loop.process();

	if (size != 0) {
		syslog(LOG_ERR, "Did not consume all data");
		fuzz_trap();
	}

	if (gRet != 0) {
		syslog(LOG_ERR, "gRet = %d", gRet);
		fuzz_trap();
	}

	} catch (nl::SocketError x) {
		// Ignore socket wrapper errors
	}

bail:
	close(fd[0]);
	close(fd[1]);
	return 0;
}

int
NCPControlInterfaceFuzzTarget(const uint8_t *data, size_t size) {
	// TODO: Write me!
	return 0;
}

extern "C" int
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
	static bool did_init;

	if (!did_init) {
		did_init = true;

#if DEBUG
		openlog("wpantund-fuzz", LOG_PERROR, LOG_DAEMON);
#endif
		signal(SIGPIPE, SIG_IGN);
	}

	if (size >= 1) {
		char type = *data++;
		size--;
		switch (type) {
		case '0': // Config file fuzzing
			return ConfigFileFuzzTarget(data, size);
			break;

		case '1': // NCP Input fuzzing
			return NCPInputFuzzTarget(data, size);
			break;

		case '2': // NCPControlInterface fuzzing
			return NCPControlInterfaceFuzzTarget(data, size);
			break;

		default:
			break;
		}
	}

	return 0;
}
<commit_msg>wpantund-fuzz: Ignore SocketError exceptions.<commit_after>/*
 * Copyright (c) 2017 Nest Labs, Inc.
 * All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *    Description:
 *		This file implements the wpantund fuzzer.
 *
 */

#define main __XX_main
#include "wpantund.cpp"

#include <poll.h>
#include <sys/select.h>
#include <sys/cdefs.h>
#include <unistd.h>
#include "util/SocketWrapper.h"

#define HDLC_BYTE_FLAG             0x7E
#define HDLC_BYTE_ESC              0x7D
#define HDLC_BYTE_XON              0x11
#define HDLC_BYTE_XOFF             0x13
#define HDLC_BYTE_SPECIAL          0xF8
#define HDLC_ESCAPE_XFORM          0x20

int
ConfigFileFuzzTarget(const uint8_t *data, size_t size) {
	std::map<std::string, std::string> settings;
	FILE *file = tmpfile();

	fwrite(data, 1, size, file);
	fflush(file);
	rewind(file);
	fread_config(file, &add_to_map, &settings);
	fclose(file);

	if (!settings.empty()) {
		std::map<std::string, std::string>::const_iterator iter;

		for(iter = settings.begin(); iter != settings.end(); iter++) {
			set_config_param(NULL, iter->first.c_str(), iter->second.c_str());
		}

		try {
			MainLoop main_loop(settings);
		} catch (nl::SocketError x) {
			// Ignore socket errors
		}
	}

	return 0;
}

void fuzz_trap() {
	sleep(1);
	abort();
}

#define FUZZ_SPECIAL_WAIT_FOR_FRAME			0
#define FUZZ_SPECIAL_FF_DECISECONDS			1

int
NCPInputFuzzTarget(const uint8_t *data, size_t size) {
	std::map<std::string, std::string> settings;

	int fd[2] = { -1, -1 };
	uint8_t data_out[100];
	uint32_t i = 0;
	const uint32_t max_iterations = 10000000;
	static const uint8_t hdlc_flag = HDLC_BYTE_FLAG;

	gRet = 0;

	if (socketpair(PF_UNIX, SOCK_STREAM, 0, fd) < 0) {
		syslog(LOG_ERR, "Call to socketpair() failed: %s (%d)", strerror(errno), errno);
		fuzz_trap();
	}

	{
		char *fd_string = NULL;

		if (0 >= asprintf(&fd_string, "fd:%d", fd[1])) {
			syslog(LOG_ERR, "Call to asprintf() failed: %s (%d)", strerror(errno), errno);
			fuzz_trap();
		}

		assert(fd_string != NULL);

		settings[kWPANTUNDProperty_ConfigNCPSocketPath] = fd_string;

		free(fd_string);
	}

	try {

#if VERBOSE_DEBUG
	settings[kWPANTUNDProperty_DaemonSyslogMask] = "all";
#elif DEBUG
	settings[kWPANTUNDProperty_DaemonSyslogMask] = "all -debug";
#endif

	MainLoop main_loop(settings);

	// wpantund dup'd the file descriptor we gave it,
	// so we should close this one here.
	close(fd[1]);
	fd[1] = -1;

	for (i = 0; (i < 10) && main_loop.block_until_ready(); i++) {
		main_loop.process();
	}
	main_loop.process();

	while (size > 0 && gRet == 0) {
		uint8_t c = *data++;
		size--;

		// Special command.
		if ((size > 0) && (c == HDLC_BYTE_SPECIAL)) {
			c = *data++;
			size--;

			if (c == FUZZ_SPECIAL_WAIT_FOR_FRAME) {
				for (i = 0; i < 5 && checkpoll(fd[0], POLLIN|POLLERR|POLLHUP) == 0; i++) {
					if (main_loop.block_until_ready()) {
						main_loop.process();
					} else {
						break;
					}
				}

				while (checkpoll(fd[0], POLLIN|POLLERR|POLLHUP) != 0 && gRet == 0) {
					ssize_t bytesread = read(fd[0], data_out, sizeof(data_out));
					if (bytesread <= 0) {
						syslog(LOG_WARNING, "Call to read() failed: %s (%d)", strerror(errno), errno);
						goto bail;
					}

					if (main_loop.block_until_ready()) {
						main_loop.process();
					} else {
						break;
					}
#if DEBUG
					fprintf(stderr, "NCPInputFuzzTarget: Got %lu bytes from wpantund\n", bytesread);
#endif
				}
				continue;
			} else if ((c == FUZZ_SPECIAL_FF_DECISECONDS) && (size > 0)) {
				c = *data++;
				size--;
				// Fast forward the given number of deciseconds
				fuzz_ff_cms(c * (MSEC_PER_SEC/10));
			}
		}

		while (checkpoll(fd[0], POLLOUT|POLLERR|POLLHUP) == 0 && gRet == 0) {
			main_loop.block_until_ready();
			main_loop.process();
		}

		ssize_t byteswritten = write(fd[0], &c, 1);
		if (byteswritten <= 0) {
			syslog(LOG_WARNING, "Call to write() failed: %s (%d)", strerror(errno), errno);
			goto bail;;
		}

		main_loop.block_until_ready();
		main_loop.process();
	}

	for (i = 0; (i < 10) && main_loop.block_until_ready(); i++) {
		main_loop.process();
	}
	main_loop.process();

	if (size != 0) {
		syslog(LOG_ERR, "Did not consume all data");
		fuzz_trap();
	}

	if (gRet != 0) {
		syslog(LOG_ERR, "gRet = %d", gRet);
		fuzz_trap();
	}

	} catch (nl::SocketError x) {
		// Ignore socket wrapper errors
	}

bail:
	close(fd[0]);
	close(fd[1]);
	return 0;
}

int
NCPControlInterfaceFuzzTarget(const uint8_t *data, size_t size) {
	// TODO: Write me!
	return 0;
}

extern "C" int
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
	static bool did_init;

	if (!did_init) {
		did_init = true;

#if DEBUG
		openlog("wpantund-fuzz", LOG_PERROR, LOG_DAEMON);
#endif
		signal(SIGPIPE, SIG_IGN);
	}

	if (size >= 1) {
		char type = *data++;
		size--;
		switch (type) {
		case '0': // Config file fuzzing
			return ConfigFileFuzzTarget(data, size);
			break;

		case '1': // NCP Input fuzzing
			return NCPInputFuzzTarget(data, size);
			break;

		case '2': // NCPControlInterface fuzzing
			return NCPControlInterfaceFuzzTarget(data, size);
			break;

		default:
			break;
		}
	}

	return 0;
}
<|endoftext|>