text:
/**
 * Copyright Soramitsu Co., Ltd. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0
 */

#include "runtime/binaryen/runtime_external_interface.hpp"

#include <binaryen/wasm-s-parser.h>
#include <boost/format.hpp>

#include "crypto/crypto_store/key_type.hpp"
#include "mock/core/blockchain/block_header_repository_mock.hpp"
#include "mock/core/host_api/host_api_factory_mock.hpp"
#include "mock/core/host_api/host_api_mock.hpp"
#include "mock/core/runtime/binaryen_wasm_memory_factory_mock.hpp"
#include "mock/core/runtime/core_api_factory_mock.hpp"
#include "mock/core/runtime/memory_mock.hpp"
#include "mock/core/runtime/memory_provider_mock.hpp"
#include "mock/core/runtime/module_repository_mock.hpp"
#include "mock/core/runtime/runtime_environment_factory_mock.hpp"
#include "mock/core/runtime/trie_storage_provider_mock.hpp"
#include "runtime/common/constant_code_provider.hpp"
#include "runtime/common/memory_allocator.hpp"
#include "runtime/ptr_size.hpp"
#include "testutil/prepare_loggers.hpp"

using ::testing::_;
using ::testing::Invoke;
using ::testing::Return;

using kagome::blockchain::BlockHeaderRepositoryMock;
using kagome::crypto::KEY_TYPE_BABE;
using kagome::host_api::HostApi;
using kagome::host_api::HostApiFactoryMock;
using kagome::host_api::HostApiMock;
using kagome::runtime::ConstantCodeProvider;
using kagome::runtime::CoreApiFactoryMock;
using kagome::runtime::MemoryMock;
using kagome::runtime::MemoryProviderMock;
using kagome::runtime::ModuleRepositoryMock;
using kagome::runtime::PtrSize;
using kagome::runtime::RuntimeEnvironmentFactoryMock;
using kagome::runtime::TrieStorageProviderMock;
using kagome::runtime::WasmEnum;
using kagome::runtime::WasmLogLevel;
using kagome::runtime::WasmOffset;
using kagome::runtime::WasmPointer;
using kagome::runtime::WasmSize;
using kagome::runtime::WasmSpan;
using kagome::runtime::binaryen::BinaryenWasmMemoryFactoryMock;
using kagome::runtime::binaryen::RuntimeExternalInterface;
using wasm::Element;
using wasm::Module;
using wasm::ModuleInstance;
using wasm::SExpressionParser;
using wasm::SExpressionWasmBuilder;

/// extend Runtime external interface by adding wasm assertion functions
class TestableExternalInterface : public RuntimeExternalInterface {
 public:
  using RuntimeExternalInterface::RuntimeExternalInterface;

  wasm::Literal callImport(wasm::Function *import,
                           wasm::LiteralList &arguments) override {
    if (import->module == "env" && import->base == "assert") {
      EXPECT_TRUE(arguments.at(0).geti32());
      return wasm::Literal();
    }
    if (import->module == "env" && import->base == "assert_eq_i32") {
      EXPECT_EQ(arguments.at(0).geti32(), arguments.at(1).geti32());
      return wasm::Literal();
    }
    if (import->module == "env" && import->base == "assert_eq_i64") {
      EXPECT_EQ(arguments.at(0).geti64(), arguments.at(1).geti64());
      return wasm::Literal();
    }
    return RuntimeExternalInterface::callImport(import, arguments);
  }
};

class REITest : public ::testing::Test {
 public:
  static void SetUpTestCase() {
    testutil::prepareLoggers();
  }

  void SetUp() override {
    memory_ = std::make_shared<MemoryMock>();
    host_api_ = std::make_unique<HostApiMock>();
    host_api_factory_ = std::make_shared<HostApiFactoryMock>();
    storage_provider_ = std::make_shared<TrieStorageProviderMock>();
    core_api_factory_ = std::make_shared<CoreApiFactoryMock>();
    memory_provider_ = std::make_shared<MemoryProviderMock>();
    auto code_provider =
        std::make_shared<ConstantCodeProvider>(kagome::common::Buffer{});
    auto module_repo = std::make_shared<ModuleRepositoryMock>();
    auto header_repo = std::make_shared<BlockHeaderRepositoryMock>();
    runtime_env_factory_ =
        std::make_shared<RuntimeEnvironmentFactoryMock>(code_provider,
                                                        module_repo,
                                                        header_repo);
  }

  void executeWasm(std::string call_code) {
    std::string code = (boost::format(wasm_template_) % call_code).str();

    // parse wast
    Module wasm{};

    // clang-8 doesn't know char * std::string::data(),
    // it returns only const char *
    char *data = const_cast<char *>(code.data());
    SExpressionParser parser(data);
    Element &root = *parser.root;
    ASSERT_GT(root.size(), 0);
    ASSERT_NE(root[0], nullptr);
    SExpressionWasmBuilder builder(wasm, *root[0]);
    EXPECT_CALL(*host_api_, memory()).WillRepeatedly(Return(memory_));

    TestableExternalInterface rei(host_api_);

    // interpret module
    ModuleInstance instance(wasm, &rei);
  }

 protected:
  std::shared_ptr<MemoryMock> memory_;
  std::shared_ptr<CoreApiFactoryMock> core_api_factory_;
  std::shared_ptr<RuntimeEnvironmentFactoryMock> runtime_env_factory_;
  std::shared_ptr<HostApiMock> host_api_;
  std::shared_ptr<HostApiFactoryMock> host_api_factory_;
  std::shared_ptr<TrieStorageProviderMock> storage_provider_;
  std::shared_ptr<MemoryProviderMock> memory_provider_;

  // clang-format off
  const std::string wasm_template_ =
      "(module\n"
      "  (type (;0;) (func (param i32 i32)))\n"
      "  (type (;1;) (func (param i32)))\n"
      "  (type (;2;) (func (param i32 i32 i32) (result i32)))\n"
      "  (type (;3;) (func (param i32 i32) (result i32)))\n"
      "  (type (;4;) (func (param i32 i32 i32 i32 i32) (result i32)))\n"
      "  (type (;5;) (func (param i32 i32 i32)))\n"
      "  (type (;6;) (func (param i32 i32 i32 i32)))\n"
      "  (type (;7;) (func (param i64)))\n"
      "  (type (;8;) (func (param i32) (result i32)))\n"
      "  (type (;9;) (func (param i32 i32 i32 i32) (result i32)))\n"
      "  (type (;10;) (func (param i32 i32 i64 i32) (result i32)))\n"
      "  (type (;11;) (func))\n"
      "  (type (;12;) (func (param i32 i64 i64)))\n"
      "  (type (;13;) (func (param i64 i32) (result i32)))\n"
      "  (type (;14;) (func (param i32) (result i64)))\n"
      "  (type (;15;) (func (param i64 i32)))\n"
      "  (type (;16;) (func (param i32 i32 i64 i64)))\n"
      "  (type (;17;) (func (param i32 i64 i64 i64)))\n"
      "  (type (;18;) (func (param i64 i64)))\n"
      "  (type (;19;) (func (param i32 i32 i32 i32 i32)))\n"
      "  (type (;20;) (func (param i32 i64)))\n"
      "  (type (;21;) (func (param i32 i64 i32 i32 i64)))\n"
      "  (type (;22;) (func (param i32 i32 i32 i64 i64)))\n"
      "  (type (;23;) (func (param i32 i32) (result i64)))\n"
      "  (type (;24;) (func (param i32 i64 i64 i64 i64)))\n"
      "  (type (;25;) (func (param i32 i64 i64 i32)))\n"
      "  (type (;26;) (func (param i32 i64 i64 i64 i64 i32)))\n"
      "  (type (;27;) (func (result i64)))\n"
      "  (type (;28;) (func (param i32 i32 i32)))\n"
      "  (type (;29;) (func (param i64) (result i64)))\n"
      "  (type (;30;) (func (param i32 i64) (result i32)))\n"
      "  (type (;31;) (func (param i32 i32 i64) (result i64)))\n"
      "  (type (;32;) (func (param i32 i64 i32) (result i32)))\n"
      "  (type (;33;) (func (param i64 i64 i32) (result i64)))\n"
      "  (type (;34;) (func (param i64) (result i32)))\n"
      "  (type (;35;) (func (result i32)))\n"

      /// version 1
      "  (import \"env\" \"ext_crypto_start_batch_verify\" (func $ext_crypto_start_batch_verify_version_1 (type 11)))\n"
      "  (import \"env\" \"ext_crypto_finish_batch_verify\" (func $ext_crypto_finish_batch_verify_version_1 (type 35)))\n"
      "  (import \"env\" \"ext_crypto_ed25519_public_keys_version_1\" (func $ext_crypto_ed25519_public_keys_version_1 (type 29)))\n"
      "  (import \"env\" \"ext_crypto_ed25519_generate_version_1\" (func $ext_crypto_ed25519_generate_version_1 (type 30)))\n"
      "  (import \"env\" \"ext_crypto_ed25519_sign_version_1\" (func $ext_crypto_ed25519_sign_version_1 (type 31)))\n"
      "  (import \"env\" \"ext_crypto_ed25519_verify_version_1\" (func $ext_crypto_ed25519_verify_version_1 (type 32)))\n"
      "  (import \"env\" \"ext_crypto_sr25519_public_keys_version_1\" (func $ext_crypto_sr25519_public_keys_version_1 (type 29)))\n"
      "  (import \"env\" \"ext_crypto_sr25519_generate_version_1\" (func $ext_crypto_sr25519_generate_version_1 (type 30)))\n"
      "  (import \"env\" \"ext_crypto_sr25519_sign_version_1\" (func $ext_crypto_sr25519_sign_version_1 (type 31)))\n"
      "  (import \"env\" \"ext_crypto_sr25519_verify_version_2\" (func $ext_crypto_sr25519_verify_version_2 (type 32)))\n"
      "  (import \"env\" \"ext_crypto_secp256k1_ecdsa_recover_version_1\" (func $ext_crypto_secp256k1_ecdsa_recover_version_1 (type 31)))\n"
      "  (import \"env\" \"ext_crypto_secp256k1_ecdsa_recover_compressed_version_1\" (func $ext_crypto_secp256k1_ecdsa_recover_compressed_version_1 (type 31)))\n"

      /// hashing methods
      "  (import \"env\" \"ext_hashing_keccak_256_version_1\" (func $ext_hashing_keccak_256_version_1 (type 34)))\n"
      "  (import \"env\" \"ext_hashing_sha2_256_version_1\" (func $ext_hashing_sha2_256_version_1 (type 34)))\n"
      "  (import \"env\" \"ext_hashing_blake2_128_version_1\" (func $ext_hashing_blake2_128_version_1 (type 34)))\n"
      "  (import \"env\" \"ext_hashing_blake2_256_version_1\" (func $ext_hashing_blake2_256_version_1 (type 34)))\n"
      "  (import \"env\" \"ext_hashing_twox_256_version_1\" (func $ext_hashing_twox_256_version_1 (type 34)))\n"
      "  (import \"env\" \"ext_hashing_twox_128_version_1\" (func $ext_hashing_twox_128_version_1 (type 34)))\n"
      "  (import \"env\" \"ext_hashing_twox_64_version_1\" (func $ext_hashing_twox_64_version_1 (type 34)))\n"

      /// allocator methods
      "  (import \"env\" \"ext_allocator_malloc_version_1\" (func $ext_allocator_malloc_version_1 (type 8)))\n"
      "  (import \"env\" \"ext_allocator_free_version_1\" (func $ext_allocator_free_version_1 (type 1)))\n"

      /// storage methods
      "  (import \"env\" \"ext_storage_set_version_1\" (func $ext_storage_set_version_1 (type 18)))\n"
      "  (import \"env\" \"ext_storage_get_version_1\" (func $ext_storage_get_version_1 (type 29)))\n"
      "  (import \"env\" \"ext_storage_clear_version_1\" (func $ext_storage_clear_version_1 (type 7)))\n"
      "  (import \"env\" \"ext_storage_exists_version_1\" (func $ext_storage_exists_version_1 (type 34)))\n"
      "  (import \"env\" \"ext_storage_read_version_1\" (func $ext_storage_read_version_1 (type 33)))\n"
      "  (import \"env\" \"ext_storage_clear_prefix_version_1\" (func $ext_storage_clear_prefix_version_1 (type 7)))\n"
      "  (import \"env\" \"ext_storage_changes_root_version_1\" (func $ext_storage_changes_root_version_1 (type 29)))\n"
      "  (import \"env\" \"ext_storage_root_version_1\" (func $ext_storage_root_version_1 (type 27)))\n"
      "  (import \"env\" \"ext_storage_next_key_version_1\" (func $ext_storage_next_key_version_1 (type 29)))\n"

      /// trie methods
      "  (import \"env\" \"ext_trie_blake2_256_root_version_1\" (func $ext_trie_blake2_256_root_version_1 (type 34)))\n"
      "  (import \"env\" \"ext_trie_blake2_256_ordered_root_version_1\" (func $ext_trie_blake2_256_ordered_root_version_1 (type 34)))\n"

      /// assertions to check output in wasm
      "  (import \"env\" \"assert\" (func $assert (param i32)))\n"
      "  (import \"env\" \"assert_eq_i32\" (func $assert_eq_i32 (param i32 i32)))\n"
      "  (import \"env\" \"assert_eq_i64\" (func $assert_eq_i64 (param i64 i64)))\n"

