<commit_before>/*
* (C) 2010,2014,2015 Jack Lloyd
* (C) 2017 René Korthaus, Rohde & Schwarz Cybersecurity
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include "cli.h"

#if defined(BOTAN_HAS_X509_CERTIFICATES) && defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)

#include <botan/certstor.h>
#include <botan/pk_keys.h>
#include <botan/pkcs8.h>
#include <botan/x509_ca.h>
#include <botan/x509cert.h>
#include <botan/x509path.h>
#include <botan/x509self.h>
#include <botan/data_src.h>

#if defined(BOTAN_HAS_OCSP)
   #include <botan/ocsp.h>
#endif

namespace Botan_CLI {

class Sign_Cert final : public Command
   {
   public:
      Sign_Cert()
         : Command("sign_cert --ca-key-pass= --hash=SHA-256 "
                   "--duration=365 --emsa= ca_cert ca_key pkcs10_req") {}

      std::string group() const override
         {
         return "x509";
         }

      std::string description() const override
         {
         return "Create a CA-signed X.509 certificate from a PKCS #10 CSR";
         }

      void go() override
         {
         Botan::X509_Certificate ca_cert(get_arg("ca_cert"));
         std::unique_ptr<Botan::Private_Key> key;
         const std::string pass = get_arg("ca-key-pass");

         if(!pass.empty())
            {
            key.reset(Botan::PKCS8::load_key(get_arg("ca_key"), rng(), pass));
            }
         else
            {
            key.reset(Botan::PKCS8::load_key(get_arg("ca_key"), rng()));
            }

         if(!key)
            {
            throw CLI_Error("Failed to load key from " + get_arg("ca_key"));
            }

         Botan::X509_CA ca(ca_cert, *key,
            {{"padding",get_arg_or("emsa", "EMSA4")}}, get_arg("hash"), rng());

         Botan::PKCS10_Request req(get_arg("pkcs10_req"));

         auto now = std::chrono::system_clock::now();

         Botan::X509_Time start_time(now);

         typedef std::chrono::duration<int, std::ratio<86400>> days;

         Botan::X509_Time end_time(now + days(get_arg_sz("duration")));

         Botan::X509_Certificate new_cert = ca.sign_request(req, rng(), start_time, end_time);

         output() << new_cert.PEM_encode();
         }
   };

BOTAN_REGISTER_COMMAND("sign_cert", Sign_Cert);

class Cert_Info final : public Command
   {
   public:
      Cert_Info() : Command("cert_info --fingerprint --ber file") {}

      std::string group() const override
         {
         return "x509";
         }

      std::string description() const override
         {
         return "Parse X.509 certificate and display data fields";
         }

      void go() override
         {
         Botan::DataSource_Stream in(get_arg("file"), flag_set("ber"));

         while(!in.end_of_data())
            {
            try
               {
               Botan::X509_Certificate cert(in);

               try
                  {
                  output() << cert.to_string() << std::endl;
                  }
               catch(Botan::Exception& e)
                  {
                  // to_string failed - report the exception and continue
                  output() << "X509_Certificate::to_string failed: " << e.what() << "\n";
                  }

               if(flag_set("fingerprint"))
                  output() << "Fingerprint: " << cert.fingerprint("SHA-256") << std::endl;
               }
            catch(Botan::Exception& e)
               {
               if(!in.end_of_data())
                  {
                  output() << "X509_Certificate parsing failed " << e.what() << "\n";
                  }
               }
            }
         }
   };

BOTAN_REGISTER_COMMAND("cert_info", Cert_Info);

#if defined(BOTAN_HAS_OCSP) && defined(BOTAN_HAS_HTTP_UTIL)

class OCSP_Check final : public Command
   {
   public:
      OCSP_Check() : Command("ocsp_check --timeout=3000 subject issuer") {}

      std::string group() const override
         {
         return "x509";
         }

      std::string description() const override
         {
         return "Verify an X.509 certificate against the issuers OCSP responder";
         }

      void go() override
         {
         Botan::X509_Certificate subject(get_arg("subject"));
         Botan::X509_Certificate issuer(get_arg("issuer"));
         std::chrono::milliseconds timeout(get_arg_sz("timeout"));

         Botan::Certificate_Store_In_Memory cas;
         cas.add_certificate(issuer);
         Botan::OCSP::Response resp = Botan::OCSP::online_check(issuer, subject, &cas, timeout);

         auto status = resp.status_for(issuer, subject, std::chrono::system_clock::now());

         if(status == Botan::Certificate_Status_Code::OCSP_RESPONSE_GOOD)
            {
            output() << "OCSP check OK\n";
            }
         else
            {
            output() << "OCSP check failed " << Botan::Path_Validation_Result::status_string(status) << "\n";
            }
         }
   };

BOTAN_REGISTER_COMMAND("ocsp_check", OCSP_Check);

#endif // OCSP && HTTP

class Cert_Verify final : public Command
   {
   public:
      Cert_Verify() : Command("cert_verify subject *ca_certs") {}

      std::string group() const override
         {
         return "x509";
         }

      std::string description() const override
         {
         return "Verify if the passed X.509 certificate passes path validation";
         }

      void go() override
         {
         Botan::X509_Certificate subject_cert(get_arg("subject"));
         Botan::Certificate_Store_In_Memory trusted;

         for(auto const& certfile : get_arg_list("ca_certs"))
            {
            trusted.add_certificate(Botan::X509_Certificate(certfile));
            }

         Botan::Path_Validation_Restrictions restrictions;

         Botan::Path_Validation_Result result =
            Botan::x509_path_validate(subject_cert,
                                      restrictions,
                                      trusted);

         if(result.successful_validation())
            {
            output() << "Certificate passes validation checks\n";
            }
         else
            {
            output() << "Certificate did not validate - " << result.result_string() << "\n";
            }
         }
   };

BOTAN_REGISTER_COMMAND("cert_verify", Cert_Verify);

class Gen_Self_Signed final : public Command
   {
   public:
      Gen_Self_Signed()
         : Command("gen_self_signed key CN --country= --dns= "
                   "--organization= --email= --key-pass= --ca --hash=SHA-256 --emsa=") {}

      std::string group() const override
         {
         return "x509";
         }

      std::string description() const override
         {
         return "Generate a self signed X.509 certificate";
         }

      void go() override
         {
         std::unique_ptr<Botan::Private_Key> key(Botan::PKCS8::load_key(get_arg("key"), rng(), get_arg("key-pass")));

         if(!key)
            {
            throw CLI_Error("Failed to load key from " + get_arg("key"));
            }

         Botan::X509_Cert_Options opts;

         opts.common_name  = get_arg("CN");
         opts.country      = get_arg("country");
         opts.organization = get_arg("organization");
         opts.email        = get_arg("email");
         opts.dns          = get_arg("dns");
         opts.set_padding_scheme(get_arg_or("emsa", "EMSA4"));

         if(flag_set("ca"))
            {
            opts.CA_key();
            }

         Botan::X509_Certificate cert = Botan::X509::create_self_signed_cert(opts, *key, get_arg("hash"), rng());

         output() << cert.PEM_encode();
         }
   };

BOTAN_REGISTER_COMMAND("gen_self_signed", Gen_Self_Signed);

class Generate_PKCS10 final : public Command
   {
   public:
      Generate_PKCS10()
         : Command("gen_pkcs10 key CN --country= --organization= "
                   "--email= --key-pass= --hash=SHA-256 --emsa=") {}

      std::string group() const override
         {
         return "x509";
         }

      std::string description() const override
         {
         return "Generate a PKCS #10 certificate signing request (CSR)";
         }

      void go() override
         {
         std::unique_ptr<Botan::Private_Key> key(Botan::PKCS8::load_key(get_arg("key"), rng(), get_arg("key-pass")));

         if(!key)
            {
            throw CLI_Error("Failed to load key from " + get_arg("key"));
            }

         Botan::X509_Cert_Options opts;

         opts.common_name  = get_arg("CN");
         opts.country      = get_arg("country");
         opts.organization = get_arg("organization");
         opts.email        = get_arg("email");
         opts.set_padding_scheme(get_arg_or("emsa", "EMSA4"));

         Botan::PKCS10_Request req = Botan::X509::create_cert_req(opts, *key, get_arg("hash"), rng());

         output() << req.PEM_encode();
         }
   };

BOTAN_REGISTER_COMMAND("gen_pkcs10", Generate_PKCS10);

}

#endif
<commit_msg>Don't default to PSS signatures<commit_after>/*
* (C) 2010,2014,2015 Jack Lloyd
* (C) 2017 René Korthaus, Rohde & Schwarz Cybersecurity
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include "cli.h"

#if defined(BOTAN_HAS_X509_CERTIFICATES) && defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)

#include <botan/certstor.h>
#include <botan/pk_keys.h>
#include <botan/pkcs8.h>
#include <botan/x509_ca.h>
#include <botan/x509cert.h>
#include <botan/x509path.h>
#include <botan/x509self.h>
#include <botan/data_src.h>

#if defined(BOTAN_HAS_OCSP)
   #include <botan/ocsp.h>
#endif

namespace Botan_CLI {

class Sign_Cert final : public Command
   {
   public:
      Sign_Cert()
         : Command("sign_cert --ca-key-pass= --hash=SHA-256 "
                   "--duration=365 --emsa= ca_cert ca_key pkcs10_req") {}

      std::string group() const override
         {
         return "x509";
         }

      std::string description() const override
         {
         return "Create a CA-signed X.509 certificate from a PKCS #10 CSR";
         }

      void go() override
         {
         Botan::X509_Certificate ca_cert(get_arg("ca_cert"));
         std::unique_ptr<Botan::Private_Key> key;
         const std::string pass = get_arg("ca-key-pass");
         const std::string emsa = get_arg("emsa");
         const std::string hash = get_arg("hash");

         if(!pass.empty())
            {
            key.reset(Botan::PKCS8::load_key(get_arg("ca_key"), rng(), pass));
            }
         else
            {
            key.reset(Botan::PKCS8::load_key(get_arg("ca_key"), rng()));
            }

         if(!key)
            {
            throw CLI_Error("Failed to load key from " + get_arg("ca_key"));
            }

         std::map<std::string, std::string> options;
         if(emsa.empty() == false)
            options["padding"] = emsa;

         Botan::X509_CA ca(ca_cert, *key, options, hash, rng());

         Botan::PKCS10_Request req(get_arg("pkcs10_req"));

         auto now = std::chrono::system_clock::now();

         Botan::X509_Time start_time(now);

         typedef std::chrono::duration<int, std::ratio<86400>> days;

         Botan::X509_Time end_time(now + days(get_arg_sz("duration")));

         Botan::X509_Certificate new_cert = ca.sign_request(req, rng(), start_time, end_time);

         output() << new_cert.PEM_encode();
         }
   };

BOTAN_REGISTER_COMMAND("sign_cert", Sign_Cert);

class Cert_Info final : public Command
   {
   public:
      Cert_Info() : Command("cert_info --fingerprint --ber file") {}

      std::string group() const override
         {
         return "x509";
         }

      std::string description() const override
         {
         return "Parse X.509 certificate and display data fields";
         }

      void go() override
         {
         Botan::DataSource_Stream in(get_arg("file"), flag_set("ber"));

         while(!in.end_of_data())
            {
            try
               {
               Botan::X509_Certificate cert(in);

               try
                  {
                  output() << cert.to_string() << std::endl;
                  }
               catch(Botan::Exception& e)
                  {
                  // to_string failed - report the exception and continue
                  output() << "X509_Certificate::to_string failed: " << e.what() << "\n";
                  }

               if(flag_set("fingerprint"))
                  output() << "Fingerprint: " << cert.fingerprint("SHA-256") << std::endl;
               }
            catch(Botan::Exception& e)
               {
               if(!in.end_of_data())
                  {
                  output() << "X509_Certificate parsing failed " << e.what() << "\n";
                  }
               }
            }
         }
   };

BOTAN_REGISTER_COMMAND("cert_info", Cert_Info);

#if defined(BOTAN_HAS_OCSP) && defined(BOTAN_HAS_HTTP_UTIL)

class OCSP_Check final : public Command
   {
   public:
      OCSP_Check() : Command("ocsp_check --timeout=3000 subject issuer") {}

      std::string group() const override
         {
         return "x509";
         }

      std::string description() const override
         {
         return "Verify an X.509 certificate against the issuers OCSP responder";
         }

      void go() override
         {
         Botan::X509_Certificate subject(get_arg("subject"));
         Botan::X509_Certificate issuer(get_arg("issuer"));
         std::chrono::milliseconds timeout(get_arg_sz("timeout"));

         Botan::Certificate_Store_In_Memory cas;
         cas.add_certificate(issuer);
         Botan::OCSP::Response resp = Botan::OCSP::online_check(issuer, subject, &cas, timeout);

         auto status = resp.status_for(issuer, subject, std::chrono::system_clock::now());

         if(status == Botan::Certificate_Status_Code::OCSP_RESPONSE_GOOD)
            {
            output() << "OCSP check OK\n";
            }
         else
            {
            output() << "OCSP check failed " << Botan::Path_Validation_Result::status_string(status) << "\n";
            }
         }
   };

BOTAN_REGISTER_COMMAND("ocsp_check", OCSP_Check);

#endif // OCSP && HTTP

class Cert_Verify final : public Command
   {
   public:
      Cert_Verify() : Command("cert_verify subject *ca_certs") {}

      std::string group() const override
         {
         return "x509";
         }

      std::string description() const override
         {
         return "Verify if the passed X.509 certificate passes path validation";
         }

      void go() override
         {
         Botan::X509_Certificate subject_cert(get_arg("subject"));
         Botan::Certificate_Store_In_Memory trusted;

         for(auto const& certfile : get_arg_list("ca_certs"))
            {
            trusted.add_certificate(Botan::X509_Certificate(certfile));
            }

         Botan::Path_Validation_Restrictions restrictions;

         Botan::Path_Validation_Result result =
            Botan::x509_path_validate(subject_cert,
                                      restrictions,
                                      trusted);

         if(result.successful_validation())
            {
            output() << "Certificate passes validation checks\n";
            }
         else
            {
            output() << "Certificate did not validate - " << result.result_string() << "\n";
            }
         }
   };

BOTAN_REGISTER_COMMAND("cert_verify", Cert_Verify);

class Gen_Self_Signed final : public Command
   {
   public:
      Gen_Self_Signed()
         : Command("gen_self_signed key CN --country= --dns= "
                   "--organization= --email= --key-pass= --ca --hash=SHA-256 --emsa=") {}

      std::string group() const override
         {
         return "x509";
         }

      std::string description() const override
         {
         return "Generate a self signed X.509 certificate";
         }

      void go() override
         {
         std::unique_ptr<Botan::Private_Key> key(Botan::PKCS8::load_key(get_arg("key"), rng(), get_arg("key-pass")));

         if(!key)
            {
            throw CLI_Error("Failed to load key from " + get_arg("key"));
            }

         Botan::X509_Cert_Options opts;

         opts.common_name  = get_arg("CN");
         opts.country      = get_arg("country");
         opts.organization = get_arg("organization");
         opts.email        = get_arg("email");
         opts.dns          = get_arg("dns");

         std::string emsa = get_arg("emsa");

         if(emsa.empty() == false)
            opts.set_padding_scheme(emsa);

         if(flag_set("ca"))
            {
            opts.CA_key();
            }

         Botan::X509_Certificate cert = Botan::X509::create_self_signed_cert(opts, *key, get_arg("hash"), rng());

         output() << cert.PEM_encode();
         }
   };

BOTAN_REGISTER_COMMAND("gen_self_signed", Gen_Self_Signed);

class Generate_PKCS10 final : public Command
   {
   public:
      Generate_PKCS10()
         : Command("gen_pkcs10 key CN --country= --organization= "
                   "--email= --key-pass= --hash=SHA-256 --emsa=") {}

      std::string group() const override
         {
         return "x509";
         }

      std::string description() const override
         {
         return "Generate a PKCS #10 certificate signing request (CSR)";
         }

      void go() override
         {
         std::unique_ptr<Botan::Private_Key> key(Botan::PKCS8::load_key(get_arg("key"), rng(), get_arg("key-pass")));

         if(!key)
            {
            throw CLI_Error("Failed to load key from " + get_arg("key"));
            }

         Botan::X509_Cert_Options opts;

         opts.common_name  = get_arg("CN");
         opts.country      = get_arg("country");
         opts.organization = get_arg("organization");
         opts.email        = get_arg("email");

         std::string emsa = get_arg("emsa");

         if(emsa.empty() == false)
            opts.set_padding_scheme(emsa);

         Botan::PKCS10_Request req = Botan::X509::create_cert_req(opts, *key, get_arg("hash"), rng());

         output() << req.PEM_encode();
         }
   };

BOTAN_REGISTER_COMMAND("gen_pkcs10", Generate_PKCS10);

}

#endif
<|endoftext|>


<commit_before>#include "stdafx.h"

static float CalcRadius(const Mesh* m)
{
	const Block& b = m->GetRawDatas();
	float maxSq = 0;
	for (auto& it : b.vertices) {
		float sq = XMVectorGetX(XMVector3LengthSq(XMLoadFloat3(&it.xyz)));
		maxSq = std::max(maxSq, sq);
	}
	return sqrt(maxSq);
}

App::App() : scale(1), lastX(-1), lastY(-1), sprite(nullptr), font(nullptr), meshTiny(nullptr), animationNumber(0)
{
	quat = XMQuaternionIdentity();
	ZeroMemory(mesh, sizeof(mesh));
}

App::~App()
{
}

void App::Init(const char* fileName)
{
	Destroy();

	debugRenderer.Init();

	g_type = "mesh";

	sprite = new SpriteBatch(deviceMan11.GetContext());
	font = new SpriteFont(deviceMan11.GetDevice(), L"resource\\font.spritefont");

	meshTiny = new MeshX("C:\\Program Files (x86)\\Microsoft DirectX SDK (August 2009)\\Samples\\Media\\Tiny\\tiny.x");

	if (fileName) {
		const char* ext = strrchr(fileName, '.');
		if (ext && !_stricmp(ext, ".bvh")) {
			mesh[0] = new Bvh(fileName);
		} else {
			mesh[0] = new MeshX(fileName);
		}
	} else {
		mesh[0] = new Bvh("D:\\github\\aachan.bvh");
	//	mesh[1] = new Bvh("D:\\github\\kashiyuka.bvh");
	//	mesh[2] = new Bvh("D:\\github\\nocchi.bvh");
	}

	float radius = CalcRadius(mesh[0]);
	scale = 1 / std::max(0.00001f, radius);

	matrixMan.Set(MatrixMan::PROJ, XMMatrixPerspectiveFovLH(45 * XM_PI / 180, (float)SCR_W / SCR_H, 0.1f, 1000.0f));

	dynamic_cast<Bvh*>(mesh[0])->FixBones("Chest");
	dynamic_cast<Bvh*>(mesh[0])->LinkTo("RightHip", "Chest");
	dynamic_cast<Bvh*>(mesh[0])->LinkTo("LeftHip", "Chest");
	dynamic_cast<Bvh*>(mesh[0])->FixBones("Neck");
	dynamic_cast<Bvh*>(mesh[0])->LinkTo("RightCollar", "Neck");
	dynamic_cast<Bvh*>(mesh[0])->LinkTo("LeftCollar", "Neck");
	meshTiny->ApplyXLocalAxisToBvh(dynamic_cast<Bvh*>(mesh[0]));
}

void App::MouseWheel(float delta)
{
	if (delta > 0) {
		scale *= 1.1f;
	}
	if (delta < 0) {
		scale /= 1.1f;
	}
}

void App::LButtonDown(float x, float y)
{
	lastX = x;
	lastY = y;
}

void App::LButtonUp(float x, float y)
{
	MouseMove(x, y);
	lastX = lastY = -1;
}

void App::MouseMove(float x, float y)
{
	if (lastX < 0 || lastY < 0) {
		return;
	}
	float dx = x - lastX;
	float dy = - (y - lastY);

	lastX = x;
	lastY = y;

	XMVECTOR axis = XMVectorSet(-dy, dx, 0, 0);
	float len = XMVectorGetX(XMVector2Length(axis));
	if (!len) {
		return;
	}

	XMVECTOR q = XMQuaternionRotationAxis(axis, len * -2 * XM_PI);
	quat = XMQuaternionMultiply(quat, q);
}

inline XMFLOAT2 GetScreenPos(const XMMATRIX& mLocal)
{
	XMFLOAT4X4 mViewport;
	XMMATRIX mW, mV, mP;
	matrixMan.Get(MatrixMan::WORLD, mW);
	matrixMan.Get(MatrixMan::VIEW, mV);
	matrixMan.Get(MatrixMan::PROJ, mP);
	XMStoreFloat4x4(&mViewport, XMMatrixIdentity());
	mViewport._11 = SCR_W / 2;
	mViewport._22 = -SCR_H / 2;
	mViewport._41 = SCR_W / 2;
	mViewport._42 = SCR_H / 2;

	XMMATRIX m = mLocal * mW * mV * mP * XMLoadFloat4x4(&mViewport);

	XMFLOAT2 p;
	p.x = XMVectorGetX(m.r[3]) / XMVectorGetW(m.r[3]);
	p.y = XMVectorGetY(m.r[3]) / XMVectorGetW(m.r[3]);
	return p;
}

void App::DrawBoneNames(Bvh* bvh)
{
	const std::vector<BvhFrame>& frames = bvh->GetFrames();
	for (auto& it : frames) {
		if (it.childId < 0) {
			continue;
		}
		XMFLOAT2 pos = GetScreenPos(XMLoadFloat4x4(&it.result));

		WCHAR wname[MAX_PATH];
		MultiByteToWideChar(CP_ACP, 0, it.name, -1, wname, dimof(wname));

		XMVECTOR size = font->MeasureString(wname);
		pos.x -= XMVectorGetX(size) / 2;
		pos.y -= XMVectorGetY(size) / 2;
		XMFLOAT2 origin = {0, 0};
		font->DrawString(sprite, wname, pos, Colors::Black, 0, origin, 0.7f);
		pos.x += 1.0f;
		pos.y += 1.0f;
		font->DrawString(sprite, wname, pos, Colors::White, 0, origin, 0.7f);
	}
}

void App::DrawBoneNames(MeshX* meshX)
{
	const std::vector<Frame>& frames = meshX->GetFrames();
	for (auto& it : frames) {
		XMFLOAT2 pos = GetScreenPos(XMLoadFloat4x4(&it.result));

		WCHAR wname[MAX_PATH];
		MultiByteToWideChar(CP_ACP, 0, it.name, -1, wname, dimof(wname));
		if (wname[0] == '\0') {
			wcscpy(wname, L"[NO NAME]");
		}

		XMVECTOR size = font->MeasureString(wname);
		pos.x -= XMVectorGetX(size) / 2;
		pos.y -= XMVectorGetY(size) / 2;
		XMFLOAT2 origin = {0, 0};
		font->DrawString(sprite, wname, pos, Colors::Black, 0, origin, 0.7f);
		pos.x += 1.0f;
		pos.y += 1.0f;
		font->DrawString(sprite, wname, pos, Colors::White, 0, origin, 0.7f);
	}
}

void App::Update()
{
	if (GetKeyState('P') & 0x80) {
		g_type = "pivot";
	}
	if (GetKeyState('M') & 0x80) {
		g_type = "mesh";
	}
	if (GetKeyState('B') & 0x80) {
		g_type = "bone";
	}
	for (auto& i : {'0', '1', '2', '3', '4'}) {
		if (GetKeyState(i) & 0x80) {
			animationNumber = i - '0';
		}
	}
}

void App::Draw()
{
	LARGE_INTEGER t, f;
	QueryPerformanceCounter(&t);
	QueryPerformanceFrequency(&f);
	double time = ((double)t.QuadPart / f.QuadPart);
//	float time = 0;

//	XMMATRIX mRot = XMMatrixRotationQuaternion(XMQuaternionRotationAxis(XMVectorSet(1, 0, 0, 0), time / 2 * XM_PI));
	XMMATRIX mRot = XMMatrixRotationQuaternion(quat);
	XMMATRIX mScale = XMMatrixScaling(scale, scale, scale);

	matrixMan.Set(MatrixMan::WORLD, mScale * mRot);

	float dist = 3;
//	float rot = time / 5 * XM_PI;
	float rot = XM_PI;
	matrixMan.Set(MatrixMan::VIEW, XMMatrixLookAtLH(XMVectorSet(sin(rot) * dist, 0, cos(rot) * dist, 1), XMVectorSet(0, 0, 0, 0), XMVectorSet(0, 1, 0, 0)));

    sprite->Begin();

	for (auto& it : mesh) {
		if (it && meshTiny) {
			it->Draw(0, time);

			Bvh* bvh = dynamic_cast<Bvh*>(it);

			if (bvh) {
				meshTiny->DrawBvh(bvh, time);
			//	meshTiny->Draw(animationNumber, time);
				DrawBoneNames(bvh);
			}
		}
	}

	MeshX* x = dynamic_cast<MeshX*>(meshTiny);
	if (x) {
		DrawBoneNames(x);
	}

	sprite->End();
}

void App::Destroy()
{
	SAFE_DELETE(mesh[0]);
	SAFE_DELETE(mesh[1]);
	SAFE_DELETE(mesh[2]);
	SAFE_DELETE(meshTiny);
	SAFE_DELETE(font);
	SAFE_DELETE(sprite);

	debugRenderer.Destroy();
}

std::string g_type;
<commit_msg>toggle debug text by pressing 'T'<commit_after>#include "stdafx.h"

static float CalcRadius(const Mesh* m)
{
	const Block& b = m->GetRawDatas();
	float maxSq = 0;
	for (auto& it : b.vertices) {
		float sq = XMVectorGetX(XMVector3LengthSq(XMLoadFloat3(&it.xyz)));
		maxSq = std::max(maxSq, sq);
	}
	return sqrt(maxSq);
}

App::App() : scale(1), lastX(-1), lastY(-1), sprite(nullptr), font(nullptr), meshTiny(nullptr), animationNumber(0)
{
	quat = XMQuaternionIdentity();
	ZeroMemory(mesh, sizeof(mesh));
}

App::~App()
{
}

void App::Init(const char* fileName)
{
	Destroy();

	debugRenderer.Init();

	g_type = "mesh";

	sprite = new SpriteBatch(deviceMan11.GetContext());
	font = new SpriteFont(deviceMan11.GetDevice(), L"resource\\font.spritefont");

	meshTiny = new MeshX("C:\\Program Files (x86)\\Microsoft DirectX SDK (August 2009)\\Samples\\Media\\Tiny\\tiny.x");

	if (fileName) {
		const char* ext = strrchr(fileName, '.');
		if (ext && !_stricmp(ext, ".bvh")) {
			mesh[0] = new Bvh(fileName);
		} else {
			mesh[0] = new MeshX(fileName);
		}
	} else {
		mesh[0] = new Bvh("D:\\github\\aachan.bvh");
	//	mesh[1] = new Bvh("D:\\github\\kashiyuka.bvh");
	//	mesh[2] = new Bvh("D:\\github\\nocchi.bvh");
	}

	float radius = CalcRadius(mesh[0]);
	scale = 1 / std::max(0.00001f, radius);

	matrixMan.Set(MatrixMan::PROJ, XMMatrixPerspectiveFovLH(45 * XM_PI / 180, (float)SCR_W / SCR_H, 0.1f, 1000.0f));

	dynamic_cast<Bvh*>(mesh[0])->FixBones("Chest");
	dynamic_cast<Bvh*>(mesh[0])->LinkTo("RightHip", "Chest");
	dynamic_cast<Bvh*>(mesh[0])->LinkTo("LeftHip", "Chest");
	dynamic_cast<Bvh*>(mesh[0])->FixBones("Neck");
	dynamic_cast<Bvh*>(mesh[0])->LinkTo("RightCollar", "Neck");
	dynamic_cast<Bvh*>(mesh[0])->LinkTo("LeftCollar", "Neck");
	meshTiny->ApplyXLocalAxisToBvh(dynamic_cast<Bvh*>(mesh[0]));
}

void App::MouseWheel(float delta)
{
	if (delta > 0) {
		scale *= 1.1f;
	}
	if (delta < 0) {
		scale /= 1.1f;
	}
}

void App::LButtonDown(float x, float y)
{
	lastX = x;
	lastY = y;
}

void App::LButtonUp(float x, float y)
{
	MouseMove(x, y);
	lastX = lastY = -1;
}

void App::MouseMove(float x, float y)
{
	if (lastX < 0 || lastY < 0) {
		return;
	}
	float dx = x - lastX;
	float dy = - (y - lastY);

	lastX = x;
	lastY = y;

	XMVECTOR axis = XMVectorSet(-dy, dx, 0, 0);
	float len = XMVectorGetX(XMVector2Length(axis));
	if (!len) {
		return;
	}

	XMVECTOR q = XMQuaternionRotationAxis(axis, len * -2 * XM_PI);
	quat = XMQuaternionMultiply(quat, q);
}

inline XMFLOAT2 GetScreenPos(const XMMATRIX& mLocal)
{
	XMFLOAT4X4 mViewport;
	XMMATRIX mW, mV, mP;
	matrixMan.Get(MatrixMan::WORLD, mW);
	matrixMan.Get(MatrixMan::VIEW, mV);
	matrixMan.Get(MatrixMan::PROJ, mP);
	XMStoreFloat4x4(&mViewport, XMMatrixIdentity());
	mViewport._11 = SCR_W / 2;
	mViewport._22 = -SCR_H / 2;
	mViewport._41 = SCR_W / 2;
	mViewport._42 = SCR_H / 2;

	XMMATRIX m = mLocal * mW * mV * mP * XMLoadFloat4x4(&mViewport);

	XMFLOAT2 p;
	p.x = XMVectorGetX(m.r[3]) / XMVectorGetW(m.r[3]);
	p.y = XMVectorGetY(m.r[3]) / XMVectorGetW(m.r[3]);
	return p;
}

void App::DrawBoneNames(Bvh* bvh)
{
	const std::vector<BvhFrame>& frames = bvh->GetFrames();
	for (auto& it : frames) {
		if (it.childId < 0) {
			continue;
		}
		XMFLOAT2 pos = GetScreenPos(XMLoadFloat4x4(&it.result));

		WCHAR wname[MAX_PATH];
		MultiByteToWideChar(CP_ACP, 0, it.name, -1, wname, dimof(wname));

		XMVECTOR size = font->MeasureString(wname);
		pos.x -= XMVectorGetX(size) / 2;
		pos.y -= XMVectorGetY(size) / 2;
		XMFLOAT2 origin = {0, 0};
		font->DrawString(sprite, wname, pos, Colors::Black, 0, origin, 0.7f);
		pos.x += 1.0f;
		pos.y += 1.0f;
		font->DrawString(sprite, wname, pos, Colors::White, 0, origin, 0.7f);
	}
}

void App::DrawBoneNames(MeshX* meshX)
{
	const std::vector<Frame>& frames = meshX->GetFrames();
	for (auto& it : frames) {
		XMFLOAT2 pos = GetScreenPos(XMLoadFloat4x4(&it.result));

		WCHAR wname[MAX_PATH];
		MultiByteToWideChar(CP_ACP, 0, it.name, -1, wname, dimof(wname));
		if (wname[0] == '\0') {
			wcscpy(wname, L"[NO NAME]");
		}

		XMVECTOR size = font->MeasureString(wname);
		pos.x -= XMVectorGetX(size) / 2;
		pos.y -= XMVectorGetY(size) / 2;
		XMFLOAT2 origin = {0, 0};
		font->DrawString(sprite, wname, pos, Colors::Black, 0, origin, 0.7f);
		pos.x += 1.0f;
		pos.y += 1.0f;
		font->DrawString(sprite, wname, pos, Colors::White, 0, origin, 0.7f);
	}
}

void App::Update()
{
	if (GetKeyState('P') & 0x80) {
		g_type = "pivot";
	}
	if (GetKeyState('M') & 0x80) {
		g_type = "mesh";
	}
	if (GetKeyState('B') & 0x80) {
		g_type = "bone";
	}
	for (auto& i : {'0', '1', '2', '3', '4'}) {
		if (GetKeyState(i) & 0x80) {
			animationNumber = i - '0';
		}
	}
}

void App::Draw()
{
	LARGE_INTEGER t, f;
	QueryPerformanceCounter(&t);
	QueryPerformanceFrequency(&f);
	double time = ((double)t.QuadPart / f.QuadPart);
//	float time = 0;

//	XMMATRIX mRot = XMMatrixRotationQuaternion(XMQuaternionRotationAxis(XMVectorSet(1, 0, 0, 0), time / 2 * XM_PI));
	XMMATRIX mRot = XMMatrixRotationQuaternion(quat);
	XMMATRIX mScale = XMMatrixScaling(scale, scale, scale);

	matrixMan.Set(MatrixMan::WORLD, mScale * mRot);

	float dist = 3;
//	float rot = time / 5 * XM_PI;
	float rot = XM_PI;
	matrixMan.Set(MatrixMan::VIEW, XMMatrixLookAtLH(XMVectorSet(sin(rot) * dist, 0, cos(rot) * dist, 1), XMVectorSet(0, 0, 0, 0), XMVectorSet(0, 1, 0, 0)));

    sprite->Begin();

	for (auto& it : mesh) {
		if (it && meshTiny) {
			it->Draw(0, time);

			Bvh* bvh = dynamic_cast<Bvh*>(it);

			if (bvh) {
				meshTiny->DrawBvh(bvh, time);
			//	meshTiny->Draw(animationNumber, time);
				if (GetKeyState('T') & 0x01) {
					DrawBoneNames(bvh);
				}
			}
		}
	}

	MeshX* x = dynamic_cast<MeshX*>(meshTiny);
	if (x && (GetKeyState('T') & 0x01)) {
		DrawBoneNames(x);
	}

	sprite->End();
}

void App::Destroy()
{
	SAFE_DELETE(mesh[0]);
	SAFE_DELETE(mesh[1]);
	SAFE_DELETE(mesh[2]);
	SAFE_DELETE(meshTiny);
	SAFE_DELETE(font);
	SAFE_DELETE(sprite);

	debugRenderer.Destroy();
}

std::string g_type;
<|endoftext|>


<commit_before>/*
 *  NotifyUser.cpp
 *  OpenLieroX
 *
 *  Created by Albert Zeyer on 25.09.08.
 *  code under LGPL
 *
 */

