<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: vclchartprocessor2d.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: aw $ $Date: 2008-03-13 08:22:03 $
 *
 *  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_drawinglayer.hxx"

#include <drawinglayer/processor2d/vclprocessor2d.hxx>
#include <drawinglayer/primitive2d/chartprimitive2d.hxx>
#include <svtools/chartprettypainter.hxx>
#include <com/sun/star/lang/XUnoTunnel.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <drawinglayer/processor2d/vclpixelprocessor2d.hxx>

//////////////////////////////////////////////////////////////////////////////

using namespace com::sun::star;

//////////////////////////////////////////////////////////////////////////////

namespace drawinglayer
{
    namespace processor2d
    {
        void VclProcessor2D::RenderChartPrimitive2D(const primitive2d::ChartPrimitive2D& rChartCandidate)
        {
            bool bChartRendered(false);

            // code from chart PrettyPrinter
            try
            {
                uno::Reference< lang::XMultiServiceFactory > xFact( rChartCandidate.getChartModel(), uno::UNO_QUERY );
                OSL_ENSURE( xFact.is(), "Chart cannot be painted pretty!\n" );

                if( xFact.is() )
                {
                    uno::Reference< lang::XUnoTunnel > xChartRenderer( xFact->createInstance(
                        ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart2.ChartRenderer" ) ) ), uno::UNO_QUERY );
                    OSL_ENSURE( xChartRenderer.is(), "Chart cannot be painted pretty!\n" );

                    if( xChartRenderer.is() )
                    {
                        ChartPrettyPainter* pPrettyPainter = reinterpret_cast<ChartPrettyPainter*>(
                            xChartRenderer->getSomething( ChartPrettyPainter::getUnoTunnelId() ));

                        if( pPrettyPainter )
                        {
                            // create logic object range
                            basegfx::B2DRange aObjectRange(0.0, 0.0, 1.0, 1.0);
                            aObjectRange.transform(rChartCandidate.getTransformation());
                            const Rectangle aRectangle(
                                    (sal_Int32)aObjectRange.getMinX(), (sal_Int32)aObjectRange.getMinY(),
                                    (sal_Int32)aObjectRange.getMaxX(), (sal_Int32)aObjectRange.getMaxY());

                            bChartRendered = pPrettyPainter->DoPaint(mpOutputDevice, aRectangle);
                        }
                    }
                }
            }
            catch( uno::Exception& e )
            {
                (void)e;
                DBG_ERROR( "Chart cannot be painted pretty!" );
            }

            if(!bChartRendered)
            {
                // fallback to decompositopn (MetaFile)
                process(rChartCandidate.get2DDecomposition(getViewInformation2D()));
            }
        }
    } // end of namespace processor2d
} // end of namespace drawinglayer

//////////////////////////////////////////////////////////////////////////////
// eof
<commit_msg>#i10000# remove file<commit_after><|endoftext|>


<commit_before>#ifndef INCLUDE_AL_MATRIX4_HPP
#define INCLUDE_AL_MATRIX4_HPP

#include "math/al_Constants.hpp"
#include "math/al_Quat.hpp"
#include "math/al_Vec.hpp"

namespace al {

template<class T> class Matrix4;

/// 4x4 Matrix (Homogenous Transform)
template<typename T=double>
class Matrix4 : public Mat<4, T> {
public:
	typedef Mat<4, T> Base;

	Matrix4()
	: Base(
		1, 0, 0, 0,
		0, 1, 0, 0,
		0, 0, 1, 0,
		0, 0, 0, 1
	)
	{}

	Matrix4(
		const T& v11, const T& v21, const T& v31, const T& v41,
		const T& v12, const T& v22, const T& v32, const T& v42,
		const T& v13, const T& v23, const T& v33, const T& v43,
		const T& v14, const T& v24, const T& v34, const T& v44
	)
	:	Base(
			v11, v21, v31, v41,
			v12, v22, v32, v42,
			v13, v23, v33, v43,
			v14, v24, v34, v44
		)
	{}

	Matrix4(
		const Vec3<T>& xaxis,
		const Vec3<T>& yaxis,
		const Vec3<T>& zaxis,
		const Vec3<T>& position
	)
	:	Base(
			xaxis[0], xaxis[1], xaxis[2], 0,
			yaxis[0], yaxis[1], yaxis[2], 0,
			zaxis[0], zaxis[1], zaxis[2], 0,
			position[0], position[1], position[2], 1
		)
	{}

	Matrix4(const T * src)
	:	Base(src)
	{}

	Matrix4(const Base & src)
	:	Base(src)
	{}

	Matrix4& set(const Base & src) { Base::set(src.elems); return *this; }

	Quat<T>& toQuat() {
		Quat<T> q;
		q.fromMatrix(Base::elems);
		return q;
	}
	void fromQuat(Quat<T>& q) { q.toMatrix(Base::elems); }

	static const Matrix4 identity() {
		return Matrix4(
			1,	0,	0,	0,
			0,	1,	0,	0,
			0,	0,	1,	0,
			0,	0,	0,	1
		);
	}

	static const Matrix4 translate(T x, T y, T z) {
		return Matrix4(
			1, 0, 0, 0,
			0, 1, 0, 0,
			0, 0, 1, 0,
			x, y, z, 1
		);
	}

	static const Matrix4 scale(T x, T y, T z) {
		return Matrix4(
			x,	0,	0,	0,
			0,	y,	0,	0,
			0,	0,	z,	0,
			0,	0,	0,	1
		);
	}

	static const Matrix4 rotateYZ(T theta) {
		const T C = cos(theta);
		const T S = sin(theta);
		const T m[] = {	1,	0,	0,	0,
						0,	C,	-S,	0,
						0,	S,	C,	0,
						0,	0,	0,	1 };
		return Matrix4(m);
	}
	static const Matrix4 rotateZX(T theta) {
		const T C = cos(theta);
		const T S = sin(theta);
		const T m[] = {	C,	0,	S,	0,
						0,	1,	0,	0,
						-S,	0,	C,	0,
						0,	0,	0,	1 };
		return Matrix4(m);
	}
	static const Matrix4 rotateXY(T theta) {
		const T C = cos(theta);
		const T S = sin(theta);
		const T m[] = {	C,	-S,	0,	0,
						S,	C,	0,	0,
						0,	0,	1,	0,
						0,	0,	0,	1 };
		return Matrix4(m);
	}

	static const Matrix4 rotate(float angle, const Vec<3, T> &v) {
		Vec<3, T> axis(v);
		axis.normalize();

		float c = cos(angle*M_DEG2RAD);
		float s = sin(angle*M_DEG2RAD);

		Matrix4 m(
			axis[0]*axis[0]*(1-c)+c,
			axis[1]*axis[0]*(1-c)+axis[2]*s,
			axis[0]*axis[2]*(1-c)-axis[1]*s,
			0,

			axis[0]*axis[1]*(1-c)-axis[2]*s,
			axis[1]*axis[1]*(1-c)+c,
			axis[1]*axis[2]*(1-c)+axis[0]*s,
			0,

			axis[0]*axis[2]*(1-c)+axis[1]*s,
			axis[1]*axis[2]*(1-c)-axis[0]*s,
			axis[2]*axis[2]*(1-c)+c,
			0,

			0, 0, 0, 1
		);

		return m;
	}

	static const Matrix4 shearYZ(T y, T z) {
		const T m[] = {	1,	0,	0,	0,
						y,	1,	0,	0,
						z,	0,	1,	0,
						0,	0,	0,	1 };
		return Matrix4(m);
	}
	static const Matrix4 shearZX(T z, T x) {
		const T m[] = {	1,	x,	0,	0,
						0,	1,	0,	0,
						0,	z,	1,	0,
						0,	0,	0,	1 };
		return Matrix4(m);
	}
	static const Matrix4 shearXY(T x, T y) {
		const T m[] = {	1,	0,	x,	0,
						0,	1,	y,	0,
						0,	0,	1,	0,
						0,	0,	0,	1 };
		return Matrix4(m);
	}

	static const Matrix4 perspective(T fovy, T aspect, T near, T far) {
		float f = 1/tan(fovy*M_DEG2RAD/2.);
		return Matrix4(
			f/aspect, 0, 0, 0,
			0, f, 0, 0,
			0, 0, (far+near)/(near-far), -1,
			0, 0, (2*far*near)/(near-far), 0
		);
	}

	static const Matrix4 perspective(T l, T r, T b, T t, T n, T f) {
		const T W = r-l;	const T W2 = r+l;
		const T H = t-b;	const T H2 = t+b;
		const T D = f-n;	const T D2 = f+n;
		const T n2 = n*2;
		const T fn2 = f*n2;
		const T m[] = {	n2/W,	0,		W2/W,	0,
						0,		n2/H,	H2/H,	0,
						0,		0,		-D2/D,	-fn2/D,
						0,		0,		-1,		0 };
		return Matrix4(m);
	}

	static const Matrix4 unPerspective(T l, T r, T b, T t, T n, T f) {
		const T W = r-l;	const T W2 = r+l;
		const T H = t-b;	const T H2 = t+b;
		const T D = f-n;	const T D2 = f+n;
		const T n2 = n*2;
		const T fn2 = f*n2;
		const T m[] = {	W/n2,	0,		0,		W2/n2,
						0,		H/n2,	0,		H2/n2,
						0,		0,		0,		-1,
						0,		0,		-D/fn2,	D2/fn2 };
		return Matrix4(m);
	}

	static const Matrix4 ortho(T l, T r, T b, T t, T n, T f) {
		const T W = r-l;	const T W2 = r+l;
		const T H = t-b;	const T H2 = t+b;
		const T D = f-n;	const T D2 = f+n;
		const T m[] = {	2/W,	0,		0,		-W2/W,
						0,		2/H,	0,		-H2/H,
						0,		0,		-2/D,	-D2/D,
						0,		0,		0,		1 };
		return Matrix4(m);
	}

	static const Matrix4 unOrtho(T l, T r, T b, T t, T n, T f) {
		const T W = r-l;	const T W2 = r+l;
		const T H = t-b;	const T H2 = t+b;
		const T D = f-n;	const T D2 = f+n;
		const T m[] = {	W/2,	0,		0,		W2/2,
						0,		H/2,	0,		H2/2,
						0,		0,		D/-2,	D2/2,
						0,		0,		0,		1 };
		return Matrix4(m);
	}

