<commit_before>// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/app/atom_content_client.h"

#include <string>
#include <vector>

#include "atom/common/atom_version.h"
#include "atom/common/chrome_version.h"
#include "atom/common/options_switches.h"
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/pepper_plugin_info.h"
#include "content/public/common/user_agent.h"
#include "ppapi/shared_impl/ppapi_permissions.h"
#include "third_party/widevine/cdm/stub/widevine_cdm_version.h"
#include "ui/base/l10n/l10n_util.h"
#include "url/url_constants.h"

#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
#include "chrome/common/widevine_cdm_constants.h"
#endif

namespace atom {

namespace {

content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path,
                                                const std::string& version) {
  content::PepperPluginInfo plugin;

  plugin.is_out_of_process = true;
  plugin.name = content::kFlashPluginName;
  plugin.path = path;
  plugin.permissions = ppapi::PERMISSION_ALL_BITS;

  std::vector<std::string> flash_version_numbers = base::SplitString(
      version, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
  if (flash_version_numbers.size() < 1)
    flash_version_numbers.push_back("11");
  // |SplitString()| puts in an empty string given an empty string. :(
  else if (flash_version_numbers[0].empty())
    flash_version_numbers[0] = "11";
  if (flash_version_numbers.size() < 2)
    flash_version_numbers.push_back("2");
  if (flash_version_numbers.size() < 3)
    flash_version_numbers.push_back("999");
  if (flash_version_numbers.size() < 4)
    flash_version_numbers.push_back("999");
  // E.g., "Shockwave Flash 10.2 r154":
  plugin.description = plugin.name + " " + flash_version_numbers[0] + "." +
      flash_version_numbers[1] + " r" + flash_version_numbers[2];
  plugin.version = base::JoinString(flash_version_numbers, ".");
  content::WebPluginMimeType swf_mime_type(
      content::kFlashPluginSwfMimeType,
      content::kFlashPluginSwfExtension,
      content::kFlashPluginSwfDescription);
  plugin.mime_types.push_back(swf_mime_type);
  content::WebPluginMimeType spl_mime_type(
      content::kFlashPluginSplMimeType,
      content::kFlashPluginSplExtension,
      content::kFlashPluginSplDescription);
  plugin.mime_types.push_back(spl_mime_type);

  return plugin;
}

#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
content::PepperPluginInfo CreateWidevineCdmInfo(const base::FilePath& path,
                                                const std::string& version) {
  content::PepperPluginInfo widevine_cdm;
  widevine_cdm.is_out_of_process = true;
  widevine_cdm.path = path;
  widevine_cdm.name = kWidevineCdmDisplayName;
  widevine_cdm.description = kWidevineCdmDescription +
                             std::string(" (version: ") +
                             version + ")";
  widevine_cdm.version = version;
  content::WebPluginMimeType widevine_cdm_mime_type(
      kWidevineCdmPluginMimeType,
      kWidevineCdmPluginExtension,
      kWidevineCdmPluginMimeTypeDescription);

  // Add the supported codecs as if they came from the component manifest.
  std::vector<std::string> codecs;
  codecs.push_back(kCdmSupportedCodecVorbis);
  codecs.push_back(kCdmSupportedCodecVp8);
  codecs.push_back(kCdmSupportedCodecVp9);
#if defined(USE_PROPRIETARY_CODECS)
  codecs.push_back(kCdmSupportedCodecAac);
  codecs.push_back(kCdmSupportedCodecAvc1);
#endif  // defined(USE_PROPRIETARY_CODECS)
  std::string codec_string = base::JoinString(
      codecs, std::string(1, kCdmSupportedCodecsValueDelimiter));
  widevine_cdm_mime_type.additional_param_names.push_back(
      base::ASCIIToUTF16(kCdmSupportedCodecsParamName));
  widevine_cdm_mime_type.additional_param_values.push_back(
      base::ASCIIToUTF16(codec_string));

  widevine_cdm.mime_types.push_back(widevine_cdm_mime_type);
  widevine_cdm.permissions = kWidevineCdmPluginPermissions;

  return widevine_cdm;
}
#endif

void ConvertStringWithSeparatorToVector(std::vector<std::string>* vec,
                                        const char* separator,
                                        const char* cmd_switch) {
  auto command_line = base::CommandLine::ForCurrentProcess();
  auto string_with_separator = command_line->GetSwitchValueASCII(cmd_switch);
  if (!string_with_separator.empty())
    *vec = base::SplitString(string_with_separator, separator,
                             base::TRIM_WHITESPACE,
                             base::SPLIT_WANT_NONEMPTY);
}

}  // namespace

void AddPepperFlashFromCommandLine(
    std::vector<content::PepperPluginInfo>* plugins) {
  auto command_line = base::CommandLine::ForCurrentProcess();
  base::FilePath flash_path = command_line->GetSwitchValuePath(
      switches::kPpapiFlashPath);
  if (flash_path.empty())
    return;

  auto flash_version = command_line->GetSwitchValueASCII(
      switches::kPpapiFlashVersion);

  plugins->push_back(CreatePepperFlashInfo(flash_path, flash_version));
}

#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
void AddWidevineCdmFromCommandLine(
    std::vector<content::PepperPluginInfo>* plugins) {
  auto command_line = base::CommandLine::ForCurrentProcess();
  base::FilePath widevine_cdm_path = command_line->GetSwitchValuePath(
      switches::kWidevineCdmPath);
  if (widevine_cdm_path.empty())
    return;

  if (!base::PathExists(widevine_cdm_path))
    return;

  auto widevine_cdm_version = command_line->GetSwitchValueASCII(
      switches::kWidevineCdmVersion);
  if (widevine_cdm_version.empty())
    return;

  plugins->push_back(CreateWidevineCdmInfo(widevine_cdm_path,
                                           widevine_cdm_version));
}
#endif

AtomContentClient::AtomContentClient() {
}

AtomContentClient::~AtomContentClient() {
}

std::string AtomContentClient::GetProduct() const {
  return "Chrome/" CHROME_VERSION_STRING;
}

std::string AtomContentClient::GetUserAgent() const {
  return content::BuildUserAgentFromProduct(
      "Chrome/" CHROME_VERSION_STRING " "
      ATOM_PRODUCT_NAME "/" ATOM_VERSION_STRING);
}

base::string16 AtomContentClient::GetLocalizedString(int message_id) const {
  return l10n_util::GetStringUTF16(message_id);
}

void AtomContentClient::AddAdditionalSchemes(
    std::vector<url::SchemeWithType>* standard_schemes,
    std::vector<url::SchemeWithType>* referrer_schemes,
    std::vector<std::string>* savable_schemes) {
  standard_schemes->push_back({"chrome-extension", url::SCHEME_WITHOUT_PORT});
}

void AtomContentClient::AddPepperPlugins(
    std::vector<content::PepperPluginInfo>* plugins) {
  AddPepperFlashFromCommandLine(plugins);
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
  AddWidevineCdmFromCommandLine(plugins);
#endif
}

void AtomContentClient::AddServiceWorkerSchemes(
    std::set<std::string>* service_worker_schemes) {
  std::vector<std::string> schemes;
  ConvertStringWithSeparatorToVector(&schemes, ",",
                                     switches::kRegisterServiceWorkerSchemes);
  if (!schemes.empty()) {
    for (const std::string& scheme : schemes)
      service_worker_schemes->insert(scheme);
  }
  service_worker_schemes->insert(url::kFileScheme);
}

}  // namespace atom
<commit_msg>Remove Vorbis from CDM support<commit_after>// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/app/atom_content_client.h"

#include <string>
#include <vector>

#include "atom/common/atom_version.h"
#include "atom/common/chrome_version.h"
#include "atom/common/options_switches.h"
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/pepper_plugin_info.h"
#include "content/public/common/user_agent.h"
#include "ppapi/shared_impl/ppapi_permissions.h"
#include "third_party/widevine/cdm/stub/widevine_cdm_version.h"
#include "ui/base/l10n/l10n_util.h"
#include "url/url_constants.h"

#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
#include "chrome/common/widevine_cdm_constants.h"
#endif

namespace atom {

namespace {

content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path,
                                                const std::string& version) {
  content::PepperPluginInfo plugin;

  plugin.is_out_of_process = true;
  plugin.name = content::kFlashPluginName;
  plugin.path = path;
  plugin.permissions = ppapi::PERMISSION_ALL_BITS;

  std::vector<std::string> flash_version_numbers = base::SplitString(
      version, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
  if (flash_version_numbers.size() < 1)
    flash_version_numbers.push_back("11");
  // |SplitString()| puts in an empty string given an empty string. :(
  else if (flash_version_numbers[0].empty())
    flash_version_numbers[0] = "11";
  if (flash_version_numbers.size() < 2)
    flash_version_numbers.push_back("2");
  if (flash_version_numbers.size() < 3)
    flash_version_numbers.push_back("999");
  if (flash_version_numbers.size() < 4)
    flash_version_numbers.push_back("999");
  // E.g., "Shockwave Flash 10.2 r154":
  plugin.description = plugin.name + " " + flash_version_numbers[0] + "." +
      flash_version_numbers[1] + " r" + flash_version_numbers[2];
  plugin.version = base::JoinString(flash_version_numbers, ".");
  content::WebPluginMimeType swf_mime_type(
      content::kFlashPluginSwfMimeType,
      content::kFlashPluginSwfExtension,
      content::kFlashPluginSwfDescription);
  plugin.mime_types.push_back(swf_mime_type);
  content::WebPluginMimeType spl_mime_type(
      content::kFlashPluginSplMimeType,
      content::kFlashPluginSplExtension,
      content::kFlashPluginSplDescription);
  plugin.mime_types.push_back(spl_mime_type);

  return plugin;
}

#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
content::PepperPluginInfo CreateWidevineCdmInfo(const base::FilePath& path,
                                                const std::string& version) {
  content::PepperPluginInfo widevine_cdm;
  widevine_cdm.is_out_of_process = true;
  widevine_cdm.path = path;
  widevine_cdm.name = kWidevineCdmDisplayName;
  widevine_cdm.description = kWidevineCdmDescription +
                             std::string(" (version: ") +
                             version + ")";
  widevine_cdm.version = version;
  content::WebPluginMimeType widevine_cdm_mime_type(
      kWidevineCdmPluginMimeType,
      kWidevineCdmPluginExtension,
      kWidevineCdmPluginMimeTypeDescription);

  // Add the supported codecs as if they came from the component manifest.
  std::vector<std::string> codecs;
  codecs.push_back(kCdmSupportedCodecVp8);
  codecs.push_back(kCdmSupportedCodecVp9);
#if defined(USE_PROPRIETARY_CODECS)
  codecs.push_back(kCdmSupportedCodecAac);
  codecs.push_back(kCdmSupportedCodecAvc1);
#endif  // defined(USE_PROPRIETARY_CODECS)
  std::string codec_string = base::JoinString(
      codecs, std::string(1, kCdmSupportedCodecsValueDelimiter));
  widevine_cdm_mime_type.additional_param_names.push_back(
      base::ASCIIToUTF16(kCdmSupportedCodecsParamName));
  widevine_cdm_mime_type.additional_param_values.push_back(
      base::ASCIIToUTF16(codec_string));

  widevine_cdm.mime_types.push_back(widevine_cdm_mime_type);
  widevine_cdm.permissions = kWidevineCdmPluginPermissions;

  return widevine_cdm;
}
#endif

void ConvertStringWithSeparatorToVector(std::vector<std::string>* vec,
                                        const char* separator,
                                        const char* cmd_switch) {
  auto command_line = base::CommandLine::ForCurrentProcess();
  auto string_with_separator = command_line->GetSwitchValueASCII(cmd_switch);
  if (!string_with_separator.empty())
    *vec = base::SplitString(string_with_separator, separator,
                             base::TRIM_WHITESPACE,
                             base::SPLIT_WANT_NONEMPTY);
}

}  // namespace

void AddPepperFlashFromCommandLine(
    std::vector<content::PepperPluginInfo>* plugins) {
  auto command_line = base::CommandLine::ForCurrentProcess();
  base::FilePath flash_path = command_line->GetSwitchValuePath(
      switches::kPpapiFlashPath);
  if (flash_path.empty())
    return;

  auto flash_version = command_line->GetSwitchValueASCII(
      switches::kPpapiFlashVersion);

  plugins->push_back(CreatePepperFlashInfo(flash_path, flash_version));
}

#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
void AddWidevineCdmFromCommandLine(
    std::vector<content::PepperPluginInfo>* plugins) {
  auto command_line = base::CommandLine::ForCurrentProcess();
  base::FilePath widevine_cdm_path = command_line->GetSwitchValuePath(
      switches::kWidevineCdmPath);
  if (widevine_cdm_path.empty())
    return;

  if (!base::PathExists(widevine_cdm_path))
    return;

  auto widevine_cdm_version = command_line->GetSwitchValueASCII(
      switches::kWidevineCdmVersion);
  if (widevine_cdm_version.empty())
    return;

  plugins->push_back(CreateWidevineCdmInfo(widevine_cdm_path,
                                           widevine_cdm_version));
}
#endif

AtomContentClient::AtomContentClient() {
}

AtomContentClient::~AtomContentClient() {
}

std::string AtomContentClient::GetProduct() const {
  return "Chrome/" CHROME_VERSION_STRING;
}

std::string AtomContentClient::GetUserAgent() const {
  return content::BuildUserAgentFromProduct(
      "Chrome/" CHROME_VERSION_STRING " "
      ATOM_PRODUCT_NAME "/" ATOM_VERSION_STRING);
}

base::string16 AtomContentClient::GetLocalizedString(int message_id) const {
  return l10n_util::GetStringUTF16(message_id);
}

void AtomContentClient::AddAdditionalSchemes(
    std::vector<url::SchemeWithType>* standard_schemes,
    std::vector<url::SchemeWithType>* referrer_schemes,
    std::vector<std::string>* savable_schemes) {
  standard_schemes->push_back({"chrome-extension", url::SCHEME_WITHOUT_PORT});
}

void AtomContentClient::AddPepperPlugins(
    std::vector<content::PepperPluginInfo>* plugins) {
  AddPepperFlashFromCommandLine(plugins);
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
  AddWidevineCdmFromCommandLine(plugins);
#endif
}

void AtomContentClient::AddServiceWorkerSchemes(
    std::set<std::string>* service_worker_schemes) {
  std::vector<std::string> schemes;
  ConvertStringWithSeparatorToVector(&schemes, ",",
                                     switches::kRegisterServiceWorkerSchemes);
  if (!schemes.empty()) {
    for (const std::string& scheme : schemes)
      service_worker_schemes->insert(scheme);
  }
  service_worker_schemes->insert(url::kFileScheme);
}

}  // namespace atom
<|endoftext|>