#include "NotifyUser.h"

#ifdef DEDICATED_ONLY

void NotifyUserOnEvent() {}
void ClearUserNotify() {}

#else

#if defined(__APPLE__)
	#include <Carbon/Carbon.h>
#elif defined(WIN32)
	#include <windows.h>
	#include <SDL.h>
	#include <SDL_syswm.h>
#elif defined(X11)
	#include <X11/Xlib.h>
	#include <SDL.h>
	#include <SDL_syswm.h>

void x11_SetDemandsAttention( bool v ) {
	SDL_SysWMinfo info;
	SDL_VERSION(&info.version);
	SDL_GetWMInfo(&info);

	info.info.x11.lock_func();

	// they will stay always the same as long as X11 is running
	static Atom demandsAttention = XInternAtom(info.info.x11.display, "_NET_WM_STATE_DEMANDS_ATTENTION", true);
	static Atom wmState = XInternAtom(info.info.x11.display, "_NET_WM_STATE", true);

	XEvent e;
	e.xclient.type = ClientMessage;
	e.xclient.message_type = wmState;
	e.xclient.display = info.info.x11.display;
	e.xclient.window = info.info.x11.wmwindow;
	e.xclient.format = 32;
	e.xclient.data.l[0] = v ? 1 : 0;
	e.xclient.data.l[1] = demandsAttention;
	e.xclient.data.l[2] = 0l;
	e.xclient.data.l[3] = 0l;
	e.xclient.data.l[4] = 0l;

	// This code is not needed - XSendEvent is enough, window manager will change window property by itself
	/*
	if( v ) // Add the property (actually it will replace WM_STATE, clearing MODAL, MAXIMIZED etc flags).
		XChangeProperty(info.info.x11.display, info.info.x11.wmwindow, wmState, XA_ATOM, 32, PropModeReplace, (unsigned char *)&demandsAttention, 1);
	else	// Clean the property
		XChangeProperty(info.info.x11.display, info.info.x11.wmwindow, wmState, XA_ATOM, 32, PropModeReplace, (unsigned char *)&demandsAttention, 0);
	*/

	XSendEvent(info.info.x11.display, DefaultRootWindow(info.info.x11.display), False, (SubstructureRedirectMask | SubstructureNotifyMask), &e);

	info.info.x11.unlock_func();
}

