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