diff options
author | Remko Tronçon <git@el-tramo.be> | 2010-05-06 18:00:41 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2010-05-06 18:00:41 (GMT) |
commit | 4c58e9a2d266c23a2060edd08081bf86ebd1862c (patch) | |
tree | 0030a4f3360c9da905165db1feed18997481fee5 /3rdParty/Boost/src/boost/uuid | |
parent | c2cf7f0e59c7880a9ce979d8a45d97442c705110 (diff) | |
download | swift-contrib-4c58e9a2d266c23a2060edd08081bf86ebd1862c.zip swift-contrib-4c58e9a2d266c23a2060edd08081bf86ebd1862c.tar.bz2 |
Use UUIDs as nonce when authenticating with SCRAM-SHA-1.
Diffstat (limited to '3rdParty/Boost/src/boost/uuid')
-rw-r--r-- | 3rdParty/Boost/src/boost/uuid/name_generator.hpp | 125 | ||||
-rw-r--r-- | 3rdParty/Boost/src/boost/uuid/nil_generator.hpp | 34 | ||||
-rw-r--r-- | 3rdParty/Boost/src/boost/uuid/random_generator.hpp | 118 | ||||
-rw-r--r-- | 3rdParty/Boost/src/boost/uuid/seed_rng.hpp | 262 | ||||
-rw-r--r-- | 3rdParty/Boost/src/boost/uuid/sha1.hpp | 208 | ||||
-rw-r--r-- | 3rdParty/Boost/src/boost/uuid/string_generator.hpp | 184 | ||||
-rw-r--r-- | 3rdParty/Boost/src/boost/uuid/uuid.hpp | 218 | ||||
-rw-r--r-- | 3rdParty/Boost/src/boost/uuid/uuid_generators.hpp | 19 |
8 files changed, 1168 insertions, 0 deletions
diff --git a/3rdParty/Boost/src/boost/uuid/name_generator.hpp b/3rdParty/Boost/src/boost/uuid/name_generator.hpp new file mode 100644 index 0000000..42473a6 --- /dev/null +++ b/3rdParty/Boost/src/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 <boost/uuid/uuid.hpp> +#include <boost/uuid/sha1.hpp> +#include <boost/assert.hpp> +#include <string> +#include <cstring> // 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 <typename ch, typename char_traits, typename alloc> + uuid operator()(std::basic_string<ch, char_traits, alloc> 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 <typename char_type> + 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<count; i++) { + uint32_t c = characters[i]; + sha.process_byte( (c >> 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/3rdParty/Boost/src/boost/uuid/nil_generator.hpp b/3rdParty/Boost/src/boost/uuid/nil_generator.hpp new file mode 100644 index 0000000..c3c5818 --- /dev/null +++ b/3rdParty/Boost/src/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 <boost/uuid/uuid.hpp> + +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/3rdParty/Boost/src/boost/uuid/random_generator.hpp b/3rdParty/Boost/src/boost/uuid/random_generator.hpp new file mode 100644 index 0000000..4d11f6b --- /dev/null +++ b/3rdParty/Boost/src/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 <boost/uuid/uuid.hpp> +#include <boost/uuid/seed_rng.hpp> +#include <boost/random/uniform_int.hpp> +#include <boost/random/variate_generator.hpp> +#include <boost/random/mersenne_twister.hpp> +#include <boost/assert.hpp> +#include <boost/shared_ptr.hpp> +#include <limits> + +namespace boost { +namespace uuids { + +// generate a random-based uuid +template <typename UniformRandomNumberGenerator> +class basic_random_generator { +private: + typedef uniform_int<unsigned long> distribution_type; + typedef variate_generator<UniformRandomNumberGenerator*, distribution_type> 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<unsigned long>::min)() + , (std::numeric_limits<unsigned long>::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<unsigned long>::min)() + , (std::numeric_limits<unsigned long>::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<unsigned long>::min)() + , (std::numeric_limits<unsigned long>::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<UniformRandomNumberGenerator> pURNG; + generator_type generator; +}; + +typedef basic_random_generator<mt19937> random_generator; + +}} // namespace boost::uuids + +#endif //BOOST_UUID_RANDOM_GENERATOR_HPP diff --git a/3rdParty/Boost/src/boost/uuid/seed_rng.hpp b/3rdParty/Boost/src/boost/uuid/seed_rng.hpp new file mode 100644 index 0000000..3090197 --- /dev/null +++ b/3rdParty/Boost/src/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 <boost/config.hpp> +#include <cstring> // for memcpy +#include <limits> +#include <memory.h> +#include <ctime> // for time_t, time, clock_t, clock +#include <cstdlib> // for rand +#include <cstdio> // for FILE, fopen, fread, fclose +#include <boost/uuid/sha1.hpp> +//#include <boost/nondet_random.hpp> //forward declare boost::random_device + +// can't use boost::generator_iterator since boost::random number seed(Iter&, Iter) +// functions need a last iterator +//#include <boost/generator_iterator.hpp> +# include <boost/iterator/iterator_facade.hpp> + +#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<result_type>::min)(); + } + result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const + { + return (std::numeric_limits<result_type>::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> +class generator_iterator + : public iterator_facade< + generator_iterator<Generator> + , typename Generator::result_type + , single_pass_traversal_tag + , typename Generator::result_type const& + > +{ + typedef iterator_facade< + generator_iterator<Generator> + , 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 <typename UniformRandomNumberGenerator> +inline void seed(UniformRandomNumberGenerator& rng) +{ + seed_rng seed_gen; + generator_iterator<seed_rng> begin(&seed_gen); + generator_iterator<seed_rng> end; + rng.seed(begin, end); +} + +// random_device does not / can not be seeded +template <> +inline void seed<boost::random_device>(boost::random_device&) {} + +// random_device does not / can not be seeded +template <> +inline void seed<seed_rng>(seed_rng&) {} + +}}} //namespace boost::uuids::detail + +#if defined(_MSC_VER) +#pragma warning(pop) // Restore warnings to previous state. +#endif + +#endif diff --git a/3rdParty/Boost/src/boost/uuid/sha1.hpp b/3rdParty/Boost/src/boost/uuid/sha1.hpp new file mode 100644 index 0000000..b4a1344 --- /dev/null +++ b/3rdParty/Boost/src/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 <boost/static_assert.hpp> +#include <cstddef> + +#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<<n) ^ (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<unsigned char const*>(bytes_begin); + unsigned char const* end = static_cast<unsigned char const*>(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<unsigned char const*>(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<unsigned char>((bit_count>>24) & 0xFF)); + process_byte( static_cast<unsigned char>((bit_count>>16) & 0xFF)); + process_byte( static_cast<unsigned char>((bit_count>>8 ) & 0xFF)); + process_byte( static_cast<unsigned char>((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/3rdParty/Boost/src/boost/uuid/string_generator.hpp b/3rdParty/Boost/src/boost/uuid/string_generator.hpp new file mode 100644 index 0000000..7d2733b --- /dev/null +++ b/3rdParty/Boost/src/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 <boost/uuid/uuid.hpp> +#include <string> +#include <cstring> // for strlen, wcslen +#include <iterator> +#include <algorithm> // for find +#include <stdexcept> + +#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 <typename ch, typename char_traits, typename alloc> + uuid operator()(std::basic_string<ch, char_traits, alloc> 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 <typename CharIterator> + uuid operator()(CharIterator begin, CharIterator end) const + { + typedef typename std::iterator_traits<CharIterator>::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 CharIterator> + typename std::iterator_traits<CharIterator>::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<unsigned char>(-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<unsigned char>(-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/3rdParty/Boost/src/boost/uuid/uuid.hpp b/3rdParty/Boost/src/boost/uuid/uuid.hpp new file mode 100644 index 0000000..ceebd4d --- /dev/null +++ b/3rdParty/Boost/src/boost/uuid/uuid.hpp @@ -0,0 +1,218 @@ +// 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 <boost/config.hpp> +#include <stddef.h> +#include <boost/cstdint.hpp> +#include <algorithm> +#include <boost/config.hpp> // for static assert +#include <boost/mpl/bool.hpp> +#include <boost/type_traits/is_pod.hpp> + +#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<static_size(); i++) { + if (data[i] != 0U) { + return false; + } + } + return true; + } + + enum variant_type + { + variant_ncs, // NCS backward compatibility + variant_rfc_4122, // defined in RFC 4122 document + variant_microsoft, // Microsoft Corporation backward compatibility + variant_future // future definition + }; + variant_type variant() const /* throw() */ + { + // variant is stored in octet 7 + // which is index 8, since indexes count backwards + unsigned char octet7 = data[8]; // octet 7 is array index 8 + if ( (octet7 & 0x80) == 0x00 ) { // 0b0xxxxxxx + return variant_ncs; + } else if ( (octet7 & 0xC0) == 0x80 ) { // 0b10xxxxxx + return variant_rfc_4122; + } else if ( (octet7 & 0xE0) == 0xC0 ) { // 0b110xxxxx + return variant_microsoft; + } else { + //assert( (octet7 & 0xE0) == 0xE0 ) // 0b111xxxx + return variant_future; + } + } + + enum version_type + { + version_unknown = -1, + version_time_based = 1, + version_dce_security = 2, + version_name_based_md5 = 3, + version_random_number_based = 4, + version_name_based_sha1 = 5 + }; + version_type version() const /* throw() */ + { + //version is stored in octet 9 + // which is index 6, since indexes count backwards + unsigned char octet9 = data[6]; + if ( (octet9 & 0xF0) == 0x10 ) { + return version_time_based; + } else if ( (octet9 & 0xF0) == 0x20 ) { + return version_dce_security; + } else if ( (octet9 & 0xF0) == 0x30 ) { + return version_name_based_md5; + } else if ( (octet9 & 0xF0) == 0x40 ) { + return version_random_number_based; + } else if ( (octet9 & 0xF0) == 0x50 ) { + return version_name_based_sha1; + } else { + return version_unknown; + } + } + + // note: linear complexity + void swap(uuid& rhs) /* throw() */ + { + std::swap_ranges(begin(), end(), rhs.begin()); + } + +public: + // or should it be array<uint8_t, 16> + 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<std::size_t>(*i) + 0x9e3779b9 + (seed << 6) + (seed >> 2); + } + + return seed; +} + +}} //namespace boost::uuids + +// type traits specializations +namespace boost { + +template <> +struct is_pod<uuids::uuid> : mpl::true_ +{}; + +} // namespace boost + +#if defined(_MSC_VER) +#pragma warning(pop) // Restore warnings to previous state. +#endif + +#endif // BOOST_UUID_HPP diff --git a/3rdParty/Boost/src/boost/uuid/uuid_generators.hpp b/3rdParty/Boost/src/boost/uuid/uuid_generators.hpp new file mode 100644 index 0000000..29d39cc --- /dev/null +++ b/3rdParty/Boost/src/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 <boost/uuid/nil_generator.hpp> +#include <boost/uuid/string_generator.hpp> +#include <boost/uuid/name_generator.hpp> +#include <boost/uuid/random_generator.hpp> + +#endif //BOOST_UUID_GENERATORS_HPP |