#endif

#include <iostream>

#include "InputEvents.h"
#include "Sounds.h"

using namespace std;

// HINT: I don't include LieroX.h directly as it declares Rect<>, which is already declared by Carbon
extern bool bDedicated;

// Make the sound, and blink the game window (platform-dependent)
void NotifyUserOnEvent()
{
	if( bDedicated || ApplicationHasFocus() )
		return;

	cout << "Notifying busy user" << endl;

	PlaySoundSample(sfxGeneral.smpNotify);

#if defined(__APPLE__)

	NMRecPtr	notePtr;
	OSErr		err;
	notePtr = (NMRecPtr) NewPtr ( sizeof ( NMRec ) );

	notePtr->qType = nmType; // standard queue type for NM
	notePtr->nmMark = 1;
	notePtr->nmIcon = NULL;
	notePtr->nmSound = NULL;  //(Handle) -1L; // use system alert snd
	notePtr->nmStr = NULL; // (StringPtr) NewPtr ( sizeof ( Str255 ) ); BlockMoveData( notice, notePtr->nmStr, notice[0] + 1 );
	notePtr->nmResp = NULL; // NewNMProc( MyResponse );
	notePtr->nmRefCon = 0; // fFatal;

	err = NMInstall( notePtr );

#elif defined(WIN32)

	SDL_SysWMinfo info;
	SDL_VERSION(&info.version);
	if( SDL_GetWMInfo(&info) != 1 )
		return;

	FLASHWINFO flash;
	flash.cbSize = sizeof(flash);
	flash.hwnd = info.window;
	flash.dwFlags = FLASHW_ALL;
	flash.uCount = 3;
	flash.dwTimeout = 0;
	FlashWindowEx( &flash );

#elif defined(X11)

	x11_SetDemandsAttention(true);

#else

	cout << "WARNING: NotifyUserOnEvent(): cannot notify windowmanager, unsupported system" << endl;

#endif

}

void ClearUserNotify() {
	if(bDedicated) return;
#if defined(__APPLE__)
#elif defined(WIN32)
#elif defined(X11)
	x11_SetDemandsAttention(false);
#endif
}

#endif
<commit_msg>another fix to notifyuser<commit_after>/*
 *  NotifyUser.cpp
 *  OpenLieroX
 *
 *  Created by Albert Zeyer on 25.09.08.
 *  code under LGPL
 *
 */

#include "NotifyUser.h"

#ifdef DEDICATED_ONLY

void NotifyUserOnEvent() {}
void ClearUserNotify() {}

#else

#if defined(__APPLE__)
	#include <Carbon/Carbon.h>
#elif defined(WIN32)
	#include <windows.h>
	#include <SDL.h>
	#include <SDL_syswm.h>
#elif defined(X11)
	#include <X11/Xlib.h>
	#include <SDL.h>
	#include <SDL_syswm.h>

void x11_SetDemandsAttention( bool v ) {
	SDL_SysWMinfo info;
	SDL_VERSION(&info.version);
	SDL_GetWMInfo(&info);

	info.info.x11.lock_func();

	// they will stay always the same as long as X11 is running
	static Atom demandsAttention = XInternAtom(info.info.x11.display, "_NET_WM_STATE_DEMANDS_ATTENTION", true);
	static Atom wmState = XInternAtom(info.info.x11.display, "_NET_WM_STATE", true);

	XEvent e;
	e.xclient.type = ClientMessage;
	e.xclient.message_type = wmState;
	e.xclient.display = info.info.x11.display;
	e.xclient.window = info.info.x11.wmwindow;
	e.xclient.format = 32;
	e.xclient.data.l[0] = v ? 1 : 0;
	e.xclient.data.l[1] = demandsAttention;
	e.xclient.data.l[2] = 0l;
	e.xclient.data.l[3] = 0l;
	e.xclient.data.l[4] = 0l;

	if( v ) // ensure that the property is there (that is not guaranteed on all systems)
		XChangeProperty(info.info.x11.display, info.info.x11.wmwindow, wmState, XA_ATOM, 32, PropModeReplace, (unsigned char *)&demandsAttention, 1);

	XSendEvent(info.info.x11.display, DefaultRootWindow(info.info.x11.display), False, (SubstructureRedirectMask | SubstructureNotifyMask), &e);

	info.info.x11.unlock_func();
}

