<commit_before>#include <sofa/helper/system/config.h>
#include <sofa/core/ObjectFactory.h>
#include <iostream>

namespace sofa
{

namespace simulation
{

namespace tree
{

void init()
{
    static bool first = true;
    if (first)
    {
        std::cout << "Sofa components initialized."<<std::endl;

        //std::ofstream ofile("sofa-classes.html");
        //ofile << "\n";
        //sofa::core::ObjectFactory::getInstance()->dumpHTML(ofile);
        //ofile << "\n";
        first = false;
    }
}

} // namespace tree

} // namespace simulation

} // namespace sofa

////////// BEGIN CLASS LIST //////////
SOFA_LINK_CLASS(BarycentricLagrangianMultiplierContact)
SOFA_LINK_CLASS(BarycentricMapping)
SOFA_LINK_CLASS(BarycentricPenalityContact)
SOFA_LINK_CLASS(BeamFEMForceField)
SOFA_LINK_CLASS(BruteForce)
SOFA_LINK_CLASS(CGImplicit)
SOFA_LINK_CLASS(ComplianceCGImplicitSolver)
SOFA_LINK_CLASS(MatrixStatic)
SOFA_LINK_CLASS(DefaultCollisionGroupManager)
SOFA_LINK_CLASS(DefaultContactManager)
SOFA_LINK_CLASS(ContinuousIntersection)
SOFA_LINK_CLASS(ComplianceEuler)
SOFA_LINK_CLASS(CoordinateSystem)
SOFA_LINK_CLASS(Cube)
SOFA_LINK_CLASS(DiagonalMass)
SOFA_LINK_CLASS(DiscreteIntersection)
SOFA_LINK_CLASS(EdgePressureForceField)
SOFA_LINK_CLASS(EdgeRemoveContact)
SOFA_LINK_CLASS(EdgeSetTopology)
SOFA_LINK_CLASS(Euler)
SOFA_LINK_CLASS(ExternalForceField)
SOFA_LINK_CLASS(FixedConstraint)
SOFA_LINK_CLASS(FixedPlaneConstraint)
SOFA_LINK_CLASS(Fluid2D)
SOFA_LINK_CLASS(Fluid3D)
SOFA_LINK_CLASS(FrictionLessContact)
SOFA_LINK_CLASS(GNode)
SOFA_LINK_CLASS(Gravity)
SOFA_LINK_CLASS(GridTopology)
SOFA_LINK_CLASS(IdentityMapping)
SOFA_LINK_CLASS(ImageBMP)
SOFA_LINK_CLASS(ImagePNG)
SOFA_DECL_CLASS(ImplicitFieldIntersection)
SOFA_LINK_CLASS(ImplicitSurfaceMapping)
SOFA_LINK_CLASS(LagrangianMultiplierAttachConstraint)
SOFA_LINK_CLASS(LagrangianMultiplierContactConstraint)
SOFA_LINK_CLASS(LagrangianMultiplierFixedConstraint)
SOFA_LINK_CLASS(LaparoscopicRigidMapping)
SOFA_LINK_CLASS(LennardJonesForceField)
SOFA_LINK_CLASS(Line)
SOFA_LINK_CLASS(MasterContactSolver)
SOFA_LINK_CLASS(MechanicalObject)
SOFA_LINK_CLASS(MeshOBJ)
SOFA_LINK_CLASS(MeshSpringForceField)
SOFA_LINK_CLASS(MeshTopology)
SOFA_LINK_CLASS(MeshTrian)
SOFA_LINK_CLASS(MinProximityIntersection)
//SOFA_LINK_CLASS(MultiResSparseGridTopology)
SOFA_LINK_CLASS(Node)
SOFA_LINK_CLASS(Object)
SOFA_LINK_CLASS(OglModel)
SOFA_LINK_CLASS(OscillatorConstraint)
SOFA_LINK_CLASS(PenalityContactForceField)
SOFA_LINK_CLASS(DefaultPipeline)
SOFA_LINK_CLASS(PlaneForceField)
SOFA_LINK_CLASS(Point)
SOFA_LINK_CLASS(PointSetTopology)
SOFA_LINK_CLASS(ProximityIntersection)
SOFA_LINK_CLASS(Ray)
SOFA_LINK_CLASS(RayContact)
SOFA_LINK_CLASS(RegularGridSpringForceField)
SOFA_LINK_CLASS(RegularGridTopology)
SOFA_LINK_CLASS(RepulsiveSpringForceField)
SOFA_LINK_CLASS(RigidMapping)
SOFA_LINK_CLASS(RungeKutta4)
SOFA_LINK_CLASS(BoxConstraint)
//SOFA_LINK_CLASS(SparseGridSpringForceField)
SOFA_LINK_CLASS(Sphere)
SOFA_LINK_CLASS(SphereForceField)
SOFA_LINK_CLASS(SPHFluidForceField)
SOFA_LINK_CLASS(SPHFluidSurfaceMapping)
SOFA_LINK_CLASS(SpringForceField)
//SOFA_LINK_CLASS(SpringEdgeDataForceField)
SOFA_LINK_CLASS(StaticSolver)
SOFA_LINK_CLASS(StiffSpringForceField)
SOFA_LINK_CLASS(SurfaceIdentityMapping)
SOFA_LINK_CLASS(SubsetMapping)
//SOFA_LINK_CLASS(TensorForceField)
SOFA_LINK_CLASS(TetrahedronFEMForceField)
SOFA_LINK_CLASS(ThreadSimulation)
SOFA_LINK_CLASS(Triangle)
SOFA_LINK_CLASS(TriangleBendingSprings)
SOFA_LINK_CLASS(TriangleFEMForceField)
SOFA_LINK_CLASS(FittedRegularGridTopology)
SOFA_LINK_CLASS(UniformMass)
SOFA_LINK_CLASS(TestDetection)
SOFA_LINK_CLASS(SphereTreeModel)
//SOFA_LINK_CLASS(VoxelGrid)
SOFA_LINK_CLASS(WashingMachineForceField)
SOFA_LINK_CLASS(ReadState)
SOFA_LINK_CLASS(WriteState)
SOFA_LINK_CLASS(QuadBendingSprings)
<commit_msg>r1014/sofa-dev : FIX compilation<commit_after>#include <sofa/helper/system/config.h>
#include <sofa/core/ObjectFactory.h>
#include <iostream>

namespace sofa
{

namespace simulation
{

namespace tree
{

void init()
{
    static bool first = true;
    if (first)
    {
        std::cout << "Sofa components initialized."<<std::endl;

        //std::ofstream ofile("sofa-classes.html");
        //ofile << "\n";
        //sofa::core::ObjectFactory::getInstance()->dumpHTML(ofile);
        //ofile << "\n";
        first = false;
    }
}

} // namespace tree

} // namespace simulation

} // namespace sofa

////////// BEGIN CLASS LIST //////////
SOFA_LINK_CLASS(BarycentricLagrangianMultiplierContact)
SOFA_LINK_CLASS(BarycentricMapping)
SOFA_LINK_CLASS(BarycentricPenalityContact)
SOFA_LINK_CLASS(BeamFEMForceField)
SOFA_LINK_CLASS(BruteForce)
SOFA_LINK_CLASS(CGImplicit)
SOFA_LINK_CLASS(ComplianceCGImplicitSolver)
SOFA_LINK_CLASS(MatrixStatic)
SOFA_LINK_CLASS(DefaultCollisionGroupManager)
SOFA_LINK_CLASS(DefaultContactManager)
SOFA_LINK_CLASS(ContinuousIntersection)
SOFA_LINK_CLASS(ComplianceEuler)
SOFA_LINK_CLASS(CoordinateSystem)
SOFA_LINK_CLASS(Cube)
SOFA_LINK_CLASS(DiagonalMass)
SOFA_LINK_CLASS(DiscreteIntersection)
SOFA_LINK_CLASS(EdgePressureForceField)
SOFA_LINK_CLASS(EdgeRemoveContact)
SOFA_LINK_CLASS(EdgeSetTopology)
SOFA_LINK_CLASS(Euler)
SOFA_LINK_CLASS(ExternalForceField)
SOFA_LINK_CLASS(FixedConstraint)
SOFA_LINK_CLASS(FixedPlaneConstraint)
SOFA_LINK_CLASS(Fluid2D)
SOFA_LINK_CLASS(Fluid3D)
SOFA_LINK_CLASS(FrictionLessContact)
SOFA_LINK_CLASS(GNode)
SOFA_LINK_CLASS(Gravity)
SOFA_LINK_CLASS(GridTopology)
SOFA_LINK_CLASS(IdentityMapping)
SOFA_LINK_CLASS(ImageBMP)
SOFA_LINK_CLASS(ImagePNG)
SOFA_LINK_CLASS(ImplicitSurfaceMapping)
SOFA_LINK_CLASS(LagrangianMultiplierAttachConstraint)
SOFA_LINK_CLASS(LagrangianMultiplierContactConstraint)
SOFA_LINK_CLASS(LagrangianMultiplierFixedConstraint)
SOFA_LINK_CLASS(LaparoscopicRigidMapping)
SOFA_LINK_CLASS(LennardJonesForceField)
SOFA_LINK_CLASS(Line)
SOFA_LINK_CLASS(MasterContactSolver)
SOFA_LINK_CLASS(MechanicalObject)
SOFA_LINK_CLASS(MeshOBJ)
SOFA_LINK_CLASS(MeshSpringForceField)
SOFA_LINK_CLASS(MeshTopology)
SOFA_LINK_CLASS(MeshTrian)
SOFA_LINK_CLASS(MinProximityIntersection)
//SOFA_LINK_CLASS(MultiResSparseGridTopology)
SOFA_LINK_CLASS(Node)
SOFA_LINK_CLASS(Object)
SOFA_LINK_CLASS(OglModel)
SOFA_LINK_CLASS(OscillatorConstraint)
SOFA_LINK_CLASS(PenalityContactForceField)
SOFA_LINK_CLASS(DefaultPipeline)
SOFA_LINK_CLASS(PlaneForceField)
SOFA_LINK_CLASS(Point)
SOFA_LINK_CLASS(PointSetTopology)
SOFA_LINK_CLASS(ProximityIntersection)
SOFA_LINK_CLASS(Ray)
SOFA_LINK_CLASS(RayContact)
SOFA_LINK_CLASS(RegularGridSpringForceField)
SOFA_LINK_CLASS(RegularGridTopology)
SOFA_LINK_CLASS(RepulsiveSpringForceField)
SOFA_LINK_CLASS(RigidMapping)
SOFA_LINK_CLASS(RungeKutta4)
SOFA_LINK_CLASS(BoxConstraint)
//SOFA_LINK_CLASS(SparseGridSpringForceField)
SOFA_LINK_CLASS(Sphere)
SOFA_LINK_CLASS(SphereForceField)
SOFA_LINK_CLASS(SPHFluidForceField)
SOFA_LINK_CLASS(SPHFluidSurfaceMapping)
SOFA_LINK_CLASS(SpringForceField)
//SOFA_LINK_CLASS(SpringEdgeDataForceField)
SOFA_LINK_CLASS(StaticSolver)
SOFA_LINK_CLASS(StiffSpringForceField)
SOFA_LINK_CLASS(SurfaceIdentityMapping)
SOFA_LINK_CLASS(SubsetMapping)
//SOFA_LINK_CLASS(TensorForceField)
SOFA_LINK_CLASS(TetrahedronFEMForceField)
SOFA_LINK_CLASS(ThreadSimulation)
SOFA_LINK_CLASS(Triangle)
SOFA_LINK_CLASS(TriangleBendingSprings)
SOFA_LINK_CLASS(TriangleFEMForceField)
SOFA_LINK_CLASS(FittedRegularGridTopology)
SOFA_LINK_CLASS(UniformMass)
SOFA_LINK_CLASS(TestDetection)
SOFA_LINK_CLASS(SphereTreeModel)
//SOFA_LINK_CLASS(VoxelGrid)
SOFA_LINK_CLASS(WashingMachineForceField)
SOFA_LINK_CLASS(ReadState)
SOFA_LINK_CLASS(WriteState)
SOFA_LINK_CLASS(QuadBendingSprings)
<|endoftext|>


<commit_before>// Copyright (c) 2012-2013, Zeex
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
//    this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

#include <cstdint>
#include <cstring>
#ifdef _WIN32
	#include <windows.h>
#else
	#include <stdint.h>
	#include <unistd.h>
	#include <sys/mman.h>
#endif
#include "hook.h"

Hook::Hook()
	: src_(nullptr)
	, dst_(nullptr)
	, installed_(false)
{}

Hook::Hook(void *src, void *dst)
	: src_(nullptr)
	, dst_(nullptr)
	, installed_(false)
{
	Install(src, dst);
}

Hook::~Hook() {
	Remove();
}

bool Hook::Install() {
	if (installed_) {
		return false;
	}

	// Set write permission
	Unprotect(src_, kJmpInstrSize);

	// Store the code we are going to overwrite (probably to copy it back later)
	memcpy(code_, src_, kJmpInstrSize);

	// E9 - jump near, relative
	std::uint8_t JMP = 0xE9;
	memcpy(src_, &JMP, 1);

	// Jump address is relative to the next instruction's address
	std::intptr_t offset = (std::intptr_t)dst_ - ((std::intptr_t)src_ + kJmpInstrSize);
	memcpy((void*)((std::intptr_t)src_ + 1), &offset, kJmpInstrSize - 1);

	installed_ = true;
	return true;
}

bool Hook::Install(void *src, void *dst) {
	if (installed_) {
		return false;
	}

    src_ = src;
	dst_ = dst;
	return Install();
}

bool Hook::Remove() {
	if (!installed_) {
		return false;
	}

	std::memcpy(src_, code_, kJmpInstrSize);
	installed_ = false;
	return true;
}

bool Hook::IsInstalled() const {
	return installed_;
}

