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 );