libutil++  1.9.3
 All Classes Functions Variables
UUID.cpp
1 /*
2 ** libutil++
3 ** $Id: UUID.cpp 1703 2016-08-16 00:16:40Z sella $
4 ** Copyright (c) 2011-2016 Digital Genesis, LLC. All Rights Reserved.
5 ** Released under the LGPL Version 2.1 License.
6 ** http://www.digitalgenesis.com
7 */
8 
9 static const char rcsid[] __attribute__((used)) = "$Id: UUID.cpp 1703 2016-08-16 00:16:40Z sella $";
10 
11 #include "UUID.h"
12 #include "String.h"
13 
14 #include <string.h>
15 
16 #define BUFFER_SIZE 64
17 #define HASH_ALGO_DJB2
18 
19 using namespace sella::util;
20 
21 UUID::UUID() throw () : scache(), bcache(), bcache_std(false), hcache(0) {
22  uuid_generate(this->uuid);
23 }
24 
25 UUID::UUID(uuid_t &uuid) throw () : scache(), bcache(), bcache_std(false), hcache(0) {
26  uuid_copy(this->uuid, uuid);
27 }
28 
29 UUID::UUID(const std::string &uuid) throw (UUIDException) : scache(), bcache(), bcache_std(false), hcache(0) {
30  if (uuid_parse(uuid.c_str(), this->uuid) != 0) {
31  THROW(UUIDException, "Improperly formatted UUID '%s' provided", uuid.c_str());
32  }
33 }
34 
35 UUID::UUID(const char *uuid) throw (UUIDException) : scache(), bcache(), bcache_std(false), hcache(0) {
36  if (uuid_parse(uuid, this->uuid) != 0) {
37  THROW(UUIDException, "Improperly formatted UUID '%s' provided", uuid);
38  }
39 }
40 
41 UUID::UUID(const UUID &other) :
42  scache(other.scache),
43  bcache(other.bcache),
44  bcache_std(other.bcache_std),
45  hcache(other.hcache)
46 {
47  uuid_copy(this->uuid, other.uuid);
48 }
49 
50 UUID::UUID(const UUID &&other) :
51  scache(std::move(other.scache)),
52  bcache(std::move(other.bcache)),
53  bcache_std(other.bcache_std),
54  hcache(other.hcache)
55 {
56  uuid_copy(this->uuid, other.uuid);
57 }
58 
59 UUID::~UUID() {
60  clear();
61 }
62 
63 UUID& UUID::operator=(const UUID &other) throw () {
64  if (this != &other) {
65  uuid_copy(this->uuid, other.uuid);
66  this->scache = other.scache;
67  this->bcache = other.bcache;
68  this->bcache_std = other.bcache_std;
69  this->hcache = other.hcache;
70  }
71 
72  return *this;
73 }
74 
75 UUID& UUID::operator=(const UUID &&other) throw () {
76  if (this != &other) {
77  uuid_copy(this->uuid, other.uuid);
78  this->scache = std::move(other.scache);
79  this->bcache = std::move(other.bcache);
80  this->bcache_std = other.bcache_std;
81  this->hcache = other.hcache;
82  }
83 
84  return *this;
85 }
86 
87 UUID& UUID::operator=(const std::string &uuid) throw (UUIDException) {
88  this->scache.clear();
89  this->bcache.clear();
90  this->bcache_std = false;
91  this->hcache = 0;
92 
93  if (uuid_parse(uuid.c_str(), this->uuid) != 0) {
94  THROW(UUIDException, "Improperly formatted UUID '%s' provided", uuid.c_str());
95  }
96 
97  return *this;
98 }
99 
100 UUID& UUID::operator=(const char *uuid) throw (UUIDException) {
101  this->scache.clear();
102  this->bcache.clear();
103  this->bcache_std = false;
104  this->hcache = 0;
105 
106  if (uuid_parse(uuid, this->uuid) != 0) {
107  THROW(UUIDException, "Improperly formatted UUID '%s' provided", uuid);
108  }
109 
110  return *this;
111 }
112 
113 bool UUID::operator==(const UUID &other) const throw () {
114  return (uuid_compare(this->uuid, other.uuid) == 0);
115 }
116 
117 bool UUID::operator!=(const UUID &other) const throw () {
118  return !(*this == other);
119 }
120 
121 bool UUID::operator>=(const UUID &other) const throw () {
122  if (*this == other) {
123  return true;
124  }
125 
126  return (*this > other);
127 }
128 
129 bool UUID::operator<=(const UUID &other) const throw () {
130  if (*this == other) {
131  return true;
132  }
133 
134  return (*this < other);
135 }
136 
137 bool UUID::operator>(const UUID &other) const throw () {
138  return uuid_compare(this->uuid, other.uuid) > 0;
139 }
140 
141 bool UUID::operator<(const UUID &other) const throw () {
142  return uuid_compare(this->uuid, other.uuid) < 0;
143 }
144 
145 void UUID::set(uuid_t &uuid) throw () {
146  scache.clear();
147  bcache.clear();
148  bcache_std = false;
149  hcache = 0;
150 
151  uuid_copy(this->uuid, uuid);
152 }
153 
154 const uuid_t& UUID::get(void) const throw () {
155  return this->uuid;
156 }
157 
158 void UUID::generate(void) throw () {
159  this->scache.clear();
160  this->bcache.clear();
161  this->bcache_std = false;
162  this->hcache = 0;
163 
164  uuid_generate(this->uuid);
165 }
166 
167 void UUID::clear(void) throw () {
168  this->scache.clear();
169  this->bcache.clear();
170  this->bcache_std = false;
171  this->hcache = 0;
172 
173  uuid_clear(this->uuid);
174 }
175 
176 bool UUID::isNull(void) const throw () {
177  return uuid_is_null(this->uuid);
178 }
179 
180 void UUID::shrink_to_fit(void) throw () {
181  std::string(scache.begin(), scache.end()).swap(scache);
182  std::string(bcache.begin(), bcache.end()).swap(bcache);
183 }
184 
185 const std::string& UUID::str(void) const throw () {
186  if (scache.empty()) {
187  char buffer[BUFFER_SIZE];
188 
189  uuid_unparse(this->uuid, buffer);
190 
191  scache = buffer;
192  }
193 
194  return scache;
195 }
196 
197 const std::string& UUID::base64(bool standard) const throw () {
198  if (bcache.empty() || bcache_std != standard) {
199  bcache = String::base64_encode((unsigned char const*) this->uuid, sizeof(this->uuid), standard);
200  bcache_std = standard;
201  }
202 
203  return bcache;
204 }
205 
206 const char* UUID::c_str(void) const throw () {
207  return str().c_str();
208 }
209 
210 const char* UUID::c_base64(bool standard) const throw () {
211  return base64(standard).c_str();
212 }
213 
214 const UUID::shared UUID::shared_ptr(void) throw () {
215  return std::make_shared<UUID>();
216 }
217 
218 const UUID::shared UUID::shared_ptr(uuid_t &uuid) throw () {
219  return std::make_shared<UUID>(uuid);
220 }
221 
222 uint32_t UUID::getU32(void) const throw () {
223  const uint32_t *a = (const uint32_t *) this->uuid;
224 
225  return (a[0] ^ a[1] ^ a[2] ^ a[3]);
226 }
227 
228 uint32_t UUID::getHash(void) const throw () {
229  if (hcache != 0) {
230  return hcache;
231  }
232 
233 #if defined HASH_ALGO_INT1 /* Fast. Nibble swap. */
234  uint32_t k = getU32();
235 
236  hcache = ((k & 0xF0F0F0F0) >> 4) | ((k & 0x0F0F0F0F) << 4);
237 #elif defined HASH_ALGO_INT2
238  uint32_t k = getU32();
239 
240  hcache = (k<<16)^(k>>16)^k; /* Fast. Mix by XOR shifting.. */
241 #elif defined HASH_ALGO_INT3 /* Very fast, but not good. */
242  hcache = getU32();
243 #elif defined HASH_ALGO_DJB2 /* This is a Dan Bernstein hash algo. Excellent hash for english characters. */
244  uint32_t i;
245  hcache = 5381;
246 
247  for (i = 0; i < sizeof(uuid_t); ++i) {
248  hcache = ((hcache << 5) + hcache) + uuid[i]; /* h * 33 + i */
249  }
250 #elif defined HASH_ALGO_SDBM /* This is the SDBM hash algo. Good general string hash. */
251  uint32_t i;
252  hcache = 0;
253 
254  for (i = 0; i < sizeof(uuid_t); ++i) {
255  hcache = uuid[i] + (hcache << 6) + (hcache << 16) - hcache;
256  }
257 #else
258  #error No hash algo selected.
259 #endif
260 
261  return hcache;
262 }
263 
264 /*
265 ** vim: noet ts=3 sw=3
266 */