	static const Matrix4 lookAt(const Vec3d& ux, const Vec3d& uz, const Vec3d& uy, const Vec3d& pos) {
		return Matrix4(
			ux[0], uy[0], -uz[0], 0,
			ux[1], uy[1], -uz[1], 0,
			ux[2], uy[2], -uz[2], 0,
			-(ux.dot(pos)), -(uy.dot(pos)), (uz.dot(pos)), 1
		);
	}

};

typedef Matrix4<double>	Matrix4d;	///< Double-precision quaternion
typedef Matrix4<float>	Matrix4f;	///< Single-precision quaternion

} // al::

#endif /* include guard */
<commit_msg>more perspective/modelview constructors for Matrix4d<commit_after>#ifndef INCLUDE_AL_MATRIX4_HPP
#define INCLUDE_AL_MATRIX4_HPP

#include "math/al_Constants.hpp"
#include "math/al_Quat.hpp"
#include "math/al_Vec.hpp"

namespace al {

template<class T> class Matrix4;

/// 4x4 Matrix (Homogenous Transform)
template<typename T=double>
class Matrix4 : public Mat<4, T> {
public:
	typedef Mat<4, T> Base;

	Matrix4()
	: Base(
		1, 0, 0, 0,
		0, 1, 0, 0,
		0, 0, 1, 0,
		0, 0, 0, 1
	)
	{}

	Matrix4(
		const T& v11, const T& v21, const T& v31, const T& v41,
		const T& v12, const T& v22, const T& v32, const T& v42,
		const T& v13, const T& v23, const T& v33, const T& v43,
		const T& v14, const T& v24, const T& v34, const T& v44
	)
	:	Base(
			v11, v21, v31, v41,
			v12, v22, v32, v42,
			v13, v23, v33, v43,
			v14, v24, v34, v44
		)
	{}

	Matrix4(
		const Vec3<T>& xaxis,
		const Vec3<T>& yaxis,
		const Vec3<T>& zaxis,
		const Vec3<T>& position
	)
	:	Base(
			xaxis[0], xaxis[1], xaxis[2], 0,
			yaxis[0], yaxis[1], yaxis[2], 0,
			zaxis[0], zaxis[1], zaxis[2], 0,
			position[0], position[1], position[2], 1
		)
	{}

	Matrix4(const T * src)
	:	Base(src)
	{}

	Matrix4(const Base & src)
	:	Base(src)
	{}

	Matrix4& set(const Base & src) { Base::set(src.elems); return *this; }

	Quat<T>& toQuat() {
		Quat<T> q;
		q.fromMatrix(Base::elems);
		return q;
	}
	void fromQuat(Quat<T>& q) { q.toMatrix(Base::elems); }

	static const Matrix4 identity() {
		return Matrix4(
			1,	0,	0,	0,
			0,	1,	0,	0,
			0,	0,	1,	0,
			0,	0,	0,	1
		);
	}

	static const Matrix4 translate(T x, T y, T z) {
		return Matrix4(
			1, 0, 0, 0,
			0, 1, 0, 0,
			0, 0, 1, 0,
			x, y, z, 1
		);
	}

	static const Matrix4 scale(T x, T y, T z) {
		return Matrix4(
			x,	0,	0,	0,
			0,	y,	0,	0,
			0,	0,	z,	0,
			0,	0,	0,	1
		);
	}

	static const Matrix4 rotateYZ(T theta) {
		const T C = cos(theta);
		const T S = sin(theta);
		const T m[] = {	1,	0,	0,	0,
						0,	C,	-S,	0,
						0,	S,	C,	0,
						0,	0,	0,	1 };
		return Matrix4(m);
	}
	static const Matrix4 rotateZX(T theta) {
		const T C = cos(theta);
		const T S = sin(theta);
		const T m[] = {	C,	0,	S,	0,
						0,	1,	0,	0,
						-S,	0,	C,	0,
						0,	0,	0,	1 };
		return Matrix4(m);
	}
	static const Matrix4 rotateXY(T theta) {
		const T C = cos(theta);
		const T S = sin(theta);
		const T m[] = {	C,	-S,	0,	0,
						S,	C,	0,	0,
						0,	0,	1,	0,
						0,	0,	0,	1 };
		return Matrix4(m);
	}

	static const Matrix4 rotate(float angle, const Vec<3, T> &v) {
		Vec<3, T> axis(v);
		axis.normalize();

		float c = cos(angle*M_DEG2RAD);
		float s = sin(angle*M_DEG2RAD);

		Matrix4 m(
			axis[0]*axis[0]*(1-c)+c,
			axis[1]*axis[0]*(1-c)+axis[2]*s,
			axis[0]*axis[2]*(1-c)-axis[1]*s,
			0,

			axis[0]*axis[1]*(1-c)-axis[2]*s,
			axis[1]*axis[1]*(1-c)+c,
			axis[1]*axis[2]*(1-c)+axis[0]*s,
			0,

			axis[0]*axis[2]*(1-c)+axis[1]*s,
			axis[1]*axis[2]*(1-c)-axis[0]*s,
			axis[2]*axis[2]*(1-c)+c,
			0,

			0, 0, 0, 1
		);

		return m;
	}

	static const Matrix4 shearYZ(T y, T z) {
		const T m[] = {	1,	0,	0,	0,
						y,	1,	0,	0,
						z,	0,	1,	0,
						0,	0,	0,	1 };
		return Matrix4(m);
	}
	static const Matrix4 shearZX(T z, T x) {
		const T m[] = {	1,	x,	0,	0,
						0,	1,	0,	0,
						0,	z,	1,	0,
						0,	0,	0,	1 };
		return Matrix4(m);
	}
	static const Matrix4 shearXY(T x, T y) {
		const T m[] = {	1,	0,	x,	0,
						0,	1,	y,	0,
						0,	0,	1,	0,
						0,	0,	0,	1 };
		return Matrix4(m);
	}

	static const Matrix4 perspective(T fovy, T aspect, T near, T far) {
		float f = 1/tan(fovy*M_DEG2RAD/2.);
		return Matrix4(
			f/aspect, 0, 0, 0,
			0, f, 0, 0,
			0, 0, (far+near)/(near-far), -1,
			0, 0, (2*far*near)/(near-far), 0
		);
	}

	// for stereographics:
	static const Matrix4 perspectiveLeft(T fovy, T aspect, T near, T far, T eyeSep, T focal) {
		T D = 0.5*eyeSep*near/focal;				// stereo eye separation adjustment
		T top = near * tan(fovy*M_DEG2RAD*0.5);	// height of view at distance = near
		T bottom = -top;
		T left = -aspect*top + D;
		T right = aspect*top + D;
		return perspective(left, right, bottom, top, near, far);
	}

	// for stereographics:
	static const Matrix4 perspectiveRight(T fovy, T aspect, T near, T far, T eyeSep, T focal) {
		T D = -0.5*eyeSep*near/focal;				// stereo eye separation adjustment
		T top = near * tan(fovy*M_DEG2RAD*0.5);	// height of view at distance = near
		T bottom = -top;
		T left = -aspect*top + D;
		T right = aspect*top + D;
		return perspective(left, right, bottom, top, near, far);
	}

	static const Matrix4 perspective(T l, T r, T b, T t, T n, T f) {
		const T W = r-l;	const T W2 = r+l;
		const T H = t-b;	const T H2 = t+b;
		const T D = f-n;	const T D2 = f+n;
		const T n2 = n*2;
		const T fn2 = f*n2;
		const T m[] = {	n2/W,	0,		W2/W,	0,
						0,		n2/H,	H2/H,	0,
						0,		0,		-D2/D,	-fn2/D,
						0,		0,		-1,		0 };
		return Matrix4(m);
	}

	static const Matrix4 unPerspective(T l, T r, T b, T t, T n, T f) {
		const T W = r-l;	const T W2 = r+l;
		const T H = t-b;	const T H2 = t+b;
		const T D = f-n;	const T D2 = f+n;
		const T n2 = n*2;
		const T fn2 = f*n2;
		const T m[] = {	W/n2,	0,		0,		W2/n2,
						0,		H/n2,	0,		H2/n2,
						0,		0,		0,		-1,
						0,		0,		-D/fn2,	D2/fn2 };
		return Matrix4(m);
	}

	static const Matrix4 ortho(T l, T r, T b, T t, T n, T f) {
		const T W = r-l;	const T W2 = r+l;
		const T H = t-b;	const T H2 = t+b;
		const T D = f-n;	const T D2 = f+n;
		const T m[] = {	2/W,	0,		0,		-W2/W,
						0,		2/H,	0,		-H2/H,
						0,		0,		-2/D,	-D2/D,
						0,		0,		0,		1 };
		return Matrix4(m);
	}

	static const Matrix4 unOrtho(T l, T r, T b, T t, T n, T f) {
		const T W = r-l;	const T W2 = r+l;
		const T H = t-b;	const T H2 = t+b;
		const T D = f-n;	const T D2 = f+n;
		const T m[] = {	W/2,	0,		0,		W2/2,
						0,		H/2,	0,		H2/2,
						0,		0,		D/-2,	D2/2,
						0,		0,		0,		1 };
		return Matrix4(m);
	}

	static const Matrix4 lookAt(const Vec3<T>& ux, const Vec3<T>& uz, const Vec3<T>& uy, const Vec3<T>& pos) {
		return Matrix4(
			ux[0], uy[0], -uz[0], 0,
			ux[1], uy[1], -uz[1], 0,
			ux[2], uy[2], -uz[2], 0,
			-(ux.dot(pos)), -(uy.dot(pos)), (uz.dot(pos)), 1
		);
	}

