diff options
Diffstat (limited to 'dep/ACE_wrappers/ace/UUID.cpp')
-rw-r--r-- | dep/ACE_wrappers/ace/UUID.cpp | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/dep/ACE_wrappers/ace/UUID.cpp b/dep/ACE_wrappers/ace/UUID.cpp index cd9aa519f4e..d27c8f8a33b 100644 --- a/dep/ACE_wrappers/ace/UUID.cpp +++ b/dep/ACE_wrappers/ace/UUID.cpp @@ -1,9 +1,12 @@ //$Id: UUID.cpp 81541 2008-04-30 13:56:12Z shuston $ + #include "ace/UUID.h" #include "ace/Guard_T.h" + #if !defined (__ACE_INLINE__) #include "ace/UUID.inl" #endif /* __ACE_INLINE__ */ + #include "ace/Log_Msg.h" #include "ace/OS_NS_stdio.h" #include "ace/OS_NS_string.h" @@ -11,11 +14,14 @@ #include "ace/OS_NS_netdb.h" #include "ace/OS_NS_unistd.h" #include "ace/ACE.h" + ACE_RCSID (ace, UUID, "$Id: UUID.cpp 81541 2008-04-30 13:56:12Z shuston $") + ACE_BEGIN_VERSIONED_NAMESPACE_DECL + namespace ACE_Utils { UUID_Node::UUID_Node (void) @@ -23,18 +29,22 @@ namespace ACE_Utils for (int i = 0; i < UUID_Node::NODE_ID_SIZE; ++i) node_ID_[i] = 0; } + UUID_Node::Node_ID& UUID_Node::node_ID (void) { return node_ID_; } + void UUID_Node::node_ID (Node_ID& node_ID) { for (int i = 0; i < UUID_Node::NODE_ID_SIZE; ++i) node_ID_[i] = node_ID[i]; } + UUID UUID::NIL_UUID; + /// Construct a nil UUID. Such a UUID has every one of it's data /// elements set to zero. UUID::UUID (void) @@ -50,6 +60,7 @@ namespace ACE_Utils ACE_NEW (node_, UUID_Node); } + /// Construct a UUID from a string representation of an UUID. UUID::UUID (const ACE_CString& uuid_string) : time_low_ (0), @@ -63,8 +74,10 @@ namespace ACE_Utils { ACE_NEW (node_, UUID_Node); + this->from_string_i (uuid_string); } + UUID::UUID (const UUID &right) : time_low_ (right.time_low_), time_mid_ (right.time_mid_), @@ -76,13 +89,16 @@ namespace ACE_Utils ACE_NEW (node_, UUID_Node (*right.node_)); } + UUID::~UUID (void) { if (node_release_) delete node_; + if (as_string_ != 0) delete as_string_; } + const ACE_CString* UUID::to_string (void) { @@ -93,12 +109,14 @@ namespace ACE_Utils // gauge. Don't forget the trailing nul. size_t UUID_STRING_LENGTH = 36 + thr_id_.length () + pid_.length (); char *buf = 0; + if ((thr_id_.length () != 0) && (pid_.length () != 0)) { UUID_STRING_LENGTH += 2; //for '-' ACE_NEW_RETURN (buf, char[UUID_STRING_LENGTH + 1], 0); + ACE_OS::sprintf (buf, "%8.8x-%4.4x-%4.4x-%2.2x%2.2x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x-%s-%s", this->time_low_, @@ -121,6 +139,7 @@ namespace ACE_Utils ACE_NEW_RETURN (buf, char[UUID_STRING_LENGTH + 1], 0); + ACE_OS::sprintf (buf, "%8.8x-%4.4x-%4.4x-%2.2x%2.2x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x", this->time_low_, @@ -136,19 +155,24 @@ namespace ACE_Utils (this->node_->node_ID ()) [5] ); } + // We allocated 'buf' above dynamically, so we shouldn't use // ACE_NEW_RETURN here to avoid a possible memory leak. ACE_NEW_NORETURN (this->as_string_, ACE_CString (buf, UUID_STRING_LENGTH)); + // we first free the dynamically allocated 'buf'. delete [] buf; + // then we test that ACE_NEW succeded for 'as_string_' // if not, we return 0 (NULL) to indicate failure. if (this->as_string_ == 0 ) return 0; } + return as_string_; } + void UUID::from_string_i (const ACE_CString& uuid_string) { @@ -159,6 +183,7 @@ namespace ACE_Utils "IllegalArgument (incorrect string length)\n")); return; } + /// Special case for the nil UUID. if (uuid_string == *NIL_UUID.to_string ()) { @@ -168,6 +193,7 @@ namespace ACE_Utils ACE_UNUSED_ARG (copy_constructor_not_supported); return; } + unsigned int time_low; unsigned int time_mid; unsigned int time_hi_and_version; @@ -175,6 +201,7 @@ namespace ACE_Utils unsigned int clock_seq_low; unsigned int node [UUID_Node::NODE_ID_SIZE]; char thr_pid_buf [BUFSIZ]; + if (uuid_string.length () == NIL_UUID.to_string ()->length ()) { // This might seem quite strange this being in ACE, but it @@ -202,6 +229,7 @@ namespace ACE_Utils &node[4], &node[5] ); + if (nScanned != 11) { ACE_DEBUG ((LM_DEBUG, @@ -247,6 +275,7 @@ namespace ACE_Utils thr_pid_buf ); #endif /* ACE_HAS_TR24731_2005_CRT */ + if (nScanned != 12) { ACE_DEBUG ((LM_DEBUG, @@ -255,15 +284,19 @@ namespace ACE_Utils return; } } + this->time_low_ = static_cast<ACE_UINT32> (time_low); this->time_mid_ = static_cast<ACE_UINT16> (time_mid); this->time_hi_and_version_ = static_cast<ACE_UINT16> (time_hi_and_version); this->clock_seq_hi_and_reserved_ = static_cast<u_char> (clock_seq_hi_and_reserved); this->clock_seq_low_ = static_cast<u_char> (clock_seq_low); + UUID_Node::Node_ID node_id; for (int i = 0; i < UUID_Node::NODE_ID_SIZE; ++i) node_id [i] = static_cast<u_char> (node[i]); + this->node_->node_ID (node_id); + // Support varient 10- only if ((this->clock_seq_hi_and_reserved_ & 0xc0) != 0x80 && (this->clock_seq_hi_and_reserved_ & 0xc0) != 0xc0) { @@ -272,8 +305,10 @@ namespace ACE_Utils "IllegalArgument (unsupported variant)\n")); return; } + /// Support versions 1, 3, and 4 only ACE_UINT16 V1 = this->time_hi_and_version_; + if ((V1 & 0xF000) != 0x1000 && (V1 & 0xF000) != 0x3000 && (V1 & 0xF000) != 0x4000) @@ -283,6 +318,7 @@ namespace ACE_Utils "IllegalArgument (unsupported version)\n")); return; } + if ((this->clock_seq_hi_and_reserved_ & 0xc0) == 0xc0) { if (uuid_string.length () == NIL_UUID.to_string ()->length ()) @@ -298,10 +334,12 @@ namespace ACE_Utils ACE_DEBUG ((LM_DEBUG, "ACE_UUID::from_string_i - " "IllegalArgument (Thread and Process Id format incorrect)\n")); + this->thr_id_ = thr_pid_str.substr (0, pos); this->pid_ = thr_pid_str.substr (pos+1, thr_pid_str.length ()-pos-1); } } + UUID_Generator::UUID_Generator () : time_last_ (0), destroy_lock_ (true) @@ -309,16 +347,19 @@ namespace ACE_Utils ACE_NEW (lock_, ACE_SYNCH_MUTEX); } + UUID_Generator::~UUID_Generator () { if (destroy_lock_) delete lock_; } + void UUID_Generator::init (void) { ACE_OS::macaddr_node_t macaddress; int result = ACE_OS::getmacaddress (&macaddress); + UUID_Node::Node_ID node_id; if (result != -1) { @@ -330,6 +371,7 @@ namespace ACE_Utils // macaddress.node [3], // macaddress.node [4], // macaddress.node [5])); + ACE_OS::memcpy (&node_id, macaddress.node, sizeof (node_id)); @@ -343,46 +385,57 @@ namespace ACE_Utils node_id [4] = static_cast<u_char> (ACE_OS::rand ()); node_id [5] = static_cast<u_char> (ACE_OS::rand ()); } + this->get_timestamp (time_last_); + { ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, *lock_); uuid_state_.timestamp = time_last_; uuid_state_.node.node_ID (node_id); } } + void UUID_Generator::generate_UUID (UUID& uuid,ACE_UINT16 version, u_char variant) { UUID_Time timestamp; ACE_UINT16 clock_sequence; + this->get_timestamp_and_clocksequence (timestamp, clock_sequence); + // Construct a Version 1 UUID with the information in the arguements. uuid.time_low (static_cast<ACE_UINT32> (timestamp & 0xFFFFFFFF)); uuid.time_mid (static_cast<ACE_UINT16> ((timestamp >> 32) & 0xFFFF)); + ACE_UINT16 tHAV = static_cast<ACE_UINT16> ((timestamp >> 48) & 0xFFFF); tHAV |= (version << 12); uuid.time_hi_and_version (tHAV); + u_char cseqHAV; uuid.clock_seq_low (static_cast<u_char> (clock_sequence & 0xFF)); cseqHAV = static_cast<u_char> ((clock_sequence & 0x3f00) >> 8); uuid_state_.timestamp = timestamp; + cseqHAV |= variant; uuid.clock_seq_hi_and_reserved (cseqHAV); uuid.node (& (uuid_state_.node)); + if (variant == 0xc0) { ACE_Thread_ID thread_id; char buf [BUFSIZ]; thread_id.to_string (buf); uuid.thr_id (buf); + ACE_OS::sprintf (buf, "%d", static_cast<int> (ACE_OS::getpid ())); uuid.pid (buf); } } + UUID* UUID_Generator::generate_UUID (ACE_UINT16 version, u_char variant) { @@ -390,16 +443,20 @@ namespace ACE_Utils ACE_NEW_RETURN (uuid, UUID, 0); + this->generate_UUID (*uuid, version, variant); return uuid; } + /// Obtain a new timestamp. If UUID's are being generated too quickly /// the clock sequence will be incremented void UUID_Generator::get_timestamp (UUID_Time& timestamp) { ACE_GUARD (ACE_SYNCH_MUTEX, mon, *lock_); + this->get_systemtime (timestamp); + // Account for the clock being set back. Increment the clock / // sequence. if (timestamp <= time_last_) @@ -413,25 +470,32 @@ namespace ACE_Utils { uuid_state_.clock_sequence = 0; } + time_last_ = timestamp; } + void UUID_Generator::get_timestamp_and_clocksequence (UUID_Time& timestamp, ACE_UINT16& clock_sequence) { ACE_GUARD (ACE_SYNCH_MUTEX, mon, *lock_); + this->get_systemtime (timestamp); + // Account for the clock being set back. Increment the clock / // sequence. if (timestamp <= time_last_) uuid_state_.clock_sequence = static_cast<ACE_UINT16> ((uuid_state_.clock_sequence + 1) & ACE_UUID_CLOCK_SEQ_MASK); + // If the system time ticked since the last UUID was // generated. Set / the clock sequence back. else if (timestamp > time_last_) uuid_state_.clock_sequence = 0; + time_last_ = timestamp; clock_sequence = uuid_state_.clock_sequence; } + /** * ACE_Time_Value is in POSIX time, seconds since Jan 1, 1970. UUIDs use * time in 100ns ticks since 15 October 1582. The difference is: @@ -454,6 +518,7 @@ namespace ACE_Utils #else ACE_UINT64_LITERAL (0x1B21DD213814000); #endif /* ACE_LACKS_UNSIGNEDLONGLONG_T */ + /// Get the time of day, convert to 100ns ticks then add the offset. ACE_Time_Value now = ACE_OS::gettimeofday (); ACE_UINT64 time; @@ -461,24 +526,30 @@ namespace ACE_Utils time = time * 10; timestamp = time + timeOffset; } + ACE_SYNCH_MUTEX* UUID_Generator::lock (void) { return this->lock_; } + void UUID_Generator::lock (ACE_SYNCH_MUTEX* lock, bool release_lock) { if (this->destroy_lock_) delete this->lock_; + this->lock_ = lock; this->destroy_lock_ = release_lock; } + } + #if defined (ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION) template ACE_Singleton<ACE_Utils::UUID_Generator, ACE_SYNCH_MUTEX> * ACE_Singleton<ACE_Utils::UUID_Generator, ACE_SYNCH_MUTEX>::singleton_; #endif /* ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION */ + ACE_END_VERSIONED_NAMESPACE_DECL |