<commit_before>//
// Copyright (c) 2009, Markus Rickert
// 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.
//
// 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 HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//

#include <BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h>
#include <BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h>
#include <BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h>
#include <BulletCollision/NarrowPhaseCollision/btPointCollector.h>
#include <BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h>

#include "../Exception.h"
#include "Body.h"
#include "Model.h"
#include "Scene.h"
#include "Shape.h"

namespace rl
{
	namespace sg
	{
		namespace bullet
		{
			Scene::Scene() :
				::rl::sg::Scene(),
				::rl::sg::DistanceScene(),
				::rl::sg::RaycastScene(),
				::rl::sg::SimpleScene(),
				broadphase(),
				configuration(),
				dispatcher(&configuration),
				world(&dispatcher, &broadphase, &configuration)
			{
			}

			Scene::~Scene()
			{
				while (this->models.size() > 0)
				{
					delete this->models[0];
				}
			}

			bool
			Scene::areColliding(::rl::sg::Body* first, ::rl::sg::Body* second)
			{
				Body* body1 = static_cast<Body*>(first);
				Body* body2 = static_cast<Body*>(second);

				ContactResultCallback resultCallback;
				this->world.contactPairTest(&body1->object, &body2->object, resultCallback);

				return resultCallback.collision;
			}

			bool
			Scene::areColliding(::rl::sg::Shape* first, ::rl::sg::Shape* second)
			{
				throw Exception("::rl::sg::bullet::Scene::areColliding(::rl::sg::Shape* first, ::rl::sg::Shape* second) - not supported");
			}

			::rl::sg::Model*
			Scene::create()
			{
				return new Model(this);
			}

			::rl::math::Real
			Scene::depth(::rl::sg::Body* first, ::rl::sg::Body* second, ::rl::math::Vector3& point1, ::rl::math::Vector3& point2)
			{
				Body* body1 = static_cast<Body*>(first);
				Body* body2 = static_cast<Body*>(second);

				ContactResultCallback resultCallback;
				this->world.contactPairTest(&body1->object, &body2->object, resultCallback);

				point1.x() = resultCallback.positionWorldOnA.getX();
				point1.y() = resultCallback.positionWorldOnA.getY();
				point1.z() = resultCallback.positionWorldOnA.getZ();

				point2.x() = resultCallback.positionWorldOnB.getX();
				point2.y() = resultCallback.positionWorldOnB.getY();
				point2.z() = resultCallback.positionWorldOnB.getZ();

				return resultCallback.collision ? ::std::abs(resultCallback.distance) : 0;
			}

			::rl::math::Real
			Scene::depth(::rl::sg::Shape* first, ::rl::sg::Shape* second, ::rl::math::Vector3& point1, ::rl::math::Vector3& point2)
			{
				throw Exception("::rl::sg::bullet::Scene::depth(::rl::sg::Shape* first, ::rl::sg::Shape* second, ::rl::math::Vector3& point1, ::rl::math::Vector3& point2) - not supported");
			}

			::rl::math::Real
			Scene::distance(::rl::sg::Shape* first, ::rl::sg::Shape* second, ::rl::math::Vector3& point1, ::rl::math::Vector3& point2)
			{
				Shape* shape1 = static_cast<Shape*>(first);
				Shape* shape2 = static_cast<Shape*>(second);

				if (!shape1->shape->isConvex() || !shape2->shape->isConvex())
				{
					throw Exception("::rl::sg::bullet::Scene::distance() - distance calculation only supported between convex shapes");
				}

				Body* body1 = static_cast<Body*>(shape1->getBody());
				Body* body2 = static_cast<Body*>(shape2->getBody());

				::btVoronoiSimplexSolver simplexSolver;
				::btGjkEpaPenetrationDepthSolver penetrationDepthSolver;
				::btGjkPairDetector pairDetector(
					dynamic_cast< ::btConvexShape*>(shape1->shape),
					dynamic_cast< ::btConvexShape*>(shape2->shape),
					&simplexSolver,
					&penetrationDepthSolver
				);

				::btPointCollector pointCollector;
				::btGjkPairDetector::ClosestPointInput input;
				input.m_transformA = body1->object.getWorldTransform() * shape1->transform;
				input.m_transformB = body2->object.getWorldTransform() * shape2->transform;
				pairDetector.getClosestPoints(input, pointCollector, 0);

				point1.x() = pointCollector.m_pointInWorld.x();
				point1.y() = pointCollector.m_pointInWorld.y();
				point1.z() = pointCollector.m_pointInWorld.z();

				btVector3 endPt = pointCollector.m_pointInWorld + pointCollector.m_normalOnBInWorld * pointCollector.m_distance;

				point2.x() = endPt.x();
				point2.y() = endPt.y();
				point2.z() = endPt.z();

				return pointCollector.m_distance;
			}

			::rl::math::Real
			Scene::distance(::rl::sg::Shape* shape, const ::rl::math::Vector3& point, ::rl::math::Vector3& point1, ::rl::math::Vector3& point2)
			{
				::btSphereShape sphere(0);

				::btVoronoiSimplexSolver sGjkSimplexSolver;

				::btGjkEpaPenetrationDepthSolver epa;
				::btGjkPairDetector convexConvex(
					dynamic_cast< ::btConvexShape*>(static_cast<Shape*>(shape)->shape),
					dynamic_cast< ::btConvexShape*>(&sphere),
					&sGjkSimplexSolver,
					&epa
				);

				Body* body = static_cast<Body*>(shape->getBody());

				::btPointCollector gjkOutput;
				::btGjkPairDetector::ClosestPointInput input;
				input.m_transformA = body->object.getWorldTransform() * static_cast<Shape*>(shape)->transform;
				input.m_transformB.setIdentity();
				input.m_transformB.getOrigin().setValue(
					static_cast< ::btScalar>(point.x()),
					static_cast< ::btScalar>(point.y()),
					static_cast< ::btScalar>(point.z())
				);

				convexConvex.getClosestPoints(input, gjkOutput, 0);

				point1.x() = gjkOutput.m_pointInWorld.x();
				point1.y() = gjkOutput.m_pointInWorld.y();
				point1.z() = gjkOutput.m_pointInWorld.z();

				::btVector3 endPt = gjkOutput.m_pointInWorld + gjkOutput.m_normalOnBInWorld * gjkOutput.m_distance;

				point2.x() = endPt.x();
				point2.y() = endPt.y();
				point2.z() = endPt.z();

				return gjkOutput.m_distance;
			}

			bool
			Scene::isColliding()
			{
				this->world.performDiscreteCollisionDetection();

				for (int i = 0; i < this->world.getDispatcher()->getNumManifolds(); ++i)
				{
					if (this->world.getDispatcher()->getManifoldByIndexInternal(i)->getNumContacts() > 0)
					{
						return true;
					}
				}

				return false;
			}

			bool
			Scene::isScalingSupported() const
			{
				return false;
			}

			::rl::sg::Shape*
			Scene::raycast(const ::rl::math::Vector3& source, const ::rl::math::Vector3& target, ::rl::math::Real& distance)
			{
				::btVector3 rayFromWorld(
					static_cast< ::btScalar>(source.x()),
					static_cast< ::btScalar>(source.y()),
					static_cast< ::btScalar>(source.z())
				);

				::btVector3 rayToWorld(
					static_cast< ::btScalar>(target.x()),
					static_cast< ::btScalar>(target.y()),
					static_cast< ::btScalar>(target.z())
				);

				RayResultCallback resultCallback;

				this->world.rayTest(rayFromWorld, rayToWorld, resultCallback);

				if (nullptr != resultCallback.collisionShape)
				{
					::btVector3 hitPointWorld;
					hitPointWorld.setInterpolate3(rayFromWorld, rayToWorld, resultCallback.m_closestHitFraction);
					distance = rayFromWorld.distance(hitPointWorld);
					return static_cast<Shape*>(resultCallback.collisionShape->getUserPointer());
				}
				else
				{
					distance = ::std::numeric_limits< ::btScalar>::quiet_NaN();
					return nullptr;
				}
			}

			bool
			Scene::raycast(::rl::sg::Shape* shape, const ::rl::math::Vector3& source, const ::rl::math::Vector3& target, ::rl::math::Real& distance)
			{
				Body* body = static_cast<Body*>(shape->getBody());

				::btVector3 rayFromWorld(
					static_cast< ::btScalar>(source.x()),
					static_cast< ::btScalar>(source.y()),
					static_cast< ::btScalar>(source.z())
				);

				::btTransform rayFromTrans;
				rayFromTrans.setIdentity();
				rayFromTrans.setOrigin(rayFromWorld);

				::btVector3 rayToWorld(
					static_cast< ::btScalar>(target.x()),
					static_cast< ::btScalar>(target.y()),
					static_cast< ::btScalar>(target.z())
				);

				::btTransform rayToTrans;
				rayToTrans.setIdentity();
				rayToTrans.setOrigin(rayToWorld);

				RayResultCallback resultCallback;

				this->world.rayTestSingle(
					rayFromTrans,
					rayToTrans,
					&body->object,
					static_cast<Shape*>(shape)->shape,
					body->object.getWorldTransform() * static_cast<Shape*>(shape)->transform, // TODO
					resultCallback
				);

				if (nullptr != resultCallback.collisionShape)
				{
					::btVector3 hitPointWorld;
					hitPointWorld.setInterpolate3(rayFromWorld, rayToWorld, resultCallback.m_closestHitFraction);
					distance = rayFromWorld.distance(hitPointWorld);
					return true;
				}
				else
				{
					distance = ::std::numeric_limits< ::btScalar>::quiet_NaN();
					return false;
				}
			}

			Scene::ContactResultCallback::ContactResultCallback() :
				collision(false),
				distance(0),
				positionWorldOnA(),
				positionWorldOnB()
			{
			}

			btScalar
#if (BT_BULLET_VERSION < 281)
			Scene::ContactResultCallback::addSingleResult(::btManifoldPoint& cp, const ::btCollisionObject* colObj0, int partId0, int index0, const ::btCollisionObject* colObj1, int partId1, int index1)
#else
			Scene::ContactResultCallback::addSingleResult(::btManifoldPoint& cp, const ::btCollisionObjectWrapper* colObj0, int partId0, int index0, const ::btCollisionObjectWrapper* colObj1, int partId1, int index1)
#endif
			{
				this->collision = true;

				if (cp.getDistance() <= this->distance)
				{
					this->distance = cp.getDistance();
					this->positionWorldOnA = cp.getPositionWorldOnA();
					this->positionWorldOnB = cp.getPositionWorldOnB();
				}

				return 0;
			}

			Scene::RayResultCallback::RayResultCallback() :
				collisionShape(nullptr),
				hitPointWorld()
			{
			}

