00001
00002
00003 #include "ace/UUID.h"
00004 #include "ace/Guard_T.h"
00005
00006 #if !defined (__ACE_INLINE__)
00007 #include "ace/UUID.inl"
00008 #endif
00009
00010 #include "ace/Log_Msg.h"
00011 #include "ace/OS_NS_stdio.h"
00012 #include "ace/OS_NS_string.h"
00013 #include "ace/OS_NS_sys_time.h"
00014 #include "ace/OS_NS_netdb.h"
00015 #include "ace/OS_NS_unistd.h"
00016 #include "ace/ACE.h"
00017
00018 ACE_RCSID (ace,
00019 UUID,
00020 "UUID.cpp,v 1.31 2006/04/19 19:13:09 jwillemsen Exp")
00021
00022
00023 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00024
00025 namespace ACE_Utils
00026 {
00027
00028 UUID_node::UUID_node (void)
00029 {
00030 for (int i = 0; i < UUID_node::NODE_ID_SIZE; ++i)
00031 {
00032 nodeID_[i] = 0;
00033 }
00034 }
00035
00036 UUID_node::NodeID&
00037 UUID_node::nodeID (void)
00038 {
00039 return nodeID_;
00040 }
00041
00042 void
00043 UUID_node::nodeID (NodeID& nodeID)
00044 {
00045 for (int i = 0; i < UUID_node::NODE_ID_SIZE; ++i)
00046 {
00047 nodeID_[i] = nodeID[i];
00048 }
00049 }
00050
00051 UUID UUID::NIL_UUID;
00052
00053
00054
00055 UUID::UUID(void)
00056 : timeLow_ (0),
00057 timeMid_ (0),
00058 timeHiAndVersion_ (0),
00059 clockSeqHiAndReserved_ (0),
00060 clockSeqLow_ (0),
00061 as_string_ (0)
00062 {
00063 ACE_NEW (node_,
00064 UUID_node);
00065
00066 node_release_ = 1;
00067 }
00068
00069
00070 UUID::UUID (const ACE_CString& uuid_string)
00071 : timeLow_ (0),
00072 timeMid_ (0),
00073 timeHiAndVersion_ (0),
00074 clockSeqHiAndReserved_ (0),
00075 clockSeqLow_ (0),
00076 as_string_ (0)
00077 {
00078 ACE_NEW (node_,
00079 UUID_node);
00080
00081 node_release_ = 1;
00082
00083
00084 if (uuid_string.length() < NIL_UUID.to_string ()->length ())
00085 {
00086 ACE_DEBUG ((LM_DEBUG,
00087 "%N ACE_UUID::UUID - "
00088 "IllegalArgument(incorrect string length)\n"));
00089 return;
00090 }
00091
00092
00093 if (uuid_string == *NIL_UUID.to_string ())
00094 {
00095 bool copy_constructor_not_supported = false;
00096 ACE_ASSERT (copy_constructor_not_supported);
00097
00098 ACE_UNUSED_ARG (copy_constructor_not_supported);
00099 return;
00100 }
00101
00102 unsigned int timeLow;
00103 unsigned int timeMid;
00104 unsigned int timeHiAndVersion;
00105 unsigned int clockSeqHiAndReserved;
00106 unsigned int clockSeqLow;
00107 unsigned int node [UUID_node::NODE_ID_SIZE];
00108 char thr_pid_buf [BUFSIZ];
00109
00110 if (uuid_string.length() == NIL_UUID.to_string()->length())
00111 {
00112
00113
00114
00115
00116
00117 const int nScanned =
00118 ::sscanf(uuid_string.c_str(),
00119 "%8x-%4x-%4x-%2x%2x-%2x%2x%2x%2x%2x%2x",
00120 &timeLow,
00121 &timeMid,
00122 &timeHiAndVersion,
00123 &clockSeqHiAndReserved,
00124 &clockSeqLow,
00125 &node[0],
00126 &node[1],
00127 &node[2],
00128 &node[3],
00129 &node[4],
00130 &node[5]
00131 );
00132
00133 if (nScanned != 11)
00134 {
00135 ACE_DEBUG ((LM_DEBUG,
00136 "UUID::UUID - "
00137 "IllegalArgument(invalid string representation)\n"));
00138 return;
00139 }
00140 }
00141 else
00142 {
00143 const int nScanned =
00144 ::sscanf (uuid_string.c_str(),
00145 "%8x-%4x-%4x-%2x%2x-%2x%2x%2x%2x%2x%2x-%s",
00146 &timeLow,
00147 &timeMid,
00148 &timeHiAndVersion,
00149 &clockSeqHiAndReserved,
00150 &clockSeqLow,
00151 &node[0],
00152 &node[1],
00153 &node[2],
00154 &node[3],
00155 &node[4],
00156 &node[5],
00157 thr_pid_buf
00158 );
00159
00160 if (nScanned != 12)
00161 {
00162 ACE_DEBUG ((LM_DEBUG,
00163 "ACE_UUID::ACE_UUID - "
00164 "IllegalArgument(invalid string representation)\n"));
00165 return;
00166 }
00167 }
00168
00169 this->timeLow_ = static_cast<ACE_UINT32> (timeLow);
00170 this->timeMid_ = static_cast<ACE_UINT16> (timeMid);
00171 this->timeHiAndVersion_ = static_cast<ACE_UINT16> (timeHiAndVersion);
00172 this->clockSeqHiAndReserved_ = static_cast<u_char> (clockSeqHiAndReserved);
00173 this->clockSeqLow_ = static_cast<u_char> (clockSeqLow);
00174
00175 UUID_node::NodeID nodeID;
00176 for (int i = 0; i < UUID_node::NODE_ID_SIZE; ++i)
00177 nodeID [i] = static_cast<u_char> (node[i]);
00178
00179 this->node_->nodeID (nodeID);
00180
00181
00182 if ((this->clockSeqHiAndReserved_ & 0xc0) != 0x80 && (this->clockSeqHiAndReserved_ & 0xc0) != 0xc0)
00183 {
00184 ACE_DEBUG ((LM_DEBUG,
00185 "ACE_UUID_Impl::ACE_UUID_Impl - "
00186 "IllegalArgument(unsupported variant)\n"));
00187 return;
00188 }
00189
00190
00191 ACE_UINT16 V1 = this->timeHiAndVersion_;
00192
00193 if ((V1 & 0xF000) != 0x1000 &&
00194 (V1 & 0xF000) != 0x3000 &&
00195 (V1 & 0xF000) != 0x4000)
00196 {
00197 ACE_DEBUG ((LM_DEBUG,
00198 "ACE_UUID::ACE_UUID - "
00199 "IllegalArgument(unsupported version)\n"));
00200 return;
00201 }
00202 if ((this->clockSeqHiAndReserved_ & 0xc0) == 0xc0)
00203 {
00204 if (uuid_string.length() == NIL_UUID.to_string()->length())
00205 {
00206 ACE_DEBUG ((LM_DEBUG,
00207 "ACE_UUID::ACE_UUID - "
00208 "IllegalArgument (Missing Thread and Process Id)\n"));
00209 return;
00210 }
00211 ACE_CString thr_pid_str (thr_pid_buf);
00212 ssize_t pos = thr_pid_str.find ('-');
00213 if (pos == -1)
00214 ACE_DEBUG ((LM_DEBUG,
00215 "ACE_UUID::ACE_UUID - "
00216 "IllegalArgument (Thread and Process Id format incorrect)\n"));
00217
00218 this->thr_id_ = thr_pid_str.substr (0, pos);
00219 this->pid_ = thr_pid_str.substr (pos+1, thr_pid_str.length ()-pos-1);
00220 }
00221 }
00222
00223 UUID::~UUID (void)
00224 {
00225 if (node_release_)
00226 delete node_;
00227
00228 if (as_string_ != 0)
00229 delete as_string_;
00230 }
00231
00232 const ACE_CString*
00233 UUID::to_string (void)
00234 {
00235
00236 if (as_string_ == 0)
00237 {
00238
00239
00240 size_t UUID_STRING_LENGTH = 36 + thr_id_.length () + pid_.length ();
00241 char *buf;
00242
00243 if ((thr_id_.length () != 0) && (pid_.length () != 0))
00244 {
00245 UUID_STRING_LENGTH += 2;
00246 ACE_NEW_RETURN (buf,
00247 char[UUID_STRING_LENGTH + 1],
00248 0);
00249
00250 ACE_OS::sprintf(buf,
00251 "%8.8x-%4.4x-%4.4x-%2.2x%2.2x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x-%s-%s",
00252 this->timeLow_,
00253 this->timeMid_,
00254 this->timeHiAndVersion_,
00255 this->clockSeqHiAndReserved_,
00256 this->clockSeqLow_,
00257 (this->node_->nodeID ()) [0],
00258 (this->node_->nodeID ()) [1],
00259 (this->node_->nodeID ()) [2],
00260 (this->node_->nodeID ()) [3],
00261 (this->node_->nodeID ()) [4],
00262 (this->node_->nodeID ()) [5],
00263 thr_id_.c_str (),
00264 pid_.c_str ()
00265 );
00266 }
00267 else
00268 {
00269 ACE_NEW_RETURN (buf,
00270 char[UUID_STRING_LENGTH + 1],
00271 0);
00272
00273 ACE_OS::sprintf (buf,
00274 "%8.8x-%4.4x-%4.4x-%2.2x%2.2x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x",
00275 this->timeLow_,
00276 this->timeMid_,
00277 this->timeHiAndVersion_,
00278 this->clockSeqHiAndReserved_,
00279 this->clockSeqLow_,
00280 (this->node_->nodeID ()) [0],
00281 (this->node_->nodeID ()) [1],
00282 (this->node_->nodeID ()) [2],
00283 (this->node_->nodeID ()) [3],
00284 (this->node_->nodeID ()) [4],
00285 (this->node_->nodeID ()) [5]
00286 );
00287 }
00288
00289 ACE_NEW_RETURN (this->as_string_,
00290 ACE_CString (buf, UUID_STRING_LENGTH),
00291 0);
00292 delete [] buf;
00293 }
00294
00295 return as_string_;
00296 }
00297
00298 UUID_Generator::UUID_Generator ()
00299 : timeLast_ (0)
00300 {
00301 ACE_NEW (lock_,
00302 ACE_SYNCH_MUTEX);
00303 destroy_lock_ = 1;
00304 }
00305
00306 UUID_Generator::~UUID_Generator()
00307 {
00308 if (destroy_lock_)
00309 delete lock_;
00310 }
00311
00312 void
00313 UUID_Generator::init (void)
00314 {
00315 ACE_OS::macaddr_node_t macaddress;
00316 int result =
00317 ACE_OS::getmacaddress (&macaddress);
00318
00319 UUID_node::NodeID nodeID;
00320 if (result != -1)
00321 {
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331 ACE_OS::memcpy (&nodeID,
00332 macaddress.node,
00333 sizeof (nodeID));
00334 }
00335 else
00336 {
00337 nodeID [0] = static_cast<u_char> (ACE_OS::rand());
00338 nodeID [1] = static_cast<u_char> (ACE_OS::rand());
00339 nodeID [2] = static_cast<u_char> (ACE_OS::rand());
00340 nodeID [3] = static_cast<u_char> (ACE_OS::rand());
00341 nodeID [4] = static_cast<u_char> (ACE_OS::rand());
00342 nodeID [5] = static_cast<u_char> (ACE_OS::rand());
00343 }
00344
00345 this->get_timestamp (timeLast_);
00346
00347 {
00348 ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, *lock_);
00349 uuid_state_.timestamp = timeLast_;
00350 uuid_state_.node.nodeID (nodeID);
00351 }
00352 }
00353
00354
00355 void
00356 UUID_Generator::generateUUID (UUID& uuid,ACE_UINT16 version, u_char variant)
00357 {
00358 UUID_time timestamp;
00359 this->get_timestamp (timestamp);
00360
00361
00362
00363 uuid.timeLow (static_cast<ACE_UINT32> (timestamp & 0xFFFFFFFF));
00364 uuid.timeMid (static_cast<ACE_UINT16> ((timestamp >> 32) & 0xFFFF));
00365
00366
00367 ACE_UINT16 tHAV = static_cast<ACE_UINT16> ((timestamp >> 48) & 0xFFFF);
00368 tHAV |= (version << 12);
00369 uuid.timeHiAndVersion (tHAV);
00370
00371 u_char cseqHAV;
00372 {
00373 ACE_GUARD (ACE_SYNCH_MUTEX, mon, *lock_);
00374 uuid.clockSeqLow (static_cast<u_char> (uuid_state_.clockSequence & 0xFF));
00375 cseqHAV = static_cast<u_char> ((uuid_state_.clockSequence & 0x3f00) >> 8);
00376 uuid_state_.timestamp = timestamp;
00377 }
00378
00379 cseqHAV |= variant;
00380 uuid.clockSeqHiAndReserved (cseqHAV);
00381 uuid.node (&(uuid_state_.node));
00382
00383 if (variant == 0xc0)
00384 {
00385 ACE_Thread_ID thread_id;
00386 char buf [BUFSIZ];
00387 thread_id.to_string (buf);
00388 uuid.thr_id (buf);
00389
00390 ACE_OS::sprintf (buf,
00391 "%d",
00392 static_cast<int> (ACE_OS::getpid ()));
00393 uuid.pid (buf);
00394 }
00395 }
00396
00397 UUID*
00398 UUID_Generator::generateUUID (ACE_UINT16 version, u_char variant)
00399 {
00400 UUID* uuid;
00401 ACE_NEW_RETURN (uuid,
00402 UUID,
00403 0);
00404
00405 this->generateUUID (*uuid, version, variant);
00406 return uuid;
00407 }
00408
00409
00410
00411 void
00412 UUID_Generator::get_timestamp (UUID_time& timestamp)
00413 {
00414 ACE_GUARD (ACE_SYNCH_MUTEX, mon, *lock_);
00415
00416 this->get_systemtime(timestamp);
00417
00418
00419
00420 if (timestamp <= timeLast_)
00421 uuid_state_.clockSequence = static_cast<u_char> ((uuid_state_.clockSequence + 1) & ACE_UUID_CLOCK_SEQ_MASK);
00422
00423
00424
00425 else if (timestamp > timeLast_)
00426 uuid_state_.clockSequence = 0;
00427
00428 timeLast_ = timestamp;
00429 }
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442 void
00443 UUID_Generator::get_systemtime (UUID_time & timestamp)
00444 {
00445 const UUID_time timeOffset = ACE_UINT64_LITERAL (0x1B21DD213814000);
00446
00447
00448 ACE_Time_Value now = ACE_OS::gettimeofday();
00449 ACE_UINT64 time;
00450 now.to_usec (time);
00451 time = time * 10;
00452 timestamp = time + timeOffset;
00453 }
00454
00455 ACE_SYNCH_MUTEX*
00456 UUID_Generator::lock (void)
00457 {
00458 return this->lock_;
00459 }
00460
00461 ACE_SYNCH_MUTEX*
00462 UUID_Generator::lock (ACE_SYNCH_MUTEX* lock,
00463 int release_lock_)
00464 {
00465 if (destroy_lock_)
00466 delete lock_;
00467
00468 ACE_SYNCH_MUTEX* prev_lock = this->lock_;
00469 this->lock_ = lock;
00470 this->destroy_lock_ = release_lock_;
00471 return prev_lock;
00472 }
00473
00474 }
00475
00476 #if defined (ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION)
00477 template ACE_Singleton<ACE_Utils::UUID_Generator, ACE_SYNCH_MUTEX> *
00478 ACE_Singleton<ACE_Utils::UUID_Generator, ACE_SYNCH_MUTEX>::singleton_;
00479 #endif
00480
00481 ACE_END_VERSIONED_NAMESPACE_DECL