	// for stereographics:
	static const Matrix4 lookAtLeft(const Vec3<T>& ux, const Vec3<T>& uz, const Vec3<T>& uy, const Vec3<T>& pos, double eyeSep) {
		Vec3<T> eyePos = pos - (ux * eyeSep);

		return Matrix4(
			ux[0], uy[0], -uz[0], 0,
			ux[1], uy[1], -uz[1], 0,
			ux[2], uy[2], -uz[2], 0,
			-(ux.dot(eyePos)), -(uy.dot(eyePos)), (uz.dot(eyePos)), 1
		);
	}
	static const Matrix4 lookAtRight(const Vec3<T>& ux, const Vec3<T>& uz, const Vec3<T>& uy, const Vec3<T>& pos, double eyeSep) {
		Vec3<T> eyePos = pos + (ux * eyeSep);

		return Matrix4(
			ux[0], uy[0], -uz[0], 0,
			ux[1], uy[1], -uz[1], 0,
			ux[2], uy[2], -uz[2], 0,
			-(ux.dot(eyePos)), -(uy.dot(eyePos)), (uz.dot(eyePos)), 1
		);
	}

};

typedef Matrix4<double>	Matrix4d;	///< Double-precision quaternion
typedef Matrix4<float>	Matrix4f;	///< Single-precision quaternion

} // al::

#endif /* include guard */
<|endoftext|>


<commit_before>/*

Copyright (c) 2009, Arvid Norberg
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 the author nor the names of its
      contributors 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.

*/

#ifndef TORRENT_DEADLINE_TIMER_HPP_INCLUDED
#define TORRENT_DEADLINE_TIMER_HPP_INCLUDED

#ifdef __OBJC__
#define Protocol Protocol_
#endif

#if BOOST_VERSION < 103500
#include <asio/basic_deadline_timer.hpp>
#include <asio/time_traits.hpp>
#else
#include <boost/asio/basic_deadline_timer.hpp>
#include <boost/asio/time_traits.hpp>
#endif

#ifdef __OBJC__
#undef Protocol
#endif

#include "libtorrent/time.hpp"

// asio time_traits
#if BOOST_VERSION >= 103500
namespace boost {
#endif
namespace asio
{
	template<>
	struct time_traits<libtorrent::ptime>
	{
		typedef libtorrent::ptime time_type;
		typedef libtorrent::time_duration duration_type;
		static time_type now()
		{ return time_type(libtorrent::time_now_hires()); }
		static time_type add(time_type t, duration_type d)
		{ return time_type(t.time + d.diff);}
		static duration_type subtract(time_type t1, time_type t2)
		{ return duration_type(t1 - t2); }
		static bool less_than(time_type t1, time_type t2)
		{ return t1 < t2; }
		static boost::posix_time::time_duration to_posix_duration(
			duration_type d)
		{ return boost::posix_time::microseconds(libtorrent::total_microseconds(d)); }
	};
}
#if BOOST_VERSION >= 103500
}
#endif

namespace libtorrent
{

#if BOOST_VERSION < 103500
	typedef ::asio::basic_deadline_timer<libtorrent::ptime> deadline_timer;
#else
	typedef boost::asio::basic_deadline_timer<libtorrent::ptime> deadline_timer;
#endif
}

#endif // TORRENT_DEADLINE_TIMER_HPP_INCLUDED

<commit_msg>USE_BOOST_DATE_TIME fix<commit_after>/*

Copyright (c) 2009, Arvid Norberg
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 the author nor the names of its
      contributors 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.

*/

#ifndef TORRENT_DEADLINE_TIMER_HPP_INCLUDED
#define TORRENT_DEADLINE_TIMER_HPP_INCLUDED

#ifdef __OBJC__
#define Protocol Protocol_
#endif

#if BOOST_VERSION < 103500
#include <asio/basic_deadline_timer.hpp>
#include <asio/time_traits.hpp>
#else
#include <boost/asio/basic_deadline_timer.hpp>
#include <boost/asio/time_traits.hpp>
#endif

#ifdef __OBJC__
#undef Protocol
#endif

#include "libtorrent/time.hpp"

// asio time_traits
#if !TORRENT_USE_BOOST_DATE_TIME
#if BOOST_VERSION >= 103500
namespace boost {
#endif
namespace asio
{
	template<>
	struct time_traits<libtorrent::ptime>
	{
		typedef libtorrent::ptime time_type;
		typedef libtorrent::time_duration duration_type;
		static time_type now()
		{ return time_type(libtorrent::time_now_hires()); }
		static time_type add(time_type t, duration_type d)
		{ return time_type(t.time + d.diff);}
		static duration_type subtract(time_type t1, time_type t2)
		{ return duration_type(t1 - t2); }
		static bool less_than(time_type t1, time_type t2)
		{ return t1 < t2; }
		static boost::posix_time::time_duration to_posix_duration(
			duration_type d)
		{ return boost::posix_time::microseconds(libtorrent::total_microseconds(d)); }
	};
}
#if BOOST_VERSION >= 103500
}
#endif
#endif

namespace libtorrent
{

#if BOOST_VERSION < 103500
	typedef ::asio::basic_deadline_timer<libtorrent::ptime> deadline_timer;
#else
	typedef boost::asio::basic_deadline_timer<libtorrent::ptime> deadline_timer;
#endif
}

#endif // TORRENT_DEADLINE_TIMER_HPP_INCLUDED

<|endoftext|>


<commit_before>#pragma once

#include <iterator>

namespace helene
{

template <class IteratorCategory, class IteratorToStruct, class MemberType>
class member_iterator_base;

template <class IteratorToStruct, class MemberType>
class member_iterator_base<std::input_iterator_tag,
                           IteratorToStruct,
                           MemberType>
{
public:
    member_iterator_base(IteratorToStruct it) : current_(it)
    {
    }

    bool
    operator!=(const member_iterator_base& other) const
    {
        return current_ != other.current_;
    }

protected:
    IteratorToStruct current_;
};

template <class IteratorToStruct, class MemberType>
class member_iterator_base<std::forward_iterator_tag,
                           IteratorToStruct,
                           MemberType>
    : public member_iterator_base<std::input_iterator_tag,
                                  IteratorToStruct,
                                  MemberType>
{
public:
    using member_iterator_base<std::input_iterator_tag,
                               IteratorToStruct,
                               MemberType>::member_iterator_base;
};

/*
template <class IteratorToStruct>
class member_iterator_base<std::random_access_iterator_tag, IteratorToStruct>
{
public:
    member_iterator_base(IteratorToStruct it) : current_(it)
    {
    }

protected:
    IteratorToStruct current_;
};
*/

template <class MemberType,
          class StructType,
          class IteratorToStruct,
          MemberType StructType::*PtrValue>
class member_iterator
    : public member_iterator_base<
          typename std::iterator_traits<IteratorToStruct>::iterator_category,
          IteratorToStruct,
          MemberType>
{
public:
    // using base class constructor directly
    using member_iterator_base<
        typename std::iterator_traits<IteratorToStruct>::iterator_category,
        IteratorToStruct,
        MemberType>::member_iterator_base;

};
}
<commit_msg>Remove member_iterator_base for random access iterator for now. 	modified:   include/member_iterator.hpp<commit_after>#pragma once

#include <iterator>

namespace helene
{

template <class IteratorCategory, class IteratorToStruct, class MemberType>
class member_iterator_base;

template <class IteratorToStruct, class MemberType>
class member_iterator_base<std::input_iterator_tag,
                           IteratorToStruct,
                           MemberType>
{
public:
    member_iterator_base(IteratorToStruct it) : current_(it)
    {
    }

    bool
    operator!=(const member_iterator_base& other) const
    {
        return current_ != other.current_;
    }

protected:
    IteratorToStruct current_;
};

template <class IteratorToStruct, class MemberType>
class member_iterator_base<std::forward_iterator_tag,
                           IteratorToStruct,
                           MemberType>
    : public member_iterator_base<std::input_iterator_tag,
                                  IteratorToStruct,
                                  MemberType>
{
public:
    using member_iterator_base<std::input_iterator_tag,
                               IteratorToStruct,
                               MemberType>::member_iterator_base;
};

template <class MemberType,
          class StructType,
          class IteratorToStruct,
          MemberType StructType::*PtrValue>
class member_iterator
    : public member_iterator_base<
          typename std::iterator_traits<IteratorToStruct>::iterator_category,
          IteratorToStruct,
          MemberType>
{
public:
    // using base class constructor directly
    using member_iterator_base<
        typename std::iterator_traits<IteratorToStruct>::iterator_category,
        IteratorToStruct,
        MemberType>::member_iterator_base;

};
}
<|endoftext|>


<commit_before>/*

Copyright (c) 2007, Arvid Norberg
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 the author nor the names of its
      contributors 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.

*/

#ifdef TORRENT_DISK_STATS
#include <fstream>
#endif

#include "libtorrent/storage.hpp"
#include <boost/thread/thread.hpp>
#include <boost/function.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/bind.hpp>
#include <boost/pool/pool.hpp>
#include <boost/noncopyable.hpp>
#include "libtorrent/config.hpp"

namespace libtorrent
{

	struct disk_io_job
	{
		disk_io_job()
			: action(read)
			, buffer(0)
			, buffer_size(0)
			, piece(0)
			, offset(0)
			, priority(0)
		{}

		enum action_t
		{
			read
			, write
			, hash
			, move_storage
			, release_files
			, delete_files
		};

		action_t action;

		char* buffer;
		size_type buffer_size;
		boost::intrusive_ptr<piece_manager> storage;
		// arguments used for read and write
		int piece, offset;
		// used for move_storage. On errors, this is set
		// to the error message
		std::string str;

		// priority decides whether or not this
		// job will skip entries in the queue or
		// not. It always skips in front of entries
		// with lower priority
		int priority;

		// this is called when operation completes
		boost::function<void(int, disk_io_job const&)> callback;
	};

	// this is a singleton consisting of the thread and a queue
	// of disk io jobs
	struct disk_io_thread : boost::noncopyable
	{
		disk_io_thread(int block_size = 16 * 1024);
		~disk_io_thread();

#ifdef TORRENT_STATS
		int disk_allocations() const
		{ return m_allocations; }
#endif

		// aborts read operations
		void stop(boost::intrusive_ptr<piece_manager> s);
		void add_job(disk_io_job const& j
			, boost::function<void(int, disk_io_job const&)> const& f
			= boost::function<void(int, disk_io_job const&)>());

#ifndef NDEBUG
		disk_io_job find_job(boost::intrusive_ptr<piece_manager> s
			, int action, int piece) const;
#endif
		// keep track of the number of bytes in the job queue
		// at any given time. i.e. the sum of all buffer_size.
		// this is used to slow down the download global download
		// speed when the queue buffer size is too big.
		size_type queue_buffer_size() const
		{ return m_queue_buffer_size; }

		void operator()();

