<commit_before>/*
* (C) 2016 Daniel Neus
*     2016 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include "tests.h"

#if defined(BOTAN_HAS_FILTERS)
  #include <botan/secqueue.h>
  #include <botan/pipe.h>
  #include <botan/filters.h>
  #include <botan/comp_filter.h>
  #include <botan/cipher_filter.h>
#endif

namespace Botan_Tests {

#if defined(BOTAN_HAS_FILTERS)

class Filter_Tests : public Test
   {
   public:
      std::vector<Test::Result> run() override
         {
         std::vector<Test::Result> results;

         results.push_back(test_secqueue());
         results.push_back(test_pipe_hash());
         results.push_back(test_pipe_mac());
         results.push_back(test_pipe_stream());
         results.push_back(test_pipe_cipher());
         results.push_back(test_pipe_compress());
         results.push_back(test_pipe_codec());
         results.push_back(test_fork());

#if defined(BOTAN_TARGET_OS_HAS_THREADS) && 0
         // Threaded_Fork is broken
         results.push_back(test_threaded_fork());
#endif

         return results;
         }

   private:
      Test::Result test_secqueue()
         {
         Test::Result result("SecureQueue");

         try
            {
            Botan::SecureQueue queue_a;
            std::vector<uint8_t> test_data = {0x24, 0xB2, 0xBF, 0xC2, 0xE6, 0xD4, 0x7E, 0x04, 0x67, 0xB3};
            queue_a.write(test_data.data(), test_data.size());

            result.test_eq("size of SecureQueue is correct", queue_a.size(), test_data.size());
            result.test_eq("0 bytes read so far from SecureQueue", queue_a.get_bytes_read(), 0);

            uint8_t b;
            size_t bytes_read = queue_a.read_byte(b);
            result.test_eq("1 byte read", bytes_read, 1);

            Botan::secure_vector<uint8_t> produced(b);
            Botan::secure_vector<uint8_t> expected(test_data.at(0));
            result.test_eq("byte read is correct", produced, expected);

            result.test_eq("1 bytes read so far from SecureQueue", queue_a.get_bytes_read(), 1);

            Botan::SecureQueue queue_b;
            queue_a = queue_b;
            result.test_eq("bytes_read is set correctly", queue_a.get_bytes_read(), 0);
            }
         catch (std::exception& e)
            {
            result.test_failure("SecureQueue", e.what());
            }

         return result;
         }

      Test::Result test_pipe_mac()
         {
         Test::Result result("Pipe");
         const Botan::SymmetricKey key("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
         Botan::Pipe pipe(new Botan::MAC_Filter("HMAC(SHA-256)", key, 12),
                          new Botan::Base64_Encoder);

         pipe.process_msg("Hi");
         pipe.process_msg("Bye");
         pipe.process_msg("Hi");

         result.test_eq("MAC 1", pipe.read_all_as_string(0), "e7NoVbtudgU0QiCZ");
         result.test_eq("MAC 2", pipe.read_all_as_string(1), "LhPnfEG+0rk+Ej6y");
         result.test_eq("MAC 3", pipe.read_all_as_string(2), "e7NoVbtudgU0QiCZ");

         return result;
         }

      Test::Result test_pipe_hash()
         {
         Test::Result result("Pipe");
         Botan::Pipe pipe(new Botan::Hash_Filter("SHA-224"));
         pipe.pop();
         pipe.append(new Botan::Hash_Filter("SHA-256"));

         result.test_eq("Message count", pipe.message_count(), 0);

         pipe.start_msg();
         uint8_t inb = 0x41;
         pipe.write(&inb, 1);
         pipe.write(std::vector<uint8_t>(6, 0x41));
         pipe.write(inb);
         pipe.end_msg();

         result.test_eq("Message count", pipe.message_count(), 1);
         result.test_eq("Message size", pipe.remaining(), 32);

         std::vector<uint8_t> out(32), last16(16);

         result.test_eq("Bytes read", pipe.get_bytes_read(0), 0);
         result.test_eq("Expected read count", pipe.read(&out[0], 5), 5);
         result.test_eq("Bytes read", pipe.get_bytes_read(0), 5);
         result.test_eq("Peek read", pipe.peek(last16.data(), 18, 11), 16);
         result.test_eq("Expected read count", pipe.read(&out[5], 17), 17);
         result.test_eq("Bytes read", pipe.get_bytes_read(0), 22);
         result.test_eq("Remaining", pipe.remaining(), 10);
         result.test_eq("Remaining", pipe.remaining(), 10);
         result.test_eq("Expected read count", pipe.read(&out[22], 12), 10);
         result.test_eq("Expected read count", pipe.read(&out[0], 1), 0); // no more output
         result.test_eq("Bytes read", pipe.get_bytes_read(0), 32);

         result.test_eq("Expected output", out, "C34AB6ABB7B2BB595BC25C3B388C872FD1D575819A8F55CC689510285E212385");
         result.test_eq("Expected last16", last16, "D1D575819A8F55CC689510285E212385");

         pipe.reset();

#if defined(BOTAN_HAS_CRC32)
         pipe.prepend(new Botan::Hash_Filter("CRC32"));
         pipe.append(new Botan::Hash_Filter("CRC32"));
         pipe.process_msg(std::vector<byte>(1024, 0));
         result.test_eq("Expected CRC32d", pipe.read_all(1), "99841F60");
#endif

         return result;
         }

      Test::Result test_pipe_cipher()
         {
         Test::Result result("Pipe");

         Botan::Cipher_Mode_Filter* cipher =
            new Botan::Cipher_Mode_Filter(Botan::get_cipher_mode("AES-128/CBC/PKCS7", Botan::ENCRYPTION));

          // takes ownership of cipher
         Botan::Pipe pipe(cipher);

         cipher->set_key(Botan::SymmetricKey("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
         cipher->set_iv(Botan::InitializationVector("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));

         pipe.process_msg("Don't use plain CBC mode");

         auto ciphertext = pipe.read_all();

         result.test_eq("Ciphertext", ciphertext, "9BDD7300E0CB61CA71FFF957A71605DB6836159C36781246A1ADF50982757F4B");

         Botan::Cipher_Mode_Filter* dec_cipher =
            new Botan::Cipher_Mode_Filter(Botan::get_cipher_mode("AES-128/CBC/PKCS7", Botan::DECRYPTION));
         pipe.append(dec_cipher);
         dec_cipher->set_key(Botan::SymmetricKey("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
         dec_cipher->set_iv(Botan::InitializationVector("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB"));
         cipher->set_iv(Botan::InitializationVector("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB"));

         const std::vector<byte> zeros_in(1024);
         Botan::DataSource_Memory src(zeros_in);
         pipe.start_msg();
         pipe.write(src);
         pipe.end_msg();

         Botan::secure_vector<byte> zeros_out = pipe.read_all(1);

         result.test_eq("Cipher roundtrip", zeros_in, zeros_out);
         return result;
         }

      Test::Result test_pipe_compress()
         {
         Test::Result result("Pipe");

#if defined(BOTAN_HAS_ZLIB)
         Botan::Pipe pipe(new Botan::Compression_Filter("zlib", 9));

         const std::string input_str = "Hello there HELLO there I said is this thing on?";

         pipe.start_msg();
         pipe.write(input_str);
         pipe.end_msg();

         auto compr = pipe.read_all(0);
         // Can't do equality check on compression because output may differ
         result.test_lt("Compressed is shorter", compr.size(), input_str.size());

         pipe.append(new Botan::Decompression_Filter("zlib"));
         pipe.pop(); // remove compressor

         pipe.process_msg(compr);

         std::string decomp = pipe.read_all_as_string(1);
         result.test_eq("Decompressed ok", decomp, input_str);
#endif

         return result;
         }

      Test::Result test_pipe_codec()
         {
         Test::Result result("Pipe");

         Botan::Pipe pipe(new Botan::Base64_Encoder);

         result.test_eq("Message count", pipe.message_count(), 0);

         pipe.process_msg("ABCDX");

         result.test_eq("Message count", pipe.message_count(), 1);
         result.test_eq("Message size", pipe.remaining(), 8);

         std::string output = pipe.read_all_as_string(0);
         result.test_eq("Message size", pipe.remaining(0), 0);
         result.test_eq("Output round tripped", output, "QUJDRFg=");

         pipe.append(new Botan::Base64_Decoder);
         pipe.process_msg("FOOBAZ");

         result.test_eq("base64 roundtrip", pipe.read_all_as_string(1), "FOOBAZ");

         pipe.pop();
         pipe.pop();

         // Pipe is empty of filters, should still pass through
         pipe.process_msg("surprise plaintext");

         pipe.set_default_msg(2);
         result.test_eq("Message 2", pipe.read_all_as_string(), "surprise plaintext");

         pipe.append(new Botan::Hex_Decoder);

         pipe.process_msg("F331F00D");
         Botan::secure_vector<uint8_t> bin = pipe.read_all(3);
         result.test_eq("hex decoded", bin, "F331F00D");

         pipe.append(new Botan::Hex_Encoder);
         pipe.process_msg("F331F00D");
         result.test_eq("hex roundtrip", pipe.read_all_as_string(4), "F331F00D");

         return result;
         }

      Test::Result test_pipe_stream()
         {
         Test::Result result("Pipe");

         Botan::Keyed_Filter* aes = nullptr;
         const Botan::SymmetricKey key("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
         const Botan::InitializationVector iv("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
         Botan::Pipe pipe(aes = new Botan::StreamCipher_Filter("CTR-BE(AES-128)", key));

         aes->set_iv(iv);

         pipe.process_msg("ABCDEF");

         result.test_eq("Message count", pipe.message_count(), 1);
         result.test_eq("Ciphertext", pipe.read_all(), "FDFD6238F7C6");
         return result;
         }

      Test::Result test_fork()
         {
         Test::Result result("Fork");

         Botan::Pipe pipe(new Botan::Fork(new Botan::Hash_Filter("SHA-256"),
                                          new Botan::Hash_Filter("SHA-512-256")));

         result.test_eq("Message count", pipe.message_count(), 0);
         pipe.process_msg("OMG");
         result.test_eq("Message count", pipe.message_count(), 2);

         // Test reading out of order
         result.test_eq("Hash 2", pipe.read_all(1), "610480FFA82F24F6926544B976FE387878E3D973C03DFD591C2E9896EFB903E0");
         result.test_eq("Hash 1", pipe.read_all(0), "C00862D1C6C1CF7C1B49388306E7B3C1BB79D8D6EC978B41035B556DBB3797DF");

         return result;

         }

#if defined(BOTAN_TARGET_OS_HAS_THREADS)
      Test::Result test_threaded_fork()
         {
         Test::Result result("Threaded_Fork");

         Botan::Pipe pipe(new Botan::Threaded_Fork(new Botan::Hex_Encoder,
                                                   new Botan::Base64_Encoder));

         result.test_eq("Message count", pipe.message_count(), 0);
         pipe.process_msg("woo");
         result.test_eq("Message count", pipe.message_count(), 2);

         // Test reading out of order
         result.test_eq("Hash 2", pipe.read_all_as_string(1), "d29v");
         result.test_eq("Hash 1", pipe.read_all_as_string(0), "776F6F");

         pipe.reset();

         const size_t filter_count = 5;
         Botan::Filter* filters[filter_count];
         for(size_t i = 0; i != filter_count; ++i)
            filters[i] = new Botan::Hash_Filter("SHA-256");

         pipe.append(new Botan::Threaded_Fork(filters, filter_count));

         result.test_eq("Message count before start_msg", pipe.message_count(), 2);

         pipe.start_msg();
         for(size_t i = 0; i != 919; ++i)
            {
            std::vector<uint8_t> input(i + 5, static_cast<uint8_t>(i));
            pipe.write(input);
            }
         pipe.end_msg();

         result.test_eq("Message count after end_msg", pipe.message_count(), 2+filter_count);
         for(size_t i = 0; i != filter_count; ++i)
            result.test_eq("Output " + std::to_string(i),
                           pipe.read_all(2+i),
                           "327AD8055223F5926693D8BEA40F7B35BDEEB535647DFB93F464E40EA01939A9");

         return result;
         }
#endif

   };

BOTAN_REGISTER_TEST("filter", Filter_Tests);

#endif

}
<commit_msg>Re-enable the Threaded Fork test<commit_after>/*
* (C) 2016 Daniel Neus
*     2016 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include "tests.h"

#if defined(BOTAN_HAS_FILTERS)
  #include <botan/secqueue.h>
  #include <botan/pipe.h>
  #include <botan/filters.h>
  #include <botan/comp_filter.h>
  #include <botan/cipher_filter.h>
#endif

namespace Botan_Tests {

#if defined(BOTAN_HAS_FILTERS)

class Filter_Tests : public Test
   {
   public:
      std::vector<Test::Result> run() override
         {
         std::vector<Test::Result> results;

         results.push_back(test_secqueue());
         results.push_back(test_pipe_hash());
         results.push_back(test_pipe_mac());
         results.push_back(test_pipe_stream());
         results.push_back(test_pipe_cipher());
         results.push_back(test_pipe_compress());
         results.push_back(test_pipe_codec());
         results.push_back(test_fork());

#if defined(BOTAN_TARGET_OS_HAS_THREADS)
         // Threaded_Fork is broken
         results.push_back(test_threaded_fork());
#endif

         return results;
         }

   private:
      Test::Result test_secqueue()
         {
         Test::Result result("SecureQueue");

         try
            {
            Botan::SecureQueue queue_a;
            std::vector<uint8_t> test_data = {0x24, 0xB2, 0xBF, 0xC2, 0xE6, 0xD4, 0x7E, 0x04, 0x67, 0xB3};
            queue_a.write(test_data.data(), test_data.size());

            result.test_eq("size of SecureQueue is correct", queue_a.size(), test_data.size());
            result.test_eq("0 bytes read so far from SecureQueue", queue_a.get_bytes_read(), 0);

            uint8_t b;
            size_t bytes_read = queue_a.read_byte(b);
            result.test_eq("1 byte read", bytes_read, 1);

            Botan::secure_vector<uint8_t> produced(b);
            Botan::secure_vector<uint8_t> expected(test_data.at(0));
            result.test_eq("byte read is correct", produced, expected);

            result.test_eq("1 bytes read so far from SecureQueue", queue_a.get_bytes_read(), 1);

            Botan::SecureQueue queue_b;
            queue_a = queue_b;
            result.test_eq("bytes_read is set correctly", queue_a.get_bytes_read(), 0);
            }
         catch (std::exception& e)
            {
            result.test_failure("SecureQueue", e.what());
            }

         return result;
         }

      Test::Result test_pipe_mac()
         {
         Test::Result result("Pipe");
         const Botan::SymmetricKey key("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
         Botan::Pipe pipe(new Botan::MAC_Filter("HMAC(SHA-256)", key, 12),
                          new Botan::Base64_Encoder);

         pipe.process_msg("Hi");
         pipe.process_msg("Bye");
         pipe.process_msg("Hi");

         result.test_eq("MAC 1", pipe.read_all_as_string(0), "e7NoVbtudgU0QiCZ");
         result.test_eq("MAC 2", pipe.read_all_as_string(1), "LhPnfEG+0rk+Ej6y");
         result.test_eq("MAC 3", pipe.read_all_as_string(2), "e7NoVbtudgU0QiCZ");

         return result;
         }

      Test::Result test_pipe_hash()
         {
         Test::Result result("Pipe");
         Botan::Pipe pipe(new Botan::Hash_Filter("SHA-224"));
         pipe.pop();
         pipe.append(new Botan::Hash_Filter("SHA-256"));

         result.test_eq("Message count", pipe.message_count(), 0);

         pipe.start_msg();
         uint8_t inb = 0x41;
         pipe.write(&inb, 1);
         pipe.write(std::vector<uint8_t>(6, 0x41));
         pipe.write(inb);
         pipe.end_msg();

         result.test_eq("Message count", pipe.message_count(), 1);
         result.test_eq("Message size", pipe.remaining(), 32);

         std::vector<uint8_t> out(32), last16(16);

         result.test_eq("Bytes read", pipe.get_bytes_read(0), 0);
         result.test_eq("Expected read count", pipe.read(&out[0], 5), 5);
         result.test_eq("Bytes read", pipe.get_bytes_read(0), 5);
         result.test_eq("Peek read", pipe.peek(last16.data(), 18, 11), 16);
         result.test_eq("Expected read count", pipe.read(&out[5], 17), 17);
         result.test_eq("Bytes read", pipe.get_bytes_read(0), 22);
         result.test_eq("Remaining", pipe.remaining(), 10);
         result.test_eq("Remaining", pipe.remaining(), 10);
         result.test_eq("Expected read count", pipe.read(&out[22], 12), 10);
         result.test_eq("Expected read count", pipe.read(&out[0], 1), 0); // no more output
         result.test_eq("Bytes read", pipe.get_bytes_read(0), 32);

         result.test_eq("Expected output", out, "C34AB6ABB7B2BB595BC25C3B388C872FD1D575819A8F55CC689510285E212385");
         result.test_eq("Expected last16", last16, "D1D575819A8F55CC689510285E212385");

         pipe.reset();

#if defined(BOTAN_HAS_CRC32)
         pipe.prepend(new Botan::Hash_Filter("CRC32"));
         pipe.append(new Botan::Hash_Filter("CRC32"));
         pipe.process_msg(std::vector<byte>(1024, 0));
         result.test_eq("Expected CRC32d", pipe.read_all(1), "99841F60");
#endif

         return result;
         }

      Test::Result test_pipe_cipher()
         {
         Test::Result result("Pipe");

         Botan::Cipher_Mode_Filter* cipher =
            new Botan::Cipher_Mode_Filter(Botan::get_cipher_mode("AES-128/CBC/PKCS7", Botan::ENCRYPTION));

          // takes ownership of cipher
         Botan::Pipe pipe(cipher);

         cipher->set_key(Botan::SymmetricKey("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
         cipher->set_iv(Botan::InitializationVector("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));

         pipe.process_msg("Don't use plain CBC mode");

         auto ciphertext = pipe.read_all();

         result.test_eq("Ciphertext", ciphertext, "9BDD7300E0CB61CA71FFF957A71605DB6836159C36781246A1ADF50982757F4B");

         Botan::Cipher_Mode_Filter* dec_cipher =
            new Botan::Cipher_Mode_Filter(Botan::get_cipher_mode("AES-128/CBC/PKCS7", Botan::DECRYPTION));
         pipe.append(dec_cipher);
         dec_cipher->set_key(Botan::SymmetricKey("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
         dec_cipher->set_iv(Botan::InitializationVector("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB"));
         cipher->set_iv(Botan::InitializationVector("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB"));

         const std::vector<byte> zeros_in(1024);
         Botan::DataSource_Memory src(zeros_in);
         pipe.start_msg();
         pipe.write(src);
         pipe.end_msg();

         Botan::secure_vector<byte> zeros_out = pipe.read_all(1);

         result.test_eq("Cipher roundtrip", zeros_in, zeros_out);
         return result;
         }

      Test::Result test_pipe_compress()
         {
         Test::Result result("Pipe");

#if defined(BOTAN_HAS_ZLIB)
         Botan::Pipe pipe(new Botan::Compression_Filter("zlib", 9));

         const std::string input_str = "Hello there HELLO there I said is this thing on?";

         pipe.start_msg();
         pipe.write(input_str);
         pipe.end_msg();

         auto compr = pipe.read_all(0);
         // Can't do equality check on compression because output may differ
         result.test_lt("Compressed is shorter", compr.size(), input_str.size());

         pipe.append(new Botan::Decompression_Filter("zlib"));
         pipe.pop(); // remove compressor

         pipe.process_msg(compr);

         std::string decomp = pipe.read_all_as_string(1);
         result.test_eq("Decompressed ok", decomp, input_str);
#endif

         return result;
         }

      Test::Result test_pipe_codec()
         {
         Test::Result result("Pipe");

         Botan::Pipe pipe(new Botan::Base64_Encoder);

         result.test_eq("Message count", pipe.message_count(), 0);

         pipe.process_msg("ABCDX");

         result.test_eq("Message count", pipe.message_count(), 1);
         result.test_eq("Message size", pipe.remaining(), 8);

         std::string output = pipe.read_all_as_string(0);
         result.test_eq("Message size", pipe.remaining(0), 0);
         result.test_eq("Output round tripped", output, "QUJDRFg=");

         pipe.append(new Botan::Base64_Decoder);
         pipe.process_msg("FOOBAZ");

         result.test_eq("base64 roundtrip", pipe.read_all_as_string(1), "FOOBAZ");

         pipe.pop();
         pipe.pop();

         // Pipe is empty of filters, should still pass through
         pipe.process_msg("surprise plaintext");

         pipe.set_default_msg(2);
         result.test_eq("Message 2", pipe.read_all_as_string(), "surprise plaintext");

         pipe.append(new Botan::Hex_Decoder);

         pipe.process_msg("F331F00D");
         Botan::secure_vector<uint8_t> bin = pipe.read_all(3);
         result.test_eq("hex decoded", bin, "F331F00D");

         pipe.append(new Botan::Hex_Encoder);
         pipe.process_msg("F331F00D");
         result.test_eq("hex roundtrip", pipe.read_all_as_string(4), "F331F00D");

         return result;
         }

      Test::Result test_pipe_stream()
         {
         Test::Result result("Pipe");

         Botan::Keyed_Filter* aes = nullptr;
         const Botan::SymmetricKey key("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
         const Botan::InitializationVector iv("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
         Botan::Pipe pipe(aes = new Botan::StreamCipher_Filter("CTR-BE(AES-128)", key));

         aes->set_iv(iv);

         pipe.process_msg("ABCDEF");

         result.test_eq("Message count", pipe.message_count(), 1);
         result.test_eq("Ciphertext", pipe.read_all(), "FDFD6238F7C6");
         return result;
         }

      Test::Result test_fork()
         {
         Test::Result result("Fork");

         Botan::Pipe pipe(new Botan::Fork(new Botan::Hash_Filter("SHA-256"),
                                          new Botan::Hash_Filter("SHA-512-256")));

         result.test_eq("Message count", pipe.message_count(), 0);
         pipe.process_msg("OMG");
         result.test_eq("Message count", pipe.message_count(), 2);

         // Test reading out of order
         result.test_eq("Hash 2", pipe.read_all(1), "610480FFA82F24F6926544B976FE387878E3D973C03DFD591C2E9896EFB903E0");
         result.test_eq("Hash 1", pipe.read_all(0), "C00862D1C6C1CF7C1B49388306E7B3C1BB79D8D6EC978B41035B556DBB3797DF");

         return result;

         }

#if defined(BOTAN_TARGET_OS_HAS_THREADS)
      Test::Result test_threaded_fork()
         {
         Test::Result result("Threaded_Fork");

         Botan::Pipe pipe(new Botan::Threaded_Fork(new Botan::Hex_Encoder,
                                                   new Botan::Base64_Encoder));

         result.test_eq("Message count", pipe.message_count(), 0);
         pipe.process_msg("woo");
         result.test_eq("Message count", pipe.message_count(), 2);

         // Test reading out of order
         result.test_eq("Hash 2", pipe.read_all_as_string(1), "d29v");
         result.test_eq("Hash 1", pipe.read_all_as_string(0), "776F6F");

         pipe.reset();

         const size_t filter_count = 5;
         Botan::Filter* filters[filter_count];
         for(size_t i = 0; i != filter_count; ++i)
            filters[i] = new Botan::Hash_Filter("SHA-256");

         pipe.append(new Botan::Threaded_Fork(filters, filter_count));

         result.test_eq("Message count before start_msg", pipe.message_count(), 2);

         pipe.start_msg();
         for(size_t i = 0; i != 919; ++i)
            {
            std::vector<uint8_t> input(i + 5, static_cast<uint8_t>(i));
            pipe.write(input);
            }
         pipe.end_msg();

         result.test_eq("Message count after end_msg", pipe.message_count(), 2+filter_count);
         for(size_t i = 0; i != filter_count; ++i)
            result.test_eq("Output " + std::to_string(i),
                           pipe.read_all(2+i),
                           "327AD8055223F5926693D8BEA40F7B35BDEEB535647DFB93F464E40EA01939A9");

         return result;
         }
#endif

   };

BOTAN_REGISTER_TEST("filter", Filter_Tests);

#endif

}
<|endoftext|>


<commit_before>/**
 * @file posix/wait.cpp
 * @brief POSIX event/timeout handling
 *
 * (c) 2013-2014 by Mega Limited, Wellsford, New Zealand
 *
 * This file is part of the MEGA SDK - Client Access Engine.
 *
 * Applications using the MEGA API must present a valid application key
 * and comply with the the rules set forth in the Terms of Service.
 *
 * The MEGA SDK is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * @copyright Simplified (2-clause) BSD License.
 *
 * You should have received a copy of the license along with this
 * program.
 *
 * This file is also distributed under the terms of the GNU General
 * Public License, see http://www.gnu.org/copyleft/gpl.txt for details.
 */

