Due to need to use activemq-cpp on various Unix platforms and 
non-standard uuid libraries, I decided to settle for one and modify 
activemq-cpp to use it.  I selected OSSP uuid library 
(http://www.ossp.org/pkg/lib/uuid/).

The interface is different to existing ones understood by util::Guid, 
and the patch identifies the library with UUID_VERSION macro that is 
defined in uuid.h.  I had to remove unused bytes conversion operator 
since it would create memory allocation problems.

Is there any interest integrating this to activemq-cpp?  This patch 
works for the latest released version 1.5.1 if headers and libraries 
are found in the compiler's path.

Teemu
diff --git a/src/main/activemq/util/Guid.cpp b/src/main/activemq/util/Guid.cpp
--- a/src/main/activemq/util/Guid.cpp
+++ b/src/main/activemq/util/Guid.cpp
@@ -25,7 +25,11 @@ Guid::Guid()
 Guid::Guid()
 {
     // Clear internal uuid, would pass isNull
-    #if !defined(HAVE_OBJBASE_H)
+    #if UUID_VERSION
+        uuid_rc_t status = uuid_create (&uuid);
+	if (status != UUID_RC_OK)
+	  throw RuntimeException(__FILE__, __LINE__, uuid_error (status));
+    #elif !defined(HAVE_OBJBASE_H)
         memset(&uuid, 0, sizeof(uuid_t));
     #else
         ::UuidCreateNil(&uuid);
@@ -36,7 +40,13 @@ Guid::Guid( const Guid& source )
 Guid::Guid( const Guid& source )
 {
     // Set this uuid to that of the source
-    *this = source;
+    #if UUID_VERSION
+        uuid_rc_t status = uuid_clone (source.uuid, &uuid);
+	if (status != UUID_RC_OK)
+	  throw IllegalArgumentException(__FILE__, __LINE__, uuid_error (status));
+    #else
+	*this = source;
+    #endif
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -50,19 +60,30 @@ Guid::Guid( const std::string& source )
             "GUID::fromBytes - Source was Empty");
     }
 
+#if UUID_VERSION
+    uuid_create (&uuid);
+#endif
+
     // Set this uuid to that of the source
-    *this = source;   
+    *this = source;
 }
    
 ////////////////////////////////////////////////////////////////////////////////
 Guid::~Guid()
 {
+    #if UUID_VERSION
+        uuid_destroy (uuid);
+    #endif
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 bool Guid::isNull() const
 {
-    #if !defined(HAVE_OBJBASE_H) 
+    #if UUID_VERSION
+        int result = 0;
+        uuid_isnil (uuid, &result);
+	return result != 0;
+    #elif !defined(HAVE_OBJBASE_H) 
         // Check the uuid APIs is null method
         return uuid_is_null(*(const_cast<uuid_t*>(&uuid))) == 1 ? true : false;
     #else
@@ -77,7 +98,9 @@ bool Guid::isNull() const
 ////////////////////////////////////////////////////////////////////////////////
 void Guid::setNull()
 {
-    #if !defined(HAVE_OBJBASE_H) 
+    #if UUID_VERSION
+	uuid_load (uuid, "nil");
+    #elif !defined(HAVE_OBJBASE_H) 
         // use the uuid function to clear
         uuid_clear(uuid);
     #else
@@ -88,7 +111,11 @@ void Guid::setNull()
 ////////////////////////////////////////////////////////////////////////////////
 Guid& Guid::createGUID() throw( RuntimeException )
 {
-    #if !defined(HAVE_OBJBASE_H) 
+    #if UUID_VERSION
+	uuid_rc_t status = uuid_make (uuid, UUID_MAKE_V4);
+	if (status != UUID_RC_OK)
+	  throw RuntimeException(__FILE__, __LINE__, uuid_error (status));
+    #elif !defined(HAVE_OBJBASE_H) 
         // Use the uuid_generate method to create a new GUID
         uuid_generate(uuid);
     #else
@@ -111,7 +138,19 @@ std::string Guid::toString() const throw
 {
     std::string uuid_str = "";
 
-    #if !defined(HAVE_OBJBASE_H) 
+    #if UUID_VERSION
+	char string[UUID_LEN_STR + 1] = {0};
+	size_t length = UUID_LEN_STR + 1;
+
+	union cast { char *sp; void *vp; } u;
+	u.sp = string;
+
+        uuid_rc_t status = uuid_export (uuid, UUID_FMT_STR, &u.vp, &length);
+	if (status != UUID_RC_OK)
+	  throw RuntimeException(__FILE__, __LINE__, uuid_error (status));
+
+	uuid_str = u.sp;
+    #elif !defined(HAVE_OBJBASE_H) 
         // Create storage for the string buffer
         char buffer[36] = {0};
       
@@ -155,7 +194,20 @@ const unsigned char* Guid::toBytes() con
     unsigned char* buffer = new unsigned char[getRawBytesSize()];
    
     // copy our buffer
-    #if !defined(HAVE_OBJBASE_H) 
+    #if UUID_VERSION
+	size_t length = UUID_LEN_BIN;
+
+	union cast { unsigned char *cp; void *vp; } u;
+	u.cp = buffer;
+
+        uuid_rc_t status = uuid_export (uuid, UUID_FMT_BIN, &u.vp, &length);
+	if (status != UUID_RC_OK)
+	  throw RuntimeException(__FILE__, __LINE__, uuid_error (status));
+
+	// Must return the union to avoid type-alias breakage.
+	//return u.cp;
+
+    #elif !defined(HAVE_OBJBASE_H) 
         uuid_copy(buffer, *(const_cast<uuid_t*>(&uuid)));
     #else
         memcpy(buffer, &uuid, getRawBytesSize());
@@ -176,7 +228,12 @@ Guid& Guid::fromBytes( const unsigned ch
     }
    
     // Copy the data
-    #if !defined(HAVE_OBJBASE_H) 
+    #if UUID_VERSION
+	uuid_rc_t status = uuid_import (uuid, UUID_FMT_BIN,
+					bytes, UUID_LEN_BIN);
+	if (status != UUID_RC_OK)
+	  throw IllegalArgumentException(__FILE__, __LINE__, uuid_error (status));
+    #elif !defined(HAVE_OBJBASE_H) 
         memcpy(uuid, bytes, getRawBytesSize());
     #else
         memcpy(&uuid, bytes, getRawBytesSize());
@@ -188,20 +245,12 @@ Guid& Guid::fromBytes( const unsigned ch
 ////////////////////////////////////////////////////////////////////////////////
 int Guid::getRawBytesSize() const
 {
-    #if !defined(HAVE_OBJBASE_H) 
+    #if UUID_VERSION
+	return UUID_LEN_BIN;
+    #elif !defined(HAVE_OBJBASE_H) 
         return sizeof(uuid_t);
     #else
         return sizeof(::GUID);
-    #endif
-}
-
-////////////////////////////////////////////////////////////////////////////////
-Guid::operator const unsigned char*() const
-{
-    #if !defined(HAVE_OBJBASE_H) 
-        return &uuid[0];
-    #else
-        return reinterpret_cast<const unsigned char*>(&uuid);
     #endif
 }
 
@@ -209,7 +258,12 @@ Guid& Guid::operator=( const Guid& sourc
 Guid& Guid::operator=( const Guid& source )
    throw ( IllegalArgumentException )
 {
-    #if !defined(HAVE_OBJBASE_H) 
+    #if UUID_VERSION
+	uuid_destroy (uuid);
+        uuid_rc_t status = uuid_clone (source.uuid, &uuid);
+	if (status != UUID_RC_OK)
+	  throw IllegalArgumentException(__FILE__, __LINE__, uuid_error (status));
+    #elif !defined(HAVE_OBJBASE_H) 
         // Use the uuid method to copy
         uuid_copy(uuid, *(const_cast<uuid_t*>(&source.uuid)));
     #else
@@ -224,7 +278,18 @@ Guid& Guid::operator=( const std::string
 Guid& Guid::operator=( const std::string& source ) 
     throw ( IllegalArgumentException )
 {
-    #if !defined(HAVE_OBJBASE_H) 
+    #if UUID_VERSION
+	if (source.empty ())
+	    uuid_load (uuid, "nil");
+	else
+	{
+	    uuid_rc_t status = uuid_import (uuid, UUID_FMT_STR,
+					    source.c_str (), source.length ());
+	    if (status != UUID_RC_OK)
+	      throw IllegalArgumentException(__FILE__, __LINE__,
+					     uuid_error (status));
+	}
+    #elif !defined(HAVE_OBJBASE_H) 
         // Parse a uuid from the passed in string
         uuid_parse( const_cast<char*>(source.c_str()), uuid );
     #else
@@ -252,7 +317,11 @@ Guid& Guid::operator=( const std::string
 ////////////////////////////////////////////////////////////////////////////////
 bool Guid::operator==( const Guid& source ) const
 {
-    #if !defined(HAVE_OBJBASE_H) 
+    #if UUID_VERSION
+	int result;
+	uuid_compare (uuid, source.uuid, &result);
+	return result == 0;
+    #elif !defined(HAVE_OBJBASE_H) 
         // uuid_compare returns 0 for equal
         return uuid_compare(
                 *(const_cast<uuid_t*>(&uuid)), 
@@ -290,7 +359,11 @@ bool Guid::operator!=( const std::string
 ////////////////////////////////////////////////////////////////////////////////
 bool Guid::operator<( const Guid& source ) const
 {
-    #if !defined(HAVE_OBJBASE_H) 
+    #if UUID_VERSION
+	int result;
+	uuid_compare (uuid, source.uuid, &result);
+	return result < 0;
+    #elif !defined(HAVE_OBJBASE_H) 
         // uuid_compare returns 0 for equal
         return uuid_compare(
                  *(const_cast<uuid_t*>(&uuid)), 
@@ -316,7 +389,11 @@ bool Guid::operator<( const std::string&
 ////////////////////////////////////////////////////////////////////////////////
 bool Guid::operator<=( const Guid& source ) const
 {
-    #if !defined(HAVE_OBJBASE_H) 
+    #if UUID_VERSION
+	int result;
+	uuid_compare (uuid, source.uuid, &result);
+	return result <= 0;
+    #elif !defined(HAVE_OBJBASE_H) 
         // uuid_compare returns 0 for equal
         return uuid_compare(
                  *(const_cast<uuid_t*>(&uuid)), 
@@ -342,7 +419,11 @@ bool Guid::operator<=( const std::string
 ////////////////////////////////////////////////////////////////////////////////
 bool Guid::operator>( const Guid& source ) const
 {
-    #if !defined(HAVE_OBJBASE_H) 
+    #if UUID_VERSION
+	int result;
+	uuid_compare (uuid, source.uuid, &result);
+	return result > 0;
+    #elif !defined(HAVE_OBJBASE_H) 
         // uuid_compare returns 0 for equal
         return uuid_compare(
                  *(const_cast<uuid_t*>(&uuid)), 
@@ -368,7 +449,11 @@ bool Guid::operator>( const std::string&
 ////////////////////////////////////////////////////////////////////////////////
 bool Guid::operator>=( const Guid& source ) const
 {
-    #if !defined(HAVE_OBJBASE_H) 
+    #if UUID_VERSION
+	int result;
+	uuid_compare (uuid, source.uuid, &result);
+	return result >= 0;
+    #elif !defined(HAVE_OBJBASE_H) 
         // uuid_compare returns 0 for equal
         return uuid_compare(
                  *(const_cast<uuid_t*>(&uuid)), 
diff --git a/src/main/activemq/util/Guid.h b/src/main/activemq/util/Guid.h
--- a/src/main/activemq/util/Guid.h
+++ b/src/main/activemq/util/Guid.h
@@ -25,10 +25,10 @@
 #if defined(HAVE_OBJBASE_H)  
     #include <objbase.h>
     #include <rpcdce.h>
+#elif defined(HAVE_UUID_H)
+    #include <uuid.h>
 #elif defined(HAVE_UUID_UUID_H)
     #include <uuid/uuid.h>    
-#elif defined(HAVE_UUID_H)
-    #include <uuid.h>
 #endif
 
 #include <string>
@@ -98,12 +98,6 @@ namespace util{
          * @returns string representation of this GUID
          */
         operator std::string() const;
-      
-        /**
-         * byte array cast operator, caller does not own this memeory
-         * @returns byte array with the GUID byte value representation
-         */
-        operator const unsigned char*() const;
       
         /**
          * Assignment operators
@@ -176,6 +170,8 @@ namespace util{
         // the uuid that this object represents.
         #ifdef HAVE_OBJBASE_H
             ::GUID uuid;
+        #elif UUID_VERSION
+	    uuid_t *uuid;
         #elif defined(HAVE_UUID_T)
             uuid_t uuid;
         #else
diff --git a/src/test/activemq/util/GuidTest.h b/src/test/activemq/util/GuidTest.h
--- a/src/test/activemq/util/GuidTest.h
+++ b/src/test/activemq/util/GuidTest.h
@@ -73,11 +73,6 @@ namespace util{
 
          delete [] bytes;
 
-         Guid bytesGUID2;
-         bytesGUID2.fromBytes((const unsigned char*)guid);
-         
-         CPPUNIT_ASSERT( guid == bytesGUID2 );
-   
          Guid stringGUID(guid.toString());
    
          CPPUNIT_ASSERT( stringGUID == guid );

Reply via email to