		char* allocate_buffer();
		void free_buffer(char* buf);

	private:

		typedef boost::recursive_mutex mutex_t;
		mutable mutex_t m_mutex;
		boost::condition m_signal;
		bool m_abort;
		std::deque<disk_io_job> m_jobs;
		size_type m_queue_buffer_size;

		// memory pool for read and write operations
		boost::pool<> m_pool;

#ifndef NDEBUG
		int m_block_size;
		disk_io_job m_current;
#endif

#ifdef TORRENT_DISK_STATS
		std::ofstream m_log;
#endif
#ifdef TORRENT_STATS
		int m_allocations;
#endif

		// thread for performing blocking disk io operations
		boost::thread m_disk_io_thread;
	};

}

<commit_msg>added missing include guard to disk_io_thread.hpp<commit_after>/*

Copyright (c) 2007, Arvid Norberg
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 the author nor the names of its
      contributors 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.

*/

#ifndef TORRENT_DISK_IO_THREAD
#define TORRENT_DISK_IO_THREAD

#ifdef TORRENT_DISK_STATS
#include <fstream>
#endif

#include "libtorrent/storage.hpp"
#include <boost/thread/thread.hpp>
#include <boost/function.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/bind.hpp>
#include <boost/pool/pool.hpp>
#include <boost/noncopyable.hpp>
#include "libtorrent/config.hpp"

namespace libtorrent
{

	struct disk_io_job
	{
		disk_io_job()
			: action(read)
			, buffer(0)
			, buffer_size(0)
			, piece(0)
			, offset(0)
			, priority(0)
		{}

		enum action_t
		{
			read
			, write
			, hash
			, move_storage
			, release_files
			, delete_files
		};

		action_t action;

		char* buffer;
		size_type buffer_size;
		boost::intrusive_ptr<piece_manager> storage;
		// arguments used for read and write
		int piece, offset;
		// used for move_storage. On errors, this is set
		// to the error message
		std::string str;

		// priority decides whether or not this
		// job will skip entries in the queue or
		// not. It always skips in front of entries
		// with lower priority
		int priority;

		// this is called when operation completes
		boost::function<void(int, disk_io_job const&)> callback;
	};

	// this is a singleton consisting of the thread and a queue
	// of disk io jobs
	struct disk_io_thread : boost::noncopyable
	{
		disk_io_thread(int block_size = 16 * 1024);
		~disk_io_thread();

#ifdef TORRENT_STATS
		int disk_allocations() const
		{ return m_allocations; }
#endif

		// aborts read operations
		void stop(boost::intrusive_ptr<piece_manager> s);
		void add_job(disk_io_job const& j
			, boost::function<void(int, disk_io_job const&)> const& f
			= boost::function<void(int, disk_io_job const&)>());

#ifndef NDEBUG
		disk_io_job find_job(boost::intrusive_ptr<piece_manager> s
			, int action, int piece) const;
#endif
		// keep track of the number of bytes in the job queue
		// at any given time. i.e. the sum of all buffer_size.
		// this is used to slow down the download global download
		// speed when the queue buffer size is too big.
		size_type queue_buffer_size() const
		{ return m_queue_buffer_size; }

		void operator()();

		char* allocate_buffer();
		void free_buffer(char* buf);

	private:

		typedef boost::recursive_mutex mutex_t;
		mutable mutex_t m_mutex;
		boost::condition m_signal;
		bool m_abort;
		std::deque<disk_io_job> m_jobs;
		size_type m_queue_buffer_size;

		// memory pool for read and write operations
		boost::pool<> m_pool;

#ifndef NDEBUG
		int m_block_size;
		disk_io_job m_current;
#endif

#ifdef TORRENT_DISK_STATS
		std::ofstream m_log;
#endif
#ifdef TORRENT_STATS
		int m_allocations;
#endif

		// thread for performing blocking disk io operations
		boost::thread m_disk_io_thread;
	};

}

#endif

<|endoftext|>


<commit_before>/** \file nginxconfig/ast.hpp
 *  Raw manipulation of the nginx configuration AST.
 *
 *  Copyright (c) 2014 by Travis Gockel. All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify it under the terms of the Apache License
 *  as published by the Apache Software Foundation, either version 2 of the License, or (at your option) any later
 *  version.
 *
 *  \author Travis Gockel (travis@gockelhut.com)
**/
#ifndef __NGINXCONFIG_AST_HPP_INCLUDED__
#define __NGINXCONFIG_AST_HPP_INCLUDED__

#include <nginxconfig/config.hpp>

#include <deque>
#include <iosfwd>
#include <stdexcept>
#include <string>

namespace nginxconfig
{

enum class ast_entry_kind : unsigned int
{
    /** A \c simple entry is a name and a list of atrributes. **/
    simple,
    /** A \c complex entry has a name, a list of attributes and a list of child entries. **/
    complex,
    /** A \c document has child entries and only exists as the root entry of a configuration file. **/
    document,
    /** A \c comment has only the comment string. **/
    comment,
};

NGINXCONFIG_PUBLIC std::ostream& operator<<(std::ostream& os, const ast_entry_kind& kind);

/** Thrown when attempting to perform an operation on an \c ast_entry of the wrong kind. **/
class NGINXCONFIG_PUBLIC kind_error :
        public std::logic_error
{
public:
    explicit kind_error(const std::string& description);

    virtual ~kind_error() noexcept;
};

/** Represents an entry in an nginx configuration file. **/
class NGINXCONFIG_PUBLIC ast_entry
{
public:
    using attribute_list = std::deque<std::string>;
    using child_list     = std::deque<ast_entry>;

public:
    static ast_entry make_simple(std::string    name,
                                 attribute_list attributes   = attribute_list(),
                                 std::string    comment_text = std::string()
                                );

    static ast_entry make_complex(std::string    name,
                                  attribute_list attributes = attribute_list(),
                                  child_list     children   = child_list()
                                 );

    static ast_entry make_document(child_list children   = child_list());

    static ast_entry make_comment(std::string comment_text);

    ast_entry(const ast_entry&);
    ast_entry& operator=(const ast_entry&);

    ast_entry(ast_entry&&) noexcept;
    ast_entry& operator=(ast_entry&&) noexcept;

    ~ast_entry() noexcept;

    friend void swap(ast_entry& a, ast_entry& b) noexcept;

    ast_entry_kind kind() const;

    const std::string& name() const;
    std::string&       name();

    const attribute_list& attributes() const;
    attribute_list&       attributes();

    const child_list& children() const;
    child_list&       children();

    const std::string& comment() const;
    std::string&       comment();

    bool operator==(const ast_entry& other) const;
    bool operator!=(const ast_entry& other) const;

private:
    explicit ast_entry(ast_entry_kind kind);

private:
    ast_entry_kind _kind;
    std::string    _name;
    attribute_list _attributes;
    child_list     _children;
    std::string    _comment;
};

NGINXCONFIG_PUBLIC std::ostream& operator<<(std::ostream&, const ast_entry&);

}

#endif/*__NGINXCONFIG_AST_HPP_INCLUDED__*/
<commit_msg>Adds comments to ast_entry.<commit_after>/** \file nginxconfig/ast.hpp
 *  Raw manipulation of the nginx configuration AST.
 *
 *  Copyright (c) 2014 by Travis Gockel. All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify it under the terms of the Apache License
 *  as published by the Apache Software Foundation, either version 2 of the License, or (at your option) any later
 *  version.
 *
 *  \author Travis Gockel (travis@gockelhut.com)
**/
#ifndef __NGINXCONFIG_AST_HPP_INCLUDED__
#define __NGINXCONFIG_AST_HPP_INCLUDED__

#include <nginxconfig/config.hpp>

#include <deque>
#include <iosfwd>
#include <stdexcept>
#include <string>

namespace nginxconfig
{

enum class ast_entry_kind : unsigned int
{
    /** A \c simple entry is a name and a list of atrributes. **/
    simple,
    /** A \c complex entry has a name, a list of attributes and a list of child entries. **/
    complex,
    /** A \c document has child entries and only exists as the root entry of a configuration file. **/
    document,
    /** A \c comment has only the comment string. **/
    comment,
};

NGINXCONFIG_PUBLIC std::ostream& operator<<(std::ostream& os, const ast_entry_kind& kind);

/** Thrown when attempting to perform an operation on an \c ast_entry of the wrong kind. **/
class NGINXCONFIG_PUBLIC kind_error :
        public std::logic_error
{
public:
    explicit kind_error(const std::string& description);

    virtual ~kind_error() noexcept;
};

/** Represents an entry in an nginx configuration file. **/
class NGINXCONFIG_PUBLIC ast_entry
{
public:
    using attribute_list = std::deque<std::string>;
    using child_list     = std::deque<ast_entry>;

public:
    /** Create a \c simple AST entry. **/
    static ast_entry make_simple(std::string    name,
                                 attribute_list attributes   = attribute_list(),
                                 std::string    comment_text = std::string()
                                );

    /** Create a \c complex AST entry. **/
    static ast_entry make_complex(std::string    name,
                                  attribute_list attributes = attribute_list(),
                                  child_list     children   = child_list()
                                 );

    /** Create a \c document. **/
    static ast_entry make_document(child_list children   = child_list());

    /** Create a \c comment AST entry. **/
    static ast_entry make_comment(std::string comment_text);

    ast_entry(const ast_entry&);
    ast_entry& operator=(const ast_entry&);

    ast_entry(ast_entry&&) noexcept;
    ast_entry& operator=(ast_entry&&) noexcept;

    ~ast_entry() noexcept;

    /** Swap the contents of \a a with \a b. This will never throw. **/
    friend void swap(ast_entry& a, ast_entry& b) noexcept;

    /** Get the kind of entry this is.
     *
     *  \see ast_entry_kind
    **/
    ast_entry_kind kind() const;

    /** The name of the entry is the first part of a \c simple or \c complex entry. This is typically something like
     *  "http", "location" or "root". The only allowed characters according to nginx are alphanumeric and underscores,
     *  but your input is not validated.
     *
     *  \throws kind_error if \c kind is not \c simple or \c complex.
    **/
    const std::string& name() const;
    std::string&       name();

    /** The attributes immediately follow the \c name of a \c simple or \c complex entry. This is used to specify
     *  additional options to an entry.
     *
     *  \throws kind_error if \c kind is not \c simple or \c complex.
    **/
    const attribute_list& attributes() const;
    attribute_list&       attributes();