#include "mega/thread/posixthread.h"
#include "mega/logging.h"
#include <sys/time.h>
#include <errno.h>

#ifdef USE_PTHREAD
#if defined (__MINGW32__) && !defined(__struct_timespec_defined)
struct timespec
{
  long long	tv_sec; 	/* seconds */
  long  	tv_nsec;	/* nanoseconds */
};
# define __struct_timespec_defined  1
#endif

namespace mega {

PosixThread::PosixThread()
{
    thread = new pthread_t();
}

void PosixThread::start(void *(*start_routine)(void*), void *parameter)
{
    pthread_create(thread, NULL, start_routine, parameter);
}

void PosixThread::join()
{
    pthread_join(*thread, NULL);
}

unsigned long long PosixThread::currentThreadId()
{
#if defined(_WIN32) && !defined(__WINPTHREADS_VERSION)
    return (unsigned long long) pthread_self().x;
#else
    return (unsigned long long) pthread_self();
#endif
}

PosixThread::~PosixThread()
{
    delete thread;
}

//PosixMutex
PosixMutex::PosixMutex()
{
    mutex = NULL;
    attr = NULL;
}

PosixMutex::PosixMutex(bool recursive)
{
    mutex = NULL;
    attr = NULL;

    init(recursive);
}

void PosixMutex::init(bool recursive)
{
    if (recursive)
    {
        mutex = new pthread_mutex_t();
        attr = new pthread_mutexattr_t();
        pthread_mutexattr_init(attr);
        pthread_mutexattr_settype(attr, PTHREAD_MUTEX_RECURSIVE);
        pthread_mutex_init(mutex, attr);
    }
    else
    {
        mutex = new pthread_mutex_t();
        pthread_mutex_init(mutex, NULL);
    }
}

void PosixMutex::lock()
{
    pthread_mutex_lock(mutex);
}

void PosixMutex::unlock()
{
    pthread_mutex_unlock(mutex);
}

PosixMutex::~PosixMutex()
{
    if (mutex)
    {
        pthread_mutex_destroy(mutex);
        delete mutex;
    }

    if (attr)
    {
        pthread_mutexattr_destroy(attr);
        delete attr;
    }
}

//PosixSemaphore
PosixSemaphore::PosixSemaphore()
{
    count = 0;
    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    pthread_mutex_init(&mtx, &attr);
    pthread_mutexattr_destroy(&attr);
    pthread_cond_init(&cv, NULL);
}

void PosixSemaphore::wait()
{
    pthread_mutex_lock(&mtx);
    while (!count)
    {
        int ret = pthread_cond_wait(&cv,&mtx);
        if (ret)
        {
            pthread_mutex_unlock(&mtx);
            LOG_fatal << "Error in sem_wait: " << ret;
            return;
        }
    }
    count--;
    pthread_mutex_unlock(&mtx);
}

static inline
void timespec_add_msec(struct timespec *tv, int milliseconds)
{
    int seconds = milliseconds / 1000;
    int milliseconds_left = milliseconds % 1000;

    tv->tv_sec += seconds;
    tv->tv_nsec += milliseconds_left * 1000000;

    if (tv->tv_nsec >= 1000000000)
    {
        tv->tv_nsec -= 1000000000;
        tv->tv_sec++;
    }
}

int PosixSemaphore::timedwait(int milliseconds)
{
    struct timespec ts;
    struct timeval now;

    int ret = gettimeofday(&now, NULL); //not Y2K38 safe :-D
    if (ret)
    {
        LOG_err << "Error in gettimeofday: " << ret;
        return -2;
    }
    ts.tv_sec = now.tv_sec;
    ts.tv_nsec = now.tv_usec * 1000;
    timespec_add_msec (&ts, milliseconds);

    pthread_mutex_lock(&mtx);
    while (!count)
    {
        int ret = pthread_cond_timedwait(&cv, &mtx, &ts);
        if (ret == ETIMEDOUT)
        {
            pthread_mutex_unlock(&mtx);
            return -1;
        }

        if (ret)
        {
            pthread_mutex_unlock(&mtx);
            LOG_err << "Unexpected error in pthread_cond_timedwait: " << ret;
            return -2;
        }
    }

    count--;
    pthread_mutex_unlock(&mtx);
    return 0;
}

void PosixSemaphore::release()
{
    pthread_mutex_lock(&mtx);
    count++;
    int ret = pthread_cond_signal(&cv);
    if (ret)
    {
        LOG_fatal << "Unexpected error in pthread_cond_signal: " << ret;
    }
    pthread_mutex_unlock(&mtx);
}

PosixSemaphore::~PosixSemaphore()
{
    pthread_mutex_destroy(&mtx);
    pthread_cond_destroy(&cv);
}

}// namespace

