add boost on mac

This commit is contained in:
Bassem Girgis
2019-08-10 16:38:17 -05:00
parent 861b918727
commit be945cb63b
14105 changed files with 2714968 additions and 0 deletions

View File

@@ -0,0 +1,166 @@
// Boost basic_name_generator.hpp header file -----------------------//
// Copyright 2010 Andy Tompkins.
// Copyright 2017 James E. King III
// 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_BASIC_NAME_GENERATOR_HPP
#define BOOST_UUID_BASIC_NAME_GENERATOR_HPP
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/static_assert.hpp>
#include <boost/uuid/uuid.hpp>
#include <cstring> // for strlen, wcslen
#include <string>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#ifdef BOOST_NO_STDC_NAMESPACE
namespace std {
using ::size_t;
using ::strlen;
using ::wcslen;
} //namespace std
#endif //BOOST_NO_STDC_NAMESPACE
namespace boost {
namespace uuids {
//! \brief Generate a name based UUID using
//! the provided hashing algorithm that
//! implements the NameHashProvider concept.
template<class HashAlgo>
class basic_name_generator
{
public:
typedef uuid result_type;
typedef typename HashAlgo::digest_type digest_type;
explicit basic_name_generator(uuid const& namespace_uuid_)
: namespace_uuid(namespace_uuid_)
{}
uuid operator()(const char* name) const {
HashAlgo hash;
hash.process_bytes(namespace_uuid.begin(), namespace_uuid.size());
process_characters(hash, name, std::strlen(name));
return hash_to_uuid(hash);
}
uuid operator()(const wchar_t* name) const {
HashAlgo hash;
hash.process_bytes(namespace_uuid.begin(), namespace_uuid.size());
process_characters(hash, name, std::wcslen(name));
return hash_to_uuid(hash);
}
template <typename ch, typename char_traits, typename alloc>
uuid operator()(std::basic_string<ch, char_traits, alloc> const& name) const {
HashAlgo hash;
hash.process_bytes(namespace_uuid.begin(), namespace_uuid.size());
process_characters(hash, name.c_str(), name.length());
return hash_to_uuid(hash);
}
uuid operator()(void const* buffer, std::size_t byte_count) const {
HashAlgo hash;
hash.process_bytes(namespace_uuid.begin(), namespace_uuid.size());
hash.process_bytes(buffer, byte_count);
return hash_to_uuid(hash);
}
private:
// we convert all characters to uint32_t so that each
// character is 4 bytes regardless 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(HashAlgo& hash, char_type const*const characters, std::size_t count) const {
BOOST_STATIC_ASSERT(sizeof(uint32_t) >= sizeof(char_type));
for (std::size_t i=0; i<count; i++) {
std::size_t c = characters[i];
hash.process_byte(static_cast<unsigned char>((c >> 0) & 0xFF));
hash.process_byte(static_cast<unsigned char>((c >> 8) & 0xFF));
hash.process_byte(static_cast<unsigned char>((c >> 16) & 0xFF));
hash.process_byte(static_cast<unsigned char>((c >> 24) & 0xFF));
}
}
void process_characters(HashAlgo& hash, char const*const characters, std::size_t count) const {
hash.process_bytes(characters, count);
}
uuid hash_to_uuid(HashAlgo& hash) const
{
digest_type digest;
hash.get_digest(digest);
BOOST_STATIC_ASSERT(sizeof(digest_type) >= 16);
uuid u;
for (int i=0; i<4; ++i) {
*(u.begin() + i*4+0) = static_cast<uint8_t>((digest[i] >> 24) & 0xFF);
*(u.begin() + i*4+1) = static_cast<uint8_t>((digest[i] >> 16) & 0xFF);
*(u.begin() + i*4+2) = static_cast<uint8_t>((digest[i] >> 8) & 0xFF);
*(u.begin() + i*4+3) = static_cast<uint8_t>((digest[i] >> 0) & 0xFF);
}
// set variant: must be 0b10xxxxxx
*(u.begin()+8) &= 0xBF;
*(u.begin()+8) |= 0x80;
// set version
unsigned char hashver = hash.get_version();
*(u.begin()+6) &= 0x0F; // clear out the relevant bits
*(u.begin()+6) |= (hashver << 4); // and apply them
return u;
}
private:
uuid namespace_uuid;
};
namespace ns {
BOOST_FORCEINLINE uuid dns() {
uuid result = {{
0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1 ,
0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 }};
return result;
}
BOOST_FORCEINLINE uuid url() {
uuid result = {{
0x6b, 0xa7, 0xb8, 0x11, 0x9d, 0xad, 0x11, 0xd1 ,
0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 }};
return result;
}
BOOST_FORCEINLINE uuid oid() {
uuid result = {{
0x6b, 0xa7, 0xb8, 0x12, 0x9d, 0xad, 0x11, 0xd1 ,
0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 }};
return result;
}
BOOST_FORCEINLINE uuid x500dn() {
uuid result = {{
0x6b, 0xa7, 0xb8, 0x14, 0x9d, 0xad, 0x11, 0xd1 ,
0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 }};
return result;
}
} // ns
} // uuids
} // boost
#endif // BOOST_UUID_BASIC_NAME_GENERATOR_HPP

View File

@@ -0,0 +1,74 @@
/*
* Copyright Andrey Semashev 2013.
* 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)
*/
/*!
* \file uuid/detail/config.hpp
*
* \brief This header defines configuration macros for Boost.UUID.
*/
#ifndef BOOST_UUID_DETAIL_CONFIG_HPP_INCLUDED_
#define BOOST_UUID_DETAIL_CONFIG_HPP_INCLUDED_
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#if !defined(BOOST_UUID_NO_SIMD)
#if defined(__GNUC__) && defined(__SSE2__)
// GCC and its pretenders go here
#ifndef BOOST_UUID_USE_SSE2
#define BOOST_UUID_USE_SSE2
#endif
#if defined(__SSE3__) && !defined(BOOST_UUID_USE_SSE3)
#define BOOST_UUID_USE_SSE3
#endif
#if defined(__SSE4_1__) && !defined(BOOST_UUID_USE_SSE41)
#define BOOST_UUID_USE_SSE41
#endif
#elif defined(_MSC_VER)
#if (defined(_M_X64) || (defined(_M_IX86) && defined(_M_IX86_FP) && _M_IX86_FP >= 2)) && !defined(BOOST_UUID_USE_SSE2)
#define BOOST_UUID_USE_SSE2
#endif
#if defined(__AVX__)
#if !defined(BOOST_UUID_USE_SSE41)
#define BOOST_UUID_USE_SSE41
#endif
#if !defined(BOOST_UUID_USE_SSE3)
#define BOOST_UUID_USE_SSE3
#endif
#if !defined(BOOST_UUID_USE_SSE2)
#define BOOST_UUID_USE_SSE2
#endif
#endif
#endif
// More advanced ISA extensions imply less advanced are also available
#if !defined(BOOST_UUID_USE_SSE3) && defined(BOOST_UUID_USE_SSE41)
#define BOOST_UUID_USE_SSE3
#endif
#if !defined(BOOST_UUID_USE_SSE2) && defined(BOOST_UUID_USE_SSE3)
#define BOOST_UUID_USE_SSE2
#endif
#if !defined(BOOST_UUID_NO_SIMD) && !defined(BOOST_UUID_USE_SSE41) && !defined(BOOST_UUID_USE_SSE3) && !defined(BOOST_UUID_USE_SSE2)
#define BOOST_UUID_NO_SIMD
#endif
#endif // !defined(BOOST_UUID_NO_SIMD)
#endif // BOOST_UUID_DETAIL_CONFIG_HPP_INCLUDED_

View File

