File indexing completed on 2025-01-30 10:02:08
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_UUID_STRING_GENERATOR_HPP
0009 #define BOOST_UUID_STRING_GENERATOR_HPP
0010
0011 #include <boost/uuid/uuid.hpp>
0012 #include <string>
0013 #include <cstring> // for strlen, wcslen
0014 #include <iterator>
0015 #include <algorithm> // for find
0016 #include <stdexcept>
0017 #include <boost/throw_exception.hpp>
0018 #include <boost/config.hpp>
0019
0020 #ifdef BOOST_NO_STDC_NAMESPACE
0021 namespace std {
0022 using ::strlen;
0023 using ::wcslen;
0024 }
0025 #endif
0026
0027 namespace boost {
0028 namespace uuids {
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 struct string_generator {
0041 typedef uuid result_type;
0042
0043 template <typename ch, typename char_traits, typename alloc>
0044 uuid operator()(std::basic_string<ch, char_traits, alloc> const& s) const {
0045 return operator()(s.begin(), s.end());
0046 }
0047
0048 uuid operator()(char const*const s) const {
0049 return operator()(s, s+std::strlen(s));
0050 }
0051
0052 uuid operator()(wchar_t const*const s) const {
0053 return operator()(s, s+std::wcslen(s));
0054 }
0055
0056 template <typename CharIterator>
0057 uuid operator()(CharIterator begin, CharIterator end) const
0058 {
0059 typedef typename std::iterator_traits<CharIterator>::value_type char_type;
0060
0061
0062 char_type c = get_next_char(begin, end);
0063 bool has_open_brace = is_open_brace(c);
0064 char_type open_brace_char = c;
0065 if (has_open_brace) {
0066 c = get_next_char(begin, end);
0067 }
0068
0069 bool has_dashes = false;
0070
0071 uuid u;
0072 int i=0;
0073 for (uuid::iterator it_byte=u.begin(); it_byte!=u.end(); ++it_byte, ++i) {
0074 if (it_byte != u.begin()) {
0075 c = get_next_char(begin, end);
0076 }
0077
0078 if (i == 4) {
0079 has_dashes = is_dash(c);
0080 if (has_dashes) {
0081 c = get_next_char(begin, end);
0082 }
0083 }
0084
0085
0086 else if (i == 6 || i == 8 || i == 10) {
0087 if (has_dashes == true) {
0088 if (is_dash(c)) {
0089 c = get_next_char(begin, end);
0090 } else {
0091 throw_invalid();
0092 }
0093 }
0094 }
0095
0096
0097 *it_byte = get_value(c);
0098
0099 c = get_next_char(begin, end);
0100 *it_byte <<= 4;
0101 *it_byte |= get_value(c);
0102 }
0103
0104
0105 if (has_open_brace) {
0106 c = get_next_char(begin, end);
0107 check_close_brace(c, open_brace_char);
0108 }
0109
0110
0111 if (begin != end) {
0112 throw_invalid();
0113 }
0114
0115 return u;
0116 }
0117
0118 private:
0119 template <typename CharIterator>
0120 typename std::iterator_traits<CharIterator>::value_type
0121 get_next_char(CharIterator& begin, CharIterator end) const {
0122 if (begin == end) {
0123 throw_invalid();
0124 }
0125 return *begin++;
0126 }
0127
0128 unsigned char get_value(char c) const {
0129 static char const digits_begin[] = "0123456789abcdefABCDEF";
0130 static size_t digits_len = (sizeof(digits_begin) / sizeof(char)) - 1;
0131 static char const*const digits_end = digits_begin + digits_len;
0132
0133 static unsigned char const values[] =
0134 { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,10,11,12,13,14,15 };
0135
0136 size_t pos = std::find(digits_begin, digits_end, c) - digits_begin;
0137 if (pos >= digits_len) {
0138 throw_invalid();
0139 }
0140 return values[pos];
0141 }
0142
0143 unsigned char get_value(wchar_t c) const {
0144 static wchar_t const digits_begin[] = L"0123456789abcdefABCDEF";
0145 static size_t digits_len = (sizeof(digits_begin) / sizeof(wchar_t)) - 1;
0146 static wchar_t const*const digits_end = digits_begin + digits_len;
0147
0148 static unsigned char const values[] =
0149 { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,10,11,12,13,14,15 };
0150
0151 size_t pos = std::find(digits_begin, digits_end, c) - digits_begin;
0152 if (pos >= digits_len) {
0153 throw_invalid();
0154 }
0155 return values[pos];
0156 }
0157
0158 bool is_dash(char c) const {
0159 return c == '-';
0160 }
0161
0162 bool is_dash(wchar_t c) const {
0163 return c == L'-';
0164 }
0165
0166
0167 bool is_open_brace(char c) const {
0168 return (c == '{');
0169 }
0170
0171 bool is_open_brace(wchar_t c) const {
0172 return (c == L'{');
0173 }
0174
0175 void check_close_brace(char c, char open_brace) const {
0176 if (open_brace == '{' && c == '}') {
0177
0178 } else {
0179 throw_invalid();
0180 }
0181 }
0182
0183 void check_close_brace(wchar_t c, wchar_t open_brace) const {
0184 if (open_brace == L'{' && c == L'}') {
0185
0186 } else {
0187 throw_invalid();
0188 }
0189 }
0190
0191 BOOST_NORETURN void throw_invalid() const {
0192 BOOST_THROW_EXCEPTION(std::runtime_error("invalid uuid string"));
0193 }
0194 };
0195
0196 }}
0197
0198 #endif
0199