#endif
<commit_msg>posixthread: fix duplicate define of time_spec on mingw-w64 with posix<commit_after>/**
 * @file posix/wait.cpp
 * @brief POSIX event/timeout handling
 *
 * (c) 2013-2014 by Mega Limited, Wellsford, New Zealand
 *
 * This file is part of the MEGA SDK - Client Access Engine.
 *
 * Applications using the MEGA API must present a valid application key
 * and comply with the the rules set forth in the Terms of Service.
 *
 * The MEGA SDK is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * @copyright Simplified (2-clause) BSD License.
 *
 * You should have received a copy of the license along with this
 * program.
 *
 * This file is also distributed under the terms of the GNU General
 * Public License, see http://www.gnu.org/copyleft/gpl.txt for details.
 */

#include "mega/thread/posixthread.h"
#include "mega/logging.h"
#include <sys/time.h>
#include <errno.h>

#ifdef USE_PTHREAD
// Apparently this is defined by pthread.h, if that header had been included.
// __struct_timespec_defined is defined in time.h for MinGW on Windows
#if defined (__MINGW32__) && !defined(_TIMESPEC_DEFINED) && ! __struct_timespec_defined
struct timespec
{
  long long	tv_sec; 	/* seconds */
  long  	tv_nsec;	/* nanoseconds */
};
# define __struct_timespec_defined  1
#endif

namespace mega {

PosixThread::PosixThread()
{
    thread = new pthread_t();
}

void PosixThread::start(void *(*start_routine)(void*), void *parameter)
{
    pthread_create(thread, NULL, start_routine, parameter);
}

void PosixThread::join()
{
    pthread_join(*thread, NULL);
}

unsigned long long PosixThread::currentThreadId()
{
#if defined(_WIN32) && !defined(__WINPTHREADS_VERSION)
    return (unsigned long long) pthread_self().x;
#else
    return (unsigned long long) pthread_self();
#endif
}

PosixThread::~PosixThread()
{
    delete thread;
}

//PosixMutex
PosixMutex::PosixMutex()
{
    mutex = NULL;
    attr = NULL;
}

PosixMutex::PosixMutex(bool recursive)
{
    mutex = NULL;
    attr = NULL;

    init(recursive);
}

void PosixMutex::init(bool recursive)
{
    if (recursive)
    {
        mutex = new pthread_mutex_t();
        attr = new pthread_mutexattr_t();
        pthread_mutexattr_init(attr);
        pthread_mutexattr_settype(attr, PTHREAD_MUTEX_RECURSIVE);
        pthread_mutex_init(mutex, attr);
    }
    else
    {
        mutex = new pthread_mutex_t();
        pthread_mutex_init(mutex, NULL);
    }
}

void PosixMutex::lock()
{
    pthread_mutex_lock(mutex);
}

void PosixMutex::unlock()
{
    pthread_mutex_unlock(mutex);
}

PosixMutex::~PosixMutex()
{
    if (mutex)
    {
        pthread_mutex_destroy(mutex);
        delete mutex;
    }

    if (attr)
    {
        pthread_mutexattr_destroy(attr);
        delete attr;
    }
}

//PosixSemaphore
PosixSemaphore::PosixSemaphore()
{
    count = 0;
    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    pthread_mutex_init(&mtx, &attr);
    pthread_mutexattr_destroy(&attr);
    pthread_cond_init(&cv, NULL);
}

void PosixSemaphore::wait()
{
    pthread_mutex_lock(&mtx);
    while (!count)
    {
        int ret = pthread_cond_wait(&cv,&mtx);
        if (ret)
        {
            pthread_mutex_unlock(&mtx);
            LOG_fatal << "Error in sem_wait: " << ret;
            return;
        }
    }
    count--;
    pthread_mutex_unlock(&mtx);
}

static inline
void timespec_add_msec(struct timespec *tv, int milliseconds)
{
    int seconds = milliseconds / 1000;
    int milliseconds_left = milliseconds % 1000;

    tv->tv_sec += seconds;
    tv->tv_nsec += milliseconds_left * 1000000;

    if (tv->tv_nsec >= 1000000000)
    {
        tv->tv_nsec -= 1000000000;
        tv->tv_sec++;
    }
}

int PosixSemaphore::timedwait(int milliseconds)
{
    struct timespec ts;
    struct timeval now;

    int ret = gettimeofday(&now, NULL); //not Y2K38 safe :-D
    if (ret)
    {
        LOG_err << "Error in gettimeofday: " << ret;
        return -2;
    }
    ts.tv_sec = now.tv_sec;
    ts.tv_nsec = now.tv_usec * 1000;
    timespec_add_msec (&ts, milliseconds);

    pthread_mutex_lock(&mtx);
    while (!count)
    {
        int ret = pthread_cond_timedwait(&cv, &mtx, &ts);
        if (ret == ETIMEDOUT)
        {
            pthread_mutex_unlock(&mtx);
            return -1;
        }

        if (ret)
        {
            pthread_mutex_unlock(&mtx);
            LOG_err << "Unexpected error in pthread_cond_timedwait: " << ret;
            return -2;
        }
    }

    count--;
    pthread_mutex_unlock(&mtx);
    return 0;
}

void PosixSemaphore::release()
{
    pthread_mutex_lock(&mtx);
    count++;
    int ret = pthread_cond_signal(&cv);
    if (ret)
    {
        LOG_fatal << "Unexpected error in pthread_cond_signal: " << ret;
    }
    pthread_mutex_unlock(&mtx);
}

PosixSemaphore::~PosixSemaphore()
{
    pthread_mutex_destroy(&mtx);
    pthread_cond_destroy(&cv);
}

}// namespace

#endif
<|endoftext|>


<commit_before>// Copyright (C) 2012-2015 Leap Motion, Inc. All rights reserved.
#include "stdafx.h"
#include <autowiring/config_descriptor.h>
#include <autowiring/config.h>
#include <autowiring/ConfigRegistry.h>
#include <autowiring/observable.h>

namespace aw = autowiring;

class AutoConfigTest:
  public testing::Test
{};

namespace {
  class multi_meta {
  public:
    static const bool multi = true;

    std::string name;

    template<typename T>
    void bind(const aw::config_field& field, T&) {
      name = field.name;
    }
  };

  static_assert(aw::valid<int, multi_meta>::value, "Float metadata field not detected as being valid");

  class single_meta {
  public:
    single_meta(const char* name) :
      name(name)
    {}

    const char* name;
    static const bool multi = false;
  };

  class MyConfigurableClass {
  public:
    autowiring::config<std::string> a{ "Hello world!" };
    std::atomic<int> b{ 929 };
    std::atomic<unsigned int> bUnsigned{ 92999 };
    volatile bool c = false;
    volatile float d = 1.0f;
    volatile double e = 99.2;
    autowiring::observable<int> obs{ 44 };
    autowiring::config<int> cfg{ 929999 };