@@ -0,0 +1,342 @@
/*
* This RFC 1321 compatible MD5 implementation originated at:
* http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
*
* Author:
* Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
*
* This software was written by Alexander Peslyak in 2001. No copyright is
* claimed, and the software is hereby placed in the public domain.
* In case this attempt to disclaim copyright and place the software in the
* public domain is deemed null and void, then the software is
* Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
* general public under the following terms:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted.
*
* There's ABSOLUTELY NO WARRANTY, express or implied.
*
*/
// 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_MD5_HPP
#define BOOST_UUID_MD5_HPP
#include <boost/cast.hpp>
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/uuid/uuid.hpp> // for version
#include <string.h>
namespace boost {
namespace uuids {
namespace detail {
class md5
{
public:
typedef unsigned int(digest_type)[4];
md5()
{
MD5_Init(&ctx_);
}
void process_byte(unsigned char byte)
{
MD5_Update(&ctx_, &byte, 1);
}
void process_bytes(void const* buffer, std::size_t byte_count)
{
MD5_Update(&ctx_, buffer, boost::numeric_cast<unsigned long>(byte_count));
}
void get_digest(digest_type& digest)
{
MD5_Final(reinterpret_cast<unsigned char *>(&digest[0]), &ctx_);
}
unsigned char get_version() const
{
// RFC 4122 Section 4.1.3
return uuid::version_name_based_md5;
}
private:
/* Any 32-bit or wider unsigned integer data type will do */
typedef uint32_t MD5_u32plus;
typedef struct {
MD5_u32plus lo, hi;
MD5_u32plus a, b, c, d;
unsigned char buffer[64];
MD5_u32plus block[16];
} MD5_CTX;
/*
* The basic MD5 functions.
*
* F and G are optimized compared to their RFC 1321 definitions for
* architectures that lack an AND-NOT instruction, just like in Colin Plumb's
* implementation.
*/
BOOST_FORCEINLINE MD5_u32plus BOOST_UUID_DETAIL_MD5_F(MD5_u32plus x, MD5_u32plus y, MD5_u32plus z) { return ((z) ^ ((x) & ((y) ^ (z)))); }
BOOST_FORCEINLINE MD5_u32plus BOOST_UUID_DETAIL_MD5_G(MD5_u32plus x, MD5_u32plus y, MD5_u32plus z) { return ((y) ^ ((z) & ((x) ^ (y)))); }
BOOST_FORCEINLINE MD5_u32plus BOOST_UUID_DETAIL_MD5_H(MD5_u32plus x, MD5_u32plus y, MD5_u32plus z) { return (((x) ^ (y)) ^ (z)); }
BOOST_FORCEINLINE MD5_u32plus BOOST_UUID_DETAIL_MD5_H2(MD5_u32plus x, MD5_u32plus y, MD5_u32plus z) { return ((x) ^ ((y) ^ (z))); }
BOOST_FORCEINLINE MD5_u32plus BOOST_UUID_DETAIL_MD5_I(MD5_u32plus x, MD5_u32plus y, MD5_u32plus z) { return ((y) ^ ((x) | ~(z))); }
/*
* The MD5 transformation for all four rounds.
*/
#define BOOST_UUID_DETAIL_MD5_STEP(f, a, b, c, d, x, t, s) \
(a) += f((b), (c), (d)) + (x) + (t); \
(a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
(a) += (b);
/*
* SET reads 4 input bytes in little-endian byte order and stores them in a
* properly aligned word in host byte order.
*
* The check for little-endian architectures that tolerate unaligned memory
* accesses is just an optimization. Nothing will break if it fails to detect
* a suitable architecture.
*
* Unfortunately, this optimization may be a C strict aliasing rules violation
* if the caller's data buffer has effective type that cannot be aliased by
* MD5_u32plus. In practice, this problem may occur if these MD5 routines are
* inlined into a calling function, or with future and dangerously advanced
* link-time optimizations. For the time being, keeping these MD5 routines in
* their own translation unit avoids the problem.
*/
#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
#define BOOST_UUID_DETAIL_MD5_SET(n) \
(*(MD5_u32plus *)&ptr[(n) * 4])
#define BOOST_UUID_DETAIL_MD5_GET(n) \
BOOST_UUID_DETAIL_MD5_SET(n)
#else
#define BOOST_UUID_DETAIL_MD5_SET(n) \
(ctx->block[(n)] = \
(MD5_u32plus)ptr[(n) * 4] | \
((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
#define BOOST_UUID_DETAIL_MD5_GET(n) \
(ctx->block[(n)])
#endif
/*
* This processes one or more 64-byte data blocks, but does NOT update the bit
* counters. There are no alignment requirements.
*/
const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
{
const unsigned char *ptr;
MD5_u32plus a, b, c, d;
MD5_u32plus saved_a, saved_b, saved_c, saved_d;
ptr = (const unsigned char *)data;
a = ctx->a;
b = ctx->b;
c = ctx->c;
d = ctx->d;
do {
saved_a = a;
saved_b = b;
saved_c = c;
saved_d = d;
/* Round 1 */
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, a, b, c, d, BOOST_UUID_DETAIL_MD5_SET(0), 0xd76aa478, 7)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, d, a, b, c, BOOST_UUID_DETAIL_MD5_SET(1), 0xe8c7b756, 12)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, c, d, a, b, BOOST_UUID_DETAIL_MD5_SET(2), 0x242070db, 17)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, b, c, d, a, BOOST_UUID_DETAIL_MD5_SET(3), 0xc1bdceee, 22)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, a, b, c, d, BOOST_UUID_DETAIL_MD5_SET(4), 0xf57c0faf, 7)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, d, a, b, c, BOOST_UUID_DETAIL_MD5_SET(5), 0x4787c62a, 12)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, c, d, a, b, BOOST_UUID_DETAIL_MD5_SET(6), 0xa8304613, 17)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, b, c, d, a, BOOST_UUID_DETAIL_MD5_SET(7), 0xfd469501, 22)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, a, b, c, d, BOOST_UUID_DETAIL_MD5_SET(8), 0x698098d8, 7)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, d, a, b, c, BOOST_UUID_DETAIL_MD5_SET(9), 0x8b44f7af, 12)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, c, d, a, b, BOOST_UUID_DETAIL_MD5_SET(10), 0xffff5bb1, 17)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, b, c, d, a, BOOST_UUID_DETAIL_MD5_SET(11), 0x895cd7be, 22)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, a, b, c, d, BOOST_UUID_DETAIL_MD5_SET(12), 0x6b901122, 7)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, d, a, b, c, BOOST_UUID_DETAIL_MD5_SET(13), 0xfd987193, 12)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, c, d, a, b, BOOST_UUID_DETAIL_MD5_SET(14), 0xa679438e, 17)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, b, c, d, a, BOOST_UUID_DETAIL_MD5_SET(15), 0x49b40821, 22)
/* Round 2 */
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(1), 0xf61e2562, 5)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(6), 0xc040b340, 9)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(11), 0x265e5a51, 14)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(0), 0xe9b6c7aa, 20)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(5), 0xd62f105d, 5)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(10), 0x02441453, 9)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(15), 0xd8a1e681, 14)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(4), 0xe7d3fbc8, 20)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(9), 0x21e1cde6, 5)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(14), 0xc33707d6, 9)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(3), 0xf4d50d87, 14)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(8), 0x455a14ed, 20)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(13), 0xa9e3e905, 5)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(2), 0xfcefa3f8, 9)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(7), 0x676f02d9, 14)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(12), 0x8d2a4c8a, 20)
/* Round 3 */
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(5), 0xfffa3942, 4)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H2, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(8), 0x8771f681, 11)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(11), 0x6d9d6122, 16)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H2, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(14), 0xfde5380c, 23)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(1), 0xa4beea44, 4)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H2, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(4), 0x4bdecfa9, 11)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(7), 0xf6bb4b60, 16)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H2, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(10), 0xbebfbc70, 23)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(13), 0x289b7ec6, 4)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H2, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(0), 0xeaa127fa, 11)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(3), 0xd4ef3085, 16)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H2, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(6), 0x04881d05, 23)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(9), 0xd9d4d039, 4)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H2, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(12), 0xe6db99e5, 11)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(15), 0x1fa27cf8, 16)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H2, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(2), 0xc4ac5665, 23)
/* Round 4 */
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(0), 0xf4292244, 6)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(7), 0x432aff97, 10)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(14), 0xab9423a7, 15)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(5), 0xfc93a039, 21)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(12), 0x655b59c3, 6)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(3), 0x8f0ccc92, 10)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(10), 0xffeff47d, 15)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(1), 0x85845dd1, 21)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(8), 0x6fa87e4f, 6)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(15), 0xfe2ce6e0, 10)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(6), 0xa3014314, 15)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(13), 0x4e0811a1, 21)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(4), 0xf7537e82, 6)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(11), 0xbd3af235, 10)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(2), 0x2ad7d2bb, 15)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(9), 0xeb86d391, 21)
a += saved_a;
b += saved_b;
c += saved_c;
d += saved_d;
ptr += 64;
} while (size -= 64);
ctx->a = a;
ctx->b = b;
ctx->c = c;
ctx->d = d;
return ptr;
}
void MD5_Init(MD5_CTX *ctx)
{
ctx->a = 0x67452301;
ctx->b = 0xefcdab89;
ctx->c = 0x98badcfe;
ctx->d = 0x10325476;
ctx->lo = 0;
ctx->hi = 0;
}
void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
{
MD5_u32plus saved_lo;
unsigned long used, available;
saved_lo = ctx->lo;
if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
ctx->hi++;
ctx->hi += size >> 29;
used = saved_lo & 0x3f;
if (used) {
available = 64 - used;
if (size < available) {
memcpy(&ctx->buffer[used], data, size);
return;
}
memcpy(&ctx->buffer[used], data, available);
data = (const unsigned char *)data + available;
size -= available;
body(ctx, ctx->buffer, 64);
}
if (size >= 64) {
data = body(ctx, data, size & ~(unsigned long)0x3f);
size &= 0x3f;
}
memcpy(ctx->buffer, data, size);
}
#define BOOST_UUID_DETAIL_MD5_OUT(dst, src) \
(dst)[0] = (unsigned char)(src); \
(dst)[1] = (unsigned char)((src) >> 8); \
(dst)[2] = (unsigned char)((src) >> 16); \
(dst)[3] = (unsigned char)((src) >> 24);
void MD5_Final(unsigned char *result, MD5_CTX *ctx)
{
unsigned long used, available;
used = ctx->lo & 0x3f;
ctx->buffer[used++] = 0x80;
available = 64 - used;
if (available < 8) {
memset(&ctx->buffer[used], 0, available);
body(ctx, ctx->buffer, 64);
used = 0;
available = 64;
}
memset(&ctx->buffer[used], 0, available - 8);
ctx->lo <<= 3;
BOOST_UUID_DETAIL_MD5_OUT(&ctx->buffer[56], ctx->lo)
BOOST_UUID_DETAIL_MD5_OUT(&ctx->buffer[60], ctx->hi)
body(ctx, ctx->buffer, 64);
BOOST_UUID_DETAIL_MD5_OUT(&result[0], ctx->a)
BOOST_UUID_DETAIL_MD5_OUT(&result[4], ctx->b)
BOOST_UUID_DETAIL_MD5_OUT(&result[8], ctx->c)
BOOST_UUID_DETAIL_MD5_OUT(&result[12], ctx->d)
memset(ctx, 0, sizeof(*ctx));
}
#undef BOOST_UUID_DETAIL_MD5_OUT
#undef BOOST_UUID_DETAIL_MD5_SET
#undef BOOST_UUID_DETAIL_MD5_GET
#undef BOOST_UUID_DETAIL_MD5_STEP
MD5_CTX ctx_;
};
} // detail
} // uuids
} // boost
#endif // BOOST_UUID_MD5_HPP