// static
void *Hook::GetTargetAddress(void *jmp) {
	if (*reinterpret_cast<unsigned char*>(jmp) == 0xE9) {
		std::intptr_t next_instr = reinterpret_cast<std::intptr_t>(reinterpret_cast<char*>(jmp) + kJmpInstrSize);
		std::intptr_t rel_addr = *reinterpret_cast<std::intptr_t*>(reinterpret_cast<char*>(jmp) + 1);
		std::intptr_t abs_addr = rel_addr + next_instr;
		return reinterpret_cast<void*>(abs_addr);
	}
	return nullptr;
}

// static
void Hook::Unprotect(void *address, int size) {
	#ifdef _WIN32
		DWORD oldProtect;
		VirtualProtect(address, size, PAGE_EXECUTE_READWRITE, &oldProtect);
	#else
		int pagesize = getpagesize();
		std::intptr_t where = ((reinterpret_cast<std::intptr_t>(address) / pagesize) * pagesize);
		std::intptr_t count = (size / pagesize) * pagesize + pagesize * 2;
		mprotect(reinterpret_cast<void*>(where), count, PROT_READ | PROT_WRITE | PROT_EXEC);
	#endif
}
<commit_msg>Remove unnecessary size alignment code<commit_after>// Copyright (c) 2012-2013, Zeex
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
//    this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

#include <cstdint>
#include <cstring>
#ifdef _WIN32
	#include <windows.h>
#else
	#include <stdint.h>
	#include <unistd.h>
	#include <sys/mman.h>
#endif
#include "hook.h"

Hook::Hook()
	: src_(nullptr)
	, dst_(nullptr)
	, installed_(false)
{}

Hook::Hook(void *src, void *dst)
	: src_(nullptr)
	, dst_(nullptr)
	, installed_(false)
{
	Install(src, dst);
}

Hook::~Hook() {
	Remove();
}

bool Hook::Install() {
	if (installed_) {
		return false;
	}

	// Set write permission
	Unprotect(src_, kJmpInstrSize);

	// Store the code we are going to overwrite (probably to copy it back later)
	memcpy(code_, src_, kJmpInstrSize);

	// E9 - jump near, relative
	std::uint8_t JMP = 0xE9;
	memcpy(src_, &JMP, 1);

	// Jump address is relative to the next instruction's address
	std::intptr_t offset = (std::intptr_t)dst_ - ((std::intptr_t)src_ + kJmpInstrSize);
	memcpy((void*)((std::intptr_t)src_ + 1), &offset, kJmpInstrSize - 1);

	installed_ = true;
	return true;
}

bool Hook::Install(void *src, void *dst) {
	if (installed_) {
		return false;
	}

    src_ = src;
	dst_ = dst;
	return Install();
}

bool Hook::Remove() {
	if (!installed_) {
		return false;
	}

	std::memcpy(src_, code_, kJmpInstrSize);
	installed_ = false;
	return true;
}

bool Hook::IsInstalled() const {
	return installed_;
}

// static
void *Hook::GetTargetAddress(void *jmp) {
	if (*reinterpret_cast<unsigned char*>(jmp) == 0xE9) {
		std::intptr_t next_instr = reinterpret_cast<std::intptr_t>(reinterpret_cast<char*>(jmp) + kJmpInstrSize);
		std::intptr_t rel_addr = *reinterpret_cast<std::intptr_t*>(reinterpret_cast<char*>(jmp) + 1);
		std::intptr_t abs_addr = rel_addr + next_instr;
		return reinterpret_cast<void*>(abs_addr);
	}
	return nullptr;
}

// static
void Hook::Unprotect(void *address, int size) {
	#ifdef _WIN32
		DWORD oldProtect;
		VirtualProtect(address, size, PAGE_EXECUTE_READWRITE, &oldProtect);
	#else
		std::intptr_t aligned_address = reinterpret_cast<intptr_t>(address);
		aligned_address &= ~(getpagesize() - 1);
		mprotect(reinterpret_cast<void*>(aligned_address), size, PROT_READ | PROT_WRITE | PROT_EXEC);
	#endif
}
<|endoftext|>


<commit_before>#include <julia.h>
#include "JMain.h"

using namespace std;

shared_ptr<nj::Expr> JMain::eval(const shared_ptr<nj::Expr> &expr)
{
   shared_ptr<nj::Expr> result;

   return result;
}

JMain::JMain()
{
   initialized = false;
   deactivated = false;
}

void JMain::initialize(int argc,const char *argv[]) throw(nj::InitializationException)
{
   unique_lock<mutex> lock(m_state);

   if(argc >= 1) install_directory = argv[0];
   initialized = true;
}

shared_ptr<nj::Expr> JMain::de_queue(list<shared_ptr<nj::Expr>> &queue)
{
   bool done = false;
   shared_ptr<nj::Expr> expr;

   while(!done)
   {
      {
         unique_lock<mutex> lock(m_state);

         while(eval_queue.empty() && !done)
         {
printf("Waiting for an expression\n");
            c_state.wait(lock);
            if(deactivated) done = true;
         }

         if(!deactivated)
         {
printf("Checking end of queue\n");
            if((expr = queue.back()))
            {
printf("Got expr\n");
               queue.pop_back();
printf("Poped end of queue\n");
               if(expr.get())
               {
                  done = true;
                  printf("Expr text = %s\n",expr->getText().c_str());
               }
            }
         }
         else done = true;
      }
   }
   return expr;
}

void JMain::operator()()
{
   bool done = false;

   while(!done)
   {
      unique_lock<mutex> lock(m_state);

      if(!initialized) c_state.wait(lock);
      if(initialized || deactivated) done = true;
   }

   if(!deactivated)
   {
      if(install_directory == "") jl_init(0);
      else jl_init((char*)install_directory.c_str());
      JL_SET_STACK_BASE;

      done = false;

      while(!done)
      {
printf("entering de_queue\n");
         shared_ptr<nj::Expr> expr = de_queue(eval_queue);

printf("got an expr\n");

         if(expr.get())
         {
printf("expr text = %s\n",expr->getText().c_str());
            shared_ptr<nj::Expr> result = eval(expr);

printf("Got a result\n");
            if(result.get())
            {
printf("Expr result = %s\n",result->getText().c_str());
              unique_lock<mutex> lock(m_state);

              if(!deactivated)
              {
printf("Pushing result\n");
                 result_queue.push_front(result);
                 c_state.notify_all();
              }
              else done = true;
            }
            else result_queue.push_front(result);
         }
         else printf("Expr was null\n");
      }
   }
}

void JMain::evalQueuePut(const string &expressionText)
{
   unique_lock<mutex> lock(m_state);
   shared_ptr<nj::Expr> expr(new nj::Expr(expressionText));
printf("Received an expr %s\n",expressionText.c_str());
   eval_queue.push_front(expr);
   c_state.notify_all();
}

string JMain::resultQueueGet()
{
   shared_ptr<nj::Expr> expr = de_queue(result_queue);
printf("Got Result\n");
   if(expr.get())
   {
printf("Result text = %s\n",expr->getText().c_str());
    return expr->getText();
   }
printf("Result text = ""\n");
   return "";
}

void JMain::stop()
{
   unique_lock<mutex> lock(m_state);

   deactivated = true;
   c_state.notify_all();
}

JMain::~JMain() {}
<commit_msg>Changed check for zero length queue<commit_after>#include <julia.h>
#include "JMain.h"

using namespace std;

shared_ptr<nj::Expr> JMain::eval(const shared_ptr<nj::Expr> &expr)
{
   shared_ptr<nj::Expr> result;

   return result;
}

JMain::JMain()
{
   initialized = false;
   deactivated = false;
}

void JMain::initialize(int argc,const char *argv[]) throw(nj::InitializationException)
{
   unique_lock<mutex> lock(m_state);

   if(argc >= 1) install_directory = argv[0];
   initialized = true;
}

shared_ptr<nj::Expr> JMain::de_queue(list<shared_ptr<nj::Expr>> &queue)
{
   bool done = false;
   shared_ptr<nj::Expr> expr;

   while(!done)
   {
      {
         unique_lock<mutex> lock(m_state);

         while(eval_queue.empty() && !done)
         {
printf("Waiting for an expression\n");
            c_state.wait(lock);
            if(deactivated) done = true;
         }

         if(!deactivated)
         {
printf("Checking end of queue\n");
            if(queue.size() != 0)
            {
               expr = queue.back();
printf("Got expr\n");
               queue.pop_back();
printf("Poped end of queue\n");
               if(expr.get())
               {
                  done = true;
                  printf("Expr text = %s\n",expr->getText().c_str());
               }
            }
         }
         else done = true;
      }
   }
   return expr;
}

void JMain::operator()()
{
   bool done = false;

   while(!done)
   {
      unique_lock<mutex> lock(m_state);

      if(!initialized) c_state.wait(lock);
      if(initialized || deactivated) done = true;
   }

   if(!deactivated)
   {
      if(install_directory == "") jl_init(0);
      else jl_init((char*)install_directory.c_str());
      JL_SET_STACK_BASE;

      done = false;

      while(!done)
      {
printf("entering de_queue\n");
         shared_ptr<nj::Expr> expr = de_queue(eval_queue);

printf("got an expr\n");

         if(expr.get())
         {
printf("expr text = %s\n",expr->getText().c_str());
            shared_ptr<nj::Expr> result = eval(expr);

printf("Got a result\n");
            if(result.get())
            {
printf("Expr result = %s\n",result->getText().c_str());
              unique_lock<mutex> lock(m_state);

              if(!deactivated)
              {
printf("Pushing result\n");
                 result_queue.push_front(result);
                 c_state.notify_all();
              }
              else done = true;
            }
            else result_queue.push_front(result);
         }
         else printf("Expr was null\n");
      }
   }
}

void JMain::evalQueuePut(const string &expressionText)
{
   unique_lock<mutex> lock(m_state);
   shared_ptr<nj::Expr> expr(new nj::Expr(expressionText));
printf("Received an expr %s\n",expressionText.c_str());
   eval_queue.push_front(expr);
   c_state.notify_all();
}

string JMain::resultQueueGet()
{
   shared_ptr<nj::Expr> expr = de_queue(result_queue);
printf("Got Result\n");
   if(expr.get())
   {
printf("Result text = %s\n",expr->getText().c_str());
    return expr->getText();
   }
printf("Result text = ""\n");
   return "";
}

void JMain::stop()
{
   unique_lock<mutex> lock(m_state);

   deactivated = true;
   c_state.notify_all();
}

JMain::~JMain() {}
<|endoftext|>


<commit_before>#include <chrono>
#include <cstdio>
#include <vector>
#include <memory>
#include <algorithm>
#include <poll.h>

#include <xf86drm.h>
#include <xf86drmMode.h>
#include <gbm.h>

#include <kms++/kms++.h>
#include <kms++util/kms++util.h>
#include "cube-egl.h"
#include "cube-gles2.h"

using namespace kms;
using namespace std;

static int s_flip_pending;
static bool s_need_exit;

static bool s_support_planes;

class GbmDevice
{
public:
	GbmDevice(Card& card)
	{
		m_dev = gbm_create_device(card.fd());
		FAIL_IF(!m_dev, "failed to create gbm device");
	}

	~GbmDevice()
	{
		gbm_device_destroy(m_dev);
	}

	GbmDevice(const GbmDevice& other) = delete;
	GbmDevice& operator=(const GbmDevice& other) = delete;

	struct gbm_device* handle() const { return m_dev; }

private:
	struct gbm_device* m_dev;
};

class GbmSurface
{
public:
	GbmSurface(GbmDevice& gdev, int width, int height)
	{
		m_surface = gbm_surface_create(gdev.handle(), width, height,
					       GBM_FORMAT_XRGB8888,
					       GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
		FAIL_IF(!m_surface, "failed to create gbm surface");
	}

	~GbmSurface()
	{
		gbm_surface_destroy(m_surface);
	}

	GbmSurface(const GbmSurface& other) = delete;
	GbmSurface& operator=(const GbmSurface& other) = delete;

	bool has_free()
	{
		return gbm_surface_has_free_buffers(m_surface);
	}

	gbm_bo* lock_front_buffer()
	{
		return gbm_surface_lock_front_buffer(m_surface);
	}

	void release_buffer(gbm_bo *bo)
	{
		gbm_surface_release_buffer(m_surface, bo);
	}

	struct gbm_surface* handle() const { return m_surface; }

private:
	struct gbm_surface* m_surface;
};

class GbmEglSurface
{
public:
	GbmEglSurface(Card& card, GbmDevice& gdev, const EglState& egl, int width, int height)
		: card(card), egl(egl), m_width(width), m_height(height),
		  bo_prev(0), bo_next(0)
	{
		gsurface = unique_ptr<GbmSurface>(new GbmSurface(gdev, width, height));
		esurface = eglCreateWindowSurface(egl.display(), egl.config(), gsurface->handle(), NULL);
		FAIL_IF(esurface == EGL_NO_SURFACE, "failed to create egl surface");
	}

	~GbmEglSurface()
	{
		if (bo_next)
			gsurface->release_buffer(bo_next);
		eglDestroySurface(egl.display(), esurface);
	}

	void make_current()
	{
		FAIL_IF(!gsurface->has_free(), "No free buffers");

		eglMakeCurrent(egl.display(), esurface, esurface, egl.context());
	}

	void swap_buffers()
	{
		eglSwapBuffers(egl.display(), esurface);
	}

	static void drm_fb_destroy_callback(struct gbm_bo *bo, void *data)
	{
		auto fb = reinterpret_cast<Framebuffer*>(data);
		delete fb;
	}

	static Framebuffer* drm_fb_get_from_bo(struct gbm_bo *bo, Card& card)
	{
		auto fb = reinterpret_cast<Framebuffer*>(gbm_bo_get_user_data(bo));
		if (fb)
			return fb;

		uint32_t width = gbm_bo_get_width(bo);
		uint32_t height = gbm_bo_get_height(bo);
		uint32_t stride = gbm_bo_get_stride(bo);
		uint32_t handle = gbm_bo_get_handle(bo).u32;
		PixelFormat format = (PixelFormat)gbm_bo_get_format(bo);

		vector<uint32_t> handles { handle };
		vector<uint32_t> strides { stride };
		vector<uint32_t> offsets { 0 };

		fb = new ExtFramebuffer(card, width, height, format, handles, strides, offsets);

		gbm_bo_set_user_data(bo, fb, drm_fb_destroy_callback);

		return fb;
	}

