From 38ebdde6ede21622ce896babfb455eae39f2b908 Mon Sep 17 00:00:00 2001 From: "Xawotihs@gmail.com" Date: Sun, 6 Jan 2013 17:53:29 +0000 Subject: [PATCH] Adding boost uuid support --- Boost/boost/uuid/name_generator.hpp | 125 ++++++++++++ Boost/boost/uuid/nil_generator.hpp | 34 ++++ Boost/boost/uuid/random_generator.hpp | 118 ++++++++++++ Boost/boost/uuid/seed_rng.hpp | 262 ++++++++++++++++++++++++++ Boost/boost/uuid/sha1.hpp | 208 ++++++++++++++++++++ Boost/boost/uuid/string_generator.hpp | 184 ++++++++++++++++++ Boost/boost/uuid/uuid.hpp | 221 ++++++++++++++++++++++ Boost/boost/uuid/uuid_generators.hpp | 19 ++ Boost/boost/uuid/uuid_io.hpp | 198 +++++++++++++++++++ Boost/boost/uuid/uuid_serialize.hpp | 20 ++ 10 files changed, 1389 insertions(+) create mode 100644 Boost/boost/uuid/name_generator.hpp create mode 100644 Boost/boost/uuid/nil_generator.hpp create mode 100644 Boost/boost/uuid/random_generator.hpp create mode 100644 Boost/boost/uuid/seed_rng.hpp create mode 100644 Boost/boost/uuid/sha1.hpp create mode 100644 Boost/boost/uuid/string_generator.hpp create mode 100644 Boost/boost/uuid/uuid.hpp create mode 100644 Boost/boost/uuid/uuid_generators.hpp create mode 100644 Boost/boost/uuid/uuid_io.hpp create mode 100644 Boost/boost/uuid/uuid_serialize.hpp diff --git a/Boost/boost/uuid/name_generator.hpp b/Boost/boost/uuid/name_generator.hpp new file mode 100644 index 000000000..2b5d62e23 --- /dev/null +++ b/Boost/boost/uuid/name_generator.hpp @@ -0,0 +1,125 @@ +// Boost name_generator.hpp header file ----------------------------------------------// + +// Copyright 2010 Andy Tompkins. +// 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) + +#ifndef BOOST_UUID_NAME_GENERATOR_HPP +#define BOOST_UUID_NAME_GENERATOR_HPP + +#include +#include +#include +#include +#include // for strlen, wcslen + +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std { + using ::strlen; + using ::wcslen; +} //namespace std +#endif //BOOST_NO_STDC_NAMESPACE + +namespace boost { +namespace uuids { + +// generate a name-based uuid +// TODO: add in common namesspace uuids +class name_generator { +public: + typedef uuid result_type; + + explicit name_generator(uuid const& namespace_uuid) + : namespace_uuid(namespace_uuid) + {} + + uuid operator()(const char* name) { + reset(); + process_characters(name, std::strlen(name)); + return sha_to_uuid(); + } + + uuid operator()(const wchar_t* name) { + reset(); + process_characters(name, std::wcslen(name)); + return sha_to_uuid(); + } + + template + uuid operator()(std::basic_string const& name) { + reset(); + process_characters(name.c_str(), name.length()); + return sha_to_uuid(); + } + + uuid operator()(void const* buffer, std::size_t byte_count) { + reset(); + sha.process_bytes(buffer, byte_count); + return sha_to_uuid(); + }; + +private: + // we convert all characters to uint32_t so that each + // character is 4 bytes reguardless of sizeof(char) or + // sizeof(wchar_t). We want the name string on any + // platform / compiler to generate the same uuid + // except for char + template + void process_characters(char_type const*const characters, size_t count) { + BOOST_ASSERT(sizeof(uint32_t) >= sizeof(char_type)); + + for (size_t i=0; i> 0) && 0xFF ); + sha.process_byte( (c >> 8) && 0xFF ); + sha.process_byte( (c >> 16) && 0xFF ); + sha.process_byte( (c >> 24) && 0xFF ); + } + } + + void process_characters(char const*const characters, size_t count) { + sha.process_bytes(characters, count); + } + + void reset() + { + sha.reset(); + sha.process_bytes(namespace_uuid.begin(), namespace_uuid.size()); + } + + uuid sha_to_uuid() + { + unsigned int digest[5]; + + sha.get_digest(digest); + + uuid u; + for (int i=0; i<4; ++i) { + *(u.begin() + i*4+0) = ((digest[i] >> 24) & 0xFF); + *(u.begin() + i*4+1) = ((digest[i] >> 16) & 0xFF); + *(u.begin() + i*4+2) = ((digest[i] >> 8) & 0xFF); + *(u.begin() + i*4+3) = ((digest[i] >> 0) & 0xFF); + } + + // set variant + // must be 0b10xxxxxx + *(u.begin()+8) &= 0xBF; + *(u.begin()+8) |= 0x80; + + // set version + // must be 0b0101xxxx + *(u.begin()+6) &= 0x5F; //0b01011111 + *(u.begin()+6) |= 0x50; //0b01010000 + + return u; + } + +private: + uuid namespace_uuid; + detail::sha1 sha; +}; + +}} // namespace boost::uuids + +#endif // BOOST_UUID_NAME_GENERATOR_HPP diff --git a/Boost/boost/uuid/nil_generator.hpp b/Boost/boost/uuid/nil_generator.hpp new file mode 100644 index 000000000..7b7393f43 --- /dev/null +++ b/Boost/boost/uuid/nil_generator.hpp @@ -0,0 +1,34 @@ +// Boost nil_generator.hpp header file ----------------------------------------------// + +// Copyright 2010 Andy Tompkins. +// 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) + +#ifndef BOOST_UUID_NIL_GENERATOR_HPP +#define BOOST_UUID_NIL_GENERATOR_HPP + +#include + +namespace boost { +namespace uuids { + +// generate a nil uuid +struct nil_generator { + typedef uuid result_type; + + uuid operator()() const { + // initialize to all zeros + uuid u = {{0}}; + return u; + } +}; + +inline uuid nil_uuid() { + return nil_generator()(); +} + +}} // namespace boost::uuids + +#endif // BOOST_UUID_NIL_GENERATOR_HPP + diff --git a/Boost/boost/uuid/random_generator.hpp b/Boost/boost/uuid/random_generator.hpp new file mode 100644 index 000000000..1ba0ffba9 --- /dev/null +++ b/Boost/boost/uuid/random_generator.hpp @@ -0,0 +1,118 @@ +// Boost random_generator.hpp header file ----------------------------------------------// + +// Copyright 2010 Andy Tompkins. +// 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) + +#ifndef BOOST_UUID_RANDOM_GENERATOR_HPP +#define BOOST_UUID_RANDOM_GENERATOR_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace uuids { + +// generate a random-based uuid +template +class basic_random_generator { +private: + typedef uniform_int distribution_type; + typedef variate_generator generator_type; + + struct null_deleter + { + void operator()(void const *) const {} + }; + +public: + typedef uuid result_type; + + // default constructor creates the random number generator + basic_random_generator() + : pURNG(new UniformRandomNumberGenerator) + , generator + ( pURNG.get() + , distribution_type + ( (std::numeric_limits::min)() + , (std::numeric_limits::max)() + ) + ) + { + // seed the random number generator + detail::seed(*pURNG); + } + + // keep a reference to a random number generator + // don't seed a given random number generator + explicit basic_random_generator(UniformRandomNumberGenerator& gen) + : pURNG(&gen, null_deleter()) + , generator + ( pURNG.get() + , distribution_type + ( (std::numeric_limits::min)() + , (std::numeric_limits::max)() + ) + ) + {} + + // keep a pointer to a random number generator + // don't seed a given random number generator + explicit basic_random_generator(UniformRandomNumberGenerator* pGen) + : pURNG(pGen, null_deleter()) + , generator + ( pURNG.get() + , distribution_type + ( (std::numeric_limits::min)() + , (std::numeric_limits::max)() + ) + ) + { + BOOST_ASSERT(pURNG); + } + + uuid operator()() + { + uuid u; + + int i=0; + unsigned long random_value = generator(); + for (uuid::iterator it=u.begin(); it!=u.end(); ++it, ++i) { + if (i==sizeof(unsigned long)) { + random_value = generator(); + i = 0; + } + + *it = ((random_value >> (i*8)) & 0xFF); + } + + // set variant + // must be 0b10xxxxxx + *(u.begin()+8) &= 0xBF; + *(u.begin()+8) |= 0x80; + + // set version + // must be 0b0100xxxx + *(u.begin()+6) &= 0x4F; //0b01001111 + *(u.begin()+6) |= 0x40; //0b01000000 + + return u; + } + +private: + shared_ptr pURNG; + generator_type generator; +}; + +typedef basic_random_generator random_generator; + +}} // namespace boost::uuids + +#endif //BOOST_UUID_RANDOM_GENERATOR_HPP diff --git a/Boost/boost/uuid/seed_rng.hpp b/Boost/boost/uuid/seed_rng.hpp new file mode 100644 index 000000000..49afd51c4 --- /dev/null +++ b/Boost/boost/uuid/seed_rng.hpp @@ -0,0 +1,262 @@ +// Boost seed_rng.hpp header file ----------------------------------------------// + +// Copyright 2007 Andy Tompkins. +// 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) + +// Revision History +// 09 Nov 2007 - Initial Revision +// 25 Feb 2008 - moved to namespace boost::uuids::detail +// 28 Nov 2009 - disabled deprecated warnings for MSVC + +// seed_rng models a UniformRandomNumberGenerator (see Boost.Random). +// Random number generators are hard to seed well. This is intended to provide +// good seed values for random number generators. +// It creates random numbers from a sha1 hash of data from a variary of sources, +// all of which are standard function calls. It produces random numbers slowly. +// Peter Dimov provided the details of sha1_random_digest_(). +// see http://archives.free.net.ph/message/20070507.175609.4c4f503a.en.html + +#ifndef BOOST_UUID_SEED_RNG_HPP +#define BOOST_UUID_SEED_RNG_HPP + +#include +#include // for memcpy +#include +#include +#include // for time_t, time, clock_t, clock +#include // for rand +#include // for FILE, fopen, fread, fclose +#include +//#include //forward declare boost::random_device + +// can't use boost::generator_iterator since boost::random number seed(Iter&, Iter) +// functions need a last iterator +//#include +# include + +#if defined(_MSC_VER) +#pragma warning(push) // Save warning settings. +#pragma warning(disable : 4996) // Disable deprecated std::fopen +#endif + +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std { + using ::memcpy; + using ::time_t; + using ::time; + using ::clock_t; + using ::clock; + using ::rand; + using ::FILE; + using ::fopen; + using ::fread; + using ::fclose; +} //namespace std +#endif + +// forward declare random number generators +namespace boost { +class random_device; +} //namespace boost + +namespace boost { +namespace uuids { +namespace detail { + +// should this be part of Boost.Random? +class seed_rng +{ +public: + typedef unsigned int result_type; + BOOST_STATIC_CONSTANT(bool, has_fixed_range = false); + //BOOST_STATIC_CONSTANT(unsigned int, min_value = 0); + //BOOST_STATIC_CONSTANT(unsigned int, max_value = UINT_MAX); + +public: + // note: rd_ intentionally left uninitialized + seed_rng() + : rd_index_(5) + , random_(std::fopen( "/dev/urandom", "rb" )) + {} + + ~seed_rng() + { + if (random_) { + std::fclose(random_); + } + } + + result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const + { + return (std::numeric_limits::min)(); + } + result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const + { + return (std::numeric_limits::max)(); + } + + result_type operator()() + { + if (rd_index_ >= 5) { + //get new digest + sha1_random_digest_(); + + rd_index_ = 0; + } + + return rd_[rd_index_++]; + } + +private: + static unsigned int * sha1_random_digest_state_() + { + // intentionally left uninitialized + static unsigned int state[ 5 ]; + return state; + } + + void sha1_random_digest_() + { + boost::uuids::detail::sha1 sha; + + unsigned int * ps = sha1_random_digest_state_(); + + unsigned int state[ 5 ]; + std::memcpy( state, ps, sizeof( state ) ); // harmless data race + + sha.process_bytes( (unsigned char const*)state, sizeof( state ) ); + sha.process_bytes( (unsigned char const*)&ps, sizeof( ps ) ); + + { + std::time_t tm = std::time( 0 ); + sha.process_bytes( (unsigned char const*)&tm, sizeof( tm ) ); + } + + { + std::clock_t ck = std::clock(); + sha.process_bytes( (unsigned char const*)&ck, sizeof( ck ) ); + } + + { + unsigned int rn[] = { std::rand(), std::rand(), std::rand() }; + sha.process_bytes( (unsigned char const*)rn, sizeof( rn ) ); + } + + { + // intentionally left uninitialized + unsigned char buffer[ 20 ]; + + if(random_) + { + std::fread( buffer, 1, 20, random_ ); + } + + // using an uninitialized buffer[] if fopen fails + // intentional, we rely on its contents being random + sha.process_bytes( buffer, sizeof( buffer ) ); + } + + { + // *p is intentionally left uninitialized + unsigned int * p = new unsigned int; + + sha.process_bytes( (unsigned char const*)p, sizeof( *p ) ); + sha.process_bytes( (unsigned char const*)&p, sizeof( p ) ); + + delete p; + } + + sha.process_bytes( (unsigned char const*)rd_, sizeof( rd_ ) ); + + unsigned int digest[ 5 ]; + sha.get_digest( digest ); + + for( int i = 0; i < 5; ++i ) + { + // harmless data race + ps[ i ] ^= digest[ i ]; + rd_[ i ] ^= digest[ i ]; + } + } + +private: + unsigned int rd_[5]; + int rd_index_; + std::FILE * random_; + +private: // make seed_rng noncopyable + seed_rng(seed_rng const&); + seed_rng& operator=(seed_rng const&); +}; + +// almost a copy of boost::generator_iterator +// but default constructor sets m_g to NULL +template +class generator_iterator + : public iterator_facade< + generator_iterator + , typename Generator::result_type + , single_pass_traversal_tag + , typename Generator::result_type const& + > +{ + typedef iterator_facade< + generator_iterator + , typename Generator::result_type + , single_pass_traversal_tag + , typename Generator::result_type const& + > super_t; + + public: + generator_iterator() : m_g(NULL) {} + generator_iterator(Generator* g) : m_g(g), m_value((*m_g)()) {} + + void increment() + { + m_value = (*m_g)(); + } + + const typename Generator::result_type& + dereference() const + { + return m_value; + } + + bool equal(generator_iterator const& y) const + { + return this->m_g == y.m_g && this->m_value == y.m_value; + } + + private: + Generator* m_g; + typename Generator::result_type m_value; +}; + +// seed() seeds a random number generator with good seed values + +template +inline void seed(UniformRandomNumberGenerator& rng) +{ + seed_rng seed_gen; + generator_iterator begin(&seed_gen); + generator_iterator end; + rng.seed(begin, end); +} + +// random_device does not / can not be seeded +template <> +inline void seed(boost::random_device&) {} + +// random_device does not / can not be seeded +template <> +inline void seed(seed_rng&) {} + +}}} //namespace boost::uuids::detail + +#if defined(_MSC_VER) +#pragma warning(pop) // Restore warnings to previous state. +#endif + +#endif diff --git a/Boost/boost/uuid/sha1.hpp b/Boost/boost/uuid/sha1.hpp new file mode 100644 index 000000000..1ce5e58c8 --- /dev/null +++ b/Boost/boost/uuid/sha1.hpp @@ -0,0 +1,208 @@ +// boost/uuid/sha1.hpp header file ----------------------------------------------// + +// Copyright 2007 Andy Tompkins. +// 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) + +// Revision History +// 29 May 2007 - Initial Revision +// 25 Feb 2008 - moved to namespace boost::uuids::detail + +// This is a byte oriented implementation +// Note: this implementation does not handle message longer than +// 2^32 bytes. + +#ifndef BOOST_UUID_SHA1_H +#define BOOST_UUID_SHA1_H + +#include +#include + +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std { + using ::size_t; +} // namespace std +#endif + +namespace boost { +namespace uuids { +namespace detail { + +BOOST_STATIC_ASSERT(sizeof(unsigned char)*8 == 8); +BOOST_STATIC_ASSERT(sizeof(unsigned int)*8 == 32); + +inline unsigned int left_rotate(unsigned int x, std::size_t n) +{ + return (x<> (32-n)); +} + +class sha1 +{ +public: + typedef unsigned int(&digest_type)[5]; +public: + sha1(); + + void reset(); + + void process_byte(unsigned char byte); + void process_block(void const* bytes_begin, void const* bytes_end); + void process_bytes(void const* buffer, std::size_t byte_count); + + void get_digest(digest_type digest); + +private: + void process_block(); + +private: + unsigned int h_[5]; + + unsigned char block_[64]; + + std::size_t block_byte_index_; + std::size_t byte_count_; +}; + +inline sha1::sha1() +{ + reset(); +} + +inline void sha1::reset() +{ + h_[0] = 0x67452301; + h_[1] = 0xEFCDAB89; + h_[2] = 0x98BADCFE; + h_[3] = 0x10325476; + h_[4] = 0xC3D2E1F0; + + block_byte_index_ = 0; + byte_count_ = 0; +} + +inline void sha1::process_byte(unsigned char byte) +{ + block_[block_byte_index_++] = byte; + ++byte_count_; + if (block_byte_index_ == 64) { + block_byte_index_ = 0; + process_block(); + } +} + +inline void sha1::process_block(void const* bytes_begin, void const* bytes_end) +{ + unsigned char const* begin = static_cast(bytes_begin); + unsigned char const* end = static_cast(bytes_end); + for(; begin != end; ++begin) { + process_byte(*begin); + } +} + +inline void sha1::process_bytes(void const* buffer, std::size_t byte_count) +{ + unsigned char const* b = static_cast(buffer); + process_block(b, b+byte_count); +} + +inline void sha1::process_block() +{ + unsigned int w[80]; + for (std::size_t i=0; i<16; ++i) { + w[i] = (block_[i*4 + 0] << 24); + w[i] |= (block_[i*4 + 1] << 16); + w[i] |= (block_[i*4 + 2] << 8); + w[i] |= (block_[i*4 + 3]); + } + for (std::size_t i=16; i<80; ++i) { + w[i] = left_rotate((w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]), 1); + } + + unsigned int a = h_[0]; + unsigned int b = h_[1]; + unsigned int c = h_[2]; + unsigned int d = h_[3]; + unsigned int e = h_[4]; + + for (std::size_t i=0; i<80; ++i) { + unsigned int f; + unsigned int k; + + if (i<20) { + f = (b & c) | (~b & d); + k = 0x5A827999; + } else if (i<40) { + f = b ^ c ^ d; + k = 0x6ED9EBA1; + } else if (i<60) { + f = (b & c) | (b & d) | (c & d); + k = 0x8F1BBCDC; + } else { + f = b ^ c ^ d; + k = 0xCA62C1D6; + } + + unsigned temp = left_rotate(a, 5) + f + e + k + w[i]; + e = d; + d = c; + c = left_rotate(b, 30); + b = a; + a = temp; + } + + h_[0] += a; + h_[1] += b; + h_[2] += c; + h_[3] += d; + h_[4] += e; +} + +inline void sha1::get_digest(digest_type digest) +{ + std::size_t bit_count = byte_count_*8; + + // append the bit '1' to the message + process_byte(0x80); + + // append k bits '0', where k is the minimum number >= 0 + // such that the resulting message length is congruent to 56 (mod 64) + // check if there is enough space for padding and bit_count + if (block_byte_index_ > 56) { + // finish this block + while (block_byte_index_ != 0) { + process_byte(0); + } + + // one more block + while (block_byte_index_ < 56) { + process_byte(0); + } + } else { + while (block_byte_index_ < 56) { + process_byte(0); + } + } + + // append length of message (before pre-processing) + // as a 64-bit big-endian integer + process_byte(0); + process_byte(0); + process_byte(0); + process_byte(0); + process_byte( static_cast((bit_count>>24) & 0xFF)); + process_byte( static_cast((bit_count>>16) & 0xFF)); + process_byte( static_cast((bit_count>>8 ) & 0xFF)); + process_byte( static_cast((bit_count) & 0xFF)); + + // get final digest + digest[0] = h_[0]; + digest[1] = h_[1]; + digest[2] = h_[2]; + digest[3] = h_[3]; + digest[4] = h_[4]; +} + +}}} // namespace boost::uuids::detail + +#endif diff --git a/Boost/boost/uuid/string_generator.hpp b/Boost/boost/uuid/string_generator.hpp new file mode 100644 index 000000000..84afcff8b --- /dev/null +++ b/Boost/boost/uuid/string_generator.hpp @@ -0,0 +1,184 @@ +// Boost string_generator.hpp header file ----------------------------------------------// + +// Copyright 2010 Andy Tompkins. +// 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) + +#ifndef BOOST_UUID_STRING_GENERATOR_HPP +#define BOOST_UUID_STRING_GENERATOR_HPP + +#include +#include +#include // for strlen, wcslen +#include +#include // for find +#include + +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std { + using ::strlen; + using ::wcslen; +} //namespace std +#endif //BOOST_NO_STDC_NAMESPACE + +namespace boost { +namespace uuids { + +// generate a uuid from a string +// lexical_cast works fine using uuid_io.hpp +// but this generator should accept more forms +// and be more efficient +// would like to accept the following forms: +// 0123456789abcdef0123456789abcdef +// 01234567-89ab-cdef-0123456789abcdef +// {01234567-89ab-cdef-0123456789abcdef} +// {0123456789abcdef0123456789abcdef} +// others? +struct string_generator { + typedef uuid result_type; + + template + uuid operator()(std::basic_string const& s) const { + return operator()(s.begin(), s.end()); + }; + + uuid operator()(char const*const s) const { + return operator()(s, s+std::strlen(s)); + } + + uuid operator()(wchar_t const*const s) const { + return operator()(s, s+std::wcslen(s)); + } + + template + uuid operator()(CharIterator begin, CharIterator end) const + { + typedef typename std::iterator_traits::value_type char_type; + + // check open brace + char_type c = get_next_char(begin, end); + bool has_open_brace = is_open_brace(c); + char_type open_brace_char = c; + if (has_open_brace) { + c = get_next_char(begin, end); + } + + bool has_dashes = false; + + uuid u; + int i=0; + for (uuid::iterator it_byte=u.begin(); it_byte!=u.end(); ++it_byte, ++i) { + if (it_byte != u.begin()) { + c = get_next_char(begin, end); + } + + if (i == 4) { + has_dashes = is_dash(c); + if (has_dashes) { + c = get_next_char(begin, end); + } + } + + if (has_dashes) { + if (i == 6 || i == 8 || i == 10) { + if (is_dash(c)) { + c = get_next_char(begin, end); + } else { + throw_invalid(); + } + } + } + + *it_byte = get_value(c); + + c = get_next_char(begin, end); + *it_byte <<= 4; + *it_byte |= get_value(c); + } + + // check close brace + if (has_open_brace) { + c = get_next_char(begin, end); + check_close_brace(c, open_brace_char); + } + + return u; + } + +private: + template + typename std::iterator_traits::value_type + get_next_char(CharIterator& begin, CharIterator end) const { + if (begin == end) { + throw_invalid(); + } + return *begin++; + } + + unsigned char get_value(char c) const { + static char const*const digits_begin = "0123456789abcdefABCDEF"; + static char const*const digits_end = digits_begin + 22; + + static unsigned char const values[] = + { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,10,11,12,13,14,15 + , static_cast(-1) }; + + char const* d = std::find(digits_begin, digits_end, c); + return values[d - digits_begin]; + } + + unsigned char get_value(wchar_t c) const { + static wchar_t const*const digits_begin = L"0123456789abcdefABCDEF"; + static wchar_t const*const digits_end = digits_begin + 22; + + static unsigned char const values[] = + { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,10,11,12,13,14,15 + , static_cast(-1) }; + + wchar_t const* d = std::find(digits_begin, digits_end, c); + return values[d - digits_begin]; + } + + bool is_dash(char c) const { + return c == '-'; + } + + bool is_dash(wchar_t c) const { + return c == L'-'; + } + + // return closing brace + bool is_open_brace(char c) const { + return (c == '{'); + } + + bool is_open_brace(wchar_t c) const { + return (c == L'{'); + } + + void check_close_brace(char c, char open_brace) const { + if (open_brace == '{' && c == '}') { + //great + } else { + throw_invalid(); + } + } + + void check_close_brace(wchar_t c, wchar_t open_brace) const { + if (open_brace == L'{' && c == L'}') { + // great + } else { + throw_invalid(); + } + } + + void throw_invalid() const { + throw std::runtime_error("invalid uuid string"); + } +}; + +}} // namespace boost::uuids + +#endif //BOOST_UUID_STRING_GENERATOR_HPP + diff --git a/Boost/boost/uuid/uuid.hpp b/Boost/boost/uuid/uuid.hpp new file mode 100644 index 000000000..5aa1708ba --- /dev/null +++ b/Boost/boost/uuid/uuid.hpp @@ -0,0 +1,221 @@ +// Boost uuid.hpp header file ----------------------------------------------// + +// Copyright 2006 Andy Tompkins. +// 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) + +// Revision History +// 06 Feb 2006 - Initial Revision +// 09 Nov 2006 - fixed variant and version bits for v4 guids +// 13 Nov 2006 - added serialization +// 17 Nov 2006 - added name-based guid creation +// 20 Nov 2006 - add fixes for gcc (from Tim Blechmann) +// 07 Mar 2007 - converted to header only +// 10 May 2007 - removed need for Boost.Thread +// - added better seed - thanks Peter Dimov +// - removed null() +// - replaced byte_count() and output_bytes() with size() and begin() and end() +// 11 May 2007 - fixed guid(ByteInputIterator first, ByteInputIterator last) +// - optimized operator>> +// 14 May 2007 - converted from guid to uuid +// 29 May 2007 - uses new implementation of sha1 +// 01 Jun 2007 - removed using namespace directives +// 09 Nov 2007 - moved implementation to uuid.ipp file +// 12 Nov 2007 - moved serialize code to uuid_serialize.hpp file +// 25 Feb 2008 - moved to namespace boost::uuids +// 19 Mar 2009 - changed to a POD, reorganized files +// 28 Nov 2009 - disabled deprecated warnings for MSVC +// 30 Nov 2009 - used BOOST_STATIC_CONSTANT +// 02 Dec 2009 - removed BOOST_STATIC_CONSTANT - not all compilers like it + +#ifndef BOOST_UUID_HPP +#define BOOST_UUID_HPP + +#include +#include +#include +#include +#include // for static assert +#ifndef BOOST_UUID_NO_TYPE_TRAITS +#include +#include +#endif + +#if defined(_MSC_VER) +#pragma warning(push) // Save warning settings. +#pragma warning(disable : 4996) // Disable deprecated std::swap_ranges, std::equal +#endif + +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std { + using ::size_t; + using ::ptrdiff_t; +} //namespace std +#endif //BOOST_NO_STDC_NAMESPACE + +namespace boost { +namespace uuids { + +struct uuid +{ +public: + typedef uint8_t value_type; + typedef uint8_t& reference; + typedef uint8_t const& const_reference; + typedef uint8_t* iterator; + typedef uint8_t const* const_iterator; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + // This does not work on some compilers + // They seem to want the variable definec in + // a cpp file + //BOOST_STATIC_CONSTANT(size_type, static_size = 16); + static size_type static_size() { return 16; } + +public: + iterator begin() { return data; } /* throw() */ + const_iterator begin() const { return data; } /* throw() */ + iterator end() { return data+size(); } /* throw() */ + const_iterator end() const { return data+size(); } /* throw() */ + + size_type size() const { return static_size(); } /* throw() */ + + bool is_nil() const /* throw() */ + { + for(size_t i=0; i + uint8_t data[16]; +}; + +inline bool operator==(uuid const& lhs, uuid const& rhs) /* throw() */ +{ + return std::equal(lhs.begin(), lhs.end(), rhs.begin()); +} + +inline bool operator!=(uuid const& lhs, uuid const& rhs) /* throw() */ +{ + return !(lhs == rhs); +} + +inline bool operator<(uuid const& lhs, uuid const& rhs) /* throw() */ +{ + return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); +} + +inline bool operator>(uuid const& lhs, uuid const& rhs) /* throw() */ +{ + return rhs < lhs; +} +inline bool operator<=(uuid const& lhs, uuid const& rhs) /* throw() */ +{ + return !(rhs < lhs); +} + +inline bool operator>=(uuid const& lhs, uuid const& rhs) /* throw() */ +{ + return !(lhs < rhs); +} + +inline void swap(uuid& lhs, uuid& rhs) /* throw() */ +{ + lhs.swap(rhs); +} + +// This is equivalent to boost::hash_range(u.begin(), u.end()); +inline std::size_t hash_value(uuid const& u) /* throw() */ +{ + std::size_t seed = 0; + for(uuid::const_iterator i=u.begin(); i != u.end(); ++i) + { + seed ^= static_cast(*i) + 0x9e3779b9 + (seed << 6) + (seed >> 2); + } + + return seed; +} + +}} //namespace boost::uuids + +#ifndef BOOST_UUID_NO_TYPE_TRAITS +// type traits specializations +namespace boost { + +template <> +struct is_pod : true_type {}; + +} // namespace boost +#endif + +#if defined(_MSC_VER) +#pragma warning(pop) // Restore warnings to previous state. +#endif + +#endif // BOOST_UUID_HPP diff --git a/Boost/boost/uuid/uuid_generators.hpp b/Boost/boost/uuid/uuid_generators.hpp new file mode 100644 index 000000000..d8e35a326 --- /dev/null +++ b/Boost/boost/uuid/uuid_generators.hpp @@ -0,0 +1,19 @@ +// Boost uuid_generators.hpp header file ----------------------------------------------// + +// Copyright 2006 Andy Tompkins. +// 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) + +// Revision History +// 06 Feb 2006 - Initial Revision + +#ifndef BOOST_UUID_GENERATORS_HPP +#define BOOST_UUID_GENERATORS_HPP + +#include +#include +#include +#include + +#endif //BOOST_UUID_GENERATORS_HPP diff --git a/Boost/boost/uuid/uuid_io.hpp b/Boost/boost/uuid/uuid_io.hpp new file mode 100644 index 000000000..eae7c73e9 --- /dev/null +++ b/Boost/boost/uuid/uuid_io.hpp @@ -0,0 +1,198 @@ +// Boost uuid_io.hpp header file ----------------------------------------------// + +// Copyright 2009 Andy Tompkins. +// 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) + +// Revision History +// 20 Mar 2009 - Initial Revision +// 28 Nov 2009 - disabled deprecated warnings for MSVC + +#ifndef BOOST_UUID_IO_HPP +#define BOOST_UUID_IO_HPP + +#include +#include +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +#pragma warning(push) // Save warning settings. +#pragma warning(disable : 4996) // Disable deprecated std::ctype::widen, std::copy +#endif + +namespace boost { +namespace uuids { + +template + std::basic_ostream& operator<<(std::basic_ostream &os, uuid const& u) +{ + io::ios_flags_saver flags_saver(os); + io::basic_ios_fill_saver fill_saver(os); + + const typename std::basic_ostream::sentry ok(os); + if (ok) { + const std::streamsize width = os.width(0); + const std::streamsize uuid_width = 36; + const std::ios_base::fmtflags flags = os.flags(); + const typename std::basic_ios::char_type fill = os.fill(); + if (flags & (std::ios_base::right | std::ios_base::internal)) { + for (std::streamsize i=uuid_width; i(*i_data); + if (i == 3 || i == 5 || i == 7 || i == 9) { + os << os.widen('-'); + } + } + + if (flags & std::ios_base::left) { + for (std::streamsize i=uuid_width; i + std::basic_istream& operator>>(std::basic_istream &is, uuid &u) +{ + const typename std::basic_istream::sentry ok(is); + if (ok) { + unsigned char data[16]; + + typedef std::ctype ctype_t; + ctype_t const& ctype = std::use_facet(is.getloc()); + + ch xdigits[16]; + { + char szdigits[] = "0123456789ABCDEF"; + ctype.widen(szdigits, szdigits+16, xdigits); + } + ch*const xdigits_end = xdigits+16; + + ch c; + for (std::size_t i=0; i> c; + c = ctype.toupper(c); + + ch* f = std::find(xdigits, xdigits_end, c); + if (f == xdigits_end) { + is.setstate(std::ios_base::failbit); + break; + } + + unsigned char byte = static_cast(std::distance(&xdigits[0], f)); + + is >> c; + c = ctype.toupper(c); + f = std::find(xdigits, xdigits_end, c); + if (f == xdigits_end) { + is.setstate(std::ios_base::failbit); + break; + } + + byte <<= 4; + byte |= static_cast(std::distance(&xdigits[0], f)); + + data[i] = byte; + + if (is) { + if (i == 3 || i == 5 || i == 7 || i == 9) { + is >> c; + if (c != is.widen('-')) is.setstate(std::ios_base::failbit); + } + } + } + + if (is) { + std::copy(data, data+16, u.begin()); + } + } + return is; +} + +namespace detail { +inline char to_char(size_t i) { + if (i <= 9) { + return static_cast('0' + i); + } else { + return static_cast('a' + (i-10)); + } +} + +inline wchar_t to_wchar(size_t i) { + if (i <= 9) { + return static_cast(L'0' + i); + } else { + return static_cast(L'a' + (i-10)); + } +} + +} // namespace detail + +inline std::string to_string(uuid const& u) +{ + std::string result; + result.reserve(36); + + std::size_t i=0; + for (uuid::const_iterator it_data = u.begin(); it_data!=u.end(); ++it_data, ++i) { + const size_t hi = ((*it_data) >> 4) & 0x0F; + result += detail::to_char(hi); + + const size_t lo = (*it_data) & 0x0F; + result += detail::to_char(lo); + + if (i == 3 || i == 5 || i == 7 || i == 9) { + result += '-'; + } + } + return result; +} + +#ifndef BOOST_NO_STD_WSTRING +inline std::wstring to_wstring(uuid const& u) +{ + std::wstring result; + result.reserve(36); + + std::size_t i=0; + for (uuid::const_iterator it_data = u.begin(); it_data!=u.end(); ++it_data, ++i) { + const size_t hi = ((*it_data) >> 4) & 0x0F; + result += detail::to_wchar(hi); + + const size_t lo = (*it_data) & 0x0F; + result += detail::to_wchar(lo); + + if (i == 3 || i == 5 || i == 7 || i == 9) { + result += L'-'; + } + } + return result; +} + +#endif + +}} //namespace boost::uuids + +#if defined(_MSC_VER) +#pragma warning(pop) // Restore warnings to previous state. +#endif + +#endif // BOOST_UUID_IO_HPP diff --git a/Boost/boost/uuid/uuid_serialize.hpp b/Boost/boost/uuid/uuid_serialize.hpp new file mode 100644 index 000000000..d4f29663d --- /dev/null +++ b/Boost/boost/uuid/uuid_serialize.hpp @@ -0,0 +1,20 @@ +// Boost uuid_serialize.hpp header file ----------------------------------------------// + +// Copyright 2007 Andy Tompkins. +// 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) + +// Revision History +// 12 Nov 2007 - Initial Revision +// 25 Feb 2008 - moved to namespace boost::uuids::detail + +#ifndef BOOST_UUID_SERIALIZE_HPP +#define BOOST_UUID_SERIALIZE_HPP + +#include +#include + +BOOST_CLASS_IMPLEMENTATION(boost::uuids::uuid, boost::serialization::primitive_type) + +#endif // BOOST_UUID_SERIALIZE_HPP