View File

@@ -0,0 +1,91 @@
//
// Copyright (c) 2017 James E. King III
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENCE_1_0.txt)
//
// Platform-specific random entropy provider
//
#ifndef BOOST_UUID_DETAIL_RANDOM_PROVIDER_HPP
#define BOOST_UUID_DETAIL_RANDOM_PROVIDER_HPP
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/limits.hpp>
#include <boost/static_assert.hpp>
#include <boost/move/core.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_unsigned.hpp>
#include <boost/uuid/entropy_error.hpp>
#include <climits>
#include <iterator>
// Detection of the platform is separated from inclusion of the correct
// header to facilitate mock testing of the provider implementations.
#include <boost/uuid/detail/random_provider_detect_platform.hpp>
#include <boost/uuid/detail/random_provider_include_platform.hpp>
namespace boost {
namespace uuids {
namespace detail {
//! \brief Contains code common to all random_provider implementations.
//! \note random_provider_base is required to provide this method:
//! void get_random_bytes(void *buf, size_t siz);
//! \note noncopyable because of some base implementations so
//! this makes it uniform across platforms to avoid any
//! porting surprises
class random_provider :
public detail::random_provider_base
{
BOOST_MOVABLE_BUT_NOT_COPYABLE(random_provider)
public:
BOOST_DEFAULTED_FUNCTION(random_provider(), {})
random_provider(BOOST_RV_REF(random_provider) that) BOOST_NOEXCEPT :
detail::random_provider_base(boost::move(static_cast< detail::random_provider_base& >(that)))
{
}
random_provider& operator= (BOOST_RV_REF(random_provider) that) BOOST_NOEXCEPT
{
static_cast< detail::random_provider_base& >(*this) = boost::move(static_cast< detail::random_provider_base& >(that));
return *this;
}
//! Leverage the provider as a SeedSeq for
//! PseudoRandomNumberGeneration seeing.
//! \note: See Boost.Random documentation for more details
template<class Iter>
void generate(Iter first, Iter last)
{
typedef typename std::iterator_traits<Iter>::value_type value_type;
BOOST_STATIC_ASSERT(is_integral<value_type>::value);
BOOST_STATIC_ASSERT(is_unsigned<value_type>::value);
BOOST_STATIC_ASSERT(sizeof(value_type) * CHAR_BIT >= 32);
for (; first != last; ++first)
{
get_random_bytes(&*first, sizeof(*first));
*first &= (std::numeric_limits<boost::uint32_t>::max)();
}
}
//! Return the name of the selected provider
const char * name() const
{
return BOOST_UUID_RANDOM_PROVIDER_STRINGIFY(BOOST_UUID_RANDOM_PROVIDER_NAME);
}
};
} // detail
} // uuids
} // boost
#endif // BOOST_UUID_DETAIL_RANDOM_PROVIDER_HPP

View File

@@ -0,0 +1,33 @@
//
// Copyright (c) 2017 James E. King III
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENCE_1_0.txt)
//
// "A Replacement Call for Random"
// https://man.openbsd.org/arc4random.3
//
#include <cstddef>
#include <stdlib.h>
namespace boost {
namespace uuids {
namespace detail {
class random_provider_base
{
public:
//! Obtain entropy and place it into a memory location
//! \param[in] buf the location to write entropy
//! \param[in] siz the number of bytes to acquire
void get_random_bytes(void *buf, std::size_t siz)
{
arc4random_buf(buf, siz);
}
};
} // detail
} // uuids
} // boost

View File

@@ -0,0 +1,103 @@
//
// Copyright (c) 2017 James E. King III
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENCE_1_0.txt)
//
// BCrypt provider for entropy
//
#include <cstddef>
#include <boost/config.hpp>
#include <boost/core/ignore_unused.hpp>
#include <boost/move/core.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/winapi/bcrypt.hpp>
#include <boost/winapi/get_last_error.hpp>
#include <boost/throw_exception.hpp>
#if defined(BOOST_UUID_FORCE_AUTO_LINK) || (!defined(BOOST_ALL_NO_LIB) && !defined(BOOST_UUID_RANDOM_PROVIDER_NO_LIB))
# define BOOST_LIB_NAME "bcrypt"
# define BOOST_AUTO_LINK_NOMANGLE
# include <boost/config/auto_link.hpp>
# undef BOOST_AUTO_LINK_NOMANGLE
#endif
namespace boost {
namespace uuids {
namespace detail {
class random_provider_base
{
BOOST_MOVABLE_BUT_NOT_COPYABLE(random_provider_base)
public:
random_provider_base()
: hProv_(NULL)
{
boost::winapi::NTSTATUS_ status =
boost::winapi::BCryptOpenAlgorithmProvider(
&hProv_,
boost::winapi::BCRYPT_RNG_ALGORITHM_,
NULL,
0);
if (BOOST_UNLIKELY(status != 0))
{
BOOST_THROW_EXCEPTION(entropy_error(status, "BCryptOpenAlgorithmProvider"));
}
}
random_provider_base(BOOST_RV_REF(random_provider_base) that) BOOST_NOEXCEPT : hProv_(that.hProv_)
{
that.hProv_ = NULL;
}
random_provider_base& operator= (BOOST_RV_REF(random_provider_base) that) BOOST_NOEXCEPT
{
destroy();
hProv_ = that.hProv_;
that.hProv_ = NULL;
return *this;
}
~random_provider_base() BOOST_NOEXCEPT
{
destroy();
}
//! Obtain entropy and place it into a memory location
//! \param[in] buf the location to write entropy
//! \param[in] siz the number of bytes to acquire
void get_random_bytes(void *buf, std::size_t siz)
{
boost::winapi::NTSTATUS_ status =
boost::winapi::BCryptGenRandom(
hProv_,
static_cast<boost::winapi::PUCHAR_>(buf),
boost::numeric_cast<boost::winapi::ULONG_>(siz),
0);
if (BOOST_UNLIKELY(status != 0))
{
BOOST_THROW_EXCEPTION(entropy_error(status, "BCryptGenRandom"));
}
}
private:
void destroy() BOOST_NOEXCEPT
{
if (hProv_)
{
boost::ignore_unused(boost::winapi::BCryptCloseAlgorithmProvider(hProv_, 0));
}
}
private:
boost::winapi::BCRYPT_ALG_HANDLE_ hProv_;
};
} // detail
} // uuids
} // boost