	Framebuffer* lock_next()
	{
		bo_prev = bo_next;
		bo_next = gsurface->lock_front_buffer();
		FAIL_IF(!bo_next, "could not lock gbm buffer");
		return drm_fb_get_from_bo(bo_next, card);
	}

	void free_prev()
	{
		if (bo_prev) {
			gsurface->release_buffer(bo_prev);
			bo_prev = 0;
		}
	}

	uint32_t width() const { return m_width; }
	uint32_t height() const { return m_height; }

private:
	Card& card;
	const EglState& egl;

	unique_ptr<GbmSurface> gsurface;
	EGLSurface esurface;

	int m_width;
	int m_height;

	struct gbm_bo* bo_prev;
	struct gbm_bo* bo_next;
};

class OutputHandler : private PageFlipHandlerBase
{
public:
	OutputHandler(Card& card, GbmDevice& gdev, const EglState& egl, Connector* connector, Crtc* crtc, Videomode& mode, Plane* plane, float rotation_mult)
		: m_frame_num(0), m_connector(connector), m_crtc(crtc), m_plane(plane), m_mode(mode),
		  m_rotation_mult(rotation_mult)
	{
		m_surface1 = unique_ptr<GbmEglSurface>(new GbmEglSurface(card, gdev, egl, mode.hdisplay, mode.vdisplay));
		m_scene1 = unique_ptr<GlScene>(new GlScene());
		m_scene1->set_viewport(m_surface1->width(), m_surface1->height());

		if (m_plane) {
			m_surface2 = unique_ptr<GbmEglSurface>(new GbmEglSurface(card, gdev, egl, 400, 400));
			m_scene2 = unique_ptr<GlScene>(new GlScene());
			m_scene2->set_viewport(m_surface2->width(), m_surface2->height());
		}
	}

	OutputHandler(const OutputHandler& other) = delete;
	OutputHandler& operator=(const OutputHandler& other) = delete;

	void setup()
	{
		int ret;

		m_surface1->make_current();
		m_surface1->swap_buffers();
		Framebuffer* fb = m_surface1->lock_next();

		Framebuffer* planefb = 0;

		if (m_plane) {
			m_surface2->make_current();
			m_surface2->swap_buffers();
			planefb = m_surface2->lock_next();
		}

		ret = m_crtc->set_mode(m_connector, *fb, m_mode);
		FAIL_IF(ret, "failed to set mode");

		Plane* root_plane = 0;
		for (Plane* p : m_crtc->get_possible_planes()) {
			if (p->crtc_id() == m_crtc->id()) {
				root_plane = p;
				break;
			}
		}

		FAIL_IF(!root_plane, "No primary plane for crtc %d", m_crtc->id());

		m_root_plane = root_plane;

		if (m_plane) {
			ret = m_crtc->set_plane(m_plane, *planefb,
						0, 0, planefb->width(), planefb->height(),
						0, 0, planefb->width(), planefb->height());
			FAIL_IF(ret, "failed to set plane");
		}
	}

	void start_flipping()
	{
		m_t1 = chrono::steady_clock::now();
		queue_next();
	}

private:
	void handle_page_flip(uint32_t frame, double time)
	{
		++m_frame_num;

		if (m_frame_num  % 100 == 0) {
			auto t2 = chrono::steady_clock::now();
			chrono::duration<float> fsec = t2 - m_t1;
			printf("fps: %f\n", 100.0 / fsec.count());
			m_t1 = t2;
		}

		s_flip_pending--;

		m_surface1->free_prev();
		if (m_plane)
			m_surface2->free_prev();

		if (s_need_exit)
			return;

		queue_next();
	}

	void queue_next()
	{
		m_surface1->make_current();
		m_scene1->draw(m_frame_num * m_rotation_mult);
		m_surface1->swap_buffers();
		Framebuffer* fb = m_surface1->lock_next();

		Framebuffer* planefb = 0;

		if (m_plane) {
			m_surface2->make_current();
			m_scene2->draw(m_frame_num * m_rotation_mult * 2);
			m_surface2->swap_buffers();
			planefb = m_surface2->lock_next();
		}

		int r;

		AtomicReq req(m_crtc->card());

		req.add(m_root_plane, "FB_ID", fb->id());
		if (m_plane)
			req.add(m_plane, "FB_ID", planefb->id());

		r = req.test();
		FAIL_IF(r, "atomic test failed");

		r = req.commit(this);
		FAIL_IF(r, "atomic commit failed");

		s_flip_pending++;
	}

	int m_frame_num;
	chrono::steady_clock::time_point m_t1;

	Connector* m_connector;
	Crtc* m_crtc;
	Plane* m_plane;
	Videomode m_mode;
	Plane* m_root_plane;

	unique_ptr<GbmEglSurface> m_surface1;
	unique_ptr<GbmEglSurface> m_surface2;

	unique_ptr<GlScene> m_scene1;
	unique_ptr<GlScene> m_scene2;

	float m_rotation_mult;
};

void main_gbm()
{
	Card card;

	FAIL_IF(!card.has_atomic(), "No atomic modesetting");

	GbmDevice gdev(card);
	EglState egl(gdev.handle());

	vector<unique_ptr<OutputHandler>> outputs;
	vector<Plane*> used_planes;

	float rot_mult = 1;

	for (auto pipe : card.get_connected_pipelines()) {
		auto connector = pipe.connector;
		auto crtc = pipe.crtc;
		auto mode = connector->get_default_mode();

		Plane* plane = 0;

		if (s_support_planes) {
			for (Plane* p : crtc->get_possible_planes()) {
				if (find(used_planes.begin(), used_planes.end(), p) != used_planes.end())
					continue;

				if (p->plane_type() != PlaneType::Overlay)
					continue;

				plane = p;
				break;
			}
		}

		if (plane)
			used_planes.push_back(plane);

		auto out = new OutputHandler(card, gdev, egl, connector, crtc, mode, plane, rot_mult);
		outputs.emplace_back(out);

		rot_mult *= 1.33;
	}

	for (auto& out : outputs)
		out->setup();

	for (auto& out : outputs)
		out->start_flipping();

	struct pollfd fds[2] = { };
	fds[0].fd = 0;
	fds[0].events =  POLLIN;
	fds[1].fd = card.fd();
	fds[1].events =  POLLIN;

	while (!s_need_exit || s_flip_pending) {
		int r = poll(fds, ARRAY_SIZE(fds), -1);
		FAIL_IF(r < 0, "poll error %d", r);

		if (fds[0].revents)
			s_need_exit = true;

		if (fds[1].revents)
			card.call_page_flip_handlers();
	}
}
<commit_msg>kmscube: update drm resource allocation<commit_after>#include <chrono>
#include <cstdio>
#include <vector>
#include <memory>
#include <algorithm>
#include <poll.h>

#include <xf86drm.h>
#include <xf86drmMode.h>
#include <gbm.h>

#include <kms++/kms++.h>
#include <kms++util/kms++util.h>
#include "cube-egl.h"
#include "cube-gles2.h"

using namespace kms;
using namespace std;

static int s_flip_pending;
static bool s_need_exit;

static bool s_support_planes;

class GbmDevice
{
public:
	GbmDevice(Card& card)
	{
		m_dev = gbm_create_device(card.fd());
		FAIL_IF(!m_dev, "failed to create gbm device");
	}

	~GbmDevice()
	{
		gbm_device_destroy(m_dev);
	}

	GbmDevice(const GbmDevice& other) = delete;
	GbmDevice& operator=(const GbmDevice& other) = delete;

	struct gbm_device* handle() const { return m_dev; }

private:
	struct gbm_device* m_dev;
};

class GbmSurface
{
public:
	GbmSurface(GbmDevice& gdev, int width, int height)
	{
		m_surface = gbm_surface_create(gdev.handle(), width, height,
					       GBM_FORMAT_XRGB8888,
					       GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
		FAIL_IF(!m_surface, "failed to create gbm surface");
	}

	~GbmSurface()
	{
		gbm_surface_destroy(m_surface);
	}

	GbmSurface(const GbmSurface& other) = delete;
	GbmSurface& operator=(const GbmSurface& other) = delete;

	bool has_free()
	{
		return gbm_surface_has_free_buffers(m_surface);
	}

	gbm_bo* lock_front_buffer()
	{
		return gbm_surface_lock_front_buffer(m_surface);
	}

	void release_buffer(gbm_bo *bo)
	{
		gbm_surface_release_buffer(m_surface, bo);
	}

	struct gbm_surface* handle() const { return m_surface; }

private:
	struct gbm_surface* m_surface;
};

class GbmEglSurface
{
public:
	GbmEglSurface(Card& card, GbmDevice& gdev, const EglState& egl, int width, int height)
		: card(card), egl(egl), m_width(width), m_height(height),
		  bo_prev(0), bo_next(0)
	{
		gsurface = unique_ptr<GbmSurface>(new GbmSurface(gdev, width, height));
		esurface = eglCreateWindowSurface(egl.display(), egl.config(), gsurface->handle(), NULL);
		FAIL_IF(esurface == EGL_NO_SURFACE, "failed to create egl surface");
	}

	~GbmEglSurface()
	{
		if (bo_next)
			gsurface->release_buffer(bo_next);
		eglDestroySurface(egl.display(), esurface);
	}

	void make_current()
	{
		FAIL_IF(!gsurface->has_free(), "No free buffers");

		eglMakeCurrent(egl.display(), esurface, esurface, egl.context());
	}

	void swap_buffers()
	{
		eglSwapBuffers(egl.display(), esurface);
	}

	static void drm_fb_destroy_callback(struct gbm_bo *bo, void *data)
	{
		auto fb = reinterpret_cast<Framebuffer*>(data);
		delete fb;
	}

	static Framebuffer* drm_fb_get_from_bo(struct gbm_bo *bo, Card& card)
	{
		auto fb = reinterpret_cast<Framebuffer*>(gbm_bo_get_user_data(bo));
		if (fb)
			return fb;

		uint32_t width = gbm_bo_get_width(bo);
		uint32_t height = gbm_bo_get_height(bo);
		uint32_t stride = gbm_bo_get_stride(bo);
		uint32_t handle = gbm_bo_get_handle(bo).u32;
		PixelFormat format = (PixelFormat)gbm_bo_get_format(bo);

		vector<uint32_t> handles { handle };
		vector<uint32_t> strides { stride };
		vector<uint32_t> offsets { 0 };

		fb = new ExtFramebuffer(card, width, height, format, handles, strides, offsets);

		gbm_bo_set_user_data(bo, fb, drm_fb_destroy_callback);

		return fb;
	}

	Framebuffer* lock_next()
	{
		bo_prev = bo_next;
		bo_next = gsurface->lock_front_buffer();
		FAIL_IF(!bo_next, "could not lock gbm buffer");
		return drm_fb_get_from_bo(bo_next, card);
	}

	void free_prev()
	{
		if (bo_prev) {
			gsurface->release_buffer(bo_prev);
			bo_prev = 0;
		}
	}

	uint32_t width() const { return m_width; }
	uint32_t height() const { return m_height; }

private:
	Card& card;
	const EglState& egl;

	unique_ptr<GbmSurface> gsurface;
	EGLSurface esurface;

	int m_width;
	int m_height;

	struct gbm_bo* bo_prev;
	struct gbm_bo* bo_next;
};

class OutputHandler : private PageFlipHandlerBase
{
public:
	OutputHandler(Card& card, GbmDevice& gdev, const EglState& egl, Connector* connector, Crtc* crtc, Videomode& mode, Plane* root_plane, Plane* plane, float rotation_mult)
		: m_frame_num(0), m_connector(connector), m_crtc(crtc), m_root_plane(root_plane), m_plane(plane), m_mode(mode),
		  m_rotation_mult(rotation_mult)
	{
		m_surface1 = unique_ptr<GbmEglSurface>(new GbmEglSurface(card, gdev, egl, mode.hdisplay, mode.vdisplay));
		m_scene1 = unique_ptr<GlScene>(new GlScene());
		m_scene1->set_viewport(m_surface1->width(), m_surface1->height());

		if (m_plane) {
			m_surface2 = unique_ptr<GbmEglSurface>(new GbmEglSurface(card, gdev, egl, 400, 400));
			m_scene2 = unique_ptr<GlScene>(new GlScene());
			m_scene2->set_viewport(m_surface2->width(), m_surface2->height());
		}
	}

	OutputHandler(const OutputHandler& other) = delete;
	OutputHandler& operator=(const OutputHandler& other) = delete;

	void setup()
	{
		int ret;

		m_surface1->make_current();
		m_surface1->swap_buffers();
		Framebuffer* fb = m_surface1->lock_next();

		Framebuffer* planefb = 0;

		if (m_plane) {
			m_surface2->make_current();
			m_surface2->swap_buffers();
			planefb = m_surface2->lock_next();
		}

		ret = m_crtc->set_mode(m_connector, *fb, m_mode);
		FAIL_IF(ret, "failed to set mode");

		if (m_plane) {
			ret = m_crtc->set_plane(m_plane, *planefb,
						0, 0, planefb->width(), planefb->height(),
						0, 0, planefb->width(), planefb->height());
			FAIL_IF(ret, "failed to set plane");
		}
	}

	void start_flipping()
	{
		m_t1 = chrono::steady_clock::now();
		queue_next();
	}

private:
	void handle_page_flip(uint32_t frame, double time)
	{
		++m_frame_num;

		if (m_frame_num  % 100 == 0) {
			auto t2 = chrono::steady_clock::now();
			chrono::duration<float> fsec = t2 - m_t1;
			printf("fps: %f\n", 100.0 / fsec.count());
			m_t1 = t2;
		}

		s_flip_pending--;

		m_surface1->free_prev();
		if (m_plane)
			m_surface2->free_prev();

		if (s_need_exit)
			return;

		queue_next();
	}