    static autowiring::config_descriptor GetConfigDescriptor(void) {
      return {
        { "a", "Field A description", &MyConfigurableClass::a, "Hello world!" },
        { "b", "Field B description", &MyConfigurableClass::b, 929, aw::bounds<int>{ 0, 1000 }, multi_meta{}, multi_meta{} },
        { "bUnsigned", "Description", &MyConfigurableClass::bUnsigned, 4444, single_meta{"Hello world!"} },
        { "c", &MyConfigurableClass::c },
        { "d", &MyConfigurableClass::d },
        { "e", &MyConfigurableClass::e },
        { "obs", &MyConfigurableClass::obs },
        { "cfg", &MyConfigurableClass::cfg }
      };
    }
  };

  class BadClass {
  public:
    autowiring::config_descriptor GetConfigDescriptor(void) { return{}; }
  };
}

static_assert(!aw::is_multi<aw::bounds<int>>::value, "Bounds should not have been marked as a multi-select type");
static_assert(!aw::is_multi<single_meta>::value, "Single metadata type incorrectly detected as supporting multiple instantiations");
static_assert(aw::is_multi<multi_meta>::value, "Multi metadata type not correctly detecting as supporting multiple instantiations");
static_assert(aw::has_getconfigdescriptor<MyConfigurableClass>::value, "Static new not correctly detected");
static_assert(!aw::has_getconfigdescriptor<BadClass>::value, "Bad class cannot have a configuration descriptor");
static_assert(!aw::has_bind<aw::bounds<int>, int>::value, "Bind incorrectly detected on bounds field");
static_assert(aw::has_contextual_bind<multi_meta, int>::value, "Contextual bind not detected on multimeta type");

TEST_F(AutoConfigTest, ConfigFieldAssign) {
  autowiring::config<std::string> x{ "Hello world!" };
  ASSERT_TRUE(x.is_dirty()) << "Config values are assumed to be initially dirty";
}

TEST_F(AutoConfigTest, String) {
  MyConfigurableClass c;

  std::string expected{ "Forescore and seven years ago" };
  autowiring::ConfigSet("a", c, expected.c_str());
  ASSERT_TRUE(c.a.clear_dirty());
  ASSERT_STREQ(expected.c_str(), c.a->c_str()) << "String configuration value not assigned";
}

TEST_F(AutoConfigTest, Integer) {
  MyConfigurableClass c;

  autowiring::ConfigSet("b", c, "999");
  ASSERT_EQ(c.b, 999) << "Integer configuration value not assigned";

  autowiring::ConfigSet("b", c, "-999");
  ASSERT_EQ(c.b, -999) << "Negative integer configuration value not assigned";
}

TEST_F(AutoConfigTest, IntegerUnsigned) {
  MyConfigurableClass c;

  c.bUnsigned = 10929;
  std::string strVal = autowiring::ConfigGet("bUnsigned", c);
  ASSERT_STREQ("10929", strVal.c_str());

  autowiring::ConfigSet("bUnsigned", c, "999");
  ASSERT_EQ(c.bUnsigned, 999) << "Integer configuration value not assigned";
  ASSERT_ANY_THROW(autowiring::ConfigSet("bUnsigned", c, "-999")) << "Incorrectly assigned as signed value to an unsigned field";
}

TEST_F(AutoConfigTest, Bool) {
  MyConfigurableClass c;

  autowiring::ConfigSet("c", c, "true");
  ASSERT_TRUE(c.c) << "Boolean configuration value not assigned";
}

TEST_F(AutoConfigTest, Float) {
  MyConfigurableClass c;

  c.d = 10929.4f;
  std::string strVal = autowiring::ConfigGet("d", c);
  ASSERT_STREQ("10929.4", strVal.c_str());

  autowiring::ConfigSet("d", c, "123.4");
  ASSERT_FLOAT_EQ(c.d, 123.4f) << "Float configuration value not assigned";
}

TEST_F(AutoConfigTest, Double) {
  MyConfigurableClass c;
  std::string strVal;

  c.e = 10929.4423;
  strVal = autowiring::ConfigGet("e", c);
  ASSERT_STREQ("10929.4423", strVal.c_str());

  c.e = 109290000000000;
  strVal = autowiring::ConfigGet("e", c);
  ASSERT_STREQ("109290000000000", strVal.c_str());

  c.e = -0.0099291;
  strVal = autowiring::ConfigGet("e", c);
  ASSERT_STREQ("-0.0099291", strVal.c_str());

  autowiring::ConfigSet("e", c, "77482.4");
  ASSERT_DOUBLE_EQ(c.e, 77482.4) << "Double configuration value not assigned";
}

TEST_F(AutoConfigTest, Observable) {
  MyConfigurableClass c;

  bool hit = false;
  c.obs.onChanged += [&hit] { hit = true; };
  autowiring::ConfigSet("obs", c, "101");
  ASSERT_EQ(101, c.obs) << "Value not properly assigned";
  ASSERT_TRUE(hit) << "Observable signal not asserted";
}

TEST_F(AutoConfigTest, Configurable) {
  AutoCurrentContext ctxt;
  AutoRequired<MyConfigurableClass> c;

  ASSERT_TRUE(c->cfg.clear_dirty()) << "Dirty flag was not set on a value that should have been dirty";
  ASSERT_FALSE(c->cfg.is_dirty());
  ctxt->Config.Set("cfg", "888");
  ASSERT_TRUE(c->cfg.is_dirty()) << "Dirty flag not set correctly after being updated in configuration";
  ASSERT_TRUE(c->cfg.clear_dirty());
  ASSERT_EQ(888, c->cfg);
}

TEST_F(AutoConfigTest, ContextSetSimple) {
  AutoCurrentContext ctxt;
  AutoRequired<MyConfigurableClass> mcc;

  ctxt->Config.Set("b", "1029");
  ASSERT_EQ(mcc->b, 1029);
}

TEST_F(AutoConfigTest, ContextSetAfter) {
  AutoCurrentContext ctxt;
  ctxt->Config.Set("b", "10442");

  AutoRequired<MyConfigurableClass> mcc;
  ASSERT_EQ(mcc->b, 10442);
}

namespace {
  class slider
  {
  public:
    template<typename U>
    struct valid {
      static const bool value = std::is_arithmetic<U>::value;
    };
  };

  static_assert(aw::valid<float, slider>::value, "Float metadata field not detected as being valid");
  static_assert(!std::is_arithmetic<std::string>::value, "Strings are not arithmetic");
  static_assert(!slider::valid<std::string>::value, "Slider should not believe strings are valid");
  static_assert(!aw::valid<std::string, slider>::value, "String metadata field incorrectly detected as being valid");

  class SliderManager {
  public:
    SliderManager(void) {
      AutoCurrentContext ctxt;
      ctxt->Config.When(
        [this] (const aw::config_field& field, const slider& slider) {
          sliderReg.push_back(slider);
        }
      );
    }

    std::vector<slider> sliderReg;
  };

  class ClassWithBoundsField {
  public:
    std::atomic<int> b{ 929 };

    static autowiring::config_descriptor GetConfigDescriptor(void) {
      return{
        aw::config_field { "b", "Field B description", &ClassWithBoundsField::b, 929, slider{}, aw::bounds<int>{ 10, 423 } },
      };
    }
  };
}

TEST_F(AutoConfigTest, OpenRegistry) {
  AutoRequired<SliderManager> mgr;
  AutoRequired<ClassWithBoundsField> cwbf;

  ASSERT_EQ(1UL, mgr->sliderReg.size()) << "Slider registration count did not match expectatiosn";
}
<commit_msg>Fix transposed letters<commit_after>// Copyright (C) 2012-2015 Leap Motion, Inc. All rights reserved.
#include "stdafx.h"
#include <autowiring/config_descriptor.h>
#include <autowiring/config.h>
#include <autowiring/ConfigRegistry.h>
#include <autowiring/observable.h>

namespace aw = autowiring;

class AutoConfigTest:
  public testing::Test
{};

namespace {
  class multi_meta {
  public:
    static const bool multi = true;

    std::string name;

    template<typename T>
    void bind(const aw::config_field& field, T&) {
      name = field.name;
    }
  };

  static_assert(aw::valid<int, multi_meta>::value, "Float metadata field not detected as being valid");

  class single_meta {
  public:
    single_meta(const char* name) :
      name(name)
    {}

    const char* name;
    static const bool multi = false;
  };

  class MyConfigurableClass {
  public:
    autowiring::config<std::string> a{ "Hello world!" };
    std::atomic<int> b{ 929 };
    std::atomic<unsigned int> bUnsigned{ 92999 };
    volatile bool c = false;
    volatile float d = 1.0f;
    volatile double e = 99.2;
    autowiring::observable<int> obs{ 44 };
    autowiring::config<int> cfg{ 929999 };

    static autowiring::config_descriptor GetConfigDescriptor(void) {
      return {
        { "a", "Field A description", &MyConfigurableClass::a, "Hello world!" },
        { "b", "Field B description", &MyConfigurableClass::b, 929, aw::bounds<int>{ 0, 1000 }, multi_meta{}, multi_meta{} },
        { "bUnsigned", "Description", &MyConfigurableClass::bUnsigned, 4444, single_meta{"Hello world!"} },
        { "c", &MyConfigurableClass::c },
        { "d", &MyConfigurableClass::d },
        { "e", &MyConfigurableClass::e },
        { "obs", &MyConfigurableClass::obs },
        { "cfg", &MyConfigurableClass::cfg }
      };
    }
  };

  class BadClass {
  public:
    autowiring::config_descriptor GetConfigDescriptor(void) { return{}; }
  };
}

static_assert(!aw::is_multi<aw::bounds<int>>::value, "Bounds should not have been marked as a multi-select type");
static_assert(!aw::is_multi<single_meta>::value, "Single metadata type incorrectly detected as supporting multiple instantiations");
static_assert(aw::is_multi<multi_meta>::value, "Multi metadata type not correctly detecting as supporting multiple instantiations");
static_assert(aw::has_getconfigdescriptor<MyConfigurableClass>::value, "Static new not correctly detected");
static_assert(!aw::has_getconfigdescriptor<BadClass>::value, "Bad class cannot have a configuration descriptor");
static_assert(!aw::has_bind<aw::bounds<int>, int>::value, "Bind incorrectly detected on bounds field");
static_assert(aw::has_contextual_bind<multi_meta, int>::value, "Contextual bind not detected on multimeta type");

TEST_F(AutoConfigTest, ConfigFieldAssign) {
  autowiring::config<std::string> x{ "Hello world!" };
  ASSERT_TRUE(x.is_dirty()) << "Config values are assumed to be initially dirty";
}

TEST_F(AutoConfigTest, String) {
  MyConfigurableClass c;

  std::string expected{ "Forescore and seven years ago" };
  autowiring::ConfigSet("a", c, expected.c_str());
  ASSERT_TRUE(c.a.clear_dirty());
  ASSERT_STREQ(expected.c_str(), c.a->c_str()) << "String configuration value not assigned";
}

TEST_F(AutoConfigTest, Integer) {
  MyConfigurableClass c;

  autowiring::ConfigSet("b", c, "999");
  ASSERT_EQ(c.b, 999) << "Integer configuration value not assigned";

  autowiring::ConfigSet("b", c, "-999");
  ASSERT_EQ(c.b, -999) << "Negative integer configuration value not assigned";
}

TEST_F(AutoConfigTest, IntegerUnsigned) {
  MyConfigurableClass c;

  c.bUnsigned = 10929;
  std::string strVal = autowiring::ConfigGet("bUnsigned", c);
  ASSERT_STREQ("10929", strVal.c_str());

  autowiring::ConfigSet("bUnsigned", c, "999");
  ASSERT_EQ(c.bUnsigned, 999) << "Integer configuration value not assigned";
  ASSERT_ANY_THROW(autowiring::ConfigSet("bUnsigned", c, "-999")) << "Incorrectly assigned as signed value to an unsigned field";
}

TEST_F(AutoConfigTest, Bool) {
  MyConfigurableClass c;

  autowiring::ConfigSet("c", c, "true");
  ASSERT_TRUE(c.c) << "Boolean configuration value not assigned";
}

TEST_F(AutoConfigTest, Float) {
  MyConfigurableClass c;

  c.d = 10929.4f;
  std::string strVal = autowiring::ConfigGet("d", c);
  ASSERT_STREQ("10929.4", strVal.c_str());

  autowiring::ConfigSet("d", c, "123.4");
  ASSERT_FLOAT_EQ(c.d, 123.4f) << "Float configuration value not assigned";
}