    /** Get the children of a \c complex or \c document entry.
     *
     *  \throws kind_error if \c kind is not \c complex or \c document.
    **/
    const child_list& children() const;
    child_list&       children();

    /** Get the comment of a \c comment, \c simple or \c complex entry. Comments are appended \e after the closing \c ;
     *  or \c {. For \c document comments, add them as a child.
     *
     *  \throws kind_error if \c kind is not \c comment, \c simple or \c complex.
    **/
    const std::string& comment() const;
    std::string&       comment();

    /** Compare the AST for equality. **/
    bool operator==(const ast_entry& other) const;
    bool operator!=(const ast_entry& other) const;

private:
    explicit ast_entry(ast_entry_kind kind);

private:
    ast_entry_kind _kind;
    std::string    _name;
    attribute_list _attributes;
    child_list     _children;
    std::string    _comment;
};

NGINXCONFIG_PUBLIC std::ostream& operator<<(std::ostream&, const ast_entry&);

}

#endif/*__NGINXCONFIG_AST_HPP_INCLUDED__*/
<|endoftext|>


<commit_before>#pragma once
#include <mos/gfx/texture_cube.hpp>
#include <mos/gfx/box.hpp>
#include <mos/gfx/target.hpp>
#include <mos/gfx/cube_camera.hpp>

namespace mos {
namespace gfx {

/** Real time environment light. */
class EnvironmentLight {
  friend class Renderer;
public:
  /** @param extent Describes how big the environment is, for parallax/box correction. */
  EnvironmentLight(const glm::vec3 &position = glm::vec3(0.0f, 0.0f, 1.0f),
                   const glm::vec3 &extent = glm::vec3(50.0f),
                   const float strength = 1.0f,
                   const glm::uvec2 resolution = glm::uvec2(128, 128));
  EnvironmentLight(const EnvironmentLight &light);
  EnvironmentLight &operator=(const EnvironmentLight &other);

  Box box;
  float strength;
private:
  Target target;
  CubeCamera cube_camera;
  TextureCube texture;
};
}
}
<commit_msg>Performance<commit_after>#pragma once
#include <mos/gfx/texture_cube.hpp>
#include <mos/gfx/box.hpp>
#include <mos/gfx/target.hpp>
#include <mos/gfx/cube_camera.hpp>

namespace mos {
namespace gfx {

/** Real time environment light. */
class EnvironmentLight {
  friend class Renderer;
public:
  /** @param extent Describes how big the environment is, for parallax/box correction. */
  EnvironmentLight(const glm::vec3 &position = glm::vec3(0.0f, 0.0f, 1.0f),
                   const glm::vec3 &extent = glm::vec3(50.0f),
                   const float strength = 1.0f,
                   const glm::uvec2 resolution = glm::uvec2(32, 32));
  EnvironmentLight(const EnvironmentLight &light);
  EnvironmentLight &operator=(const EnvironmentLight &other);

  Box box;
  float strength;
private:
  Target target;
  CubeCamera cube_camera;
  TextureCube texture;
};
}
}
<|endoftext|>


<commit_before>/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  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.
 */

/*
 * Copyright (C) 2015 ScyllaDB
 */

#pragma once

#include <seastar/core/future.hh>
#include <seastar/core/expiring_fifo.hh>

namespace seastar {

/// \addtogroup future-module
/// @{

/// Changes the clock used by shared_future<> and shared_promise<> when passed as the first template parameter.
template<typename Clock>
struct with_clock {};

/// \cond internal

template <typename... T>
struct future_option_traits;

template <typename Clock, typename... T>
struct future_option_traits<with_clock<Clock>, T...> {
    using clock_type = Clock;

    template<template <typename...> class Class>
    struct parametrize {
        using type = Class<T...>;
    };
};

template <typename... T>
struct future_option_traits {
    using clock_type = lowres_clock;

    template<template <typename...> class Class>
    struct parametrize {
        using type = Class<T...>;
    };
};

/// \endcond

/// \brief Like \ref future except the result can be waited for by many fibers.
///
/// Represents a value which may not yet be ready. A fiber can wait for the value using
/// the \ref future obtained by calling \ref get_future() or casting to \ref future type.
/// Multiple fibers are allowed to obtain a \ref future for the result using the same
/// instance of \ref shared_future.
///
/// All futures obtained from shared_future should end up in the same state. However,
/// if the value's copy constructor throws, some of the futures may end up in a failed state
/// with an exception thrown from the copy constructor and end up with a state
/// different than other futures.
///
/// The scope of shared_future instance doesn't have to include scopes of the futures
/// obtained from that instance. In that sense the returned futures are independent.
///
/// shared_future can be copied at any time and all copies will resolve with the same value.
///
/// shared_future can be in a disengaged state when it's default-constructed or moved-from.
/// When it's in such a state we say it's invalid and obtaining futures must not be attempted.
///
/// The types in the parameter pack T must all be copy-constructible.
///
/// When the first type in the parameter pack is \ref with_clock then it has the effect
/// of changing the clock used for timeouts by this instance. This type is omitted from
/// the parameter of the future<> objects.
///
/// Example:
///
///    future<int> f;
///    shared_future<with_clock<manual_clock>, int> sf(std::move(f));
///    future<int> f2 = sf;
///
template<typename... T>
class shared_future {
    template <typename... U> friend class shared_promise;
    using options = future_option_traits<T...>;
public:
    using clock = typename options::clock_type;
    using time_point = typename clock::time_point;
    using future_type = typename future_option_traits<T...>::template parametrize<future>::type;
    using promise_type = typename future_option_traits<T...>::template parametrize<promise>::type;
    using value_tuple_type = typename future_option_traits<T...>::template parametrize<std::tuple>::type;
private:
    using promise_expiry = typename future_option_traits<T...>::template parametrize<promise_expiry>::type;

    /// \cond internal
    class shared_state : public enable_lw_shared_from_this<shared_state> {
        future_type _original_future;
        expiring_fifo<promise_type, promise_expiry, clock> _peers;

    public:
        ~shared_state() {
            // Don't warn if the shared future is exceptional. Any
            // warnings will be reported by the futures returned by
            // get_future.
            if (_original_future.failed()) {
                _original_future.ignore_ready_future();
            }
        }
        explicit shared_state(future_type f) noexcept : _original_future(std::move(f)) { }
        void resolve(future_type&& f) noexcept {
            _original_future = std::move(f);
            auto& state = _original_future._state;
            if (_original_future.failed()) {
                while (_peers) {
                    _peers.front().set_exception(state.get_exception());
                    _peers.pop_front();
                }
            } else {
                while (_peers) {
                    auto& p = _peers.front();
                    try {
                        p.set_value(state.get_value());
                    } catch (...) {
                        p.set_exception(std::current_exception());
                    }
                    _peers.pop_front();
                }
            }
        }

        future_type get_future(time_point timeout = time_point::max()) noexcept {
            // Note that some functions called below may throw,
            // like pushing to _peers or copying _original_future's ready value.
            // We'd rather terminate than propagate these errors similar to
            // .then()'s failure to allocate a continuation as the caller cannot
            // distinguish between an error returned by the original future to
            // failing to perform `get_future` itself.
            memory::scoped_critical_alloc_section _;
            if (!_original_future.available()) {
                promise_type p;
                auto f = p.get_future();
                if (_original_future._state.valid()) {
                    // _original_future's result is forwarded to each peer.
                    (void)_original_future.then_wrapped([s = this->shared_from_this()] (future_type&& f) mutable {
                        s->resolve(std::move(f));
                    });
                }
                _peers.push_back(std::move(p), timeout);
                return f;
            } else if (_original_future.failed()) {
                return future_type(exception_future_marker(), std::exception_ptr(_original_future._state.get_exception()));
            } else {
                return future_type(ready_future_marker(), _original_future._state.get_value());
            }
        }

        bool available() const noexcept {
            return _original_future.available();
        }

        bool failed() const noexcept {
            return _original_future.failed();
        }
    };
    /// \endcond
    lw_shared_ptr<shared_state> _state;
public:
    /// \brief Forwards the result of future \c f into this shared_future.
    shared_future(future_type f)
        : _state(make_lw_shared<shared_state>(std::move(f))) { }

    shared_future() = default; // noexcept, based on the respective lw_shared_ptr constructor
    shared_future(const shared_future&) = default; // noexcept, based on the respective lw_shared_ptr constructor
    shared_future& operator=(const shared_future&) = default; // noexcept, based on respective constructor
    shared_future(shared_future&&) = default; // noexcept, based on the respective lw_shared_ptr constructor
    shared_future& operator=(shared_future&&) = default; // noexcept, based on the respective constructor

    /// \brief Creates a new \c future which will resolve with the result of this shared_future
    ///
    /// \param timeout When engaged, the returned future will resolve with \ref timed_out_error
    /// if this shared_future doesn't resolve before timeout is reached.
    ///
    /// This object must be in a valid state.
    future_type get_future(time_point timeout = time_point::max()) const noexcept {
        return _state->get_future(timeout);
    }

    /// \brief Returns true if the future is available (ready or failed)
    ///
    /// \note This object must be in a valid state.
    bool available() const noexcept {
        return _state->available();
    }

    /// \brief Returns true if the future is failed
    ///
    /// \note This object must be in a valid state.
    bool failed() const noexcept {
        return _state->failed();
    }

    /// \brief Equivalent to \ref get_future()
    operator future_type() const noexcept {
        return get_future();
    }

    /// \brief Returns true if the instance is in valid state
    bool valid() const noexcept {
        return bool(_state);
    }
};

/// \brief Like \ref promise except that its counterpart is \ref shared_future instead of \ref future
///
/// When the shared_promise is made ready, every waiter is also made ready.
///
/// Like the shared_future, the types in the parameter pack T must all be copy-constructible.
template <typename... T>
class shared_promise {
public:
    using shared_future_type = shared_future<T...>;
    using future_type = typename shared_future_type::future_type;
    using promise_type = typename shared_future_type::promise_type;
    using clock = typename shared_future_type::clock;
    using time_point = typename shared_future_type::time_point;
    using value_tuple_type = typename shared_future_type::value_tuple_type;
private:
    promise_type _promise;
    shared_future_type _shared_future;
    static constexpr bool copy_noexcept = future_type::copy_noexcept;
public:
    shared_promise(const shared_promise&) = delete;
    shared_promise(shared_promise&&) = default; // noexcept, based on the respective promise and shared_future constructors
    shared_promise& operator=(shared_promise&&) = default; // noexcept, based on the respective promise and shared_future constructors
    shared_promise() : _promise(), _shared_future(_promise.get_future()) {
    }