	void queue_next()
	{
		m_surface1->make_current();
		m_scene1->draw(m_frame_num * m_rotation_mult);
		m_surface1->swap_buffers();
		Framebuffer* fb = m_surface1->lock_next();

		Framebuffer* planefb = 0;

		if (m_plane) {
			m_surface2->make_current();
			m_scene2->draw(m_frame_num * m_rotation_mult * 2);
			m_surface2->swap_buffers();
			planefb = m_surface2->lock_next();
		}

		int r;

		AtomicReq req(m_crtc->card());

		req.add(m_root_plane, "FB_ID", fb->id());
		if (m_plane)
			req.add(m_plane, "FB_ID", planefb->id());

		r = req.test();
		FAIL_IF(r, "atomic test failed");

		r = req.commit(this);
		FAIL_IF(r, "atomic commit failed");

		s_flip_pending++;
	}

	int m_frame_num;
	chrono::steady_clock::time_point m_t1;

	Connector* m_connector;
	Crtc* m_crtc;
	Plane* m_root_plane;
	Plane* m_plane;
	Videomode m_mode;

	unique_ptr<GbmEglSurface> m_surface1;
	unique_ptr<GbmEglSurface> m_surface2;

	unique_ptr<GlScene> m_scene1;
	unique_ptr<GlScene> m_scene2;

	float m_rotation_mult;
};

void main_gbm()
{
	Card card;

	FAIL_IF(!card.has_atomic(), "No atomic modesetting");

	GbmDevice gdev(card);
	EglState egl(gdev.handle());

	ResourceManager resman(card);

	vector<unique_ptr<OutputHandler>> outputs;

	float rot_mult = 1;

	for (Connector* conn : card.get_connectors()) {
		if (!conn->connected())
			continue;

		resman.reserve_connector(conn);

		Crtc* crtc = resman.reserve_crtc(conn);
		auto mode = conn->get_default_mode();

		Plane* root_plane = resman.reserve_generic_plane(crtc);
		FAIL_IF(!root_plane, "Root plane not available");

		Plane* plane = nullptr;

		if (s_support_planes)
			plane = resman.reserve_generic_plane(crtc);

		auto out = new OutputHandler(card, gdev, egl, conn, crtc, mode, root_plane, plane, rot_mult);
		outputs.emplace_back(out);

		rot_mult *= 1.33;
	}

	for (auto& out : outputs)
		out->setup();

	for (auto& out : outputs)
		out->start_flipping();

	struct pollfd fds[2] = { };
	fds[0].fd = 0;
	fds[0].events =  POLLIN;
	fds[1].fd = card.fd();
	fds[1].events =  POLLIN;

	while (!s_need_exit || s_flip_pending) {
		int r = poll(fds, ARRAY_SIZE(fds), -1);
		FAIL_IF(r < 0, "poll error %d", r);

		if (fds[0].revents)
			s_need_exit = true;

		if (fds[1].revents)
			card.call_page_flip_handlers();
	}
}
<|endoftext|>


<commit_before>#include "Level.h"

#include <fstream>

#include "Engine/Errors.h"
#include <stddef.h>

const int ROW = 200;
const int COL = 200;
const double CELL_SIZE = 1;

Level::Level(const std::string &fileName) : nCols(0), nRows(0), levelData(nullptr)
{
	//initialization
	vboId = iboId = vboIdWireframe = iboIdWireframe = 0;
	showWireframe = false;

	//read binary data from file
	readBinaryData(fileName);

	//build color height
	heightColorMap.insert(std::make_pair(0.0f, Engine::ColorRGBA8()));
	heightColorMap.insert(std::make_pair(1100.0f, Engine::ColorRGBA8(0,150,150)));
	heightColorMap.insert(std::make_pair(1500.0f, Engine::ColorRGBA8(0,180,0)));
	heightColorMap.insert(std::make_pair(1700.0f, Engine::ColorRGBA8(255,255,0)));
	heightColorMap.insert(std::make_pair(1900.0f, Engine::ColorRGBA8(255,120,0)));
	heightColorMap.insert(std::make_pair(2100.0f, Engine::ColorRGBA8(180,31,21)));
	heightColorMap.insert(std::make_pair(2300.0f, Engine::ColorRGBA8(128,60,60)));
	heightColorMap.insert(std::make_pair(2600.0f, Engine::ColorRGBA8(255,255,255)));
	heightColorMap.insert(std::make_pair(3500.0f, Engine::ColorRGBA8(255,255,255,100)));

	//construct vertex data based on level data
	Engine::Vertex *vertexData = new Engine::Vertex[ ROW * COL ];
	for(int z=0; z<ROW; z++)
		for (int x=0; x<COL; x++)
		{
			float y = levelData[z*nRows + x];
			vertexData[z*ROW + x].SetPosition((x)*CELL_SIZE, y/10 - 230, (z)*CELL_SIZE);
			vertexData[z*ROW + x].color = getColorByHeight(y);
		}
	glGenBuffers(1, &vboId);
	glBindBuffer(GL_ARRAY_BUFFER, vboId);
	glBufferData(GL_ARRAY_BUFFER, sizeof(Engine::Vertex)*ROW * COL, vertexData,GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER, 0);

	//set color for wire frame vertex, and upload to GPU
	Engine::ColorRGBA8 wireframeColor(0,0,0,255);
	for(int z=0; z<ROW; z++)
		for (int x=0; x<COL; x++)
			vertexData[z*ROW + x].color = wireframeColor;
	glGenBuffers(1, &vboIdWireframe);
	glBindBuffer(GL_ARRAY_BUFFER, vboIdWireframe);
	glBufferData(GL_ARRAY_BUFFER, sizeof(Engine::Vertex)*ROW * COL,vertexData, GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	delete[] vertexData;

	//assign triangle indices. Two triangles at once, that form a rectangle.
	unsigned int *mapElements = new unsigned int[(COL-1)*(ROW-1)*2*3];
	for(int i=0,k=0; i<ROW-1; i++)
		for(int j=0; j<COL-1; j++)
		{
			mapElements[k++] = i*COL + j;
			mapElements[k++] = i*COL + j+1;
			mapElements[k++] = (i+1)*COL + j;

 			mapElements[k++] = i*COL + j+1;
 			mapElements[k++] = (i+1)*COL + j;
 			mapElements[k++] = (i+1)*COL + j+1;
		}
	glGenBuffers(1, &iboId);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iboId);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int)*(COL-1)*(ROW-1)*2*3, mapElements, GL_STATIC_DRAW);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
	delete[] mapElements;

	//assign horizontal line indices.
	unsigned int *wireframeElements = new unsigned int[(COL-1)*(ROW-1)*2*3*2];
	for(int i=0,k=0; i<ROW-1; i++)
		for(int j=0; j<COL-1; j++)
		{
			wireframeElements[k++] = i*COL + j;
			wireframeElements[k++] = i*COL + j+1;

			wireframeElements[k++] = i*COL + j+1;
			wireframeElements[k++] = (i+1)*COL + j;

			wireframeElements[k++] = (i+1)*COL + j;
			wireframeElements[k++] = i*COL + j;

			//rem
			wireframeElements[k++] = i*COL + j+1;
			wireframeElements[k++] = (i+1)*COL + j;

			wireframeElements[k++] = (i+1)*COL + j;
			wireframeElements[k++] = (i+1)*COL + j+1;

			wireframeElements[k++] = (i+1)*COL + j+1;
			wireframeElements[k++] = i*COL + j+1;
		}
	glGenBuffers(1, &iboIdWireframe);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iboIdWireframe);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int)*(COL-1)*(ROW-1)*2*3*2, wireframeElements, GL_STATIC_DRAW);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
	delete[] wireframeElements;

	printf("Uploaded map!\n");
}

Level::~Level(void)
{
	delete[] levelData;
}

void Level::SwitchWireframeVisibility()
{
	showWireframe = !showWireframe;
	glPolygonOffset(1, 1);
}

void Level::Render()
{
	glBindBuffer(GL_ARRAY_BUFFER, vboId);
	glEnableVertexAttribArray(0);
	glEnableVertexAttribArray(1);
	glEnableVertexAttribArray(2);
	glEnableVertexAttribArray(3);
	glVertexAttribPointer(0, 3, GL_FLOAT ,GL_FALSE, sizeof(Engine::Vertex), (void*)offsetof(Engine::Vertex,position));
	glVertexAttribPointer(1, 3, GL_FLOAT ,GL_FALSE, sizeof(Engine::Vertex), (void*)offsetof(Engine::Vertex,normal));
	glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Engine::Vertex), (void*)offsetof(Engine::Vertex,color));
	glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Engine::Vertex), (void*)offsetof(Engine::Vertex,uv));

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iboId);
	int size;  glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
	glDrawElements(GL_TRIANGLES, size/sizeof(unsigned int), GL_UNSIGNED_INT, 0);

	if(showWireframe)
	{
		glEnable(GL_POLYGON_OFFSET_FILL);

		glEnableVertexAttribArray(0);
		glEnableVertexAttribArray(1);
		glEnableVertexAttribArray(2);
		glEnableVertexAttribArray(3);
		glVertexAttribPointer(0, 3, GL_FLOAT ,GL_FALSE, sizeof(Engine::Vertex), (void*)offsetof(Engine::Vertex,position));
		glVertexAttribPointer(1, 3, GL_FLOAT ,GL_FALSE, sizeof(Engine::Vertex), (void*)offsetof(Engine::Vertex,normal));
		glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Engine::Vertex), (void*)offsetof(Engine::Vertex,color));
		glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Engine::Vertex), (void*)offsetof(Engine::Vertex,uv));

		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iboIdWireframe);
		int size;  glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
		glDrawElements(GL_LINES, size/sizeof(unsigned int), GL_UNSIGNED_INT, 0);
	}

	//glDrawArrays(GL_TRIANGLES, 0, /*(ROW-1) **/ (COL-2));

	glDisableVertexAttribArray(0);
	glDisableVertexAttribArray(1);
	glDisableVertexAttribArray(2);
	glDisableVertexAttribArray(3);
	glBindBuffer(GL_ARRAY_BUFFER, 0);
}

double Level::GetHeight(glm::vec2 point2d)
{
	int posx1 = (int)(point2d.x / CELL_SIZE);
	int posx2 = posx1 + 1;
	int posy1 = (int)(point2d.y / CELL_SIZE);
	int posy2 = posy1 + 1;

	double f00 = levelData[posy1*nRows + posx1];
	double f10 = levelData[posy1*nRows + posx2];
	double f11 = levelData[posy2*nRows + posx2];
	double f01 = levelData[posy2*nRows + posx1];

	double px = point2d.x / CELL_SIZE - posx1;
	double py = point2d.y / CELL_SIZE - posy2;

	double fFinal = f00 * (1.0 - px) * (1.0 - py) +
		f10 * px * (1.0 - py) + f01 * (1.0 - px) * py + f11 * px * py;

	return fFinal;
}

void Level::readAscFile(const std::string &fileName)
{
	std::ifstream file(fileName);
	if(file.fail())
		Engine::fatalError("File could not be opened!");

	std::string temp; ///temporary string

	file>>temp>>nCols; ///ignore word and read nCols

	file>>temp>>nRows; ///ignore word and read nRows

	for (int i=0; i < 5; i++)
		std::getline(file,temp); ///ignore next 4 rows

	//allocate memory
	levelData = new float[nRows*nCols];
	//read actual matrix data
	for (int y=0; y<nRows; ++y)
	{
		const int FINISHED_ELEMENTS = y*nCols;
		for (int x=0; x<nCols; ++x)
			file>>levelData[FINISHED_ELEMENTS + x];
	}
}

void Level::writeToBinary(const std::string &fileName, unsigned int nCols, unsigned int nRows)
{
	std::ofstream file(fileName,std::ios::binary);
	if(file.fail())
		Engine::fatalError("File could not be opened!");
	if(!nCols) nCols = this->nCols;
	if(!nRows) nRows = this->nRows;

	file.write((char*)&nCols,sizeof(nCols));
	file.write((char*)&nRows,sizeof(nRows));

	for(int i=0; i<nRows; i++)
		file.write((char*)&levelData[i*this->nCols],sizeof(float)*nCols);
}

Engine::ColorRGBA8 Level::getColorByHeight(float height)
{
	//Get the first element that is greater than or equal with height. This will be the upper bound. Seriously.
	auto itLow = heightColorMap.lower_bound(height);
	//Now make the upper bound equal to lower bound(witch is still the upper bound), then decrement the upper bound.
	auto itUp = itLow--;

	float height1=itLow->first, height2=itUp->first;
	Engine::ColorRGBA8 c1=itLow->second, c2=itUp->second, cRes;
	float t = (height - height1) / (height2 - height1);
	cRes.r = (c2.r - c1.r) * t + c1.r;
	cRes.g = (c2.g - c1.g) * t + c1.g;
	cRes.b = (c2.b - c1.b) * t + c1.b;
	cRes.a = (c2.a - c1.a) * t + c1.a;
	return cRes;
}

Engine::Position Level::normal(Engine::Position p[3])
{
	Engine::Position a, b;
	// calculate the vectors A and B
	// note that p[3] is defined with counterclockwise winding in mind
	// a
	a.x = p[0].x - p[1].x;
	a.y = p[0].y - p[1].y;
	a.z = p[0].z - p[1].z;
	// b
	b.x = p[1].x - p[2].x;
	b.y = p[1].y - p[2].y;
	b.z = p[1].z - p[2].z;

	// calculate the cross product
	Engine::Position normal;
	normal.x = (a.y * b.z) - (a.z * b.y);
	normal.y = (a.z * b.x) - (a.x * b.z);
	normal.z = (a.x * b.y) - (a.y * b.x);

	// normalize
	normal.Normalize();
}

