00001
00002
00003
00004
00005
00006
00007
00008
00009 static const char rcsid[] __attribute__((used)) = "$Id: UUID.cpp 1197 2014-10-14 22:26:11Z sella $";
00010
00011 #include "UUID.h"
00012
00013 #include <string.h>
00014
00015 #define BUFFER_SIZE 64
00016 #define HASH_ALGO_DJB2
00017
00018 using namespace sella::util;
00019
00020 UUID::UUID() throw () : scache(), hcache(0) {
00021 uuid_generate(this->uuid);
00022 }
00023
00024 UUID::UUID(uuid_t &uuid) throw () : scache(), hcache(0) {
00025 uuid_copy(this->uuid, uuid);
00026 }
00027
00028 UUID::UUID(const std::string &uuid) throw (UUIDException) : scache(), hcache(0) {
00029 if (uuid_parse(uuid.c_str(), this->uuid) != 0) {
00030 THROW(UUIDException, "Improperly formatted UUID '%s' provided", uuid.c_str());
00031 }
00032 }
00033
00034 UUID::UUID(const char *uuid) throw (UUIDException) : scache(), hcache(0) {
00035 if (uuid_parse(uuid, this->uuid) != 0) {
00036 THROW(UUIDException, "Improperly formatted UUID '%s' provided", uuid);
00037 }
00038 }
00039
00040 UUID::UUID(const UUID &other) :
00041 scache(other.scache),
00042 hcache(other.hcache)
00043 {
00044 uuid_copy(this->uuid, other.uuid);
00045 }
00046
00047 UUID::UUID(const UUID &&other) :
00048 scache(std::move(other.scache)),
00049 hcache(other.hcache)
00050 {
00051 uuid_copy(this->uuid, other.uuid);
00052 }
00053
00054 UUID::~UUID() {
00055 clear();
00056 }
00057
00058 UUID& UUID::operator=(const UUID &other) throw () {
00059 if (this != &other) {
00060 uuid_copy(this->uuid, other.uuid);
00061 this->scache = other.scache;
00062 this->hcache = other.hcache;
00063 }
00064
00065 return *this;
00066 }
00067
00068 UUID& UUID::operator=(const UUID &&other) throw () {
00069 if (this != &other) {
00070 uuid_copy(this->uuid, other.uuid);
00071 this->scache = std::move(other.scache);
00072 this->hcache = other.hcache;
00073 }
00074
00075 return *this;
00076 }
00077
00078 UUID& UUID::operator=(const std::string &uuid) throw (UUIDException) {
00079 this->scache.clear();
00080 this->hcache = 0;
00081
00082 if (uuid_parse(uuid.c_str(), this->uuid) != 0) {
00083 THROW(UUIDException, "Improperly formatted UUID '%s' provided", uuid.c_str());
00084 }
00085
00086 return *this;
00087 }
00088
00089 UUID& UUID::operator=(const char *uuid) throw (UUIDException) {
00090 this->scache.clear();
00091 this->hcache = 0;
00092
00093 if (uuid_parse(uuid, this->uuid) != 0) {
00094 THROW(UUIDException, "Improperly formatted UUID '%s' provided", uuid);
00095 }
00096
00097 return *this;
00098 }
00099
00100 bool UUID::operator==(const UUID &other) const throw () {
00101 return (uuid_compare(this->uuid, other.uuid) == 0);
00102 }
00103
00104 bool UUID::operator!=(const UUID &other) const throw () {
00105 return !(*this == other);
00106 }
00107
00108 bool UUID::operator>=(const UUID &other) const throw () {
00109 if (*this == other) {
00110 return true;
00111 }
00112
00113 return (*this > other);
00114 }
00115
00116 bool UUID::operator<=(const UUID &other) const throw () {
00117 if (*this == other) {
00118 return true;
00119 }
00120
00121 return (*this < other);
00122 }
00123
00124 bool UUID::operator>(const UUID &other) const throw () {
00125 return uuid_compare(this->uuid, other.uuid) > 0;
00126 }
00127
00128 bool UUID::operator<(const UUID &other) const throw () {
00129 return uuid_compare(this->uuid, other.uuid) < 0;
00130 }
00131
00132 void UUID::set(uuid_t &uuid) throw () {
00133 scache.clear();
00134 hcache = 0;
00135
00136 uuid_copy(this->uuid, uuid);
00137 }
00138
00139 const uuid_t& UUID::get(void) const throw () {
00140 return this->uuid;
00141 }
00142
00143 void UUID::generate(void) throw () {
00144 this->scache.clear();
00145 this->hcache = 0;
00146
00147 uuid_generate(this->uuid);
00148 }
00149
00150 void UUID::clear(void) throw () {
00151 this->scache.clear();
00152 this->hcache = 0;
00153
00154 uuid_clear(this->uuid);
00155 }
00156
00157 bool UUID::isNull(void) const throw () {
00158 return uuid_is_null(this->uuid);
00159 }
00160
00161 void UUID::shrink_to_fit(void) throw () {
00162 std::string(scache.begin(), scache.end()).swap(scache);
00163 }
00164
00165 const std::string& UUID::str(void) const throw () {
00166 char buffer[BUFFER_SIZE];
00167
00168 if (scache.empty()) {
00169 uuid_unparse(this->uuid, buffer);
00170
00171 scache = buffer;
00172 }
00173
00174 return scache;
00175 }
00176
00177 const char* UUID::c_str(void) const throw () {
00178 return str().c_str();
00179 }
00180
00181 const UUID::shared UUID::shared_ptr(void) throw () {
00182 return std::make_shared<UUID>();
00183 }
00184
00185 const UUID::shared UUID::shared_ptr(uuid_t &uuid) throw () {
00186 return std::make_shared<UUID>(uuid);
00187 }
00188
00189 uint32_t UUID::getU32(void) const throw () {
00190 const uint32_t *a = (const uint32_t *) this->uuid;
00191
00192 return (a[0] ^ a[1] ^ a[2] ^ a[3]);
00193 }
00194
00195 uint32_t UUID::getHash(void) const throw () {
00196 if (hcache != 0) {
00197 return hcache;
00198 }
00199
00200 #if defined HASH_ALGO_INT1
00201 uint32_t k = getU32();
00202
00203 hcache = ((k & 0xF0F0F0F0) >> 4) | ((k & 0x0F0F0F0F) << 4);
00204 #elif defined HASH_ALGO_INT2
00205 uint32_t k = getU32();
00206
00207 hcache = (k<<16)^(k>>16)^k;
00208 #elif defined HASH_ALGO_INT3
00209 hcache = getU32();
00210 #elif defined HASH_ALGO_DJB2
00211 uint32_t i;
00212 hcache = 5381;
00213
00214 for (i = 0; i < sizeof(uuid_t); ++i) {
00215 hcache = ((hcache << 5) + hcache) + uuid[i];
00216 }
00217 #elif defined HASH_ALGO_SDBM
00218 uint32_t i;
00219 hcache = 0;
00220
00221 for (i = 0; i < sizeof(uuid_t); ++i) {
00222 hcache = uuid[i] + (hcache << 6) + (hcache << 16) - hcache;
00223 }
00224 #else
00225 #error No hash algo selected.
00226 #endif
00227
00228 return hcache;
00229 }
00230
00231
00232
00233