#endif

#include <iostream>

#include "InputEvents.h"
#include "Sounds.h"

using namespace std;

// HINT: I don't include LieroX.h directly as it declares Rect<>, which is already declared by Carbon
extern bool bDedicated;

// Make the sound, and blink the game window (platform-dependent)
void NotifyUserOnEvent()
{
	if( bDedicated || ApplicationHasFocus() )
		return;

	cout << "Notifying busy user" << endl;

	PlaySoundSample(sfxGeneral.smpNotify);

#if defined(__APPLE__)

	NMRecPtr	notePtr;
	OSErr		err;
	notePtr = (NMRecPtr) NewPtr ( sizeof ( NMRec ) );

	notePtr->qType = nmType; // standard queue type for NM
	notePtr->nmMark = 1;
	notePtr->nmIcon = NULL;
	notePtr->nmSound = NULL;  //(Handle) -1L; // use system alert snd
	notePtr->nmStr = NULL; // (StringPtr) NewPtr ( sizeof ( Str255 ) ); BlockMoveData( notice, notePtr->nmStr, notice[0] + 1 );
	notePtr->nmResp = NULL; // NewNMProc( MyResponse );
	notePtr->nmRefCon = 0; // fFatal;

	err = NMInstall( notePtr );

#elif defined(WIN32)

	SDL_SysWMinfo info;
	SDL_VERSION(&info.version);
	if( SDL_GetWMInfo(&info) != 1 )
		return;

	FLASHWINFO flash;
	flash.cbSize = sizeof(flash);
	flash.hwnd = info.window;
	flash.dwFlags = FLASHW_ALL;
	flash.uCount = 3;
	flash.dwTimeout = 0;
	FlashWindowEx( &flash );

#elif defined(X11)

	x11_SetDemandsAttention(true);

#else

	cout << "WARNING: NotifyUserOnEvent(): cannot notify windowmanager, unsupported system" << endl;

#endif

}

void ClearUserNotify() {
	if(bDedicated) return;
#if defined(__APPLE__)
#elif defined(WIN32)
#elif defined(X11)
	x11_SetDemandsAttention(false);
#endif
}

#endif
<|endoftext|>


<commit_before>// formatxx - C++ string formatting library.
//
// This is free and unencumbered software released into the public domain.
//
// Anyone is free to copy, modify, publish, use, compile, sell, or
// distribute this software, either in source code form or as a compiled
// binary, for any purpose, commercial or non - commercial, and by any
// means.
//
// In jurisdictions that recognize copyright laws, the author or authors
// of this software dedicate any and all copyright interest in the
// software to the public domain. We make this dedication for the benefit
// of the public at large and to the detriment of our heirs and
// successors. We intend this dedication to be an overt act of
// relinquishment in perpetuity of all present and future rights to this
// software under copyright law.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
// For more information, please refer to <http://unlicense.org/>
//
// Authors:
//   Sean Middleditch <sean@middleditch.us>

#include <formatxx/format.h>
#include <formatxx/wide.h>

#include <formatxx/_detail/format_traits.h>
#include <formatxx/_detail/parse_unsigned.h>
#include <formatxx/_detail/parse_format.h>
#include <formatxx/_detail/write_integer.h>
#include <formatxx/_detail/format_impl.h>
#include <formatxx/_detail/printf_impl.h>

#include <cwchar>
#include <cstdlib>

namespace formatxx {

#pragma warning(push)
#pragma warning(disable: 4996)

FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, char ch, wstring_view)
{
	std::mbstate_t state;
	wchar_t wc;
	std::size_t const rs = std::mbrtowc(&wc, &ch, 1, &state);
	if (rs > 0 && rs < static_cast<std::size_t>(-2))
	{
		out.write({&wc, 1});
	}
}

FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, char* zstr, wstring_view spec)
{
	format_value(out, const_cast<char const*>(zstr), spec);
}

FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, char const* zstr, wstring_view)
{
	if (zstr != nullptr)
	{
		std::mbstate_t state;
		while (*zstr != '\0')
		{
			wchar_t wc;
			std::size_t const rs = std::mbrtowc(&wc, zstr++, 1, &state);
			if (rs != static_cast<std::size_t>(-2))
			{
				out.write({&wc, 1});
			}
		}
	}
}

FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, string_view str, wstring_view)
{
	std::mbstate_t state;
	for (auto const ch : str)
	{
		wchar_t wc;
		std::size_t const rs = std::mbrtowc(&wc, &ch, 1, &state);
		if (rs != static_cast<std::size_t>(-2))
		{
			out.write({&wc, 1});
		}
	}
}

FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, wchar_t ch, wstring_view)
{
	out.write(wstring_view(&ch, 1));
}

FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, wchar_t* zstr, wstring_view spec)
{
	format_value(out, wstring_view(zstr), spec);
}

FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, wchar_t const* zstr, wstring_view spec)
{
	format_value(out, wstring_view(zstr), spec);
}

FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, wstring_view str, wstring_view)
{
	out.write(str);
}

FORMATXX_PUBLIC void FORMATXX_API format_value(format_writer& out, wchar_t ch, string_view)
{
	std::mbstate_t state;
	char mb[MB_LEN_MAX];
	std::size_t const rs = std::wcrtomb(mb, ch, &state);
	out.write({mb, rs});
}

FORMATXX_PUBLIC void FORMATXX_API format_value(format_writer& out, wchar_t* zstr, string_view spec)
{
	format_value(out, const_cast<wchar_t const*>(zstr), spec);
}

FORMATXX_PUBLIC void FORMATXX_API format_value(format_writer& out, wchar_t const* zstr, string_view)
{
	if (zstr != nullptr)
	{
		std::mbstate_t state;
		char mb[MB_LEN_MAX];
		while (*zstr != '\0')
		{
			std::size_t const rs = std::wcrtomb(mb, *zstr++, &state);
			out.write({mb, rs});
		}
	}
}

FORMATXX_PUBLIC void FORMATXX_API format_value(format_writer& out, wstring_view str, string_view)
{
	std::mbstate_t state;
	char mb[MB_LEN_MAX];
	for (auto const ch : str)
	{
		std::size_t const rs = std::wcrtomb(mb, ch, &state);
		out.write({mb, rs});
	}
}

FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, bool value, wstring_view spec)
{
	format_value(out, value ? _detail::FormatTraits<wchar_t>::sTrue : _detail::FormatTraits<wchar_t>::sFalse, spec);
}

#pragma warning(pop)

FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, signed int value, wstring_view spec) { _detail::write_integer(out, value, spec); }
FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, signed char value, wstring_view spec) { _detail::write_integer(out, value, spec); }
FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, signed long value, wstring_view spec) { _detail::write_integer(out, value, spec); }
FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, signed short value, wstring_view spec) { _detail::write_integer(out, value, spec); }
FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, signed long long value, wstring_view spec) { _detail::write_integer(out, value, spec); }

FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, unsigned int value, wstring_view spec) { _detail::write_integer(out, value, spec); }
FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, unsigned char value, wstring_view spec) { _detail::write_integer(out, value, spec); }
FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, unsigned long value, wstring_view spec) { _detail::write_integer(out, value, spec); }
FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, unsigned short value, wstring_view spec) { _detail::write_integer(out, value, spec); }
FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, unsigned long long value, wstring_view spec) { _detail::write_integer(out, value, spec); }

FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, float value, wstring_view spec)
{
	format_value(out, static_cast<double>(value), spec);
}

FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, double value, wstring_view spec_string)
{
	wchar_t fmt[3] = L"%f";

	wformat_spec const spec = parse_format_spec(spec_string);

	switch (spec.code)
	{
	case L'a':
	case L'A':
	case L'e':
	case L'E':
	case L'f':
	case L'F':
	case L'g':
	case L'G':
		fmt[1] = spec.code;
		break;
	default:
		// leave default
		break;
	}

	constexpr std::size_t buf_size = 1024;
	wchar_t buf[buf_size]; // not actually enough for every float, but...
	int const len = std::swprintf(buf, buf_size, fmt, value);
	if (len > 0)
		out.write({buf, std::size_t(len)});
}

namespace _detail {

template basic_format_writer<wchar_t>& FORMATXX_API format_impl(basic_format_writer<wchar_t>& out, basic_string_view<wchar_t> format, std::size_t count, BasicFormatterThunk<wchar_t> const* funcs, FormatterParameter const* values);

template basic_format_writer<wchar_t>& FORMATXX_API printf_impl(basic_format_writer<wchar_t>& out, basic_string_view<wchar_t> format, std::size_t count, BasicFormatterThunk<wchar_t> const* funcs, FormatterParameter const* values);

} // namespace _detail

template basic_format_spec<wchar_t> FORMATXX_API parse_format_spec(basic_string_view<wchar_t>);

} // namespace formatxx<commit_msg>MB_LEN_MAX is in climits.<commit_after>// formatxx - C++ string formatting library.
//
// This is free and unencumbered software released into the public domain.
//
// Anyone is free to copy, modify, publish, use, compile, sell, or
// distribute this software, either in source code form or as a compiled
// binary, for any purpose, commercial or non - commercial, and by any
// means.
//
// In jurisdictions that recognize copyright laws, the author or authors
// of this software dedicate any and all copyright interest in the
// software to the public domain. We make this dedication for the benefit
// of the public at large and to the detriment of our heirs and
// successors. We intend this dedication to be an overt act of
// relinquishment in perpetuity of all present and future rights to this
// software under copyright law.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
// For more information, please refer to <http://unlicense.org/>
//
// Authors:
//   Sean Middleditch <sean@middleditch.us>

#include <formatxx/format.h>
#include <formatxx/wide.h>

#include <formatxx/_detail/format_traits.h>
#include <formatxx/_detail/parse_unsigned.h>
#include <formatxx/_detail/parse_format.h>
#include <formatxx/_detail/write_integer.h>
#include <formatxx/_detail/format_impl.h>
#include <formatxx/_detail/printf_impl.h>

#include <cwchar>
#include <cstdlib>
#include <climits>

namespace formatxx {

#pragma warning(push)
#pragma warning(disable: 4996)

FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, char ch, wstring_view)
{
	std::mbstate_t state;
	wchar_t wc;
	std::size_t const rs = std::mbrtowc(&wc, &ch, 1, &state);
	if (rs > 0 && rs < static_cast<std::size_t>(-2))
	{
		out.write({&wc, 1});
	}
}

FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, char* zstr, wstring_view spec)
{
	format_value(out, const_cast<char const*>(zstr), spec);
}

FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, char const* zstr, wstring_view)
{
	if (zstr != nullptr)
	{
		std::mbstate_t state;
		while (*zstr != '\0')
		{
			wchar_t wc;
			std::size_t const rs = std::mbrtowc(&wc, zstr++, 1, &state);
			if (rs != static_cast<std::size_t>(-2))
			{
				out.write({&wc, 1});
			}
		}
	}
}

FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, string_view str, wstring_view)
{
	std::mbstate_t state;
	for (auto const ch : str)
	{
		wchar_t wc;
		std::size_t const rs = std::mbrtowc(&wc, &ch, 1, &state);
		if (rs != static_cast<std::size_t>(-2))
		{
			out.write({&wc, 1});
		}
	}
}

FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, wchar_t ch, wstring_view)
{
	out.write(wstring_view(&ch, 1));
}

FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, wchar_t* zstr, wstring_view spec)
{
	format_value(out, wstring_view(zstr), spec);
}

FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, wchar_t const* zstr, wstring_view spec)
{
	format_value(out, wstring_view(zstr), spec);
}

FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, wstring_view str, wstring_view)
{
	out.write(str);
}

FORMATXX_PUBLIC void FORMATXX_API format_value(format_writer& out, wchar_t ch, string_view)
{
	std::mbstate_t state;
	char mb[MB_LEN_MAX];
	std::size_t const rs = std::wcrtomb(mb, ch, &state);
	out.write({mb, rs});
}

FORMATXX_PUBLIC void FORMATXX_API format_value(format_writer& out, wchar_t* zstr, string_view spec)
{
	format_value(out, const_cast<wchar_t const*>(zstr), spec);
}

FORMATXX_PUBLIC void FORMATXX_API format_value(format_writer& out, wchar_t const* zstr, string_view)
{
	if (zstr != nullptr)
	{
		std::mbstate_t state;
		char mb[MB_LEN_MAX];
		while (*zstr != '\0')
		{
			std::size_t const rs = std::wcrtomb(mb, *zstr++, &state);
			out.write({mb, rs});
		}
	}
}

FORMATXX_PUBLIC void FORMATXX_API format_value(format_writer& out, wstring_view str, string_view)
{
	std::mbstate_t state;
	char mb[MB_LEN_MAX];
	for (auto const ch : str)
	{
		std::size_t const rs = std::wcrtomb(mb, ch, &state);
		out.write({mb, rs});
	}
}

FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, bool value, wstring_view spec)
{
	format_value(out, value ? _detail::FormatTraits<wchar_t>::sTrue : _detail::FormatTraits<wchar_t>::sFalse, spec);
}

#pragma warning(pop)

FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, signed int value, wstring_view spec) { _detail::write_integer(out, value, spec); }
FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, signed char value, wstring_view spec) { _detail::write_integer(out, value, spec); }
FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, signed long value, wstring_view spec) { _detail::write_integer(out, value, spec); }
FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, signed short value, wstring_view spec) { _detail::write_integer(out, value, spec); }
FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, signed long long value, wstring_view spec) { _detail::write_integer(out, value, spec); }

FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, unsigned int value, wstring_view spec) { _detail::write_integer(out, value, spec); }
FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, unsigned char value, wstring_view spec) { _detail::write_integer(out, value, spec); }
FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, unsigned long value, wstring_view spec) { _detail::write_integer(out, value, spec); }
FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, unsigned short value, wstring_view spec) { _detail::write_integer(out, value, spec); }
FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, unsigned long long value, wstring_view spec) { _detail::write_integer(out, value, spec); }

FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, float value, wstring_view spec)
{
	format_value(out, static_cast<double>(value), spec);
}

FORMATXX_PUBLIC void FORMATXX_API format_value(wformat_writer& out, double value, wstring_view spec_string)
{
	wchar_t fmt[3] = L"%f";

	wformat_spec const spec = parse_format_spec(spec_string);

	switch (spec.code)
	{
	case L'a':
	case L'A':
	case L'e':
	case L'E':
	case L'f':
	case L'F':
	case L'g':
	case L'G':
		fmt[1] = spec.code;
		break;
	default:
		// leave default
		break;
	}

	constexpr std::size_t buf_size = 1024;
	wchar_t buf[buf_size]; // not actually enough for every float, but...
	int const len = std::swprintf(buf, buf_size, fmt, value);
	if (len > 0)
		out.write({buf, std::size_t(len)});
}

namespace _detail {

template basic_format_writer<wchar_t>& FORMATXX_API format_impl(basic_format_writer<wchar_t>& out, basic_string_view<wchar_t> format, std::size_t count, BasicFormatterThunk<wchar_t> const* funcs, FormatterParameter const* values);

template basic_format_writer<wchar_t>& FORMATXX_API printf_impl(basic_format_writer<wchar_t>& out, basic_string_view<wchar_t> format, std::size_t count, BasicFormatterThunk<wchar_t> const* funcs, FormatterParameter const* values);

} // namespace _detail

template basic_format_spec<wchar_t> FORMATXX_API parse_format_spec(basic_string_view<wchar_t>);

} // namespace formatxx<|endoftext|>


<commit_before>/**
 * Copyright (c) Sjors Gielen, 2010
 * See LICENSE for license.
 */

#include "database.h"
#include "config.h"
#include <QtCore/QVariant>
#include <QtCore/QDebug>
#include <mongo.h>
#include <cerrno>

// #define DEBUG

#define M (mongo_sync_connection*)m_

/**
 * @brief Constructor.
 */
Database::Database( const std::string &hostname, uint16_t port, const std::string &database, const std::string &username, const std::string &password )
: m_(0)
{
	hostName_ = hostname;
	port_ = port;
	databaseName_ = database;
	username_ = username;
	password_ = password;
}

/**
 * @brief Destructor.
 */
Database::~Database()
{
}

/**
 * @brief Returns the last error in the QSqlDatabase object.
 */
std::string Database::lastError() const
{
	return lastError_;
}

bool Database::open()
{
	m_ = (void*)mongo_sync_connect(hostName_.c_str(), port_, TRUE);
	if(!m_) {
		lastError_ = strerror(errno);
		return false;
	}
	if(!mongo_sync_conn_set_auto_reconnect(M, TRUE)) {
		lastError_ = strerror(errno);
		mongo_sync_disconnect(M);
		return false;
	}
#warning TODO: db.properties.ensureIndex({'network':1,'receiver':1,'sender':1})
	return true;
}

/**
 * @brief Retrieve all properties under a certain namespace.
 *
 * All properties whose names start with the given namespace name, then a
 * single dot, and that match the given scope values, are returned from this
 * method.
 *
 * This method guarantees that if it returns a certain key, property() will
 * return the correct value of that key given that network, receiver and
 * sender scope are the same.
 */
QStringList Database::propertyKeys( const QString &ns, const QString &networkScope,
 const QString &receiverScope, const QString &senderScope )
{
  checkDatabaseConnection();

  QString nsQuery = ns + ".%";
  QSqlQuery data(db_);
  data.prepare(QLatin1String("SELECT variable,network,receiver,sender"
    " FROM properties WHERE variable LIKE ?"));
  data.addBindValue(nsQuery);

  QStringList k;
  if( !data.exec() )
  {
    qWarning() << "Property retrieve keys failed: " << data.lastError();
    return k;
  }

  // index the results
  while( data.next() )
  {
    // Check if the name really matches
    QString actualName = data.value(0).toString();
    if( !actualName.startsWith(ns + '.') )
       continue;
    actualName = actualName.mid(ns.length() + 1);

    if( data.value(3).isNull() )
    {
      if( data.value(2).isNull() )
      {
        if( data.value(1).isNull() )
          k.append(actualName);
        else if( data.value(1).toString() == networkScope )
          k.append(actualName);
      }
      else if( data.value(1).toString() == networkScope
            && data.value(2).toString() == receiverScope )
        k.append(actualName);
    }
    else if( data.value(1).toString() == networkScope
          && data.value(2).toString() == receiverScope
          && data.value(3).toString() == senderScope )
      k.append(actualName);
  }

  return k;
}

/**
 * @brief Retrieve property from database.
 *
 * The most specific scope will be selected first, i.e. user-specific scope.
 * If that yields no results, channel-specific scope will be returned, then
 * network-specific scope, then global scope.
 *
 * Variable should be formatted using reverse-domain format, i.e. for the
 * plugin MyFirstPlugin created by John Doe, to save a 'foo' variable one
 * could use:
 * net.jondoe.myfirstplugin.foo
 */
QVariant Database::property( const QString &variable,
 const QString &networkScope, const QString &receiverScope,
 const QString &senderScope )
{
  checkDatabaseConnection();

  // retrieve from database
  QSqlQuery data(db_);
  data.prepare(QLatin1String("SELECT value,network,receiver,sender"
     " FROM properties WHERE variable=?"));
  data.addBindValue(variable);
  if( !data.exec() )
  {
    qWarning() << "Property retrieve query failed: " << data.lastError();
    return QVariant();
  }

  // index the results
  QVariant global, network, receiver, sender;
  while( data.next() )
  {
    if( data.value(3).isNull() )
    {
      if( data.value(2).isNull() )
      {
        if( data.value(1).isNull() )
          global = data.value(0);
        else if( data.value(1).toString() == networkScope )
          network = data.value(0);
      }
      else if( data.value(1).toString() == networkScope
            && data.value(2).toString() == receiverScope )
        receiver = data.value(0);
    }
    else if( data.value(1).toString() == networkScope
          && data.value(2).toString() == receiverScope
          && data.value(3).toString() == senderScope )
      sender = data.value(0);
  }

#ifdef DEBUG
  qDebug() << "For variable " << variable;
  qDebug() << "Global: " << global;
  qDebug() << "Network: " << network;
  qDebug() << "Receiver: " << receiver;
  qDebug() << "Sender: " << sender;
#endif

  if( !sender.isNull() )
    return sender;
  if( !receiver.isNull() )
    return receiver;
  if( !network.isNull() )
    return network;
  return global;
}

void Database::setProperty( const QString &variable,
 const QVariant &value, const QString &networkScope,
 const QString &receiverScope, const QString &senderScope )
{
#ifdef DEBUG
  qDebug() << "Setting property " << variable << "to" << value;
#endif
  checkDatabaseConnection();

  // first, select it from the database, to see whether to update or insert
  // (not all database engines support "on duplicate key update".)
  QSqlQuery finder(db_);
  // because size() always returns -1 on an SQLite backend, we use COUNT.
  finder.prepare(
      QString(QLatin1String("SELECT id,COUNT(id) FROM properties WHERE "
                "variable=? AND network %1 AND receiver %2 AND sender %3"))
      .arg( QLatin1String(networkScope.isEmpty()  ? "IS NULL" : "=?") )
      .arg( QLatin1String(receiverScope.isEmpty() ? "IS NULL" : "=?") )
      .arg( QLatin1String(senderScope.isEmpty()   ? "IS NULL" : "=?") )
  );
  // This ugly hack seems necessary as MySQL does not allow =NULL, requires IS NULL.
  finder.addBindValue(variable);
  if( !networkScope.isEmpty() )
    finder.addBindValue(networkScope);
  if( !receiverScope.isEmpty() )
    finder.addBindValue(receiverScope);
  if( !senderScope.isEmpty() )
    finder.addBindValue(senderScope);

  if( !finder.exec() )
  {
    qWarning() << "Select property before setting failed: " << finder.lastError();
    return;
  }

  if( !finder.next() )
  {
    qWarning() << "Could not select first value row before setting: " << finder.lastError();
    return;
  }

  int resultSize = finder.value(1).isValid() ? finder.value(1).toInt() : 0;
  int returnedId = finder.value(0).isValid() ? finder.value(0).toInt() : -1;

  if( resultSize > 1 )
    qWarning() << "*** WARNING: More than one result to variable retrieve! This is a bug. ***";

  QSqlQuery data(db_);

  if( !resultSize )
  {
    // insert
    if( !value.isValid() )
    {
      // Don't insert null values.
      return;
    }
#ifdef DEBUG
    qDebug() << "Seeing property " << variable << "for the first time, inserting.";
    qDebug() << finder.executedQuery();
    QList<QVariant> list = finder.boundValues().values();
    for (int i = 0; i < list.size(); ++i)
      qDebug() << i << ": " << list.at(i).toString().toAscii().data() << endl;
#endif
    data.prepare(QLatin1String("INSERT INTO properties (variable,value,"
                "network,receiver,sender) VALUES (?, ?, ?, ?, ?)"));
    data.addBindValue(variable);
    data.addBindValue(value);
    data.addBindValue(networkScope.isEmpty()  ? QVariant() : networkScope);
    data.addBindValue(receiverScope.isEmpty() ? QVariant() : receiverScope);
    data.addBindValue(senderScope.isEmpty()   ? QVariant() : senderScope);
  }
  else
  {
    // update
    if( !value.isValid() )
    {
      // Don't insert null values - delete the old one
      data.prepare(QLatin1String("DELETE FROM properties WHERE id=?"));
    }
    else
    {
      // update the old one
      data.prepare(QLatin1String("UPDATE properties SET value=? WHERE id=?"));
      data.addBindValue(value);
    }
    data.addBindValue(returnedId);
  }

#ifdef DEBUG
  qDebug() << "Executing data query: " << data.lastQuery();
  qDebug() << "Bound data query values: " << data.boundValues();
#endif

  if( !data.exec() )
  {
    qWarning() << "Set property failed: " << data.lastError();
  }
}
<commit_msg>Implement variable querying<commit_after>/**
 * Copyright (c) Sjors Gielen, 2010
 * See LICENSE for license.
 */

#include "database.h"
#include "config.h"
#include <QtCore/QVariant>
#include <QtCore/QDebug>
#include <mongo.h>
#include <cerrno>
#include <cassert>

// #define DEBUG

#define M (mongo_sync_connection*)m_

/**
 * @brief Constructor.
 */
Database::Database( const std::string &hostname, uint16_t port, const std::string &database, const std::string &username, const std::string &password )
: m_(0)
{
	hostName_ = hostname;
	port_ = port;
	databaseName_ = database;
	username_ = username;
	password_ = password;
}

/**
 * @brief Destructor.
 */
Database::~Database()
{
}

/**
 * @brief Returns the last error in the QSqlDatabase object.
 */
std::string Database::lastError() const
{
	return lastError_;
}

bool Database::open()
{
	m_ = (void*)mongo_sync_connect(hostName_.c_str(), port_, TRUE);
	if(!m_) {
		lastError_ = strerror(errno);
		return false;
	}
	if(!mongo_sync_conn_set_auto_reconnect(M, TRUE)) {
		lastError_ = strerror(errno);
		mongo_sync_disconnect(M);
		return false;
	}
#warning TODO: db.properties.ensureIndex({'network':1,'receiver':1,'sender':1})
	return true;
}

/**
 * @brief Retrieve all properties under a certain namespace.
 *
 * All properties whose names start with the given namespace name, then a
 * single dot, and that match the given scope values, are returned from this
 * method.
 *
 * This method guarantees that if it returns a certain key, property() will
 * return the correct value of that key given that network, receiver and
 * sender scope are the same.
 */
QStringList Database::propertyKeys( const QString &ns, const QString &networkScope,
 const QString &receiverScope, const QString &senderScope )
{
  checkDatabaseConnection();

  QString nsQuery = ns + ".%";
  QSqlQuery data(db_);
  data.prepare(QLatin1String("SELECT variable,network,receiver,sender"
    " FROM properties WHERE variable LIKE ?"));
  data.addBindValue(nsQuery);

  QStringList k;
  if( !data.exec() )
  {
    qWarning() << "Property retrieve keys failed: " << data.lastError();
    return k;
  }

  // index the results
  while( data.next() )
  {
    // Check if the name really matches
    QString actualName = data.value(0).toString();
    if( !actualName.startsWith(ns + '.') )
       continue;
    actualName = actualName.mid(ns.length() + 1);

    if( data.value(3).isNull() )
    {
      if( data.value(2).isNull() )
      {
        if( data.value(1).isNull() )
          k.append(actualName);
        else if( data.value(1).toString() == networkScope )
          k.append(actualName);
      }
      else if( data.value(1).toString() == networkScope
            && data.value(2).toString() == receiverScope )
        k.append(actualName);
    }
    else if( data.value(1).toString() == networkScope
          && data.value(2).toString() == receiverScope
          && data.value(3).toString() == senderScope )
      k.append(actualName);
  }

  return k;
}