			btScalar
			Scene::RayResultCallback::addSingleResult(::btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace)
			{
				this->collisionShape = rayResult.m_collisionObject->getCollisionShape();
				this->m_closestHitFraction = rayResult.m_hitFraction;
				return 0;
			}
		}
	}
}
<commit_msg>Use static_cast to handle USE_MSVC_DISABLE_RTTI option<commit_after>//
// Copyright (c) 2009, Markus Rickert
// 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.
//
// 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 HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//

#include <BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h>
#include <BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h>
#include <BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h>
#include <BulletCollision/NarrowPhaseCollision/btPointCollector.h>
#include <BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h>

#include "../Exception.h"
#include "Body.h"
#include "Model.h"
#include "Scene.h"
#include "Shape.h"

namespace rl
{
	namespace sg
	{
		namespace bullet
		{
			Scene::Scene() :
				::rl::sg::Scene(),
				::rl::sg::DistanceScene(),
				::rl::sg::RaycastScene(),
				::rl::sg::SimpleScene(),
				broadphase(),
				configuration(),
				dispatcher(&configuration),
				world(&dispatcher, &broadphase, &configuration)
			{
			}

			Scene::~Scene()
			{
				while (this->models.size() > 0)
				{
					delete this->models[0];
				}
			}

			bool
			Scene::areColliding(::rl::sg::Body* first, ::rl::sg::Body* second)
			{
				Body* body1 = static_cast<Body*>(first);
				Body* body2 = static_cast<Body*>(second);

				ContactResultCallback resultCallback;
				this->world.contactPairTest(&body1->object, &body2->object, resultCallback);

				return resultCallback.collision;
			}

			bool
			Scene::areColliding(::rl::sg::Shape* first, ::rl::sg::Shape* second)
			{
				throw Exception("::rl::sg::bullet::Scene::areColliding(::rl::sg::Shape* first, ::rl::sg::Shape* second) - not supported");
			}

			::rl::sg::Model*
			Scene::create()
			{
				return new Model(this);
			}

			::rl::math::Real
			Scene::depth(::rl::sg::Body* first, ::rl::sg::Body* second, ::rl::math::Vector3& point1, ::rl::math::Vector3& point2)
			{
				Body* body1 = static_cast<Body*>(first);
				Body* body2 = static_cast<Body*>(second);

				ContactResultCallback resultCallback;
				this->world.contactPairTest(&body1->object, &body2->object, resultCallback);

				point1.x() = resultCallback.positionWorldOnA.getX();
				point1.y() = resultCallback.positionWorldOnA.getY();
				point1.z() = resultCallback.positionWorldOnA.getZ();

				point2.x() = resultCallback.positionWorldOnB.getX();
				point2.y() = resultCallback.positionWorldOnB.getY();
				point2.z() = resultCallback.positionWorldOnB.getZ();

				return resultCallback.collision ? ::std::abs(resultCallback.distance) : 0;
			}

			::rl::math::Real
			Scene::depth(::rl::sg::Shape* first, ::rl::sg::Shape* second, ::rl::math::Vector3& point1, ::rl::math::Vector3& point2)
			{
				throw Exception("::rl::sg::bullet::Scene::depth(::rl::sg::Shape* first, ::rl::sg::Shape* second, ::rl::math::Vector3& point1, ::rl::math::Vector3& point2) - not supported");
			}

			::rl::math::Real
			Scene::distance(::rl::sg::Shape* first, ::rl::sg::Shape* second, ::rl::math::Vector3& point1, ::rl::math::Vector3& point2)
			{
				Shape* shape1 = static_cast<Shape*>(first);
				Shape* shape2 = static_cast<Shape*>(second);

				if (!shape1->shape->isConvex() || !shape2->shape->isConvex())
				{
					throw Exception("::rl::sg::bullet::Scene::distance() - distance calculation only supported between convex shapes");
				}

				Body* body1 = static_cast<Body*>(shape1->getBody());
				Body* body2 = static_cast<Body*>(shape2->getBody());

				::btVoronoiSimplexSolver simplexSolver;
				::btGjkEpaPenetrationDepthSolver penetrationDepthSolver;
				::btGjkPairDetector pairDetector(
					static_cast< ::btConvexShape*>(shape1->shape),
					static_cast< ::btConvexShape*>(shape2->shape),
					&simplexSolver,
					&penetrationDepthSolver
				);

				::btPointCollector pointCollector;
				::btGjkPairDetector::ClosestPointInput input;
				input.m_transformA = body1->object.getWorldTransform() * shape1->transform;
				input.m_transformB = body2->object.getWorldTransform() * shape2->transform;
				pairDetector.getClosestPoints(input, pointCollector, 0);

				point1.x() = pointCollector.m_pointInWorld.x();
				point1.y() = pointCollector.m_pointInWorld.y();
				point1.z() = pointCollector.m_pointInWorld.z();

				btVector3 endPt = pointCollector.m_pointInWorld + pointCollector.m_normalOnBInWorld * pointCollector.m_distance;

				point2.x() = endPt.x();
				point2.y() = endPt.y();
				point2.z() = endPt.z();

				return pointCollector.m_distance;
			}

			::rl::math::Real
			Scene::distance(::rl::sg::Shape* shape, const ::rl::math::Vector3& point, ::rl::math::Vector3& point1, ::rl::math::Vector3& point2)
			{
				::btSphereShape sphere(0);

				::btVoronoiSimplexSolver sGjkSimplexSolver;

				::btGjkEpaPenetrationDepthSolver epa;
				::btGjkPairDetector convexConvex(
					static_cast< ::btConvexShape*>(static_cast<Shape*>(shape)->shape),
					static_cast< ::btConvexShape*>(&sphere),
					&sGjkSimplexSolver,
					&epa
				);

				Body* body = static_cast<Body*>(shape->getBody());

				::btPointCollector gjkOutput;
				::btGjkPairDetector::ClosestPointInput input;
				input.m_transformA = body->object.getWorldTransform() * static_cast<Shape*>(shape)->transform;
				input.m_transformB.setIdentity();
				input.m_transformB.getOrigin().setValue(
					static_cast< ::btScalar>(point.x()),
					static_cast< ::btScalar>(point.y()),
					static_cast< ::btScalar>(point.z())
				);

				convexConvex.getClosestPoints(input, gjkOutput, 0);

				point1.x() = gjkOutput.m_pointInWorld.x();
				point1.y() = gjkOutput.m_pointInWorld.y();
				point1.z() = gjkOutput.m_pointInWorld.z();

				::btVector3 endPt = gjkOutput.m_pointInWorld + gjkOutput.m_normalOnBInWorld * gjkOutput.m_distance;

				point2.x() = endPt.x();
				point2.y() = endPt.y();
				point2.z() = endPt.z();

				return gjkOutput.m_distance;
			}

			bool
			Scene::isColliding()
			{
				this->world.performDiscreteCollisionDetection();

				for (int i = 0; i < this->world.getDispatcher()->getNumManifolds(); ++i)
				{
					if (this->world.getDispatcher()->getManifoldByIndexInternal(i)->getNumContacts() > 0)
					{
						return true;
					}
				}

				return false;
			}

			bool
			Scene::isScalingSupported() const
			{
				return false;
			}

			::rl::sg::Shape*
			Scene::raycast(const ::rl::math::Vector3& source, const ::rl::math::Vector3& target, ::rl::math::Real& distance)
			{
				::btVector3 rayFromWorld(
					static_cast< ::btScalar>(source.x()),
					static_cast< ::btScalar>(source.y()),
					static_cast< ::btScalar>(source.z())
				);

				::btVector3 rayToWorld(
					static_cast< ::btScalar>(target.x()),
					static_cast< ::btScalar>(target.y()),
					static_cast< ::btScalar>(target.z())
				);

				RayResultCallback resultCallback;

				this->world.rayTest(rayFromWorld, rayToWorld, resultCallback);

				if (nullptr != resultCallback.collisionShape)
				{
					::btVector3 hitPointWorld;
					hitPointWorld.setInterpolate3(rayFromWorld, rayToWorld, resultCallback.m_closestHitFraction);
					distance = rayFromWorld.distance(hitPointWorld);
					return static_cast<Shape*>(resultCallback.collisionShape->getUserPointer());
				}
				else
				{
					distance = ::std::numeric_limits< ::btScalar>::quiet_NaN();
					return nullptr;
				}
			}

			bool
			Scene::raycast(::rl::sg::Shape* shape, const ::rl::math::Vector3& source, const ::rl::math::Vector3& target, ::rl::math::Real& distance)
			{
				Body* body = static_cast<Body*>(shape->getBody());

				::btVector3 rayFromWorld(
					static_cast< ::btScalar>(source.x()),
					static_cast< ::btScalar>(source.y()),
					static_cast< ::btScalar>(source.z())
				);

				::btTransform rayFromTrans;
				rayFromTrans.setIdentity();
				rayFromTrans.setOrigin(rayFromWorld);

				::btVector3 rayToWorld(
					static_cast< ::btScalar>(target.x()),
					static_cast< ::btScalar>(target.y()),
					static_cast< ::btScalar>(target.z())
				);

				::btTransform rayToTrans;
				rayToTrans.setIdentity();
				rayToTrans.setOrigin(rayToWorld);

				RayResultCallback resultCallback;

				this->world.rayTestSingle(
					rayFromTrans,
					rayToTrans,
					&body->object,
					static_cast<Shape*>(shape)->shape,
					body->object.getWorldTransform() * static_cast<Shape*>(shape)->transform, // TODO
					resultCallback
				);

				if (nullptr != resultCallback.collisionShape)
				{
					::btVector3 hitPointWorld;
					hitPointWorld.setInterpolate3(rayFromWorld, rayToWorld, resultCallback.m_closestHitFraction);
					distance = rayFromWorld.distance(hitPointWorld);
					return true;
				}
				else
				{
					distance = ::std::numeric_limits< ::btScalar>::quiet_NaN();
					return false;
				}
			}

			Scene::ContactResultCallback::ContactResultCallback() :
				collision(false),
				distance(0),
				positionWorldOnA(),
				positionWorldOnB()
			{
			}

			btScalar
#if (BT_BULLET_VERSION < 281)
			Scene::ContactResultCallback::addSingleResult(::btManifoldPoint& cp, const ::btCollisionObject* colObj0, int partId0, int index0, const ::btCollisionObject* colObj1, int partId1, int index1)
#else
			Scene::ContactResultCallback::addSingleResult(::btManifoldPoint& cp, const ::btCollisionObjectWrapper* colObj0, int partId0, int index0, const ::btCollisionObjectWrapper* colObj1, int partId1, int index1)
#endif
			{
				this->collision = true;

				if (cp.getDistance() <= this->distance)
				{
					this->distance = cp.getDistance();
					this->positionWorldOnA = cp.getPositionWorldOnA();
					this->positionWorldOnB = cp.getPositionWorldOnB();
				}

				return 0;
			}