    /// \brief Gets new future associated with this promise.
    /// If the promise is not resolved before timeout the returned future will resolve with \ref timed_out_error.
    /// This instance doesn't have to be kept alive until the returned future resolves.
    future_type get_shared_future(time_point timeout = time_point::max()) const noexcept {
        return _shared_future.get_future(timeout);
    }

    /// \brief Sets the shared_promise's value (as tuple; by copying), same as normal promise
    void set_value(const value_tuple_type& result) noexcept(copy_noexcept) {
        _promise.set_value(result);
    }

    /// \brief Sets the shared_promise's value (as tuple; by moving), same as normal promise
    void set_value(value_tuple_type&& result) noexcept {
        _promise.set_value(std::move(result));
    }

    /// \brief Sets the shared_promise's value (variadic), same as normal promise
    template <typename... A>
    void set_value(A&&... a) noexcept {
        _promise.set_value(std::forward<A>(a)...);
    }

    /// \brief Marks the shared_promise as failed, same as normal promise
    void set_exception(std::exception_ptr ex) noexcept {
        _promise.set_exception(std::move(ex));
    }

    /// \brief Marks the shared_promise as failed, same as normal promise
    template<typename Exception>
    void set_exception(Exception&& e) noexcept {
        set_exception(make_exception_ptr(std::forward<Exception>(e)));
    }

    /// \brief Returns true if the underlying future is available (ready or failed)
    bool available() const noexcept {
        return _shared_future.available();
    }

    /// \brief Returns true if the underlying future is  failed
    bool failed() const noexcept {
        return _shared_future.failed();
    }
};

/// @}

}
<commit_msg>Move shared_future to use abortable_fifo.<commit_after>/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  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.
 */

/*
 * Copyright (C) 2015 ScyllaDB
 */

#pragma once

#include <seastar/core/future.hh>
#include <seastar/core/abortable_fifo.hh>
#include <seastar/core/abort_on_expiry.hh>
#include <seastar/core/timed_out_error.hh>

namespace seastar {

/// \addtogroup future-module
/// @{

/// Changes the clock used by shared_future<> and shared_promise<> when passed as the first template parameter.
template<typename Clock>
struct with_clock {};

/// \cond internal

template <typename... T>
struct future_option_traits;

template <typename Clock, typename... T>
struct future_option_traits<with_clock<Clock>, T...> {
    using clock_type = Clock;

    template<template <typename...> class Class>
    struct parametrize {
        using type = Class<T...>;
    };
};

template <typename... T>
struct future_option_traits {
    using clock_type = lowres_clock;

    template<template <typename...> class Class>
    struct parametrize {
        using type = Class<T...>;
    };
};

/// \endcond

/// \brief Like \ref future except the result can be waited for by many fibers.
///
/// Represents a value which may not yet be ready. A fiber can wait for the value using
/// the \ref future obtained by calling \ref get_future() or casting to \ref future type.
/// Multiple fibers are allowed to obtain a \ref future for the result using the same
/// instance of \ref shared_future.
///
/// All futures obtained from shared_future should end up in the same state. However,
/// if the value's copy constructor throws, some of the futures may end up in a failed state
/// with an exception thrown from the copy constructor and end up with a state
/// different than other futures.
///
/// The scope of shared_future instance doesn't have to include scopes of the futures
/// obtained from that instance. In that sense the returned futures are independent.
///
/// shared_future can be copied at any time and all copies will resolve with the same value.
///
/// shared_future can be in a disengaged state when it's default-constructed or moved-from.
/// When it's in such a state we say it's invalid and obtaining futures must not be attempted.
///
/// The types in the parameter pack T must all be copy-constructible.
///
/// When the first type in the parameter pack is \ref with_clock then it has the effect
/// of changing the clock used for timeouts by this instance. This type is omitted from
/// the parameter of the future<> objects.
///
/// Example:
///
///    future<int> f;
///    shared_future<with_clock<manual_clock>, int> sf(std::move(f));
///    future<int> f2 = sf;
///
template<typename... T>
class shared_future {
    template <typename... U> friend class shared_promise;
    using options = future_option_traits<T...>;
public:
    using clock = typename options::clock_type;
    using time_point = typename clock::time_point;
    using future_type = typename future_option_traits<T...>::template parametrize<future>::type;
    using promise_type = typename future_option_traits<T...>::template parametrize<promise>::type;
    using value_tuple_type = typename future_option_traits<T...>::template parametrize<std::tuple>::type;
private:
    /// \cond internal
    class shared_state : public enable_lw_shared_from_this<shared_state> {
        future_type _original_future;
        struct entry {
            promise_type pr;
            std::optional<abort_on_expiry<clock>> timer;
        };

        struct entry_expiry {
            void operator()(entry& e) noexcept {
                e.pr.set_exception(std::make_exception_ptr(timed_out_error()));
            };
        };

        internal::abortable_fifo<entry, entry_expiry> _peers;

    public:
        ~shared_state() {
            // Don't warn if the shared future is exceptional. Any
            // warnings will be reported by the futures returned by
            // get_future.
            if (_original_future.failed()) {
                _original_future.ignore_ready_future();
            }
        }
        explicit shared_state(future_type f) noexcept : _original_future(std::move(f)) { }
        void resolve(future_type&& f) noexcept {
            _original_future = std::move(f);
            auto& state = _original_future._state;
            if (_original_future.failed()) {
                while (_peers) {
                    _peers.front().pr.set_exception(state.get_exception());
                    _peers.pop_front();
                }
            } else {
                while (_peers) {
                    auto& p = _peers.front().pr;
                    try {
                        p.set_value(state.get_value());
                    } catch (...) {
                        p.set_exception(std::current_exception());
                    }
                    _peers.pop_front();
                }
            }
        }

        future_type get_future(time_point timeout = time_point::max()) noexcept {
            // Note that some functions called below may throw,
            // like pushing to _peers or copying _original_future's ready value.
            // We'd rather terminate than propagate these errors similar to
            // .then()'s failure to allocate a continuation as the caller cannot
            // distinguish between an error returned by the original future to
            // failing to perform `get_future` itself.
            memory::scoped_critical_alloc_section _;
            if (!_original_future.available()) {
                entry& e = _peers.emplace_back();

                auto f = e.pr.get_future();
                if (timeout != time_point::max()) {
                    e.timer.emplace(timeout);
                    abort_source& as = e.timer->abort_source();
                   _peers.make_back_abortable(as);
                }
                if (_original_future._state.valid()) {
                    // _original_future's result is forwarded to each peer.
                    (void)_original_future.then_wrapped([s = this->shared_from_this()] (future_type&& f) mutable {
                        s->resolve(std::move(f));
                    });
                }
                return f;
            } else if (_original_future.failed()) {
                return future_type(exception_future_marker(), std::exception_ptr(_original_future._state.get_exception()));
            } else {
                return future_type(ready_future_marker(), _original_future._state.get_value());
            }
        }

        bool available() const noexcept {
            return _original_future.available();
        }

        bool failed() const noexcept {
            return _original_future.failed();
        }
    };
    /// \endcond
    lw_shared_ptr<shared_state> _state;
public:
    /// \brief Forwards the result of future \c f into this shared_future.
    shared_future(future_type f)
        : _state(make_lw_shared<shared_state>(std::move(f))) { }

    shared_future() = default; // noexcept, based on the respective lw_shared_ptr constructor
    shared_future(const shared_future&) = default; // noexcept, based on the respective lw_shared_ptr constructor
    shared_future& operator=(const shared_future&) = default; // noexcept, based on respective constructor
    shared_future(shared_future&&) = default; // noexcept, based on the respective lw_shared_ptr constructor
    shared_future& operator=(shared_future&&) = default; // noexcept, based on the respective constructor

    /// \brief Creates a new \c future which will resolve with the result of this shared_future
    ///
    /// \param timeout When engaged, the returned future will resolve with \ref timed_out_error
    /// if this shared_future doesn't resolve before timeout is reached.
    ///
    /// This object must be in a valid state.
    future_type get_future(time_point timeout = time_point::max()) const noexcept {
        return _state->get_future(timeout);
    }

    /// \brief Returns true if the future is available (ready or failed)
    ///
    /// \note This object must be in a valid state.
    bool available() const noexcept {
        return _state->available();
    }

    /// \brief Returns true if the future is failed
    ///
    /// \note This object must be in a valid state.
    bool failed() const noexcept {
        return _state->failed();
    }

    /// \brief Equivalent to \ref get_future()
    operator future_type() const noexcept {
        return get_future();
    }

    /// \brief Returns true if the instance is in valid state
    bool valid() const noexcept {
        return bool(_state);
    }
};

/// \brief Like \ref promise except that its counterpart is \ref shared_future instead of \ref future
///
/// When the shared_promise is made ready, every waiter is also made ready.
///
/// Like the shared_future, the types in the parameter pack T must all be copy-constructible.
template <typename... T>
class shared_promise {
public:
    using shared_future_type = shared_future<T...>;
    using future_type = typename shared_future_type::future_type;
    using promise_type = typename shared_future_type::promise_type;
    using clock = typename shared_future_type::clock;
    using time_point = typename shared_future_type::time_point;
    using value_tuple_type = typename shared_future_type::value_tuple_type;
private:
    promise_type _promise;
    shared_future_type _shared_future;
    static constexpr bool copy_noexcept = future_type::copy_noexcept;
public:
    shared_promise(const shared_promise&) = delete;
    shared_promise(shared_promise&&) = default; // noexcept, based on the respective promise and shared_future constructors
    shared_promise& operator=(shared_promise&&) = default; // noexcept, based on the respective promise and shared_future constructors
    shared_promise() : _promise(), _shared_future(_promise.get_future()) {
    }

    /// \brief Gets new future associated with this promise.
    /// If the promise is not resolved before timeout the returned future will resolve with \ref timed_out_error.
    /// This instance doesn't have to be kept alive until the returned future resolves.
    future_type get_shared_future(time_point timeout = time_point::max()) const noexcept {
        return _shared_future.get_future(timeout);
    }