void Level::readBinaryData(const std::string &fileName)
{
	//data from file
	std::ifstream file(fileName,std::ios::binary);
	if(file.fail())
		Engine::fatalError("File could not be opened!");
	file.read((char*)&nCols,sizeof(nCols));
	file.read((char*)&nRows,sizeof(nRows));

	levelData = new float[nRows*nCols];
	file.read((char*)levelData,sizeof(float)*nRows*nCols);
}
<commit_msg>Fixed wireframe not showing. Commented grid drawing.<commit_after>#include "Level.h"

#include <fstream>

#include "Engine/Errors.h"
#include <stddef.h>

const int ROW = 200;
const int COL = 200;
const double CELL_SIZE = 1;

Level::Level(const std::string &fileName) : nCols(0), nRows(0), levelData(nullptr)
{
	//initialization
	vboId = iboId = vboIdWireframe = iboIdWireframe = 0;
	showWireframe = false;

	//read binary data from file
	readBinaryData(fileName);

	//build color height
	heightColorMap.insert(std::make_pair(0.0f, Engine::ColorRGBA8()));
	heightColorMap.insert(std::make_pair(1100.0f, Engine::ColorRGBA8(0,150,150)));
	heightColorMap.insert(std::make_pair(1500.0f, Engine::ColorRGBA8(0,180,0)));
	heightColorMap.insert(std::make_pair(1700.0f, Engine::ColorRGBA8(255,255,0)));
	heightColorMap.insert(std::make_pair(1900.0f, Engine::ColorRGBA8(255,120,0)));
	heightColorMap.insert(std::make_pair(2100.0f, Engine::ColorRGBA8(180,31,21)));
	heightColorMap.insert(std::make_pair(2300.0f, Engine::ColorRGBA8(128,60,60)));
	heightColorMap.insert(std::make_pair(2600.0f, Engine::ColorRGBA8(255,255,255)));
	heightColorMap.insert(std::make_pair(3500.0f, Engine::ColorRGBA8(255,255,255,100)));

	//construct vertex data based on level data
	Engine::Vertex *vertexData = new Engine::Vertex[ ROW * COL ];
	for(int z=0; z<ROW; z++)
		for (int x=0; x<COL; x++)
		{
			float y = levelData[z*nRows + x];
			vertexData[z*ROW + x].SetPosition((x)*CELL_SIZE, y/10 - 230, (z)*CELL_SIZE);
			vertexData[z*ROW + x].color = getColorByHeight(y);
		}
	glGenBuffers(1, &vboId);
	glBindBuffer(GL_ARRAY_BUFFER, vboId);
	glBufferData(GL_ARRAY_BUFFER, sizeof(Engine::Vertex)*ROW * COL, vertexData,GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER, 0);

	//set color for wire frame vertex, and upload to GPU
	Engine::ColorRGBA8 wireframeColor(0,0,0,255);
	for(int z=0; z<ROW; z++)
		for (int x=0; x<COL; x++)
			vertexData[z*ROW + x].color = wireframeColor;
	glGenBuffers(1, &vboIdWireframe);
	glBindBuffer(GL_ARRAY_BUFFER, vboIdWireframe);
	glBufferData(GL_ARRAY_BUFFER, sizeof(Engine::Vertex)*ROW * COL,vertexData, GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	delete[] vertexData;

	//assign triangle indices. Two triangles at once, that form a rectangle.
	unsigned int *mapElements = new unsigned int[(COL-1)*(ROW-1)*2*3];
	for(int i=0,k=0; i<ROW-1; i++)
		for(int j=0; j<COL-1; j++)
		{
			mapElements[k++] = i*COL + j;
			mapElements[k++] = i*COL + j+1;
			mapElements[k++] = (i+1)*COL + j;

 			mapElements[k++] = i*COL + j+1;
 			mapElements[k++] = (i+1)*COL + j;
 			mapElements[k++] = (i+1)*COL + j+1;
		}
	glGenBuffers(1, &iboId);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iboId);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int)*(COL-1)*(ROW-1)*2*3, mapElements, GL_STATIC_DRAW);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
	delete[] mapElements;

	//assign line indices.
	unsigned int *wireframeElements = new unsigned int[(COL-1)*(ROW-1)*2*3*2];
	for(int i=0,k=0; i<ROW-1; i++)
		for(int j=0; j<COL-1; j++)
		{
			//horizontal top
			wireframeElements[k++] = i*COL + j;
			wireframeElements[k++] = i*COL + j+1;

			//diagonal
			wireframeElements[k++] = i*COL + j+1;
			wireframeElements[k++] = (i+1)*COL + j;

			//vertical left
			wireframeElements[k++] = (i+1)*COL + j;
			wireframeElements[k++] = i*COL + j;

			//horizontal bottom
			wireframeElements[k++] = (i+1)*COL + j;
			wireframeElements[k++] = (i+1)*COL + j+1;

			//vertical right
			wireframeElements[k++] = (i+1)*COL + j+1;
			wireframeElements[k++] = i*COL + j+1;
		}
	glGenBuffers(1, &iboIdWireframe);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iboIdWireframe);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int)*(COL-1)*(ROW-1)*2*3*2, wireframeElements, GL_STATIC_DRAW);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
	delete[] wireframeElements;

	printf("Uploaded map!\n");
}

Level::~Level(void)
{
	delete[] levelData;
}

void Level::SwitchWireframeVisibility()
{
	showWireframe = !showWireframe;
	glPolygonOffset(1, 1);
}

void Level::Render()
{
	glBindBuffer(GL_ARRAY_BUFFER, vboId);
	glEnableVertexAttribArray(0);
	glEnableVertexAttribArray(1);
	glEnableVertexAttribArray(2);
	glEnableVertexAttribArray(3);
	glVertexAttribPointer(0, 3, GL_FLOAT ,GL_FALSE, sizeof(Engine::Vertex), (void*)offsetof(Engine::Vertex,position));
	glVertexAttribPointer(1, 3, GL_FLOAT ,GL_FALSE, sizeof(Engine::Vertex), (void*)offsetof(Engine::Vertex,normal));
	glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Engine::Vertex), (void*)offsetof(Engine::Vertex,color));
	glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Engine::Vertex), (void*)offsetof(Engine::Vertex,uv));

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iboId);
	int size;  glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
	glDrawElements(GL_TRIANGLES, size/sizeof(unsigned int), GL_UNSIGNED_INT, 0);

	if(showWireframe)
	{
		glEnable(GL_POLYGON_OFFSET_FILL);

		glBindBuffer(GL_ARRAY_BUFFER, vboIdWireframe);
		glEnableVertexAttribArray(0);
		glEnableVertexAttribArray(1);
		glEnableVertexAttribArray(2);
		glEnableVertexAttribArray(3);
		glVertexAttribPointer(0, 3, GL_FLOAT ,GL_FALSE, sizeof(Engine::Vertex), (void*)offsetof(Engine::Vertex,position));
		glVertexAttribPointer(1, 3, GL_FLOAT ,GL_FALSE, sizeof(Engine::Vertex), (void*)offsetof(Engine::Vertex,normal));
		glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Engine::Vertex), (void*)offsetof(Engine::Vertex,color));
		glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Engine::Vertex), (void*)offsetof(Engine::Vertex,uv));

		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iboIdWireframe);
		int size;  glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
		glDrawElements(GL_LINES, size/sizeof(unsigned int), GL_UNSIGNED_INT, 0);
	}

	//glDrawArrays(GL_TRIANGLES, 0, /*(ROW-1) **/ (COL-2));

	glDisableVertexAttribArray(0);
	glDisableVertexAttribArray(1);
	glDisableVertexAttribArray(2);
	glDisableVertexAttribArray(3);
	glBindBuffer(GL_ARRAY_BUFFER, 0);
}

double Level::GetHeight(glm::vec2 point2d)
{
	int posx1 = (int)(point2d.x / CELL_SIZE);
	int posx2 = posx1 + 1;
	int posy1 = (int)(point2d.y / CELL_SIZE);
	int posy2 = posy1 + 1;

	double f00 = levelData[posy1*nRows + posx1];
	double f10 = levelData[posy1*nRows + posx2];
	double f11 = levelData[posy2*nRows + posx2];
	double f01 = levelData[posy2*nRows + posx1];

	double px = point2d.x / CELL_SIZE - posx1;
	double py = point2d.y / CELL_SIZE - posy2;

	double fFinal = f00 * (1.0 - px) * (1.0 - py) +
		f10 * px * (1.0 - py) + f01 * (1.0 - px) * py + f11 * px * py;

	return fFinal;
}

void Level::readAscFile(const std::string &fileName)
{
	std::ifstream file(fileName);
	if(file.fail())
		Engine::fatalError("File could not be opened!");

	std::string temp; ///temporary string

	file>>temp>>nCols; ///ignore word and read nCols

	file>>temp>>nRows; ///ignore word and read nRows

	for (int i=0; i < 5; i++)
		std::getline(file,temp); ///ignore next 4 rows

	//allocate memory
	levelData = new float[nRows*nCols];
	//read actual matrix data
	for (int y=0; y<nRows; ++y)
	{
		const int FINISHED_ELEMENTS = y*nCols;
		for (int x=0; x<nCols; ++x)
			file>>levelData[FINISHED_ELEMENTS + x];
	}
}

void Level::writeToBinary(const std::string &fileName, unsigned int nCols, unsigned int nRows)
{
	std::ofstream file(fileName,std::ios::binary);
	if(file.fail())
		Engine::fatalError("File could not be opened!");
	if(!nCols) nCols = this->nCols;
	if(!nRows) nRows = this->nRows;

	file.write((char*)&nCols,sizeof(nCols));
	file.write((char*)&nRows,sizeof(nRows));

	for(int i=0; i<nRows; i++)
		file.write((char*)&levelData[i*this->nCols],sizeof(float)*nCols);
}

Engine::ColorRGBA8 Level::getColorByHeight(float height)
{
	//Get the first element that is greater than or equal with height. This will be the upper bound. Seriously.
	auto itLow = heightColorMap.lower_bound(height);
	//Now make the upper bound equal to lower bound(witch is still the upper bound), then decrement the upper bound.
	auto itUp = itLow--;

	float height1=itLow->first, height2=itUp->first;
	Engine::ColorRGBA8 c1=itLow->second, c2=itUp->second, cRes;
	float t = (height - height1) / (height2 - height1);
	cRes.r = (c2.r - c1.r) * t + c1.r;
	cRes.g = (c2.g - c1.g) * t + c1.g;
	cRes.b = (c2.b - c1.b) * t + c1.b;
	cRes.a = (c2.a - c1.a) * t + c1.a;
	return cRes;
}

Engine::Position Level::normal(Engine::Position p[3])
{
	Engine::Position a, b;
	// calculate the vectors A and B
	// note that p[3] is defined with counterclockwise winding in mind
	// a
	a.x = p[0].x - p[1].x;
	a.y = p[0].y - p[1].y;
	a.z = p[0].z - p[1].z;
	// b
	b.x = p[1].x - p[2].x;
	b.y = p[1].y - p[2].y;
	b.z = p[1].z - p[2].z;

	// calculate the cross product
	Engine::Position normal;
	normal.x = (a.y * b.z) - (a.z * b.y);
	normal.y = (a.z * b.x) - (a.x * b.z);
	normal.z = (a.x * b.y) - (a.y * b.x);

	// normalize
	normal.Normalize();
}

void Level::readBinaryData(const std::string &fileName)
{
	//data from file
	std::ifstream file(fileName,std::ios::binary);
	if(file.fail())
		Engine::fatalError("File could not be opened!");
	file.read((char*)&nCols,sizeof(nCols));
	file.read((char*)&nRows,sizeof(nRows));

	levelData = new float[nRows*nCols];
	file.read((char*)levelData,sizeof(float)*nRows*nCols);
}
<|endoftext|>


<commit_before>
#include "vexcl.h"
#include "tests.h"
vex::Context* VexCLTest::CreateContext() {
  ctx = new vex::Context(vex::Filter::Env && vex::Filter::DoublePrecision);
  return ctx;
}

 vex::vector<double> VexCLTest::ConvertVector(blaze::DynamicVector<double>& blaze_vec) {
   unsigned int num_rows = blaze_vec.size();

  std::vector<double> temp(num_rows);

  for (int i = 0; i < num_rows; i++) {
    temp[i] = blaze_vec[i];
  }

  vex::vector<double> vex_vec(*ctx, num_rows);
  vex::copy(temp, vex_vec);

  return vex_vec;
}

 vex::SpMat<double> VexCLTest::ConvertMatrix(CSR& data) {
   unsigned int & num_rows = data.num_rows;
   unsigned int & num_cols = data.num_cols;

  std::vector<size_t>& row = data.row;
  std::vector<size_t>& col = data.col;
  std::vector<double>& val = data.val;

  vex::SpMat<double> mat(*ctx, num_rows, num_cols, row.data(), col.data(), val.data());

  return mat;
}

void VexCLTest::RunSPMV(vex::SpMat<double>& D_T, vex::SpMat<double>& M_invD, vex::vector<double>& gamma) {
  unsigned int num_rows = gamma.size();

  vex::vector<double> temporary(*ctx, num_rows);
  vex::vector<double> result(*ctx, num_rows);
  SPMV(D_T, M_invD, gamma, temporary, result);
  ctx->finish();
}
<commit_msg>Defined the WarmUp function with a simple vector addition code taken from a VexCL example<commit_after>
#include "vexcl.h"
#include "tests.h"
vex::Context* VexCLTest::CreateContext() {
  ctx = new vex::Context(vex::Filter::Env && vex::Filter::DoublePrecision);
  return ctx;
}