			Scene::RayResultCallback::RayResultCallback() :
				collisionShape(nullptr),
				hitPointWorld()
			{
			}

			btScalar
			Scene::RayResultCallback::addSingleResult(::btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace)
			{
				this->collisionShape = rayResult.m_collisionObject->getCollisionShape();
				this->m_closestHitFraction = rayResult.m_hitFraction;
				return 0;
			}
		}
	}
}
<|endoftext|>


<commit_before>#include <sys/ioctl.h> // I2C
#include <sys/types.h> // I2C
#include <sys/stat.h> // I2C
#include <linux/i2c-dev.h> // I2C
#include <unistd.h>
#include <fcntl.h>
#include "compass.h"
#include "math.h"

using namespace std;

int compass::start()
{
	init = true;

	/* Initialize i2c compass */
	if ((i2c_fd = open("/dev/i2c-1", O_RDWR)) < 0) {
		//snprintf( (char *)buf, STARBOT_HISTORY_NB_CHAR_X, "** Failed to open i2c bus.");
		//console_log( (char *)buf );
		return 0;
	}

	/* initialise HMC5883L */

	select_i2c_device(i2c_fd, HMC5883L_I2C_ADDR, "HMC5883L");

	write_to_i2c(i2c_fd, 0x01, 32);
	write_to_i2c(i2c_fd, 0x02, 0);

	return 1;
}

int compass::update()
{
	float angle = 0;
	unsigned char i2c_buf[16];
	i2c_buf[0] = 0x03;

	if ((write(i2c_fd, i2c_buf, 1)) != 1) {
		// Send the register to read from
		//fprintf(stderr, "Error writing to i2c slave\n");
		return 0;
	}

	if (read(i2c_fd, i2c_buf, 6) != 6) {
		//fprintf(stderr, "Unable to read from HMC5883L\n");
		return 0;
	}
	else {
		short x = (i2c_buf[0] << 8) | i2c_buf[1];
		short y = (i2c_buf[4] << 8) | i2c_buf[5];
		//short z = (i2c_buf[2] << 8) | i2c_buf[3];

		angle = atan2(y, x) * 180 / M_PI;
	}

	//if(init) {
	//	state = kalman_init( 0.025f, 16, 1, angle );
	//	init = false;
	//}

	//kalman_update( &state, angle );

	bearing = 180 + angle; // state.x;

	return 1;
}

bool compass::select_i2c_device(int fd, int addr, char * name) {
	//char buf[STARBOT_HISTORY_NB_CHAR_X];

	if (ioctl(fd, I2C_SLAVE, addr) < 0) {
		//snprintf( (char *)buf, STARBOT_HISTORY_NB_CHAR_X, "%s not present\n", name);
		//console_log( (char *)buf );

		return false;
	}

	return true;
}

bool compass::write_to_i2c(int fd, int reg, int val) {
	char buf[2];
	//char log[STARBOT_HISTORY_NB_CHAR_X];

	buf[0] = reg;
	buf[1] = val;

	if (write(fd, buf, 2) != 2) {
		//snprintf( (char *)log, STARBOT_HISTORY_NB_CHAR_X, "Can't write to ADXL345\n");
		//console_log( (char *)log );
		return false;
	}

	return true;
}

compass_point compass::get_compass_point() {
	if (bearing >= compass_points[MIN_COMPASS].min || bearing <= compass_points[MIN_COMPASS].max) {
		return compass_points[MIN_COMPASS];
	}

	for (int i = MIN_COMPASS + 1; i < MAX_COMPASS; i++) {
		if (bearing >= compass_points[i].min && bearing <= compass_points[i].max) {
			return compass_points[i];
		}
	}
}

float compass::get_compass_point_variance(compass_point cp) {
	return bearing - cp.mid;
}

<commit_msg>180 conversion<commit_after>#include <sys/ioctl.h> // I2C
#include <sys/types.h> // I2C
#include <sys/stat.h> // I2C
#include <linux/i2c-dev.h> // I2C
#include <unistd.h>
#include <fcntl.h>
#include "compass.h"
#include "math.h"

using namespace std;

int compass::start()
{
	init = true;

	/* Initialize i2c compass */
	if ((i2c_fd = open("/dev/i2c-1", O_RDWR)) < 0) {
		//snprintf( (char *)buf, STARBOT_HISTORY_NB_CHAR_X, "** Failed to open i2c bus.");
		//console_log( (char *)buf );
		return 0;
	}

	/* initialise HMC5883L */

	select_i2c_device(i2c_fd, HMC5883L_I2C_ADDR, "HMC5883L");

	write_to_i2c(i2c_fd, 0x01, 32);
	write_to_i2c(i2c_fd, 0x02, 0);

	return 1;
}

int compass::update()
{
	float angle = 0;
	unsigned char i2c_buf[16];
	i2c_buf[0] = 0x03;

	if ((write(i2c_fd, i2c_buf, 1)) != 1) {
		// Send the register to read from
		//fprintf(stderr, "Error writing to i2c slave\n");
		return 0;
	}

	if (read(i2c_fd, i2c_buf, 6) != 6) {
		//fprintf(stderr, "Unable to read from HMC5883L\n");
		return 0;
	}
	else {
		short x = (i2c_buf[0] << 8) | i2c_buf[1];
		short y = (i2c_buf[4] << 8) | i2c_buf[5];
		//short z = (i2c_buf[2] << 8) | i2c_buf[3];

		angle = atan2(y, x) * 180 / M_PI;
	}

	//if(init) {
	//	state = kalman_init( 0.025f, 16, 1, angle );
	//	init = false;
	//}

	//kalman_update( &state, angle );

	bearing = angle - 180; // state.x;

	return 1;
}

bool compass::select_i2c_device(int fd, int addr, char * name) {
	//char buf[STARBOT_HISTORY_NB_CHAR_X];

	if (ioctl(fd, I2C_SLAVE, addr) < 0) {
		//snprintf( (char *)buf, STARBOT_HISTORY_NB_CHAR_X, "%s not present\n", name);
		//console_log( (char *)buf );

		return false;
	}

	return true;
}

bool compass::write_to_i2c(int fd, int reg, int val) {
	char buf[2];
	//char log[STARBOT_HISTORY_NB_CHAR_X];

	buf[0] = reg;
	buf[1] = val;

	if (write(fd, buf, 2) != 2) {
		//snprintf( (char *)log, STARBOT_HISTORY_NB_CHAR_X, "Can't write to ADXL345\n");
		//console_log( (char *)log );
		return false;
	}

	return true;
}

compass_point compass::get_compass_point() {
	if (bearing >= compass_points[MIN_COMPASS].min || bearing <= compass_points[MIN_COMPASS].max) {
		return compass_points[MIN_COMPASS];
	}

	for (int i = MIN_COMPASS + 1; i < MAX_COMPASS; i++) {
		if (bearing >= compass_points[i].min && bearing <= compass_points[i].max) {
			return compass_points[i];
		}
	}
}

float compass::get_compass_point_variance(compass_point cp) {
	return bearing - cp.mid;
}

<|endoftext|>


<commit_before>#include "sceneitems/terrain.hpp"

#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

#include "heightmap/heightmapgenerator.hpp"
#include "render/shaderpipeline.hpp"

sceneitems::Terrain::Terrain(const glm::mat4 myParentMatrix) : parentMatrix(myParentMatrix), rotation(STATIONARY) {
	//Create VAO and VBO
	glGenVertexArrays(1, vaos);
	glBindVertexArray(vaos[0]);

	glGenBuffers(1, vbos);
	glBindBuffer(GL_ARRAY_BUFFER, vbos[0]);

	//Generate heightmap
	HeightmapGenerator* hmgen = new HeightmapGenerator(65, 0, 75);
	hmgen->fillMap();
	hmgen->convertMap();

	//Buffer heightmap-data to VBO
	vertexCount = hmgen->getVertexCount();
	glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(HMVertex), hmgen->getVertices(), GL_STATIC_DRAW);

	//Set vertex attribute index 0 to current VBO
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
	glEnableVertexAttribArray(0);

	//Create UBO
	glGenBuffers(1, ubos);

	//Scale 0.1x
	modelMatrix = glm::scale<float>(glm::mat4(1.0f), glm::vec3(0.1f, 0.1f, 0.1f));
	updateMatrix();

	//Create shader pipeline
	render::ShaderPipeLine shaderpipe("Vertex-Pass Y", "Fragment-Colour Height");
	shaderpipe.addShaderAttribute("vertex");
	shaderpipe.setShaderUniform("hmMatrices", ubos[0]);

	shaderpipe.linkPipeLine();
	shaderProgram = shaderpipe.getShaderProgram();
}

void sceneitems::Terrain::updateMatrix() {
	glBindBuffer(GL_UNIFORM_BUFFER, ubos[0]);

	//Rotation
	float degrees;
	switch(rotation) {
	case LEFT:
		degrees = 1.0f;
		break;
	case RIGHT:
		degrees = -1.0f;
		break;
	}

	if(rotation != STATIONARY) {
		modelMatrix = glm::rotate<float>(modelMatrix, degrees, glm::vec3(0.0f, 1.0f, 0.0f));
	}

	//HACK Temporarily get a new parentMatrix from World till we have a proper scene graph
	parentMatrix = scene::World::getMatrix();

	glm::mat4 mVPMatrix = parentMatrix * modelMatrix;

	glBufferData(GL_UNIFORM_BUFFER, sizeof(glm::mat4), glm::value_ptr(mVPMatrix), GL_DYNAMIC_DRAW);
}

void sceneitems::Terrain::render() const {
	glBindVertexArray(vaos[0]);
	glUseProgram(shaderProgram);

	glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexCount);
}
<commit_msg>Fix memory leak in Terrain constructor<commit_after>#include "sceneitems/terrain.hpp"

#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

#include "heightmap/heightmapgenerator.hpp"
#include "render/shaderpipeline.hpp"

sceneitems::Terrain::Terrain(const glm::mat4 myParentMatrix) : parentMatrix(myParentMatrix), rotation(STATIONARY) {
	//Create VAO and VBO
	glGenVertexArrays(1, vaos);
	glBindVertexArray(vaos[0]);

	glGenBuffers(1, vbos);
	glBindBuffer(GL_ARRAY_BUFFER, vbos[0]);

	//Generate heightmap
	HeightmapGenerator hmgen(65, 0, 75);
	hmgen.fillMap();
	hmgen.convertMap();

	//Buffer heightmap-data to VBO
	vertexCount = hmgen.getVertexCount();
	glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(HMVertex), hmgen.getVertices(), GL_STATIC_DRAW);

	//Set vertex attribute index 0 to current VBO
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
	glEnableVertexAttribArray(0);

	//Create UBO
	glGenBuffers(1, ubos);

	//Scale 0.1x
	modelMatrix = glm::scale<float>(glm::mat4(1.0f), glm::vec3(0.1f, 0.1f, 0.1f));
	updateMatrix();

	//Create shader pipeline
	render::ShaderPipeLine shaderpipe("Vertex-Pass Y", "Fragment-Colour Height");
	shaderpipe.addShaderAttribute("vertex");
	shaderpipe.setShaderUniform("hmMatrices", ubos[0]);

	shaderpipe.linkPipeLine();
	shaderProgram = shaderpipe.getShaderProgram();
}