    /// \brief Sets the shared_promise's value (as tuple; by copying), same as normal promise
    void set_value(const value_tuple_type& result) noexcept(copy_noexcept) {
        _promise.set_value(result);
    }

    /// \brief Sets the shared_promise's value (as tuple; by moving), same as normal promise
    void set_value(value_tuple_type&& result) noexcept {
        _promise.set_value(std::move(result));
    }

    /// \brief Sets the shared_promise's value (variadic), same as normal promise
    template <typename... A>
    void set_value(A&&... a) noexcept {
        _promise.set_value(std::forward<A>(a)...);
    }

    /// \brief Marks the shared_promise as failed, same as normal promise
    void set_exception(std::exception_ptr ex) noexcept {
        _promise.set_exception(std::move(ex));
    }

    /// \brief Marks the shared_promise as failed, same as normal promise
    template<typename Exception>
    void set_exception(Exception&& e) noexcept {
        set_exception(make_exception_ptr(std::forward<Exception>(e)));
    }

    /// \brief Returns true if the underlying future is available (ready or failed)
    bool available() const noexcept {
        return _shared_future.available();
    }

    /// \brief Returns true if the underlying future is  failed
    bool failed() const noexcept {
        return _shared_future.failed();
    }
};

/// @}

}
<|endoftext|>


<commit_before>#ifndef PICOLIB_SOCKET_IMPL_H_
#define PICOLIB_SOCKET_IMPL_H_

#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/un.h>

namespace Pico {

    namespace Network {

        template <AddressType>
        struct Sockaddr;

        template <>
        struct Address<AddressType::UNIX_ABSTRACT>
        {
            char *path;
        };

        using UnixAbstractAddress   = Address<AddressType::UNIX_ABSTRACT>;

        template <>
        struct Sockaddr<AddressType::UNIX_ABSTRACT>
        {
            static constexpr int family = AF_UNIX;
            using type = struct sockaddr_un;

            FUNCTION
            struct sockaddr_un pack(UnixAbstractAddress const unixaddr, size_t& size)
            {
                struct sockaddr_un addr;

                addr.sun_family = AF_UNIX;
                addr.sun_path[0] = '\0';
                String::copy(addr.sun_path + 1, unixaddr.path, sizeof(addr.sun_path) - 1);

                size = sizeof(addr.sun_family) + String::length(unixaddr.path) + 1;
                return addr;
            }
        };

        METHOD
        size_t SocketIO::available_input_bytes()
        {
            size_t nr_bytes = 0;

            Syscall::ioctl(fd, FIONREAD, &nr_bytes);
            return nr_bytes;
        }

        CONSTRUCTOR
        SctpSocket::SctpSocket() : StreamSocket(AF_INET, IPPROTO_SCTP) {}

        CONSTRUCTOR
        Sctp6Socket::Sctp6Socket() : StreamSocket(AF_INET6, IPPROTO_SCTP) {}
    }
}

#endif
<commit_msg>freebsd/pico/socket: add missing include<commit_after>#ifndef PICOLIB_SOCKET_IMPL_H_
#define PICOLIB_SOCKET_IMPL_H_

#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>

namespace Pico {

    namespace Network {

        template <AddressType>
        struct Sockaddr;

        template <>
        struct Address<AddressType::UNIX_ABSTRACT>
        {
            char *path;
        };

        using UnixAbstractAddress   = Address<AddressType::UNIX_ABSTRACT>;

        template <>
        struct Sockaddr<AddressType::UNIX_ABSTRACT>
        {
            static constexpr int family = AF_UNIX;
            using type = struct sockaddr_un;

            FUNCTION
            struct sockaddr_un pack(UnixAbstractAddress const unixaddr, size_t& size)
            {
                struct sockaddr_un addr;

                addr.sun_family = AF_UNIX;
                addr.sun_path[0] = '\0';
                String::copy(addr.sun_path + 1, unixaddr.path, sizeof(addr.sun_path) - 1);

                size = sizeof(addr.sun_family) + String::length(unixaddr.path) + 1;
                return addr;
            }
        };

        METHOD
        size_t SocketIO::available_input_bytes()
        {
            size_t nr_bytes = 0;

            Syscall::ioctl(fd, FIONREAD, &nr_bytes);
            return nr_bytes;
        }

        CONSTRUCTOR
        SctpSocket::SctpSocket() : StreamSocket(AF_INET, IPPROTO_SCTP) {}