void VexCLTest::WarmUp(){

 // This code is taken from the VexCL demo
 const size_t N = 1024 * 1024;
 const size_t M = 1024;
 std::vector<double> A(N, 0);
 std::vector<double> B = random_vector<double>(N);
 std::vector<double> C = random_vector<double>(N);
 std::vector<double> D = random_vector<double>(N);
 vex::vector<double> a(*ctx, A);
 vex::vector<double> b(*ctx, B);
 vex::vector<double> c(*ctx, C);
 vex::vector<double> d(*ctx, D);
 a += b + c * d;

}

 vex::vector<double> VexCLTest::ConvertVector(blaze::DynamicVector<double>& blaze_vec) {
   unsigned int num_rows = blaze_vec.size();

  std::vector<double> temp(num_rows);

  for (int i = 0; i < num_rows; i++) {
    temp[i] = blaze_vec[i];
  }

  vex::vector<double> vex_vec(*ctx, num_rows);
  vex::copy(temp, vex_vec);

  return vex_vec;
}

 vex::SpMat<double> VexCLTest::ConvertMatrix(CSR& data) {
   unsigned int & num_rows = data.num_rows;
   unsigned int & num_cols = data.num_cols;

  std::vector<size_t>& row = data.row;
  std::vector<size_t>& col = data.col;
  std::vector<double>& val = data.val;

  vex::SpMat<double> mat(*ctx, num_rows, num_cols, row.data(), col.data(), val.data());

  return mat;
}

void VexCLTest::RunSPMV(vex::SpMat<double>& D_T, vex::SpMat<double>& M_invD, vex::vector<double>& gamma) {
  unsigned int num_rows = gamma.size();

  vex::vector<double> temporary(*ctx, num_rows);
  vex::vector<double> result(*ctx, num_rows);
  SPMV(D_T, M_invD, gamma, temporary, result);
  ctx->finish();
}
<|endoftext|>


<commit_before>/*
 *  Lab 1 - Basic multiprogramming
 *
 *	By: Andrew Radlbeck & John Wood
 *
 *
 * TODO:
 *			-- change errors to redirect to stderr
 *
 *
 */
#include <cstdio>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
using namespace std;

#define MAX_CMDS 2		//TODO upgrade to handle more commands
#define MAX_ARGS 5

int parse_user_commands(char *cmds[][MAX_ARGS], char *input, int *cmd_amount, int *arg_amount);
int child_first(char *cmd[], int pipefd[]);
int child_last(char *cmd[], int next_pipe[], int prev_pipe[]);

int main(int argc, char *argv[])
{
	// make sure correct parameter amount is entered
	if(argc != 2){
		printf("Error: %s [\"cmd | cmd\"]\n", argv[0]);		// inform user of usage
		printf("		  ^specify \"cmd\"s\n");
		return -1;										    // exit with an error
	}

	// parse user input
	int  cmd_amount, arg_amount;
	char *cmds[MAX_CMDS][MAX_ARGS];
	if(parse_user_commands(cmds, argv[1], &cmd_amount, &arg_amount)) return -1;

	// setup process
	int pipefd[2];		// create pipe file descripters
	int pipefd_b[2];		// create pipe file descripters

	if(pipe(pipefd) == -1){							// handle pipe errors
		printf("Error: could not open pipe\n");
		return -1;
	}

	if(pipe(pipefd_b) == -1){							// handle pipe errors
		printf("Error: could not open pipe\n");
		return -1;
	}

	pid_t cid = fork();
	if(cid == -1){									// handle fork errors
		printf("Error: could not create child\n");
		return -1;
	}

	if(cid == 0){	// in child
		child_first(cmds[0], pipefd);

	}else{			// in parent
		waitpid(cid, 0, 0);
		pid_t cid1 = fork();

		if(cid1 == -1){									// handle fork errors
			printf("Error: could not create child\n");
			return -1;
		}

		if(cid1 == 0){
			child_last(cmds[1], pipefd_b, pipefd);
		}else{
			close(pipefd_b[1]);	 		// close write end
			close(pipefd[0]);
			close(pipefd[1]);
			waitpid(cid1, 0, 0);
			char buf;	// reads bit-by-bit from pipe to stdout

			while(read(pipefd_b[0], &buf, 1)){
				write(1, &buf, 1);
			}printf("\n");

			close(pipefd_b[0]);		// close pipe
		}
	}

	return 0;
}

int child_first(char *cmd[], int pipefd[]){
	close(pipefd[0]); 		// close read end
	dup2(pipefd[1], 1);		// copys pipes write end into stdout [stdout > pipe]

	execvp(cmd[0], cmd);								// replace child with cmd		//TODO this needs to be execvp
	printf("Error: failed to launch %s\n", cmd[0]);	// if failed the code will continue
	return 0;
}

int child_last(char *cmd[], int next_pipe[], int prev_pipe[]){
	close(prev_pipe[1]);
	close(next_pipe[0]);
	dup2(prev_pipe[0], 0);		// copys pipes read end into stdin [pipe < stdin]
	dup2(next_pipe[1], 1);		// copys pipes write end into stdout [stdout > pipe]

	execvp(cmd[0], cmd);								// replace child with cmd		//TODO this needs to be execvp
	printf("Error: failed to launch %s\n", cmd[0]);	// if failed the code will continue
	return 0;
}

int parse_user_commands(char *cmds[][MAX_ARGS], char *input, int *cmd_amount, int *arg_amount)
{
	// TODO to add bonous part 2 insert another tokenizer to catch ">,<,<<,>>"
	//	- add file redirection code to pipe as well
	// get cmds from user input
	char *str, *token, *saveptr;					//TODO sub tokenize to handle command arguments
	char *sub_str, *sub_token, *sub_saveptr;
	int i, j;
	for(i = 1, str = input; ; i++, str = NULL){ 	// 'str = NULL' - resume last spot of the string
		token = strtok_r(str, "|", &saveptr);		// get pointer for next token
		if(token == NULL) break;

		for(j = 1, sub_str = token; ;j++, sub_str=NULL){ 		// sub tokenize to find arguments for commands
			sub_token = strtok_r(sub_str, " ", &sub_saveptr);

			if(i <= MAX_CMDS){
				if(j <= (MAX_ARGS + 1)){
					cmds[(i - 1)][(j - 1)] = sub_token;
					//printf("%i, %i, %s\n", i, j, cmds[(i - 1)][(j - 1)]); //TODO REMOVE
				}else{
					printf("Error: too many arguments\n");
					return -1;
				}
			}else{
				printf("Error: too many commands\n");
					return -1;
			}
			if(sub_token == NULL) break;					// we want the null in our argument array
		}
	}
	cmd_amount = &i;
	arg_amount = &j;

	return 0;
}<commit_msg>need to figure out signal handling<commit_after>/*
 *  Lab 1 - Basic multiprogramming
 *
 *	By: Andrew Radlbeck & John Wood
 *
 *
 * TODO:
 *			-- change errors to redirect to stderr
 *			-- close all pipe ends that are not being used in the current process
 *
 */
#include <cstdio>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
using namespace std;

#define MAX_CMDS 2		//TODO upgrade to handle more commands
#define MAX_ARGS 5

int parse_user_commands(char *cmds[][MAX_ARGS], char *input, int *cmd_amount, int *arg_amount);
int child_first(char *cmd[], int pipefd[]);
int child_last(char *cmd[], int next_pipe[], int prev_pipe[]);

int main(int argc, char *argv[])
{
	// make sure correct parameter amount is entered
	if(argc != 2){
		printf("Error: %s [\"cmd | cmd\"]\n", argv[0]);		// inform user of usage
		printf("		  ^specify \"cmd\"s\n");
		return -1;										    // exit with an error
	}

	// parse user input
	int  cmd_amount, arg_amount;
	char *cmds[MAX_CMDS][MAX_ARGS];
	if(parse_user_commands(cmds, argv[1], &cmd_amount, &arg_amount)) return -1;

	// setup process
	int pipefd[2];		// create pipe file descripters
	int pipefd_b[2];		// create pipe file descripters

	if(pipe(pipefd) == -1){							// handle pipe errors
		printf("Error: could not open pipe\n");
		return -1;
	}

	if(pipe(pipefd_b) == -1){							// handle pipe errors
		printf("Error: could not open pipe\n");
		return -1;
	}

	pid_t cid = fork();
	if(cid == -1){									// handle fork errors
		printf("Error: could not create child\n");
		return -1;
	}

	if(cid == 0){	// in child
		child_first(cmds[0], pipefd);

	}else{			// in parent
		waitpid(cid, 0, 0);
		pid_t cid1 = fork();

		if(cid1 == -1){									// handle fork errors
			printf("Error: could not create child\n");
			return -1;
		}

		if(cid1 == 0){
			child_last(cmds[1], pipefd_b, pipefd);
		}else{

			close(pipefd_b[1]);	 		// close write end
			close(pipefd[0]);
			close(pipefd[1]);
			char buf;	// reads bit-by-bit from pipe to stdout

			while(read(pipefd_b[0], &buf, 1)){
				write(1, &buf, 1);
			}printf("\n");
			//kill(cid1, SIGINT); //TODO need to return the signal back to the child process somehow
			wait(NULL);
			//waitpid(cid1, 0, 0);
			close(pipefd_b[0]);		// close pipe

		}
	}

	return 0;
}

int child_first(char *cmd[], int pipefd[]){
	close(pipefd[0]); 		// close read end
	dup2(pipefd[1], 1);		// copys pipes write end into stdout [stdout > pipe]

	execvp(cmd[0], cmd);								// replace child with cmd		//TODO this needs to be execvp
	printf("Error: failed to launch %s\n", cmd[0]);	// if failed the code will continue
	return 0;
}

int child_last(char *cmd[], int next_pipe[], int prev_pipe[]){
	close(prev_pipe[1]);
	close(next_pipe[0]);
	dup2(prev_pipe[0], 0);		// copys pipes read end into stdin [pipe < stdin]
	dup2(next_pipe[1], 1);		// copys pipes write end into stdout [stdout > pipe]
	dup2(next_pipe[0], 0);		// copys pipes write end into stdout [stdout > pipe]

	execvp(cmd[0], cmd);								// replace child with cmd		//TODO this needs to be execvp
	printf("Error: failed to launch %s\n", cmd[0]);	// if failed the code will continue
	return 0;
}

int parse_user_commands(char *cmds[][MAX_ARGS], char *input, int *cmd_amount, int *arg_amount)
{
	// TODO to add bonous part 2 insert another tokenizer to catch ">,<,<<,>>"
	//	- add file redirection code to pipe as well
	// get cmds from user input
	char *str, *token, *saveptr;					//TODO sub tokenize to handle command arguments
	char *sub_str, *sub_token, *sub_saveptr;
	int i, j;
	for(i = 1, str = input; ; i++, str = NULL){ 	// 'str = NULL' - resume last spot of the string
		token = strtok_r(str, "|", &saveptr);		// get pointer for next token
		if(token == NULL) break;

		for(j = 1, sub_str = token; ;j++, sub_str=NULL){ 		// sub tokenize to find arguments for commands
			sub_token = strtok_r(sub_str, " ", &sub_saveptr);

			if(i <= MAX_CMDS){
				if(j <= (MAX_ARGS + 1)){
					cmds[(i - 1)][(j - 1)] = sub_token;
					//printf("%i, %i, %s\n", i, j, cmds[(i - 1)][(j - 1)]); //TODO REMOVE
				}else{
					printf("Error: too many arguments\n");
					return -1;
				}
			}else{
				printf("Error: too many commands\n");
					return -1;
			}
			if(sub_token == NULL) break;					// we want the null in our argument array
		}
	}
	cmd_amount = &i;
	arg_amount = &j;

	return 0;
}<|endoftext|>