void sceneitems::Terrain::updateMatrix() {
	glBindBuffer(GL_UNIFORM_BUFFER, ubos[0]);

	//Rotation
	float degrees;
	switch(rotation) {
	case LEFT:
		degrees = 1.0f;
		break;
	case RIGHT:
		degrees = -1.0f;
		break;
	}

	if(rotation != STATIONARY) {
		modelMatrix = glm::rotate<float>(modelMatrix, degrees, glm::vec3(0.0f, 1.0f, 0.0f));
	}

	//HACK Temporarily get a new parentMatrix from World till we have a proper scene graph
	parentMatrix = scene::World::getMatrix();

	glm::mat4 mVPMatrix = parentMatrix * modelMatrix;

	glBufferData(GL_UNIFORM_BUFFER, sizeof(glm::mat4), glm::value_ptr(mVPMatrix), GL_DYNAMIC_DRAW);
}

void sceneitems::Terrain::render() const {
	glBindVertexArray(vaos[0]);
	glUseProgram(shaderProgram);

	glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexCount);
}
<|endoftext|>


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

#ifndef _CHART2_CHARTTYPEHELPER_HXX
#define _CHART2_CHARTTYPEHELPER_HXX

#ifndef _COM_SUN_STAR_CHART2_XCHARTTYPE_HPP_
#include <com/sun/star/chart2/XChartType.hpp>
#endif
#ifndef _COM_SUN_STAR_CHART2_AXISTYPE_HPP_
#include <com/sun/star/chart2/AxisType.hpp>
#endif

#ifndef _COM_SUN_STAR_DRAWING_DIRECTION3D_HPP_
#include <com/sun/star/drawing/Direction3D.hpp>
#endif

//.............................................................................
namespace chart
{
//.............................................................................

//-----------------------------------------------------------------------------
/**
*/

class ChartTypeHelper
{
public:
    static sal_Bool isSupportingGeometryProperties(  const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType, sal_Int32 nDimensionCount );
    static sal_Bool isSupportingStatisticProperties( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType, sal_Int32 nDimensionCount );
    static sal_Bool isSupportingRegressionProperties(const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType, sal_Int32 nDimensionCount );
    static sal_Bool isSupportingMainAxis(            const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType, sal_Int32 nDimensionCount, sal_Int32 nDimensionIndex );
    static sal_Bool isSupportingSecondaryAxis(       const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType, sal_Int32 nDimensionCount, sal_Int32 nDimensionIndex );
    static sal_Bool isSupportingAreaProperties(      const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType, sal_Int32 nDimensionCount );
    static sal_Bool isSupportingSymbolProperties(    const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType, sal_Int32 nDimensionCount );
    static sal_Bool isSupportingOverlapAndGapWidthProperties( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType, sal_Int32 nDimensionCount );
    static sal_Bool isSupportingBarConnectors(       const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType, sal_Int32 nDimensionCount );
    static sal_Bool isSupportingRightAngledAxes(       const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType );

    static ::com::sun::star::drawing::Direction3D getDefaultSimpleLightDirection( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType );
    static ::com::sun::star::drawing::Direction3D getDefaultRealisticLightDirection( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType );
    static sal_Int32 getDefaultDirectLightColor( bool bSimple, const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType );
    static sal_Int32 getDefaultAmbientLightColor( bool bSimple, const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType );
    static bool noBordersForSimpleScheme( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType );

    static sal_Int32 //one of ::com::sun::star::chart2::AxisType
                    getAxisType( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType
                                , sal_Int32 nDimensionIndex );
};

//.............................................................................
} //namespace chart
//.............................................................................
#endif
<commit_msg>INTEGRATION: CWS chart11 (1.9.14); FILE MERGED 2007/08/17 16:30:21 bm 1.9.14.1: #i67225# do not include invisible objects in ObjectHierarchy for a11y and keyboard navigation<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ChartTypeHelper.hxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: vg $ $Date: 2007-09-18 14:57:19 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _CHART2_CHARTTYPEHELPER_HXX
#define _CHART2_CHARTTYPEHELPER_HXX

#ifndef _COM_SUN_STAR_CHART2_XCHARTTYPE_HPP_
#include <com/sun/star/chart2/XChartType.hpp>
#endif
#ifndef _COM_SUN_STAR_CHART2_AXISTYPE_HPP_
#include <com/sun/star/chart2/AxisType.hpp>
#endif

#ifndef _COM_SUN_STAR_DRAWING_DIRECTION3D_HPP_
#include <com/sun/star/drawing/Direction3D.hpp>
#endif

//.............................................................................
namespace chart
{
//.............................................................................

//-----------------------------------------------------------------------------
/**
*/

class ChartTypeHelper
{
public:
    static sal_Bool isSupportingGeometryProperties(  const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType, sal_Int32 nDimensionCount );
    static sal_Bool isSupportingStatisticProperties( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType, sal_Int32 nDimensionCount );
    static sal_Bool isSupportingRegressionProperties(const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType, sal_Int32 nDimensionCount );
    static sal_Bool isSupportingMainAxis(            const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType, sal_Int32 nDimensionCount, sal_Int32 nDimensionIndex );
    static sal_Bool isSupportingSecondaryAxis(       const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType, sal_Int32 nDimensionCount, sal_Int32 nDimensionIndex );
    static sal_Bool isSupportingAreaProperties(      const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType, sal_Int32 nDimensionCount );
    static sal_Bool isSupportingSymbolProperties(    const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType, sal_Int32 nDimensionCount );
    static sal_Bool isSupportingOverlapAndGapWidthProperties( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType, sal_Int32 nDimensionCount );
    static sal_Bool isSupportingBarConnectors(       const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType, sal_Int32 nDimensionCount );
    static sal_Bool isSupportingRightAngledAxes(       const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType );

    static ::com::sun::star::drawing::Direction3D getDefaultSimpleLightDirection( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType );
    static ::com::sun::star::drawing::Direction3D getDefaultRealisticLightDirection( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType );
    static sal_Int32 getDefaultDirectLightColor( bool bSimple, const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType );
    static sal_Int32 getDefaultAmbientLightColor( bool bSimple, const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType );
    static sal_Int32 getNumberOfDisplayedSeries( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType, sal_Int32 nNumberOfSeries );
    static bool noBordersForSimpleScheme( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType );

    static sal_Int32 //one of ::com::sun::star::chart2::AxisType
                    getAxisType( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType
                                , sal_Int32 nDimensionIndex );
};

//.............................................................................
} //namespace chart
//.............................................................................
#endif
<|endoftext|>


<commit_before>/**
 * Challenge #333 [Easy] Packet Assembler
 *
 * https://www.reddit.com/r/dailyprogrammer/comments/72ivih/20170926_challenge_333_easy_packet_assembler/
 */

int main(void) {
    return 0;
}

<commit_msg>Solution implemented<commit_after>/**
 * Challenge #333 [Easy] Packet Assembler
 *
 * https://www.reddit.com/r/dailyprogrammer/comments/72ivih/20170926_challenge_333_easy_packet_assembler/
 *
 * Start 9:50 PM
 * Stop xx:xx xx
 */

#include <fstream>
#include <iostream>
#include <sstream>

#include <map>
#include <set>
#include <string>
#include <vector>

std::ifstream inf("input.txt");
std::ofstream ouf("output.txt");

#define cout ouf // Uncomment this line to echo state to stdout

/**
 * Packet element holds sorting information in addition to the primary message
 */
struct PacketElement {
    int messageId;    //!< The message ID is the highest group level
    int packetId;     //!< zero-indexed location of the message
    int packetCount;  //!< Total number of packets in the message
    std::string line; //!< The entire package input line

    // Constructor maps the sorting information onto semantic variables
    PacketElement(int messageId, int packetId, int packetCount, std::string line)
    {
        this->messageId = messageId;
        this->packetId  = packetId;
        this->packetCount = packetCount;
        this->line = line;
    }

    // Elements are sorted on @packetId to return correct relative ordering
    bool operator< (const PacketElement& rhs) const {
        return packetId < rhs.packetId;
    }
};

/**
 * The packet container stores packet collections based on message ID
 */
typedef std::pair<int, std::set<PacketElement> > PacketIdToPacket;
typedef std::map<int, std::set<PacketElement> > MessageToPackets;

/**
 * Prototypes
 */
PacketElement generatePacketElement(const std::string& line);
void storePacketElementIntoSortedContainer(const PacketElement packetElement, MessageToPackets& packets);
void readPackets(MessageToPackets& packets);

/**
 * MAIN
 */
using namespace std;
int main(void) {
    // The primary packet container stores first by message, and then packet ID
    MessageToPackets packets;

    // Read the lines of input (simulating stdin)
    string line = "";
    while(getline(inf, line))
    {
        // Generate and store the packet element onto container
        PacketElement packetElement = generatePacketElement(line);
        storePacketElementIntoSortedContainer(packetElement, packets);
    }

    // The entire contents of the container echoed at the end for completeness
    // Note that the contents may be queried anytime, such as whithin the loop
    readPackets(packets);

    return 0;
}

/**
 * Parses the input packet message to extract sorting information
 *
 * @param line
 *      raw HTML input message
 * @return
 *      PacketElement containing the parsed location information
 */
PacketElement generatePacketElement(const std::string& line)
{
    // Read line into a string stream based on " "
    stringstream ss(line);

    // Read the first three integers X Y Z into string array
    int x,y,z;
    ss >> x;
    ss >> y;
    ss >> z;

    return PacketElement(x,y,z,line);
}

/**
 * Stores packet elements onto the passed container
 *
 * @param packetElement
 *      copy of the packet element that will be stored
 * @param packets
 *      packet container
 */
void storePacketElementIntoSortedContainer(const PacketElement packetElement, MessageToPackets& packets)
{
    // Check if packet sub-container exists
    if(packets.find(packetElement.messageId) == packets.end())
    {
        set<PacketElement> elements;
        packets.insert(PacketIdToPacket(packetElement.messageId, elements));
    }

    // Extract the packet elements container to store the new input
    set<PacketElement>& elements = packets.find(packetElement.messageId)->second;
    elements.insert(packetElement);

    return;
}