View File

@@ -0,0 +1,74 @@
//
// Copyright (c) 2017 James E. King III
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENCE_1_0.txt)
//
// Platform-specific random entropy provider platform detection
//
#ifndef BOOST_UUID_DETAIL_RANDOM_PROVIDER_PLATFORM_DETECTION_HPP
#define BOOST_UUID_DETAIL_RANDOM_PROVIDER_PLATFORM_DETECTION_HPP
#include <boost/predef/library/c/cloudabi.h>
#include <boost/predef/library/c/gnu.h>
#include <boost/predef/os/bsd/open.h>
#include <boost/predef/os/windows.h>
// Note: Don't use Boost.Predef to detect Linux and Android as it may give different results depending on header inclusion order.
// https://github.com/boostorg/predef/issues/81#issuecomment-413329061
#if (defined(__linux__) || defined(__linux) || defined(linux)) && (!defined(__ANDROID__) || __ANDROID_API__ >= 28)
#include <sys/syscall.h>
#if defined(SYS_getrandom)
#define BOOST_UUID_RANDOM_PROVIDER_HAS_GETRANDOM
#endif // defined(SYS_getrandom)
#endif
//
// Platform Detection - will load in the correct header and
// will define the class <tt>random_provider_base</tt>.
//
#if BOOST_OS_BSD_OPEN >= BOOST_VERSION_NUMBER(2, 1, 0) || BOOST_LIB_C_CLOUDABI
# define BOOST_UUID_RANDOM_PROVIDER_ARC4RANDOM
# define BOOST_UUID_RANDOM_PROVIDER_NAME arc4random
#elif BOOST_OS_WINDOWS
# include <boost/winapi/config.hpp>
# if BOOST_WINAPI_PARTITION_APP_SYSTEM && \
!defined(BOOST_UUID_RANDOM_PROVIDER_FORCE_WINCRYPT) && \
!defined(_WIN32_WCE) && \
(BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6)
# define BOOST_UUID_RANDOM_PROVIDER_BCRYPT
# define BOOST_UUID_RANDOM_PROVIDER_NAME bcrypt
# elif BOOST_WINAPI_PARTITION_DESKTOP || BOOST_WINAPI_PARTITION_SYSTEM
# define BOOST_UUID_RANDOM_PROVIDER_WINCRYPT
# define BOOST_UUID_RANDOM_PROVIDER_NAME wincrypt
# else
# error Unable to find a suitable windows entropy provider
# endif
#elif defined(BOOST_UUID_RANDOM_PROVIDER_HAS_GETRANDOM) && !defined(BOOST_UUID_RANDOM_PROVIDER_FORCE_POSIX) && !defined(BOOST_UUID_RANDOM_PROVIDER_DISABLE_GETRANDOM)
# define BOOST_UUID_RANDOM_PROVIDER_GETRANDOM
# define BOOST_UUID_RANDOM_PROVIDER_NAME getrandom
#elif BOOST_LIB_C_GNU >= BOOST_VERSION_NUMBER(2, 25, 0) && !defined(BOOST_UUID_RANDOM_PROVIDER_FORCE_POSIX)
# define BOOST_UUID_RANDOM_PROVIDER_GETENTROPY
# define BOOST_UUID_RANDOM_PROVIDER_NAME getentropy
#else
# define BOOST_UUID_RANDOM_PROVIDER_POSIX
# define BOOST_UUID_RANDOM_PROVIDER_NAME posix
#endif
#define BOOST_UUID_RANDOM_PROVIDER_STRINGIFY2(X) #X
#define BOOST_UUID_RANDOM_PROVIDER_STRINGIFY(X) BOOST_UUID_RANDOM_PROVIDER_STRINGIFY2(X)
#if defined(BOOST_UUID_RANDOM_PROVIDER_SHOW)
#pragma message("BOOST_UUID_RANDOM_PROVIDER_NAME " BOOST_UUID_RANDOM_PROVIDER_STRINGIFY(BOOST_UUID_RANDOM_PROVIDER_NAME))
#endif
#endif // BOOST_UUID_DETAIL_RANDOM_PROVIDER_PLATFORM_DETECTION_HPP

View File

@@ -0,0 +1,40 @@
//
// Copyright (c) 2017 James E. King III
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENCE_1_0.txt)
//
// getentropy() capable platforms
//
#include <boost/config.hpp>
#include <boost/throw_exception.hpp>
#include <cerrno>
#include <cstddef>
#include <unistd.h>
namespace boost {
namespace uuids {
namespace detail {
class random_provider_base
{
public:
//! Obtain entropy and place it into a memory location
//! \param[in] buf the location to write entropy
//! \param[in] siz the number of bytes to acquire
void get_random_bytes(void *buf, std::size_t siz)
{
int res = getentropy(buf, siz);
if (BOOST_UNLIKELY(-1 == res))
{
int err = errno;
BOOST_THROW_EXCEPTION(entropy_error(err, "getentropy"));
}
}
};
} // detail
} // uuids
} // boost

View File

@@ -0,0 +1,77 @@
//
// Copyright (c) 2018 Andrey Semashev
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENCE_1_0.txt)
//
// getrandom() capable platforms
//
#include <boost/config.hpp>
#include <boost/throw_exception.hpp>
#include <boost/predef/library/c/gnu.h>
#include <cerrno>
#include <cstddef>
#if !defined(BOOST_UUID_RANDOM_PROVIDER_GETRANDOM_IMPL_GETRANDOM)
#if BOOST_LIB_C_GNU >= BOOST_VERSION_NUMBER(2, 25, 0)
#define BOOST_UUID_RANDOM_PROVIDER_GETRANDOM_HAS_LIBC_WRAPPER
#elif defined(__has_include)
#if __has_include(<sys/random.h>)
#define BOOST_UUID_RANDOM_PROVIDER_GETRANDOM_HAS_LIBC_WRAPPER
#endif
#endif
#endif // !defined(BOOST_UUID_RANDOM_PROVIDER_GETRANDOM_IMPL_GETRANDOM)
#if defined(BOOST_UUID_RANDOM_PROVIDER_GETRANDOM_HAS_LIBC_WRAPPER)
#include <sys/random.h>
#else
#include <stddef.h> // ssize_t
#endif
namespace boost {
namespace uuids {
namespace detail {
class random_provider_base
{
public:
//! Obtain entropy and place it into a memory location
//! \param[in] buf the location to write entropy
//! \param[in] siz the number of bytes to acquire
void get_random_bytes(void *buf, std::size_t siz)
{
std::size_t offset = 0;
while (offset < siz)
{
ssize_t sz = get_random(static_cast< char* >(buf) + offset, siz - offset, 0u);
if (BOOST_UNLIKELY(sz < 0))
{
int err = errno;
if (err == EINTR)
continue;
BOOST_THROW_EXCEPTION(entropy_error(err, "getrandom"));
}
offset += sz;
}
}
private:
static ssize_t get_random(void *buf, std::size_t size, unsigned int flags)
{
#if defined(BOOST_UUID_RANDOM_PROVIDER_GETRANDOM_IMPL_GETRANDOM)
return BOOST_UUID_RANDOM_PROVIDER_GETRANDOM_IMPL_GETRANDOM(buf, size, flags);
#elif defined(BOOST_UUID_RANDOM_PROVIDER_GETRANDOM_HAS_LIBC_WRAPPER)
return ::getrandom(buf, size, flags);
#else
return ::syscall(SYS_getrandom, buf, size, flags);
#endif
}
};
} // detail
} // uuids
} // boost

View File

@@ -0,0 +1,29 @@
//
// Copyright (c) 2017 James E. King III
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENCE_1_0.txt)
//
// Platform-specific random entropy provider platform definition
//
#ifndef BOOST_UUID_DETAIL_RANDOM_PROVIDER_PLATFORM_INCLUDE_HPP
#define BOOST_UUID_DETAIL_RANDOM_PROVIDER_PLATFORM_INCLUDE_HPP
#if defined(BOOST_UUID_RANDOM_PROVIDER_ARC4RANDOM)
# include <boost/uuid/detail/random_provider_arc4random.ipp>
#elif defined(BOOST_UUID_RANDOM_PROVIDER_BCRYPT)
# include <boost/uuid/detail/random_provider_bcrypt.ipp>
#elif defined(BOOST_UUID_RANDOM_PROVIDER_GETENTROPY)
# include <boost/uuid/detail/random_provider_getentropy.ipp>
#elif defined(BOOST_UUID_RANDOM_PROVIDER_GETRANDOM)
# include <boost/uuid/detail/random_provider_getrandom.ipp>
#elif defined(BOOST_UUID_RANDOM_PROVIDER_POSIX)
# include <boost/uuid/detail/random_provider_posix.ipp>
#elif defined(BOOST_UUID_RANDOM_PROVIDER_WINCRYPT)
# include <boost/uuid/detail/random_provider_wincrypt.ipp>
#endif
#endif // BOOST_UUID_DETAIL_RANDOM_PROVIDER_PLATFORM_INCLUDE_HPP