      "  (import \"env\" \"ext_logging_log_version_1\" (func $ext_logging_log_version_1 (type 12)))\n"
      "  (import \"env\" \"ext_logging_max_level_version_1\" (func $ext_logging_max_level_version_1 (type 35)))\n"

      /// below is start function with import function call defined in test case
      "  (type $v (func))\n"
      "  (start $starter)\n"
      "  (func $starter (; 11 ;) (type 11)\n"
      "%s" // to plug actual call
      "  )\n"
      ")";
  // clang-format on
};

/**
 * For all tests:
 * @given runtime external interface with mocked externals
 * @when external function is invoked with provided arguments from WASM
 * @then corresponding host function is invoked with provided arguments
 */

TEST_F(REITest, ext_blake2_256_enumerated_trie_root_Test) {
  WasmSpan values = PtrSize{12, 42}.combine();
  WasmPointer result = 321;

  EXPECT_CALL(*host_api_, ext_trie_blake2_256_ordered_root_version_1(values))
      .WillOnce(Return(result));
  auto execute_code =
      (boost::format("(call $assert_eq_i32\n"
                     "    (call $ext_trie_blake2_256_ordered_root_version_1\n"
                     "      (i64.const %d)\n"
                     "    )\n"
                     "    (i32.const %d)\n"
                     ")\n")
       % values % result)
          .str();
  executeWasm(execute_code);
}

TEST_F(REITest, ext_storage_changes_root_Test) {
  WasmPointer parent_hash_data = 123;
  WasmSize parent_hash_len = 42;
  WasmPointer result = 321;

  EXPECT_CALL(*host_api_, ext_storage_changes_root_version_1(PtrSize(parent_hash_data, parent_hash_len).combine()))
      .WillOnce(Return(result));

  auto execute_code =
      (boost::format("    (call $assert_eq_i64\n"
                     "      (call $ext_storage_changes_root_version_1\n"
                     "        (i64.const %d)\n"
                     "      )\n"
                     "      (i64.const %d)\n"
                     "    )\n")
       % PtrSize(parent_hash_data, parent_hash_len).combine() % result)
          .str();
  SCOPED_TRACE("ext_storage_changes_root_Test");
  executeWasm(execute_code);
}

TEST_F(REITest, ext_storage_root_Test) {
  WasmPointer storage_root = 12;

  EXPECT_CALL(*host_api_, ext_storage_root_version_1()).WillOnce(Return(storage_root));
  auto execute_code = (boost::format("    (call $assert_eq_i64\n"
                                     "      (call $ext_storage_root_version_1)\n"
                                     "      (i64.const %d)\n"
                                     "    )\n") % storage_root).str();
  executeWasm(execute_code);
}

TEST_F(REITest, ext_logging_log_version_1_Test) {
  PtrSize position(12, 12);
  const auto pos_packed = position.combine();
  WasmEnum ll = static_cast<WasmEnum>(WasmLogLevel::Error);

  EXPECT_CALL(*host_api_, ext_logging_log_version_1(ll, pos_packed, pos_packed))
      .Times(1);
  auto execute_code = (boost::format("    (call $ext_logging_log_version_1\n"
                                     "      (i32.const %d)\n"
                                     "      (i64.const %d)\n"
                                     "      (i64.const %d)\n"
                                     "    )\n")
                       % ll % position.combine() % position.combine())
                          .str();
  executeWasm(execute_code);
}

/**
 * @given wasm runtime ext_logging_max_level_version_1
 * @when try to get max log level
 * @then correct log level returned once
 */
TEST_F(REITest, ext_logging_max_level_version_1_Test) {
  WasmEnum expected_res = static_cast<WasmEnum>(WasmLogLevel::Info);

  EXPECT_CALL(*host_api_, ext_logging_max_level_version_1())
      .WillOnce(Return(expected_res));
  auto execute_code =
      (boost::format("    (call $assert_eq_i32\n"
                     "      (call $ext_logging_max_level_version_1)\n"
                     "      (i32.const %d)\n"
                     "    )\n")
       % expected_res)
          .str();
  SCOPED_TRACE("ext_logging_max_level_version_1_Test");
  executeWasm(execute_code);
}

TEST_F(REITest, ext_ed25519_public_keys_v1_Test) {
  WasmSize key_type = KEY_TYPE_BABE;
  WasmSpan res = PtrSize(1, 2).combine();

  EXPECT_CALL(*host_api_, ext_crypto_ed25519_public_keys_version_1(key_type))
      .WillOnce(Return(res));

  auto execute_code =
      (boost::format("    (call $assert_eq_i64\n"
                     "      (call $ext_crypto_ed25519_public_keys_version_1\n"
                     "        (i32.const %d)\n"
                     "      )\n"
                     "      (i64.const %d)\n"
                     "    )\n")
       % key_type % res)
          .str();
  SCOPED_TRACE("ext_ed25519_public_keys_Test");
  executeWasm(execute_code);
}

TEST_F(REITest, ext_ed25519_generate_v1_Test) {
  WasmSize key_type = KEY_TYPE_BABE;
  WasmSpan seed = PtrSize(1, 2).combine();

  WasmPointer res = 4;

  EXPECT_CALL(*host_api_, ext_crypto_ed25519_generate_version_1(key_type, seed))
      .WillOnce(Return(res));

  auto execute_code =
      (boost::format("    (call $assert_eq_i32\n"
                     "      (call $ext_crypto_ed25519_generate_version_1\n"
                     "        (i32.const %d)\n"
                     "        (i64.const %d)\n"
                     "      )\n"
                     "      (i32.const %d)\n"
                     "    )\n")
       % key_type % seed % res)
          .str();
  SCOPED_TRACE("ext_ed25519_generate_Test");
  executeWasm(execute_code);
}

TEST_F(REITest, ext_ed25519_sign_v1_Test) {
  WasmSize key_type = KEY_TYPE_BABE;
  WasmPointer key = 1;
  WasmSpan msg = PtrSize(33, 2).combine();
  WasmSpan res = PtrSize(35, 25).combine();

  EXPECT_CALL(*host_api_, ext_crypto_ed25519_sign_version_1(key_type, key, msg))
      .WillOnce(Return(res));

  auto execute_code =
      (boost::format("    (call $assert_eq_i64\n"
                     "      (call $ext_crypto_ed25519_sign_version_1\n"
                     "        (i32.const %d)\n"
                     "        (i32.const %d)\n"
                     "        (i64.const %d)\n"
                     "      )\n"
                     "      (i64.const %d)\n"
                     "    )\n")
       % key_type % key % msg % res)
          .str();
  SCOPED_TRACE("ext_ed25519_generate_Test");
  executeWasm(execute_code);
}

TEST_F(REITest, ext_ed25519_verify_v1_Test) {
  WasmPointer msg_data = 123;
  WasmSize msg_len = 1233;
  WasmSpan msg = PtrSize(msg_data, msg_len).combine();
  WasmPointer sig_data = 42;
  WasmPointer pubkey_data = 321;

  WasmSize res = 1;

  EXPECT_CALL(*host_api_,
              ext_crypto_ed25519_verify_version_1(sig_data, msg, pubkey_data))
      .WillOnce(Return(res));

  auto execute_code =
      (boost::format("    (call $assert_eq_i32\n"
                     "      (call $ext_crypto_ed25519_verify_version_1\n"
                     "        (i32.const %d)\n"
                     "        (i64.const %d)\n"
                     "        (i32.const %d)\n"
                     "      )\n"
                     "      (i32.const %d)\n"
                     "    )\n")
       % sig_data % msg % pubkey_data % res)
          .str();
  SCOPED_TRACE("ext_ed25519_verify_Test");
  executeWasm(execute_code);
}

TEST_F(REITest, ext_sr25519_public_keys_v1_Test) {
  WasmSize key_type = KEY_TYPE_BABE;

  WasmSpan res = PtrSize(1, 2).combine();

  EXPECT_CALL(*host_api_, ext_crypto_sr25519_public_keys_version_1(key_type))
      .WillOnce(Return(res));

  auto execute_code =
      (boost::format("    (call $assert_eq_i64\n"
                     "      (call $ext_crypto_sr25519_public_keys_version_1\n"
                     "        (i32.const %d)\n"
                     "      )\n"
                     "      (i64.const %d)\n"
                     "    )\n")
       % key_type % res)
          .str();
  SCOPED_TRACE("ext_sr25519_public_keys_Test");
  executeWasm(execute_code);
}

TEST_F(REITest, ext_sr25519_generate_v1_Test) {
  WasmSize key_type = KEY_TYPE_BABE;
  WasmSpan seed = PtrSize(1, 2).combine();

  WasmPointer res = 4;

  EXPECT_CALL(*host_api_, ext_crypto_sr25519_generate_version_1(key_type, seed))
      .WillOnce(Return(res));

  auto execute_code =
      (boost::format("    (call $assert_eq_i32\n"
                     "      (call $ext_crypto_sr25519_generate_version_1\n"
                     "        (i32.const %d)\n"
                     "        (i64.const %d)\n"
                     "      )\n"
                     "      (i32.const %d)\n"
                     "    )\n")
       % key_type % seed % res)
          .str();
  SCOPED_TRACE("ext_sr25519_generate_Test");
  executeWasm(execute_code);
}

TEST_F(REITest, ext_sr25519_sign_v1_Test) {
  WasmSize key_type = KEY_TYPE_BABE;
  WasmPointer key = 1;
  WasmSpan msg = PtrSize(33, 2).combine();
  WasmSpan res = PtrSize(35, 25).combine();

  EXPECT_CALL(*host_api_, ext_crypto_sr25519_sign_version_1(key_type, key, msg))
      .WillOnce(Return(res));

  auto execute_code =
      (boost::format("    (call $assert_eq_i64\n"
                     "      (call $ext_crypto_sr25519_sign_version_1\n"
                     "        (i32.const %d)\n"
                     "        (i32.const %d)\n"
                     "        (i64.const %d)\n"
                     "      )\n"
                     "      (i64.const %d)\n"
                     "    )\n")
       % key_type % key % msg % res)
          .str();
  SCOPED_TRACE("ext_sr25519_sign_Test");
  executeWasm(execute_code);
}

TEST_F(REITest, ext_sr25519_verify_v2_Test) {
  WasmPointer msg_data = 123;
  WasmSize msg_len = 1233;
  WasmSpan msg = PtrSize(msg_data, msg_len).combine();
  WasmPointer sig_data = 42;
  WasmPointer pubkey_data = 321;

  WasmSize res = 1;

  EXPECT_CALL(*host_api_,
              ext_crypto_sr25519_verify_version_2(sig_data, msg, pubkey_data))
      .WillOnce(Return(res));

  auto execute_code =
      (boost::format("    (call $assert_eq_i32\n"
                     "      (call $ext_crypto_sr25519_verify_version_2\n"
                     "        (i32.const %d)\n"
                     "        (i64.const %d)\n"
                     "        (i32.const %d)\n"
                     "      )\n"
                     "      (i32.const %d)\n"
                     "    )\n")
       % sig_data % msg % pubkey_data % res)
          .str();
  SCOPED_TRACE("ext_sr25519_verify_Test");
  executeWasm(execute_code);
}

TEST_F(REITest, ext_crypto_secp256k1_ecdsa_recover_version_1_Test) {
  WasmPointer sig_ptr = 12;
  WasmPointer msg_ptr = 77;
  WasmSpan out_span = PtrSize{109, 41}.combine();

  EXPECT_CALL(*host_api_,
              ext_crypto_secp256k1_ecdsa_recover_version_1(sig_ptr, msg_ptr))
      .WillOnce(Return(out_span));
  auto execute_code =
      (boost::format("(call $assert_eq_i64\n"
                     "    (call $ext_crypto_secp256k1_ecdsa_recover_version_1\n"
                     "      (i32.const %d)\n"
                     "      (i32.const %d)\n"
                     "    )\n"
                     "    (i64.const %d)\n"
                     ")")
       % sig_ptr % msg_ptr % out_span)
          .str();
  executeWasm(execute_code);
}

TEST_F(REITest, ext_crypto_secp256k1_ecdsa_recover_compressed_version_1_Test) {
  WasmPointer sig_ptr = 12;
  WasmPointer msg_ptr = 77;
  WasmSpan out_span = PtrSize{109, 41}.combine();

  EXPECT_CALL(
      *host_api_,
      ext_crypto_secp256k1_ecdsa_recover_compressed_version_1(sig_ptr, msg_ptr))
      .WillOnce(Return(out_span));
  auto execute_code =
      (boost::format(
           "(call $assert_eq_i64\n"
           "    (call "
           "$ext_crypto_secp256k1_ecdsa_recover_compressed_version_1\n"
           "      (i32.const %d)\n"
           "      (i32.const %d)\n"
           "    )\n"
           "    (i64.const %d)\n"
           ")")
       % sig_ptr % msg_ptr % out_span)
          .str();
  executeWasm(execute_code);
}