/**
 * @brief Retrieve property from database.
 *
 * The most specific scope will be selected first, i.e. user-specific scope.
 * If that yields no results, channel-specific scope will be returned, then
 * network-specific scope, then global scope.
 *
 * Variable should be formatted using reverse-domain format, i.e. for the
 * plugin MyFirstPlugin created by John Doe, to save a 'foo' variable one
 * could use:
 * net.jondoe.myfirstplugin.foo
 */
QVariant Database::property( const QString &variable,
 const QString &networkScope, const QString &receiverScope,
 const QString &senderScope )
{
	// variable, [networkScope, [receiverScope, [senderScope]]]
	// (empty if not given)

	// db.c.
	//   find() // for everything
	//   find({network:{$in: ['NETWORKNAME',null]}}) // for network scope
	//   find({network:{$in: ['NETWORKNAME',null]}, receiver:{$in: ['RECEIVER',null]}}) // for receiver scope
	//   find({network:..., receiver:..., sender:{$in: ['SENDER',null]}}) // for sender scope
	// .sort({'a':-1,'b':-1,'c':-1}).limit(1)
	// Reverse sort and limit(1) will make sure we only receive the most
	// specific result. This works, as long as the assumption is true that
	// no specific fields are set without their less specific fields also
	// being set (i.e. receiver can't be empty if sender is non-empty).

	bson *query = bson_build_full(
		BSON_TYPE_DOCUMENT, "$orderby", TRUE,
		bson_build(BSON_TYPE_INT32, "network", -1, BSON_TYPE_INT32, "receiver", -1, BSON_TYPE_INT32, "sender", -1, BSON_TYPE_NONE),
		BSON_TYPE_NONE
	);

	/*
		'$query':{
			'variable':'foo',
			'network':{'$in':['bla',null]},
			'receiver':{'$in':['moo', null]},
		}
	*/

	bson *selector = bson_new();
	bson *network = 0, *receiver = 0, *sender = 0;
	bson_append_string(selector, "variable", variable.toUtf8().constData(), -1);
	if(networkScope.length() > 0) {
		network = bson_build_full(
			BSON_TYPE_ARRAY, "$in", TRUE,
			bson_build(BSON_TYPE_STRING, "1", networkScope.toUtf8().constData(), -1,
			           BSON_TYPE_NULL, "2", BSON_TYPE_NONE),
			BSON_TYPE_NONE );
		bson_finish(network);
		bson_append_document(selector, "network", network);
		if(receiverScope.length() > 0) {
			receiver = bson_build_full(
				BSON_TYPE_ARRAY, "$in", TRUE,
				bson_build(BSON_TYPE_STRING, "1", receiverScope.toUtf8().constData(), -1,
				           BSON_TYPE_NULL, "2", BSON_TYPE_NONE),
				BSON_TYPE_NONE );
			bson_finish(receiver);
			bson_append_document(selector, "receiver", receiver);
			if(senderScope.length() > 0) {
				sender = bson_build_full(
					BSON_TYPE_ARRAY, "$in", TRUE,
					bson_build(BSON_TYPE_STRING, "1", senderScope.toUtf8().constData(), -1,
						   BSON_TYPE_NULL, "2", BSON_TYPE_NONE),
					BSON_TYPE_NONE );
				bson_finish(sender);
				bson_append_document(selector, "sender", sender);
			}
		}
	}
	bson_finish(selector);
	bson_append_document(query, "$query", selector);
	bson_finish(query);

	mongo_packet *p = mongo_sync_cmd_query(M, std::string(databaseName_ + ".properties").c_str(), 0, 0, 1, query, NULL /* TODO: value only? */);

	bson_free(query);
	bson_free(selector);
	if(network) bson_free(network);
	if(receiver) bson_free(receiver);
	if(sender) bson_free(sender);

	if(!p) {
		lastError_ = strerror(errno);
		return QVariant();
	}

	mongo_sync_cursor *cursor = mongo_sync_cursor_new(M, std::string(databaseName_ + ".properties").c_str(), p);
	if(!cursor) {
		lastError_ = strerror(errno);
		return QVariant();
	}

	if(!mongo_sync_cursor_next(cursor)) {
#ifdef DEBUG
		fprintf(stderr, "Variable %s not found within given scope.\n", variable.toUtf8().constData());
#endif
	}

	bson *result = mongo_sync_cursor_get_data(cursor);
	if(!result) {
		lastError_ = strerror(errno);
		mongo_sync_cursor_free(cursor);
		return QVariant();
	}

	bson_cursor *c = bson_find(result, "value");
	const char *value;
	if(!bson_cursor_get_string(c, &value)) {
		lastError_ = strerror(errno);
		mongo_sync_cursor_free(cursor);
		bson_cursor_free(c);
		return QVariant();
	}

	bson_free(result);
	bson_cursor_free(c);

	// only one result
	assert(!mongo_sync_cursor_next(cursor));

	mongo_sync_cursor_free(cursor);
	return QVariant(value);
}

void Database::setProperty( const QString &variable,
 const QVariant &value, const QString &networkScope,
 const QString &receiverScope, const QString &senderScope )
{
#ifdef DEBUG
  qDebug() << "Setting property " << variable << "to" << value;
#endif
  checkDatabaseConnection();

  // first, select it from the database, to see whether to update or insert
  // (not all database engines support "on duplicate key update".)
  QSqlQuery finder(db_);
  // because size() always returns -1 on an SQLite backend, we use COUNT.
  finder.prepare(
      QString(QLatin1String("SELECT id,COUNT(id) FROM properties WHERE "
                "variable=? AND network %1 AND receiver %2 AND sender %3"))
      .arg( QLatin1String(networkScope.isEmpty()  ? "IS NULL" : "=?") )
      .arg( QLatin1String(receiverScope.isEmpty() ? "IS NULL" : "=?") )
      .arg( QLatin1String(senderScope.isEmpty()   ? "IS NULL" : "=?") )
  );
  // This ugly hack seems necessary as MySQL does not allow =NULL, requires IS NULL.
  finder.addBindValue(variable);
  if( !networkScope.isEmpty() )
    finder.addBindValue(networkScope);
  if( !receiverScope.isEmpty() )
    finder.addBindValue(receiverScope);
  if( !senderScope.isEmpty() )
    finder.addBindValue(senderScope);

  if( !finder.exec() )
  {
    qWarning() << "Select property before setting failed: " << finder.lastError();
    return;
  }

  if( !finder.next() )
  {
    qWarning() << "Could not select first value row before setting: " << finder.lastError();
    return;
  }

  int resultSize = finder.value(1).isValid() ? finder.value(1).toInt() : 0;
  int returnedId = finder.value(0).isValid() ? finder.value(0).toInt() : -1;

  if( resultSize > 1 )
    qWarning() << "*** WARNING: More than one result to variable retrieve! This is a bug. ***";

  QSqlQuery data(db_);

  if( !resultSize )
  {
    // insert
    if( !value.isValid() )
    {
      // Don't insert null values.
      return;
    }
#ifdef DEBUG
    qDebug() << "Seeing property " << variable << "for the first time, inserting.";
    qDebug() << finder.executedQuery();
    QList<QVariant> list = finder.boundValues().values();
    for (int i = 0; i < list.size(); ++i)
      qDebug() << i << ": " << list.at(i).toString().toAscii().data() << endl;
#endif
    data.prepare(QLatin1String("INSERT INTO properties (variable,value,"
                "network,receiver,sender) VALUES (?, ?, ?, ?, ?)"));
    data.addBindValue(variable);
    data.addBindValue(value);
    data.addBindValue(networkScope.isEmpty()  ? QVariant() : networkScope);
    data.addBindValue(receiverScope.isEmpty() ? QVariant() : receiverScope);
    data.addBindValue(senderScope.isEmpty()   ? QVariant() : senderScope);
  }
  else
  {
    // update
    if( !value.isValid() )
    {
      // Don't insert null values - delete the old one
      data.prepare(QLatin1String("DELETE FROM properties WHERE id=?"));
    }
    else
    {
      // update the old one
      data.prepare(QLatin1String("UPDATE properties SET value=? WHERE id=?"));
      data.addBindValue(value);
    }
    data.addBindValue(returnedId);
  }

#ifdef DEBUG
  qDebug() << "Executing data query: " << data.lastQuery();
  qDebug() << "Bound data query values: " << data.boundValues();
#endif

  if( !data.exec() )
  {
    qWarning() << "Set property failed: " << data.lastError();
  }
}
<|endoftext|>


<commit_before>/* -*- coding: utf-8 -*-
*   Copyright (c) 2010, Tim Kleinschmit.  This file is
*   licensed under the General Public License version 3 or later.
*   See the COPYRIGHT file.
*/

#include "database.h"

bool Database::openDB () {
// bracket are for the correct way to work with databases
  {
    // Find QSLite driver
    QSqlDatabase db( QSqlDatabase::addDatabase( "QSQLITE", "db" ));

    if( QFile::exists ( DB_PATH ))
	return true;
    else
	db.setDatabaseName( DB_PATH );

    if( db.open ()) {
	QSqlQuery query( db );
        if ( !query.exec( "CREATE TABLE IF NOT EXISTS searchWords (id INTEGER PRIMARY KEY, "
	                                      "searchWord VARCHAR(20) NOT NULL,"
                                              "numberOfUsed INTEGER NOT NULL DEFAULT 1)" ))
            qWarning()<< QObject::tr( "Database Error: " ) + query.lastError ().text ();
        if ( !query.exec("CREATE UNIQUE INDEX word_idx ON searchWords( searchWord )" ))
            qWarning()<< QObject::tr( "Database Error: " ) + query.lastError ().text ();
    }
    else {
        qDebug() << db.lastError();
        qFatal( DB_NOT_OPEN );
        return false;
    }
    db.close ();
  }

    QSqlDatabase::removeDatabase ( "db" );
    return true;
}

bool Database::deleteDB () {
    return QFile::remove ( DB_PATH );
}

bool Database::setSearchWord( QString word = "" ) {
// bracket are for the correct way to work with databases
  {
    QSqlDatabase db( QSqlDatabase::addDatabase( "QSQLITE", "db" ));
    db.setDatabaseName ( DB_PATH );

    if( db.open ()) {
	QSqlQuery query( db );
            query.prepare ( "INSERT INTO searchWords ( searchWord ) VALUES ( :w )" );
            query.bindValue ( ":w", word, QSql::InOut );
            if ( !query.exec ())
                qWarning()<< QObject::tr( "Database Error: " ) + query.lastError ().text ();
    }
    else {
        qDebug() << db.lastError();
        qFatal( DB_NOT_OPEN );
	return false;
    }

    db.close ();
  }
    QSqlDatabase::removeDatabase ( "db" );
    return true;
}

<commit_msg>better code<commit_after>/* -*- coding: utf-8 -*-
*   Copyright (c) 2010, Tim Kleinschmit.  This file is
*   licensed under the General Public License version 3 or later.
*   See the COPYRIGHT file.
*/

#include "database.h"

bool Database::openDB () {
// bracket are for the correct way to work with databases
  {
    // Find QSLite driver
    QSqlDatabase db( QSqlDatabase::addDatabase( "QSQLITE", "db" ));

    if( !QFile::exists ( DB_PATH ))
	db.setDatabaseName( DB_PATH );

    if( db.open ()) {
	QSqlQuery query( db );
        if ( !query.exec( "CREATE TABLE IF NOT EXISTS searchWords (id INTEGER PRIMARY KEY, "
	                                      "searchWord VARCHAR(20) NOT NULL,"
                                              "numberOfUsed INTEGER NOT NULL DEFAULT 1)" ))
            qWarning()<< QObject::tr( "Database Error: " ) + query.lastError ().text ();
        if ( !query.exec("CREATE UNIQUE INDEX word_idx ON searchWords( searchWord )" ))
            qWarning()<< QObject::tr( "Database Error: " ) + query.lastError ().text ();
    }
    else {
        qDebug() << db.lastError();
        qFatal( DB_NOT_OPEN );
        return false;
    }
    db.close ();
  }

    QSqlDatabase::removeDatabase ( "db" );
    return true;
}

bool Database::deleteDB () {
    return QFile::remove ( DB_PATH );
}

bool Database::setSearchWord( QString word = "" ) {
// bracket are for the correct way to work with databases
  {
    QSqlDatabase db( QSqlDatabase::addDatabase( "QSQLITE", "db" ));
    db.setDatabaseName ( DB_PATH );

    if( db.open ()) {
	QSqlQuery query( db );
            query.prepare ( "INSERT INTO searchWords ( searchWord ) VALUES ( :w )" );
            query.bindValue ( ":w", word, QSql::InOut );
            if ( !query.exec ())
                qWarning()<< QObject::tr( "Database Error: " ) + query.lastError ().text ();
    }
    else {
        qDebug() << db.lastError();
        qFatal( DB_NOT_OPEN );
	return false;
    }

    db.close ();
  }
    QSqlDatabase::removeDatabase ( "db" );
    return true;
}

<|endoftext|>


<commit_before>#include "dbg_path.h"
#include <deque>
#include <algorithm>