<commit_before>// GLEW
#define GLEW_STATIC
#include <GL/glew.h>
// GLFW
#include <GLFW/glfw3.h>
// SOIL
#include <SOIL.h>
// GLM
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

#include "Test.h"
#include "GLFWApplication.h"
#include "Renderable.h"
#include "Texture.h"
#include "VAO.h"
#include "VBO.h"
#include "EBO.h"
#include "Shader.h"
#include "ShaderProgram.h"
#include "Sprite2D.h"

// Others
#include <iostream>
#include <memory>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cmath>

#ifdef _MSC_VER
#pragma warning(disable: 4099)
#endif

class AGLTest;

class Boxes : agl::Renderable {
public:
	Boxes(AGLTest* a);
	void setUp();
	void tearDown() {
		delete container;
		delete awesome; // aww
		delete vbo;
		delete ebo;
		delete vao;
		delete program;
	}
	void tick();
	void update() {
	}
private:
	agl::Texture* container;
	agl::Texture* awesome;
	agl::VBO* vbo;
	agl::EBO* ebo;
	agl::VAO* vao;
	agl::ShaderProgram* program;
	AGLTest* app;
};

#define DIGIT_WIDTH 14.8f
#define DIGIT_HEIGHT 18
#define DIGIT_BASEX 16
#define DIGIT_BASEY 230

class AGLTest : public agl::GLFWApplication {
public:
	using agl::GLFWApplication::GLFWApplication;
	void initialize() {
		std::cout << "hi\n";
		boxes = new Boxes(this);
		ptex = new agl::Texture("textures/fuckyou.png");
		stex = std::make_shared<agl::Texture>(*ptex);
		sprites = new agl::Sprite2D(stex);
		sprites->setApp(this);
		sprites->addSprite({
			{0, 448, 512, 512},
			{0, 0, 512, 64}
		});
		sprites->addSprite({
			{DIGIT_BASEX, DIGIT_BASEY, DIGIT_BASEX + 4 * DIGIT_WIDTH, DIGIT_BASEY + DIGIT_HEIGHT},
			{50, 500, 50 + 4 * DIGIT_WIDTH, 500 + DIGIT_HEIGHT}
		});
		sprites->addSprite({
			{ DIGIT_BASEX + 14 * DIGIT_WIDTH, DIGIT_BASEY, DIGIT_BASEX + 15 * DIGIT_WIDTH, DIGIT_BASEY + DIGIT_HEIGHT },
			{50 + 6 * DIGIT_WIDTH, 500, 50 + 7 * DIGIT_WIDTH, 500 + DIGIT_HEIGHT}
		});
		for (int i = 0; i < 4; ++i) {
			GLfloat x = 50 + (4 + i + (i >= 2)) * DIGIT_WIDTH;
			sprites->addSprite({
				{0, DIGIT_BASEY, 0, DIGIT_BASEY + DIGIT_HEIGHT},
				{x, 500, x + DIGIT_WIDTH, 500 + DIGIT_HEIGHT}
			});
		}
		sprites->setUp();
	}
	bool ff = true;
	void tick() {
		glClearColor(0.5f, 0.7f, 1.0f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		++frame;
		int which = (frame >> 6) & 3;
		sprites->getLoc(0)->source.top = (GLfloat) (448 - (which << 6));
		sprites->getLoc(0)->source.bottom = (GLfloat) (512 - (which << 6));
		int rfps = (int) (getRollingFPS() * 100);
		for (int i = 3; i >= 0; --i) {
			setDigit(i, rfps % 10);
			rfps /= 10;
		}
		sprites->update();
		boxes->tick();
		sprites->tick();
		char* ctitle = new char[256];
		snprintf(ctitle, 255, "TestApp @ GL %s | FPS: %lf", glGetString(GL_VERSION), getRollingFPS());
		glfwSetWindowTitle(underlying(), ctitle);
	}
	void readKeys() {
		// Test if window should close
		if (testKey(GLFW_KEY_ESCAPE))
			glfwSetWindowShouldClose(underlying(), GL_TRUE);
		// Camera controls
		GLfloat cameraSpeed = 5.0f * (GLfloat) getDelta();
		if (testKey(GLFW_KEY_W))
			cameraPos += cameraSpeed * cameraFront;
		if (testKey(GLFW_KEY_S))
			cameraPos -= cameraSpeed * cameraFront;
		if (testKey(GLFW_KEY_A))
			cameraPos -= glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;
		if (testKey(GLFW_KEY_D))
			cameraPos += glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;
		// Slider controls
		if (testKey(GLFW_KEY_UP)) mix += 0.005f;
		if (testKey(GLFW_KEY_DOWN)) mix -= 0.005f;
	}
	void onMouse(double xpos, double ypos) {
		if (firstMouse) {
			lastX = (GLfloat) xpos;
			lastY = (GLfloat) ypos;
			firstMouse = false;
		}
		GLfloat xoffset = (GLfloat) xpos - lastX;
		GLfloat yoffset = lastY - (GLfloat) ypos;
		lastX = (GLfloat) xpos;
		lastY = (GLfloat) ypos;
		GLfloat sensitivity = 0.10f;
		xoffset *= sensitivity;
		yoffset *= sensitivity;
		yaw += xoffset;
		pitch += yoffset;
		if (pitch > 89.0f) pitch = 89.0f;
		if (pitch < -89.0f) pitch = -89.0f;
		glm::vec3 front;
		front.x = cos(glm::radians(pitch)) * cos(glm::radians(yaw));
		front.y = sin(glm::radians(pitch));
		front.z = cos(glm::radians(pitch)) * sin(glm::radians(yaw));
		cameraFront = glm::normalize(front);
	}
	void start() {
		GLFWApplication::start();
	}
	~AGLTest() {
		delete boxes;
		delete sprites;
	}
	GLfloat getMix() { return mix; }
	GLfloat mix = 0.0f;
	glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 3.0f);
	glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f);
	glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f);
	GLfloat deltaTime = 0.0f;
	GLfloat lastFrame = 0.0f;
	GLfloat lastX = 400, lastY = 300;
	GLfloat yaw = 90, pitch = 0;
	bool firstMouse = true;
	GLfloat fov = 45.0f;
	Boxes* boxes;
	std::shared_ptr<agl::Texture> stex;
	agl::Texture* ptex;
	agl::Sprite2D* sprites;
	int frame = 0;
	void setDigit(int i, int v) {
		agl::Sprite2DInfo* spr = sprites->getLoc(3 + i);
		spr->source.left = DIGIT_BASEX + (4 + v) * DIGIT_WIDTH;
		spr->source.right = DIGIT_BASEX + (5 + v) * DIGIT_WIDTH;
	}
};

Boxes::Boxes(AGLTest* a) {
	app = a;
	setUp();
}
void Boxes::setUp() {
	container = new agl::Texture("textures/container.jpg");
	awesome = new agl::Texture("textures/awesomeface.png");
	vbo = new agl::VBO();
	ebo = new agl::EBO();
	agl::Shader* vertexShader = agl::openShaderFromFile("shader/vertex.glsl", GL_VERTEX_SHADER);
	agl::Shader* fragmentShader = agl::openShaderFromFile("shader/fragment.glsl", GL_FRAGMENT_SHADER);
	program = new agl::ShaderProgram();
	program->attach(*vertexShader);
	program->attach(*fragmentShader);
	program->link();
	program->use();
	delete vertexShader;
	delete fragmentShader;
	vao = new agl::VAO();
	vao->setActive();
	vbo->feedData(sizeof(vertices), vertices, GL_STATIC_DRAW);
	ebo->feedData(sizeof(indices), indices, GL_STATIC_DRAW);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*) 0);
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*) (3 * sizeof(GLfloat)));
	glEnableVertexAttribArray(1);
}
void Boxes::tick() {
	vao->setActive();
	program->use();
	glEnable(GL_DEPTH_TEST);
	container->bindTo(0);
	SETUNSP(*program, 1i, "ourTexture", 0);
	awesome->bindTo(1);
	SETUNSP(*program, 1i, "ourTexture2", 1);
	SETUNSP(*program, 1f, "m", app->mix);
	GLfloat radius = 10.0f;
	GLfloat camX = (GLfloat) sin(glfwGetTime()) * radius;
	GLfloat camZ = (GLfloat) cos(glfwGetTime()) * radius;
	glm::mat4 view;
	view = glm::lookAt(
		app->cameraPos, // position
		app->cameraPos + app->cameraFront, // target
		app->cameraUp); // up
	glm::mat4 projection;
	GLfloat aspect = ((GLfloat) app->getWidth()) / app->getHeight();
	projection = glm::perspective(glm::radians(app->fov), aspect, 0.1f, 100.0f);
	for (int i = 0; i < 10; ++i) {
		glm::mat4 model;
		model = glm::translate(model, cubePositions[i]);
		model = glm::rotate(model, glm::radians((GLfloat) ((i % 3 == 0 ? glfwGetTime() * 50.0f : 0) + i * 20.0f)), glm::vec3(0.5f, 1.0f, 0.0f));
		SETUNSPM(*program, 4fv, "model", glm::value_ptr(model));
		SETUNSPM(*program, 4fv, "view", glm::value_ptr(view));
		SETUNSPM(*program, 4fv, "projection", glm::value_ptr(projection));
		glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
	}
}