void readPackets(MessageToPackets& packets)
{
    // Primary loop is over all message ID's
    MessageToPackets::iterator messageBlock = packets.begin();
    MessageToPackets::iterator messageEnd = packets.end();
    for (; messageBlock != messageEnd; ++messageBlock)
    {
        // Secondary loop is over all packet ID's
        set<PacketElement>& elements = messageBlock->second;
        set<PacketElement>::iterator it = elements.begin();
        set<PacketElement>::iterator et = elements.end();
        for (; it != et; ++it)
        {
            cout << it->line << endl;
        }
    }

    return;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: StockBar.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: ihi $ $Date: 2008-01-14 14:02:06 $
 *
 *  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_chart2.hxx"

#include "StockBar.hxx"
#include "LineProperties.hxx"
#include "FillProperties.hxx"
#include "UserDefinedProperties.hxx"
#include "PropertyHelper.hxx"
#include "macros.hxx"
#include "ContainerHelper.hxx"

#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
#include <com/sun/star/beans/PropertyAttribute.hpp>
#endif
#ifndef _COM_SUN_STAR_STYLE_XSTYLE_HPP_
#include <com/sun/star/style/XStyle.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif

#ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_
#include <com/sun/star/uno/Sequence.hxx>
#endif

#include <algorithm>

using namespace ::com::sun::star;

using ::com::sun::star::uno::Reference;
using ::com::sun::star::beans::Property;
using ::osl::MutexGuard;

// ____________________________________________________________

namespace
{

static const ::rtl::OUString lcl_aServiceName(
    RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart2.StockBar" ));

const uno::Sequence< Property > & lcl_GetPropertySequence()
{
    static uno::Sequence< Property > aPropSeq;

    // /--
    MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
    if( 0 == aPropSeq.getLength() )
    {
        // get properties
        ::std::vector< ::com::sun::star::beans::Property > aProperties;
        ::chart::LineProperties::AddPropertiesToVector( aProperties );
        ::chart::FillProperties::AddPropertiesToVector( aProperties );
        ::chart::UserDefinedProperties::AddPropertiesToVector( aProperties );

        // and sort them for access via bsearch
        ::std::sort( aProperties.begin(), aProperties.end(),
                     ::chart::PropertyNameLess() );

        // transfer result to static Sequence
        aPropSeq = ::chart::ContainerHelper::ContainerToSequence( aProperties );
    }

    return aPropSeq;
}

void lcl_AddDefaultsToMap(
    ::chart::tPropertyValueMap & rOutMap )
{
    // override other defaults
    ::chart::PropertyHelper::setPropertyValue< sal_Int32 >( rOutMap, ::chart::FillProperties::PROP_FILL_COLOR, 0xffffff ); // white
}

::cppu::IPropertyArrayHelper & lcl_getInfoHelper()
{
    static ::cppu::OPropertyArrayHelper aArrayHelper(
        lcl_GetPropertySequence(),
        /* bSorted = */ sal_True );

    return aArrayHelper;
}

} // anonymous namespace

// ____________________________________________________________

namespace chart
{

StockBar::StockBar( bool bRisingCourse ) :
        ::property::OPropertySet( m_aMutex ),
    m_bRisingCourse( bRisingCourse ),
    m_xModifyEventForwarder( new ModifyListenerHelper::ModifyEventForwarder())
{
    if( ! m_bRisingCourse )
    {
        setFastPropertyValue_NoBroadcast(
            ::chart::FillProperties::PROP_FILL_COLOR,
            uno::makeAny( sal_Int32( 0x000000 ))); // black
        setFastPropertyValue_NoBroadcast(
            ::chart::LineProperties::PROP_LINE_COLOR,
            uno::makeAny( sal_Int32( 0xb3b3b3 ))); // gray30
    }
}

StockBar::StockBar( const StockBar & rOther ) :
        MutexContainer(),
        impl::StockBar_Base(),
        ::property::OPropertySet( rOther, m_aMutex ),
    m_bRisingCourse( rOther.m_bRisingCourse ),
    m_xModifyEventForwarder( new ModifyListenerHelper::ModifyEventForwarder())
{}

StockBar::~StockBar()
{}

// ____ XCloneable ____
uno::Reference< util::XCloneable > SAL_CALL StockBar::createClone()
    throw (uno::RuntimeException)
{
    return uno::Reference< util::XCloneable >( new StockBar( *this ));
}

// ____ OPropertySet ____
uno::Any StockBar::GetDefaultValue( sal_Int32 nHandle ) const
    throw(beans::UnknownPropertyException)
{
    static tPropertyValueMap aStaticDefaults;

    // /--
    ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
    if( 0 == aStaticDefaults.size() )
    {
        // initialize defaults
        LineProperties::AddDefaultsToMap( aStaticDefaults );
        FillProperties::AddDefaultsToMap( aStaticDefaults );

        // overrides a line property
        lcl_AddDefaultsToMap( aStaticDefaults );
    }

    tPropertyValueMap::const_iterator aFound(
        aStaticDefaults.find( nHandle ));

    if( aFound == aStaticDefaults.end())
        return uno::Any();

    return (*aFound).second;
    // \--
}

::cppu::IPropertyArrayHelper & SAL_CALL StockBar::getInfoHelper()
{
    return lcl_getInfoHelper();
}

// ____ XPropertySet ____
Reference< beans::XPropertySetInfo > SAL_CALL
    StockBar::getPropertySetInfo()
    throw (uno::RuntimeException)
{
    static Reference< beans::XPropertySetInfo > xInfo;

    // /--
    ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
    if( !xInfo.is())
    {
        xInfo = ::cppu::OPropertySetHelper::createPropertySetInfo(
            lcl_getInfoHelper());
    }

    return xInfo;
    // \--
}

// ____ XModifyBroadcaster ____
void SAL_CALL StockBar::addModifyListener( const uno::Reference< util::XModifyListener >& aListener )
    throw (uno::RuntimeException)
{
    try
    {
        uno::Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW );
        xBroadcaster->addModifyListener( aListener );
    }
    catch( const uno::Exception & ex )
    {
        ASSERT_EXCEPTION( ex );
    }
}

void SAL_CALL StockBar::removeModifyListener( const uno::Reference< util::XModifyListener >& aListener )
    throw (uno::RuntimeException)
{
    try
    {
        uno::Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW );
        xBroadcaster->removeModifyListener( aListener );
    }
    catch( const uno::Exception & ex )
    {
        ASSERT_EXCEPTION( ex );
    }
}

// ____ XModifyListener ____
void SAL_CALL StockBar::modified( const lang::EventObject& aEvent )
    throw (uno::RuntimeException)
{
    m_xModifyEventForwarder->modified( aEvent );
}

// ____ XEventListener (base of XModifyListener) ____
void SAL_CALL StockBar::disposing( const lang::EventObject& /* Source */ )
    throw (uno::RuntimeException)
{
    // nothing
}

// ____ OPropertySet ____
void StockBar::firePropertyChangeEvent()
{
    fireModifyEvent();
}

void StockBar::fireModifyEvent()
{
    m_xModifyEventForwarder->modified( lang::EventObject( static_cast< uno::XWeak* >( this )));
}

// ================================================================================

uno::Sequence< ::rtl::OUString > StockBar::getSupportedServiceNames_Static()
{
    uno::Sequence< ::rtl::OUString > aServices( 2 );
    aServices[ 0 ] = C2U( "com.sun.star.chart2.StockBar" );
    aServices[ 1 ] = C2U( "com.sun.star.beans.PropertySet" );
    return aServices;
}

// implement XServiceInfo methods basing upon getSupportedServiceNames_Static
APPHELPER_XSERVICEINFO_IMPL( StockBar, lcl_aServiceName );

using impl::StockBar_Base;

IMPLEMENT_FORWARD_XINTERFACE2( StockBar, StockBar_Base, ::property::OPropertySet )

} //  namespace chart
<commit_msg>INTEGRATION: CWS changefileheader (1.5.44); FILE MERGED 2008/04/01 15:04:19 thb 1.5.44.3: #i85898# Stripping all external header guards 2008/04/01 10:50:33 thb 1.5.44.2: #i85898# Stripping all external header guards 2008/03/28 16:44:09 rt 1.5.44.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: StockBar.cxx,v $
 * $Revision: 1.6 $
 *
 * 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_chart2.hxx"

#include "StockBar.hxx"
#include "LineProperties.hxx"
#include "FillProperties.hxx"
#include "UserDefinedProperties.hxx"
#include "PropertyHelper.hxx"
#include "macros.hxx"
#include "ContainerHelper.hxx"
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/style/XStyle.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/uno/Sequence.hxx>

#include <algorithm>

using namespace ::com::sun::star;

using ::com::sun::star::uno::Reference;
using ::com::sun::star::beans::Property;
using ::osl::MutexGuard;

// ____________________________________________________________