TEST_F(AutoConfigTest, Double) {
  MyConfigurableClass c;
  std::string strVal;

  c.e = 10929.4423;
  strVal = autowiring::ConfigGet("e", c);
  ASSERT_STREQ("10929.4423", strVal.c_str());

  c.e = 109290000000000;
  strVal = autowiring::ConfigGet("e", c);
  ASSERT_STREQ("109290000000000", strVal.c_str());

  c.e = -0.0099291;
  strVal = autowiring::ConfigGet("e", c);
  ASSERT_STREQ("-0.0099291", strVal.c_str());

  autowiring::ConfigSet("e", c, "77482.4");
  ASSERT_DOUBLE_EQ(c.e, 77482.4) << "Double configuration value not assigned";
}

TEST_F(AutoConfigTest, Observable) {
  MyConfigurableClass c;

  bool hit = false;
  c.obs.onChanged += [&hit] { hit = true; };
  autowiring::ConfigSet("obs", c, "101");
  ASSERT_EQ(101, c.obs) << "Value not properly assigned";
  ASSERT_TRUE(hit) << "Observable signal not asserted";
}

TEST_F(AutoConfigTest, Configurable) {
  AutoCurrentContext ctxt;
  AutoRequired<MyConfigurableClass> c;

  ASSERT_TRUE(c->cfg.clear_dirty()) << "Dirty flag was not set on a value that should have been dirty";
  ASSERT_FALSE(c->cfg.is_dirty());
  ctxt->Config.Set("cfg", "888");
  ASSERT_TRUE(c->cfg.is_dirty()) << "Dirty flag not set correctly after being updated in configuration";
  ASSERT_TRUE(c->cfg.clear_dirty());
  ASSERT_EQ(888, c->cfg);
}

TEST_F(AutoConfigTest, ContextSetSimple) {
  AutoCurrentContext ctxt;
  AutoRequired<MyConfigurableClass> mcc;

  ctxt->Config.Set("b", "1029");
  ASSERT_EQ(mcc->b, 1029);
}

TEST_F(AutoConfigTest, ContextSetAfter) {
  AutoCurrentContext ctxt;
  ctxt->Config.Set("b", "10442");

  AutoRequired<MyConfigurableClass> mcc;
  ASSERT_EQ(mcc->b, 10442);
}

namespace {
  class slider
  {
  public:
    template<typename U>
    struct valid {
      static const bool value = std::is_arithmetic<U>::value;
    };
  };

  static_assert(aw::valid<float, slider>::value, "Float metadata field not detected as being valid");
  static_assert(!std::is_arithmetic<std::string>::value, "Strings are not arithmetic");
  static_assert(!slider::valid<std::string>::value, "Slider should not believe strings are valid");
  static_assert(!aw::valid<std::string, slider>::value, "String metadata field incorrectly detected as being valid");

  class SliderManager {
  public:
    SliderManager(void) {
      AutoCurrentContext ctxt;
      ctxt->Config.When(
        [this] (const aw::config_field& field, const slider& slider) {
          sliderReg.push_back(slider);
        }
      );
    }

    std::vector<slider> sliderReg;
  };

  class ClassWithBoundsField {
  public:
    std::atomic<int> b{ 929 };

    static autowiring::config_descriptor GetConfigDescriptor(void) {
      return{
        aw::config_field { "b", "Field B description", &ClassWithBoundsField::b, 929, slider{}, aw::bounds<int>{ 10, 423 } },
      };
    }
  };
}

TEST_F(AutoConfigTest, OpenRegistry) {
  AutoRequired<SliderManager> mgr;
  AutoRequired<ClassWithBoundsField> cwbf;

  ASSERT_EQ(1UL, mgr->sliderReg.size()) << "Slider registration count did not match expectations";
}
<|endoftext|>


<commit_before>#include "pch.h"
#include "axl_err_Error.h"
#include "axl_spy_ImportTableMgr.h"

#if (_AXL_OS_POSIX)
#	include "axl_sys_psx_DynamicLib.h"
#	include <link.h>
#endif

namespace axl {
namespace spy {

//..............................................................................

#if (_AXL_OS_WIN)

size_t
ImportTableMgr::enumerateImports(void* module)
{
	if (!module)
		module = ::GetModuleHandle(NULL);

	char* moduleBase = (char*)module;

	IMAGE_DOS_HEADER* dosHdr = (IMAGE_DOS_HEADER*)moduleBase;
	if (dosHdr->e_magic != IMAGE_DOS_SIGNATURE)
	{
		err::setError("invalid module (bad DOS signature)");
		return -1;
	}

	IMAGE_NT_HEADERS* peHdr = (IMAGE_NT_HEADERS*)(moduleBase + dosHdr->e_lfanew);
	if (peHdr->Signature != IMAGE_NT_SIGNATURE)
	{
		err::setError("invalid module (bad PE signature)");
		return -1;
	}

	IMAGE_DATA_DIRECTORY* importDir = (IMAGE_DATA_DIRECTORY*)&peHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
	IMAGE_IMPORT_DESCRIPTOR* p = (IMAGE_IMPORT_DESCRIPTOR*)(moduleBase + importDir->VirtualAddress);
	IMAGE_IMPORT_DESCRIPTOR* end = p + importDir->Size / sizeof(IMAGE_IMPORT_DESCRIPTOR);

	size_t count = 0;

	for (; p < end && p->Name; p++)
	{
        IMAGE_THUNK_DATA* nameThunk = (IMAGE_THUNK_DATA*)(moduleBase + p->OriginalFirstThunk);
        IMAGE_THUNK_DATA* addrThunk = (IMAGE_THUNK_DATA*)(moduleBase + p->FirstThunk);

		const char* moduleName = moduleBase + p->Name;
		printf("%s\n", moduleName);

		for (; addrThunk->u1.Function; nameThunk++, addrThunk++, count++)
		{
            if (IMAGE_SNAP_BY_ORDINAL(nameThunk->u1.Ordinal))
			{
                uint_t ordinal = IMAGE_ORDINAL(nameThunk->u1.Ordinal);
				printf("  @%d\n", ordinal);
            }
			else
			{
				IMAGE_IMPORT_BY_NAME* name = (IMAGE_IMPORT_BY_NAME*)(moduleBase + nameThunk->u1.AddressOfData);
				printf("  hint %04x: %s\n", name->Hint, name->Name);
			}
		}
	}

	return count;
}

#elif (_AXL_OS_LINUX)
#	if (_AXL_CPU_X86)
#	define ELF_R_TYPE  ELF32_R_TYPE
#	define ELF_R_SYM   ELF32_R_SYM
#	define ELF_ST_TYPE ELF32_ST_TYPE
#	define ELF_ST_BIND ELF32_ST_BIND

	typedef ElfW(Rel) ElfRel;

	enum Dt
	{
		Dt_Rel     = DT_REL,
		Dt_RelSz   = DT_RELSZ,
		Dt_RelEnt  = DT_RELENT,

		R_GlobDat  = R_386_GLOB_DAT,
		R_JumpSlot = R_386_JMP_SLOT,
	};
#	elif (_AXL_CPU_AMD64)
#	define ELF_R_TYPE  ELF64_R_TYPE
#	define ELF_R_SYM   ELF64_R_SYM
#	define ELF_ST_TYPE ELF64_ST_TYPE
#	define ELF_ST_BIND ELF64_ST_BIND

	typedef ElfW(Rela) ElfRel;

	enum
	{
		Dt_Rel     = DT_RELA,
		Dt_RelSz   = DT_RELASZ,
		Dt_RelEnt  = DT_RELAENT,

		R_GlobDat  = R_X86_64_GLOB_DAT,
		R_JumpSlot = R_X86_64_JUMP_SLOT,
	}
#	elif (_AXL_CPU_ARM32)
#	define ELF_R_TYPE  ELF32_R_TYPE
#	define ELF_R_SYM   ELF32_R_SYM
#	define ELF_ST_TYPE ELF32_ST_TYPE
#	define ELF_ST_BIND ELF32_ST_BIND

	typedef ElfW(Rel) ElfRel;

	enum
	{
		Dt_Rel     = DT_RELA,
		Dt_RelSz   = DT_RELASZ,
		Dt_RelEnt  = DT_RELAENT,

		R_GlobDat  = R_X86_64_GLOB_DAT,
		R_JumpSlot = R_X86_64_JUMP_SLOT,
	};
#	endif

void
printRelTable(
	ElfRel* rel,
	size_t count,
	int relType,
	char* moduleBase,
	ElfW(Sym)* symbolTable,
	char* stringTable,
	size_t stringTableSize
	)
{
	ElfRel* end = rel + count;

	for (; rel < end; rel++)
	{
		if (ELF_R_TYPE(rel->r_info) != relType)
			continue;

		size_t symIdx = ELF_R_SYM(rel->r_info);
		ElfW(Sym)* sym = symbolTable + symIdx;
		if (ELF_ST_TYPE(sym->st_info) != STT_FUNC)
			continue;

		if (sym->st_name >= stringTableSize)
		{
			printf("*** symbol out of string table\n");
			continue;
		}

		char* name = stringTable + sym->st_name;
		void** p = (void**)(moduleBase + rel->r_offset);
		printf("  %p %s\n", *p, name);
	}
}

size_t
ImportTableMgr::enumerateImports(void* module)
{
	bool result;

	sys::psx::DynamicLib exe;
	if (!module)
	{
		result = exe.open(NULL, RTLD_LAZY | RTLD_NOLOAD);
		if (!result)
			return -1;

		module = exe;
	}

	link_map* linkMap;

	sys::psx::DynamicLib lib;
	lib.attach(module);
	result = exe.getInfo(RTLD_DI_LINKMAP, &linkMap);
	lib.detach();

	if (!result)
		return -1;

	ElfW(Dyn)* dynTable[DT_NUM] = { 0 };
	ElfW(Dyn)* dyn = linkMap->l_ld;
	for (; dyn->d_tag; dyn++)
	{
		if (dyn->d_tag < countof(dynTable))
			dynTable[dyn->d_tag] = dyn;
	}

	// sanity checks

	if (!dynTable[DT_SYMTAB] ||
		!dynTable[DT_SYMENT] ||
		!dynTable[DT_STRTAB] ||
		!dynTable[DT_STRSZ] ||
		!dynTable[Dt_Rel] != !dynTable[Dt_RelSz] ||
		!dynTable[Dt_Rel] != !dynTable[Dt_RelEnt] ||
		!dynTable[DT_JMPREL] != !dynTable[DT_PLTRELSZ] ||
		dynTable[DT_SYMENT]->d_un.d_val != sizeof(ElfW(Sym)) ||
		dynTable[Dt_RelEnt]->d_un.d_val != sizeof(ElfRel))
	{
		err::setError("invalid ELF (missing or bad section(s))");
		return -1;
	}

	ElfW(Sym)* symbolTable = (ElfW(Sym)*)dynTable[DT_SYMTAB]->d_un.d_ptr;
	char* stringTable = (char*)dynTable[DT_STRTAB]->d_un.d_ptr;
	size_t stringTableSize = dynTable[DT_STRSZ]->d_un.d_val;

	size_t pltCount = dynTable[DT_PLTRELSZ] ? dynTable[DT_PLTRELSZ]->d_un.d_val / sizeof(ElfRel) : 0;
	size_t gotCount = dynTable[Dt_RelSz] ? dynTable[Dt_RelSz]->d_un.d_val / sizeof(ElfRel) : 0;

	if (pltCount)
	{
		printf("PLT:\n");

		printRelTable(
			(ElfRel*)dynTable[DT_JMPREL]->d_un.d_ptr,
			pltCount,
			R_JumpSlot,
			(char*)linkMap->l_addr,
			symbolTable,
			stringTable,
			stringTableSize
			);
	}

	if (gotCount)
	{
		printf("GOT:\n");

		printRelTable(
			(ElfRel*)dynTable[Dt_Rel]->d_un.d_ptr,
			gotCount,
			R_GlobDat,
			(char*)linkMap->l_addr,
			symbolTable,
			stringTable,
			stringTableSize
			);
	}

	return 0;
}

#elif (_AXL_OS_DARWIN)
#endif

//..............................................................................

} // namespace spy
} // namespace axl
<commit_msg>[axl_spy] enumerate import names for mach-o<commit_after>#include "pch.h"
#include "axl_err_Error.h"
#include "axl_spy_ImportTableMgr.h"
#include "axl_sl_Array.h"