int main(int argc, char** argv) {
	try {
		// Kriët ė test wýndö
		AGLTest* a = new AGLTest(800, 600, 0, 0, u8"テスト");
		a->start();
	} catch (char* s) {
		std::cout << u8"An error has Okuued!\n\n" << s << u8"\n\n";
		getchar();
	}
}<commit_msg>Disable blend when rendering crates<commit_after>// GLEW
#define GLEW_STATIC
#include <GL/glew.h>
// GLFW
#include <GLFW/glfw3.h>
// SOIL
#include <SOIL.h>
// GLM
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

#include "Test.h"
#include "GLFWApplication.h"
#include "Renderable.h"
#include "Texture.h"
#include "VAO.h"
#include "VBO.h"
#include "EBO.h"
#include "Shader.h"
#include "ShaderProgram.h"
#include "Sprite2D.h"

// Others
#include <iostream>
#include <memory>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cmath>

#ifdef _MSC_VER
#pragma warning(disable: 4099)
#endif

class AGLTest;

class Boxes : agl::Renderable {
public:
	Boxes(AGLTest* a);
	void setUp();
	void tearDown() {
		delete container;
		delete awesome; // aww
		delete vbo;
		delete ebo;
		delete vao;
		delete program;
	}
	void tick();
	void update() {
	}
private:
	agl::Texture* container;
	agl::Texture* awesome;
	agl::VBO* vbo;
	agl::EBO* ebo;
	agl::VAO* vao;
	agl::ShaderProgram* program;
	AGLTest* app;
};

#define DIGIT_WIDTH 14.8f
#define DIGIT_HEIGHT 18
#define DIGIT_BASEX 16
#define DIGIT_BASEY 230

class AGLTest : public agl::GLFWApplication {
public:
	using agl::GLFWApplication::GLFWApplication;
	void initialize() {
		std::cout << "hi\n";
		boxes = new Boxes(this);
		ptex = new agl::Texture("textures/fuckyou.png");
		stex = std::make_shared<agl::Texture>(*ptex);
		sprites = new agl::Sprite2D(stex);
		sprites->setApp(this);
		sprites->addSprite({
			{0, 448, 512, 512},
			{0, 0, 512, 64}
		});
		sprites->addSprite({
			{DIGIT_BASEX, DIGIT_BASEY, DIGIT_BASEX + 4 * DIGIT_WIDTH, DIGIT_BASEY + DIGIT_HEIGHT},
			{50, 500, 50 + 4 * DIGIT_WIDTH, 500 + DIGIT_HEIGHT}
		});
		sprites->addSprite({
			{ DIGIT_BASEX + 14 * DIGIT_WIDTH, DIGIT_BASEY, DIGIT_BASEX + 15 * DIGIT_WIDTH, DIGIT_BASEY + DIGIT_HEIGHT },
			{50 + 6 * DIGIT_WIDTH, 500, 50 + 7 * DIGIT_WIDTH, 500 + DIGIT_HEIGHT}
		});
		for (int i = 0; i < 4; ++i) {
			GLfloat x = 50 + (4 + i + (i >= 2)) * DIGIT_WIDTH;
			sprites->addSprite({
				{0, DIGIT_BASEY, 0, DIGIT_BASEY + DIGIT_HEIGHT},
				{x, 500, x + DIGIT_WIDTH, 500 + DIGIT_HEIGHT}
			});
		}
		sprites->setUp();
	}
	bool ff = true;
	void tick() {
		glClearColor(0.5f, 0.7f, 1.0f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		++frame;
		int which = (frame >> 6) & 3;
		sprites->getLoc(0)->source.top = (GLfloat) (448 - (which << 6));
		sprites->getLoc(0)->source.bottom = (GLfloat) (512 - (which << 6));
		int rfps = (int) (getRollingFPS() * 100);
		for (int i = 3; i >= 0; --i) {
			setDigit(i, rfps % 10);
			rfps /= 10;
		}
		sprites->update();
		boxes->tick();
		sprites->tick();
		char* ctitle = new char[256];
		snprintf(ctitle, 255, "TestApp @ GL %s | FPS: %lf", glGetString(GL_VERSION), getRollingFPS());
		glfwSetWindowTitle(underlying(), ctitle);
	}
	void readKeys() {
		// Test if window should close
		if (testKey(GLFW_KEY_ESCAPE))
			glfwSetWindowShouldClose(underlying(), GL_TRUE);
		// Camera controls
		GLfloat cameraSpeed = 5.0f * (GLfloat) getDelta();
		if (testKey(GLFW_KEY_W))
			cameraPos += cameraSpeed * cameraFront;
		if (testKey(GLFW_KEY_S))
			cameraPos -= cameraSpeed * cameraFront;
		if (testKey(GLFW_KEY_A))
			cameraPos -= glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;
		if (testKey(GLFW_KEY_D))
			cameraPos += glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;
		// Slider controls
		if (testKey(GLFW_KEY_UP)) mix += 0.005f;
		if (testKey(GLFW_KEY_DOWN)) mix -= 0.005f;
	}
	void onMouse(double xpos, double ypos) {
		if (firstMouse) {
			lastX = (GLfloat) xpos;
			lastY = (GLfloat) ypos;
			firstMouse = false;
		}
		GLfloat xoffset = (GLfloat) xpos - lastX;
		GLfloat yoffset = lastY - (GLfloat) ypos;
		lastX = (GLfloat) xpos;
		lastY = (GLfloat) ypos;
		GLfloat sensitivity = 0.10f;
		xoffset *= sensitivity;
		yoffset *= sensitivity;
		yaw += xoffset;
		pitch += yoffset;
		if (pitch > 89.0f) pitch = 89.0f;
		if (pitch < -89.0f) pitch = -89.0f;
		glm::vec3 front;
		front.x = cos(glm::radians(pitch)) * cos(glm::radians(yaw));
		front.y = sin(glm::radians(pitch));
		front.z = cos(glm::radians(pitch)) * sin(glm::radians(yaw));
		cameraFront = glm::normalize(front);
	}
	void start() {
		GLFWApplication::start();
	}
	~AGLTest() {
		delete boxes;
		delete sprites;
	}
	GLfloat getMix() { return mix; }
	GLfloat mix = 0.0f;
	glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 3.0f);
	glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f);
	glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f);
	GLfloat deltaTime = 0.0f;
	GLfloat lastFrame = 0.0f;
	GLfloat lastX = 400, lastY = 300;
	GLfloat yaw = 90, pitch = 0;
	bool firstMouse = true;
	GLfloat fov = 45.0f;
	Boxes* boxes;
	std::shared_ptr<agl::Texture> stex;
	agl::Texture* ptex;
	agl::Sprite2D* sprites;
	int frame = 0;
	void setDigit(int i, int v) {
		agl::Sprite2DInfo* spr = sprites->getLoc(3 + i);
		spr->source.left = DIGIT_BASEX + (4 + v) * DIGIT_WIDTH;
		spr->source.right = DIGIT_BASEX + (5 + v) * DIGIT_WIDTH;
	}
};

Boxes::Boxes(AGLTest* a) {
	app = a;
	setUp();
}
void Boxes::setUp() {
	container = new agl::Texture("textures/container.jpg");
	awesome = new agl::Texture("textures/awesomeface.png");
	vbo = new agl::VBO();
	ebo = new agl::EBO();
	agl::Shader* vertexShader = agl::openShaderFromFile("shader/vertex.glsl", GL_VERTEX_SHADER);
	agl::Shader* fragmentShader = agl::openShaderFromFile("shader/fragment.glsl", GL_FRAGMENT_SHADER);
	program = new agl::ShaderProgram();
	program->attach(*vertexShader);
	program->attach(*fragmentShader);
	program->link();
	program->use();
	delete vertexShader;
	delete fragmentShader;
	vao = new agl::VAO();
	vao->setActive();
	vbo->feedData(sizeof(vertices), vertices, GL_STATIC_DRAW);
	ebo->feedData(sizeof(indices), indices, GL_STATIC_DRAW);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*) 0);
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*) (3 * sizeof(GLfloat)));
	glEnableVertexAttribArray(1);
}
void Boxes::tick() {
	glDisable(GL_BLEND);
	vao->setActive();
	program->use();
	glEnable(GL_DEPTH_TEST);
	container->bindTo(0);
	SETUNSP(*program, 1i, "ourTexture", 0);
	awesome->bindTo(1);
	SETUNSP(*program, 1i, "ourTexture2", 1);
	SETUNSP(*program, 1f, "m", app->mix);
	GLfloat radius = 10.0f;
	GLfloat camX = (GLfloat) sin(glfwGetTime()) * radius;
	GLfloat camZ = (GLfloat) cos(glfwGetTime()) * radius;
	glm::mat4 view;
	view = glm::lookAt(
		app->cameraPos, // position
		app->cameraPos + app->cameraFront, // target
		app->cameraUp); // up
	glm::mat4 projection;
	GLfloat aspect = ((GLfloat) app->getWidth()) / app->getHeight();
	projection = glm::perspective(glm::radians(app->fov), aspect, 0.1f, 100.0f);
	for (int i = 0; i < 10; ++i) {
		glm::mat4 model;
		model = glm::translate(model, cubePositions[i]);
		model = glm::rotate(model, glm::radians((GLfloat) ((i % 3 == 0 ? glfwGetTime() * 50.0f : 0) + i * 20.0f)), glm::vec3(0.5f, 1.0f, 0.0f));
		SETUNSPM(*program, 4fv, "model", glm::value_ptr(model));
		SETUNSPM(*program, 4fv, "view", glm::value_ptr(view));
		SETUNSPM(*program, 4fv, "projection", glm::value_ptr(projection));
		glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
	}
}

int main(int argc, char** argv) {
	try {
		// Kriët ė test wýndö
		AGLTest* a = new AGLTest(800, 600, 0, 0, u8"AGL Test App");
		a->start();
	} catch (char* s) {
		std::cout << u8"An error has Okuued!\n\n" << s << u8"\n\n";
		getchar();
	}
}<|endoftext|>


<commit_before>// Copyright (c) 2014 The Bitcoin developers
// Copyright (c) 2017-2018 The PIVX developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "base58.h"

#include "hash.h"
#include "uint256.h"

#include <assert.h>
#include <boost/variant/apply_visitor.hpp>
#include <boost/variant/static_visitor.hpp>
#include <sstream>
#include <stdint.h>
#include <string.h>
#include <string>
#include <vector>

/** All alphanumeric characters except for "0", "I", "O", and "l" */
static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";

bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch)
{
    // Skip leading spaces.
    while (*psz && isspace(*psz))
        psz++;
    // Skip and count leading '1's.
    int zeroes = 0;
    while (*psz == '1') {
        zeroes++;
        psz++;
    }
    // Allocate enough space in big-endian base256 representation.
    std::vector<unsigned char> b256(strlen(psz) * 733 / 1000 + 1); // log(58) / log(256), rounded up.
    // Process the characters.
    while (*psz && !isspace(*psz)) {
        // Decode base58 character
        const char* ch = strchr(pszBase58, *psz);
        if (ch == NULL)
            return false;
        // Apply "b256 = b256 * 58 + ch".
        int carry = ch - pszBase58;
        for (std::vector<unsigned char>::reverse_iterator it = b256.rbegin(); it != b256.rend(); it++) {
            carry += 58 * (*it);
            *it = carry % 256;
            carry /= 256;
        }
        assert(carry == 0);
        psz++;
    }
    // Skip trailing spaces.
    while (isspace(*psz))
        psz++;
    if (*psz != 0)
        return false;
    // Skip leading zeroes in b256.
    std::vector<unsigned char>::iterator it = b256.begin();
    while (it != b256.end() && *it == 0)
        it++;
    // Copy result into output vector.
    vch.reserve(zeroes + (b256.end() - it));
    vch.assign(zeroes, 0x00);
    while (it != b256.end())
        vch.push_back(*(it++));
    return true;
}

std::string DecodeBase58(const char* psz)
{
    std::vector<unsigned char> vch;
    DecodeBase58(psz, vch);
    std::stringstream ss;
    ss << std::hex;

    for (unsigned int i = 0; i < vch.size(); i++) {
        unsigned char* c = &vch[i];
        ss << std::setw(2) << std::setfill('0') << (int)c[0];
    }

    return ss.str();
}

