]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/uuid/string_generator.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / uuid / string_generator.hpp
1 // Boost string_generator.hpp header file ----------------------------------------------//
2
3 // Copyright 2010 Andy Tompkins.
4 // Distributed under the Boost Software License, Version 1.0. (See
5 // accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7
8 #ifndef BOOST_UUID_STRING_GENERATOR_HPP
9 #define BOOST_UUID_STRING_GENERATOR_HPP
10
11 #include <boost/uuid/uuid.hpp>
12 #include <string>
13 #include <cstring> // for strlen, wcslen
14 #include <iterator>
15 #include <algorithm> // for find
16 #include <stdexcept>
17 #include <boost/throw_exception.hpp>
18
19 #ifdef BOOST_NO_STDC_NAMESPACE
20 namespace std {
21 using ::strlen;
22 using ::wcslen;
23 } //namespace std
24 #endif //BOOST_NO_STDC_NAMESPACE
25
26 namespace boost {
27 namespace uuids {
28
29 // generate a uuid from a string
30 // lexical_cast works fine using uuid_io.hpp
31 // but this generator should accept more forms
32 // and be more efficient
33 // would like to accept the following forms:
34 // 0123456789abcdef0123456789abcdef
35 // 01234567-89ab-cdef-0123-456789abcdef
36 // {01234567-89ab-cdef-0123-456789abcdef}
37 // {0123456789abcdef0123456789abcdef}
38 // others?
39 struct string_generator {
40 typedef uuid result_type;
41
42 template <typename ch, typename char_traits, typename alloc>
43 uuid operator()(std::basic_string<ch, char_traits, alloc> const& s) const {
44 return operator()(s.begin(), s.end());
45 }
46
47 uuid operator()(char const*const s) const {
48 return operator()(s, s+std::strlen(s));
49 }
50
51 uuid operator()(wchar_t const*const s) const {
52 return operator()(s, s+std::wcslen(s));
53 }
54
55 template <typename CharIterator>
56 uuid operator()(CharIterator begin, CharIterator end) const
57 {
58 typedef typename std::iterator_traits<CharIterator>::value_type char_type;
59
60 // check open brace
61 char_type c = get_next_char(begin, end);
62 bool has_open_brace = is_open_brace(c);
63 char_type open_brace_char = c;
64 if (has_open_brace) {
65 c = get_next_char(begin, end);
66 }
67
68 bool has_dashes = false;
69
70 uuid u;
71 int i=0;
72 for (uuid::iterator it_byte=u.begin(); it_byte!=u.end(); ++it_byte, ++i) {
73 if (it_byte != u.begin()) {
74 c = get_next_char(begin, end);
75 }
76
77 if (i == 4) {
78 has_dashes = is_dash(c);
79 if (has_dashes) {
80 c = get_next_char(begin, end);
81 }
82 }
83
84 // if there are dashes, they must be in every slot
85 else if (i == 6 || i == 8 || i == 10) {
86 if (has_dashes == true) {
87 if (is_dash(c)) {
88 c = get_next_char(begin, end);
89 } else {
90 throw_invalid();
91 }
92 }
93 }
94
95
96 *it_byte = get_value(c);
97
98 c = get_next_char(begin, end);
99 *it_byte <<= 4;
100 *it_byte |= get_value(c);
101 }
102
103 // check close brace
104 if (has_open_brace) {
105 c = get_next_char(begin, end);
106 check_close_brace(c, open_brace_char);
107 }
108
109 // check end of string - any additional data is an invalid uuid
110 if (begin != end) {
111 throw_invalid();
112 }
113
114 return u;
115 }
116
117 private:
118 template <typename CharIterator>
119 typename std::iterator_traits<CharIterator>::value_type
120 get_next_char(CharIterator& begin, CharIterator end) const {
121 if (begin == end) {
122 throw_invalid();
123 }
124 return *begin++;
125 }
126
127 unsigned char get_value(char c) const {
128 static char const digits_begin[] = "0123456789abcdefABCDEF";
129 static size_t digits_len = (sizeof(digits_begin) / sizeof(char)) - 1;
130 static char const*const digits_end = digits_begin + digits_len;
131
132 static unsigned char const values[] =
133 { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,10,11,12,13,14,15 };
134
135 size_t pos = std::find(digits_begin, digits_end, c) - digits_begin;
136 if (pos >= digits_len) {
137 throw_invalid();
138 }
139 return values[pos];
140 }
141
142 unsigned char get_value(wchar_t c) const {
143 static wchar_t const digits_begin[] = L"0123456789abcdefABCDEF";
144 static size_t digits_len = (sizeof(digits_begin) / sizeof(wchar_t)) - 1;
145 static wchar_t const*const digits_end = digits_begin + digits_len;
146
147 static unsigned char const values[] =
148 { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,10,11,12,13,14,15 };
149
150 size_t pos = std::find(digits_begin, digits_end, c) - digits_begin;
151 if (pos >= digits_len) {
152 throw_invalid();
153 }
154 return values[pos];
155 }
156
157 bool is_dash(char c) const {
158 return c == '-';
159 }
160
161 bool is_dash(wchar_t c) const {
162 return c == L'-';
163 }
164
165 // return closing brace
166 bool is_open_brace(char c) const {
167 return (c == '{');
168 }
169
170 bool is_open_brace(wchar_t c) const {
171 return (c == L'{');
172 }
173
174 void check_close_brace(char c, char open_brace) const {
175 if (open_brace == '{' && c == '}') {
176 //great
177 } else {
178 throw_invalid();
179 }
180 }
181
182 void check_close_brace(wchar_t c, wchar_t open_brace) const {
183 if (open_brace == L'{' && c == L'}') {
184 // great
185 } else {
186 throw_invalid();
187 }
188 }
189
190 void throw_invalid() const {
191 BOOST_THROW_EXCEPTION(std::runtime_error("invalid uuid string"));
192 }
193 };
194
195 }} // namespace boost::uuids
196
197 #endif //BOOST_UUID_STRING_GENERATOR_HPP
198