#if (_AXL_OS_LINUX)
#	include "axl_sys_psx_DynamicLib.h"
#	include <link.h>
#elif (_AXL_OS_DARWIN)
#   include <mach-o/dyld.h>
#endif

namespace axl {
namespace spy {

//..............................................................................

#if (_AXL_OS_WIN)

size_t
ImportTableMgr::enumerateImports(void* module)
{
	if (!module)
		module = ::GetModuleHandle(NULL);

	char* moduleBase = (char*)module;

	IMAGE_DOS_HEADER* dosHdr = (IMAGE_DOS_HEADER*)moduleBase;
	if (dosHdr->e_magic != IMAGE_DOS_SIGNATURE)
	{
		err::setError("invalid module (bad DOS signature)");
		return -1;
	}

	IMAGE_NT_HEADERS* peHdr = (IMAGE_NT_HEADERS*)(moduleBase + dosHdr->e_lfanew);
	if (peHdr->Signature != IMAGE_NT_SIGNATURE)
	{
		err::setError("invalid module (bad PE signature)");
		return -1;
	}

	IMAGE_DATA_DIRECTORY* importDir = (IMAGE_DATA_DIRECTORY*)&peHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
	IMAGE_IMPORT_DESCRIPTOR* p = (IMAGE_IMPORT_DESCRIPTOR*)(moduleBase + importDir->VirtualAddress);
	IMAGE_IMPORT_DESCRIPTOR* end = p + importDir->Size / sizeof(IMAGE_IMPORT_DESCRIPTOR);

	size_t count = 0;

	for (; p < end && p->Name; p++)
	{
        IMAGE_THUNK_DATA* nameThunk = (IMAGE_THUNK_DATA*)(moduleBase + p->OriginalFirstThunk);
        IMAGE_THUNK_DATA* addrThunk = (IMAGE_THUNK_DATA*)(moduleBase + p->FirstThunk);

		const char* moduleName = moduleBase + p->Name;
		printf("%s\n", moduleName);

		for (; addrThunk->u1.Function; nameThunk++, addrThunk++, count++)
		{
            if (IMAGE_SNAP_BY_ORDINAL(nameThunk->u1.Ordinal))
			{
                uint_t ordinal = IMAGE_ORDINAL(nameThunk->u1.Ordinal);
				printf("  @%d\n", ordinal);
            }
			else
			{
				IMAGE_IMPORT_BY_NAME* name = (IMAGE_IMPORT_BY_NAME*)(moduleBase + nameThunk->u1.AddressOfData);
				printf("  hint %04x: %s\n", name->Hint, name->Name);
			}
		}
	}

	return count;
}

#elif (_AXL_OS_LINUX)
#	if (_AXL_CPU_X86)
#	define ELF_R_TYPE  ELF32_R_TYPE
#	define ELF_R_SYM   ELF32_R_SYM
#	define ELF_ST_TYPE ELF32_ST_TYPE
#	define ELF_ST_BIND ELF32_ST_BIND

	typedef ElfW(Rel) ElfRel;

	enum Dt
	{
		Dt_Rel     = DT_REL,
		Dt_RelSz   = DT_RELSZ,
		Dt_RelEnt  = DT_RELENT,

		R_GlobDat  = R_386_GLOB_DAT,
		R_JumpSlot = R_386_JMP_SLOT,
	};
#	elif (_AXL_CPU_AMD64)
#	define ELF_R_TYPE  ELF64_R_TYPE
#	define ELF_R_SYM   ELF64_R_SYM
#	define ELF_ST_TYPE ELF64_ST_TYPE
#	define ELF_ST_BIND ELF64_ST_BIND

	typedef ElfW(Rela) ElfRel;

	enum
	{
		Dt_Rel     = DT_RELA,
		Dt_RelSz   = DT_RELASZ,
		Dt_RelEnt  = DT_RELAENT,

		R_GlobDat  = R_X86_64_GLOB_DAT,
		R_JumpSlot = R_X86_64_JUMP_SLOT,
	}
#	elif (_AXL_CPU_ARM32)
#	define ELF_R_TYPE  ELF32_R_TYPE
#	define ELF_R_SYM   ELF32_R_SYM
#	define ELF_ST_TYPE ELF32_ST_TYPE
#	define ELF_ST_BIND ELF32_ST_BIND

	typedef ElfW(Rel) ElfRel;

	enum
	{
		Dt_Rel     = DT_RELA,
		Dt_RelSz   = DT_RELASZ,
		Dt_RelEnt  = DT_RELAENT,

		R_GlobDat  = R_X86_64_GLOB_DAT,
		R_JumpSlot = R_X86_64_JUMP_SLOT,
	};
#	endif

void
printRelTable(
	ElfRel* rel,
	size_t count,
	int relType,
	char* moduleBase,
	ElfW(Sym)* symbolTable,
	char* stringTable,
	size_t stringTableSize
	)
{
	ElfRel* end = rel + count;

	for (; rel < end; rel++)
	{
		if (ELF_R_TYPE(rel->r_info) != relType)
			continue;

		size_t symIdx = ELF_R_SYM(rel->r_info);
		ElfW(Sym)* sym = symbolTable + symIdx;
		if (ELF_ST_TYPE(sym->st_info) != STT_FUNC)
			continue;

		if (sym->st_name >= stringTableSize)
		{
			printf("*** symbol out of string table\n");
			continue;
		}

		char* name = stringTable + sym->st_name;
		void** p = (void**)(moduleBase + rel->r_offset);
		printf("  %p %s\n", *p, name);
	}
}

size_t
ImportTableMgr::enumerateImports(void* module)
{
	bool result;

	link_map* linkMap;

	sys::psx::DynamicLib exe;
	if (!module)
	{
		result =
			exe.open(NULL, RTLD_LAZY | RTLD_NOLOAD) &&
			exe.getInfo(RTLD_DI_LINKMAP, &linkMap);
	}
	else
	{
		sys::psx::DynamicLib lib;
		lib.attach(module);
		result = lib.getInfo(RTLD_DI_LINKMAP, &linkMap);
		lib.detach();
	}

	if (!result)
		return -1;

	ElfW(Dyn)* dynTable[DT_NUM] = { 0 };
	ElfW(Dyn)* dyn = linkMap->l_ld;
	for (; dyn->d_tag; dyn++)
	{
		if (dyn->d_tag < countof(dynTable))
			dynTable[dyn->d_tag] = dyn;
	}

	// sanity checks

	if (!dynTable[DT_SYMTAB] ||
		!dynTable[DT_SYMENT] ||
		!dynTable[DT_STRTAB] ||
		!dynTable[DT_STRSZ] ||
		!dynTable[Dt_Rel] != !dynTable[Dt_RelSz] ||
		!dynTable[Dt_Rel] != !dynTable[Dt_RelEnt] ||
		!dynTable[DT_JMPREL] != !dynTable[DT_PLTRELSZ] ||
		dynTable[DT_SYMENT]->d_un.d_val != sizeof(ElfW(Sym)) ||
		dynTable[Dt_RelEnt]->d_un.d_val != sizeof(ElfRel))
	{
		err::setError("invalid ELF (missing or bad section(s))");
		return -1;
	}

	ElfW(Sym)* symbolTable = (ElfW(Sym)*)dynTable[DT_SYMTAB]->d_un.d_ptr;
	char* stringTable = (char*)dynTable[DT_STRTAB]->d_un.d_ptr;
	size_t stringTableSize = dynTable[DT_STRSZ]->d_un.d_val;

	size_t pltCount = dynTable[DT_PLTRELSZ] ? dynTable[DT_PLTRELSZ]->d_un.d_val / sizeof(ElfRel) : 0;
	size_t gotCount = dynTable[Dt_RelSz] ? dynTable[Dt_RelSz]->d_un.d_val / sizeof(ElfRel) : 0;

	if (pltCount)
	{
		printf("PLT:\n");

		printRelTable(
			(ElfRel*)dynTable[DT_JMPREL]->d_un.d_ptr,
			pltCount,
			R_JumpSlot,
			(char*)linkMap->l_addr,
			symbolTable,
			stringTable,
			stringTableSize
			);
	}

	if (gotCount)
	{
		printf("GOT:\n");

		printRelTable(
			(ElfRel*)dynTable[Dt_Rel]->d_un.d_ptr,
			gotCount,
			R_GlobDat,
			(char*)linkMap->l_addr,
			symbolTable,
			stringTable,
			stringTableSize
			);
	}

	return pltCount + gotCount;
}

#elif (_AXL_OS_DARWIN)

uint64_t uleb128(const uint8_t** p)
{
	uint64_t r = 0;
	int s = 0;

	do
	{
		r |= (uint64_t)(**p & 0x7f) << s;
		s += 7;
	} while (*(*p)++ >= 0x80);

	return r;
}

int64_t sleb128(const uint8_t** p)
{
	int64_t r = 0;
	int s = 0;
	for (;;)
	{
		uint8_t b = *(*p)++;
		if (b < 0x80)
		{
			if (b & 0x40)
				r -= (0x80 - b) << s;
			else
				r |= (b & 0x3f) << s;

			break;
		}

		r |= (b & 0x7f) << s;
		s += 7;
	}

	return r;
}

size_t
ImportTableMgr::enumerateImports(void* module)
{
	uint8_t* slide = (uint8_t*)_dyld_get_image_vmaddr_slide(0);
	mach_header_64* machHdr = (mach_header_64*)_dyld_get_image_header(0);
	load_command* cmd = (load_command*)(machHdr + 1);

	sl::Array<segment_command_64*> segmentCmdArray;
	size_t linkEditSegmentIdx = -1;
	size_t lazyBindOffset = -1;
	size_t lazyBindSize = -1;

	for (uint_t i = 0; i < machHdr->ncmds; i++)
	{
		printf("load_command: 0x%x\n", cmd->cmd);

		switch (cmd->cmd)
		{
			segment_command_64* segmentCmd;
			dyld_info_command* dyldInfoCmd;

		case LC_SEGMENT_64:
			segmentCmd = (segment_command_64*)cmd;

			if (strcmp(segmentCmd->segname, "__LINKEDIT") == 0)
				linkEditSegmentIdx = segmentCmdArray.getCount();

			segmentCmdArray.append(segmentCmd);
			break;

		case LC_DYLD_INFO_ONLY:
			dyldInfoCmd = (dyld_info_command*)cmd;
			lazyBindOffset = dyldInfoCmd->lazy_bind_off;
			lazyBindSize = dyldInfoCmd->lazy_bind_size;
			break;
		}

		cmd = (load_command*)((char*)cmd + cmd->cmdsize);
	}

	if (linkEditSegmentIdx == -1 ||
		lazyBindOffset == -1 ||
		lazyBindSize == -1)
	{
		err::setError("invalid MACH-O file");
		return -1;
	}

	segment_command_64* linkEditSegmentCmd = segmentCmdArray[linkEditSegmentIdx];

	const uint8_t* p = slide + linkEditSegmentCmd->vmaddr - linkEditSegmentCmd->fileoff + lazyBindOffset;
	const uint8_t* end = p + lazyBindSize;

	while (p < end)
	{
		uint8_t op = *p & BIND_OPCODE_MASK;
		uint8_t imm = *p & BIND_IMMEDIATE_MASK;
		p++;

		switch (op)
		{
		case BIND_OPCODE_DONE:
		case BIND_OPCODE_DO_BIND:
		case BIND_OPCODE_SET_TYPE_IMM:
		case BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:
		case BIND_OPCODE_SET_DYLIB_SPECIAL_IMM:
		case BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
			break;

		case BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
			printf("  %s\n", p);
			p += strlen((char*)p) + 1;
			break;

		case BIND_OPCODE_SET_ADDEND_SLEB:
			sleb128(&p);
			break;

		case BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
		case BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
		case BIND_OPCODE_ADD_ADDR_ULEB:
		case BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
			uleb128(&p);
			break;

		case BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
			uleb128(&p);
			uleb128(&p);
			break;

		default:
			printf("*** unexpected bind op: 0x%02x\n", op);
		}
	}

	return -1;
}

#endif

//..............................................................................

} // namespace spy
} // namespace axl
<|endoftext|>