View File

@@ -0,0 +1,120 @@
/* boost uuid/detail/random_provider_posix implementation
*
* Copyright Jens Maurer 2000
* Copyright 2007 Andy Tompkins.
* Copyright Steven Watanabe 2010-2011
* Copyright 2017 James E. King III
*
* 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)
*
* $Id$
*/
#include <boost/config.hpp>
#include <boost/core/ignore_unused.hpp>
#include <boost/move/core.hpp>
#include <boost/throw_exception.hpp>
#include <boost/uuid/entropy_error.hpp>
#include <cerrno>
#include <cstddef>
#include <fcntl.h> // open
#include <sys/stat.h>
#include <sys/types.h>
#if defined(BOOST_HAS_UNISTD_H)
#include <unistd.h>
#endif
#ifndef BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_CLOSE
#define BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_CLOSE ::close
#endif
#ifndef BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_OPEN
#define BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_OPEN ::open
#endif
#ifndef BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_READ
#define BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_READ ::read
#endif
namespace boost {
namespace uuids {
namespace detail {
class random_provider_base
{
BOOST_MOVABLE_BUT_NOT_COPYABLE(random_provider_base)
public:
random_provider_base()
: fd_(-1)
{
int flags = O_RDONLY;
#if defined(O_CLOEXEC)
flags |= O_CLOEXEC;
#endif
fd_ = BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_OPEN("/dev/urandom", flags);
if (BOOST_UNLIKELY(-1 == fd_))
{
int err = errno;
BOOST_THROW_EXCEPTION(entropy_error(err, "open /dev/urandom"));
}
}
random_provider_base(BOOST_RV_REF(random_provider_base) that) BOOST_NOEXCEPT : fd_(that.fd_)
{
that.fd_ = -1;
}
random_provider_base& operator= (BOOST_RV_REF(random_provider_base) that) BOOST_NOEXCEPT
{
destroy();
fd_ = that.fd_;
that.fd_ = -1;
return *this;
}
~random_provider_base() BOOST_NOEXCEPT
{
destroy();
}
//! Obtain entropy and place it into a memory location
//! \param[in] buf the location to write entropy
//! \param[in] siz the number of bytes to acquire
void get_random_bytes(void *buf, std::size_t siz)
{
std::size_t offset = 0;
while (offset < siz)
{
ssize_t sz = BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_READ(
fd_, static_cast<char *>(buf) + offset, siz - offset);
if (BOOST_UNLIKELY(sz < 0))
{
int err = errno;
if (err == EINTR)
continue;
BOOST_THROW_EXCEPTION(entropy_error(err, "read"));
}
offset += sz;
}
}
private:
void destroy() BOOST_NOEXCEPT
{
if (fd_ >= 0)
{
boost::ignore_unused(BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_CLOSE(fd_));
}
}
private:
int fd_;
};
} // detail
} // uuids
} // boost

View File

@@ -0,0 +1,109 @@
/* boost uuid/detail/random_provider_wincrypt implementation
*
* Copyright Jens Maurer 2000
* Copyright 2007 Andy Tompkins.
* Copyright Steven Watanabe 2010-2011
* Copyright 2017 James E. King III
*
* 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)
*
* $Id$
*/
#include <cstddef>
#include <boost/config.hpp>
#include <boost/core/ignore_unused.hpp>
#include <boost/move/core.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/winapi/crypt.hpp>
#include <boost/winapi/get_last_error.hpp>
#include <boost/throw_exception.hpp>
#if defined(BOOST_UUID_FORCE_AUTO_LINK) || (!defined(BOOST_ALL_NO_LIB) && !defined(BOOST_UUID_RANDOM_PROVIDER_NO_LIB))
# if defined(_WIN32_WCE)
# define BOOST_LIB_NAME "coredll"
# else
# define BOOST_LIB_NAME "advapi32"
# endif
# define BOOST_AUTO_LINK_NOMANGLE
# include <boost/config/auto_link.hpp>
# undef BOOST_AUTO_LINK_NOMANGLE
#endif
namespace boost {
namespace uuids {
namespace detail {
class random_provider_base
{
BOOST_MOVABLE_BUT_NOT_COPYABLE(random_provider_base)
public:
random_provider_base()
: hProv_(0)
{
boost::winapi::BOOL_ res = boost::winapi::CryptAcquireContextW(
&hProv_,
NULL,
NULL,
boost::winapi::PROV_RSA_FULL_,
boost::winapi::CRYPT_VERIFYCONTEXT_ | boost::winapi::CRYPT_SILENT_);
if (BOOST_UNLIKELY(!res))
{
boost::winapi::DWORD_ err = boost::winapi::GetLastError();
BOOST_THROW_EXCEPTION(entropy_error(err, "CryptAcquireContext"));
}
}
random_provider_base(BOOST_RV_REF(random_provider_base) that) BOOST_NOEXCEPT : hProv_(that.hProv_)
{
that.hProv_ = 0;
}
random_provider_base& operator= (BOOST_RV_REF(random_provider_base) that) BOOST_NOEXCEPT
{
destroy();
hProv_ = that.hProv_;
that.hProv_ = 0;
return *this;
}
~random_provider_base() BOOST_NOEXCEPT
{
destroy();
}
//! Obtain entropy and place it into a memory location
//! \param[in] buf the location to write entropy
//! \param[in] siz the number of bytes to acquire
void get_random_bytes(void *buf, std::size_t siz)
{
boost::winapi::BOOL_ res = boost::winapi::CryptGenRandom(
hProv_,
boost::numeric_cast<boost::winapi::DWORD_>(siz),
static_cast<boost::winapi::BYTE_ *>(buf));
if (BOOST_UNLIKELY(!res))
{
boost::winapi::DWORD_ err = boost::winapi::GetLastError();
BOOST_THROW_EXCEPTION(entropy_error(err, "CryptGenRandom"));
}
}
private:
void destroy() BOOST_NOEXCEPT
{
if (hProv_)
{
boost::ignore_unused(boost::winapi::CryptReleaseContext(hProv_, 0));
}
}
private:
boost::winapi::HCRYPTPROV_ hProv_;
};
} // detail
} // uuids
} // boost

View File