        CONSTRUCTOR
        Sctp6Socket::Sctp6Socket() : StreamSocket(AF_INET6, IPPROTO_SCTP) {}
    }
}

#endif
<|endoftext|>


<commit_before>#include "commands/commands.h"

#include "config.h"
#include "util/log.h"
#include "interface/interface.h"
#include "config.h"
#include "pb_decode.h"

#include "commands/passthrough_command.h"
#include "commands/diagnostic_request_command.h"
#include "commands/version_command.h"
#include "commands/device_id_command.h"
#include "commands/device_platform_command.h"
#include "commands/can_message_write_command.h"
#include "commands/simple_write_command.h"
#include "commands/af_bypass_command.h"
#include "commands/payload_format_command.h"
#include "commands/predefined_obd2_command.h"
#include "commands/modem_config_command.h"
#include "commands/rtc_config_command.h"
#include "commands/sd_mount_status_command.h"

using openxc::util::log::debug;
using openxc::config::getConfiguration;
using openxc::payload::PayloadFormat;
using openxc::interface::InterfaceType;

static bool handleComplexCommand(openxc_VehicleMessage* message) {
    bool status = true;
    if(message != NULL && message->has_control_command) {
        openxc_ControlCommand* command = &message->control_command;
        switch(command->type) {
        case openxc_ControlCommand_Type_DIAGNOSTIC:
            status = openxc::commands::handleDiagnosticRequestCommand(command);
            break;
        case openxc_ControlCommand_Type_VERSION:
            status = openxc::commands::handleVersionCommand();
            break;
        case openxc_ControlCommand_Type_DEVICE_ID:
            status = openxc::commands::handleDeviceIdCommmand();
            break;
        case openxc_ControlCommand_Type_PLATFORM:
            status = openxc::commands::handleDevicePlatformCommmand();
            break;
        case openxc_ControlCommand_Type_PASSTHROUGH:
            status = openxc::commands::handlePassthroughModeCommand(command);
            break;
        case openxc_ControlCommand_Type_PREDEFINED_OBD2_REQUESTS:
            status = openxc::commands::handlePredefinedObd2RequestsCommand(command);
            break;
        case openxc_ControlCommand_Type_ACCEPTANCE_FILTER_BYPASS:
            status = openxc::commands::handleFilterBypassCommand(command);
            break;
        case openxc_ControlCommand_Type_PAYLOAD_FORMAT:
            status = openxc::commands::handlePayloadFormatCommand(command);
            break;
        case openxc_ControlCommand_Type_MODEM_CONFIGURATION:
            status = openxc::commands::handleModemConfigurationCommand(command);
            break;
        case openxc_ControlCommand_Type_RTC_CONFIGURATION:
            status = openxc::commands::handleRTCConfigurationCommand(command);
        break;
        case openxc_ControlCommand_Type_SD_MOUNT_STATUS:
            status =  openxc::commands::handleSDMountStatusCommand();
        default:
            status = false;
            break;
        }
    }
    return status;
}

size_t openxc::commands::handleIncomingMessage(uint8_t payload[], size_t length,
        openxc::interface::InterfaceDescriptor* sourceInterfaceDescriptor) {
    openxc_VehicleMessage message = {0};
    size_t bytesRead = 0;

    // TODO Not attempting to deserialize binary messages via UART,
    // see https://github.com/openxc/vi-firmware/issues/313
    if(sourceInterfaceDescriptor->type == InterfaceType::UART &&
            getConfiguration()->payloadFormat == PayloadFormat::PROTOBUF) {
        return 0;
    }

    // Ignore anything less than 2 bytes, we know it's an incomplete payload -
    // wait for more to come in before trying to parse it
    if(length > 2) {
        if((bytesRead = openxc::payload::deserialize(payload, length,
                getConfiguration()->payloadFormat, &message)) > 0) {
            if(validate(&message)) {
                switch(message.type) {
                case openxc_VehicleMessage_Type_CAN:
                    handleCan(&message, sourceInterfaceDescriptor);
                    break;
                case openxc_VehicleMessage_Type_SIMPLE:
                    handleSimple(&message);
                    break;
                case openxc_VehicleMessage_Type_CONTROL_COMMAND:
                    handleComplexCommand(&message);
                    break;
                default:
                    debug("Incoming message had unrecognized type: %d", message.type);
                    break;
                }
            } else {
                debug("Incoming message is complete but invalid");
            }
        } else {
            // This is very noisy when using UART as the packet tends to arrive
            // in a couple or bursts and is passed to this function when
            // incomplete.
            // debug("Unable to deserialize a %s message from the payload",
                 // getConfiguration()->payloadFormat == PayloadFormat::JSON ?
                     // "JSON" : "Protobuf");
        }
    }
    return bytesRead;
}

static bool validateControlCommand(openxc_VehicleMessage* message) {
    bool valid = message->has_type &&
            message->type == openxc_VehicleMessage_Type_CONTROL_COMMAND &&
            message->has_control_command &&
            message->control_command.has_type;
    if(valid) {
        switch(message->control_command.type) {
        case openxc_ControlCommand_Type_DIAGNOSTIC:
            valid = openxc::commands::validateDiagnosticRequest(message);
            break;
        case openxc_ControlCommand_Type_PASSTHROUGH:
            valid = openxc::commands::validatePassthroughRequest(message);
            break;
        case openxc_ControlCommand_Type_PREDEFINED_OBD2_REQUESTS:
            valid = openxc::commands::validatePredefinedObd2RequestsCommand(message);
            break;
        case openxc_ControlCommand_Type_ACCEPTANCE_FILTER_BYPASS:
            valid = openxc::commands::validateFilterBypassCommand(message);
            break;
        case openxc_ControlCommand_Type_PAYLOAD_FORMAT:
            valid = openxc::commands::validatePayloadFormatCommand(message);
            break;
        case openxc_ControlCommand_Type_VERSION:
        case openxc_ControlCommand_Type_DEVICE_ID:
        case openxc_ControlCommand_Type_PLATFORM:
        case openxc_ControlCommand_Type_SD_MOUNT_STATUS:
            valid =  true;
            break;
        case openxc_ControlCommand_Type_MODEM_CONFIGURATION:
            valid = openxc::commands::validateModemConfigurationCommand(message);
            break;
        case openxc_ControlCommand_Type_RTC_CONFIGURATION:
            valid = openxc::commands::validateRTCConfigurationCommand(message);
            break;
        default:
            valid = false;
            break;
        }
    }
    return valid;
}

bool openxc::commands::validate(openxc_VehicleMessage* message) {
    bool valid = false;
    if(message != NULL && message->has_type) {
        switch(message->type) {
        case openxc_VehicleMessage_Type_CAN:
            valid = validateCan(message);
            break;
        case openxc_VehicleMessage_Type_SIMPLE:
            valid = validateSimple(message);
            break;
        case openxc_VehicleMessage_Type_CONTROL_COMMAND:
            valid = validateControlCommand(message);
            break;
        default:
            debug("Incoming message had unrecognized type: %d", message->type);
            break;
        }
    }
    return valid;
}

void openxc::commands::sendCommandResponse(openxc_ControlCommand_Type commandType,
        bool status, char* responseMessage, size_t responseMessageLength) {
    openxc_VehicleMessage message = {0};
    message.has_type = true;
    message.type = openxc_VehicleMessage_Type_COMMAND_RESPONSE;
    message.has_command_response = true;
    message.command_response.has_type = true;
    message.command_response.type = commandType;
    message.command_response.has_message = false;
    message.command_response.has_status = true;
    message.command_response.status = status;
    if(responseMessage != NULL && responseMessageLength > 0) {
        message.command_response.has_message = true;
        strncpy(message.command_response.message, responseMessage,
                MIN(sizeof(message.command_response.message),
                    responseMessageLength));
    }
    pipeline::publish(&message, &getConfiguration()->pipeline);
}

void openxc::commands::sendCommandResponse(openxc_ControlCommand_Type commandType,
        bool status) {
    sendCommandResponse(commandType, status, NULL, 0);
}
<commit_msg>Turn on binary UART protobuff commands<commit_after>#include "commands/commands.h"

#include "config.h"
#include "util/log.h"
#include "interface/interface.h"
#include "config.h"
#include "pb_decode.h"

#include "commands/passthrough_command.h"
#include "commands/diagnostic_request_command.h"
#include "commands/version_command.h"
#include "commands/device_id_command.h"
#include "commands/device_platform_command.h"
#include "commands/can_message_write_command.h"
#include "commands/simple_write_command.h"
#include "commands/af_bypass_command.h"
#include "commands/payload_format_command.h"
#include "commands/predefined_obd2_command.h"
#include "commands/modem_config_command.h"
#include "commands/rtc_config_command.h"
#include "commands/sd_mount_status_command.h"

using openxc::util::log::debug;
using openxc::config::getConfiguration;
using openxc::payload::PayloadFormat;
using openxc::interface::InterfaceType;

static bool handleComplexCommand(openxc_VehicleMessage* message) {
    bool status = true;
    if(message != NULL && message->has_control_command) {
        openxc_ControlCommand* command = &message->control_command;
        switch(command->type) {
        case openxc_ControlCommand_Type_DIAGNOSTIC:
            status = openxc::commands::handleDiagnosticRequestCommand(command);
            break;
        case openxc_ControlCommand_Type_VERSION:
            status = openxc::commands::handleVersionCommand();
            break;
        case openxc_ControlCommand_Type_DEVICE_ID:
            status = openxc::commands::handleDeviceIdCommmand();
            break;
        case openxc_ControlCommand_Type_PLATFORM:
            status = openxc::commands::handleDevicePlatformCommmand();
            break;
        case openxc_ControlCommand_Type_PASSTHROUGH:
            status = openxc::commands::handlePassthroughModeCommand(command);
            break;
        case openxc_ControlCommand_Type_PREDEFINED_OBD2_REQUESTS:
            status = openxc::commands::handlePredefinedObd2RequestsCommand(command);
            break;
        case openxc_ControlCommand_Type_ACCEPTANCE_FILTER_BYPASS:
            status = openxc::commands::handleFilterBypassCommand(command);
            break;
        case openxc_ControlCommand_Type_PAYLOAD_FORMAT:
            status = openxc::commands::handlePayloadFormatCommand(command);
            break;
        case openxc_ControlCommand_Type_MODEM_CONFIGURATION:
            status = openxc::commands::handleModemConfigurationCommand(command);
            break;
        case openxc_ControlCommand_Type_RTC_CONFIGURATION:
            status = openxc::commands::handleRTCConfigurationCommand(command);
        break;
        case openxc_ControlCommand_Type_SD_MOUNT_STATUS:
            status =  openxc::commands::handleSDMountStatusCommand();
        default:
            status = false;
            break;
        }
    }
    return status;
}

size_t openxc::commands::handleIncomingMessage(uint8_t payload[], size_t length,
        openxc::interface::InterfaceDescriptor* sourceInterfaceDescriptor) {
    openxc_VehicleMessage message = {0};
    size_t bytesRead = 0;

#if (DO_NOT_PROCESS_BINARY_UART_PROTOBUFF == 1)
    // TODO Not attempting to deserialize binary messages via UART,
    // see https://github.com/openxc/vi-firmware/issues/313
    if(sourceInterfaceDescriptor->type == InterfaceType::UART &&
            getConfiguration()->payloadFormat == PayloadFormat::PROTOBUF) {
        return 0;
    }
#endif

    // Ignore anything less than 2 bytes, we know it's an incomplete payload -
    // wait for more to come in before trying to parse it
    if(length > 2) {
        if((bytesRead = openxc::payload::deserialize(payload, length,
                getConfiguration()->payloadFormat, &message)) > 0) {
            if(validate(&message)) {
                switch(message.type) {
                case openxc_VehicleMessage_Type_CAN:
                    handleCan(&message, sourceInterfaceDescriptor);
                    break;
                case openxc_VehicleMessage_Type_SIMPLE:
                    handleSimple(&message);
                    break;
                case openxc_VehicleMessage_Type_CONTROL_COMMAND:
                    handleComplexCommand(&message);
                    break;
                default:
                    debug("Incoming message had unrecognized type: %d", message.type);
                    break;
                }
            } else {
                debug("Incoming message is complete but invalid");
            }
        } else {
            // This is very noisy when using UART as the packet tends to arrive
            // in a couple or bursts and is passed to this function when
            // incomplete.
            // debug("Unable to deserialize a %s message from the payload",
                 // getConfiguration()->payloadFormat == PayloadFormat::JSON ?
                     // "JSON" : "Protobuf");
        }
    }
    return bytesRead;
}

static bool validateControlCommand(openxc_VehicleMessage* message) {
    bool valid = message->has_type &&
            message->type == openxc_VehicleMessage_Type_CONTROL_COMMAND &&
            message->has_control_command &&
            message->control_command.has_type;
    if(valid) {
        switch(message->control_command.type) {
        case openxc_ControlCommand_Type_DIAGNOSTIC:
            valid = openxc::commands::validateDiagnosticRequest(message);
            break;
        case openxc_ControlCommand_Type_PASSTHROUGH:
            valid = openxc::commands::validatePassthroughRequest(message);
            break;
        case openxc_ControlCommand_Type_PREDEFINED_OBD2_REQUESTS:
            valid = openxc::commands::validatePredefinedObd2RequestsCommand(message);
            break;
        case openxc_ControlCommand_Type_ACCEPTANCE_FILTER_BYPASS:
            valid = openxc::commands::validateFilterBypassCommand(message);
            break;
        case openxc_ControlCommand_Type_PAYLOAD_FORMAT:
            valid = openxc::commands::validatePayloadFormatCommand(message);
            break;
        case openxc_ControlCommand_Type_VERSION:
        case openxc_ControlCommand_Type_DEVICE_ID:
        case openxc_ControlCommand_Type_PLATFORM:
        case openxc_ControlCommand_Type_SD_MOUNT_STATUS:
            valid =  true;
            break;
        case openxc_ControlCommand_Type_MODEM_CONFIGURATION:
            valid = openxc::commands::validateModemConfigurationCommand(message);
            break;
        case openxc_ControlCommand_Type_RTC_CONFIGURATION:
            valid = openxc::commands::validateRTCConfigurationCommand(message);
            break;
        default:
            valid = false;
            break;
        }
    }
    return valid;
}

bool openxc::commands::validate(openxc_VehicleMessage* message) {
    bool valid = false;
    if(message != NULL && message->has_type) {
        switch(message->type) {
        case openxc_VehicleMessage_Type_CAN:
            valid = validateCan(message);
            break;
        case openxc_VehicleMessage_Type_SIMPLE:
            valid = validateSimple(message);
            break;
        case openxc_VehicleMessage_Type_CONTROL_COMMAND:
            valid = validateControlCommand(message);
            break;
        default:
            debug("Incoming message had unrecognized type: %d", message->type);
            break;
        }
    }
    return valid;
}

void openxc::commands::sendCommandResponse(openxc_ControlCommand_Type commandType,
        bool status, char* responseMessage, size_t responseMessageLength) {
    openxc_VehicleMessage message = {0};
    message.has_type = true;
    message.type = openxc_VehicleMessage_Type_COMMAND_RESPONSE;
    message.has_command_response = true;
    message.command_response.has_type = true;
    message.command_response.type = commandType;
    message.command_response.has_message = false;
    message.command_response.has_status = true;
    message.command_response.status = status;
    if(responseMessage != NULL && responseMessageLength > 0) {
        message.command_response.has_message = true;
        strncpy(message.command_response.message, responseMessage,
                MIN(sizeof(message.command_response.message),
                    responseMessageLength));
    }
    pipeline::publish(&message, &getConfiguration()->pipeline);
}

void openxc::commands::sendCommandResponse(openxc_ControlCommand_Type commandType,
        bool status) {
    sendCommandResponse(commandType, status, NULL, 0);
}
<|endoftext|>


<commit_before><commit_msg>Planning: add x(n-1)'^2 term into path_time_qp kernal<commit_after><|endoftext|>