TEST_F(REITest, ext_hashing_keccak_256_version_1_Test) {
  WasmPointer res = 3;
  WasmSpan param = PtrSize(1, 2).combine();

  EXPECT_CALL(*host_api_, ext_hashing_keccak_256_version_1(param))
      .WillOnce(Return(res));

  auto execute_code =
      (boost::format("    (call $assert_eq_i32\n"
                     "      (call $ext_hashing_keccak_256_version_1\n"
                     "        (i64.const %d)\n"
                     "      )\n"
                     "      (i32.const %d)\n"
                     "    )\n")
       % param % res)
          .str();
  SCOPED_TRACE("ext_hashing_keccak_256_version_1_Test");
  executeWasm(execute_code);
}

TEST_F(REITest, ext_hashing_sha2_256_version_1_Test) {
  WasmPointer res = 3;
  WasmSpan param = PtrSize(1, 2).combine();

  EXPECT_CALL(*host_api_, ext_hashing_sha2_256_version_1(param))
      .WillOnce(Return(res));

  auto execute_code =
      (boost::format("    (call $assert_eq_i32\n"
                     "      (call $ext_hashing_sha2_256_version_1\n"
                     "        (i64.const %d)\n"
                     "      )\n"
                     "      (i32.const %d)\n"
                     "    )\n")
       % param % res)
          .str();
  SCOPED_TRACE("ext_hashing_sha2_256_version_1_Test");
  executeWasm(execute_code);
}

TEST_F(REITest, ext_hashing_blake2_128_version_1_Test) {
  WasmPointer res = 3;
  WasmSpan param = PtrSize(1, 2).combine();

  EXPECT_CALL(*host_api_, ext_hashing_blake2_128_version_1(param))
      .WillOnce(Return(res));

  auto execute_code =
      (boost::format("    (call $assert_eq_i32\n"
                     "      (call $ext_hashing_blake2_128_version_1\n"
                     "        (i64.const %d)\n"
                     "      )\n"
                     "      (i32.const %d)\n"
                     "    )\n")
       % param % res)
          .str();
  SCOPED_TRACE("ext_hashing_blake2_128_version_1_Test");
  executeWasm(execute_code);
}

TEST_F(REITest, ext_hashing_blake2_256_version_1_Test) {
  WasmPointer res = 3;
  WasmSpan param = PtrSize(1, 2).combine();

  EXPECT_CALL(*host_api_, ext_hashing_blake2_256_version_1(param))
      .WillOnce(Return(res));

  auto execute_code =
      (boost::format("    (call $assert_eq_i32\n"
                     "      (call $ext_hashing_blake2_256_version_1\n"
                     "        (i64.const %d)\n"
                     "      )\n"
                     "      (i32.const %d)\n"
                     "    )\n")
       % param % res)
          .str();
  SCOPED_TRACE("ext_hashing_blake2_256_version_1_Test");
  executeWasm(execute_code);
}

TEST_F(REITest, ext_hashing_twox_256_version_1_Test) {
  WasmPointer res = 3;
  WasmSpan param = PtrSize(1, 2).combine();

  EXPECT_CALL(*host_api_, ext_hashing_twox_256_version_1(param))
      .WillOnce(Return(res));

  auto execute_code =
      (boost::format("    (call $assert_eq_i32\n"
                     "      (call $ext_hashing_twox_256_version_1\n"
                     "        (i64.const %d)\n"
                     "      )\n"
                     "      (i32.const %d)\n"
                     "    )\n")
       % param % res)
          .str();
  SCOPED_TRACE("ext_hashing_twox_256_version_1_Test");
  executeWasm(execute_code);
}

TEST_F(REITest, ext_hashing_twox_128_version_1_Test) {
  WasmPointer res = 3;
  WasmSpan param = PtrSize(1, 2).combine();

  EXPECT_CALL(*host_api_, ext_hashing_twox_128_version_1(param))
      .WillOnce(Return(res));

  auto execute_code =
      (boost::format("    (call $assert_eq_i32\n"
                     "      (call $ext_hashing_twox_128_version_1\n"
                     "        (i64.const %d)\n"
                     "      )\n"
                     "      (i32.const %d)\n"
                     "    )\n")
       % param % res)
          .str();
  SCOPED_TRACE("ext_hashing_twox_128_version_1_Test");
  executeWasm(execute_code);
}

TEST_F(REITest, ext_hashing_twox_64_version_1_Test) {
  WasmPointer res = 3;
  WasmSpan param = PtrSize(1, 2).combine();

  EXPECT_CALL(*host_api_, ext_hashing_twox_64_version_1(param))
      .WillOnce(Return(res));

  auto execute_code =
      (boost::format("    (call $assert_eq_i32\n"
                     "      (call $ext_hashing_twox_64_version_1\n"
                     "        (i64.const %d)\n"
                     "      )\n"
                     "      (i32.const %d)\n"
                     "    )\n")
       % param % res)
          .str();
  SCOPED_TRACE("ext_hashing_twox_64_version_1_Test");
  executeWasm(execute_code);
}

TEST_F(REITest, ext_allocator_malloc_version_1_Test) {
  WasmSize size = 42;
  WasmPointer ptr = 123;
  EXPECT_CALL(*host_api_, ext_allocator_malloc_version_1(size))
      .WillOnce(Return(ptr));
  auto execute_code =
      (boost::format("    (call $assert_eq_i32\n"
                     "      (call $ext_allocator_malloc_version_1\n"
                     "        (i32.const %d)\n"
                     "      )\n"
                     "      (i32.const %d)\n"
                     "    )\n")
       % size % ptr)
          .str();
  SCOPED_TRACE("ext_allocator_malloc_version_1_Test");
  executeWasm(execute_code);
}

TEST_F(REITest, ext_allocator_free_version_1_Test) {
  WasmPointer ptr = 123;
  EXPECT_CALL(*host_api_, ext_allocator_free_version_1(ptr)).Times(1);
  auto execute_code = (boost::format("    (call $ext_allocator_free_version_1\n"
                                     "      (i32.const %d)\n"
                                     "    )\n")
                       % ptr)
                          .str();
  SCOPED_TRACE("ext_allocator_free_version_1_Test");
  executeWasm(execute_code);
}

TEST_F(REITest, ext_storage_set_version_1_Test) {
  WasmSpan param1 = PtrSize(1, 2).combine();
  WasmSpan param2 = PtrSize(3, 4).combine();
  EXPECT_CALL(*host_api_, ext_storage_set_version_1(param1, param2))
      .WillOnce(Return());

  auto execute_code = (boost::format("      (call $ext_storage_set_version_1\n"
                                     "        (i64.const %d)\n"
                                     "        (i64.const %d)\n"
                                     "      )\n")
                       % param1 % param2)
                          .str();
  SCOPED_TRACE("ext_storage_set_version_1_Test");
  executeWasm(execute_code);
}

TEST_F(REITest, ext_storage_get_version_1_Test) {
  WasmSize key_type = KEY_TYPE_BABE;
  WasmSpan res = PtrSize(1, 2).combine();

  EXPECT_CALL(*host_api_, ext_storage_get_version_1(key_type))
      .WillOnce(Return(res));

  auto execute_code = (boost::format("    (call $assert_eq_i64\n"
                                     "      (call $ext_storage_get_version_1\n"
                                     "        (i64.const %d)\n"
                                     "      )\n"
                                     "      (i64.const %d)\n"
                                     "    )\n")
                       % key_type % res)
                          .str();
  SCOPED_TRACE("ext_storage_get_version_1_Test");
  executeWasm(execute_code);
}

TEST_F(REITest, ext_storage_clear_version_1_Test) {
  uint64_t num = 12;

  EXPECT_CALL(*host_api_, ext_storage_clear_version_1(num)).Times(1);
  auto execute_code = (boost::format("    (call $ext_storage_clear_version_1\n"
                                     "      (i64.const %d)\n"
                                     "    )\n")
                       % num)
                          .str();
  SCOPED_TRACE("ext_storage_clear_version_1_Test");
  executeWasm(execute_code);
}

TEST_F(REITest, ext_storage_exists_version_1_Test) {
  WasmPointer res = 3;
  WasmSpan param = PtrSize(1, 2).combine();

  EXPECT_CALL(*host_api_, ext_storage_exists_version_1(param))
      .WillOnce(Return(res));

  auto execute_code =
      (boost::format("    (call $assert_eq_i32\n"
                     "      (call $ext_storage_exists_version_1\n"
                     "        (i64.const %d)\n"
                     "      )\n"
                     "      (i32.const %d)\n"
                     "    )\n")
       % param % res)
          .str();
  SCOPED_TRACE("ext_storage_exists_version_1_Test");
  executeWasm(execute_code);
}

TEST_F(REITest, ext_storage_read_version_1_Test) {
  PtrSize key(123, 1233);
  PtrSize value(42, 12);
  WasmOffset offset(1);
  WasmSpan res = PtrSize(1, 2).combine();

  EXPECT_CALL(
      *host_api_,
      ext_storage_read_version_1(key.combine(), value.combine(), offset))
      .WillOnce(Return(res));
  auto execute_code = (boost::format("    (call $assert_eq_i64\n"
                                     "    (call $ext_storage_read_version_1\n"
                                     "      (i64.const %d)\n"
                                     "      (i64.const %d)\n"
                                     "      (i32.const %d)\n"
                                     "    )\n"
                                     "      (i64.const %d)\n"
                                     "    )\n")
                       % key.combine() % value.combine() % offset % res)
                          .str();
  SCOPED_TRACE("ext_storage_read_version_1_Test");
  executeWasm(execute_code);
}

TEST_F(REITest, ext_storage_clear_prefix_version_1_Test) {
  uint64_t num = 12;

  EXPECT_CALL(*host_api_, ext_storage_clear_prefix_version_1(num)).Times(1);
  auto execute_code =
      (boost::format("    (call $ext_storage_clear_prefix_version_1\n"
                     "      (i64.const %d)\n"
                     "    )\n")
       % num)
          .str();
  SCOPED_TRACE("ext_storage_clear_prefix_version_1_Test");
  executeWasm(execute_code);
}

TEST_F(REITest, ext_storage_changes_root_version_1_Test) {
  WasmSize key_type = KEY_TYPE_BABE;
  WasmSpan res = 2;

  EXPECT_CALL(*host_api_, ext_storage_changes_root_version_1(key_type))
      .WillOnce(Return(res));

  auto execute_code =
      (boost::format("    (call $assert_eq_i64\n"
                     "      (call $ext_storage_changes_root_version_1\n"
                     "        (i64.const %d)\n"
                     "      )\n"
                     "      (i64.const %d)\n"
                     "    )\n")
       % key_type % res)
          .str();
  SCOPED_TRACE("ext_storage_changes_root_version_1_Test");
  executeWasm(execute_code);
}

TEST_F(REITest, ext_storage_root_version_1_Test) {
  WasmSpan res = 123141;

  EXPECT_CALL(*host_api_, ext_storage_root_version_1()).WillOnce(Return(res));

  auto execute_code =
      (boost::format("    (call $assert_eq_i64\n"
                     "      (call $ext_storage_root_version_1)\n"
                     "      (i64.const %d)\n"
                     "    )\n")
       % res)
          .str();
  SCOPED_TRACE("ext_storage_root_version_1_Test");
  executeWasm(execute_code);
}

TEST_F(REITest, ext_storage_next_key_version_1_Test) {
  WasmSpan param = 5678;
  WasmSpan res = 123141;

  EXPECT_CALL(*host_api_, ext_storage_next_key_version_1(param))
      .WillOnce(Return(res));

  auto execute_code =
      (boost::format("    (call $assert_eq_i64\n"
                     "      (call $ext_storage_next_key_version_1"
                     "        (i64.const %d)\n"
                     "      )\n"
                     "      (i64.const %d)\n"
                     "    )\n")
       % param % res)
          .str();
  SCOPED_TRACE("ext_storage_next_key_version_1_Test");
  executeWasm(execute_code);
}

TEST_F(REITest, ext_trie_blake2_256_root_version_1_Test) {
  WasmPointer res = 3;
  WasmSpan param = PtrSize(1, 2).combine();

  EXPECT_CALL(*host_api_, ext_trie_blake2_256_root_version_1(param))
      .WillOnce(Return(res));

  auto execute_code =
      (boost::format("    (call $assert_eq_i32\n"
                     "      (call $ext_trie_blake2_256_root_version_1\n"
                     "        (i64.const %d)\n"
                     "      )\n"
                     "      (i32.const %d)\n"
                     "    )\n")
       % param % res)
          .str();
  SCOPED_TRACE("ext_trie_blake2_256_root_version_1_Test");
  executeWasm(execute_code);
}

TEST_F(REITest, ext_trie_blake2_256_ordered_root_version_1_Test) {
  WasmPointer res = 3;
  WasmSpan param = PtrSize(1, 2).combine();

  EXPECT_CALL(*host_api_, ext_trie_blake2_256_ordered_root_version_1(param))
      .WillOnce(Return(res));

  auto execute_code =
      (boost::format("    (call $assert_eq_i32\n"
                     "      (call $ext_trie_blake2_256_ordered_root_version_1\n"
                     "        (i64.const %d)\n"
                     "      )\n"
                     "      (i32.const %d)\n"
                     "    )\n")
       % param % res)
          .str();
  SCOPED_TRACE("ext_trie_blake2_256_ordered_root_version_1_Test");
  executeWasm(execute_code);
}

max_stars_repo_name: soramitsu/kagome