namespace vscode
{
	fs::path path_uncomplete(const fs::path& path, const fs::path& base, std::error_code& ec)
	{
		fs::path npath = path_normalize(path);
		fs::path nbase = path_normalize(base);
		if (npath == nbase)
			return L"./";
		fs::path from_path, from_base, output;
		fs::path::iterator path_it = npath.begin(), path_end = npath.end();
		fs::path::iterator base_it = nbase.begin(), base_end = nbase.end();

		if ((path_it == path_end) || (base_it == base_end))
		{
			ec = std::make_error_code(std::errc::not_a_directory);
			return npath;
		}

#ifdef WIN32
		if (*path_it != *base_it)
			return npath;
		++path_it, ++base_it;
#endif

		while (true) {
			if ((path_it == path_end) || (base_it == base_end) || (*path_it != *base_it)) {
				for (; base_it != base_end; ++base_it) {
					if (*base_it == L".")
						continue;
					else if (*base_it == L"/")
						continue;

					output /= L"../";
				}
				fs::path::iterator path_it_start = path_it;
				for (; path_it != path_end; ++path_it) {

					if (path_it != path_it_start)
						output /= L"/";

					if (*path_it == L".")
						continue;
					if (*path_it == L"/")
						continue;

					output /= *path_it;
				}

				break;
			}
			from_path /= fs::path(*path_it);
			from_base /= fs::path(*base_it);
			++path_it, ++base_it;
		}

		return output;
	}

	fs::path path_normalize(const fs::path& p)
	{
		fs::path result = p.root_path();
		std::deque<std::wstring> stack;
		for (auto e : p.relative_path()) {
			if (e == L".." && !stack.empty() && stack.back() != L"..") {
				stack.pop_back();
			}
			else if (e != L".") {
#if _MSC_VER >= 1900
				stack.push_back(e.wstring());
#else
				stack.push_back(e);
#endif
			}
		}
		for (auto e : stack) {
			result /= e;
		}
		std::wstring ret = result.wstring();
		std::wstring tmp;
		tmp.resize(ret.size());
		std::transform(ret.begin(), ret.end(), tmp.begin(), towlower);
		return tmp;
	}

	bool path_is_subpath(const fs::path& path, const fs::path& base)
	{
		fs::path npath = path_normalize(path);
		fs::path::iterator path_it = npath.begin(), path_end = npath.end();
		fs::path::iterator base_it = base.begin(), base_end = base.end();

		for (;;)
		{
			if (base_it == base_end) {
				return true;
			}
			if (path_it == path_end) {
				return false;
			}
			if (*path_it != *base_it) {
				return false;
			}
			++path_it;
			++base_it;
		}
		return false;
	}
}
<commit_msg>不再需要转换大小写<commit_after>#include "dbg_path.h"
#include <deque>
#include <algorithm>

namespace vscode
{
	fs::path path_uncomplete(const fs::path& path, const fs::path& base, std::error_code& ec)
	{
		fs::path npath = path_normalize(path);
		fs::path nbase = path_normalize(base);
		if (npath == nbase)
			return L"./";
		fs::path from_path, from_base, output;
		fs::path::iterator path_it = npath.begin(), path_end = npath.end();
		fs::path::iterator base_it = nbase.begin(), base_end = nbase.end();

		if ((path_it == path_end) || (base_it == base_end))
		{
			ec = std::make_error_code(std::errc::not_a_directory);
			return npath;
		}

#ifdef WIN32
		if (*path_it != *base_it)
			return npath;
		++path_it, ++base_it;
#endif

		while (true) {
			if ((path_it == path_end) || (base_it == base_end) || (*path_it != *base_it)) {
				for (; base_it != base_end; ++base_it) {
					if (*base_it == L".")
						continue;
					else if (*base_it == L"/")
						continue;

					output /= L"../";
				}
				fs::path::iterator path_it_start = path_it;
				for (; path_it != path_end; ++path_it) {

					if (path_it != path_it_start)
						output /= L"/";

					if (*path_it == L".")
						continue;
					if (*path_it == L"/")
						continue;

					output /= *path_it;
				}

				break;
			}
			from_path /= fs::path(*path_it);
			from_base /= fs::path(*base_it);
			++path_it, ++base_it;
		}

		return output;
	}

	fs::path path_normalize(const fs::path& p)
	{
		fs::path result = p.root_path();
		std::deque<std::wstring> stack;
		for (auto e : p.relative_path()) {
			if (e == L".." && !stack.empty() && stack.back() != L"..") {
				stack.pop_back();
			}
			else if (e != L".") {
#if _MSC_VER >= 1900
				stack.push_back(e.wstring());
#else
				stack.push_back(e);
#endif
			}
		}
		for (auto e : stack) {
			result /= e;
		}
		return result.wstring();
	}

	bool path_is_subpath(const fs::path& path, const fs::path& base)
	{
		fs::path npath = path_normalize(path);
		fs::path::iterator path_it = npath.begin(), path_end = npath.end();
		fs::path::iterator base_it = base.begin(), base_end = base.end();

		for (;;)
		{
			if (base_it == base_end) {
				return true;
			}
			if (path_it == path_end) {
				return false;
			}
			if (*path_it != *base_it) {
				return false;
			}
			++path_it;
			++base_it;
		}
		return false;
	}
}
<|endoftext|>


<commit_before>
//GL
#include <GL/glew.h>
#include <GL/freeglut.h>

// visiongl
#include "vglLoadShader.h"
#include "glsl2cpp_shaders.h"
#include "glsl2cpp_Stereo.h"
#include "vglImage.h"
#include "vglContext.h"
#include "vglCudaImage.h"
#include "vglSimpleBGModel.h"

//IplImage, cvLoadImage
#include <opencv2/highgui/highgui_c.h>
//cvCvtColor
#include <opencv2/imgproc/imgproc_c.h>

//time
#include <time.h>

//begin cameras
#define MAX_CAM 4
CvCapture *capture[MAX_CAM];
//end Cameras

void display(void);
void reshape(int w, int h);
void keyboard(unsigned char key, int x, int y);

using namespace std;

// NUM_CHANNELS \in {3, 4}
#define   NUM_CHANNELS    4

#define   NUM_IMG         20
VglImage* img[NUM_IMG];
VglImage* img_gray[NUM_IMG];

GLuint tex = (unsigned int)-1;

int width, height;
int img_width, img_height;

int i_frame = 0;
int disparity = 0;
int last_i_frame = -1;

// indicates number of rows and columns of images in main window
int refreshall = 2;

char* winname[VGL_MAX_WINDOWS];

VglNamedWindowList* window_list;

int num_cam = 0;

float zoomfactor = 1.0;

int showstats() {
  static int lasttime;
  static int fpscounter;
  static int fps;
  int curtime;
  curtime = time(NULL);
  if( lasttime != curtime) {
    fps=fpscounter;
    fpscounter=1;
    lasttime = curtime;
    fprintf(stderr, "fps = %d,  %f msecs\n",fps,1.0/((float)fps)*1000);
  } else {
    fpscounter++;
  }
  return fps;
}

void display_cam(void)
{

    for (int i = 0; i < num_cam; i++)
    {
        cvGrabFrame(capture[i]);
        if (NUM_CHANNELS == 3)
	{
            cvCopy(cvRetrieveFrame(capture[i]), img[i]->ipl);
	}
        else
	{
            cvCvtColor(cvRetrieveFrame(capture[i]), img[i]->ipl, CV_RGB2RGBA);
	}
        vglSetContext(img[i], VGL_RAM_CONTEXT);
        vglUpload(img[i]);
    }
    i_frame++;
}

void display(void)
{

  display_cam();

  if (num_cam == 1)
  {
    vglCopy(img[0], img[1]);
  }

  vglCopy(img[0], img[2]);
  vglCopy(img[0], img[3]);
  vglCopy(img[0], img[4]);

  vglGray(img[0], img[2]);
  vglCopy(img[2], img[4]);

  vglDilateSq3(img[2], img[3]);
  vglDilateSq3(img[3], img[2]);

  vglDilateSq3(img[2], img[3]);
  vglDilateSq3(img[3], img[2]);

  vglDilateSq3(img[2], img[3]);
  vglDilateSq3(img[3], img[2]);

  vglSobelGradient(img[4], img[5]);
  vglDilateSq3(img[5], img[6]);

  vglDiff(img[4], img[5], img[7]);
  vglCopy(img[7], img[3]);

  window_list->RefreshAll(refreshall);

  //CHECK_FRAMEBUFFER_STATUS()
  //ERRCHECK()

  int fps = showstats();
}

void reshape(int w, int h)
{
   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
   width = w, height = h;
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
}

void keyboard(unsigned char key, int x, int y)
{
   switch (key) {
      case 'q':
      case 'Q':
      case 27:
         glutLeaveMainLoop();
         break;
      default:
         break;
   }
}

void PrintCaptureProperty(CvCapture *capture){
  float result;
  IplImage *img_in = cvQueryFrame(capture);
  printf("CV_CAP_PROP_POS_MSEC %f\n", cvGetCaptureProperty(capture, CV_CAP_PROP_POS_MSEC));
  printf("CV_CAP_PROP_POS_FRAMES %f\n", cvGetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES));
  printf("CV_CAP_PROP_POS_AVI_RATIO %f\n", cvGetCaptureProperty(capture, CV_CAP_PROP_POS_AVI_RATIO));

  result = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
  if (result == 0.0) result = img_in->width;
  printf("CV_CAP_PROP_FRAME_WIDTH %f\n", result);

  result = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);
  if (result == 0.0) result = img_in->height;
  printf("CV_CAP_PROP_FRAME_HEIGHT %f\n", result);

  printf("CV_CAP_PROP_FPS %f\n", cvGetCaptureProperty(capture, CV_CAP_PROP_FPS));
  printf("CV_CAP_PROP_FOURCC %f\n", cvGetCaptureProperty(capture, CV_CAP_PROP_FOURCC));
}

int main(int argc, char** argv)
{
  for (int i = 0; i < MAX_CAM; i++){
    capture[i] = 0;
    capture[i] = cvCaptureFromCAM(i);
    cvSetCaptureProperty(capture[i], CV_CAP_PROP_FPS, 30.0f);
    if (capture[i]){
      printf("Camera %d at %p\n", i, capture[i]);
      PrintCaptureProperty(capture[i]);
      num_cam++;
      printf("\n\n");
    }
   }

  window_list  = new VglNamedWindowList();
  window_list->main_window_id = vglInit(1280, 960);

  glutDisplayFunc(display);
  glutIdleFunc(display);

  glutReshapeFunc(reshape);
  glutKeyboardFunc(keyboard);

  for (int i = 0; i < VGL_MAX_WINDOWS; i++){
    winname[i]  = (char*) malloc(255);
    sprintf(winname[i], "win[%d]", i);
  }

  for (int i = 0; i < num_cam; i++){
    const int HAS_MIPMAP = 0;
    img[i]      = vglCreateImage(cvSize(640, 480), IPL_DEPTH_8U, NUM_CHANNELS, 2, HAS_MIPMAP);
    img_gray[i] = vglCreateImage(cvSize(640, 480), IPL_DEPTH_8U, 1, 2, HAS_MIPMAP);

    if (!img[i]){
      fprintf(stderr, "Error loading img[%d] from file\n", i);
      exit(1);
    }
    //vglPrintImageInfo(img[i]);
  }

  for (int i = num_cam; i < NUM_IMG; i++){
    img[i] = vglCreateImage(img[0]);
    img_gray[i] = vglCreateImage(img_gray[0]);
    if (!img[i]){
      fprintf(stderr, "Error creating img[%d]\n", i);
      exit(1);
    }
    vglClear(img[i], 0.0, 0.0, 0.0, 0.0);
    //vglPrintImageInfo(img[i]);
    char* img_name = (char*)malloc(255);
    sprintf(img_name, "img[%d]", i);
    vglPrintContext(img[i], img_name);
  }

  for (int i = 0; i < 4; i++){
    window_list->NamedWindow(winname[i]);
    window_list->ShowImage(winname[i], img[i]);
  }

  GLint iUnits;
  glGetIntegerv(GL_MAX_TEXTURE_UNITS, &iUnits);
  printf("Max number of textures = %d\n", iUnits);

  glutMainLoop();

  return 0;
}
<commit_msg>democam modified. Exiting gently when no camera is detected.<commit_after>
//GL
#include <GL/glew.h>
#include <GL/freeglut.h>

// visiongl
#include "vglLoadShader.h"
#include "glsl2cpp_shaders.h"
#include "glsl2cpp_Stereo.h"
#include "vglImage.h"
#include "vglContext.h"
#include "vglCudaImage.h"
#include "vglSimpleBGModel.h"

//IplImage, cvLoadImage
#include <opencv2/highgui/highgui_c.h>
//cvCvtColor
#include <opencv2/imgproc/imgproc_c.h>

//time
#include <time.h>

//begin cameras
#define MAX_CAM 4
CvCapture *capture[MAX_CAM];
//end Cameras

void display(void);
void reshape(int w, int h);
void keyboard(unsigned char key, int x, int y);

using namespace std;

// NUM_CHANNELS \in {3, 4}
#define   NUM_CHANNELS    4

#define   NUM_IMG         20
VglImage* img[NUM_IMG];
VglImage* img_gray[NUM_IMG];

GLuint tex = (unsigned int)-1;

int width, height;
int img_width, img_height;

int i_frame = 0;
int disparity = 0;
int last_i_frame = -1;

// indicates number of rows and columns of images in main window
int refreshall = 2;

char* winname[VGL_MAX_WINDOWS];

VglNamedWindowList* window_list;

int num_cam = 0;

float zoomfactor = 1.0;

int showstats() {
  static int lasttime;
  static int fpscounter;
  static int fps;
  int curtime;
  curtime = time(NULL);
  if( lasttime != curtime) {
    fps=fpscounter;
    fpscounter=1;
    lasttime = curtime;
    fprintf(stderr, "fps = %d,  %f msecs\n",fps,1.0/((float)fps)*1000);
  } else {
    fpscounter++;
  }
  return fps;
}