<commit_before>#pragma once

#include <glm/glm.hpp>

class CollisionBox2D {
public:
	inline bool collide(const glm::vec2& point) { return point.x > _pos.x && point.x < _pos.x + _size.x && point.y > _pos.y && point.y < _pos.y + _size.y; }
	inline bool collide(const CollisionBox2D& other) {
		return _pos.x < other._pos.x + other._size.x && _pos.x + _size.x > other._pos.x && _pos.y < other._pos.y + other._size.y && _pos.y + _size.y < other._pos.y;
	}

private:
	glm::vec2 _pos;
	glm::vec2 _size;
};<commit_msg>Small changes to CollisionBox2D<commit_after>#pragma once

#include <glm/glm.hpp>

struct CollisionBox2D {
	glm::vec2 position;
	glm::vec2 size;

	CollisionBox2D(glm::vec2 position, glm::vec2 size) : position(position), size(size) {
	}

	inline bool collide(const glm::vec2& point) {
		return point.x > position.x && point.x < position.x + size.x && point.y > position.y && point.y < position.y + size.y;
	}
	inline bool collide(const CollisionBox2D& other) {
		return position.x < other.position.x + other.size.x && position.x + size.x > other.position.x && position.y < other.position.y + other.size.y &&
					 position.y + size.y < other.position.y;
	}
};
<|endoftext|>


<commit_before><commit_msg>Remove extra ';'<commit_after><|endoftext|>