std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend)
{
    // Skip & count leading zeroes.
    int zeroes = 0;
    while (pbegin != pend && *pbegin == 0) {
        pbegin++;
        zeroes++;
    }
    // Allocate enough space in big-endian base58 representation.
    std::vector<unsigned char> b58((pend - pbegin) * 138 / 100 + 1); // log(256) / log(58), rounded up.
    // Process the bytes.
    while (pbegin != pend) {
        int carry = *pbegin;
        // Apply "b58 = b58 * 256 + ch".
        for (std::vector<unsigned char>::reverse_iterator it = b58.rbegin(); it != b58.rend(); it++) {
            carry += 256 * (*it);
            *it = carry % 58;
            carry /= 58;
        }
        assert(carry == 0);
        pbegin++;
    }
    // Skip leading zeroes in base58 result.
    std::vector<unsigned char>::iterator it = b58.begin();
    while (it != b58.end() && *it == 0)
        it++;
    // Translate the result into a string.
    std::string str;
    str.reserve(zeroes + (b58.end() - it));
    str.assign(zeroes, '1');
    while (it != b58.end())
        str += pszBase58[*(it++)];
    return str;
}

std::string EncodeBase58(const std::vector<unsigned char>& vch)
{
    return EncodeBase58(&vch[0], &vch[0] + vch.size());
}

bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet)
{
    return DecodeBase58(str.c_str(), vchRet);
}

std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn)
{
    // add 4-byte hash check to the end
    std::vector<unsigned char> vch(vchIn);
    uint256 hash = Hash(vch.begin(), vch.end());
    vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4);
    return EncodeBase58(vch);
}

bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet)
{
    if (!DecodeBase58(psz, vchRet) ||
        (vchRet.size() < 4)) {
        vchRet.clear();
        return false;
    }
    // re-calculate the checksum, insure it matches the included 4-byte checksum
    uint256 hash = Hash(vchRet.begin(), vchRet.end() - 4);
    if (memcmp(&hash, &vchRet.end()[-4], 4) != 0) {
        vchRet.clear();
        return false;
    }
    vchRet.resize(vchRet.size() - 4);
    return true;
}

bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet)
{
    return DecodeBase58Check(str.c_str(), vchRet);
}

CBase58Data::CBase58Data()
{
    vchVersion.clear();
    vchData.clear();
}

void CBase58Data::SetData(const std::vector<unsigned char>& vchVersionIn, const void* pdata, size_t nSize)
{
    vchVersion = vchVersionIn;
    vchData.resize(nSize);
    if (!vchData.empty())
        memcpy(&vchData[0], pdata, nSize);
}

void CBase58Data::SetData(const std::vector<unsigned char>& vchVersionIn, const unsigned char* pbegin, const unsigned char* pend)
{
    SetData(vchVersionIn, (void*)pbegin, pend - pbegin);
}

bool CBase58Data::SetString(const char* psz, unsigned int nVersionBytes)
{
    std::vector<unsigned char> vchTemp;
    bool rc58 = DecodeBase58Check(psz, vchTemp);
    if ((!rc58) || (vchTemp.size() < nVersionBytes)) {
        vchData.clear();
        vchVersion.clear();
        return false;
    }
    vchVersion.assign(vchTemp.begin(), vchTemp.begin() + nVersionBytes);
    vchData.resize(vchTemp.size() - nVersionBytes);
    if (!vchData.empty())
        memcpy(&vchData[0], &vchTemp[nVersionBytes], vchData.size());
    memory_cleanse(&vchTemp[0], vchData.size());
    return true;
}

bool CBase58Data::SetString(const std::string& str)
{
    return SetString(str.c_str());
}

std::string CBase58Data::ToString() const
{
    std::vector<unsigned char> vch = vchVersion;
    vch.insert(vch.end(), vchData.begin(), vchData.end());
    return EncodeBase58Check(vch);
}

int CBase58Data::CompareTo(const CBase58Data& b58) const
{
    if (vchVersion < b58.vchVersion)
        return -1;
    if (vchVersion > b58.vchVersion)
        return 1;
    if (vchData < b58.vchData)
        return -1;
    if (vchData > b58.vchData)
        return 1;
    return 0;
}

namespace
{
class CBitcoinAddressVisitor : public boost::static_visitor<bool>
{
private:
    CBitcoinAddress* addr;
    CChainParams::Base58Type type;

public:
    CBitcoinAddressVisitor(CBitcoinAddress* addrIn,
            const CChainParams::Base58Type addrType = CChainParams::PUBKEY_ADDRESS) :
        addr(addrIn),
        type(addrType){};

    bool operator()(const CKeyID& id) const { return addr->Set(id, type); }
    bool operator()(const CScriptID& id) const { return addr->Set(id); }
    bool operator()(const CNoDestination& no) const { return false; }
};

} // anon namespace

bool CBitcoinAddress::Set(const CKeyID& id, const CChainParams::Base58Type addrType)
{
    SetData(Params().Base58Prefix(addrType), &id, 20);
    return true;
}

bool CBitcoinAddress::Set(const CScriptID& id)
{
    SetData(Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS), &id, 20);
    return true;
}

bool CBitcoinAddress::Set(const CTxDestination& dest, const CChainParams::Base58Type addrType)
{
    return boost::apply_visitor(CBitcoinAddressVisitor(this, addrType), dest);
}

bool CBitcoinAddress::IsValid() const
{
    return IsValid(Params());
}

bool CBitcoinAddress::IsValid(const CChainParams& params) const
{
    bool fCorrectSize = vchData.size() == 20;
    bool fKnownVersion = vchVersion == params.Base58Prefix(CChainParams::PUBKEY_ADDRESS) ||
                         vchVersion == params.Base58Prefix(CChainParams::SCRIPT_ADDRESS) ||
                         vchVersion == params.Base58Prefix(CChainParams::STAKING_ADDRESS);
    return fCorrectSize && fKnownVersion;
}

CTxDestination CBitcoinAddress::Get() const
{
    if (!IsValid())
        return CNoDestination();
    uint160 id;
    memcpy(&id, &vchData[0], 20);
    if (vchVersion == Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS) ||
            vchVersion == Params().Base58Prefix(CChainParams::STAKING_ADDRESS))
        return CKeyID(id);
    else if (vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS))
        return CScriptID(id);
    else
        return CNoDestination();
}

bool CBitcoinAddress::GetKeyID(CKeyID& keyID) const
{
    if (!IsValid() ||
            (vchVersion != Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS) &&
            vchVersion != Params().Base58Prefix(CChainParams::STAKING_ADDRESS)))
        return false;
    uint160 id;
    memcpy(&id, &vchData[0], 20);
    keyID = CKeyID(id);
    return true;
}

bool CBitcoinAddress::IsScript() const
{
    bool fCorrectSize = vchData.size() == 20;
    return fCorrectSize && vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS);
}

bool CBitcoinAddress::IsStakingAddress() const
{
    bool fCorrectSize = vchData.size() == 20;
    return fCorrectSize && vchVersion == Params().Base58Prefix(CChainParams::STAKING_ADDRESS);
}

void CBitcoinSecret::SetKey(const CKey& vchSecret)
{
    assert(vchSecret.IsValid());
    SetData(Params().Base58Prefix(CChainParams::SECRET_KEY), vchSecret.begin(), vchSecret.size());
    if (vchSecret.IsCompressed())
        vchData.push_back(1);
}

CKey CBitcoinSecret::GetKey()
{
    CKey ret;
    assert(vchData.size() >= 32);
    ret.Set(vchData.begin(), vchData.begin() + 32, vchData.size() > 32 && vchData[32] == 1);
    return ret;
}

bool CBitcoinSecret::IsValid() const
{
    bool fExpectedFormat = vchData.size() == 32 || (vchData.size() == 33 && vchData[32] == 1);
    bool fCorrectVersion = vchVersion == Params().Base58Prefix(CChainParams::SECRET_KEY);
    return fExpectedFormat && fCorrectVersion;
}

bool CBitcoinSecret::SetString(const char* pszSecret)
{
    return CBase58Data::SetString(pszSecret) && IsValid();
}

bool CBitcoinSecret::SetString(const std::string& strSecret)
{
    return SetString(strSecret.c_str());
}
<commit_msg>[Wallet] Base58, do not try to parse an empty string on SetString initialization.<commit_after>// Copyright (c) 2014 The Bitcoin developers
// Copyright (c) 2017-2018 The PIVX developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "base58.h"

#include "hash.h"
#include "uint256.h"

#include <assert.h>
#include <boost/variant/apply_visitor.hpp>
#include <boost/variant/static_visitor.hpp>
#include <sstream>
#include <stdint.h>
#include <string.h>
#include <string>
#include <vector>

/** All alphanumeric characters except for "0", "I", "O", and "l" */
static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";

bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch)
{
    // Skip leading spaces.
    while (*psz && isspace(*psz))
        psz++;
    // Skip and count leading '1's.
    int zeroes = 0;
    while (*psz == '1') {
        zeroes++;
        psz++;
    }
    // Allocate enough space in big-endian base256 representation.
    std::vector<unsigned char> b256(strlen(psz) * 733 / 1000 + 1); // log(58) / log(256), rounded up.
    // Process the characters.
    while (*psz && !isspace(*psz)) {
        // Decode base58 character
        const char* ch = strchr(pszBase58, *psz);
        if (ch == NULL)
            return false;
        // Apply "b256 = b256 * 58 + ch".
        int carry = ch - pszBase58;
        for (std::vector<unsigned char>::reverse_iterator it = b256.rbegin(); it != b256.rend(); it++) {
            carry += 58 * (*it);
            *it = carry % 256;
            carry /= 256;
        }
        assert(carry == 0);
        psz++;
    }
    // Skip trailing spaces.
    while (isspace(*psz))
        psz++;
    if (*psz != 0)
        return false;
    // Skip leading zeroes in b256.
    std::vector<unsigned char>::iterator it = b256.begin();
    while (it != b256.end() && *it == 0)
        it++;
    // Copy result into output vector.
    vch.reserve(zeroes + (b256.end() - it));
    vch.assign(zeroes, 0x00);
    while (it != b256.end())
        vch.push_back(*(it++));
    return true;
}

std::string DecodeBase58(const char* psz)
{
    std::vector<unsigned char> vch;
    DecodeBase58(psz, vch);
    std::stringstream ss;
    ss << std::hex;

    for (unsigned int i = 0; i < vch.size(); i++) {
        unsigned char* c = &vch[i];
        ss << std::setw(2) << std::setfill('0') << (int)c[0];
    }

    return ss.str();
}

std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend)
{
    // Skip & count leading zeroes.
    int zeroes = 0;
    while (pbegin != pend && *pbegin == 0) {
        pbegin++;
        zeroes++;
    }
    // Allocate enough space in big-endian base58 representation.
    std::vector<unsigned char> b58((pend - pbegin) * 138 / 100 + 1); // log(256) / log(58), rounded up.
    // Process the bytes.
    while (pbegin != pend) {
        int carry = *pbegin;
        // Apply "b58 = b58 * 256 + ch".
        for (std::vector<unsigned char>::reverse_iterator it = b58.rbegin(); it != b58.rend(); it++) {
            carry += 256 * (*it);
            *it = carry % 58;
            carry /= 58;
        }
        assert(carry == 0);
        pbegin++;
    }
    // Skip leading zeroes in base58 result.
    std::vector<unsigned char>::iterator it = b58.begin();
    while (it != b58.end() && *it == 0)
        it++;
    // Translate the result into a string.
    std::string str;
    str.reserve(zeroes + (b58.end() - it));
    str.assign(zeroes, '1');
    while (it != b58.end())
        str += pszBase58[*(it++)];
    return str;
}

std::string EncodeBase58(const std::vector<unsigned char>& vch)
{
    return EncodeBase58(&vch[0], &vch[0] + vch.size());
}

bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet)
{
    return DecodeBase58(str.c_str(), vchRet);
}

std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn)
{
    // add 4-byte hash check to the end
    std::vector<unsigned char> vch(vchIn);
    uint256 hash = Hash(vch.begin(), vch.end());
    vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4);
    return EncodeBase58(vch);
}

bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet)
{
    if (!DecodeBase58(psz, vchRet) ||
        (vchRet.size() < 4)) {
        vchRet.clear();
        return false;
    }
    // re-calculate the checksum, insure it matches the included 4-byte checksum
    uint256 hash = Hash(vchRet.begin(), vchRet.end() - 4);
    if (memcmp(&hash, &vchRet.end()[-4], 4) != 0) {
        vchRet.clear();
        return false;
    }
    vchRet.resize(vchRet.size() - 4);
    return true;
}

bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet)
{
    return DecodeBase58Check(str.c_str(), vchRet);
}

CBase58Data::CBase58Data()
{
    vchVersion.clear();
    vchData.clear();
}

void CBase58Data::SetData(const std::vector<unsigned char>& vchVersionIn, const void* pdata, size_t nSize)
{
    vchVersion = vchVersionIn;
    vchData.resize(nSize);
    if (!vchData.empty())
        memcpy(&vchData[0], pdata, nSize);
}

void CBase58Data::SetData(const std::vector<unsigned char>& vchVersionIn, const unsigned char* pbegin, const unsigned char* pend)
{
    SetData(vchVersionIn, (void*)pbegin, pend - pbegin);
}

bool CBase58Data::SetString(const char* psz, unsigned int nVersionBytes)
{
    std::vector<unsigned char> vchTemp;
    bool rc58 = DecodeBase58Check(psz, vchTemp);
    if ((!rc58) || (vchTemp.size() < nVersionBytes)) {
        vchData.clear();
        vchVersion.clear();
        return false;
    }
    vchVersion.assign(vchTemp.begin(), vchTemp.begin() + nVersionBytes);
    vchData.resize(vchTemp.size() - nVersionBytes);
    if (!vchData.empty())
        memcpy(&vchData[0], &vchTemp[nVersionBytes], vchData.size());
    memory_cleanse(&vchTemp[0], vchData.size());
    return true;
}

bool CBase58Data::SetString(const std::string& str)
{
    if (str.empty())
        return false;
    return SetString(str.c_str());
}

std::string CBase58Data::ToString() const
{
    std::vector<unsigned char> vch = vchVersion;
    vch.insert(vch.end(), vchData.begin(), vchData.end());
    return EncodeBase58Check(vch);
}

int CBase58Data::CompareTo(const CBase58Data& b58) const
{
    if (vchVersion < b58.vchVersion)
        return -1;
    if (vchVersion > b58.vchVersion)
        return 1;
    if (vchData < b58.vchData)
        return -1;
    if (vchData > b58.vchData)
        return 1;
    return 0;
}

namespace
{
class CBitcoinAddressVisitor : public boost::static_visitor<bool>
{
private:
    CBitcoinAddress* addr;
    CChainParams::Base58Type type;

public:
    CBitcoinAddressVisitor(CBitcoinAddress* addrIn,
            const CChainParams::Base58Type addrType = CChainParams::PUBKEY_ADDRESS) :
        addr(addrIn),
        type(addrType){};

    bool operator()(const CKeyID& id) const { return addr->Set(id, type); }
    bool operator()(const CScriptID& id) const { return addr->Set(id); }
    bool operator()(const CNoDestination& no) const { return false; }
};

} // anon namespace

bool CBitcoinAddress::Set(const CKeyID& id, const CChainParams::Base58Type addrType)
{
    SetData(Params().Base58Prefix(addrType), &id, 20);
    return true;
}

bool CBitcoinAddress::Set(const CScriptID& id)
{
    SetData(Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS), &id, 20);
    return true;
}

bool CBitcoinAddress::Set(const CTxDestination& dest, const CChainParams::Base58Type addrType)
{
    return boost::apply_visitor(CBitcoinAddressVisitor(this, addrType), dest);
}

bool CBitcoinAddress::IsValid() const
{
    return IsValid(Params());
}

bool CBitcoinAddress::IsValid(const CChainParams& params) const
{
    bool fCorrectSize = vchData.size() == 20;
    bool fKnownVersion = vchVersion == params.Base58Prefix(CChainParams::PUBKEY_ADDRESS) ||
                         vchVersion == params.Base58Prefix(CChainParams::SCRIPT_ADDRESS) ||
                         vchVersion == params.Base58Prefix(CChainParams::STAKING_ADDRESS);
    return fCorrectSize && fKnownVersion;
}

CTxDestination CBitcoinAddress::Get() const
{
    if (!IsValid())
        return CNoDestination();
    uint160 id;
    memcpy(&id, &vchData[0], 20);
    if (vchVersion == Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS) ||
            vchVersion == Params().Base58Prefix(CChainParams::STAKING_ADDRESS))
        return CKeyID(id);
    else if (vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS))
        return CScriptID(id);
    else
        return CNoDestination();
}

bool CBitcoinAddress::GetKeyID(CKeyID& keyID) const
{
    if (!IsValid() ||
            (vchVersion != Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS) &&
            vchVersion != Params().Base58Prefix(CChainParams::STAKING_ADDRESS)))
        return false;
    uint160 id;
    memcpy(&id, &vchData[0], 20);
    keyID = CKeyID(id);
    return true;
}

bool CBitcoinAddress::IsScript() const
{
    bool fCorrectSize = vchData.size() == 20;
    return fCorrectSize && vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS);
}

bool CBitcoinAddress::IsStakingAddress() const
{
    bool fCorrectSize = vchData.size() == 20;
    return fCorrectSize && vchVersion == Params().Base58Prefix(CChainParams::STAKING_ADDRESS);
}

void CBitcoinSecret::SetKey(const CKey& vchSecret)
{
    assert(vchSecret.IsValid());
    SetData(Params().Base58Prefix(CChainParams::SECRET_KEY), vchSecret.begin(), vchSecret.size());
    if (vchSecret.IsCompressed())
        vchData.push_back(1);
}

CKey CBitcoinSecret::GetKey()
{
    CKey ret;
    assert(vchData.size() >= 32);
    ret.Set(vchData.begin(), vchData.begin() + 32, vchData.size() > 32 && vchData[32] == 1);
    return ret;
}

bool CBitcoinSecret::IsValid() const
{
    bool fExpectedFormat = vchData.size() == 32 || (vchData.size() == 33 && vchData[32] == 1);
    bool fCorrectVersion = vchVersion == Params().Base58Prefix(CChainParams::SECRET_KEY);
    return fExpectedFormat && fCorrectVersion;
}

bool CBitcoinSecret::SetString(const char* pszSecret)
{
    return CBase58Data::SetString(pszSecret) && IsValid();
}

bool CBitcoinSecret::SetString(const std::string& strSecret)
{
    return SetString(strSecret.c_str());
}
<|endoftext|>


<commit_before>#ifndef SILICIUM_SILICIUM_CONFIG_HPP
#define SILICIUM_SILICIUM_CONFIG_HPP

#include <memory>
#include <stdexcept>
#include <boost/config.hpp>
#include <boost/version.hpp>

#ifdef _MSC_VER
//avoid useless warning C4127 (conditional expression is constant)
#	define SILICIUM_FALSE (!"")
#else
#	define SILICIUM_FALSE false
#endif

#ifdef _MSC_VER
#	define SILICIUM_COMPILER_CXX11 1
#	define SILICIUM_COMPILER_CXX14 1
#elif __cplusplus > 201103L
#	define SILICIUM_COMPILER_CXX11 1
#	define SILICIUM_COMPILER_CXX14 1
#elif __cplusplus >= 201103L
#	define SILICIUM_COMPILER_CXX11 1
#	define SILICIUM_COMPILER_CXX14 1 /* actually 0, assume 1 for now */
#else
#	define SILICIUM_COMPILER_CXX11 0
#	define SILICIUM_COMPILER_CXX14 0
#endif

#ifdef NDEBUG
#	ifdef _MSC_VER
#		define SILICIUM_UNREACHABLE() __assume(false)
#	else
#		define SILICIUM_UNREACHABLE() __builtin_unreachable()
#	endif
#else
#	define SILICIUM_UNREACHABLE() do { throw ::std::logic_error("unreachable " __FILE__ ":" BOOST_STRINGIZE(__LINE__)); } while(SILICIUM_FALSE)
#endif

#if (defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 408)) || defined(__clang__)
#	define SILICIUM_COMPILER_GENERATES_MOVES 1
#else
#	define SILICIUM_COMPILER_GENERATES_MOVES 0
#endif

#if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 408) || defined(__clang__)
#	define SILICIUM_COMPILER_HAS_WORKING_NOEXCEPT 1
#else
#	define SILICIUM_COMPILER_HAS_WORKING_NOEXCEPT 0
#endif

#ifdef _MSC_VER
#	define SILICIUM_NORETURN __declspec(noreturn)
#else
//	GCC
#	define SILICIUM_NORETURN __attribute__ ((__noreturn__))
#endif

#if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 408) || defined(__clang__)
#	define SILICIUM_COMPILER_HAS_RVALUE_THIS_QUALIFIER 1
#else
#	define SILICIUM_COMPILER_HAS_RVALUE_THIS_QUALIFIER 0
#endif

#if (defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 408) && SILICIUM_COMPILER_CXX14) || defined(__clang__)
#	define SILICIUM_COMPILER_HAS_AUTO_RETURN_TYPE 1
#else
#	define SILICIUM_COMPILER_HAS_AUTO_RETURN_TYPE 0
#endif

#if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 408) || defined(__clang__)
#	define SILICIUM_COMPILER_HAS_EXTENDED_CAPTURE 1
#else
#	define SILICIUM_COMPILER_HAS_EXTENDED_CAPTURE 0
#endif

#if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 407) || defined(__clang__) || defined(_MSC_VER)
#	define SILICIUM_COMPILER_HAS_VARIADIC_PACK_EXPANSION 1
#else
#	define SILICIUM_COMPILER_HAS_VARIADIC_PACK_EXPANSION 0
#endif

#if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 407) || defined(__clang__) || defined(_MSC_VER)
#	define SILICIUM_COMPILER_HAS_USING 1
#else
#	define SILICIUM_COMPILER_HAS_USING 0
#endif

#ifdef BOOST_DELETED_FUNCTION
#	define SILICIUM_DELETED_FUNCTION BOOST_DELETED_FUNCTION
#else
#	define SILICIUM_DELETED_FUNCTION(f) private: f;
#endif

namespace Si
{
	struct nothing
	{
		BOOST_CONSTEXPR nothing() BOOST_NOEXCEPT
		{
		}
	};

	template <class T, class ...Args>
	auto make_unique(Args &&...args) -> std::unique_ptr<T>
	{
		return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
	}

#if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 407) || defined(__clang__)
#define SILICIUM_HAS_PROPER_COPY_TRAITS 1
}
#include <type_traits>
namespace Si
{
	using std::is_copy_constructible;
	using std::is_copy_assignable;
#elif BOOST_VERSION >= 105500 //1.55
#define SILICIUM_HAS_PROPER_COPY_TRAITS 1
}
#include <boost/type_traits/is_copy_constructible.hpp>
#include <boost/type_traits/is_convertible.hpp>
namespace Si
{
	using boost::is_copy_constructible;
	template <class T>
	struct is_copy_assignable : std::true_type
	{
	};
	template <class T, class D>
	struct is_copy_assignable<std::unique_ptr<T, D>> : std::false_type
	{
	};
#else
#define SILICIUM_HAS_PROPER_COPY_TRAITS 0
	template <class T>
	struct is_copy_constructible : std::true_type
	{
	};
	template <class T>
	struct is_copy_assignable : std::true_type
	{
	};
#endif

#if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 407) || defined(__clang__) || defined(_MSC_VER)
}
#include <type_traits>
namespace Si
{
	using std::is_default_constructible;
	using std::is_move_assignable;
#else
	template <class T>
	struct is_default_constructible : std::false_type
	{
	};
	template <class T>
	struct is_move_assignable : std::false_type
	{
	};
#endif
}

#endif
<commit_msg>avoid VC++ unreachable code warning<commit_after>#ifndef SILICIUM_SILICIUM_CONFIG_HPP
#define SILICIUM_SILICIUM_CONFIG_HPP

#include <memory>
#include <stdexcept>
#include <boost/config.hpp>
#include <boost/version.hpp>