max_issues_repo_name: soramitsu/kagome

max_forks_repo_name: soramitsu/kagome


text:
//==============================================================================
//         Copyright 2003 - 2011 LASMEA UMR 6602 CNRS/Univ. Clermont II
//         Copyright 2009 - 2011 LRI    UMR 8623 CNRS/Univ Paris Sud XI
//
//          Distributed under the Boost Software License, Version 1.0.
//                 See accompanying file LICENSE.txt or copy at
//                     http://www.boost.org/LICENSE_1_0.txt
//==============================================================================
#ifndef BOOST_SIMD_TOOLBOX_OPERATOR_FUNCTIONS_SIMD_SSE_SSE2_UNALIGNED_LOAD_HPP_INCLUDED
#define BOOST_SIMD_TOOLBOX_OPERATOR_FUNCTIONS_SIMD_SSE_SSE2_UNALIGNED_LOAD_HPP_INCLUDED
#ifdef BOOST_SIMD_HAS_SSE2_SUPPORT

////////////////////////////////////////////////////////////////////////////////
// unaligned_load for SSE2 SIMD types
////////////////////////////////////////////////////////////////////////////////
#include <boost/simd/toolbox/operator/functions/unaligned_load.hpp>
#include <boost/dispatch/meta/mpl.hpp>
#include <boost/simd/sdk/simd/category.hpp>
#include <boost/dispatch/meta/scalar_of.hpp>
#include <boost/simd/sdk/meta/cardinal_of.hpp>
#include <boost/dispatch/functor/preprocessor/call.hpp>

//==============================================================================
// unaligned_load vector of double
//==============================================================================
namespace boost { namespace simd { namespace ext
{
  BOOST_SIMD_FUNCTOR_IMPLEMENTATION( boost::simd::tag::unaligned_load_ , boost::simd::tag::sse2_
                            , (A0)(A1)(A2)
                            , (iterator_< scalar_< double_<A0> > >)
                              (scalar_< fundamental_<A1> >)
                              ((target_< simd_< double_<A2>, boost::simd::tag::sse_ > >))
                            )
  {
    typedef typename A2::type result_type;
    inline result_type operator()(const A0& a0, const A1& a1, const A2&)const
    {
      return _mm_loadu_pd(a0+a1);
    }
  };
} } }

namespace boost { namespace simd { namespace ext
{
  BOOST_SIMD_FUNCTOR_IMPLEMENTATION( boost::simd::tag::unaligned_load_ , boost::simd::tag::sse2_
                            , (A0)(A1)
                            , (iterator_< scalar_< double_<A0> > >)
                              ((target_< simd_< double_<A1>, boost::simd::tag::sse_ > >))
                            )
  {
    typedef typename A1::type result_type;
    inline result_type operator()(const A0& a0, const A1&)const
    {
      return _mm_loadu_pd(a0);
    }
  };
} } }

//==============================================================================
// unaligned_load vector of float
//==============================================================================
namespace boost { namespace simd { namespace ext
{
  BOOST_SIMD_FUNCTOR_IMPLEMENTATION( boost::simd::tag::unaligned_load_ , boost::simd::tag::sse2_
                            , (A0)(A1)(A2)
                            , (iterator_< scalar_< single_<A0> > >)
                              (scalar_< fundamental_<A1> >)
                              ((target_< simd_< single_<A2>, boost::simd::tag::sse_ > >))
                            )
  {
    typedef typename A2::type result_type;
    inline result_type operator()(const A0& a0, const A1& a1, const A2&)const
    {
      return _mm_loadu_ps(a0+a1);
    }
  };
} } }

namespace boost { namespace simd { namespace ext
{
  BOOST_SIMD_FUNCTOR_IMPLEMENTATION( boost::simd::tag::unaligned_load_ , boost::simd::tag::sse2_
                            , (A0)(A1)
                            , (iterator_< scalar_< single_<A0> > >)
                              ((target_< simd_< single_<A1>, boost::simd::tag::sse_ > >))
                            )
  {
    typedef typename A1::type result_type;
    inline result_type operator()(const A0& a0, const A1&)const
    {
      return _mm_loadu_ps(a0);
    }
  };
} } }

//==============================================================================
// unaligned_load vector of integer
//==============================================================================
namespace boost { namespace simd { namespace ext
{
  BOOST_SIMD_FUNCTOR_IMPLEMENTATION( boost::simd::tag::unaligned_load_ , boost::simd::tag::sse2_
                            , (A0)(A1)(A2)
                            , (iterator_< scalar_< integer_<A0> > >)
                              (scalar_< fundamental_<A1> >)
                              ((target_< simd_< integer_<A2>, boost::simd::tag::sse_ > >))
                            )
  {
    typedef typename A2::type result_type;
    inline result_type operator()(const A0& a0, const A1& a1, const A2&)const
    {
      return _mm_loadu_si128(reinterpret_cast<__m128i const*>(a0+a1));
    }
  };
} } }

namespace boost { namespace simd { namespace ext
{
  BOOST_SIMD_FUNCTOR_IMPLEMENTATION( boost::simd::tag::unaligned_load_ , boost::simd::tag::sse2_
                            , (A0)(A1)
                            , (iterator_< scalar_< integer_<A0> > >)
                              ((target_< simd_< integer_<A1>, boost::simd::tag::sse_ > >))
                            )
  {
    typedef typename A1::type result_type;
    inline result_type operator()(const A0& a0, const A1&)const
    {
      return _mm_loadu_si128(reinterpret_cast<__m128i const*>(a0));
    }
  };
} } }

#endif
#endif

ext: hpp


text:
#ifndef MATH_HPP
#define MATH_HPP

#include <Eigen/Core>
#include <Eigen/Geometry>

template<class T, int M = Eigen::Dynamic, int N = Eigen::Dynamic>
using matrix = Eigen::Matrix<T, M, N>;

template<class T, int M = Eigen::Dynamic>
using vector = matrix<T, M, 1>;

using real = double;

using vec = vector<real>;

using vec4 = vector<real, 4>;
using vec3 = vector<real, 3>;
using vec2 = vector<real, 2>;
using vec1 = vector<real, 1>;

using mat = matrix<real>;
using mat4x4 = matrix<real, 4, 4>;
using mat3x3 = matrix<real, 3, 3>;

template<class T>
using quaternion = Eigen::Quaternion<T>;

using quat = quaternion<real>;

struct rigid {
  quat orient;
  vec3 pos;

  rigid(): orient(1, 0, 0, 0), pos(0, 0, 0) {}

  static rigid translation(real x, real y, real z) {
    rigid res;
    res.pos = {x, y, z};
    return res;
  }

  static rigid translation(vec3 t) {
    return translation(t.x(), t.y(), t.z());
  }

  static rigid rotation(quat q) {
    rigid res;
    res.orient = q;
    return res;
  }

  rigid operator*(const rigid& other) const {
    rigid res;
    res.orient = orient * other.orient;
    res.pos = pos + orient * other.pos;
    return res;
  }

  rigid inv() const {
    rigid res;
    res.orient = orient.conjugate();
    res.pos = -(res.orient * pos);
    return res;
  }

};

#endif

max_stars_repo_name: maxime-tournier/cpp

max_issues_repo_name: maxime-tournier/cpp

max_forks_repo_name: maxime-tournier/cpp


text:
/*!
@brief Unit tests for CTMXWriter class
@author Ryan Ginstrom
*/

#include "StdAfx.h"
#include ".\tmxwriter.h"
#include "ResHtmlFile.h"
#include "record_local.h"
#include "output_device_fake.h"
#include "MockListener.h"