void display_cam(void)
{

    for (int i = 0; i < num_cam; i++)
    {
        cvGrabFrame(capture[i]);
        if (NUM_CHANNELS == 3)
	{
            cvCopy(cvRetrieveFrame(capture[i]), img[i]->ipl);
	}
        else
	{
            cvCvtColor(cvRetrieveFrame(capture[i]), img[i]->ipl, CV_RGB2RGBA);
	}
        vglSetContext(img[i], VGL_RAM_CONTEXT);
        int swapRgb = 1;
        vglUpload(img[i], swapRgb);
    }
    i_frame++;
}

void display(void)
{

  display_cam();

  if (num_cam == 1)
  {
    vglCopy(img[0], img[1]);
  }

  vglCopy(img[0], img[2]);
  vglCopy(img[0], img[3]);
  vglCopy(img[0], img[4]);

  vglGray(img[0], img[2]);
  vglCopy(img[2], img[4]);

  vglDilateSq3(img[2], img[3]);
  vglDilateSq3(img[3], img[2]);

  vglDilateSq3(img[2], img[3]);
  vglDilateSq3(img[3], img[2]);

  vglDilateSq3(img[2], img[3]);
  vglDilateSq3(img[3], img[2]);

  vglSobelGradient(img[4], img[5]);
  vglDilateSq3(img[5], img[6]);

  vglDiff(img[4], img[5], img[7]);
  vglCopy(img[7], img[3]);

  window_list->RefreshAll(refreshall);

  //CHECK_FRAMEBUFFER_STATUS()
  //ERRCHECK()

  int fps = showstats();
}

void reshape(int w, int h)
{
   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
   width = w, height = h;
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
}

void keyboard(unsigned char key, int x, int y)
{
   switch (key) {
      case 'q':
      case 'Q':
      case 27:
         glutLeaveMainLoop();
         break;
      default:
         break;
   }
}

void PrintCaptureProperty(CvCapture *capture){
  float result;
  IplImage *img_in = cvQueryFrame(capture);
  printf("CV_CAP_PROP_POS_MSEC %f\n", cvGetCaptureProperty(capture, CV_CAP_PROP_POS_MSEC));
  printf("CV_CAP_PROP_POS_FRAMES %f\n", cvGetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES));
  printf("CV_CAP_PROP_POS_AVI_RATIO %f\n", cvGetCaptureProperty(capture, CV_CAP_PROP_POS_AVI_RATIO));

  result = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
  if (result == 0.0) result = img_in->width;
  printf("CV_CAP_PROP_FRAME_WIDTH %f\n", result);

  result = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);
  if (result == 0.0) result = img_in->height;
  printf("CV_CAP_PROP_FRAME_HEIGHT %f\n", result);

  printf("CV_CAP_PROP_FPS %f\n", cvGetCaptureProperty(capture, CV_CAP_PROP_FPS));
  printf("CV_CAP_PROP_FOURCC %f\n", cvGetCaptureProperty(capture, CV_CAP_PROP_FOURCC));
}

int main(int argc, char** argv)
{
  for (int i = 0; i < MAX_CAM; i++){
    capture[i] = 0;
    capture[i] = cvCaptureFromCAM(i);
    cvSetCaptureProperty(capture[i], CV_CAP_PROP_FPS, 30.0f);
    if (capture[i]){
      printf("Camera %d at %p\n", i, capture[i]);
      PrintCaptureProperty(capture[i]);
      num_cam++;
      printf("\n\n");
    }
  }
  if (num_cam < 1){
    fprintf(stderr, "Error: no camera detected\n");
    exit(1);
  }

  window_list  = new VglNamedWindowList();
  window_list->main_window_id = vglInit(1280, 960);

  glutDisplayFunc(display);
  glutIdleFunc(display);

  glutReshapeFunc(reshape);
  glutKeyboardFunc(keyboard);

  for (int i = 0; i < VGL_MAX_WINDOWS; i++){
    winname[i]  = (char*) malloc(255);
    sprintf(winname[i], "win[%d]", i);
  }

  for (int i = 0; i < num_cam; i++){
    const int HAS_MIPMAP = 0;
    img[i]      = vglCreateImage(cvSize(640, 480), IPL_DEPTH_8U, NUM_CHANNELS, 2, HAS_MIPMAP);
    img_gray[i] = vglCreateImage(cvSize(640, 480), IPL_DEPTH_8U, 1, 2, HAS_MIPMAP);

    if (!img[i]){
      fprintf(stderr, "Error loading img[%d] from file\n", i);
      exit(1);
    }
    //vglPrintImageInfo(img[i]);
  }

  for (int i = num_cam; i < NUM_IMG; i++){
    img[i] = vglCreateImage(img[0]);
    img_gray[i] = vglCreateImage(img_gray[0]);
    if (!img[i]){
      fprintf(stderr, "Error creating img[%d]\n", i);
      exit(1);
    }
    vglClear(img[i], 0.0, 0.0, 0.0, 0.0);
    //vglPrintImageInfo(img[i]);
    char* img_name = (char*)malloc(255);
    sprintf(img_name, "img[%d]", i);
    vglPrintContext(img[i], img_name);
  }

  for (int i = 0; i < 4; i++){
    window_list->NamedWindow(winname[i]);
    window_list->ShowImage(winname[i], img[i]);
  }

  GLint iUnits;
  glGetIntegerv(GL_MAX_TEXTURE_UNITS, &iUnits);
  printf("Max number of textures = %d\n", iUnits);

  glutMainLoop();

  return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright 2019 Benoy Bose
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
 * and associated documentation files (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or
 * substantial portions of the Software.
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include "HoocTestHelper.hh"

#include <boost/test/unit_test.hpp>
#include <emitter/x86/X86Definitions.hh>
#include <emitter/x86/EncoderX64.hh>

using namespace hooc::emitter::x86;

BOOST_AUTO_TEST_SUITE(Encoder64Test)

    BOOST_AUTO_TEST_CASE(TEST01) {
        EncoderX64 encoder;
        auto bytes = encoder.PUSH(X86_REG_RBP);
        byte expected[1] = {0x55};
        BOOST_CHECK(VerifyByteVector(bytes, expected, 1));
    }

    BOOST_AUTO_TEST_CASE(TEST02) {
        EncoderX64 encoder;
        auto bytes = encoder.MOV(X86_REG_RSP, X86_REG_RBP);
        byte expected[3] = {0x48, 0x89, 0xE5};
        BOOST_CHECK(VerifyByteVector(bytes, expected, 3));
    }

    BOOST_AUTO_TEST_CASE(TEST03) {
        EncoderX64 encoder;
        auto bytes = encoder.MOV(X86_REG_RCX, X86_REG_RBP, 0x10);
        byte expected[4] = {0x48, 0x89, 0x4d, 0x10};
        BOOST_CHECK(VerifyByteVector(bytes, expected, 4));
    }

    BOOST_AUTO_TEST_CASE(TEST04) {
        EncoderX64 encoder;
        auto bytes = encoder.MOV(X86_REG_RDX, X86_REG_RBP, 0x18);
        byte expected[4] = {0x48, 0x89, 0x55, 0x18};
        BOOST_CHECK(VerifyByteVector(bytes, expected, 4));
    }

    BOOST_AUTO_TEST_CASE(TEST05) {
        EncoderX64 encoder;
        auto bytes = encoder.RET(true);
        byte expected[1] = {0xCB};
        BOOST_CHECK(VerifyByteVector(bytes, expected, 1));
    }

    BOOST_AUTO_TEST_CASE(TEST06) {
        EncoderX64 encoder;
        auto bytes = encoder.RET(false);
        byte expected[1] = {0xC3};
        BOOST_CHECK(VerifyByteVector(bytes, expected, 1));
    }

    BOOST_AUTO_TEST_CASE(TEST07) {
        EncoderX64 encoder;
        auto bytes = encoder.POP(X86_REG_RBP);
        byte expected[1] = {0x5D};
        BOOST_CHECK(VerifyByteVector(bytes, expected, 1));
    }

    BOOST_AUTO_TEST_CASE(TEST08) {
        EncoderX64 encoder;
        auto bytes = encoder.NOP();
        byte expected[1] = {0x90};
        BOOST_CHECK(VerifyByteVector(bytes, expected, 1));
    }

    BOOST_AUTO_TEST_CASE(TEST09) {
        EncoderX64 encoder;
        auto bytes = encoder.MOV(X86_REG_R8, X86_REG_RBP, 0x20);
        byte expected[4] = {0x4c, 0x89, 0x45, 0x20};
        BOOST_CHECK(VerifyByteVector(bytes, expected, 4));
    }

    BOOST_AUTO_TEST_CASE(TEST11) {
        EncoderX64 encoder;
        auto bytes = encoder.MOVSD(X86_REG_XMM0, X86_REG_RBP, 0x10);
        byte expected[5] = { 0xf2, 0x0f, 0x11, 0x45, 0x10 };
        BOOST_CHECK(VerifyByteVector(bytes, expected, 5));
    }

BOOST_AUTO_TEST_SUITE_END()<commit_msg>Tested a few more cases of MOVSD instruction.<commit_after>/*
 * Copyright 2019 Benoy Bose
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
 * and associated documentation files (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or
 * substantial portions of the Software.
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include "HoocTestHelper.hh"

#include <boost/test/unit_test.hpp>
#include <emitter/x86/X86Definitions.hh>
#include <emitter/x86/EncoderX64.hh>

using namespace hooc::emitter::x86;

BOOST_AUTO_TEST_SUITE(Encoder64Test)

    BOOST_AUTO_TEST_CASE(TEST01) {
        EncoderX64 encoder;
        auto bytes = encoder.PUSH(X86_REG_RBP);
        byte expected[1] = {0x55};
        BOOST_CHECK(VerifyByteVector(bytes, expected, 1));
    }

    BOOST_AUTO_TEST_CASE(TEST02) {
        EncoderX64 encoder;
        auto bytes = encoder.MOV(X86_REG_RSP, X86_REG_RBP);
        byte expected[3] = {0x48, 0x89, 0xE5};
        BOOST_CHECK(VerifyByteVector(bytes, expected, 3));
    }

    BOOST_AUTO_TEST_CASE(TEST03) {
        EncoderX64 encoder;
        auto bytes = encoder.MOV(X86_REG_RCX, X86_REG_RBP, 0x10);
        byte expected[4] = {0x48, 0x89, 0x4d, 0x10};
        BOOST_CHECK(VerifyByteVector(bytes, expected, 4));
    }

    BOOST_AUTO_TEST_CASE(TEST04) {
        EncoderX64 encoder;
        auto bytes = encoder.MOV(X86_REG_RDX, X86_REG_RBP, 0x18);
        byte expected[4] = {0x48, 0x89, 0x55, 0x18};
        BOOST_CHECK(VerifyByteVector(bytes, expected, 4));
    }

    BOOST_AUTO_TEST_CASE(TEST05) {
        EncoderX64 encoder;
        auto bytes = encoder.RET(true);
        byte expected[1] = {0xCB};
        BOOST_CHECK(VerifyByteVector(bytes, expected, 1));
    }

    BOOST_AUTO_TEST_CASE(TEST06) {
        EncoderX64 encoder;
        auto bytes = encoder.RET(false);
        byte expected[1] = {0xC3};
        BOOST_CHECK(VerifyByteVector(bytes, expected, 1));
    }

    BOOST_AUTO_TEST_CASE(TEST07) {
        EncoderX64 encoder;
        auto bytes = encoder.POP(X86_REG_RBP);
        byte expected[1] = {0x5D};
        BOOST_CHECK(VerifyByteVector(bytes, expected, 1));
    }

    BOOST_AUTO_TEST_CASE(TEST08) {
        EncoderX64 encoder;
        auto bytes = encoder.NOP();
        byte expected[1] = {0x90};
        BOOST_CHECK(VerifyByteVector(bytes, expected, 1));
    }

    BOOST_AUTO_TEST_CASE(TEST09) {
        EncoderX64 encoder;
        auto bytes = encoder.MOV(X86_REG_R8, X86_REG_RBP, 0x20);
        byte expected[4] = {0x4c, 0x89, 0x45, 0x20};
        BOOST_CHECK(VerifyByteVector(bytes, expected, 4));
    }

    BOOST_AUTO_TEST_CASE(TEST11) {
        EncoderX64 encoder;
        auto bytes = encoder.MOVSD(X86_REG_XMM0, X86_REG_RBP, 0x10);
        byte expected[5] = { 0xf2, 0x0f, 0x11, 0x45, 0x10 };
        BOOST_CHECK(VerifyByteVector(bytes, expected, 5));
    }

    BOOST_AUTO_TEST_CASE(TEST12) {
        EncoderX64 encoder;
        auto bytes = encoder.MOVSD(X86_REG_XMM1, X86_REG_RBP, 0x18);
        byte expected[5] = { 0xf2, 0x0f, 0x11, 0x4d, 0x18 };
        BOOST_CHECK(VerifyByteVector(bytes, expected, 5));
    }

    BOOST_AUTO_TEST_CASE(TEST13) {
        EncoderX64 encoder;
        auto bytes = encoder.MOVSD(X86_REG_XMM2, X86_REG_RBP, 0x20);
        byte expected[5] = { 0xf2, 0x0f, 0x11, 0x55, 0x20 };
        BOOST_CHECK(VerifyByteVector(bytes, expected, 5));
    }

    BOOST_AUTO_TEST_CASE(TEST14) {
        EncoderX64 encoder;
        auto bytes = encoder.MOVSD(X86_REG_XMM3, X86_REG_RBP, 0x28);
        byte expected[5] = { 0xf2, 0x0f, 0x11, 0x5d, 0x28 };
        BOOST_CHECK(VerifyByteVector(bytes, expected, 5));
    }

BOOST_AUTO_TEST_SUITE_END()<|endoftext|>