<commit_before>/*
 * A client for the logging protocol.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "log_client.hxx"
#include "util/ByteOrder.hxx"

#include <daemon/log.h>

#include <glib.h>
#include <assert.h>
#include <unistd.h>
#include <sys/socket.h>
#include <errno.h>
#include <string.h>

struct LogClient {
    int fd;

    size_t position;
    char buffer[32768];
};

LogClient *
log_client_new(int fd)
{
    assert(fd >= 0);

    LogClient *l = g_new(LogClient, 1);
    l->fd = fd;
    return l;
}

void
log_client_free(LogClient *l)
{
    close(l->fd);
    g_free(l);
}

static void
log_client_append(LogClient *client,
                  const void *p, size_t length)
{
    if (client->position + length <= sizeof(client->buffer))
        memcpy(client->buffer + client->position, p, length);

    client->position += length;
}

void
log_client_begin(LogClient *client)
{
    client->position = 0;

    log_client_append(client, &log_magic, sizeof(log_magic));
}

void
log_client_append_attribute(LogClient *client,
                            enum beng_log_attribute attribute,
                            const void *value, size_t length)
{
    uint8_t attribute8 = (uint8_t)attribute;
    log_client_append(client, &attribute8, sizeof(attribute8));
    log_client_append(client, value, length);
}

void
log_client_append_u16(LogClient *client,
                      enum beng_log_attribute attribute, uint16_t value)
{
    const uint16_t value2 = ToBE16(value);
    log_client_append_attribute(client, attribute, &value2, sizeof(value2));
}

void
log_client_append_u64(LogClient *client,
                      enum beng_log_attribute attribute, uint64_t value)
{
    const uint64_t value2 = ToBE64(value);
    log_client_append_attribute(client, attribute, &value2, sizeof(value2));
}

void
log_client_append_string(LogClient *client,
                         enum beng_log_attribute attribute, const char *value)
{
    assert(value != nullptr);

    log_client_append_attribute(client, attribute, value, strlen(value) + 1);
}

bool
log_client_commit(LogClient *client)
{
    assert(client != nullptr);
    assert(client->fd >= 0);
    assert(client->position > 0);

    if (client->position > sizeof(client->buffer))
        /* datagram is too large */
        return false;

    ssize_t nbytes = send(client->fd, client->buffer, client->position,
                          MSG_DONTWAIT|MSG_NOSIGNAL);
    if (nbytes < 0) {
        if (errno == EAGAIN || errno == EWOULDBLOCK)
            /* silently ignore EAGAIN */
            return true;

        daemon_log(1, "Failed to send to logger: %s\n", strerror(errno));
        return false;
    }

    if ((size_t)nbytes != client->position)
        daemon_log(1, "Short send to logger: %s\n", strerror(errno));

    return true;
}
<commit_msg>log_client: use new/delete instead of GLib<commit_after>/*
 * A client for the logging protocol.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "log_client.hxx"
#include "util/ByteOrder.hxx"

#include <daemon/log.h>

#include <assert.h>
#include <unistd.h>
#include <sys/socket.h>
#include <errno.h>
#include <string.h>

struct LogClient {
    int fd;

    size_t position;
    char buffer[32768];
};

LogClient *
log_client_new(int fd)
{
    assert(fd >= 0);

    auto *l = new LogClient();
    l->fd = fd;
    return l;
}

void
log_client_free(LogClient *l)
{
    close(l->fd);
    delete l;
}

static void
log_client_append(LogClient *client,
                  const void *p, size_t length)
{
    if (client->position + length <= sizeof(client->buffer))
        memcpy(client->buffer + client->position, p, length);

    client->position += length;
}

void
log_client_begin(LogClient *client)
{
    client->position = 0;

    log_client_append(client, &log_magic, sizeof(log_magic));
}

void
log_client_append_attribute(LogClient *client,
                            enum beng_log_attribute attribute,
                            const void *value, size_t length)
{
    uint8_t attribute8 = (uint8_t)attribute;
    log_client_append(client, &attribute8, sizeof(attribute8));
    log_client_append(client, value, length);
}

void
log_client_append_u16(LogClient *client,
                      enum beng_log_attribute attribute, uint16_t value)
{
    const uint16_t value2 = ToBE16(value);
    log_client_append_attribute(client, attribute, &value2, sizeof(value2));
}

void
log_client_append_u64(LogClient *client,
                      enum beng_log_attribute attribute, uint64_t value)
{
    const uint64_t value2 = ToBE64(value);
    log_client_append_attribute(client, attribute, &value2, sizeof(value2));
}

void
log_client_append_string(LogClient *client,
                         enum beng_log_attribute attribute, const char *value)
{
    assert(value != nullptr);

    log_client_append_attribute(client, attribute, value, strlen(value) + 1);
}

bool
log_client_commit(LogClient *client)
{
    assert(client != nullptr);
    assert(client->fd >= 0);
    assert(client->position > 0);

    if (client->position > sizeof(client->buffer))
        /* datagram is too large */
        return false;

    ssize_t nbytes = send(client->fd, client->buffer, client->position,
                          MSG_DONTWAIT|MSG_NOSIGNAL);
    if (nbytes < 0) {
        if (errno == EAGAIN || errno == EWOULDBLOCK)
            /* silently ignore EAGAIN */
            return true;

        daemon_log(1, "Failed to send to logger: %s\n", strerror(errno));
        return false;
    }

    if ((size_t)nbytes != client->position)
        daemon_log(1, "Short send to logger: %s\n", strerror(errno));

    return true;
}
<|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.

*/

#include "libtorrent/magnet_uri.hpp"
#include "libtorrent/session.hpp"
#include "libtorrent/torrent_handle.hpp"
#include "libtorrent/escape_string.hpp"

#include <string>

namespace libtorrent
{
	std::string make_magnet_uri(torrent_handle const& handle)
	{
		if (!handle.is_valid()) return "";

		char ret[1024];
		int num_chars = snprintf(ret, sizeof(ret), "magnet:?xt=urn:btih:%s"
			, base32encode(std::string((char*)handle.info_hash().begin(), 20)).c_str());

		std::string name = handle.name();

		if (!name.empty())
			num_chars += snprintf(ret + num_chars, sizeof(ret) - num_chars, "&dn=%s"
				, escape_string(name.c_str(), name.length()).c_str());

		char const* tracker = 0;
		torrent_status st = handle.status();
		if (!st.current_tracker.empty())
		{
			tracker = st.current_tracker.c_str();
		}
		else
		{
			std::vector<announce_entry> const& tr = handle.trackers();
			if (!tr.empty()) tracker = tr[0].url.c_str();
		}
		if (tracker)
			num_chars += snprintf(ret + num_chars, sizeof(ret) - num_chars, "&tr=%s"
				, escape_string(tracker, strlen(tracker)).c_str());

		return ret;
	}

	std::string make_magnet_uri(torrent_info const& info)
	{
		char ret[1024];
		int num_chars = snprintf(ret, sizeof(ret), "magnet:?xt=urn:btih:%s"
			, base32encode(std::string((char*)info.info_hash().begin(), 20)).c_str());

		std::string const& name = info.name();

		if (!name.empty())
			num_chars += snprintf(ret + num_chars, sizeof(ret) - num_chars, "&dn=%s"
				, escape_string(name.c_str(), name.length()).c_str());

		std::vector<announce_entry> const& tr = info.trackers();
		if (!tr.empty())
		{
			num_chars += snprintf(ret + num_chars, sizeof(ret) - num_chars, "&tr=%s"
				, escape_string(tr[0].url.c_str(), tr[0].url.length()).c_str());
		}

		return ret;
	}

#ifndef BOOST_NO_EXCEPTIONS
#ifndef TORRENT_NO_DEPRECATE
	torrent_handle add_magnet_uri(session& ses, std::string const& uri
		, std::string const& save_path
		, storage_mode_t storage_mode
		, bool paused
		, storage_constructor_type sc
		, void* userdata)
	{
		std::string name;
		std::string tracker;

		error_code ec;
		std::string display_name = url_has_argument(uri, "dn");
		if (!display_name.empty()) name = unescape_string(display_name.c_str(), ec);
		std::string tracker_string = url_has_argument(uri, "tr");
		if (!tracker_string.empty()) tracker = unescape_string(tracker_string.c_str(), ec);

		std::string btih = url_has_argument(uri, "xt");
		if (btih.empty()) return torrent_handle();

		if (btih.compare(0, 9, "urn:btih:") != 0) return torrent_handle();

		sha1_hash info_hash;
		if (btih.size() == 40 + 9) from_hex(&btih[9], 40, (char*)&info_hash[0]);
		else info_hash.assign(base32decode(btih.substr(9)));

		return ses.add_torrent(tracker.empty() ? 0 : tracker.c_str(), info_hash
			, name.empty() ? 0 : name.c_str(), save_path, entry()
			, storage_mode, paused, sc, userdata);
	}
#endif

	torrent_handle add_magnet_uri(session& ses, std::string const& uri
		, add_torrent_params p)
	{
		error_code ec;
		torrent_handle ret = add_magnet_uri(ses, uri, p, ec);
		if (ec) throw libtorrent_exception(ec);
		return ret;
	}
#endif
	torrent_handle add_magnet_uri(session& ses, std::string const& uri
		, add_torrent_params p, error_code& ec)
	{
		std::string name;
		std::string tracker;

		error_code e;
		std::string display_name = url_has_argument(uri, "dn");
		if (!display_name.empty()) name = unescape_string(display_name.c_str(), e);
		std::string tracker_string = url_has_argument(uri, "tr");
		if (!tracker_string.empty()) tracker = unescape_string(tracker_string.c_str(), e);

		std::string btih = url_has_argument(uri, "xt");
		if (btih.empty())
		{
			ec = error_code(errors::missing_info_hash_in_uri, libtorrent_category);
			return torrent_handle();
		}

		if (btih.compare(0, 9, "urn:btih:") != 0)
		{
			ec = error_code(errors::missing_info_hash_in_uri, libtorrent_category);
			return torrent_handle();
		}

		sha1_hash info_hash;
		if (btih.size() == 40 + 9) from_hex(&btih[9], 40, (char*)&info_hash[0]);
		else info_hash.assign(base32decode(btih.substr(9)));

		if (!tracker.empty()) p.tracker_url = tracker.c_str();
		p.info_hash = info_hash;
		if (!name.empty()) p.name = name.c_str();
		return ses.add_torrent(p, ec);
	}
}

<commit_msg>clean up in magnet_uri.cpp<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.

*/

#include "libtorrent/magnet_uri.hpp"
#include "libtorrent/session.hpp"
#include "libtorrent/torrent_handle.hpp"
#include "libtorrent/escape_string.hpp"

#include <string>

namespace libtorrent
{
	std::string make_magnet_uri(torrent_handle const& handle)
	{
		if (!handle.is_valid()) return "";

		char ret[1024];
		sha1_hash const& ih = handle.info_hash();
		int num_chars = snprintf(ret, sizeof(ret), "magnet:?xt=urn:btih:%s"
			, base32encode(std::string((char const*)&ih[0], 20)).c_str());

		std::string name = handle.name();

		if (!name.empty())
			num_chars += snprintf(ret + num_chars, sizeof(ret) - num_chars, "&dn=%s"
				, escape_string(name.c_str(), name.length()).c_str());

		char const* tracker = 0;
		torrent_status st = handle.status();
		if (!st.current_tracker.empty())
		{
			tracker = st.current_tracker.c_str();
		}
		else
		{
			std::vector<announce_entry> const& tr = handle.trackers();
			if (!tr.empty()) tracker = tr[0].url.c_str();
		}
		if (tracker)
			num_chars += snprintf(ret + num_chars, sizeof(ret) - num_chars, "&tr=%s"
				, escape_string(tracker, strlen(tracker)).c_str());

		return ret;
	}

	std::string make_magnet_uri(torrent_info const& info)
	{
		char ret[1024];
		sha1_hash const& ih = info.info_hash();
		int num_chars = snprintf(ret, sizeof(ret), "magnet:?xt=urn:btih:%s"
			, base32encode(std::string((char*)&ih[0], 20)).c_str());

		std::string const& name = info.name();

		if (!name.empty())
			num_chars += snprintf(ret + num_chars, sizeof(ret) - num_chars, "&dn=%s"
				, escape_string(name.c_str(), name.length()).c_str());

		std::vector<announce_entry> const& tr = info.trackers();
		if (!tr.empty())
		{
			num_chars += snprintf(ret + num_chars, sizeof(ret) - num_chars, "&tr=%s"
				, escape_string(tr[0].url.c_str(), tr[0].url.length()).c_str());
		}

		return ret;
	}

#ifndef BOOST_NO_EXCEPTIONS
#ifndef TORRENT_NO_DEPRECATE
	torrent_handle add_magnet_uri(session& ses, std::string const& uri
		, std::string const& save_path
		, storage_mode_t storage_mode
		, bool paused
		, storage_constructor_type sc
		, void* userdata)
	{
		std::string name;
		std::string tracker;

		error_code ec;
		std::string display_name = url_has_argument(uri, "dn");
		if (!display_name.empty()) name = unescape_string(display_name.c_str(), ec);
		std::string tracker_string = url_has_argument(uri, "tr");
		if (!tracker_string.empty()) tracker = unescape_string(tracker_string.c_str(), ec);

		std::string btih = url_has_argument(uri, "xt");
		if (btih.empty()) return torrent_handle();

		if (btih.compare(0, 9, "urn:btih:") != 0) return torrent_handle();

		sha1_hash info_hash;
		if (btih.size() == 40 + 9) from_hex(&btih[9], 40, (char*)&info_hash[0]);
		else info_hash.assign(base32decode(btih.substr(9)));

		return ses.add_torrent(tracker.empty() ? 0 : tracker.c_str(), info_hash
			, name.empty() ? 0 : name.c_str(), save_path, entry()
			, storage_mode, paused, sc, userdata);
	}
#endif

	torrent_handle add_magnet_uri(session& ses, std::string const& uri
		, add_torrent_params p)
	{
		error_code ec;
		torrent_handle ret = add_magnet_uri(ses, uri, p, ec);
		if (ec) throw libtorrent_exception(ec);
		return ret;
	}
#endif
	torrent_handle add_magnet_uri(session& ses, std::string const& uri
		, add_torrent_params p, error_code& ec)
	{
		std::string name;
		std::string tracker;

		error_code e;
		std::string display_name = url_has_argument(uri, "dn");
		if (!display_name.empty()) name = unescape_string(display_name.c_str(), e);
		std::string tracker_string = url_has_argument(uri, "tr");
		if (!tracker_string.empty()) tracker = unescape_string(tracker_string.c_str(), e);

		std::string btih = url_has_argument(uri, "xt");
		if (btih.empty())
		{
			ec = error_code(errors::missing_info_hash_in_uri, libtorrent_category);
			return torrent_handle();
		}

		if (btih.compare(0, 9, "urn:btih:") != 0)
		{
			ec = error_code(errors::missing_info_hash_in_uri, libtorrent_category);
			return torrent_handle();
		}

		sha1_hash info_hash;
		if (btih.size() == 40 + 9) from_hex(&btih[9], 40, (char*)&info_hash[0]);
		else info_hash.assign(base32decode(btih.substr(9)));

		if (!tracker.empty()) p.tracker_url = tracker.c_str();
		p.info_hash = info_hash;
		if (!name.empty()) p.name = name.c_str();
		return ses.add_torrent(p, ec);
	}
}

<|endoftext|>


<commit_before>#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QApplication>
#include <QDebug>
#include <QDir>
#include <QFile>
#include <QFileDialog>
#include <QMessageBox>
#include <QSettings>
#include <QStandardPaths>
#include <QWebFrame>

#define CONFIG_INI "config.ini"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // Set environment
    readSettings();
    xmlFileName = "";

    // Load blockly index
    ui->webView->load(QUrl("file://" + htmlIndex));
    ui->webView->page()->mainFrame()->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff);
    ui->webView->page()->mainFrame()->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff);

    // Set process
    process = new QProcess();
    process->setProcessChannelMode(QProcess::MergedChannels);
    connect(process, SIGNAL(started()), this, SLOT(onProcessStarted()));
    connect(process, SIGNAL(readyReadStandardOutput()), this, SLOT(onProcessOutputUpdated()));
    connect(process, SIGNAL(finished(int)), this, SLOT(onProcessFinished(int)));
}