namespace
{

static const ::rtl::OUString lcl_aServiceName(
    RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart2.StockBar" ));

const uno::Sequence< Property > & lcl_GetPropertySequence()
{
    static uno::Sequence< Property > aPropSeq;

    // /--
    MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
    if( 0 == aPropSeq.getLength() )
    {
        // get properties
        ::std::vector< ::com::sun::star::beans::Property > aProperties;
        ::chart::LineProperties::AddPropertiesToVector( aProperties );
        ::chart::FillProperties::AddPropertiesToVector( aProperties );
        ::chart::UserDefinedProperties::AddPropertiesToVector( aProperties );

        // and sort them for access via bsearch
        ::std::sort( aProperties.begin(), aProperties.end(),
                     ::chart::PropertyNameLess() );

        // transfer result to static Sequence
        aPropSeq = ::chart::ContainerHelper::ContainerToSequence( aProperties );
    }

    return aPropSeq;
}

void lcl_AddDefaultsToMap(
    ::chart::tPropertyValueMap & rOutMap )
{
    // override other defaults
    ::chart::PropertyHelper::setPropertyValue< sal_Int32 >( rOutMap, ::chart::FillProperties::PROP_FILL_COLOR, 0xffffff ); // white
}

::cppu::IPropertyArrayHelper & lcl_getInfoHelper()
{
    static ::cppu::OPropertyArrayHelper aArrayHelper(
        lcl_GetPropertySequence(),
        /* bSorted = */ sal_True );

    return aArrayHelper;
}

} // anonymous namespace

// ____________________________________________________________

namespace chart
{

StockBar::StockBar( bool bRisingCourse ) :
        ::property::OPropertySet( m_aMutex ),
    m_bRisingCourse( bRisingCourse ),
    m_xModifyEventForwarder( new ModifyListenerHelper::ModifyEventForwarder())
{
    if( ! m_bRisingCourse )
    {
        setFastPropertyValue_NoBroadcast(
            ::chart::FillProperties::PROP_FILL_COLOR,
            uno::makeAny( sal_Int32( 0x000000 ))); // black
        setFastPropertyValue_NoBroadcast(
            ::chart::LineProperties::PROP_LINE_COLOR,
            uno::makeAny( sal_Int32( 0xb3b3b3 ))); // gray30
    }
}

StockBar::StockBar( const StockBar & rOther ) :
        MutexContainer(),
        impl::StockBar_Base(),
        ::property::OPropertySet( rOther, m_aMutex ),
    m_bRisingCourse( rOther.m_bRisingCourse ),
    m_xModifyEventForwarder( new ModifyListenerHelper::ModifyEventForwarder())
{}

StockBar::~StockBar()
{}

// ____ XCloneable ____
uno::Reference< util::XCloneable > SAL_CALL StockBar::createClone()
    throw (uno::RuntimeException)
{
    return uno::Reference< util::XCloneable >( new StockBar( *this ));
}

// ____ OPropertySet ____
uno::Any StockBar::GetDefaultValue( sal_Int32 nHandle ) const
    throw(beans::UnknownPropertyException)
{
    static tPropertyValueMap aStaticDefaults;

    // /--
    ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
    if( 0 == aStaticDefaults.size() )
    {
        // initialize defaults
        LineProperties::AddDefaultsToMap( aStaticDefaults );
        FillProperties::AddDefaultsToMap( aStaticDefaults );

        // overrides a line property
        lcl_AddDefaultsToMap( aStaticDefaults );
    }

    tPropertyValueMap::const_iterator aFound(
        aStaticDefaults.find( nHandle ));

    if( aFound == aStaticDefaults.end())
        return uno::Any();

    return (*aFound).second;
    // \--
}

::cppu::IPropertyArrayHelper & SAL_CALL StockBar::getInfoHelper()
{
    return lcl_getInfoHelper();
}

// ____ XPropertySet ____
Reference< beans::XPropertySetInfo > SAL_CALL
    StockBar::getPropertySetInfo()
    throw (uno::RuntimeException)
{
    static Reference< beans::XPropertySetInfo > xInfo;

    // /--
    ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
    if( !xInfo.is())
    {
        xInfo = ::cppu::OPropertySetHelper::createPropertySetInfo(
            lcl_getInfoHelper());
    }

    return xInfo;
    // \--
}

// ____ XModifyBroadcaster ____
void SAL_CALL StockBar::addModifyListener( const uno::Reference< util::XModifyListener >& aListener )
    throw (uno::RuntimeException)
{
    try
    {
        uno::Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW );
        xBroadcaster->addModifyListener( aListener );
    }
    catch( const uno::Exception & ex )
    {
        ASSERT_EXCEPTION( ex );
    }
}

void SAL_CALL StockBar::removeModifyListener( const uno::Reference< util::XModifyListener >& aListener )
    throw (uno::RuntimeException)
{
    try
    {
        uno::Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW );
        xBroadcaster->removeModifyListener( aListener );
    }
    catch( const uno::Exception & ex )
    {
        ASSERT_EXCEPTION( ex );
    }
}

// ____ XModifyListener ____
void SAL_CALL StockBar::modified( const lang::EventObject& aEvent )
    throw (uno::RuntimeException)
{
    m_xModifyEventForwarder->modified( aEvent );
}

// ____ XEventListener (base of XModifyListener) ____
void SAL_CALL StockBar::disposing( const lang::EventObject& /* Source */ )
    throw (uno::RuntimeException)
{
    // nothing
}

// ____ OPropertySet ____
void StockBar::firePropertyChangeEvent()
{
    fireModifyEvent();
}

void StockBar::fireModifyEvent()
{
    m_xModifyEventForwarder->modified( lang::EventObject( static_cast< uno::XWeak* >( this )));
}

// ================================================================================

uno::Sequence< ::rtl::OUString > StockBar::getSupportedServiceNames_Static()
{
    uno::Sequence< ::rtl::OUString > aServices( 2 );
    aServices[ 0 ] = C2U( "com.sun.star.chart2.StockBar" );
    aServices[ 1 ] = C2U( "com.sun.star.beans.PropertySet" );
    return aServices;
}

// implement XServiceInfo methods basing upon getSupportedServiceNames_Static
APPHELPER_XSERVICEINFO_IMPL( StockBar, lcl_aServiceName );

using impl::StockBar_Base;

IMPLEMENT_FORWARD_XINTERFACE2( StockBar, StockBar_Base, ::property::OPropertySet )

} //  namespace chart
<|endoftext|>


<commit_before>// Scintilla source code edit control
/** @file KeyWords.cxx
 ** Colourise for particular languages.
 **/
// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>

#include <vector>

#include "ILexer.h"
#include "Scintilla.h"
#include "SciLexer.h"

#include "LexerModule.h"
#include "Catalogue.h"

#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif

static std::vector<LexerModule *> lexerCatalogue;
static int nextLanguage = SCLEX_AUTOMATIC+1;

const LexerModule *Catalogue::Find(int language) {
	Scintilla_LinkLexers();
	for (std::vector<LexerModule *>::iterator it=lexerCatalogue.begin();
		it != lexerCatalogue.end(); ++it) {
		if ((*it)->GetLanguage() == language) {
			return *it;
		}
	}
	return 0;
}

const LexerModule *Catalogue::Find(const char *languageName) {
	Scintilla_LinkLexers();
	if (languageName) {
		for (std::vector<LexerModule *>::iterator it=lexerCatalogue.begin();
			it != lexerCatalogue.end(); ++it) {
			if ((*it)->languageName && (0 == strcmp((*it)->languageName, languageName))) {
				return *it;
			}
		}
	}
	return 0;
}

void Catalogue::AddLexerModule(LexerModule *plm) {
	if (plm->GetLanguage() == SCLEX_AUTOMATIC) {
		plm->language = nextLanguage;
		nextLanguage++;
	}
	lexerCatalogue.push_back(plm);
}

// Alternative historical name for Scintilla_LinkLexers
int wxForceScintillaLexers(void) {
	return Scintilla_LinkLexers();
}

// To add or remove a lexer, add or remove its file and run LexGen.py.

// Force a reference to all of the Scintilla lexers so that the linker will
// not remove the code of the lexers.
int Scintilla_LinkLexers() {

	static int initialised = 0;
	if (initialised)
		return 0;
	initialised = 1;

// Shorten the code that declares a lexer and ensures it is linked in by calling a method.
#define LINK_LEXER(lexer) extern LexerModule lexer; Catalogue::AddLexerModule(&lexer);

//++Autogenerated -- run src/LexGen.py to regenerate
//**\(\tLINK_LEXER(\*);\n\)
//	LINK_LEXER(lmA68k);
/* notepad2-mod custom code, comment out the unused lexers */
//	LINK_LEXER(lmAbaqus);
//	LINK_LEXER(lmAda);
	LINK_LEXER(lmAHK);
//	LINK_LEXER(lmAns1);
//	LINK_LEXER(lmAPDL);
	LINK_LEXER(lmAsm);
//	LINK_LEXER(lmASY);
	LINK_LEXER(lmAU3);
//	LINK_LEXER(lmAVE);
//	LINK_LEXER(lmBaan);
	LINK_LEXER(lmBash);
	LINK_LEXER(lmBatch);
//	LINK_LEXER(lmBlitzBasic);
//	LINK_LEXER(lmBullant);
//	LINK_LEXER(lmCaml);
//	LINK_LEXER(lmClw);
//	LINK_LEXER(lmClwNoCase);
//	LINK_LEXER(lmCmake);
//	LINK_LEXER(lmCOBOL);
	LINK_LEXER(lmConf);
	LINK_LEXER(lmCPP);
//	LINK_LEXER(lmCPPNoCase);
//	LINK_LEXER(lmCsound);
	LINK_LEXER(lmCss);
//	LINK_LEXER(lmD);
	LINK_LEXER(lmDiff);
//	LINK_LEXER(lmEiffel);
//	LINK_LEXER(lmEiffelkw);
//	LINK_LEXER(lmErlang);
//	LINK_LEXER(lmErrorList);
//	LINK_LEXER(lmESCRIPT);
//	LINK_LEXER(lmF77);
//	LINK_LEXER(lmFlagShip);
//	LINK_LEXER(lmForth);
//	LINK_LEXER(lmFortran);
//	LINK_LEXER(lmFreeBasic);
//	LINK_LEXER(lmGAP);
//	LINK_LEXER(lmGui4Cli);
//	LINK_LEXER(lmHaskell);
	LINK_LEXER(lmHTML);
	LINK_LEXER(lmInno);
//	LINK_LEXER(lmKix);
	LINK_LEXER(lmLatex);
//	LINK_LEXER(lmLISP);
//	LINK_LEXER(lmLot);
//	LINK_LEXER(lmLout);
	LINK_LEXER(lmLua);
//	LINK_LEXER(lmMagikSF);
	LINK_LEXER(lmMake);
//	LINK_LEXER(lmMarkdown);
//	LINK_LEXER(lmMatlab);
//	LINK_LEXER(lmMETAPOST);
//	LINK_LEXER(lmMMIXAL);
//	LINK_LEXER(lmMSSQL);
//	LINK_LEXER(lmMySQL);
//	LINK_LEXER(lmNimrod);
//	LINK_LEXER(lmNncrontab);
	LINK_LEXER(lmNsis);
//	LINK_LEXER(lmNull);
//	LINK_LEXER(lmOctave);
//	LINK_LEXER(lmOpal);
	LINK_LEXER(lmPascal);
//	LINK_LEXER(lmPB);
	LINK_LEXER(lmPerl);
//	LINK_LEXER(lmPHPSCRIPT);
//	LINK_LEXER(lmPLM);
//	LINK_LEXER(lmPo);
//	LINK_LEXER(lmPOV);
//	LINK_LEXER(lmPowerPro);
	LINK_LEXER(lmPowerShell);
//	LINK_LEXER(lmProgress);
	LINK_LEXER(lmProps);
//	LINK_LEXER(lmPS);
//	LINK_LEXER(lmPureBasic);
	LINK_LEXER(lmPython);
//	LINK_LEXER(lmR);
//	LINK_LEXER(lmREBOL);
	LINK_LEXER(lmRuby);
//	LINK_LEXER(lmScriptol);
//	LINK_LEXER(lmSmalltalk);
//	LINK_LEXER(lmSML);
//	LINK_LEXER(lmSorc);
//	LINK_LEXER(lmSpecman);
//	LINK_LEXER(lmSpice);
	LINK_LEXER(lmSQL);
//	LINK_LEXER(lmTACL);
//	LINK_LEXER(lmTADS3);
//	LINK_LEXER(lmTAL);
	LINK_LEXER(lmTCL);
//	LINK_LEXER(lmTeX);
//	LINK_LEXER(lmTxt2tags);
	LINK_LEXER(lmVB);
	LINK_LEXER(lmVBScript);
//	LINK_LEXER(lmVerilog);
//	LINK_LEXER(lmVHDL);
	LINK_LEXER(lmXML);
//	LINK_LEXER(lmYAML);

//--Autogenerated -- end of automatically generated section

	return 1;
}
<commit_msg><commit_after>// Scintilla source code edit control
/** @file KeyWords.cxx
 ** Colourise for particular languages.
 **/
// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>

#include <vector>

#include "ILexer.h"
#include "Scintilla.h"
#include "SciLexer.h"

#include "LexerModule.h"
#include "Catalogue.h"

#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif

static std::vector<LexerModule *> lexerCatalogue;
static int nextLanguage = SCLEX_AUTOMATIC+1;

const LexerModule *Catalogue::Find(int language) {
	Scintilla_LinkLexers();
	for (std::vector<LexerModule *>::iterator it=lexerCatalogue.begin();
		it != lexerCatalogue.end(); ++it) {
		if ((*it)->GetLanguage() == language) {
			return *it;
		}
	}
	return 0;
}

const LexerModule *Catalogue::Find(const char *languageName) {
	Scintilla_LinkLexers();
	if (languageName) {
		for (std::vector<LexerModule *>::iterator it=lexerCatalogue.begin();
			it != lexerCatalogue.end(); ++it) {
			if ((*it)->languageName && (0 == strcmp((*it)->languageName, languageName))) {
				return *it;
			}
		}
	}
	return 0;
}

void Catalogue::AddLexerModule(LexerModule *plm) {
	if (plm->GetLanguage() == SCLEX_AUTOMATIC) {
		plm->language = nextLanguage;
		nextLanguage++;
	}
	lexerCatalogue.push_back(plm);
}

// Alternative historical name for Scintilla_LinkLexers
int wxForceScintillaLexers(void) {
	return Scintilla_LinkLexers();
}

// To add or remove a lexer, add or remove its file and run LexGen.py.

// Force a reference to all of the Scintilla lexers so that the linker will
// not remove the code of the lexers.
int Scintilla_LinkLexers() {

	static int initialised = 0;
	if (initialised)
		return 0;
	initialised = 1;

// Shorten the code that declares a lexer and ensures it is linked in by calling a method.
#define LINK_LEXER(lexer) extern LexerModule lexer; Catalogue::AddLexerModule(&lexer);

//++Autogenerated -- run src/LexGen.py to regenerate
//**\(\tLINK_LEXER(\*);\n\)
//	LINK_LEXER(lmA68k);
/* notepad2-mod custom code, comment out the unused lexers */
//	LINK_LEXER(lmAbaqus);
//	LINK_LEXER(lmAda);
	LINK_LEXER(lmAHK);
//	LINK_LEXER(lmAns1);
//	LINK_LEXER(lmAPDL);
	LINK_LEXER(lmAsm);
//	LINK_LEXER(lmASY);
	LINK_LEXER(lmAU3);
//	LINK_LEXER(lmAVE);
//	LINK_LEXER(lmBaan);
	LINK_LEXER(lmBash);
	LINK_LEXER(lmBatch);
//	LINK_LEXER(lmBlitzBasic);
//	LINK_LEXER(lmBullant);
//	LINK_LEXER(lmCaml);
//	LINK_LEXER(lmClw);
//	LINK_LEXER(lmClwNoCase);
//	LINK_LEXER(lmCmake);
//	LINK_LEXER(lmCOBOL);
	LINK_LEXER(lmConf);
	LINK_LEXER(lmCPP);
//	LINK_LEXER(lmCPPNoCase);
//	LINK_LEXER(lmCsound);
	LINK_LEXER(lmCss);
//	LINK_LEXER(lmD);
	LINK_LEXER(lmDiff);
//	LINK_LEXER(lmEiffel);
//	LINK_LEXER(lmEiffelkw);
//	LINK_LEXER(lmErlang);
//	LINK_LEXER(lmErrorList);
//	LINK_LEXER(lmESCRIPT);
//	LINK_LEXER(lmF77);
//	LINK_LEXER(lmFlagShip);
//	LINK_LEXER(lmForth);
//	LINK_LEXER(lmFortran);
//	LINK_LEXER(lmFreeBasic);
//	LINK_LEXER(lmGAP);
//	LINK_LEXER(lmGui4Cli);
//	LINK_LEXER(lmHaskell);
	LINK_LEXER(lmHTML);
	LINK_LEXER(lmInno);
//	LINK_LEXER(lmKix);
	LINK_LEXER(lmLatex);
//	LINK_LEXER(lmLISP);
//	LINK_LEXER(lmLot);
//	LINK_LEXER(lmLout);
	LINK_LEXER(lmLua);
//	LINK_LEXER(lmMagikSF);
	LINK_LEXER(lmMake);
//	LINK_LEXER(lmMarkdown);
//	LINK_LEXER(lmMatlab);
//	LINK_LEXER(lmMETAPOST);
//	LINK_LEXER(lmMMIXAL);
//	LINK_LEXER(lmMSSQL);
//	LINK_LEXER(lmMySQL);
//	LINK_LEXER(lmNimrod);
//	LINK_LEXER(lmNncrontab);
	LINK_LEXER(lmNsis);
//	LINK_LEXER(lmNull);
//	LINK_LEXER(lmOctave);
//	LINK_LEXER(lmOpal);
	LINK_LEXER(lmPascal);
//	LINK_LEXER(lmPB);
	LINK_LEXER(lmPerl);
	LINK_LEXER(lmPHPSCRIPT);
//	LINK_LEXER(lmPLM);
//	LINK_LEXER(lmPo);
//	LINK_LEXER(lmPOV);
//	LINK_LEXER(lmPowerPro);
	LINK_LEXER(lmPowerShell);
//	LINK_LEXER(lmProgress);
	LINK_LEXER(lmProps);
//	LINK_LEXER(lmPS);
//	LINK_LEXER(lmPureBasic);
	LINK_LEXER(lmPython);
//	LINK_LEXER(lmR);
//	LINK_LEXER(lmREBOL);
	LINK_LEXER(lmRuby);
//	LINK_LEXER(lmScriptol);
//	LINK_LEXER(lmSmalltalk);
//	LINK_LEXER(lmSML);
//	LINK_LEXER(lmSorc);
//	LINK_LEXER(lmSpecman);
//	LINK_LEXER(lmSpice);
	LINK_LEXER(lmSQL);
//	LINK_LEXER(lmTACL);
//	LINK_LEXER(lmTADS3);
//	LINK_LEXER(lmTAL);
	LINK_LEXER(lmTCL);
//	LINK_LEXER(lmTeX);
//	LINK_LEXER(lmTxt2tags);
	LINK_LEXER(lmVB);
	LINK_LEXER(lmVBScript);
//	LINK_LEXER(lmVerilog);
//	LINK_LEXER(lmVHDL);
	LINK_LEXER(lmXML);
//	LINK_LEXER(lmYAML);

//--Autogenerated -- end of automatically generated section

	return 1;
}
<|endoftext|>


<commit_before>#include "blocked_gzip_input_stream.hpp"

#include "hfile_cppstream.hpp"

// We need the hFILE* internals available.
#include <hfile_internal.h>

namespace vg {

namespace stream {

using namespace std;

BlockedGzipInputStream::BlockedGzipInputStream(std::istream& stream) : handle(nullptr), byte_count(0),
    know_offset(false) {

    // See where the stream is
    stream.clear();
    auto file_start = stream.tellg();
    bool good = stream.good();

    // Wrap the stream in an hFILE*
    hFILE* wrapped = hfile_wrap(stream);
    if (wrapped == nullptr) {
        throw runtime_error("Unable to wrap stream");
    }

    // Give ownership of it to a BGZF that reads, which we in turn own.
    handle = bgzf_hopen(wrapped, "r");
    if (handle == nullptr) {
        throw runtime_error("Unable to set up BGZF library on wrapped stream");
    }

    if (file_start >= 0 && good && bgzf_compression(handle) == 2) {
        // The stream we are wrapping is seekable, and the data is block-compressed

        // We need to make sure BGZF knows where its blocks are starting.

        // We just freshly opened the BGZF so it thinks it is at 0.

        // Tell the BGZF where its next block is actually starting.
        handle->block_address = file_start;

        // Remember the virtual offsets will be valid
        know_offset = true;
    }
}

BlockedGzipInputStream::~BlockedGzipInputStream() {
    // Close the GBZF
    bgzf_close(handle);
}

bool BlockedGzipInputStream::Next(const void** data, int* size) {
    if (handle->block_length != 0 && handle->block_offset != handle->block_length) {
        // We aren't just after a seek, but we also aren't at the end of a block. We backed up.

        // The already-read data may have started at an offset. But we don't
        // care, because if we back up by X bytes we always re-read the last X
        // bytes of the block.

        // Return the unread part of the BGZF file's buffer
        *data = (void*)((char*)handle->uncompressed_block + handle->block_offset);
        *size = handle->block_length - handle->block_offset;

        // Send the offset to the end of the block again
        handle->block_offset = handle->block_length;
        handle->uncompressed_address += *size;

#ifdef debug
        cerr << "Re-emit " << *size << " bytes of backed-up data, move to " << handle->block_offset << "/" << handle->block_length << endl;
        cerr << "errcode: " << handle->errcode << endl;
#endif

        return true;
    } else {
        // We need new data. Either we did a seek, or we are at the end of the previous block.

        if (bgzf_compression(handle) != 2) {
            // We're not BGZF compressed. bgzf_read_block only resets the
            // block_offset (when not seeking) for BGZF files. We have to do it
            // manually.
            handle->block_offset = 0;
        }

#ifdef debug
        cerr << "Compression mode: " << bgzf_compression(handle) << endl;
        cerr << "Read next block; offset is " << handle->block_offset << endl;
        if (handle->gz_stream != nullptr) {
            cerr << "\tavail_in: " << handle->gz_stream->avail_in << endl;
            if (handle->gz_stream->avail_in > 0) {
                cerr << "\t\tShould not read from backing file!" << endl;
            }
            cerr << "\tavail_out: " << handle->gz_stream->avail_out << endl;
        }
#endif

        // Make the BGZF read the next block
        if (bgzf_read_block(handle) != 0) {
            // We have encountered an error

#ifdef debug
            cerr << "Failed to read next block" << endl;
            cerr << "\terrcode: " << handle->errcode << endl;
#endif

            return false;
        }

#ifdef debug
        cerr << "See a block of length " << handle->block_length << " at " << handle->block_address << endl;
        cerr << "\terrcode: " << handle->errcode << endl;
        if (handle->gz_stream != nullptr) {
            cerr << "\tavail_in: " << handle->gz_stream->avail_in << endl;
            cerr << "\tavail_out: " << handle->gz_stream->avail_out << endl;
        }
#endif

        if (handle->block_length == 0) {
            // We have hit EOF

#ifdef debug
            cerr << "Next block reports length 0 (EOF)" << endl;
            cerr << "\terrcode: " << handle->errcode << endl;
#endif

            return false;
        }

        // Otherwise we have data.

        if (handle->block_offset > handle->block_length) {
            // We don't have enough data to fulfill the most recent seek. Signal an error.

#ifdef debug
            cerr << "Tried to seek to " << handle->block_offset << " but got only " <<  handle->block_length << " bytes" << endl;
            cerr << "\terrcode: " << handle->errcode << endl;
#endif

            return false;
        }

        // Send out the address and size, accounting for seek offset
        *data = (void*)((char*)handle->uncompressed_block + handle->block_offset);
        *size = handle->block_length - handle->block_offset;

        // Record the bytes read
        byte_count += handle->block_length - handle->block_offset;

        // Tell the BGZF that the cursor is at the end of the block (because it
        // is; subsequent reads come from there)
        handle->block_offset = handle->block_length;
        handle->uncompressed_address += *size;

#ifdef debug
        cerr << "Emit " << *size << " bytes in fresh block" << endl;
        cerr << "\terrcode: " << handle->errcode << endl;
#endif

        return true;
    }
}

void BlockedGzipInputStream::BackUp(int count) {
    assert(count <= handle->block_offset);
    handle->block_offset -= count;
    handle->uncompressed_address -= count;

#ifdef debug
    cerr << "Back up " << count << " bytes to " << handle->block_offset << "/" << handle->block_length << endl;
#endif
}

bool BlockedGzipInputStream::Skip(int count) {
    // We just implement this in terms of next and back up. There's not really
    // a more efficient way, since we can't do relative seeks.

    // We have to support this happening immediately after a seek.

    while (count > 0) {
        // Keep nexting until we get the block that is count away from where we are.
        const void* ignored_data;
        int size;

        if (!Next(&ignored_data, &size)) {
            // We hit EOF, or had an error.
            return false;
        }

        // We accomplished this much skipping.
        count -= size;
    }

    if (count < 0) {
        // We went too far. But we know we want to go somewhere in this buffer,
        // or we would have finished the loop before we did.
        BackUp(-count);
        count = 0;
    }

    return true;

}

int64_t BlockedGzipInputStream::ByteCount() const {
    return byte_count;
}

int64_t BlockedGzipInputStream::Tell() const {
    if (know_offset) {
        // Our virtual offsets are true.

        // But since we are happy to leave the BGZF's cursor at the ends of
        // blocks, we have to work out what the real virtual offset should be
        // in that case (byte 0 of the next block)
        if (handle->block_offset == handle->block_length) {
            // We need to know where the next block is

            // We don't have bgzf_htell so we fake it.
            // We also manually shift the block address to the right place.
            return htell(handle->fp) << 16;

        } else {
            // Since we use the BGZF's internal cursor correctly, we can rely on its tell function.
            return bgzf_tell(handle);
        }
    } else {
        // We don't know where the zero position in the stream was, so we can't
        // trust BGZF's virtual offsets.
        return -1;
    }
}

bool BlockedGzipInputStream::Seek(int64_t virtual_offset) {
    if (!know_offset) {
        // We can't seek
        return false;
    }

    // Do the seek, and return whether it worked.
    // This will set handle->block_length to 0, so we know we need to read the block when we read next.
    return bgzf_seek(handle, virtual_offset, SEEK_SET) == 0;

    // We won't find out if there's actually data there until we try to read...
}

}

}

