PseudoUuid.cpp

Go to the documentation of this file.
00001 /*
00002 // $Id: //open/dev/fennel/common/PseudoUuid.cpp#13 $
00003 // Fennel is a library of data storage and processing components.
00004 // Copyright (C) 2005-2009 The Eigenbase Project
00005 // Copyright (C) 2005-2009 SQLstream, Inc.
00006 // Copyright (C) 2005-2009 LucidEra, Inc.
00007 // Portions Copyright (C) 1999-2009 John V. Sichi
00008 //
00009 // This program is free software; you can redistribute it and/or modify it
00010 // under the terms of the GNU General Public License as published by the Free
00011 // Software Foundation; either version 2 of the License, or (at your option)
00012 // any later version approved by The Eigenbase Project.
00013 //
00014 // This program is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 // GNU General Public License for more details.
00018 //
00019 // You should have received a copy of the GNU General Public License
00020 // along with this program; if not, write to the Free Software
00021 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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     // REVIEW: SWZ: 9/22/2006: Consider using a different mode.  V1 seems
00063     // weak, but v3 and v5 seem reasonable.  They require arguments, however.
00064     // Also, uuid_make never returns error for V4, but might for others.
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     // NOTE: libuuid has either uuid_unparse or uuid_export (depending on
00142     // the library's version).  Those two methods produce different output
00143     // for the same UUID.
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     // NOTE: libuuid has either uuid_unparse or uuid_export (depending on
00160     // the library's version).  Those two methods produce different output
00161     // for the same UUID
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         // Make sure both characters were correctly converted
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 // End PseudoUuid.cpp

Generated on Mon Jun 22 04:00:18 2009 for Fennel by  doxygen 1.5.1