MainWindow::~MainWindow()
{
    delete process;
    delete ui;
}

void MainWindow::readSettings() {
    // Set environment
    QString configFile = QStandardPaths::locate(QStandardPaths::DataLocation,
                                                CONFIG_INI,
                                                QStandardPaths::LocateFile);
    if (configFile.isEmpty()) {
        // Couldn't locate config.ini in DataLocation dirs.
        // Search in the binary path.
        configFile = QDir(QCoreApplication::applicationDirPath())
                .filePath(CONFIG_INI);
    }

#ifdef Q_OS_LINUX
    QString platform("linux/");
#elif defined(Q_OS_WIN)
    QString platform("windows/");
#elif defined(Q_OS_MAC)
    QString platform("mac/");
#endif

    QSettings settings(configFile, QSettings::IniFormat);

    arduinoIdePath = settings.value(
                platform + "arduino_ide_path",
                "/usr/bin/arduino"
                ).toString();
    tmpDirName = settings.value(
                platform + "tmp_dir_name",
                "/tmp/visualino/"
                ).toString();
    tmpFileName = settings.value(
                platform + "tmp_file_name",
                "/tmp/visualino/visualino.ino"
                ).toString();
    htmlIndex = settings.value(
                platform + "html_index",
                "/usr/share/visualino/html/index.html"
                ).toString();

    // Add applicationDirPath if relative path.
    // Needed specially for Windows.
    arduinoIdePath = checkRelativePath(arduinoIdePath);
    htmlIndex = checkRelativePath(htmlIndex);
    tmpDirName = checkRelativePath(tmpDirName);
    tmpFileName = checkRelativePath(tmpFileName);

}

QString MainWindow::checkRelativePath(const QString &fileName) {
    // Append the binary path if relative.
    if (QDir::isRelativePath(htmlIndex)) {
        return QDir(QCoreApplication::applicationDirPath()).filePath(htmlIndex);
    }
    return fileName;
}

void MainWindow::arduinoExec(const QString &action) {
    QStringList arguments;

    // Check if temp path exists
    QDir dir(tmpDirName);
    if (dir.exists() == false) {
        dir.mkdir(tmpDirName);
    }

    // Check if tmp file exists
    QFile tmpFile(tmpFileName);
    if (tmpFile.exists()) {
        tmpFile.remove();
    }
    tmpFile.open(QIODevice::WriteOnly);

    // Read code
    QWebFrame *mainFrame = ui->webView->page()->mainFrame();
    QVariant codeVariant = mainFrame->evaluateJavaScript("Blockly.Arduino.workspaceToCode();");
    QString codeString = codeVariant.toString();

    // Write code to tmp file
    tmpFile.write(codeString.toLocal8Bit());
    tmpFile.close();

    // Verify code
    arguments << action << tmpFileName;
    process->start(arduinoIdePath, arguments);
}

void MainWindow::actionNew() {
    // Unset file name
    xmlFileName = "";

    // Clear workspace
    QWebFrame *frame = ui->webView->page()->mainFrame();
    frame->evaluateJavaScript("Blockly.mainWorkspace.clear(); renderContent();");
}

void MainWindow::actionMonitor() {
}

void MainWindow::actionUpload() {
    arduinoExec("--upload");
}

void MainWindow::actionVerify() {
    arduinoExec("--verify");
}

void MainWindow::actionOpen() {
    // Open file dialog
    QString xmlFileName = QFileDialog::getOpenFileName(this, tr("Open File"),"", tr("Files (*.*)"));
    // Return if no file to open
    if (xmlFileName.isNull()) return;

    // Open file
    QFile xmlFile(xmlFileName);
    if (!xmlFile.open(QIODevice::ReadOnly)) {
        // Display error message
        QMessageBox msgBox(this);
        msgBox.setText(QString(tr("Couldn't open file to read content: %1.")).arg(xmlFileName));
        msgBox.exec();
        return;
    }

    // Read content
    QByteArray content = xmlFile.readAll();
    QString xml(content);
    QString escapedXml(escapeCharacters(xml));
    xmlFile.close();

    // Set XML to Workspace
    QWebFrame *frame = ui->webView->page()->mainFrame();
    frame->evaluateJavaScript(QString("var data = '%1'; var xml = Blockly.Xml.textToDom(data); Blockly.Xml.domToWorkspace(Blockly.getMainWorkspace(), xml);").arg(escapedXml));

    // Set file name
    this->xmlFileName = xmlFileName;
}

void MainWindow::actionSave() {
    QString xmlFileName;

    // Get XML
    QWebFrame *frame = ui->webView->page()->mainFrame();
    QVariant xml = frame->evaluateJavaScript("var xml = Blockly.Xml.workspaceToDom(Blockly.getMainWorkspace()); var data = Blockly.Xml.domToText(xml); data;");

    if (this->xmlFileName.isEmpty()) {
        // Open file dialog
         xmlFileName = QFileDialog::getSaveFileName(this, tr("Save File"),"", tr("Files (*.*)"));
        // Return if no file to open
        if (xmlFileName.isNull()) return;
    } else {
        xmlFileName = this->xmlFileName;
    }

    // Save XML to file
    QFile xmlFile(xmlFileName);

    if (!xmlFile.open(QIODevice::WriteOnly)) {
        // Display error message
        QMessageBox msgBox(this);
        msgBox.setText(QString(tr("Couldn't open file to save content: %1.")).arg(xmlFileName));
        msgBox.exec();
        return;
    }
    xmlFile.write(xml.toByteArray());
    xmlFile.close();

    // Set file name
    if (this->xmlFileName.isEmpty()) {
        this->xmlFileName = xmlFileName;
    }

    // Feedback
    statusBar()->showMessage(tr("Done saving."), 2000);
}

void MainWindow::onProcessFinished(int exitCode) {
    ui->textBrowser->append(tr("Finished."));
}

void MainWindow::onProcessOutputUpdated() {
    ui->textBrowser->append(QString(process->readAllStandardOutput()));
}

void MainWindow::onProcessStarted() {
    ui->textBrowser->append(tr("Running..."));
}

QString MainWindow::escapeCharacters(const QString& string)
{
    QString rValue = QString(string);
    // Assign \\ to backSlash
    QString backSlash = QString(QChar(0x5c)).append(QChar(0x5c));
    /* Replace \ with \\ */
    rValue = rValue.replace('\\', backSlash);
    // Assing \" to quote.
    QString quote = QString(QChar(0x5c)).append(QChar(0x22));
    // Replace " with \"
    rValue = rValue.replace('"', quote);
    return rValue;
}
<commit_msg>Fix local file URL generation.<commit_after>#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QApplication>
#include <QDebug>
#include <QDir>
#include <QFile>
#include <QFileDialog>
#include <QMessageBox>
#include <QSettings>
#include <QStandardPaths>
#include <QWebFrame>

#define CONFIG_INI "config.ini"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // Set environment
    readSettings();
    xmlFileName = "";

    // Load blockly index
    ui->webView->load(QUrl::fromLocalFile(htmlIndex));
    ui->webView->page()->mainFrame()->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff);
    ui->webView->page()->mainFrame()->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff);

    // Set process
    process = new QProcess();
    process->setProcessChannelMode(QProcess::MergedChannels);
    connect(process, SIGNAL(started()), this, SLOT(onProcessStarted()));
    connect(process, SIGNAL(readyReadStandardOutput()), this, SLOT(onProcessOutputUpdated()));
    connect(process, SIGNAL(finished(int)), this, SLOT(onProcessFinished(int)));
}

MainWindow::~MainWindow()
{
    delete process;
    delete ui;
}

void MainWindow::readSettings() {
    // Set environment
    QString configFile = QStandardPaths::locate(QStandardPaths::DataLocation,
                                                CONFIG_INI,
                                                QStandardPaths::LocateFile);
    if (configFile.isEmpty()) {
        // Couldn't locate config.ini in DataLocation dirs.
        // Search in the binary path.
        configFile = QDir(QCoreApplication::applicationDirPath())
                .filePath(CONFIG_INI);
    }

#ifdef Q_OS_LINUX
    QString platform("linux/");
#elif defined(Q_OS_WIN)
    QString platform("windows/");
#elif defined(Q_OS_MAC)
    QString platform("mac/");
#endif

    QSettings settings(configFile, QSettings::IniFormat);

    arduinoIdePath = settings.value(
                platform + "arduino_ide_path",
                "/usr/bin/arduino"
                ).toString();
    tmpDirName = settings.value(
                platform + "tmp_dir_name",
                "/tmp/visualino/"
                ).toString();
    tmpFileName = settings.value(
                platform + "tmp_file_name",
                "/tmp/visualino/visualino.ino"
                ).toString();
    htmlIndex = settings.value(
                platform + "html_index",
                "/usr/share/visualino/html/index.html"
                ).toString();

    // Add applicationDirPath if relative path.
    // Needed specially for Windows.
    arduinoIdePath = checkRelativePath(arduinoIdePath);
    htmlIndex = checkRelativePath(htmlIndex);
    tmpDirName = checkRelativePath(tmpDirName);
    tmpFileName = checkRelativePath(tmpFileName);

}

QString MainWindow::checkRelativePath(const QString &fileName) {
    // Append the binary path if relative.
    if (QDir::isRelativePath(htmlIndex)) {
        return QDir(QCoreApplication::applicationDirPath()).filePath(htmlIndex);
    }
    return fileName;
}

void MainWindow::arduinoExec(const QString &action) {
    QStringList arguments;

    // Check if temp path exists
    QDir dir(tmpDirName);
    if (dir.exists() == false) {
        dir.mkdir(tmpDirName);
    }

    // Check if tmp file exists
    QFile tmpFile(tmpFileName);
    if (tmpFile.exists()) {
        tmpFile.remove();
    }
    tmpFile.open(QIODevice::WriteOnly);

    // Read code
    QWebFrame *mainFrame = ui->webView->page()->mainFrame();
    QVariant codeVariant = mainFrame->evaluateJavaScript("Blockly.Arduino.workspaceToCode();");
    QString codeString = codeVariant.toString();

    // Write code to tmp file
    tmpFile.write(codeString.toLocal8Bit());
    tmpFile.close();

    // Verify code
    arguments << action << tmpFileName;
    process->start(arduinoIdePath, arguments);
}

void MainWindow::actionNew() {
    // Unset file name
    xmlFileName = "";

    // Clear workspace
    QWebFrame *frame = ui->webView->page()->mainFrame();
    frame->evaluateJavaScript("Blockly.mainWorkspace.clear(); renderContent();");
}

void MainWindow::actionMonitor() {
}

void MainWindow::actionUpload() {
    arduinoExec("--upload");
}

void MainWindow::actionVerify() {
    arduinoExec("--verify");
}

void MainWindow::actionOpen() {
    // Open file dialog
    QString xmlFileName = QFileDialog::getOpenFileName(this, tr("Open File"),"", tr("Files (*.*)"));
    // Return if no file to open
    if (xmlFileName.isNull()) return;

    // Open file
    QFile xmlFile(xmlFileName);
    if (!xmlFile.open(QIODevice::ReadOnly)) {
        // Display error message
        QMessageBox msgBox(this);
        msgBox.setText(QString(tr("Couldn't open file to read content: %1.")).arg(xmlFileName));
        msgBox.exec();
        return;
    }

    // Read content
    QByteArray content = xmlFile.readAll();
    QString xml(content);
    QString escapedXml(escapeCharacters(xml));
    xmlFile.close();

    // Set XML to Workspace
    QWebFrame *frame = ui->webView->page()->mainFrame();
    frame->evaluateJavaScript(QString("var data = '%1'; var xml = Blockly.Xml.textToDom(data); Blockly.Xml.domToWorkspace(Blockly.getMainWorkspace(), xml);").arg(escapedXml));

    // Set file name
    this->xmlFileName = xmlFileName;
}

void MainWindow::actionSave() {
    QString xmlFileName;

    // Get XML
    QWebFrame *frame = ui->webView->page()->mainFrame();
    QVariant xml = frame->evaluateJavaScript("var xml = Blockly.Xml.workspaceToDom(Blockly.getMainWorkspace()); var data = Blockly.Xml.domToText(xml); data;");

    if (this->xmlFileName.isEmpty()) {
        // Open file dialog
         xmlFileName = QFileDialog::getSaveFileName(this, tr("Save File"),"", tr("Files (*.*)"));
        // Return if no file to open
        if (xmlFileName.isNull()) return;
    } else {
        xmlFileName = this->xmlFileName;
    }

    // Save XML to file
    QFile xmlFile(xmlFileName);

    if (!xmlFile.open(QIODevice::WriteOnly)) {
        // Display error message
        QMessageBox msgBox(this);
        msgBox.setText(QString(tr("Couldn't open file to save content: %1.")).arg(xmlFileName));
        msgBox.exec();
        return;
    }
    xmlFile.write(xml.toByteArray());
    xmlFile.close();

    // Set file name
    if (this->xmlFileName.isEmpty()) {
        this->xmlFileName = xmlFileName;
    }

    // Feedback
    statusBar()->showMessage(tr("Done saving."), 2000);
}

void MainWindow::onProcessFinished(int exitCode) {
    ui->textBrowser->append(tr("Finished."));
}

void MainWindow::onProcessOutputUpdated() {
    ui->textBrowser->append(QString(process->readAllStandardOutput()));
}

void MainWindow::onProcessStarted() {
    ui->textBrowser->append(tr("Running..."));
}

QString MainWindow::escapeCharacters(const QString& string)
{
    QString rValue = QString(string);
    // Assign \\ to backSlash
    QString backSlash = QString(QChar(0x5c)).append(QChar(0x5c));
    /* Replace \ with \\ */
    rValue = rValue.replace('\\', backSlash);
    // Assing \" to quote.
    QString quote = QString(QChar(0x5c)).append(QChar(0x22));
    // Replace " with \"
    rValue = rValue.replace('"', quote);
    return rValue;
}
<|endoftext|>