<commit_msg>Instrument to report BGZF seek errors<commit_after>#include "blocked_gzip_input_stream.hpp"

#include "hfile_cppstream.hpp"

// We need the hFILE* internals available.
#include <hfile_internal.h>

namespace vg {

namespace stream {

using namespace std;

BlockedGzipInputStream::BlockedGzipInputStream(std::istream& stream) : handle(nullptr), byte_count(0),
    know_offset(false) {

    // See where the stream is
    stream.clear();
    auto file_start = stream.tellg();
    bool good = stream.good();

    // Wrap the stream in an hFILE*
    hFILE* wrapped = hfile_wrap(stream);
    if (wrapped == nullptr) {
        throw runtime_error("Unable to wrap stream");
    }

    // Give ownership of it to a BGZF that reads, which we in turn own.
    handle = bgzf_hopen(wrapped, "r");
    if (handle == nullptr) {
        throw runtime_error("Unable to set up BGZF library on wrapped stream");
    }

    if (file_start >= 0 && good && bgzf_compression(handle) == 2) {
        // The stream we are wrapping is seekable, and the data is block-compressed

        // We need to make sure BGZF knows where its blocks are starting.

        // We just freshly opened the BGZF so it thinks it is at 0.

        // Tell the BGZF where its next block is actually starting.
        handle->block_address = file_start;

        // Remember the virtual offsets will be valid
        know_offset = true;
    }
}

BlockedGzipInputStream::~BlockedGzipInputStream() {
    // Close the GBZF
    bgzf_close(handle);
}

bool BlockedGzipInputStream::Next(const void** data, int* size) {
    if (handle->block_length != 0 && handle->block_offset != handle->block_length) {
        // We aren't just after a seek, but we also aren't at the end of a block. We backed up.

        // The already-read data may have started at an offset. But we don't
        // care, because if we back up by X bytes we always re-read the last X
        // bytes of the block.

        // Return the unread part of the BGZF file's buffer
        *data = (void*)((char*)handle->uncompressed_block + handle->block_offset);
        *size = handle->block_length - handle->block_offset;

        // Send the offset to the end of the block again
        handle->block_offset = handle->block_length;
        handle->uncompressed_address += *size;

#ifdef debug
        cerr << "Re-emit " << *size << " bytes of backed-up data, move to " << handle->block_offset << "/" << handle->block_length << endl;
        cerr << "errcode: " << handle->errcode << endl;
#endif

        return true;
    } else {
        // We need new data. Either we did a seek, or we are at the end of the previous block.

        if (bgzf_compression(handle) != 2) {
            // We're not BGZF compressed. bgzf_read_block only resets the
            // block_offset (when not seeking) for BGZF files. We have to do it
            // manually.
            handle->block_offset = 0;
        }

#ifdef debug
        cerr << "Compression mode: " << bgzf_compression(handle) << endl;
        cerr << "Read next block; offset is " << handle->block_offset << endl;
        if (handle->gz_stream != nullptr) {
            cerr << "\tavail_in: " << handle->gz_stream->avail_in << endl;
            if (handle->gz_stream->avail_in > 0) {
                cerr << "\t\tShould not read from backing file!" << endl;
            }
            cerr << "\tavail_out: " << handle->gz_stream->avail_out << endl;
        }
#endif

        // Make the BGZF read the next block
        if (bgzf_read_block(handle) != 0) {
            // We have encountered an error

#ifdef debug
            cerr << "Failed to read next block" << endl;
            cerr << "\terrcode: " << handle->errcode << endl;
#endif

            return false;
        }

#ifdef debug
        cerr << "See a block of length " << handle->block_length << " at " << handle->block_address << endl;
        cerr << "\terrcode: " << handle->errcode << endl;
        if (handle->gz_stream != nullptr) {
            cerr << "\tavail_in: " << handle->gz_stream->avail_in << endl;
            cerr << "\tavail_out: " << handle->gz_stream->avail_out << endl;
        }
#endif

        if (handle->block_length == 0) {
            // We have hit EOF

#ifdef debug
            cerr << "Next block reports length 0 (EOF)" << endl;
            cerr << "\terrcode: " << handle->errcode << endl;
#endif

            return false;
        }

        // Otherwise we have data.

        if (handle->block_offset > handle->block_length) {
            // We don't have enough data to fulfill the most recent seek. Signal an error.

#ifdef debug
            cerr << "Tried to seek to " << handle->block_offset << " but got only " <<  handle->block_length << " bytes" << endl;
            cerr << "\terrcode: " << handle->errcode << endl;
#endif

            return false;
        }

        // Send out the address and size, accounting for seek offset
        *data = (void*)((char*)handle->uncompressed_block + handle->block_offset);
        *size = handle->block_length - handle->block_offset;

        // Record the bytes read
        byte_count += handle->block_length - handle->block_offset;

        // Tell the BGZF that the cursor is at the end of the block (because it
        // is; subsequent reads come from there)
        handle->block_offset = handle->block_length;
        handle->uncompressed_address += *size;

#ifdef debug
        cerr << "Emit " << *size << " bytes in fresh block" << endl;
        cerr << "\terrcode: " << handle->errcode << endl;
#endif

        return true;
    }
}

void BlockedGzipInputStream::BackUp(int count) {
    assert(count <= handle->block_offset);
    handle->block_offset -= count;
    handle->uncompressed_address -= count;

#ifdef debug
    cerr << "Back up " << count << " bytes to " << handle->block_offset << "/" << handle->block_length << endl;
#endif
}

bool BlockedGzipInputStream::Skip(int count) {
    // We just implement this in terms of next and back up. There's not really
    // a more efficient way, since we can't do relative seeks.

    // We have to support this happening immediately after a seek.

    while (count > 0) {
        // Keep nexting until we get the block that is count away from where we are.
        const void* ignored_data;
        int size;

        if (!Next(&ignored_data, &size)) {
            // We hit EOF, or had an error.
            return false;
        }

        // We accomplished this much skipping.
        count -= size;
    }

    if (count < 0) {
        // We went too far. But we know we want to go somewhere in this buffer,
        // or we would have finished the loop before we did.
        BackUp(-count);
        count = 0;
    }

    return true;

}

int64_t BlockedGzipInputStream::ByteCount() const {
    return byte_count;
}

int64_t BlockedGzipInputStream::Tell() const {
    if (know_offset) {
        // Our virtual offsets are true.

        // But since we are happy to leave the BGZF's cursor at the ends of
        // blocks, we have to work out what the real virtual offset should be
        // in that case (byte 0 of the next block)
        if (handle->block_offset == handle->block_length) {
            // We need to know where the next block is

            // We don't have bgzf_htell so we fake it.
            // We also manually shift the block address to the right place.
            return htell(handle->fp) << 16;

        } else {
            // Since we use the BGZF's internal cursor correctly, we can rely on its tell function.
            return bgzf_tell(handle);
        }
    } else {
        // We don't know where the zero position in the stream was, so we can't
        // trust BGZF's virtual offsets.
        return -1;
    }
}

bool BlockedGzipInputStream::Seek(int64_t virtual_offset) {
    if (!know_offset) {
        // We can't seek
        return false;
    }

    // Do the seek.
    // This will set handle->block_length to 0, so we know we need to read the block when we read next.
    if(bgzf_seek(handle, virtual_offset, SEEK_SET) == 0) {
        // The seek succeeded
        return true;
    } else {
        // The seek failed
        // Error info is in handle->errcode and handle->fp->has_errno
        // Log the error
        cerr << "error[vg::BlockedGzipInputStream]: BGZF seek error: errcode: "
            << handle->errcode << " errno: " << handle->fp->has_errno << endl;
        return false;
    }

    // We won't find out if there's actually data there until we try to read...
}

}

}

<|endoftext|>