File Coverage

/usr/local/lib/perl5/site_perl/5.26.1/x86_64-linux/CPP/Boost/Mini.x/i/boost/uuid/string_generator.hpp
Criterion Covered Total %
statement 39 52 75.0
branch 29 60 48.3
condition n/a
subroutine n/a
pod n/a
total 68 112 60.7


line stmt bran cond sub pod time code
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
12             #include
13             #include // for strlen, wcslen
14             #include
15             #include // for find
16             #include
17             #include
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
43 2           uuid operator()(std::basic_string const& s) const {
44 2           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
56 2           uuid operator()(CharIterator begin, CharIterator end) const
57             {
58             typedef typename std::iterator_traits::value_type char_type;
59              
60             // check open brace
61 2 50         char_type c = get_next_char(begin, end);
62 2           bool has_open_brace = is_open_brace(c);
63 2           char_type open_brace_char = c;
64 2 50         if (has_open_brace) {
65 0 0         c = get_next_char(begin, end);
66             }
67              
68 2           bool has_dashes = false;
69              
70             uuid u;
71 2           int i=0;
72 18 100         for (uuid::iterator it_byte=u.begin(); it_byte!=u.end(); ++it_byte, ++i) {
73 17 100         if (it_byte != u.begin()) {
74 15 50         c = get_next_char(begin, end);
75             }
76            
77 17 100         if (i == 4) {
78 1           has_dashes = is_dash(c);
79 1 50         if (has_dashes) {
80 0 0         c = get_next_char(begin, end);
81             }
82             }
83            
84             // if there are dashes, they must be in every slot
85 16 100         else if (i == 6 || i == 8 || i == 10) {
    100          
    100          
86 3 50         if (has_dashes == true) {
87 0 0         if (is_dash(c)) {
88 0 0         c = get_next_char(begin, end);
89             } else {
90 0 0         throw_invalid();
91             }
92             }
93             }
94            
95              
96 17 100         *it_byte = get_value(c);
97              
98 16 50         c = get_next_char(begin, end);
99 16           *it_byte <<= 4;
100 16 50         *it_byte |= get_value(c);
101             }
102              
103             // check close brace
104 1 50         if (has_open_brace) {
105 0 0         c = get_next_char(begin, end);
106 0 0         check_close_brace(c, open_brace_char);
107             }
108              
109             // check end of string - any additional data is an invalid uuid
110 1 50         if (begin != end) {
111 0 0         throw_invalid();
112             }
113            
114 1           return u;
115             }
116            
117             private:
118             template
119             typename std::iterator_traits::value_type
120 33           get_next_char(CharIterator& begin, CharIterator end) const {
121 33 50         if (begin == end) {
122 0           throw_invalid();
123             }
124 33           return *begin++;
125             }
126              
127 33           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 33 100         static char const*const digits_end = digits_begin + digits_len;
    50          
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 33           size_t pos = std::find(digits_begin, digits_end, c) - digits_begin;
136 33 100         if (pos >= digits_len) {
137 1           throw_invalid();
138             }
139 32           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 1           bool is_dash(char c) const {
158 1           return c == '-';
159             }
160            
161             bool is_dash(wchar_t c) const {
162             return c == L'-';
163             }
164            
165             // return closing brace
166 2           bool is_open_brace(char c) const {
167 2           return (c == '{');
168             }
169            
170             bool is_open_brace(wchar_t c) const {
171             return (c == L'{');
172             }
173            
174 0           void check_close_brace(char c, char open_brace) const {
175 0 0         if (open_brace == '{' && c == '}') {
    0          
176             //great
177             } else {
178 0           throw_invalid();
179             }
180 0           }
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 1           void throw_invalid() const {
191 1           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