@@ -0,0 +1,237 @@
// 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
// 10 Jan 2012 - can now handle the full size of messages (2^64 - 1 bits)
// This is a byte oriented implementation
#ifndef BOOST_UUID_SHA1_H
#define BOOST_UUID_SHA1_H
#include <boost/static_assert.hpp>
#include <boost/throw_exception.hpp>
#include <boost/uuid/uuid.hpp> // for version
#include <cstddef>
#include <stdexcept>
#include <string>
#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);
unsigned char get_version() const;
private:
void process_block();
void process_byte_impl(unsigned char byte);
private:
unsigned int h_[5];
unsigned char block_[64];
std::size_t block_byte_index_;
std::size_t bit_count_low;
std::size_t bit_count_high;
};
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;
bit_count_low = 0;
bit_count_high = 0;
}
inline void sha1::process_byte(unsigned char byte)
{
process_byte_impl(byte);
// size_t max value = 0xFFFFFFFF
//if (bit_count_low + 8 >= 0x100000000) { // would overflow
//if (bit_count_low >= 0x100000000-8) {
if (bit_count_low < 0xFFFFFFF8) {
bit_count_low += 8;
} else {
bit_count_low = 0;
if (bit_count_high <= 0xFFFFFFFE) {
++bit_count_high;
} else {
BOOST_THROW_EXCEPTION(std::runtime_error("sha1 too many bytes"));
}
}
}
inline void sha1::process_byte_impl(unsigned char byte)
{
block_[block_byte_index_++] = byte;
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 unsigned char sha1::get_version() const
{
// RFC 4122 Section 4.1.3
return uuid::version_name_based_sha1;
}
inline void sha1::get_digest(digest_type& digest)
{
// append the bit '1' to the message
process_byte_impl(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_impl(0);
}
// one more block
while (block_byte_index_ < 56) {
process_byte_impl(0);
}
} else {
while (block_byte_index_ < 56) {
process_byte_impl(0);
}
}
// append length of message (before pre-processing)
// as a 64-bit big-endian integer
process_byte_impl( static_cast<unsigned char>((bit_count_high>>24) & 0xFF) );
process_byte_impl( static_cast<unsigned char>((bit_count_high>>16) & 0xFF) );
process_byte_impl( static_cast<unsigned char>((bit_count_high>>8 ) & 0xFF) );
process_byte_impl( static_cast<unsigned char>((bit_count_high) & 0xFF) );
process_byte_impl( static_cast<unsigned char>((bit_count_low>>24) & 0xFF) );
process_byte_impl( static_cast<unsigned char>((bit_count_low>>16) & 0xFF) );
process_byte_impl( static_cast<unsigned char>((bit_count_low>>8 ) & 0xFF) );
process_byte_impl( static_cast<unsigned char>((bit_count_low) & 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

View File

@@ -0,0 +1,51 @@
/*
* Copyright Andy Tompkins 2006.
* 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)
*/
/*!
* \file uuid/detail/uuid_generic.ipp
*
* \brief This header contains generic implementation of \c boost::uuid operations.
*/
#ifndef BOOST_UUID_DETAIL_UUID_GENERIC_IPP_INCLUDED_
#define BOOST_UUID_DETAIL_UUID_GENERIC_IPP_INCLUDED_
#include <string.h>
namespace boost {
namespace uuids {
inline bool uuid::is_nil() const BOOST_NOEXCEPT
{
for (std::size_t i = 0; i < sizeof(data); ++i)
{
if (data[i] != 0U)
return false;
}
return true;
}
inline void uuid::swap(uuid& rhs) BOOST_NOEXCEPT
{
uuid tmp = *this;
*this = rhs;
rhs = tmp;
}
inline bool operator== (uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT
{
return memcmp(lhs.data, rhs.data, sizeof(lhs.data)) == 0;
}
inline bool operator< (uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT
{
return memcmp(lhs.data, rhs.data, sizeof(lhs.data)) < 0;
}
} // namespace uuids
} // namespace boost
#endif // BOOST_UUID_DETAIL_UUID_GENERIC_IPP_INCLUDED_

View File

@@ -0,0 +1,135 @@
/*
* Copyright Andrey Semashev 2013.
* 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)
*/
/*!
* \file uuid/detail/uuid_x86.ipp
*
* \brief This header contains optimized SSE implementation of \c boost::uuid operations.
*/
#ifndef BOOST_UUID_DETAIL_UUID_X86_IPP_INCLUDED_
#define BOOST_UUID_DETAIL_UUID_X86_IPP_INCLUDED_
// MSVC does not always have immintrin.h (at least, not up to MSVC 10), so include the appropriate header for each instruction set
#if defined(BOOST_UUID_USE_SSE41)
#include <smmintrin.h>
#elif defined(BOOST_UUID_USE_SSE3)
#include <pmmintrin.h>
#else
#include <emmintrin.h>
#endif
#if defined(BOOST_MSVC) && defined(_M_X64) && !defined(BOOST_UUID_USE_SSE3) && (BOOST_MSVC < 1900 /* Fixed in Visual Studio 2015 */ )
// At least MSVC 9 (VS2008) and 12 (VS2013) have an optimizer bug that sometimes results in incorrect SIMD code
// generated in Release x64 mode. In particular, it affects operator==, where the compiler sometimes generates
// pcmpeqd with a memory opereand instead of movdqu followed by pcmpeqd. The problem is that uuid can be
// not aligned to 16 bytes and pcmpeqd causes alignment violation in this case. We cannot be sure that other
// MSVC versions are not affected so we apply the workaround for all versions, except VS2015 on up where
// the bug has been fixed.
//
// https://svn.boost.org/trac/boost/ticket/8509#comment:3
// https://connect.microsoft.com/VisualStudio/feedbackdetail/view/981648#tabs
#define BOOST_UUID_DETAIL_MSVC_BUG981648
#if BOOST_MSVC >= 1600
extern "C" void _ReadWriteBarrier(void);
#pragma intrinsic(_ReadWriteBarrier)
#endif
#endif
namespace boost {
namespace uuids {
namespace detail {
BOOST_FORCEINLINE __m128i load_unaligned_si128(const uint8_t* p) BOOST_NOEXCEPT
{
#if defined(BOOST_UUID_USE_SSE3)
return _mm_lddqu_si128(reinterpret_cast< const __m128i* >(p));
#elif !defined(BOOST_UUID_DETAIL_MSVC_BUG981648)
return _mm_loadu_si128(reinterpret_cast< const __m128i* >(p));
#elif defined(BOOST_MSVC) && BOOST_MSVC >= 1600
__m128i mm = _mm_loadu_si128(reinterpret_cast< const __m128i* >(p));
// Make sure this load doesn't get merged with the subsequent instructions
_ReadWriteBarrier();
return mm;
#else
// VS2008 x64 doesn't respect _ReadWriteBarrier above, so we have to generate this crippled code to load unaligned data
return _mm_unpacklo_epi64(_mm_loadl_epi64(reinterpret_cast< const __m128i* >(p)), _mm_loadl_epi64(reinterpret_cast< const __m128i* >(p + 8)));
#endif
}
} // namespace detail
inline bool uuid::is_nil() const BOOST_NOEXCEPT
{
__m128i mm = uuids::detail::load_unaligned_si128(data);
#if defined(BOOST_UUID_USE_SSE41)
return _mm_test_all_zeros(mm, mm) != 0;
#else
mm = _mm_cmpeq_epi32(mm, _mm_setzero_si128());
return _mm_movemask_epi8(mm) == 0xFFFF;
#endif
}
inline void uuid::swap(uuid& rhs) BOOST_NOEXCEPT
{
__m128i mm_this = uuids::detail::load_unaligned_si128(data);
__m128i mm_rhs = uuids::detail::load_unaligned_si128(rhs.data);
_mm_storeu_si128(reinterpret_cast< __m128i* >(rhs.data), mm_this);
_mm_storeu_si128(reinterpret_cast< __m128i* >(data), mm_rhs);
}
inline bool operator== (uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT
{
__m128i mm_left = uuids::detail::load_unaligned_si128(lhs.data);
__m128i mm_right = uuids::detail::load_unaligned_si128(rhs.data);
#if defined(BOOST_UUID_USE_SSE41)
__m128i mm = _mm_xor_si128(mm_left, mm_right);
return _mm_test_all_zeros(mm, mm) != 0;
#else
__m128i mm_cmp = _mm_cmpeq_epi32(mm_left, mm_right);
return _mm_movemask_epi8(mm_cmp) == 0xFFFF;
#endif
}
inline bool operator< (uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT
{
__m128i mm_left = uuids::detail::load_unaligned_si128(lhs.data);
__m128i mm_right = uuids::detail::load_unaligned_si128(rhs.data);
// To emulate lexicographical_compare behavior we have to perform two comparisons - the forward and reverse one.
// Then we know which bytes are equivalent and which ones are different, and for those different the comparison results
// will be opposite. Then we'll be able to find the first differing comparison result (for both forward and reverse ways),
// and depending on which way it is for, this will be the result of the operation. There are a few notes to consider:
//
// 1. Due to little endian byte order the first bytes go into the lower part of the xmm registers,
// so the comparison results in the least significant bits will actually be the most signigicant for the final operation result.
// This means we have to determine which of the comparison results have the least significant bit on, and this is achieved with
// the "(x - 1) ^ x" trick.
// 2. Because there is only signed comparison in SSE/AVX, we have to invert byte comparison results whenever signs of the corresponding
// bytes are different. I.e. in signed comparison it's -1 < 1, but in unsigned it is the opposite (255 > 1). To do that we XOR left and right,
// making the most significant bit of each byte 1 if the signs are different, and later apply this mask with another XOR to the comparison results.
// 3. pcmpgtw compares for "greater" relation, so we swap the arguments to get what we need.
const __m128i mm_signs_mask = _mm_xor_si128(mm_left, mm_right);
__m128i mm_cmp = _mm_cmpgt_epi8(mm_right, mm_left), mm_rcmp = _mm_cmpgt_epi8(mm_left, mm_right);
mm_cmp = _mm_xor_si128(mm_signs_mask, mm_cmp);
mm_rcmp = _mm_xor_si128(mm_signs_mask, mm_rcmp);
uint32_t cmp = static_cast< uint32_t >(_mm_movemask_epi8(mm_cmp)), rcmp = static_cast< uint32_t >(_mm_movemask_epi8(mm_rcmp));
cmp = (cmp - 1u) ^ cmp;
rcmp = (rcmp - 1u) ^ rcmp;
return cmp < rcmp;
}
} // namespace uuids
} // namespace boost
#endif // BOOST_UUID_DETAIL_UUID_X86_IPP_INCLUDED_

View File

@@ -0,0 +1,46 @@
//
// Copyright (c) 2017, 2018 James E. King III
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENCE_1_0.txt)
//
// Entropy error class
//
#ifndef BOOST_UUID_RANDOM_ENTROPY_ERROR_HPP
#define BOOST_UUID_RANDOM_ENTROPY_ERROR_HPP
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <stdexcept>
#include <string>
namespace boost {
namespace uuids {
//! \brief Given boost::system::system_error is in a module that
//! is not header-only, we define our own exception type
//! to handle entropy provider errors instead,
class BOOST_SYMBOL_VISIBLE entropy_error : public std::runtime_error
{
public:
entropy_error(boost::intmax_t errCode, const std::string& message)
: std::runtime_error(message)
, m_errcode(errCode)
{
}
virtual boost::intmax_t errcode() const
{
return m_errcode;
}
private:
boost::intmax_t m_errcode;
};
} // uuids
} // boost
#endif // BOOST_UUID_RANDOM_ENTROPY_ERROR_HPP

View File

@@ -0,0 +1,38 @@
// Boost name_generator.hpp header file -----------------------------//
// Copyright 2010 Andy Tompkins.
// Copyright 2017 James E. King III
// 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/config.hpp>
#include <boost/uuid/name_generator_sha1.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
namespace boost {
namespace uuids {
//! \deprecated
//! \brief this provides backwards compatibility with previous boost
//! releases however it is now deprecated to ensure that once
//! a new hashing algorithm is defined for name generation that
//! there is no confusion - at that time this will be removed.
typedef name_generator_sha1 name_generator;
//! \brief this provides the latest name generator hashing algorithm
//! regardless of boost release; if you do not need stable
//! name generation across releases then this will suffice
typedef name_generator_sha1 name_generator_latest;
} // uuids
} // boost
#endif // BOOST_UUID_NAME_GENERATOR_HPP

View File

@@ -0,0 +1,25 @@
// Boost name_generator_md5.hpp header file ------------------------//
// Copyright 2017 James E. King III
// 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_MD5_HPP
#define BOOST_UUID_NAME_GENERATOR_MD5_HPP
#include <boost/uuid/basic_name_generator.hpp>
#include <boost/uuid/detail/md5.hpp>
namespace boost {
namespace uuids {
//! \brief MD5 hashing is defined in RFC 4122 however it is not commonly
//! used; the definition is provided for backwards compatibility.
typedef basic_name_generator<detail::md5> name_generator_md5;
} // uuids
} // boost
#endif // BOOST_UUID_NAME_GENERATOR_MD5_HPP

View File

@@ -0,0 +1,26 @@
// Boost name_generator_sha1.hpp header file ------------------------//
// Copyright 2010 Andy Tompkins.
// Copyright 2017 James E. King III
// 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_SHA1_HPP
#define BOOST_UUID_NAME_GENERATOR_SHA1_HPP
#include <boost/uuid/basic_name_generator.hpp>
#include <boost/uuid/detail/sha1.hpp>
namespace boost {
namespace uuids {
//! \brief SHA1 hashing is the default method defined in RFC 4122 to be
//! used when backwards compatibility is not necessary.
typedef basic_name_generator<detail::sha1> name_generator_sha1;
} // uuids
} // boost
#endif // BOOST_UUID_NAME_GENERATOR_SHA1_HPP

View File

@@ -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

View File

@@ -0,0 +1,228 @@
// Boost random_generator.hpp header file ----------------------------------------------//
// Copyright 2010 Andy Tompkins.
// Copyright 2017 James E. King III
// 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/config.hpp>
#include <boost/assert.hpp>
#include <boost/move/core.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/core/enable_if.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int.hpp>
#include <boost/random/variate_generator.hpp>
#include <boost/tti/has_member_function.hpp>
#include <boost/uuid/detail/random_provider.hpp>
#include <boost/uuid/uuid.hpp>
#include <limits>
namespace boost {
namespace uuids {
namespace detail {
template<class U>
U& set_uuid_random_vv(U& u)
{
// 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;
}
BOOST_TTI_HAS_MEMBER_FUNCTION(seed)
}
//! generate a random-based uuid
//! \param[in] UniformRandomNumberGenerator see Boost.Random documentation
template <typename UniformRandomNumberGenerator>
class basic_random_generator
{
BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_random_generator)
private:
typedef uniform_int<unsigned long> distribution_type;
typedef variate_generator<UniformRandomNumberGenerator*, distribution_type> generator_type;
struct impl
{
generator_type generator;
explicit impl(UniformRandomNumberGenerator* purng_arg) :
generator(purng_arg, distribution_type((std::numeric_limits<unsigned long>::min)(), (std::numeric_limits<unsigned long>::max)()))
{
}
virtual ~impl() {}
BOOST_DELETED_FUNCTION(impl(impl const&))
BOOST_DELETED_FUNCTION(impl& operator= (impl const&))
};
struct urng_holder
{
UniformRandomNumberGenerator urng;
};
#if defined(BOOST_MSVC)
#pragma warning(push)
// 'this' : used in base member initializer list
#pragma warning(disable: 4355)
#endif
struct self_contained_impl :
public urng_holder,
public impl
{
self_contained_impl() : impl(&this->urng_holder::urng)
{
}
};
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
public:
typedef uuid result_type;
// default constructor creates the random number generator and
// if the UniformRandomNumberGenerator is a PseudoRandomNumberGenerator
// then it gets seeded by a random_provider.
basic_random_generator() : m_impl(new self_contained_impl())
{
// seed the random number generator if it is capable
seed(static_cast< self_contained_impl* >(m_impl)->urng);
}
// keep a reference to a random number generator
// don't seed a given random number generator
explicit basic_random_generator(UniformRandomNumberGenerator& gen) : m_impl(new impl(&gen))
{
}
// keep a pointer to a random number generator
// don't seed a given random number generator
explicit basic_random_generator(UniformRandomNumberGenerator* gen) : m_impl(new impl(gen))
{
BOOST_ASSERT(!!gen);
}
basic_random_generator(BOOST_RV_REF(basic_random_generator) that) BOOST_NOEXCEPT : m_impl(that.m_impl)
{
that.m_impl = 0;
}
basic_random_generator& operator= (BOOST_RV_REF(basic_random_generator) that) BOOST_NOEXCEPT
{
delete m_impl;
m_impl = that.m_impl;
that.m_impl = 0;
return *this;
}
~basic_random_generator()
{
delete m_impl;
}
result_type operator()()
{
result_type u;
int i=0;
unsigned long random_value = m_impl->generator();
for (uuid::iterator it = u.begin(), end = u.end(); it != end; ++it, ++i) {
if (i==sizeof(unsigned long)) {
random_value = m_impl->generator();
i = 0;
}
// static_cast gets rid of warnings of converting unsigned long to boost::uint8_t
*it = static_cast<uuid::value_type>((random_value >> (i*8)) & 0xFF);
}
return detail::set_uuid_random_vv(u);
}
private:
// Detect whether UniformRandomNumberGenerator has a seed() method which indicates that
// it is a PseudoRandomNumberGenerator and needs a seed to initialize it. This allows
// basic_random_generator to take any type of UniformRandomNumberGenerator and still
// meet the post-conditions for the default constructor.
template<class MaybePseudoRandomNumberGenerator>
typename boost::enable_if<detail::has_member_function_seed<MaybePseudoRandomNumberGenerator, void> >::type
seed(MaybePseudoRandomNumberGenerator& rng)
{
detail::random_provider seeder;
rng.seed(seeder);
}
template<class MaybePseudoRandomNumberGenerator>
typename boost::disable_if<detail::has_member_function_seed<MaybePseudoRandomNumberGenerator, void> >::type
seed(MaybePseudoRandomNumberGenerator&)
{
}
impl* m_impl;
};
//! \brief a far less complex random generator that uses
//! operating system provided entropy which will
//! satisfy the majority of use cases
class random_generator_pure
{
BOOST_MOVABLE_BUT_NOT_COPYABLE(random_generator_pure)
public:
typedef uuid result_type;
BOOST_DEFAULTED_FUNCTION(random_generator_pure(), {})
random_generator_pure(BOOST_RV_REF(random_generator_pure) that) BOOST_NOEXCEPT :
prov_(boost::move(that.prov_))
{
}
random_generator_pure& operator= (BOOST_RV_REF(random_generator_pure) that) BOOST_NOEXCEPT
{
prov_ = boost::move(that.prov_);
return *this;
}
//! \returns a random, valid uuid
//! \throws entropy_error
result_type operator()()
{
result_type result;
prov_.get_random_bytes(&result, sizeof(result_type));
return detail::set_uuid_random_vv(result);
}
private:
detail::random_provider prov_;
};
#if defined(BOOST_UUID_RANDOM_GENERATOR_COMPAT)
typedef basic_random_generator<mt19937> random_generator;
#else
typedef random_generator_pure random_generator;
typedef basic_random_generator<mt19937> random_generator_mt19937;
#endif
}} // namespace boost::uuids
#endif // BOOST_UUID_RANDOM_GENERATOR_HPP

View File

@@ -0,0 +1,199 @@
// 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>
#include <boost/throw_exception.hpp>
#include <boost/config.hpp>
#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-0123-456789abcdef
// {01234567-89ab-cdef-0123-456789abcdef}
// {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 there are dashes, they must be in every slot
else if (i == 6 || i == 8 || i == 10) {
if (has_dashes == true) {
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);
}
// check end of string - any additional data is an invalid uuid
if (begin != end) {
throw_invalid();
}
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 digits_begin[] = "0123456789abcdefABCDEF";
static size_t digits_len = (sizeof(digits_begin) / sizeof(char)) - 1;
static char const*const digits_end = digits_begin + digits_len;
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 };
size_t pos = std::find(digits_begin, digits_end, c) - digits_begin;
if (pos >= digits_len) {
throw_invalid();
}
return values[pos];
}
unsigned char get_value(wchar_t c) const {
static wchar_t const digits_begin[] = L"0123456789abcdefABCDEF";
static size_t digits_len = (sizeof(digits_begin) / sizeof(wchar_t)) - 1;
static wchar_t const*const digits_end = digits_begin + digits_len;
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 };
size_t pos = std::find(digits_begin, digits_end, c) - digits_begin;
if (pos >= digits_len) {
throw_invalid();
}
return values[pos];
}
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();
}
}
BOOST_NORETURN void throw_invalid() const {
BOOST_THROW_EXCEPTION(std::runtime_error("invalid uuid string"));
}
};
}} // namespace boost::uuids
#endif //BOOST_UUID_STRING_GENERATOR_HPP

