00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "fennel/common/CommonPreamble.h"
00025 #include "fennel/common/PseudoUuid.h"
00026
00027 #ifdef __MSVC__
00028 #include <windows.h>
00029 #include <rpcdce.h>
00030 #endif
00031
00032 #include <iomanip>
00033 #include <sstream>
00034
00035 using namespace std;
00036
00037 FENNEL_BEGIN_CPPFILE("$Id: //open/dev/fennel/common/PseudoUuid.cpp#13 $");
00038
00039 PseudoUuid::PseudoUuid()
00040 {
00041 memset(data, 0, sizeof(data));
00042 }
00043
00044 PseudoUuid::PseudoUuid(string uuid)
00045 {
00046 parse(uuid);
00047 }
00048
00049 PseudoUuid::~PseudoUuid()
00050 {
00051 memset(data, 0, sizeof(data));
00052 }
00053
00054 void PseudoUuid::generate()
00055 {
00056 #ifdef FENNEL_UUID_REAL_NEW
00057 uuid_t *apiData;
00058
00059 uuid_rc_t result = uuid_create(&apiData);
00060 assert(result == UUID_RC_OK);
00061
00062
00063
00064
00065 result = uuid_make(apiData, UUID_MAKE_V4);
00066 assert(result == UUID_RC_OK);
00067
00068 size_t len = UUID_LENGTH;
00069 result =
00070 uuid_export(
00071 apiData,
00072 UUID_FMT_BIN,
00073 reinterpret_cast<void **>(&data),
00074 &len);
00075 assert(result == UUID_RC_OK);
00076
00077 result = uuid_destroy(apiData);
00078 assert(result == UUID_RC_OK);
00079 #else
00080
00081 #ifdef FENNEL_UUID_REAL
00082
00083 uuid_generate(data);
00084
00085 #else
00086
00087 memset(&data,0,sizeof(data));
00088 #ifdef __MSVC__
00089 assert(sizeof(data) == sizeof(UUID));
00090 UuidCreate((UUID *) data);
00091 #else
00092 int x = rand();
00093 assert(sizeof(x) <= sizeof(data));
00094 memcpy(&data,&x,sizeof(x));
00095 #endif
00096
00097 #endif
00098
00099 #endif
00100 }
00101
00102 void PseudoUuid::generateInvalid()
00103 {
00104 memset(data, 0xFF, sizeof(data));
00105 }
00106
00107 bool PseudoUuid::operator == (PseudoUuid const &other) const
00108 {
00109 return (memcmp(data,other.data,sizeof(data)) == 0);
00110 }
00111
00112
00113
00114 uint8_t PseudoUuid::getByte(int index) const
00115 {
00116 assert(index < sizeof(data));
00117
00118 return data[index];
00119 }
00120
00121 const uint8_t *PseudoUuid::getBytes() const
00122 {
00123 #ifdef FENNEL_UUID_REAL
00124 return reinterpret_cast<const uint8_t *>(&data);
00125 #else
00126 return data;
00127 #endif
00128 }
00129
00130 int PseudoUuid::hashCode() const
00131 {
00132 return
00133 ((int)(data[0] ^ data[4] ^ data[8] ^ data[12]) & 0xFF) << 24 |
00134 ((int)(data[1] ^ data[5] ^ data[9] ^ data[13]) & 0xFF) << 16 |
00135 ((int)(data[2] ^ data[6] ^ data[10] ^ data[14]) & 0xFF) << 8 |
00136 ((int)(data[3] ^ data[7] ^ data[11] ^ data[15]) & 0xFF);
00137 }
00138
00139 string PseudoUuid::toString() const
00140 {
00141
00142
00143
00144 ostringstream ostr;
00145
00146 for (int i = 0; i < sizeof(data); i++) {
00147 if (i == 4 || i == 6 || i == 8 || i == 10) {
00148 ostr << "-";
00149 }
00150
00151 ostr << hex << setw(2) << setfill('0') << (int) (data[i] & 0xFF);
00152 }
00153
00154 return ostr.str();
00155 }
00156
00157 void PseudoUuid::parse(string uuid) throw (FennelExcn)
00158 {
00159
00160
00161
00162 uint8_t id[UUID_LENGTH];
00163 if (uuid.length() != 36) {
00164 ostringstream errstr;
00165 errstr << "Invalid UUID format: length " << uuid.length()
00166 << ", expected 36";
00167 throw FennelExcn(errstr.str());
00168 }
00169
00170 istringstream istr(uuid);
00171 char hexchars[3];
00172 char *endptr;
00173 int value;
00174 memset(hexchars, 0, sizeof(hexchars));
00175 istr >> noskipws;
00176 for (int i = 0; i < sizeof(id); i++) {
00177 if (i == 4 || i == 6 || i == 8 || i == 10) {
00178 char ch;
00179 istr >> ch;
00180 if (ch != '-') {
00181 throw FennelExcn("Invalid UUID format: '-' expected");
00182 }
00183 }
00184 istr >> hexchars[0];
00185 istr >> hexchars[1];
00186 value = strtol(hexchars, &endptr, 16);
00187
00188 if (endptr != hexchars + 2) {
00189 throw FennelExcn("Invalid UUID format: hex digits expected");
00190 }
00191 id[i] = (uint8_t) value;
00192 }
00193 memcpy(data, id, sizeof(data));
00194 }
00195
00196 PseudoUuidGenerator::~PseudoUuidGenerator()
00197 {
00198 }
00199
00200 void PseudoUuidGenerator::generateUuid(PseudoUuid &pseudoUuid)
00201 {
00202 pseudoUuid.generate();
00203 }
00204
00205 FENNEL_END_CPPFILE("$Id: //open/dev/fennel/common/PseudoUuid.cpp#13 $");
00206
00207