#ifdef _MSC_VER
#	define SILICIUM_COMPILER_CXX11 1
#	define SILICIUM_COMPILER_CXX14 1
#elif __cplusplus > 201103L
#	define SILICIUM_COMPILER_CXX11 1
#	define SILICIUM_COMPILER_CXX14 1
#elif __cplusplus >= 201103L
#	define SILICIUM_COMPILER_CXX11 1
#	define SILICIUM_COMPILER_CXX14 1 /* actually 0, assume 1 for now */
#else
#	define SILICIUM_COMPILER_CXX11 0
#	define SILICIUM_COMPILER_CXX14 0
#endif

#ifdef NDEBUG
#	ifdef _MSC_VER
#		define SILICIUM_UNREACHABLE() __assume(false)
#	else
#		define SILICIUM_UNREACHABLE() __builtin_unreachable()
#	endif
#else
#	define SILICIUM_UNREACHABLE() throw ::std::logic_error("unreachable " __FILE__ ":" BOOST_STRINGIZE(__LINE__))
#endif

#if (defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 408)) || defined(__clang__)
#	define SILICIUM_COMPILER_GENERATES_MOVES 1
#else
#	define SILICIUM_COMPILER_GENERATES_MOVES 0
#endif

#if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 408) || defined(__clang__)
#	define SILICIUM_COMPILER_HAS_WORKING_NOEXCEPT 1
#else
#	define SILICIUM_COMPILER_HAS_WORKING_NOEXCEPT 0
#endif

#ifdef _MSC_VER
#	define SILICIUM_NORETURN __declspec(noreturn)
#else
//	GCC
#	define SILICIUM_NORETURN __attribute__ ((__noreturn__))
#endif

#if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 408) || defined(__clang__)
#	define SILICIUM_COMPILER_HAS_RVALUE_THIS_QUALIFIER 1
#else
#	define SILICIUM_COMPILER_HAS_RVALUE_THIS_QUALIFIER 0
#endif

#if (defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 408) && SILICIUM_COMPILER_CXX14) || defined(__clang__)
#	define SILICIUM_COMPILER_HAS_AUTO_RETURN_TYPE 1
#else
#	define SILICIUM_COMPILER_HAS_AUTO_RETURN_TYPE 0
#endif

#if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 408) || defined(__clang__)
#	define SILICIUM_COMPILER_HAS_EXTENDED_CAPTURE 1
#else
#	define SILICIUM_COMPILER_HAS_EXTENDED_CAPTURE 0
#endif

#if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 407) || defined(__clang__) || defined(_MSC_VER)
#	define SILICIUM_COMPILER_HAS_VARIADIC_PACK_EXPANSION 1
#else
#	define SILICIUM_COMPILER_HAS_VARIADIC_PACK_EXPANSION 0
#endif

#if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 407) || defined(__clang__) || defined(_MSC_VER)
#	define SILICIUM_COMPILER_HAS_USING 1
#else
#	define SILICIUM_COMPILER_HAS_USING 0
#endif

#ifdef BOOST_DELETED_FUNCTION
#	define SILICIUM_DELETED_FUNCTION BOOST_DELETED_FUNCTION
#else
#	define SILICIUM_DELETED_FUNCTION(f) private: f;
#endif

namespace Si
{
	struct nothing
	{
		BOOST_CONSTEXPR nothing() BOOST_NOEXCEPT
		{
		}
	};

	template <class T, class ...Args>
	auto make_unique(Args &&...args) -> std::unique_ptr<T>
	{
		return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
	}

#if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 407) || defined(__clang__)
#define SILICIUM_HAS_PROPER_COPY_TRAITS 1
}
#include <type_traits>
namespace Si
{
	using std::is_copy_constructible;
	using std::is_copy_assignable;
#elif BOOST_VERSION >= 105500 //1.55
#define SILICIUM_HAS_PROPER_COPY_TRAITS 1
}
#include <boost/type_traits/is_copy_constructible.hpp>
#include <boost/type_traits/is_convertible.hpp>
namespace Si
{
	using boost::is_copy_constructible;
	template <class T>
	struct is_copy_assignable : std::true_type
	{
	};
	template <class T, class D>
	struct is_copy_assignable<std::unique_ptr<T, D>> : std::false_type
	{
	};
#else
#define SILICIUM_HAS_PROPER_COPY_TRAITS 0
	template <class T>
	struct is_copy_constructible : std::true_type
	{
	};
	template <class T>
	struct is_copy_assignable : std::true_type
	{
	};
#endif

#if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 407) || defined(__clang__) || defined(_MSC_VER)
}
#include <type_traits>
namespace Si
{
	using std::is_default_constructible;
	using std::is_move_assignable;
#else
	template <class T>
	struct is_default_constructible : std::false_type
	{
	};
	template <class T>
	struct is_move_assignable : std::false_type
	{
	};
#endif
}

#endif
<|endoftext|>


<commit_before>#include "catch.hpp"
#include "Bignum.h"

TEST_CASE("Kivetelkezeles", "[exceptions]") {

    Bignum b;
    std::stringstream ss;

    SECTION("negativ", "NotNaturalNum exceptiont kel dobnia")
    {
        CHECK_THROWS_AS(Bignum* b = new Bignum(-1235), NotNaturalNum&);
    }

    SECTION("nem szam", "NotNaturalNum exceptiont kel dobnia")
    {
        ss.str("12abe");
        CHECK_THROWS_AS(ss >> b, NotNaturalNum&);
    }

    SECTION("0-val kezd", "StartsWithZero exceptiont kel dobnia")
    {
        ss.str("01234");
        CHECK_THROWS_AS(ss >> b, StartsWithZero&);
    }
}

<commit_msg>Update exceptions.cpp<commit_after>#include "catch.hpp"
#include "Bignum.h"

TEST_CASE("Kivetelkezeles", "[exceptions]") {

    Bignum b;
    std::stringstream ss;

    SECTION("negativ", "NotNaturalNum exceptiont kel dobnia")
    {
        Bignum* b;
        CHECK_THROWS_AS(b = new Bignum(-1235), NotNaturalNum&);
    }

    SECTION("nem szam", "NotNaturalNum exceptiont kel dobnia")
    {
        ss.str("12abe");
        CHECK_THROWS_AS(ss >> b, NotNaturalNum&);
    }

    SECTION("0-val kezd", "StartsWithZero exceptiont kel dobnia")
    {
        ss.str("01234");
        CHECK_THROWS_AS(ss >> b, StartsWithZero&);
    }
}

<|endoftext|>


<commit_before>//
// Created by Piotr Jander on 27/08/2017.
//

#include <Socket.h>
#include <ClientMessage.h>
#include <netdb.h>
#include <thread>
#include <chrono>

int main(int argc, const char *argv[]) {
    Socket socket1, socket2, socket3;
    socket1.bindSocket(NULL, "8071");
    socket2.bindSocket(NULL, "8072");
    socket3.bindSocket(NULL, "8073");

    addrinfo *servinfoOther = Socket::getAddrInfo("127.0.0.1", "8070");
    const sockaddr *addr = servinfoOther->ai_addr;

    ClientMessage cm1(123, 0, 0, "");
    ClientMessage cm2(456, 0, 0, "Piotr");
    ClientMessage cm3(789, 0, 0, "Jed");

    cm1.sendto(socket1, addr);
    cm2.sendto(socket2, addr);
    cm3.sendto(socket3, addr);

//    std::this_thread::sleep_for(std::chrono::milliseconds(3000));

    ClientMessage cm4(456, 1, 0, "Piotr");
    ClientMessage cm5(789, -1, 0, "Jed");

    cm4.sendto(socket2, addr);
    cm5.sendto(socket3, addr);
}
<commit_msg>Makes a dummy client<commit_after>//
// Created by Piotr Jander on 27/08/2017.
//

#include <Socket.h>
#include <ClientMessage.h>
#include <netdb.h>
#include <thread>
#include <chrono>

int main(int argc, const char *argv[]) {
    Socket socket1, socket2, socket3;
    socket1.bindSocket(NULL, "8071");

    addrinfo *servinfoOther = Socket::getAddrInfo("127.0.0.1", "8070");
    const sockaddr *addr = servinfoOther->ai_addr;

    for (uint32_t i = 0; ; ++i) {
        ClientMessage cm(789, 1, i, "Jed");
        cm.sendto(socket1, addr);
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
    }

    ClientMessage cm3(789, 1, 0, "Jed");

    socket2.bindSocket(NULL, "8072");
    socket3.bindSocket(NULL, "8073");

    addrinfo *servinfoOther = Socket::getAddrInfo("127.0.0.1", "8070");
    const sockaddr *addr = servinfoOther->ai_addr;

    ClientMessage cm1(123, 0, 0, "");
    ClientMessage cm2(456, 0, 0, "Piotr");
    ClientMessage cm3(789, 0, 0, "Jed");

    cm1.sendto(socket1, addr);
    cm2.sendto(socket2, addr);
    cm3.sendto(socket3, addr);

//    std::this_thread::sleep_for(std::chrono::milliseconds(3000));

    ClientMessage cm4(456, 1, 0, "Piotr");
    ClientMessage cm5(789, -1, 0, "Jed");

    cm4.sendto(socket2, addr);
    cm5.sendto(socket3, addr);
}
<|endoftext|>


<commit_before>//
// Created by arssivka on 2/24/16.
//

#include <rd/hardware/TypeDefinition.h>
#include "rd/hardware/Locomotion.h"

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

rd::Locomotion::Locomotion(boost::shared_ptr<Robot> robot)
        : m_x(0.0), m_y(0.0), m_theta(0.0), m_step_count(0), m_meta_gait(new MetaGait),
          m_step_generator(new StepGenerator(robot, m_meta_gait.get())), m_joints(robot->getJoints()),
          m_clock(robot->getClock()), m_joint_keys(20), m_head_joint_keys(2), m_parameter_keys(PARAMETERS_COUNT),
          m_odometry_keys(ODOMETRY_COUNT), m_auto_apply_flag(false),
          m_auto_apply_worker(boost::bind(&rd::Locomotion::autoUpdater, this)), m_auto_update_sleep_time(0) {
    Gait default_gait(DEFAULT_GAIT);
    m_meta_gait->setStartGait(default_gait);
    m_meta_gait->setNewGaitTarget(default_gait);
    m_stance_joints_data = boost::make_shared<SensorData<double> >(*m_step_generator->getDefaultStance(DEFAULT_GAIT),
                                                                   m_clock->getTime());
    m_parameter_keys[X] = "X";
    m_parameter_keys[Y] = "Y";
    m_parameter_keys[THETA] = "THETA";
    m_parameter_keys[STEP_COUNT] = "STEP_COUNT";

    for (int i = 0; i < PARAMETERS_COUNT; ++i) {
        m_parameter_keys_map.insert(std::make_pair(m_parameter_keys[i], i));
    }

    m_odometry_keys[X_OFFSET] = "X_OFFSET";
    m_odometry_keys[Y_OFFSET] = "Y_OFFSET";
    m_odometry_keys[ROTATION] = "ROTATION";

    const StringKeyVector& keys = m_joints->getKeys();
    for (int i = 0; i < 20; ++i) m_joint_keys[i] = keys[StepGenerator::NB_WALKING_JOINTS[i]];
    m_joint_keys.push_back(keys[rd::Joints::HEAD_PITCH]);
    m_joint_keys.push_back(keys[rd::Joints::HEAD_YAW]);

    int now = m_clock->getTime();
    m_positions_data = boost::make_shared<SensorData<double> >(ValuesVector(m_joint_keys.size(), 0.0), now);
    m_hardness_data = boost::make_shared<SensorData<double> >(ValuesVector(m_joint_keys.size(), 0.0), now);
    m_step_generator->setSpeed(m_x, m_y, m_theta);
}

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

const StringKeyVector& rd::Locomotion::getParameterKeys() const {
    return m_parameter_keys;
}

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

rd::SensorData<double>::Ptr rd::Locomotion::getSpeedParameters(const StringKeyVector& keys) const {
    IntegerKeyVector keys_i(keys.size());
    for (int i = 0; i < keys.size(); ++i) {
        std::map<std::string, int>::const_iterator found = m_parameter_keys_map.find(keys[i]);
        if (found == m_parameter_keys_map.end())
            return boost::make_shared<SensorData<double> >();
        keys_i[i] = found->second;
    }
    return this->getSpeedParameters(keys_i);
}

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