View File

@@ -0,0 +1,212 @@
// 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
// 29 Apr 2013 - added support for noexcept and constexpr, added optimizations for SSE/AVX
#ifndef BOOST_UUID_HPP
#define BOOST_UUID_HPP
#include <cstddef>
#include <boost/cstdint.hpp>
#include <boost/uuid/detail/config.hpp>
#ifndef BOOST_UUID_NO_TYPE_TRAITS
#include <boost/type_traits/is_pod.hpp>
#include <boost/type_traits/integral_constant.hpp>
#endif
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#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 BOOST_CONSTEXPR size_type static_size() BOOST_NOEXCEPT { return 16; }
public:
iterator begin() BOOST_NOEXCEPT { return data; }
const_iterator begin() const BOOST_NOEXCEPT { return data; }
iterator end() BOOST_NOEXCEPT { return data+size(); }
const_iterator end() const BOOST_NOEXCEPT { return data+size(); }
BOOST_CONSTEXPR size_type size() const BOOST_NOEXCEPT { return static_size(); }
bool is_nil() const BOOST_NOEXCEPT;
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 BOOST_NOEXCEPT
{
// 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 BOOST_NOEXCEPT
{
// version is stored in octet 9
// which is index 6, since indexes count backwards
uint8_t 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) BOOST_NOEXCEPT;
public:
// or should it be array<uint8_t, 16>
uint8_t data[16];
};
bool operator== (uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT;
bool operator< (uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT;
inline bool operator!=(uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT
{
return !(lhs == rhs);
}
inline bool operator>(uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT
{
return rhs < lhs;
}
inline bool operator<=(uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT
{
return !(rhs < lhs);
}
inline bool operator>=(uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT
{
return !(lhs < rhs);
}
inline void swap(uuid& lhs, uuid& rhs) BOOST_NOEXCEPT
{
lhs.swap(rhs);
}
// This is equivalent to boost::hash_range(u.begin(), u.end());
inline std::size_t hash_value(uuid const& u) BOOST_NOEXCEPT
{
std::size_t seed = 0;
for(uuid::const_iterator i=u.begin(), e=u.end(); i != e; ++i)
{
seed ^= static_cast<std::size_t>(*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<uuids::uuid> : true_type {};
} // namespace boost
#endif
#if defined(BOOST_UUID_USE_SSE2)
#include <boost/uuid/detail/uuid_x86.ipp>
#else
#include <boost/uuid/detail/uuid_generic.ipp>
#endif
#if defined(_MSC_VER)
#pragma warning(pop) // Restore warnings to previous state.
#endif
#endif // BOOST_UUID_HPP

View File

@@ -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

View File

@@ -0,0 +1,40 @@
//
// Copyright (c) 2018 James E. King III
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENCE_1_0.txt)
//
// std::hash support for uuid
//
#ifndef BOOST_UUID_HASH_HPP
#define BOOST_UUID_HASH_HPP
#include <boost/config.hpp>
#include <boost/container_hash/hash.hpp>
#include <boost/uuid/uuid_io.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
#include <cstddef>
#include <functional>
namespace std
{
template<>
struct hash<boost::uuids::uuid>
{
std::size_t operator () (const boost::uuids::uuid& value) const BOOST_NOEXCEPT
{
return boost::hash_value(to_string(value));
}
};
}
#endif /* !BOOST_NO_CXX11_HDR_FUNCTIONAL */
#endif /* !BOOST_UUID_HASH_HPP */

View File

@@ -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 <boost/uuid/uuid.hpp>
#include <ios>
#include <ostream>
#include <istream>
#include <boost/io/ios_state.hpp>
#include <locale>
#include <algorithm>
#if defined(_MSC_VER)
#pragma warning(push) // Save warning settings.
#pragma warning(disable : 4996) // Disable deprecated std::ctype<char>::widen, std::copy
#endif
namespace boost {
namespace uuids {
template <typename ch, typename char_traits>
std::basic_ostream<ch, char_traits>& operator<<(std::basic_ostream<ch, char_traits> &os, uuid const& u)
{
io::ios_flags_saver flags_saver(os);
io::basic_ios_fill_saver<ch, char_traits> fill_saver(os);
const typename std::basic_ostream<ch, char_traits>::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<ch, char_traits>::char_type fill = os.fill();
if (flags & (std::ios_base::right | std::ios_base::internal)) {
for (std::streamsize i=uuid_width; i<width; i++) {
os << fill;
}
}
os << std::hex << std::right;
os.fill(os.widen('0'));
std::size_t i=0;
for (uuid::const_iterator i_data = u.begin(); i_data!=u.end(); ++i_data, ++i) {
os.width(2);
os << static_cast<unsigned int>(*i_data);
if (i == 3 || i == 5 || i == 7 || i == 9) {
os << os.widen('-');
}
}
if (flags & std::ios_base::left) {
for (std::streamsize s=uuid_width; s<width; s++) {
os << fill;
}
}
os.width(0); //used the width so reset it
}
return os;
}
template <typename ch, typename char_traits>
std::basic_istream<ch, char_traits>& operator>>(std::basic_istream<ch, char_traits> &is, uuid &u)
{
const typename std::basic_istream<ch, char_traits>::sentry ok(is);
if (ok) {
unsigned char data[16];
typedef std::ctype<ch> ctype_t;
ctype_t const& ctype = std::use_facet<ctype_t>(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<u.size() && is; ++i) {
is >> 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<unsigned char>(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<unsigned char>(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<char>('0' + i);
} else {
return static_cast<char>('a' + (i-10));
}
}
inline wchar_t to_wchar(size_t i) {
if (i <= 9) {
return static_cast<wchar_t>(L'0' + i);
} else {
return static_cast<wchar_t>(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

View File

@@ -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 <boost/uuid/uuid.hpp>
#include <boost/serialization/level.hpp>
BOOST_CLASS_IMPLEMENTATION(boost::uuids::uuid, boost::serialization::primitive_type)
#endif // BOOST_UUID_SERIALIZE_HPP