#include <boost/test/unit_test.hpp>
#ifdef UNIT_TEST
BOOST_AUTO_TEST_SUITE( CTMXWriterTestCase )

	using namespace app_props ;

	// write
	BOOST_AUTO_TEST_CASE( write_footer )
	{
		CMockListener dummy ;
		CTMXWriter tmx_writer(static_cast< CProgressListener* >(&dummy),
				get_props(),
				CUserName().as_wstring() ) ;
		OutputDeviceFake *device = new OutputDeviceFake ;
		tmx_writer.m_file = std::shared_ptr<OutputDevice>(device) ;

		tmx_writer.write_footer() ;
		string actual = string2string(device->m_value);
		string expected = "  \n</tmx>" ;
		BOOST_CHECK_EQUAL(expected, actual) ;
		BOOST_CHECK_EQUAL(1u, device->m_sensing_variable.size()) ;
		BOOST_CHECK_EQUAL(string("write_wstring"), device->m_sensing_variable[0]) ;
	}
	BOOST_AUTO_TEST_CASE( write_tu)
	{
		CMockListener dummy ;
		CTMXWriter tmx_writer(static_cast< CProgressListener* >(&dummy),
			get_props(),
			CUserName().as_wstring() ) ;
		OutputDeviceFake *device = new OutputDeviceFake ;
		tmx_writer.m_file = std::shared_ptr<OutputDevice>(device) ;

		tmx_writer.tmplText = L"{$srcseg} {$transseg}" ;

		mem_engine::record_pointer rec(new mem_engine::record_local()) ;
		rec->set_source(L"spam") ;
		rec->set_trans(L"egg");
		tmx_writer.write_tu(rec) ;
		string actual = string2string(device->m_value) ;
		string expected = "spam egg" ;
		BOOST_CHECK_EQUAL(expected, actual) ;
		BOOST_CHECK_EQUAL(1u, device->m_sensing_variable.size()) ;
		BOOST_CHECK_EQUAL(string("write_wstring"), device->m_sensing_variable[0]) ;
	}
	BOOST_AUTO_TEST_CASE( write_header)
	{
		CMockListener dummy ;
		CTMXWriter tmx_writer(static_cast< CProgressListener* >(&dummy),
			get_props(),
			CUserName().as_wstring() ) ;
		OutputDeviceFake *device = new OutputDeviceFake ;
		tmx_writer.m_file = std::shared_ptr<OutputDevice>(device) ;

		tmx_writer.m_src_lang = L"Pekinese" ;

		tmx_writer.write_header() ;
		const wstring text = device->m_value ;

		BOOST_CHECK(text.find(L"<!DOCTYPE tmx SYSTEM \"tmx14.dtd\">") != wstring::npos) ;
		BOOST_CHECK(text.find(L"<tmx version=\"1.4\">") != wstring::npos) ;
		BOOST_CHECK(text.find(L"m_sensing_variable.size()) ;
		BOOST_CHECK_EQUAL(string("write_wstring"), device->m_sensing_variable[0]) ;
	}

	// make_tu
	BOOST_AUTO_TEST_CASE( make_tu_simple )
	{
		CMockListener dummy ;
		CTMXWriter tmx_writer(static_cast< CProgressListener* >(&dummy),
			get_props(),
			CUserName().as_wstring() ) ;

		mem_engine::record_pointer rec(new mem_engine::record_local()) ;
		rec->set_source(L"spam") ;
		rec->set_trans(L"egg");
		wstring text = tmx_writer.make_tu(rec, L"{$srcseg} {$transseg}") ;
		wstring expected = L"spam egg" ;
		BOOST_CHECK_EQUAL(expected, text) ;
	}
	BOOST_AUTO_TEST_CASE( make_tu_real_trans )
	{
		CMockListener dummy ;
		CTMXWriter tmx_writer(static_cast< CProgressListener* >(&dummy),
			get_props(),
			CUserName().as_wstring() ) ;

		mem_engine::record_pointer rec(new mem_engine::record_local()) ;
		rec->set_source(L"spam") ;
		rec->set_trans(L"egg");
		CResHtmlFile resFile( _T("TMX_TU") ) ;
		wstring tmplText = (LPCWSTR)resFile.text() ;
		wstring text = tmx_writer.make_tu(rec, tmplText) ;
		wstring expected = L"<seg>egg</seg>" ;
		BOOST_CHECK(text.find(expected) != wstring::npos) ;
	}
	BOOST_AUTO_TEST_CASE( make_tu_real_trans_bad_amps )
	{
		CMockListener dummy ;
		CTMXWriter tmx_writer(static_cast< CProgressListener* >(&dummy),
			get_props(),
			CUserName().as_wstring() ) ;

		mem_engine::record_pointer rec(new mem_engine::record_local()) ;
		rec->set_source(L"spam") ;
		rec->set_trans(L"egg & spam");
		CResHtmlFile resFile( _T("TMX_TU") ) ;
		wstring tmplText = (LPCWSTR)resFile.text() ;
		wstring text = tmx_writer.make_tu(rec, tmplText) ;
		wstring expected = L"<seg>egg & spam</seg>" ;
		BOOST_CHECK(text.find(expected) != wstring::npos) ;
	}
	BOOST_AUTO_TEST_CASE( make_tu_real_source)
	{
		CMockListener dummy ;
		CTMXWriter tmx_writer(static_cast< CProgressListener* >(&dummy),
			get_props(),
			CUserName().as_wstring() ) ;

		mem_engine::record_pointer rec(new mem_engine::record_local()) ;
		rec->set_source(L"spam") ;
		rec->set_trans(L"egg");
		CResHtmlFile resFile( _T("TMX_TU") ) ;
		wstring tmplText = (LPCWSTR)resFile.text() ;
		wstring text = tmx_writer.make_tu(rec, tmplText) ;
		wstring expected = L"<seg>spam</seg>" ;
		BOOST_CHECK(text.find(expected) != wstring::npos) ;
	}
	BOOST_AUTO_TEST_CASE( make_tu_real_creationid)
	{
		CMockListener dummy ;
		CTMXWriter tmx_writer(static_cast< CProgressListener* >(&dummy),
			get_props(),
			CUserName().as_wstring() ) ;

		mem_engine::record_pointer rec(new mem_engine::record_local()) ;
		rec->set_source(L"spam") ;
		rec->set_trans(L"egg");
		rec->set_creator(L"Elephant") ;
		CResHtmlFile resFile( _T("TMX_TU") ) ;
		wstring tmplText = (LPCWSTR)resFile.text() ;
		wstring text = tmx_writer.make_tu(rec, tmplText) ;
		wstring expected = L"creationid=\"Elephant\"" ;
		BOOST_CHECK(text.find(expected) != wstring::npos) ;
	}
	BOOST_AUTO_TEST_CASE( make_tu_real_changeid)
	{
		CMockListener dummy ;
		CTMXWriter tmx_writer(static_cast< CProgressListener* >(&dummy),
			get_props(),
			CUserName().as_wstring() ) ;

		mem_engine::record_pointer rec(new mem_engine::record_local()) ;
		rec->set_source(L"spam") ;
		rec->set_trans(L"egg");
		rec->set_modified_by(L"Snuffles") ;
		CResHtmlFile resFile( _T("TMX_TU") ) ;
		wstring tmplText = (LPCWSTR)resFile.text() ;
		wstring text = tmx_writer.make_tu(rec, tmplText) ;
		wstring expected = L"changeid=\"Snuffles\"" ;
		BOOST_CHECK(text.find(expected) != wstring::npos) ;
	}

	BOOST_AUTO_TEST_CASE( SetSourceAndTrans )
	{
		CMockListener dummy ;
		CTMXWriter tmx_writer(static_cast< CProgressListener* >(&dummy),
			get_props(),
			CUserName().as_wstring() ) ;
		tmx_writer.set_src_lang( L"jp" ) ;
		BOOST_CHECK_EQUAL ( L"JP", tmx_writer.m_src_lang ) ;
		tmx_writer.set_target_lang( L"eN-US" ) ;
		BOOST_CHECK_EQUAL( L"EN-US", tmx_writer.m_target_lang) ;
	}
	BOOST_AUTO_TEST_CASE( cleanUpForTmx )
	{
		CMockListener dummy ;
		CTMXWriter tmx_writer(static_cast< CProgressListener* >(&dummy),
			get_props(),
			CUserName().as_wstring() ) ;
		wstring inStr = L"f\too hi!" ;
		wstring outStr = tmx_writer.cleanUpForTMX( inStr ) ;
		wstring expected = L"foo hi!" ;
		BOOST_CHECK_EQUAL( outStr, expected) ;
	}
BOOST_AUTO_TEST_SUITE_END()

BOOST_AUTO_TEST_SUITE( CTmxWriterTestCaseSegments )

	using namespace app_props ;

	// get_segment
	BOOST_AUTO_TEST_CASE( getSegmentSimple )
	{
		CMockListener dummy ;
		CTMXWriter tmx_writer(static_cast< CProgressListener* >(&dummy),
			get_props(),
			CUserName().as_wstring() ) ;
		wstring inStr = L"foo" ;
		wstring outStr =tmx_writer.get_segment( inStr ) ;
		BOOST_CHECK_EQUAL( inStr, outStr ) ;
		// try it twice...
		outStr =tmx_writer.get_segment( inStr ) ;
		BOOST_CHECK_EQUAL( outStr, inStr) ;
	}
	BOOST_AUTO_TEST_CASE( getSegmentBr )
	{
		CMockListener dummy ;
		CTMXWriter tmx_writer(static_cast< CProgressListener* >(&dummy),
			get_props(),
			CUserName().as_wstring() ) ;
		wstring inStr = L"foo
" ;
		wstring outStr =tmx_writer.get_segment( inStr ) ;
		wstring expected = L"foo<it pos=\"begin\" x=\"1\"><br /></it>" ;
		BOOST_CHECK_EQUAL( outStr, expected) ;
	}
	BOOST_AUTO_TEST_CASE( getSegmentP )
	{
		CMockListener dummy ;
		CTMXWriter tmx_writer(static_cast< CProgressListener* >(&dummy),
			get_props(),
			CUserName().as_wstring() ) ;
		wstring inStr = L"
foo
" ;
		wstring outStr =tmx_writer.get_segment( inStr ) ;
		wstring expected = L"<bpt i=\"1\" x=\"1\"><p></bpt>foo<ept i=\"1\"></p></ept>" ;
		BOOST_CHECK_EQUAL( outStr, expected) ;
	}
	BOOST_AUTO_TEST_CASE( getSegmentDivSpan )
	{
		CMockListener dummy ;
		CTMXWriter tmx_writer(static_cast< CProgressListener* >(&dummy),
			get_props(),
			CUserName().as_wstring() ) ;
		wstring inStr = L"
foo
" ;
		wstring outStr =tmx_writer.get_segment( inStr ) ;
		wstring expected = L"<bpt i=\"1\" x=\"1\"><div style=\"float:left;\"></bpt><bpt i=\"2\" x=\"2\"><span style=\"color:blue;\"></bpt>foo<ept i=\"2\"></span></ept><ept i=\"1\"></div></ept>" ;
		BOOST_CHECK_EQUAL( outStr, expected) ;
	}

	BOOST_AUTO_TEST_CASE( get_segment_bad_html )
	{
		CMockListener dummy ;
		CTMXWriter tmx_writer(static_cast< CProgressListener* >(&dummy),
			get_props(),
			CUserName().as_wstring() ) ;
		wstring inStr = L"This is < & > not cool..." ;
		wstring outStr =tmx_writer.get_segment( inStr ) ;
		wstring expected = L"This is < & > not cool..." ;
		BOOST_CHECK_EQUAL( outStr, expected) ;
	}
	BOOST_AUTO_TEST_CASE( get_segment_bad_html_with_tag )
	{
		CMockListener dummy ;
		CTMXWriter tmx_writer(static_cast< CProgressListener* >(&dummy),
			get_props(),
			CUserName().as_wstring() ) ;
		wstring inStr = L"This is < & > not cool...
foo
" ;
		wstring outStr =tmx_writer.get_segment( inStr ) ;
		wstring expected = L"This is < & > not cool...<bpt i=\"1\" x=\"1\"><div style=\"float:left;\"></bpt><bpt i=\"2\" x=\"2\"><span style=\"color:blue;\"></bpt>foo<ept i=\"2\"></span></ept><ept i=\"1\"></div></ept>" ;
		BOOST_CHECK_EQUAL( outStr, expected) ;
	}

BOOST_AUTO_TEST_SUITE_END()

#endif

ext: cpp

max_stars_repo_name: ultimatezen/felix

max_issues_repo_name: ultimatezen/felix

max_forks_repo_name: ultimatezen/felix


text:
/*=============================================================================
    Copyright (c) 2003 Joel de Guzman

    Use, modification and distribution is subject to the Boost Software
    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
    http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(FUSION_ADAPT_DEREF_TRAITS_HPP)
#define FUSION_ADAPT_DEREF_TRAITS_HPP

#include <boost/spirit/fusion/iterator/deref.hpp>

namespace boost { namespace fusion { namespace detail
{
    struct adapt_deref_traits
    {
        template <typename Iterator>
        struct apply
        {
            typedef typename
                meta::deref<typename Iterator::first_type>::type
            type;

            static type
            call(Iterator const& i)
            {
                return *i.first;
            }
        };
    };
}}}

#endif

max_stars_repo_name: Imperator-Knoedel/Sunset

max_issues_repo_name: Imperator-Knoedel/Sunset

max_forks_repo_name: Imperator-Knoedel/Sunset


text:
// Copyright (c) 2014-2018 The Beenode Core developers

#include "test/test_beenode.h"

#include <boost/test/unit_test.hpp>

BOOST_FIXTURE_TEST_SUITE(ratecheck_tests, BasicTestingSetup)

BOOST_AUTO_TEST_CASE(ratecheck_test)
{

}

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: bee-group/BeeNode

max_issues_repo_name: bee-group/BeeNode

max_forks_repo_name: bee-group/BeeNode


text:
// Copyright Paul A. Bristow 2017, 2018
// Copyright John Z. Maddock 2017

// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or
//  copy at http ://www.boost.org/LICENSE_1_0.txt).

/*! \brief Graph showing differences of Lambert W function double from nearest representable values.

\details

*/

#include <boost/math/special_functions/lambert_w.hpp>
using boost::math::lambert_w0;
using boost::math::lambert_wm1;
#include <boost/math/special_functions.hpp>
using boost::math::isfinite;
#include <boost/svg_plot/svg_2d_plot.hpp>
using namespace boost::svg;

// For higher precision computation of Lambert W.
#include <boost/multiprecision/cpp_bin_float.hpp>
#include <boost/math/special_functions/next.hpp> // For float_distance.
using boost::math::float_distance;

#include <iostream>
// using std::cout;
// using std::endl;
#include <exception>
#include <stdexcept>
#include <string>
#include <array>
#include <vector>
#include <utility>
using std::pair;
#include <map>
using std::map;
#include <set>
using std::multiset;
#include <limits>
using std::numeric_limits;
#include <cmath> // exp

/*!
*/

int main()
{
  try
  {
    std::cout << "Lambert W errors graph." << std::endl;
    using boost::multiprecision::cpp_bin_float_50;
    using boost::multiprecision::cpp_bin_float_quad;

    typedef cpp_bin_float_quad HPT; // High precision type.

    using boost::math::float_distance;
    using boost::math::policies::precision;
    using boost::math::policies::digits10;
    using boost::math::policies::digits2;
    using boost::math::policies::policy;

    std::cout.precision(std::numeric_limits<double>::max_digits10);

    //[lambert_w_graph_1

    //] [/lambert_w_graph_1]
    {
      std::map<const double, double> w0s;   // Lambert W0 branch values, default double precision, digits2 = 53.
      std::map<const double, double> w0s_50;   // Lambert W0 branch values digits2 = 50.

      int max_distance = 0;
      int total_distance = 0;
      int count = 0;
      const int bits = 7;
      double min_z = -0.367879; // Close to singularity at -0.3678794411714423215955237701614608727 -exp(-1)
      //double min_z = 0.06; // Above 0.05 switch point.
      double max_z = 99.99;
      double step_z = 0.05;

      for (HPT z = min_z; z < max_z; z += step_z)
      {
        double zd = static_cast<double>(z);
        double w0d = lambert_w0(zd); // double result from same default.
        HPT w0_best = lambert_w0<HPT>(z);
        double w0_best_d = static_cast<double>(w0_best); // reference result.
       // w0s[zd] = (w0d - w0_best_d); // absolute difference.
        // w0s[z] = 100 * (w0 - w0_best) / w0_best; // difference relative % .
        w0s[zd] = float_distance<double>(w0d, w0_best_d); // difference in bits.
        double fd = float_distance<double>(w0d, w0_best_d);
        int distance = static_cast<int>(fd);
        int abs_distance = abs(distance);

         // std::cout << count << " " << zd << " " << w0d << " " << w0_best_d
         //   << ", Difference = " << w0d - w0_best_d << ", % = " << (w0d - w0_best_d) / w0d << ", Distance = " << distance << std::endl;

        total_distance += abs_distance;
        if (abs_distance > max_distance)
        {
          max_distance = abs_distance;
        }
        count++;
      } // for z
      std::cout << "points " << count << std::endl;
      std::cout.precision(3);
      std::cout << "max distance " << max_distance << ", total distances = " << total_distance
        << ", mean distance " << (float)total_distance / count << std::endl;

      typedef std::map<const double, double>::const_iterator Map_Iterator;

   /* for (std::map<const double, double>::const_iterator it = w0s.begin(); it != w0s.end(); ++it)
      {
        std::cout  << " " << *(it) << "\n";
      }
  */
      svg_2d_plot data_plot_0; // <-0.368, -46> <-0.358, -4> <-0.348, 1>...

      data_plot_0.title("Lambert W0 function differences from 'best' for double.")
        .title_font_size(11)
        .x_size(400)
        .y_size(200)
        .legend_on(false)
        //.legend_font_weight(1)
        .x_label("z")
        .y_label("W0 difference (bits)")
        //.x_label_on(true)
        //.y_label_on(true)
        //.xy_values_on(false)
        .x_range(-1, 100.)
        .y_range(-4., +4.)
        .x_major_interval(10.)
        .y_major_interval(2.)
        .x_major_grid_on(true)
        .y_major_grid_on(true)
        .x_label_font_size(9)
        .y_label_font_size(9)
        //.x_values_on(true)
        //.y_values_on(true)
        .y_values_rotation(horizontal)
        //.plot_window_on(true)
        .x_values_precision(3)
        .y_values_precision(3)
        .coord_precision(3) // Needed to avoid stepping on curves.
        //.coord_precision(4) // Needed to avoid stepping on curves.
        .copyright_holder("Paul A. Bristow")
        .copyright_date("2018")
        //.background_border_color(black);
        ;

      data_plot_0.plot(w0s, "W0 branch").line_color(red).shape(none).line_on(true).bezier_on(false).line_width(0.2);
      //data_plot.plot(wm1s, "W-1 branch").line_color(blue).shape(none).line_on(true).bezier_on(false).line_width(1);
      data_plot_0.write("./lambert_w0_errors_graph");

    } // end W0 branch plot.
    { // Repeat for Lambert W-1 branch.

      std::map<const double, double> wm1s;   // Lambert W-1 branch values.
      std::map<const double, double> wm1s_50;   // Lambert Wm1 branch values digits2 = 50.

      int max_distance = 0;
      int total_distance = 0;
      int count = 0;
      const int bits = 7;
      double min_z = -0.367879; // Close to singularity at -0.3678794411714423215955237701614608727 -exp(-1)
                                //double min_z = 0.06; // Above 0.05 switch point.
      double max_z = -0.0001;
      double step_z = 0.001;

      for (HPT z = min_z; z < max_z; z += step_z)
      {
        if (z > max_z)
        {
          break;
        }
        double zd = static_cast<double>(z);
        double wm1d = lambert_wm1(zd); // double result from same default.
        HPT wm1_best = lambert_wm1<HPT>(z);
        double wm1_best_d = static_cast<double>(wm1_best); // reference result.
                                                         // wm1s[zd] = (wm1d - wm1_best_d); // absolute difference.
                                                         // wm1s[z] = 100 * (wm1 - wm1_best) / wm1_best; // difference relative % .
        wm1s[zd] = float_distance<double>(wm1d, wm1_best_d); // difference in bits.
        double fd = float_distance<double>(wm1d, wm1_best_d);
        int distance = static_cast<int>(fd);
        int abs_distance = abs(distance);

         //std::cout << count << " " << zd << " " << wm1d << " " << wm1_best_d
         //  << ", Difference = " << wm1d - wm1_best_d << ", % = " << (wm1d - wm1_best_d) / wm1d << ", Distance = " << distance << std::endl;

        total_distance += abs_distance;
        if (abs_distance > max_distance)
        {
          max_distance = abs_distance;
        }
        count++;

      } // for z
      std::cout << "points " << count << std::endl;
      std::cout.precision(3);
      std::cout << "max distance " << max_distance << ", total distances = " << total_distance
        << ", mean distance " << (float)total_distance / count << std::endl;

      typedef std::map<const double, double>::const_iterator Map_Iterator;

      /* for (std::map<const double, double>::const_iterator it = wm1s.begin(); it != wm1s.end(); ++it)
      {
      std::cout  << " " << *(it) << "\n";
      }
      */
      svg_2d_plot data_plot_m1; // <-0.368, -46> <-0.358, -4> <-0.348, 1>...

      data_plot_m1.title("Lambert W-1 function differences from 'best' for double.")
        .title_font_size(11)
        .x_size(400)
        .y_size(200)
        .legend_on(false)
        //.legend_font_weight(1)
        .x_label("z")
        .y_label("W-1 difference (bits)")
        .x_range(-0.39, +0.0001)
        .y_range(-4., +4.)
        .x_major_interval(0.1)
        .y_major_interval(2.)
        .x_major_grid_on(true)
        .y_major_grid_on(true)
        .x_label_font_size(9)
        .y_label_font_size(9)
        //.x_values_on(true)
        //.y_values_on(true)
        .y_values_rotation(horizontal)
        //.plot_window_on(true)
        .x_values_precision(3)
        .y_values_precision(3)
        .coord_precision(3) // Needed to avoid stepping on curves.
                            //.coord_precision(4) // Needed to avoid stepping on curves.
        .copyright_holder("Paul A. Bristow")
        .copyright_date("2018")
        //.background_border_color(black);
        ;
        data_plot_m1.plot(wm1s, "W-1 branch").line_color(darkblue).shape(none).line_on(true).bezier_on(false).line_width(0.2);
        data_plot_m1.write("./lambert_wm1_errors_graph");
    }
  }
  catch (std::exception& ex)
  {
    std::cout << ex.what() << std::endl;
  }
}  // int main()

   /*
   //[lambert_w_errors_graph_1_output
   Lambert W errors graph.
   points 2008
   max distance 46, total distances = 717, mean distance 0.357

   points 368
   max distance 23, total distances = 329, mean distance 0.894

   //] [/lambert_w_errors_graph_1_output]
   */

max_stars_repo_name: cpp-pm/boost

max_issues_repo_name: cpp-pm/boost

max_forks_repo_name: cpp-pm/boost


text:
// Copyright (C) 2015 The Regents of the University of California (Regents).
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//
//     * Neither the name of The Regents or University of California nor the
//       names of its contributors may be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// Please contact the author of this library if you have any questions.
// Author: Chris Sweeney (cmsweeney@cs.ucsb.edu)

#include "theia/sfm/bundle_adjustment/optimize_relative_position_with_known_rotation.h"

#include <ceres/rotation.h>
#include <Eigen/Core>
#include <glog/logging.h>
#include <algorithm>
#include <vector>

#include "theia/math/util.h"
#include "theia/matching/feature_correspondence.h"
#include "theia/sfm/triangulation/triangulation.h"

namespace theia {
namespace {

// Creates the constraint matrix such that ||A * t|| is minimized, where A is
// R_i * f_i x R_j * f_j. Given known rotations, we can solve for the
// relative translation from this constraint matrix.
void CreateConstraintMatrix(
    const std::vector<FeatureCorrespondence>& correspondences,
    const Eigen::Vector3d& rotation1,
    const Eigen::Vector3d& rotation2,
    Eigen::MatrixXd* constraint_matrix) {
  constraint_matrix->resize(3, correspondences.size());

  Eigen::Matrix3d rotation_matrix1;
  ceres::AngleAxisToRotationMatrix(
      rotation1.data(), ceres::ColumnMajorAdapter3x3(rotation_matrix1.data()));
  Eigen::Matrix3d rotation_matrix2;
  ceres::AngleAxisToRotationMatrix(
      rotation2.data(), ceres::ColumnMajorAdapter3x3(rotation_matrix2.data()));

  for (int i = 0; i < correspondences.size(); i++) {
    const Eigen::Vector3d rotated_feature1 =
        rotation_matrix1.transpose() *
        correspondences[i].feature1.point_.homogeneous();
    const Eigen::Vector3d rotated_feature2 =
        rotation_matrix2.transpose() *
        correspondences[i].feature2.point_.homogeneous();

    constraint_matrix->col(i) =
        rotated_feature2.cross(rotated_feature1).transpose() *
        rotation_matrix1.transpose();
  }
}

// Determines if the majority of the points are in front of the cameras. This is
// useful for determining the sign of the relative position. Returns true if
// more than 50% of correspondences are in front of both cameras and false
// otherwise.
bool MajorityOfPointsInFrontOfCameras(
    const std::vector<FeatureCorrespondence>& correspondences,
    const Eigen::Vector3d& rotation1,
    const Eigen::Vector3d& rotation2,
    const Eigen::Vector3d& relative_position) {
  // Compose the relative rotation.
  Eigen::Matrix3d rotation_matrix1, rotation_matrix2;
  ceres::AngleAxisToRotationMatrix(
      rotation1.data(), ceres::ColumnMajorAdapter3x3(rotation_matrix1.data()));
  ceres::AngleAxisToRotationMatrix(
      rotation2.data(), ceres::ColumnMajorAdapter3x3(rotation_matrix2.data()));
  const Eigen::Matrix3d relative_rotation_matrix =
      rotation_matrix2 * rotation_matrix1.transpose();

  // Tests all points for cheirality.
  int num_points_in_front_of_cameras = 0;
  for (const FeatureCorrespondence& match : correspondences) {
    if (IsTriangulatedPointInFrontOfCameras(match,
                                            relative_rotation_matrix,
                                            relative_position)) {
      ++num_points_in_front_of_cameras;
    }
  }

  return num_points_in_front_of_cameras > (correspondences.size() / 2);
}

}  // namespace

// Given known camera rotations and feature correspondences, this method solves
// for the relative translation that optimizes the epipolar error
// f_i * E * f_j^t = 0.
bool OptimizeRelativePositionWithKnownRotation(
    const std::vector<FeatureCorrespondence>& correspondences,
    const Eigen::Vector3d& rotation1,
    const Eigen::Vector3d& rotation2,
    Eigen::Vector3d* relative_position) {
  CHECK_NOTNULL(relative_position);

  // Set the initial relative position to random. This helps avoid a bad local
  // minima that is achieved from poor initialization.
  relative_position->setRandom();

  // Constants used for the IRLS solving.
  const double eps = 1e-5;
  const int kMaxIterations = 100;
  const int kMaxInnerIterations = 10;
  const double kMinWeight = 1e-7;

  // Create the constraint matrix from the known correspondences and rotations.
  Eigen::MatrixXd constraint_matrix;
  CreateConstraintMatrix(correspondences,
                         rotation1,
                         rotation2,
                         &constraint_matrix);

  // Initialize the weighting terms for each correspondence.
  Eigen::VectorXd weights(correspondences.size());
  weights.setConstant(1.0);

  // Solve for the relative positions using a robust IRLS.
  double cost = 0;
  int num_inner_iterations = 0;
  for (int i = 0;
       i < kMaxIterations && num_inner_iterations < kMaxInnerIterations;
       i++) {
    // Limit the minimum weight at kMinWeight.
    weights = (weights.array() < kMinWeight).select(kMinWeight, weights);

    // Apply the weights to the constraint matrix.
    const Eigen::Matrix3d lhs = constraint_matrix *
                                weights.asDiagonal().inverse() *
                                constraint_matrix.transpose();

    // Solve for the relative position which is the null vector of the weighted
    // constraints.
    const Eigen::Vector3d new_relative_position =
        lhs.jacobiSvd(Eigen::ComputeFullU).matrixU().rightCols<1>();

    // Update the weights based on the current errors.
    weights =
        (new_relative_position.transpose() * constraint_matrix).array().abs();

    // Compute the new cost.
    const double new_cost = weights.sum();

    // Check for convergence.
    const double delta = std::max(std::abs(cost - new_cost),
                                  1 - new_relative_position.squaredNorm());

    // If we have good convergence, attempt an inner iteration.
    if (delta <= eps) {
      ++num_inner_iterations;
    } else {
      num_inner_iterations = 0;
    }

    cost = new_cost;
    *relative_position = new_relative_position;
  }

  // The position solver above does not consider the sign of the relative
  // position. We can determine the sign by choosing the sign that puts the most
  // points in front of the camera.
  if (!MajorityOfPointsInFrontOfCameras(correspondences,
                                        rotation1,
                                        rotation2,
                                        *relative_position)) {
    *relative_position *= -1.0;
  }

  return true;
}

}  // namespace theia

ext: cc


text:
/*
 * Copyright (c) 2009-2016, Albertas Vyšniauskas
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
 *     * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "BrightnessDarkness.h"
#include "ColorSource.h"
#include "ColorSourceManager.h"
#include "DragDrop.h"
#include "GlobalState.h"
#include "ToolColorNaming.h"
#include "uiUtilities.h"
#include "ColorList.h"
#include "MathUtil.h"
#include "ColorRYB.h"
#include "gtk/ColorWidget.h"
#include "gtk/Range2D.h"
#include "uiColorInput.h"
#include "CopyPaste.h"
#include "Converter.h"
#include "DynvHelpers.h"
#include "I18N.h"
#include "color_names/ColorNames.h"
#include "gtk/LayoutPreview.h"
#include "layout/Layout.h"
#include "layout/Layouts.h"
#include "layout/Style.h"
#include "StandardMenu.h"
#include <gdk/gdkkeysyms.h>
#include <boost/format.hpp>
#include <math.h>
#include <string.h>
#include <sstream>
#include <iostream>
using namespace std;
using namespace layout;

typedef struct BrightnessDarknessArgs{
	ColorSource source;
	GtkWidget* main;
	GtkWidget* statusbar;
	Color color;
	GtkWidget *brightness_darkness;
	GtkWidget *layout_view;
	System* layout_system;
	struct dynvSystem *params;
	GlobalState* gs;
}BrightnessDarknessArgs;

struct BrightnessDarknessColorNameAssigner: public ToolColorNameAssigner
{
	protected:
		stringstream m_stream;
		const char *m_ident;
	public:
		BrightnessDarknessColorNameAssigner(GlobalState *gs):
			ToolColorNameAssigner(gs)
		{
		}
		void assign(ColorObject *color_object, Color *color, const char *ident)
		{
			m_ident = ident;
			ToolColorNameAssigner::assign(color_object, color);
		}
		virtual std::string getToolSpecificName(ColorObject *color_object, const Color *color)
		{
			m_stream.str("");
			m_stream << color_names_get(m_gs->getColorNames(), color, false) << " " << _("brightness darkness") << " " << m_ident;
			return m_stream.str();
		}
};
static void calc(BrightnessDarknessArgs *args, bool preview, bool save_settings)
{
	double brightness = gtk_range_2d_get_x(GTK_RANGE_2D(args->brightness_darkness));
	double darkness = gtk_range_2d_get_y(GTK_RANGE_2D(args->brightness_darkness));
	if (save_settings){
		dynv_set_float(args->params, "brightness", brightness);
		dynv_set_float(args->params, "darkness", brightness);
	}
	Color color, hsl_orig, hsl, r;
	color_copy(&args->color, &color);
	color_rgb_to_hsl(&color, &hsl_orig);
	Box* box;
	string name;
	for (int i = 1; i <= 4; i++){
		color_copy(&hsl_orig, &hsl);
		hsl.hsl.lightness = mix_float(hsl.hsl.lightness, mix_float(hsl.hsl.lightness, 1, brightness), i / 4.0); //clamp_float(hsl.hsl.lightness + brightness / 8.0 * i, 0, 1);
		color_hsl_to_rgb(&hsl, &r);
		name = boost::str(boost::format("b%d") % i);
		box = args->layout_system->GetNamedBox(name.c_str());
		if (box && box->style){
			color_copy(&r, &box->style->color);
		}
		color_copy(&hsl_orig, &hsl);
		hsl.hsl.lightness = mix_float(hsl.hsl.lightness, mix_float(hsl.hsl.lightness, 0, darkness), i / 4.0); //clamp_float(hsl.hsl.lightness - darkness / 8.0 * i, 0, 1);
		color_hsl_to_rgb(&hsl, &r);
		name = boost::str(boost::format("c%d") % i);
		box = args->layout_system->GetNamedBox(name.c_str());
		if (box && box->style){
			color_copy(&r, &box->style->color);
		}
	}
	gtk_widget_queue_draw(GTK_WIDGET(args->layout_view));
}
static void update(GtkWidget *widget, BrightnessDarknessArgs *args)
{
	calc(args, true, false);
}
static int source_get_color(BrightnessDarknessArgs *args, ColorObject** color)
{
	Style* style = 0;
	Color c;
	if (gtk_layout_preview_get_current_color(GTK_LAYOUT_PREVIEW(args->layout_view), &c) == 0){
		if (gtk_layout_preview_get_current_style(GTK_LAYOUT_PREVIEW(args->layout_view), &style) != 0){
			return -1;
		}
		*color = color_list_new_color_object(args->gs->getColorList(), &c);
		BrightnessDarknessColorNameAssigner name_assigner(args->gs);
		name_assigner.assign(*color, &c, style->label.c_str());
		return 0;
	}
	return -1;
}
static int source_set_color(BrightnessDarknessArgs *args, ColorObject* color_object)
{
	Color color = color_object->getColor();
	color_copy(&color, &args->color);
	gtk_layout_preview_set_color_named(GTK_LAYOUT_PREVIEW(args->layout_view), &color, "main");
	calc(args, true, false);
	return 0;
}
static ColorObject* get_color_object(struct DragDrop* dd)
{
	BrightnessDarknessArgs* args = (BrightnessDarknessArgs*)dd->userdata;
	ColorObject* colorobject;
	if (source_get_color(args, &colorobject) == 0){
		return colorobject;
	}
	return 0;
}
static int set_color_object_at(struct DragDrop* dd, ColorObject* color_object, int x, int y, bool move)
{
	BrightnessDarknessArgs* args = (BrightnessDarknessArgs*)dd->userdata;
	Color color = color_object->getColor();
	color_copy(&color, &args->color);
	gtk_layout_preview_set_color_named(GTK_LAYOUT_PREVIEW(args->layout_view), &color, "main");
	calc(args, true, false);
	return 0;
}
static bool test_at(struct DragDrop* dd, int x, int y)
{
	BrightnessDarknessArgs* args = (BrightnessDarknessArgs*)dd->userdata;
	gtk_layout_preview_set_focus_named(GTK_LAYOUT_PREVIEW(args->layout_view), "main");
	return gtk_layout_preview_is_selected(GTK_LAYOUT_PREVIEW(args->layout_view));
}
static void edit_cb(GtkWidget *widget, gpointer item)
{
	BrightnessDarknessArgs* args = (BrightnessDarknessArgs*)item;
	ColorObject *color_object;
	ColorObject* new_color_object = nullptr;
	if (source_get_color(args, &color_object) == 0){
		if (dialog_color_input_show(GTK_WINDOW(gtk_widget_get_toplevel(args->main)), args->gs, color_object, &new_color_object ) == 0){
			source_set_color(args, new_color_object);
			new_color_object->release();
		}
		color_object->release();
	}
}
static void paste_cb(GtkWidget *widget, BrightnessDarknessArgs* args)
{
	ColorObject* color_object;
	if (copypaste_get_color_object(&color_object, args->gs) == 0){
		source_set_color(args, color_object);
		color_object->release();
	}
}
static void add_to_palette_cb(GtkWidget *widget, gpointer item)
{
	BrightnessDarknessArgs* args = (BrightnessDarknessArgs*)item;
	ColorObject *color_object;
	if (source_get_color(args, &color_object) == 0){
		color_list_add_color_object(args->gs->getColorList(), color_object, 1);
		color_object->release();
	}
}
static void add_all_to_palette_cb(GtkWidget *widget, BrightnessDarknessArgs *args)
{
	ColorObject *color_object;
	BrightnessDarknessColorNameAssigner name_assigner(args->gs);
	for (list<Style*>::iterator i = args->layout_system->styles.begin(); i != args->layout_system->styles.end(); i++){
		color_object = color_list_new_color_object(args->gs->getColorList(), &(*i)->color);
		name_assigner.assign(color_object, &(*i)->color, (*i)->label.c_str());
		color_list_add_color_object(args->gs->getColorList(), color_object, 1);
		color_object->release();
	}
}
static gboolean button_press_cb(GtkWidget *widget, GdkEventButton *event, BrightnessDarknessArgs* args)
{
	GtkWidget *menu;
	if (event->button == 1 && event->type == GDK_2BUTTON_PRESS){
		ColorObject *color_object;
		if (source_get_color(args, &color_object) == 0){
			color_list_add_color_object(args->gs->getColorList(), color_object, 1);
			color_object->release();
		}
		return true;
	}else if (event->button == 3 && event->type == GDK_BUTTON_PRESS){
		GtkWidget* item ;
		gint32 button, event_time;
		menu = gtk_menu_new();
		bool selection_avail = gtk_layout_preview_is_selected(GTK_LAYOUT_PREVIEW(args->layout_view));
		bool edit_avail = gtk_layout_preview_is_editable(GTK_LAYOUT_PREVIEW(args->layout_view));
		item = gtk_menu_item_new_with_image(_("_Add to palette"), gtk_image_new_from_stock(GTK_STOCK_ADD, GTK_ICON_SIZE_MENU));
		gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
		g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(add_to_palette_cb), args);
		if (!selection_avail) gtk_widget_set_sensitive(item, false);
		item = gtk_menu_item_new_with_image(_("A_dd all to palette"), gtk_image_new_from_stock(GTK_STOCK_ADD, GTK_ICON_SIZE_MENU));
		gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
		g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(add_all_to_palette_cb), args);
		gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new());
		if (selection_avail){
			ColorObject* color_object;
			source_get_color(args, &color_object);
			StandardMenu::appendMenu(menu, color_object, args->gs);
			color_object->release();
		}else{
			StandardMenu::appendMenu(menu);
		}
		if (edit_avail){
			gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new());
			item = gtk_menu_item_new_with_image(_("_Edit..."), gtk_image_new_from_stock(GTK_STOCK_EDIT, GTK_ICON_SIZE_MENU));
			gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
			g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(edit_cb), args);
			if (!selection_avail) gtk_widget_set_sensitive(item, false);
			item = gtk_menu_item_new_with_image(_("_Paste"), gtk_image_new_from_stock(GTK_STOCK_PASTE, GTK_ICON_SIZE_MENU));
			gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
			g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(paste_cb), args);
			if (!selection_avail) gtk_widget_set_sensitive(item, false);
			if (copypaste_is_color_object_available(args->gs) != 0){
				gtk_widget_set_sensitive(item, false);
			}
		}
		gtk_widget_show_all(GTK_WIDGET(menu));
		button = event->button;
		event_time = event->time;
		gtk_menu_popup(GTK_MENU(menu), nullptr, nullptr, nullptr, nullptr, button, event_time);
		g_object_ref_sink(menu);
		g_object_unref(menu);
		return TRUE;
	}
	return FALSE;
}
static int source_destroy(BrightnessDarknessArgs *args)
{
	if (args->layout_system) System::unref(args->layout_system);
	args->layout_system = 0;
	dynv_system_release(args->params);
	gtk_widget_destroy(args->main);
	delete args;
	return 0;
}
static int source_activate(BrightnessDarknessArgs *args)
{
	auto chain = args->gs->getTransformationChain();
	gtk_layout_preview_set_transformation_chain(GTK_LAYOUT_PREVIEW(args->layout_view), chain);
	gtk_statusbar_push(GTK_STATUSBAR(args->statusbar), gtk_statusbar_get_context_id(GTK_STATUSBAR(args->statusbar), "empty"), "");
	return 0;
}
static int source_deactivate(BrightnessDarknessArgs *args)
{
	dynv_set_color(args->params, "color", &args->color);
	calc(args, true, true);
	return 0;
}
static ColorSource* source_implement(ColorSource *source, GlobalState *gs, struct dynvSystem *dynv_namespace)
{
	BrightnessDarknessArgs* args = new BrightnessDarknessArgs;
	args->params = dynv_system_ref(dynv_namespace);
	args->statusbar = gs->getStatusBar();
	color_source_init(&args->source, source->identificator, source->hr_name);
	args->source.destroy = (int (*)(ColorSource *source))source_destroy;
	args->source.get_color = (int (*)(ColorSource *source, ColorObject** color))source_get_color;
	args->source.set_color = (int (*)(ColorSource *source, ColorObject* color))source_set_color;
	args->source.deactivate = (int (*)(ColorSource *source))source_deactivate;
	args->source.activate = (int (*)(ColorSource *source))source_activate;
	args->layout_system = 0;
	GtkWidget *hbox, *widget;
	hbox = gtk_hbox_new(FALSE, 0);
	struct DragDrop dd;
	dragdrop_init(&dd, gs);
	dd.userdata = args;
	dd.get_color_object = get_color_object;
	dd.set_color_object_at = set_color_object_at;
	dd.test_at = test_at;
	dd.handler_map = dynv_system_get_handler_map(gs->getColorList()->params);
	args->brightness_darkness = widget = gtk_range_2d_new();
	gtk_range_2d_set_values(GTK_RANGE_2D(widget), dynv_get_float_wd(dynv_namespace, "brightness", 0.5), dynv_get_float_wd(dynv_namespace, "darkness", 0.5));
	gtk_range_2d_set_axis(GTK_RANGE_2D(widget), _("Brightness"), _("Darkness"));
	g_signal_connect(G_OBJECT(widget), "values_changed", G_CALLBACK(update), args);
	gtk_box_pack_start(GTK_BOX(hbox), widget, false, false, 0);
	args->layout_view = widget = gtk_layout_preview_new();
	g_signal_connect_after(G_OBJECT(widget), "button-press-event", G_CALLBACK(button_press_cb), args);
	gtk_box_pack_start(GTK_BOX(hbox), widget, false, false, 0);
	//setup drag&drop
	gtk_drag_dest_set( widget, GtkDestDefaults(GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT), 0, 0, GDK_ACTION_COPY);
	gtk_drag_source_set( widget, GDK_BUTTON1_MASK, 0, 0, GDK_ACTION_COPY);
	dd.handler_map = dynv_system_get_handler_map(gs->getColorList()->params);
	dd.userdata2 = (void*)-1;
	dragdrop_widget_attach(widget, DragDropFlags(DRAGDROP_SOURCE | DRAGDROP_DESTINATION), &dd);
	args->gs = gs;
	auto layout = gs->layouts().byName("std_layout_brightness_darkness");
	System* layout_system = layout->build();
	gtk_layout_preview_set_system(GTK_LAYOUT_PREVIEW(args->layout_view), layout_system);
	if (args->layout_system) System::unref(args->layout_system);
	args->layout_system = layout_system;
	Color c;
	color_set(&c, 0.5);
	Color *color = dynv_get_color_wdc(dynv_namespace, "color", &c);
	color_copy(color, &args->color);
	gtk_layout_preview_set_color_named(GTK_LAYOUT_PREVIEW(args->layout_view), color, "main");
	calc(args, true, false);
	gtk_widget_show_all(hbox);
	update(0, args);
	args->main = hbox;
	args->source.widget = hbox;
	return (ColorSource*)args;
}
int brightness_darkness_source_register(ColorSourceManager *csm)
{
	ColorSource *color_source = new ColorSource;
	color_source_init(color_source, "brightness_darkness", _("Brightness Darkness"));
	color_source->implement = (ColorSource* (*)(ColorSource *source, GlobalState *gs, struct dynvSystem *dynv_namespace))source_implement;
	color_source->default_accelerator = GDK_KEY_d;
	color_source_manager_add_source(csm, color_source);
	return 0;
}

max_stars_repo_name: waldyrious/gpick

max_issues_repo_name: waldyrious/gpick

max_forks_repo_name: waldyrious/gpick


text:
/*
    Copyright (c) 2011-2012 Andrew Hankinson, Alastair Porter, Greg Burlet and others

    Permission is hereby granted, free of charge, to any person obtaining
    a copy of this software and associated documentation files (the
    "Software"), to deal in the Software without restriction, including
    without limitation the rights to use, copy, modify, merge, publish,
    distribute, sublicense, and/or sell copies of the Software, and to
    permit persons to whom the Software is furnished to do so, subject to
    the following conditions:

    The above copyright notice and this permission notice shall be
    included in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
    LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
    OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
    WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include "Python.h"
#include <mei/exceptions.h>

#include <boost/python.hpp>
#include <boost/python/exception_translator.hpp>
#include <iostream>
#include <string>
#include <exception>

using namespace boost::python;
using namespace std;

PyObject* pyMeiExceptionType;
PyObject* pyVersionMismatchExceptionType;
PyObject* pyDuplicateAttributeExceptionType;
PyObject* pyAttributeNotFoundExceptionType;
PyObject* pyChildNotFoundExceptionType;
PyObject* pyNoVersionFoundExceptionType;
PyObject* pyElementNotRegisteredExceptionType;
PyObject* pyDocumentRootNotSetExceptionType;
PyObject* pyFileWriteFailureExceptionType;
PyObject* pyFileReadFailureExceptionType;
PyObject* pyMalformedXMLExceptionType;

void MeiExceptionTranslate(mei::MeiException const& e) {
    assert(pyMeiExceptionType != NULL);
    object pythonExceptionInstance(e);
    PyErr_SetObject(pyMeiExceptionType, pythonExceptionInstance.ptr());
    throw_error_already_set();
}

void VersionMismatchExceptionTranslate(mei::VersionMismatchException const& e) {
    assert(pyVersionMismatchExceptionType != NULL);
    object pythonExceptionInstance(e);
    PyErr_SetObject(pyVersionMismatchExceptionType, pythonExceptionInstance.ptr());
    throw_error_already_set();
}

void DuplicateAttributeExceptionTranslate(mei::DuplicateAttributeException const& e) {
    assert(pyDuplicateAttributeExceptionType != NULL);
    object pythonExceptionInstance(e);
    PyErr_SetObject(pyDuplicateAttributeExceptionType, pythonExceptionInstance.ptr());
    throw_error_already_set();
}

void AttributeNotFoundExceptionTranslate(mei::AttributeNotFoundException const& e) {
    assert(pyAttributeNotFoundExceptionType != NULL);
    object pythonExceptionInstance(e);
    PyErr_SetObject(pyAttributeNotFoundExceptionType, pythonExceptionInstance.ptr());
    throw_error_already_set();
}

void ChildNotFoundExceptionTranslate(mei::ChildNotFoundException const& e) {
    assert(pyChildNotFoundExceptionType != NULL);
    object pythonExceptionInstance(e);
    PyErr_SetObject(pyChildNotFoundExceptionType, pythonExceptionInstance.ptr());
    throw_error_already_set();
}

void NoVersionFoundExceptionTranslate(mei::NoVersionFoundException const& e) {
    assert(pyNoVersionFoundExceptionType != NULL);
    object pythonExceptionInstance(e);
    PyErr_SetObject(pyNoVersionFoundExceptionType, pythonExceptionInstance.ptr());
    throw_error_already_set();
}

void ElementNotRegisteredExceptionTranslate(mei::ElementNotRegisteredException const& e) {
    assert(pyElementNotRegisteredExceptionType != NULL);
    object pythonExceptionInstance(e);
    PyErr_SetObject(pyElementNotRegisteredExceptionType, pythonExceptionInstance.ptr());
    throw_error_already_set();
}

void DocumentRootNotSetExceptionTranslate(mei::DocumentRootNotSetException const& e) {
    assert(pyDocumentRootNotSetExceptionType != NULL);
    object pythonExceptionInstance(e);
    PyErr_SetObject(pyDocumentRootNotSetExceptionType, pythonExceptionInstance.ptr());
    throw_error_already_set();
}

void FileWriteFailureExceptionTranslate(mei::FileWriteFailureException const& e) {
    assert(pyFileWriteFailureExceptionType != NULL);
    object pythonExceptionInstance(e);
    PyErr_SetObject(pyFileWriteFailureExceptionType, pythonExceptionInstance.ptr());
    throw_error_already_set();
}

void FileReadFailureExceptionTranslate(mei::FileReadFailureException const& e) {
    assert(pyFileReadFailureExceptionType != NULL);
    object pythonExceptionInstance(e);
    PyErr_SetObject(pyFileReadFailureExceptionType, pythonExceptionInstance.ptr());
    throw_error_already_set();
}

void MalformedXMLExceptionTranslate(mei::MalformedXMLException const& e) {
    assert(pyMalformedXMLExceptionType != NULL);
    object pythonExceptionInstance(e);
    PyErr_SetObject(pyMalformedXMLExceptionType, pythonExceptionInstance.ptr());
    throw_error_already_set();
}

PyObject* createExceptionClass(const char* name, PyObject* baseTypeObj = PyExc_Exception)
{
    using std::string;
    namespace bp = boost::python;

    string scopeName = bp::extract<string>(bp::scope().attr("__name__"));
    string qualifiedName0 = scopeName + "." + name;
    char* qualifiedName1 = const_cast<char*>(qualifiedName0.c_str());

    PyObject* typeObj = PyErr_NewException(qualifiedName1, baseTypeObj, 0);
    if(!typeObj) bp::throw_error_already_set();
    bp::scope().attr(name) = bp::handle<>(bp::borrowed(typeObj));
    return typeObj;
}

BOOST_PYTHON_MODULE(_libmei_exceptions) {
    class_<mei::MeiException>("MeiException", init<string>())
        .def("what", &mei::MeiException::what)
        .add_property("message", &mei::MeiException::what)
    ;
    pyMeiExceptionType = createExceptionClass("MeiException");
    register_exception_translator<mei::MeiException>(&MeiExceptionTranslate);

    class_<mei::VersionMismatchException>("VersionMismatchException", init<string>())
        .def("what", &mei::VersionMismatchException::what)
        .add_property("message", &mei::VersionMismatchException::what)
    ;
    pyVersionMismatchExceptionType = createExceptionClass("VersionMismatchException");
    register_exception_translator<mei::VersionMismatchException>(&VersionMismatchExceptionTranslate);

    class_<mei::DuplicateAttributeException>("DuplicateAttributeException", init<string>())
        .def("what", &mei::DuplicateAttributeException::what)
        .add_property("message", &mei::DuplicateAttributeException::what)
    ;
    pyDuplicateAttributeExceptionType = createExceptionClass("DuplicateAttributeException");
    register_exception_translator<mei::DuplicateAttributeException>(&DuplicateAttributeExceptionTranslate);

    class_<mei::AttributeNotFoundException>("AttributeNotFoundException", init<string>())
        .def("what", &mei::AttributeNotFoundException::what)
        .add_property("message", &mei::AttributeNotFoundException::what)
    ;
    pyAttributeNotFoundExceptionType = createExceptionClass("AttributeNotFoundException");
    register_exception_translator<mei::AttributeNotFoundException>(&AttributeNotFoundExceptionTranslate);

    class_<mei::ChildNotFoundException>("ChildNotFoundException", init<string>())
        .def("what", &mei::ChildNotFoundException::what)
        .add_property("message", &mei::ChildNotFoundException::what)
    ;
    pyChildNotFoundExceptionType = createExceptionClass("ChildNotFoundException");
    register_exception_translator<mei::ChildNotFoundException>(&ChildNotFoundExceptionTranslate);

    class_<mei::NoVersionFoundException>("NoVersionFoundException", init<string>())
        .def("what", &mei::NoVersionFoundException::what)
        .add_property("message", &mei::NoVersionFoundException::what)
    ;
    pyNoVersionFoundExceptionType = createExceptionClass("NoVersionFoundException");
    register_exception_translator<mei::NoVersionFoundException>(&NoVersionFoundExceptionTranslate);

    class_<mei::ElementNotRegisteredException>("ElementNotRegisteredException", init<string>())
        .def("what", &mei::ElementNotRegisteredException::what)
        .add_property("message", &mei::ElementNotRegisteredException::what)
    ;
    pyElementNotRegisteredExceptionType = createExceptionClass("ElementNotRegisteredException");
    register_exception_translator<mei::ElementNotRegisteredException>(&ElementNotRegisteredExceptionTranslate);

    class_<mei::DocumentRootNotSetException>("DocumentRootNotSetException", init<string>())
        .def("what", &mei::DocumentRootNotSetException::what)
        .add_property("message", &mei::DocumentRootNotSetException::what)
    ;
    pyDocumentRootNotSetExceptionType = createExceptionClass("DocumentRootNotSetException");
    register_exception_translator<mei::DocumentRootNotSetException>(&DocumentRootNotSetExceptionTranslate);

    class_<mei::FileWriteFailureException>("FileWriteFailureException", init<string>())
        .def("what", &mei::FileWriteFailureException::what)
        .add_property("message", &mei::FileWriteFailureException::what)
    ;
    pyFileWriteFailureExceptionType = createExceptionClass("FileWriteFailureException");
    register_exception_translator<mei::FileWriteFailureException>(&FileWriteFailureExceptionTranslate);

    class_<mei::FileReadFailureException>("FileReadFailureException", init<string>())
    .def("what", &mei::FileReadFailureException::what)
    .add_property("message", &mei::FileReadFailureException::what)
    ;
    pyFileReadFailureExceptionType = createExceptionClass("FileReadFailureException");
    register_exception_translator<mei::FileReadFailureException>(&FileReadFailureExceptionTranslate);

    class_<mei::MalformedXMLException>("MalformedXMLException", init<string>())
        .def("what", &mei::MalformedXMLException::what)
        .add_property("message", &mei::MalformedXMLException::what)
    ;
    pyMalformedXMLExceptionType = createExceptionClass("MalformedXMLException");
    register_exception_translator<mei::MalformedXMLException>(&MalformedXMLExceptionTranslate);
}

max_stars_repo_name: Feasinde/libmei

max_issues_repo_name: Feasinde/libmei

max_forks_repo_name: Feasinde/libmei


text:
#include "updater.h"
#include <boost/filesystem/operations.hpp>
#include <stdio.h>

#include <event2/event.h>
#include <event2/http.h>
#include <event2/buffer.h>
#include <event2/keyvalq_struct.h>

#include <univalue.h>

/** Reply structure for request_done to fill in */
struct HTTPReply
{
    int status;
    std::string body;
};

void CUpdater::http_request_done(struct evhttp_request *req, void *ctx)
{
    HTTPReply *reply = static_cast<HTTPReply*>(ctx);

    if (req == NULL) {
        /* If req is NULL, it means an error occurred while connecting, but
         * I'm not sure how to find out which one. We also don't really care.
         */
        reply->status = 0;
        return;
    }

    reply->status = evhttp_request_get_response_code(req);

    struct evbuffer *buf = evhttp_request_get_input_buffer(req);
    if (buf)
    {
        size_t size = evbuffer_get_length(buf);
        const char *data = (const char*)evbuffer_pullup(buf, size);
        if (data)
            reply->body = std::string(data, size);
        evbuffer_drain(buf, size);
    }
}

bool CUpdater::GetFile(const std::string& serverName, const std::string& getCommand)
{
    struct event_base *base = event_base_new();
    if (!base)
    {
        lastError = "cannot create event_base";
        return false;
    }

    struct evhttp_connection *evcon = evhttp_connection_base_new(base, NULL, serverName.c_str(), 80);
    if (evcon == NULL)
    {
        lastError = "create connection failed";
        return false;
    }
    evhttp_connection_set_timeout(evcon, 2);

    HTTPReply response;
    struct evhttp_request *req = evhttp_request_new(http_request_done, (void*)&response);
    if (req == NULL)
    {
        lastError = "create http request failed";
        return false;
    }

    struct evkeyvalq *output_headers = evhttp_request_get_output_headers(req);
    assert(output_headers);
    evhttp_add_header(output_headers, "Host", host.c_str());
    //TODO: add header for binary transfer

    int r = evhttp_make_request(evcon, req, EVHTTP_REQ_GET, getCommand);
    if (r != 0) {
        evhttp_connection_free(evcon);
        event_base_free(base);
        lastError = "send http request failed";
        return false;
    }

    event_base_dispatch(base);
    evhttp_connection_free(evcon);
    event_base_free(base);

    if (response.status == 0)
        lastError = "couldn't connect to server";
    else if (response.status == HTTP_UNAUTHORIZED)
        lastError = "authorization failed";
    else if (response.status >= 400 && response.status != HTTP_BAD_REQUEST && response.status != HTTP_NOT_FOUND && response.status != HTTP_INTERNAL_SERVER_ERROR)
        lastError = strprintf("server returned HTTP error %d", response.status);
    else if (response.body.empty())
        lastError = "no response from server";
    else
    {
        //TODO: store file

        return true;
    }
    return false;
}

std::string CUpdater::getRemoteVersion()
{
}

std::string CUpdater::getLocalVersion()
{
}

bool CUpdater::updateAvailable()
{
}

bool CUpdater::downloadFile(std::string server, std::string getfile, std::string savefile)
{
    string serverName = server;
    string getCommand = "/" + getfile;

//    std::ofstream outFile(savefile, std::ofstream::out | std::ofstream::binary);
    bool res = GetFile(serverName, getCommand);
//    outFile.close();
}

bool CUpdater::renameBinary(std::string newName, std::string oldName)
{
}

bool CUpdater::launchUpdatedBinary(char args[], int argv, std::string fileName)
{
}