rd::SensorData<double>::Ptr rd::Locomotion::getSpeedParameters(const IntegerKeyVector& keys) const {
    SensorData<double>::Ptr data = boost::make_shared<SensorData<double> >(keys.size(), m_clock->getTime());
    boost::lock_guard<boost::mutex> lock(m_access);
    for (int i = 0; i < keys.size(); ++i) {
        switch (keys[i]) {
            case X:
                data->data[i] = m_x;
                break;
            case Y:
                data->data[i] = m_y;
                break;
            case THETA:
                data->data[i] = m_theta;
                break;
            case STEP_COUNT:
                data->data[i] = m_step_count;
                break;
            default:
                return boost::make_shared<SensorData<double> >();
                break;
        }
    }
    return data;
}

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

void rd::Locomotion::setSpeedParameters(const StringKeyVector& keys, const ValuesVector& values) {
    IntegerKeyVector keys_i(keys.size());
    for (int i = 0; i < keys.size(); ++i) {
        const std::map<std::string, int>::const_iterator found = m_parameter_keys_map.find(keys[i]);
        if (found == m_parameter_keys_map.end())
            return;
        keys_i[i] = found->second;
    }
    this->setSpeedParameters(keys_i, values);
}

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

void rd::Locomotion::setSpeedParameters(const IntegerKeyVector& keys, const ValuesVector& values) {
    if (keys.empty() || keys.size() != values.size())
        return;
    boost::lock_guard<boost::mutex> lock(m_access);
    m_x = 0.0;
    m_y = 0.0;
    m_theta = 0.0;
    m_step_count = 0;
    for (int i = 0; i < keys.size(); ++i) {
        switch (keys[i]) {
            case X_OFFSET:
                m_x = values[i];
                break;
            case Y_OFFSET:
                m_y = values[i];
                break;
            case THETA:
                m_theta = values[i];
                break;
            case STEP_COUNT:
                m_step_count = (unsigned int) values[i];
                break;
            default:
                continue;
        }
    }
    if (m_step_count > 0) {
        m_step_generator->takeSteps(m_x, m_y, m_theta, m_step_count);
    } else {
        m_step_generator->setSpeed(m_x, m_y, m_theta);
    }
}

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

rd::SensorData<double>::Ptr rd::Locomotion::getOdometry() {
    boost::lock_guard<boost::mutex> lock(m_access);
    rd::SensorData<double>::Ptr data = boost::make_shared<SensorData<double> >(m_step_generator->getOdometryUpdate(), m_clock->getTime());
    data->data[1] *= -1.0; // hack!!!!!
    return data;
}

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

void rd::Locomotion::resetOdometry() {
    boost::lock_guard<boost::mutex> lock(m_access);
    m_step_generator->resetOdometry(0.0, 0.0);
}

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

void rd::Locomotion::setGaitParameters(const double stance_config[WP::LEN_STANCE_CONFIG],
                                       const double step_config[WP::LEN_STEP_CONFIG],
                                       const double zmp_config[WP::LEN_ZMP_CONFIG],
                                       const double joint_hack_config[WP::LEN_HACK_CONFIG],
                                       const double sensor_config[WP::LEN_SENSOR_CONFIG],
                                       const double stiffness_config[WP::LEN_STIFF_CONFIG],
                                       const double odo_config[WP::LEN_ODO_CONFIG],
                                       const double arm_config[WP::LEN_ARM_CONFIG]) {
    boost::lock_guard<boost::mutex> lock(m_access);
    Gait next_gait(stance_config, step_config, zmp_config, joint_hack_config,
                         sensor_config, stiffness_config, odo_config, arm_config);
    m_meta_gait->setNewGaitTarget(next_gait);
    m_stance_joints_data = boost::make_shared<SensorData<double> >(*m_step_generator->getDefaultStance(next_gait),
                                                                   m_clock->getTime());
}

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

const StringKeyVector& rd::Locomotion::getJointKeys() const {
    return m_joint_keys;
}

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

void rd::Locomotion::generateStep() {
    try {
        int now = m_clock->getTime();
        boost::lock_guard<boost::mutex> lock(m_access);
        double pitch_p = m_positions_data->data[20];
        double yaw_p = m_positions_data->data[21];
        double pitch_h = m_hardness_data->data[20];
        double yaw_h = m_hardness_data->data[21];
        m_positions_data = boost::make_shared<SensorData<double> >(m_joint_keys.size(), now);
        m_hardness_data = boost::make_shared<SensorData<double> >(m_joint_keys.size(), now);
        m_meta_gait->tick_gait();
        m_step_generator->tick_controller();
        const WalkLegsTuple& legs = m_step_generator->tick_legs();
        const WalkArmsTuple& arms = m_step_generator->tick_arms();
        const ValuesVector& lleg_joints = legs.get<LEFT_FOOT>().get<JOINT_INDEX>();
        const ValuesVector& rleg_joints = legs.get<RIGHT_FOOT>().get<JOINT_INDEX>();
        const ValuesVector& lleg_gains = legs.get<LEFT_FOOT>().get<STIFF_INDEX>();
        const ValuesVector& rleg_gains = legs.get<RIGHT_FOOT>().get<STIFF_INDEX>();
        const ValuesVector& larm_joints = arms.get<LEFT_FOOT>().get<JOINT_INDEX>();
        const ValuesVector& rarm_joints = arms.get<RIGHT_FOOT>().get<JOINT_INDEX>();
        const ValuesVector& larm_gains = arms.get<LEFT_FOOT>().get<STIFF_INDEX>();
        const ValuesVector& rarm_gains = arms.get<RIGHT_FOOT>().get<STIFF_INDEX>();
        std::copy(larm_gains.begin(), larm_gains.end(), m_hardness_data->data.begin() + 0);
        std::copy(lleg_gains.begin(), lleg_gains.end(), m_hardness_data->data.begin() + 4);
        std::copy(rleg_gains.begin(), rleg_gains.end(), m_hardness_data->data.begin() + 10);
        std::copy(rarm_gains.begin(), rarm_gains.end(), m_hardness_data->data.begin() + 16);
        m_hardness_data->data[20] = pitch_h;
        m_hardness_data->data[21] = yaw_h;
        std::copy(larm_joints.begin(), larm_joints.end(), m_positions_data->data.begin() + 0);
        std::copy(lleg_joints.begin(), lleg_joints.end(), m_positions_data->data.begin() + 4);
        std::copy(rleg_joints.begin(), rleg_joints.end(), m_positions_data->data.begin() + 10);
        std::copy(rarm_joints.begin(), rarm_joints.end(), m_positions_data->data.begin() + 16);
        m_positions_data->data[20] = pitch_p;
        m_positions_data->data[21] = yaw_p;
    } catch (const char * e) {
        std::cerr << e << std::endl;
    }
}

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

rd::SensorData<double>::Ptr rd::Locomotion::getPositions() {
    boost::lock_guard<boost::mutex> lock(m_access);
    return m_positions_data;
}

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

rd::SensorData<double>::Ptr rd::Locomotion::getHardness() {
    boost::lock_guard<boost::mutex> lock(m_access);
    return m_hardness_data;
}

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

bool rd::Locomotion::isDone() {
    boost::lock_guard<boost::mutex> lock(m_access);
    return m_step_generator->isDone();
}

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

const StringKeyVector& rd::Locomotion::getOdometryKeys() const {
    return m_odometry_keys;
}

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

void rd::Locomotion::applyPositions() {
    boost::lock_guard<boost::mutex> lock(m_access);
    m_joints->setHardness(m_joint_keys, m_hardness_data->data);
    m_joints->setPositions(m_joint_keys, m_positions_data->data);
}

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

rd::SensorData<double>::Ptr rd::Locomotion::getStanceJointData() {
    boost::lock_guard<boost::mutex> lock(m_access);
    return m_stance_joints_data;
}

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

void rd::Locomotion::setAutoApply(bool enable) {
    if (enable) {
        boost::lock_guard<boost::mutex> lock(m_auto_apply_mut);
        m_auto_apply_flag.store(true);
        m_auto_apply_cv.notify_one();
    } else {
        boost::lock_guard<boost::mutex> lock(m_auto_apply_mut);
        m_auto_apply_flag.store(false);
    }
}

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

bool rd::Locomotion::isAutoApplyEnabled() const {
    return m_auto_apply_flag.load();
}

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

rd::Locomotion::~Locomotion() {
    boost::lock_guard<boost::mutex> lock(m_access);
    m_destroy.store(true);
    m_auto_apply_flag.store(true);
    m_auto_apply_cv.notify_one();
    m_auto_apply_worker.join();
}

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

void rd::Locomotion::autoUpdater() {
    while (!m_destroy.load()) {
        boost::unique_lock<boost::mutex> lock(m_auto_apply_mut);
        while (!m_auto_apply_flag.load()) m_auto_apply_cv.wait(lock);
        this->generateStep();
        this->applyPositions();
        usleep(m_auto_update_sleep_time.load());
    }
}

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

void rd::Locomotion::setAutoApplyUSleepTime(useconds_t us) {
    m_auto_update_sleep_time.store(us);
}

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

useconds_t rd::Locomotion::getAutoApplyUSleepTime() const {
    return m_auto_update_sleep_time.load();
}

void rd::Locomotion::reset(bool left) {
    m_step_generator->setSpeed(0.0, 0.0, 0.0);
    m_step_generator->resetSteps(left);
    m_step_generator->resetHard();

}

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

void rd::Locomotion::setHeadPositions(double pitch, double yaw) {
    boost::lock_guard<boost::mutex> lock(m_access);
    m_positions_data->data[20] = pitch;
    m_positions_data->data[21] = yaw;
}

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

void rd::Locomotion::setHeadHardness(double pitch, double yaw) {
    boost::lock_guard<boost::mutex> lock(m_access);
    m_hardness_data->data[20] = pitch;
    m_hardness_data->data[21] = yaw;
}

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

rd::SensorData<double>::Ptr rd::Locomotion::getHeadPositions() const {
    boost::lock_guard<boost::mutex> lock(m_access);
    return m_positions_data;//boost::make_shared<SensorData<double> >(m_head_positions, m_clock->getTime());
}

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

rd::SensorData<double>::Ptr rd::Locomotion::getHeadHardness() const {
    boost::lock_guard<boost::mutex> lock(m_access);
    return m_hardness_data;//boost::make_shared<SensorData<double> >(m_head_hardness, m_clock->getTime());
}
<commit_msg>Where step generator is done locomotions autoupdate  do nothing<commit_after>//
// Created by arssivka on 2/24/16.
//

#include <rd/hardware/TypeDefinition.h>
#include "rd/hardware/Locomotion.h"

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

rd::Locomotion::Locomotion(boost::shared_ptr<Robot> robot)
        : m_x(0.0), m_y(0.0), m_theta(0.0), m_step_count(0), m_meta_gait(new MetaGait),
          m_step_generator(new StepGenerator(robot, m_meta_gait.get())), m_joints(robot->getJoints()),
          m_clock(robot->getClock()), m_joint_keys(20), m_head_joint_keys(2), m_parameter_keys(PARAMETERS_COUNT),
          m_odometry_keys(ODOMETRY_COUNT), m_auto_apply_flag(false),
          m_auto_apply_worker(boost::bind(&rd::Locomotion::autoUpdater, this)), m_auto_update_sleep_time(0) {
    Gait default_gait(DEFAULT_GAIT);
    m_meta_gait->setStartGait(default_gait);
    m_meta_gait->setNewGaitTarget(default_gait);
    m_stance_joints_data = boost::make_shared<SensorData<double> >(*m_step_generator->getDefaultStance(DEFAULT_GAIT),
                                                                   m_clock->getTime());
    m_parameter_keys[X] = "X";
    m_parameter_keys[Y] = "Y";
    m_parameter_keys[THETA] = "THETA";
    m_parameter_keys[STEP_COUNT] = "STEP_COUNT";

    for (int i = 0; i < PARAMETERS_COUNT; ++i) {
        m_parameter_keys_map.insert(std::make_pair(m_parameter_keys[i], i));
    }

    m_odometry_keys[X_OFFSET] = "X_OFFSET";
    m_odometry_keys[Y_OFFSET] = "Y_OFFSET";
    m_odometry_keys[ROTATION] = "ROTATION";

    const StringKeyVector& keys = m_joints->getKeys();
    for (int i = 0; i < 20; ++i) m_joint_keys[i] = keys[StepGenerator::NB_WALKING_JOINTS[i]];
    m_joint_keys.push_back(keys[rd::Joints::HEAD_PITCH]);
    m_joint_keys.push_back(keys[rd::Joints::HEAD_YAW]);

    int now = m_clock->getTime();
    m_positions_data = boost::make_shared<SensorData<double> >(ValuesVector(m_joint_keys.size(), 0.0), now);
    m_hardness_data = boost::make_shared<SensorData<double> >(ValuesVector(m_joint_keys.size(), 0.0), now);
    m_step_generator->setSpeed(m_x, m_y, m_theta);
}

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