<commit_before> /*************************************************************************
 *
 *  $RCSfile: accembedded.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: hr $ $Date: 2003-03-27 15:39:17 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifdef PRECOMPILED
#include "core_pch.hxx"
#endif

#pragma hdrstop

#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLEROLE_HPP_
#include <drafts/com/sun/star/accessibility/AccessibleRole.hpp>
#endif

#ifndef _COM_SUN_STAR_UNO_RUNTIMEEXCEPTION_HPP_
#include <com/sun/star/uno/RuntimeException.hpp>
#endif
#ifndef _RTL_UUID_H_
#include <rtl/uuid.h>
#endif
#ifndef _FLYFRM_HXX
#include <flyfrm.hxx>
#endif

#ifndef _ACCEMBEDDED_HXX
#include "accembedded.hxx"
#endif

using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::uno;
using namespace ::drafts::com::sun::star::accessibility;
using namespace ::rtl;

const sal_Char sServiceName[] = "com.sun.star.text.AccessibleTextEmbeddedObject";
const sal_Char sImplementationName[] = "com.sun.star.comp.Writer.SwAccessibleEmbeddedObject";

SwAccessibleEmbeddedObject::SwAccessibleEmbeddedObject(
        SwAccessibleMap *pMap,
        const SwFlyFrm *pFlyFrm ) :
    SwAccessibleNoTextFrame( pMap, AccessibleRole::EMBEDDED_OBJECT, pFlyFrm )
{
}

SwAccessibleEmbeddedObject::~SwAccessibleEmbeddedObject()
{
}

OUString SAL_CALL SwAccessibleEmbeddedObject::getImplementationName()
        throw( RuntimeException )
{
    return OUString(RTL_CONSTASCII_USTRINGPARAM(sImplementationName));
}

sal_Bool SAL_CALL SwAccessibleEmbeddedObject::supportsService(
        const ::rtl::OUString& sTestServiceName)
    throw (::com::sun::star::uno::RuntimeException)
{
    return sTestServiceName.equalsAsciiL( sServiceName,
                                          sizeof(sServiceName)-1 ) ||
           sTestServiceName.equalsAsciiL( sAccessibleServiceName,
                                             sizeof(sAccessibleServiceName)-1 );
}

Sequence< OUString > SAL_CALL SwAccessibleEmbeddedObject::getSupportedServiceNames()
        throw( ::com::sun::star::uno::RuntimeException )
{
    Sequence< OUString > aRet(2);
    OUString* pArray = aRet.getArray();
    pArray[0] = OUString( RTL_CONSTASCII_USTRINGPARAM(sServiceName) );
    pArray[1] = OUString( RTL_CONSTASCII_USTRINGPARAM(sAccessibleServiceName) );
    return aRet;
}

Sequence< sal_Int8 > SAL_CALL SwAccessibleEmbeddedObject::getImplementationId()
        throw(RuntimeException)
{
    vos::OGuard aGuard(Application::GetSolarMutex());
    static Sequence< sal_Int8 > aId( 16 );
    static sal_Bool bInit = sal_False;
    if(!bInit)
    {
        rtl_createUuid( (sal_uInt8 *)(aId.getArray() ), 0, sal_True );
        bInit = sal_True;
    }
    return aId;
}
<commit_msg>INTEGRATION: CWS os8 (1.3.8.1.48); FILE MERGED 2003/04/03 07:09:20 os 1.3.8.1.48.1: #108583# precompiled headers removed<commit_after> /*************************************************************************
 *
 *  $RCSfile: accembedded.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: vg $ $Date: 2003-04-17 13:35:08 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#pragma hdrstop

#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLEROLE_HPP_
#include <drafts/com/sun/star/accessibility/AccessibleRole.hpp>
#endif

#ifndef _COM_SUN_STAR_UNO_RUNTIMEEXCEPTION_HPP_
#include <com/sun/star/uno/RuntimeException.hpp>
#endif
#ifndef _RTL_UUID_H_
#include <rtl/uuid.h>
#endif
#ifndef _FLYFRM_HXX
#include <flyfrm.hxx>
#endif

#ifndef _ACCEMBEDDED_HXX
#include "accembedded.hxx"
#endif

using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::uno;
using namespace ::drafts::com::sun::star::accessibility;
using namespace ::rtl;

const sal_Char sServiceName[] = "com.sun.star.text.AccessibleTextEmbeddedObject";
const sal_Char sImplementationName[] = "com.sun.star.comp.Writer.SwAccessibleEmbeddedObject";

SwAccessibleEmbeddedObject::SwAccessibleEmbeddedObject(
        SwAccessibleMap *pMap,
        const SwFlyFrm *pFlyFrm ) :
    SwAccessibleNoTextFrame( pMap, AccessibleRole::EMBEDDED_OBJECT, pFlyFrm )
{
}

SwAccessibleEmbeddedObject::~SwAccessibleEmbeddedObject()
{
}

OUString SAL_CALL SwAccessibleEmbeddedObject::getImplementationName()
        throw( RuntimeException )
{
    return OUString(RTL_CONSTASCII_USTRINGPARAM(sImplementationName));
}

sal_Bool SAL_CALL SwAccessibleEmbeddedObject::supportsService(
        const ::rtl::OUString& sTestServiceName)
    throw (::com::sun::star::uno::RuntimeException)
{
    return sTestServiceName.equalsAsciiL( sServiceName,
                                          sizeof(sServiceName)-1 ) ||
           sTestServiceName.equalsAsciiL( sAccessibleServiceName,
                                             sizeof(sAccessibleServiceName)-1 );
}

Sequence< OUString > SAL_CALL SwAccessibleEmbeddedObject::getSupportedServiceNames()
        throw( ::com::sun::star::uno::RuntimeException )
{
    Sequence< OUString > aRet(2);
    OUString* pArray = aRet.getArray();
    pArray[0] = OUString( RTL_CONSTASCII_USTRINGPARAM(sServiceName) );
    pArray[1] = OUString( RTL_CONSTASCII_USTRINGPARAM(sAccessibleServiceName) );
    return aRet;
}

Sequence< sal_Int8 > SAL_CALL SwAccessibleEmbeddedObject::getImplementationId()
        throw(RuntimeException)
{
    vos::OGuard aGuard(Application::GetSolarMutex());
    static Sequence< sal_Int8 > aId( 16 );
    static sal_Bool bInit = sal_False;
    if(!bInit)
    {
        rtl_createUuid( (sal_uInt8 *)(aId.getArray() ), 0, sal_True );
        bInit = sal_True;
    }
    return aId;
}
<|endoftext|>


<commit_before>//----------------------------  multithread_info.cc  ----------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 by the deal authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------  multithread_info.cc  ----------------

#include <base/multithread_info.h>

#if defined(__linux__)
#  include <fstream>
#  include <string>
#endif

#if defined(__sun__) || defined(__osf__) || defined(_AIX)
#  include <unistd.h>
#endif

#if defined(__sgi__)
#  include <unistd.h>
#endif

#if DEAL_II_USE_MT == 1

#if defined(__linux__)

unsigned int MultithreadInfo::get_n_cpus()
{
  std::ifstream cpuinfo;
  std::string search;
  unsigned int nCPU = 0;

  cpuinfo.open("/proc/cpuinfo");

  AssertThrow(cpuinfo,ExcProcNotPresent());

  while(cpuinfo)
    {
      cpuinfo >> search;
      if (search.find("processor")!=std::string::npos)
	nCPU++;
    }
  cpuinfo.close();

  return nCPU;
}

#elif defined(__sun__) || defined(__osf__) || defined(_AIX)

unsigned int MultithreadInfo::get_n_cpus()
{
  return sysconf(_SC_NPROCESSORS_ONLN);
}

#elif defined(__sgi__)

unsigned int MultithreadInfo::get_n_cpus()
{
  return sysconf(_SC_NPROC_ONLN);
}

#else

// if you get to see this warning, then this can have two reasons: either
// because you fell through all of the above #if clauses and on your system
// the detection of processors is really not implemented, or you are using
// a compiler that does not understand the #warning directive, in which case
// you will see a report on the screen even if the detection of processors
// is implemented for your system. In the latter case, you need not worry
// about the warning (although it is acknowledged that it is annoying),
// otherwise you might want to consider implementing the missing feature
// and submitting it back to the authors of the library.
#warning Detection of Processors not supported on this OS

unsigned int MultithreadInfo::get_n_cpus()
{
  return 1;
}

#endif

#else				 // not in multithreadmode

unsigned int MultithreadInfo::get_n_cpus()
{
  return 1;
}

#endif

MultithreadInfo::MultithreadInfo () :
                n_cpus (get_n_cpus()),
                n_default_threads (n_cpus)
{}

unsigned int
MultithreadInfo::memory_consumption ()
{
				   // only simple data elements, so
				   // use sizeof operator
  return sizeof (MultithreadInfo);
}

// definition of the variable which is declared `extern' in the .h file
MultithreadInfo multithread_info;
<commit_msg>Indent prepro statements<commit_after>//----------------------------  multithread_info.cc  ----------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 by the deal authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------  multithread_info.cc  ----------------

#include <base/multithread_info.h>

#if defined(__linux__)
#  include <fstream>
#  include <string>
#endif

#if defined(__sun__) || defined(__osf__) || defined(_AIX)
#  include <unistd.h>
#endif

#if defined(__sgi__)
#  include <unistd.h>
#endif

#if DEAL_II_USE_MT == 1

#  if defined(__linux__)

unsigned int MultithreadInfo::get_n_cpus()
{
  std::ifstream cpuinfo;
  std::string search;
  unsigned int nCPU = 0;

  cpuinfo.open("/proc/cpuinfo");

  AssertThrow(cpuinfo,ExcProcNotPresent());

  while(cpuinfo)
    {
      cpuinfo >> search;
      if (search.find("processor")!=std::string::npos)
	nCPU++;
    }
  cpuinfo.close();

  return nCPU;
}

#  elif defined(__sun__) || defined(__osf__) || defined(_AIX)

unsigned int MultithreadInfo::get_n_cpus()
{
  return sysconf(_SC_NPROCESSORS_ONLN);
}

#  elif defined(__sgi__)

unsigned int MultithreadInfo::get_n_cpus()
{
  return sysconf(_SC_NPROC_ONLN);
}

#  else

// if you get to see this warning, then this can have two reasons: either
// because you fell through all of the above #if clauses and on your system
// the detection of processors is really not implemented, or you are using
// a compiler that does not understand the #warning directive, in which case
// you will see a report on the screen even if the detection of processors
// is implemented for your system. In the latter case, you need not worry
// about the warning (although it is acknowledged that it is annoying),
// otherwise you might want to consider implementing the missing feature
// and submitting it back to the authors of the library.
#    warning Detection of Processors not supported on this OS

unsigned int MultithreadInfo::get_n_cpus()
{
  return 1;
}

#  endif

#else				 // not in MT mode

unsigned int MultithreadInfo::get_n_cpus()
{
  return 1;
}

#endif

MultithreadInfo::MultithreadInfo () :
                n_cpus (get_n_cpus()),
                n_default_threads (n_cpus)
{}

unsigned int
MultithreadInfo::memory_consumption ()
{
				   // only simple data elements, so
				   // use sizeof operator
  return sizeof (MultithreadInfo);
}

// definition of the variable which is declared `extern' in the .h file
MultithreadInfo multithread_info;
<|endoftext|>


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

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sw.hxx"

#ifndef _VOS_MUTEX_HXX_ //autogen
#include <vos/mutex.hxx>
#endif

#ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLEROLE_HPP_
#include <com/sun/star/accessibility/AccessibleRole.hpp>
#endif
#ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLESTATETYPE_HPP_
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
#endif

#ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX_
#include <unotools/accessiblestatesethelper.hxx>
#endif
#ifndef _RTL_UUID_H_
#include <rtl/uuid.h>
#endif
#ifndef _SV_SVAPP_HXX //autogen
#include <vcl/svapp.hxx>
#endif
#ifndef _FTNFRM_HXX
#include <ftnfrm.hxx>
#endif
#ifndef _FMTFTN_HXX //autogen
#include <fmtftn.hxx>
#endif
#ifndef _TXTFTN_HXX //autogen
#include <txtftn.hxx>
#endif
#ifndef _VIEWSH_HXX
#include <viewsh.hxx>
#endif

#ifndef _ACCMAP_HXX
#include <accmap.hxx>
#endif
#ifndef _ACCFOOTNOTE_HXX
#include "accfootnote.hxx"
#endif
#ifndef _ACCESS_HRC
#include "access.hrc"
#endif

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::accessibility;
using ::rtl::OUString;

const sal_Char sServiceNameFootnote[] = "com.sun.star.text.AccessibleFootnoteView";
const sal_Char sServiceNameEndnote[] = "com.sun.star.text.AccessibleEndnoteView";
const sal_Char sImplementationNameFootnote[] = "com.sun.star.comp.Writer.SwAccessibleFootnoteView";
const sal_Char sImplementationNameEndnote[] = "com.sun.star.comp.Writer.SwAccessibleEndnoteView";

SwAccessibleFootnote::SwAccessibleFootnote(
        SwAccessibleMap* pInitMap,
        sal_Bool bIsEndnote,
        sal_Int32 nFootEndNote,
        const SwFtnFrm *pFtnFrm ) :
    SwAccessibleContext( pInitMap,
        bIsEndnote ? AccessibleRole::END_NOTE : AccessibleRole::FOOTNOTE,
        pFtnFrm )
{
    vos::OGuard aGuard(Application::GetSolarMutex());

    sal_uInt16 nResId = bIsEndnote ? STR_ACCESS_ENDNOTE_NAME
                                   : STR_ACCESS_FOOTNOTE_NAME;
    OUString sArg( OUString::valueOf( nFootEndNote ) );
    SetName( GetResource( nResId, &sArg ) );
}

SwAccessibleFootnote::~SwAccessibleFootnote()
{
}

OUString SAL_CALL SwAccessibleFootnote::getAccessibleDescription (void)
        throw (uno::RuntimeException)
{
    vos::OGuard aGuard(Application::GetSolarMutex());

    CHECK_FOR_DEFUNC( XAccessibleContext )

    sal_uInt16 nResId = AccessibleRole::END_NOTE == GetRole()
        ? STR_ACCESS_ENDNOTE_DESC
        : STR_ACCESS_FOOTNOTE_DESC ;

    OUString sArg;
    const SwTxtFtn *pTxtFtn =
        static_cast< const SwFtnFrm *>( GetFrm() )->GetAttr();
    if( pTxtFtn )
    {
        const SwDoc *pDoc = GetMap()->GetShell()->GetDoc();
        sArg = pTxtFtn->GetFtn().GetViewNumStr( *pDoc );
    }

    return GetResource( nResId, &sArg );
}

OUString SAL_CALL SwAccessibleFootnote::getImplementationName()
        throw( RuntimeException )
{
    if( AccessibleRole::END_NOTE == GetRole() )
        return OUString(RTL_CONSTASCII_USTRINGPARAM(sImplementationNameEndnote));
    else
        return OUString(RTL_CONSTASCII_USTRINGPARAM(sImplementationNameFootnote));
}

sal_Bool SAL_CALL SwAccessibleFootnote::supportsService(
        const ::rtl::OUString& sTestServiceName)
    throw (uno::RuntimeException)
{
    if( sTestServiceName.equalsAsciiL( sAccessibleServiceName,
                                       sizeof(sAccessibleServiceName)-1 ) )
        return sal_True;
    else if( AccessibleRole::END_NOTE == GetRole() )
        return sTestServiceName.equalsAsciiL( sServiceNameEndnote, sizeof(sServiceNameEndnote)-1 );
    else
        return sTestServiceName.equalsAsciiL( sServiceNameFootnote, sizeof(sServiceNameFootnote)-1 );

}

Sequence< OUString > SAL_CALL SwAccessibleFootnote::getSupportedServiceNames()
        throw( uno::RuntimeException )
{
    Sequence< OUString > aRet(2);
    OUString* pArray = aRet.getArray();
    if( AccessibleRole::END_NOTE == GetRole() )
        pArray[0] = OUString( RTL_CONSTASCII_USTRINGPARAM(sServiceNameEndnote) );
    else
        pArray[0] = OUString( RTL_CONSTASCII_USTRINGPARAM(sServiceNameFootnote) );
    pArray[1] = OUString( RTL_CONSTASCII_USTRINGPARAM(sAccessibleServiceName) );
    return aRet;
}

Sequence< sal_Int8 > SAL_CALL SwAccessibleFootnote::getImplementationId()
        throw(RuntimeException)
{
    vos::OGuard aGuard(Application::GetSolarMutex());
    static Sequence< sal_Int8 > aId( 16 );
    static sal_Bool bInit = sal_False;
    if(!bInit)
    {
        rtl_createUuid( (sal_uInt8 *)(aId.getArray() ), 0, sal_True );
        bInit = sal_True;
    }
    return aId;
}

sal_Bool SwAccessibleFootnote::IsEndnote( const SwFtnFrm *pFtnFrm )
{
    const SwTxtFtn *pTxtFtn = pFtnFrm ->GetAttr();
    return pTxtFtn && pTxtFtn->GetFtn().IsEndNote() ;
}
<commit_msg>INTEGRATION: CWS changefileheader (1.15.34); FILE MERGED 2008/04/01 15:56:39 thb 1.15.34.3: #i85898# Stripping all external header guards 2008/04/01 12:53:44 thb 1.15.34.2: #i85898# Stripping all external header guards 2008/03/31 16:53:37 rt 1.15.34.1: #i87441# Change license header to LPGL v3.<commit_after> /*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: accfootnote.cxx,v $
 * $Revision: 1.16 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sw.hxx"

#include <vos/mutex.hxx>
#include <com/sun/star/accessibility/AccessibleRole.hpp>
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
#include <unotools/accessiblestatesethelper.hxx>
#include <rtl/uuid.h>
#include <vcl/svapp.hxx>
#include <ftnfrm.hxx>
#include <fmtftn.hxx>
#include <txtftn.hxx>
#include <viewsh.hxx>
#include <accmap.hxx>
#include "accfootnote.hxx"
#ifndef _ACCESS_HRC
#include "access.hrc"
#endif

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::accessibility;
using ::rtl::OUString;

const sal_Char sServiceNameFootnote[] = "com.sun.star.text.AccessibleFootnoteView";
const sal_Char sServiceNameEndnote[] = "com.sun.star.text.AccessibleEndnoteView";
const sal_Char sImplementationNameFootnote[] = "com.sun.star.comp.Writer.SwAccessibleFootnoteView";
const sal_Char sImplementationNameEndnote[] = "com.sun.star.comp.Writer.SwAccessibleEndnoteView";

SwAccessibleFootnote::SwAccessibleFootnote(
        SwAccessibleMap* pInitMap,
        sal_Bool bIsEndnote,
        sal_Int32 nFootEndNote,
        const SwFtnFrm *pFtnFrm ) :
    SwAccessibleContext( pInitMap,
        bIsEndnote ? AccessibleRole::END_NOTE : AccessibleRole::FOOTNOTE,
        pFtnFrm )
{
    vos::OGuard aGuard(Application::GetSolarMutex());

    sal_uInt16 nResId = bIsEndnote ? STR_ACCESS_ENDNOTE_NAME
                                   : STR_ACCESS_FOOTNOTE_NAME;
    OUString sArg( OUString::valueOf( nFootEndNote ) );
    SetName( GetResource( nResId, &sArg ) );
}

SwAccessibleFootnote::~SwAccessibleFootnote()
{
}

OUString SAL_CALL SwAccessibleFootnote::getAccessibleDescription (void)
        throw (uno::RuntimeException)
{
    vos::OGuard aGuard(Application::GetSolarMutex());

    CHECK_FOR_DEFUNC( XAccessibleContext )

    sal_uInt16 nResId = AccessibleRole::END_NOTE == GetRole()
        ? STR_ACCESS_ENDNOTE_DESC
        : STR_ACCESS_FOOTNOTE_DESC ;

    OUString sArg;
    const SwTxtFtn *pTxtFtn =
        static_cast< const SwFtnFrm *>( GetFrm() )->GetAttr();
    if( pTxtFtn )
    {
        const SwDoc *pDoc = GetMap()->GetShell()->GetDoc();
        sArg = pTxtFtn->GetFtn().GetViewNumStr( *pDoc );
    }

    return GetResource( nResId, &sArg );
}

OUString SAL_CALL SwAccessibleFootnote::getImplementationName()
        throw( RuntimeException )
{
    if( AccessibleRole::END_NOTE == GetRole() )
        return OUString(RTL_CONSTASCII_USTRINGPARAM(sImplementationNameEndnote));
    else
        return OUString(RTL_CONSTASCII_USTRINGPARAM(sImplementationNameFootnote));
}

sal_Bool SAL_CALL SwAccessibleFootnote::supportsService(
        const ::rtl::OUString& sTestServiceName)
    throw (uno::RuntimeException)
{
    if( sTestServiceName.equalsAsciiL( sAccessibleServiceName,
                                       sizeof(sAccessibleServiceName)-1 ) )
        return sal_True;
    else if( AccessibleRole::END_NOTE == GetRole() )
        return sTestServiceName.equalsAsciiL( sServiceNameEndnote, sizeof(sServiceNameEndnote)-1 );
    else
        return sTestServiceName.equalsAsciiL( sServiceNameFootnote, sizeof(sServiceNameFootnote)-1 );

}

Sequence< OUString > SAL_CALL SwAccessibleFootnote::getSupportedServiceNames()
        throw( uno::RuntimeException )
{
    Sequence< OUString > aRet(2);
    OUString* pArray = aRet.getArray();
    if( AccessibleRole::END_NOTE == GetRole() )
        pArray[0] = OUString( RTL_CONSTASCII_USTRINGPARAM(sServiceNameEndnote) );
    else
        pArray[0] = OUString( RTL_CONSTASCII_USTRINGPARAM(sServiceNameFootnote) );
    pArray[1] = OUString( RTL_CONSTASCII_USTRINGPARAM(sAccessibleServiceName) );
    return aRet;
}

Sequence< sal_Int8 > SAL_CALL SwAccessibleFootnote::getImplementationId()
        throw(RuntimeException)
{
    vos::OGuard aGuard(Application::GetSolarMutex());
    static Sequence< sal_Int8 > aId( 16 );
    static sal_Bool bInit = sal_False;
    if(!bInit)
    {
        rtl_createUuid( (sal_uInt8 *)(aId.getArray() ), 0, sal_True );
        bInit = sal_True;
    }
    return aId;
}

sal_Bool SwAccessibleFootnote::IsEndnote( const SwFtnFrm *pFtnFrm )
{
    const SwTxtFtn *pTxtFtn = pFtnFrm ->GetAttr();
    return pTxtFtn && pTxtFtn->GetFtn().IsEndNote() ;
}
<|endoftext|>