const StringKeyVector& rd::Locomotion::getParameterKeys() const {
    return m_parameter_keys;
}

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

rd::SensorData<double>::Ptr rd::Locomotion::getSpeedParameters(const StringKeyVector& keys) const {
    IntegerKeyVector keys_i(keys.size());
    for (int i = 0; i < keys.size(); ++i) {
        std::map<std::string, int>::const_iterator found = m_parameter_keys_map.find(keys[i]);
        if (found == m_parameter_keys_map.end())
            return boost::make_shared<SensorData<double> >();
        keys_i[i] = found->second;
    }
    return this->getSpeedParameters(keys_i);
}

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

rd::SensorData<double>::Ptr rd::Locomotion::getSpeedParameters(const IntegerKeyVector& keys) const {
    SensorData<double>::Ptr data = boost::make_shared<SensorData<double> >(keys.size(), m_clock->getTime());
    boost::lock_guard<boost::mutex> lock(m_access);
    for (int i = 0; i < keys.size(); ++i) {
        switch (keys[i]) {
            case X:
                data->data[i] = m_x;
                break;
            case Y:
                data->data[i] = m_y;
                break;
            case THETA:
                data->data[i] = m_theta;
                break;
            case STEP_COUNT:
                data->data[i] = m_step_count;
                break;
            default:
                return boost::make_shared<SensorData<double> >();
                break;
        }
    }
    return data;
}

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

void rd::Locomotion::setSpeedParameters(const StringKeyVector& keys, const ValuesVector& values) {
    IntegerKeyVector keys_i(keys.size());
    for (int i = 0; i < keys.size(); ++i) {
        const std::map<std::string, int>::const_iterator found = m_parameter_keys_map.find(keys[i]);
        if (found == m_parameter_keys_map.end())
            return;
        keys_i[i] = found->second;
    }
    this->setSpeedParameters(keys_i, values);
}

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

void rd::Locomotion::setSpeedParameters(const IntegerKeyVector& keys, const ValuesVector& values) {
    if (keys.empty() || keys.size() != values.size())
        return;
    boost::lock_guard<boost::mutex> lock(m_access);
    m_x = 0.0;
    m_y = 0.0;
    m_theta = 0.0;
    m_step_count = 0;
    for (int i = 0; i < keys.size(); ++i) {
        switch (keys[i]) {
            case X_OFFSET:
                m_x = values[i];
                break;
            case Y_OFFSET:
                m_y = values[i];
                break;
            case THETA:
                m_theta = values[i];
                break;
            case STEP_COUNT:
                m_step_count = (unsigned int) values[i];
                break;
            default:
                continue;
        }
    }
    if (m_step_count > 0) {
        m_step_generator->takeSteps(m_x, m_y, m_theta, m_step_count);
    } else {
        m_step_generator->setSpeed(m_x, m_y, m_theta);
    }
}

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

rd::SensorData<double>::Ptr rd::Locomotion::getOdometry() {
    boost::lock_guard<boost::mutex> lock(m_access);
    rd::SensorData<double>::Ptr data = boost::make_shared<SensorData<double> >(m_step_generator->getOdometryUpdate(), m_clock->getTime());
    data->data[1] *= -1.0; // hack!!!!!
    return data;
}

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

void rd::Locomotion::resetOdometry() {
    boost::lock_guard<boost::mutex> lock(m_access);
    m_step_generator->resetOdometry(0.0, 0.0);
}

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

void rd::Locomotion::setGaitParameters(const double stance_config[WP::LEN_STANCE_CONFIG],
                                       const double step_config[WP::LEN_STEP_CONFIG],
                                       const double zmp_config[WP::LEN_ZMP_CONFIG],
                                       const double joint_hack_config[WP::LEN_HACK_CONFIG],
                                       const double sensor_config[WP::LEN_SENSOR_CONFIG],
                                       const double stiffness_config[WP::LEN_STIFF_CONFIG],
                                       const double odo_config[WP::LEN_ODO_CONFIG],
                                       const double arm_config[WP::LEN_ARM_CONFIG]) {
    boost::lock_guard<boost::mutex> lock(m_access);
    Gait next_gait(stance_config, step_config, zmp_config, joint_hack_config,
                         sensor_config, stiffness_config, odo_config, arm_config);
    m_meta_gait->setNewGaitTarget(next_gait);
    m_stance_joints_data = boost::make_shared<SensorData<double> >(*m_step_generator->getDefaultStance(next_gait),
                                                                   m_clock->getTime());
}

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

const StringKeyVector& rd::Locomotion::getJointKeys() const {
    return m_joint_keys;
}

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

void rd::Locomotion::generateStep() {
    try {
        int now = m_clock->getTime();
        boost::lock_guard<boost::mutex> lock(m_access);
        if (!m_step_generator->isDone()) {
            double pitch_p = m_positions_data->data[20];
            double yaw_p = m_positions_data->data[21];
            double pitch_h = m_hardness_data->data[20];
            double yaw_h = m_hardness_data->data[21];
            m_positions_data = boost::make_shared<SensorData<double> >(m_joint_keys.size(), now);
            m_hardness_data = boost::make_shared<SensorData<double> >(m_joint_keys.size(), now);
            m_meta_gait->tick_gait();
            m_step_generator->tick_controller();
            const WalkLegsTuple& legs = m_step_generator->tick_legs();
            const WalkArmsTuple& arms = m_step_generator->tick_arms();
            const ValuesVector& lleg_joints = legs.get<LEFT_FOOT>().get<JOINT_INDEX>();
            const ValuesVector& rleg_joints = legs.get<RIGHT_FOOT>().get<JOINT_INDEX>();
            const ValuesVector& lleg_gains = legs.get<LEFT_FOOT>().get<STIFF_INDEX>();
            const ValuesVector& rleg_gains = legs.get<RIGHT_FOOT>().get<STIFF_INDEX>();
            const ValuesVector& larm_joints = arms.get<LEFT_FOOT>().get<JOINT_INDEX>();
            const ValuesVector& rarm_joints = arms.get<RIGHT_FOOT>().get<JOINT_INDEX>();
            const ValuesVector& larm_gains = arms.get<LEFT_FOOT>().get<STIFF_INDEX>();
            const ValuesVector& rarm_gains = arms.get<RIGHT_FOOT>().get<STIFF_INDEX>();
            std::copy(larm_gains.begin(), larm_gains.end(), m_hardness_data->data.begin() + 0);
            std::copy(lleg_gains.begin(), lleg_gains.end(), m_hardness_data->data.begin() + 4);
            std::copy(rleg_gains.begin(), rleg_gains.end(), m_hardness_data->data.begin() + 10);
            std::copy(rarm_gains.begin(), rarm_gains.end(), m_hardness_data->data.begin() + 16);
            m_hardness_data->data[20] = pitch_h;
            m_hardness_data->data[21] = yaw_h;
            std::copy(larm_joints.begin(), larm_joints.end(), m_positions_data->data.begin() + 0);
            std::copy(lleg_joints.begin(), lleg_joints.end(), m_positions_data->data.begin() + 4);
            std::copy(rleg_joints.begin(), rleg_joints.end(), m_positions_data->data.begin() + 10);
            std::copy(rarm_joints.begin(), rarm_joints.end(), m_positions_data->data.begin() + 16);
            m_positions_data->data[20] = pitch_p;
            m_positions_data->data[21] = yaw_p;
        } else {
            m_positions_data->timestamp = now;
            m_hardness_data->timestamp = now;
        }
    } catch (const char * e) {
        std::cerr << e << std::endl;
    }
}

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

rd::SensorData<double>::Ptr rd::Locomotion::getPositions() {
    boost::lock_guard<boost::mutex> lock(m_access);
    return m_positions_data;
}

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

rd::SensorData<double>::Ptr rd::Locomotion::getHardness() {
    boost::lock_guard<boost::mutex> lock(m_access);
    return m_hardness_data;
}

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

bool rd::Locomotion::isDone() {
    boost::lock_guard<boost::mutex> lock(m_access);
    return m_step_generator->isDone();
}

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

const StringKeyVector& rd::Locomotion::getOdometryKeys() const {
    return m_odometry_keys;
}

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

void rd::Locomotion::applyPositions() {
    boost::lock_guard<boost::mutex> lock(m_access);
    m_joints->setHardness(m_joint_keys, m_hardness_data->data);
    m_joints->setPositions(m_joint_keys, m_positions_data->data);
}

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

rd::SensorData<double>::Ptr rd::Locomotion::getStanceJointData() {
    boost::lock_guard<boost::mutex> lock(m_access);
    return m_stance_joints_data;
}

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

void rd::Locomotion::setAutoApply(bool enable) {
    if (enable) {
        boost::lock_guard<boost::mutex> lock(m_auto_apply_mut);
        m_auto_apply_flag.store(true);
        m_auto_apply_cv.notify_one();
    } else {
        boost::lock_guard<boost::mutex> lock(m_auto_apply_mut);
        m_auto_apply_flag.store(false);
    }
}

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

bool rd::Locomotion::isAutoApplyEnabled() const {
    return m_auto_apply_flag.load();
}

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

rd::Locomotion::~Locomotion() {
    boost::lock_guard<boost::mutex> lock(m_access);
    m_destroy.store(true);
    m_auto_apply_flag.store(true);
    m_auto_apply_cv.notify_one();
    m_auto_apply_worker.join();
}

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

void rd::Locomotion::autoUpdater() {
    while (!m_destroy.load()) {
        boost::unique_lock<boost::mutex> lock(m_auto_apply_mut);
        while (!m_auto_apply_flag.load()) m_auto_apply_cv.wait(lock);
        this->generateStep();
        this->applyPositions();
        usleep(m_auto_update_sleep_time.load());
    }
}

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

void rd::Locomotion::setAutoApplyUSleepTime(useconds_t us) {
    m_auto_update_sleep_time.store(us);
}

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

useconds_t rd::Locomotion::getAutoApplyUSleepTime() const {
    return m_auto_update_sleep_time.load();
}

void rd::Locomotion::reset(bool left) {
    m_step_generator->setSpeed(0.0, 0.0, 0.0);
    m_step_generator->resetSteps(left);
    m_step_generator->resetHard();

}

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

void rd::Locomotion::setHeadPositions(double pitch, double yaw) {
    boost::lock_guard<boost::mutex> lock(m_access);
    m_positions_data->data[20] = pitch;
    m_positions_data->data[21] = yaw;
}

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

void rd::Locomotion::setHeadHardness(double pitch, double yaw) {
    boost::lock_guard<boost::mutex> lock(m_access);
    m_hardness_data->data[20] = pitch;
    m_hardness_data->data[21] = yaw;
}

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

rd::SensorData<double>::Ptr rd::Locomotion::getHeadPositions() const {
    boost::lock_guard<boost::mutex> lock(m_access);
    return m_positions_data;//boost::make_shared<SensorData<double> >(m_head_positions, m_clock->getTime());
}

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

rd::SensorData<double>::Ptr rd::Locomotion::getHeadHardness() const {
    boost::lock_guard<boost::mutex> lock(m_access);
    return m_hardness_data;//boost::make_shared<SensorData<double> >(m_head_hardness, m_clock->getTime());
}
<|endoftext|>