From 59f76262e85c190395f9b68ffbb1f37f6119e5c6 Mon Sep 17 00:00:00 2001 From: Andrew Stitcher Date: Tue, 29 Apr 2014 13:29:45 +0000 Subject: QPID-5489: More cleaning up of the Uuid code - Rewrite the Uuid iosteam extractor and insertor operators to not require any underlying uuid library. - Create a specific uuid implementation for FreeBSD git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1590978 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/src/qpid/legacystore/TxnCtxt.cpp | 4 +- qpid/cpp/src/qpid/legacystore/TxnCtxt.h | 2 +- qpid/cpp/src/qpid/linearstore/TxnCtxt.cpp | 4 +- qpid/cpp/src/qpid/linearstore/TxnCtxt.h | 2 +- .../src/qpid/linearstore/journal/EmptyFilePool.cpp | 9 +-- qpid/cpp/src/qpid/sys/FreeBSD/uuid.cpp | 44 ++++++++++++++ qpid/cpp/src/qpid/sys/uuid.h | 19 ++++-- qpid/cpp/src/qpid/sys/windows/uuid.cpp | 36 ++---------- qpid/cpp/src/qpid/sys/windows/uuid.h | 35 ----------- qpid/cpp/src/qpid/types/Uuid.cpp | 68 +++++++++++++++++++--- qpid/cpp/src/tests/Uuid.cpp | 18 +++++- 11 files changed, 149 insertions(+), 92 deletions(-) create mode 100644 qpid/cpp/src/qpid/sys/FreeBSD/uuid.cpp delete mode 100644 qpid/cpp/src/qpid/sys/windows/uuid.h (limited to 'qpid/cpp') diff --git a/qpid/cpp/src/qpid/legacystore/TxnCtxt.cpp b/qpid/cpp/src/qpid/legacystore/TxnCtxt.cpp index 1db41f4c70..b02b5e887f 100644 --- a/qpid/cpp/src/qpid/legacystore/TxnCtxt.cpp +++ b/qpid/cpp/src/qpid/legacystore/TxnCtxt.cpp @@ -59,7 +59,7 @@ void TxnCtxt::commitTxn(JournalImpl* jc, bool commit) { } // static -uuid_t TxnCtxt::uuid; +qpid::sys::uuid_t TxnCtxt::uuid; // static IdSequence TxnCtxt::uuidSeq; @@ -69,7 +69,7 @@ bool TxnCtxt::staticInit = TxnCtxt::setUuid(); // static bool TxnCtxt::setUuid() { - ::uuid_generate(uuid); + qpid::sys::uuid_generate(uuid); return true; } diff --git a/qpid/cpp/src/qpid/legacystore/TxnCtxt.h b/qpid/cpp/src/qpid/legacystore/TxnCtxt.h index 77eaa27cd7..85f0226cdc 100644 --- a/qpid/cpp/src/qpid/legacystore/TxnCtxt.h +++ b/qpid/cpp/src/qpid/legacystore/TxnCtxt.h @@ -45,7 +45,7 @@ class TxnCtxt : public qpid::broker::TransactionContext protected: static qpid::sys::Mutex globalSerialiser; - static uuid_t uuid; + static qpid::sys::uuid_t uuid; static IdSequence uuidSeq; static bool staticInit; static bool setUuid(); diff --git a/qpid/cpp/src/qpid/linearstore/TxnCtxt.cpp b/qpid/cpp/src/qpid/linearstore/TxnCtxt.cpp index df2e7a442d..e26f0b8b6f 100644 --- a/qpid/cpp/src/qpid/linearstore/TxnCtxt.cpp +++ b/qpid/cpp/src/qpid/linearstore/TxnCtxt.cpp @@ -60,7 +60,7 @@ void TxnCtxt::commitTxn(JournalImpl* jc, bool commit) { } // static -uuid_t TxnCtxt::uuid; +sys::uuid_t TxnCtxt::uuid; // static IdSequence TxnCtxt::uuidSeq; @@ -70,7 +70,7 @@ bool TxnCtxt::staticInit = TxnCtxt::setUuid(); // static bool TxnCtxt::setUuid() { - ::uuid_generate(uuid); + qpid::sys::uuid_generate(uuid); return true; } diff --git a/qpid/cpp/src/qpid/linearstore/TxnCtxt.h b/qpid/cpp/src/qpid/linearstore/TxnCtxt.h index 4f95da5950..764063a615 100644 --- a/qpid/cpp/src/qpid/linearstore/TxnCtxt.h +++ b/qpid/cpp/src/qpid/linearstore/TxnCtxt.h @@ -43,7 +43,7 @@ class TxnCtxt : public qpid::broker::TransactionContext protected: static qpid::sys::Mutex globalSerialiser; - static uuid_t uuid; + static sys::uuid_t uuid; static IdSequence uuidSeq; static bool staticInit; static bool setUuid(); diff --git a/qpid/cpp/src/qpid/linearstore/journal/EmptyFilePool.cpp b/qpid/cpp/src/qpid/linearstore/journal/EmptyFilePool.cpp index 540bdcaf14..fafaf0b612 100644 --- a/qpid/cpp/src/qpid/linearstore/journal/EmptyFilePool.cpp +++ b/qpid/cpp/src/qpid/linearstore/journal/EmptyFilePool.cpp @@ -28,7 +28,7 @@ #include "qpid/linearstore/journal/JournalLog.h" #include "qpid/linearstore/journal/slock.h" #include "qpid/linearstore/journal/utils/file_hdr.h" -#include "qpid/sys/uuid.h" +#include "qpid/types/Uuid.h" #include #include #include @@ -189,12 +189,9 @@ void EmptyFilePool::createEmptyFile() { } std::string EmptyFilePool::getEfpFileName() { - uuid_t uuid; - ::uuid_generate(uuid); // NOTE: uuid_generate() is not thread safe - char uuid_str[37]; // 36 char uuid + trailing \0 - ::uuid_unparse(uuid, uuid_str); + qpid::types::Uuid uuid(true); std::ostringstream oss; - oss << efpDirectory_ << "/" << uuid_str << QLS_JRNL_FILE_EXTENSION; + oss << efpDirectory_ << "/" << uuid << QLS_JRNL_FILE_EXTENSION; return oss.str(); } diff --git a/qpid/cpp/src/qpid/sys/FreeBSD/uuid.cpp b/qpid/cpp/src/qpid/sys/FreeBSD/uuid.cpp new file mode 100644 index 0000000000..4e4a1289d1 --- /dev/null +++ b/qpid/cpp/src/qpid/sys/FreeBSD/uuid.cpp @@ -0,0 +1,44 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +#include "qpid/sys/uuid.h" + +#include +#include + +extern "C" +void uuid_generate (uint8_t out[qpid::sys::UuidSize]) +{ + uuid_t uuid; + uint32_t status; + uuid_create(&uuid, &status); + out[0] = (uuid.time_low & 0xff000000) >> 24; + out[1] = (uuid.time_low & 0x00ff0000) >> 16; + out[2] = (uuid.time_low & 0x0000ff00) >> 8; + out[3] = (uuid.time_low & 0x000000ff); + out[4] = (uuid.time_mid & 0xff00) >> 8; + out[5] = (uuid.time_mid & 0x00ff); + out[6] = (uuid.time_hi_and_version & 0xff00) >> 8; + out[7] = (uuid.time_hi_and_version & 0x00ff); + out[8] = uuid.clock_seq_hi_and_reserved; + out[9] = uuid.clock_seq_low; + ::memcpy(&out[10], &uuid.node, _UUID_NODE_LEN); +} diff --git a/qpid/cpp/src/qpid/sys/uuid.h b/qpid/cpp/src/qpid/sys/uuid.h index 804ab34463..6c32c059c4 100644 --- a/qpid/cpp/src/qpid/sys/uuid.h +++ b/qpid/cpp/src/qpid/sys/uuid.h @@ -19,10 +19,19 @@ * */ -#ifdef _WIN32 -# include "qpid/sys/windows/uuid.h" -#else -# include -#endif /* _WIN32 */ +#include "qpid/types/ImportExport.h" + +#include "qpid/sys/IntegerTypes.h" + +namespace qpid { +namespace sys { + +const int UuidSize = 16; +typedef uint8_t uuid_t[UuidSize]; + +extern "C" +QPID_TYPES_EXTERN void uuid_generate (uint8_t out[UuidSize]); + +}} #endif /* _sys_uuid_h */ diff --git a/qpid/cpp/src/qpid/sys/windows/uuid.cpp b/qpid/cpp/src/qpid/sys/windows/uuid.cpp index c8804d9ee7..4ff75ca627 100644 --- a/qpid/cpp/src/qpid/sys/windows/uuid.cpp +++ b/qpid/cpp/src/qpid/sys/windows/uuid.cpp @@ -32,7 +32,7 @@ # undef uuid_t #endif -#include "qpid/sys/windows/uuid.h" +#include "qpid/sys/uuid.h" #include @@ -43,7 +43,7 @@ inline void iswap (char *p1, char *p2) { *p2 = t; } -void toUuid (const UUID *guid, uuid_t uuid) { +void toUuid (const UUID *guid, uint8_t uuid[qpid::sys::UuidSize]) { // copy then swap bytes memcpy ((char *) uuid, (char *) guid, qpid::sys::UuidSize); char *p = (char *) uuid; @@ -53,40 +53,16 @@ void toUuid (const UUID *guid, uuid_t uuid) { iswap (p+6, p+7); } -void printHex (const unsigned char *bytes, char *buf, int n) { - static char hexrep[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'a', 'b', 'c', 'd', 'e', 'f'}; - for (;n ; n--) { - unsigned char b = *bytes++; - *buf++ = hexrep[b >> 4]; - *buf++ = hexrep[b & 0xf]; - } -} } // namespace +namespace qpid { +namespace sys { -void uuid_generate (uuid_t out) { +void uuid_generate (uint8_t out[qpid::sys::UuidSize]) { UUID guid; UuidCreate (&guid); // Version 4 GUID, convert to UUID toUuid (&guid, out); } -int uuid_parse (const char *in, uuid_t uu) { - UUID guid; - if (UuidFromString ((unsigned char*)in, &guid) != RPC_S_OK) - return -1; - toUuid (&guid, uu); - return 0; -} - -void uuid_unparse (const uuid_t uu, char *out) { - const uint8_t *in = uu; - out[8] = out[13] = out[18] = out[23] = '-'; - printHex (in, out, 4); - printHex (in+4, out+9, 2); - printHex (in+6, out+14, 2); - printHex (in+8, out+19, 2); - printHex (in+10, out+24, 6); - out[36] = '\0'; -} +}} diff --git a/qpid/cpp/src/qpid/sys/windows/uuid.h b/qpid/cpp/src/qpid/sys/windows/uuid.h deleted file mode 100644 index 69da709a03..0000000000 --- a/qpid/cpp/src/qpid/sys/windows/uuid.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef _sys_windows_uuid_h -#define _sys_windows_uuid_h - -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -#include "qpid/types/ImportExport.h" -#include - -namespace qpid { namespace sys { const size_t UuidSize = 16; }} -typedef uint8_t uuid_t[qpid::sys::UuidSize]; - -QPID_TYPES_EXTERN void uuid_generate (uuid_t out); -QPID_TYPES_EXTERN int uuid_parse (const char *in, uuid_t uu); // Returns 0 on success, else -1 -QPID_TYPES_EXTERN void uuid_unparse (const uuid_t uu, char *out); - -#endif /*!_sys_windows_uuid_h*/ diff --git a/qpid/cpp/src/qpid/types/Uuid.cpp b/qpid/cpp/src/qpid/types/Uuid.cpp index 3d31ab45c9..c0e38e1da5 100644 --- a/qpid/cpp/src/qpid/types/Uuid.cpp +++ b/qpid/cpp/src/qpid/types/Uuid.cpp @@ -23,6 +23,8 @@ #include "qpid/sys/IntegerTypes.h" #include #include +#include +#include #include namespace qpid { @@ -31,7 +33,7 @@ namespace types { using namespace std; const size_t Uuid::SIZE=16; -static const size_t UNPARSED_SIZE=36; +static const int UNPARSED_SIZE=36; Uuid::Uuid(bool unique) { @@ -66,7 +68,7 @@ Uuid& Uuid::operator=(const Uuid& other) void Uuid::generate() { - uuid_generate(bytes); + sys::uuid_generate(bytes); } void Uuid::clear() @@ -122,17 +124,69 @@ bool operator>=(const Uuid& a, const Uuid& b) ostream& operator<<(ostream& out, Uuid uuid) { - char unparsed[UNPARSED_SIZE + 1]; - uuid_unparse(uuid.bytes, unparsed); - return out << unparsed; + const uint8_t* bytes = uuid.bytes; + + ios_base::fmtflags f = out.flags(); + out << hex << setfill('0') + << setw(2) << int(bytes[0]) + << setw(2) << int(bytes[1]) + << setw(2) << int(bytes[2]) + << setw(2) << int(bytes[3]) + << "-" + << setw(2) << int(bytes[4]) + << setw(2) << int(bytes[5]) + << "-" + << setw(2) << int(bytes[6]) + << setw(2) << int(bytes[7]) + << "-" + << setw(2) << int(bytes[8]) + << setw(2) << int(bytes[9]) + << "-" + << setw(2) << int(bytes[10]) + << setw(2) << int(bytes[11]) + << setw(2) << int(bytes[12]) + << setw(2) << int(bytes[13]) + << setw(2) << int(bytes[14]) + << setw(2) << int(bytes[15]); + out.flags(f); + return out; } istream& operator>>(istream& in, Uuid& uuid) { + unsigned bytes[16]; char unparsed[UNPARSED_SIZE + 1] = {0}; - in.get(unparsed, sizeof(unparsed)); - if (uuid_parse(unparsed, uuid.bytes) != 0) + + istream::sentry s(in); + if ( !s ) return in; + + in.get(unparsed, UNPARSED_SIZE+1); + + // Check if we read enough characters + if ( in.gcount()!=UNPARSED_SIZE ) { + in.setstate(ios::failbit); + return in; + } + int r = ::sscanf(unparsed, "%2x%2x%2x%2x-" + "%2x%2x-" + "%2x%2x-" + "%2x%2x-" + "%2x%2x%2x%2x%2x%2x", + &bytes[0], &bytes[1], &bytes[2], &bytes[3], + &bytes[4], &bytes[5], + &bytes[6], &bytes[7], + &bytes[8], &bytes[9], + &bytes[10], &bytes[11], &bytes[12], &bytes[13], &bytes[14], &bytes[15] + ); + // Check if we got enough converted input + if ( r!=int(Uuid::SIZE) ) { in.setstate(ios::failbit); + return in; + } + + for (unsigned i=0; i<16; ++i) { + uuid.bytes[i] = bytes[i]; + } return in; } diff --git a/qpid/cpp/src/tests/Uuid.cpp b/qpid/cpp/src/tests/Uuid.cpp index 5fb848a500..f9a67d9db0 100644 --- a/qpid/cpp/src/tests/Uuid.cpp +++ b/qpid/cpp/src/tests/Uuid.cpp @@ -49,9 +49,11 @@ QPID_AUTO_TEST_CASE(testUuidCtor) { for_each(uuids.begin(), uuids.end(), unique); } -boost::array sample = {{0x1b, 0x4e, 0x28, 0xba, 0x2f, 0xa1, 0x11, 0xd2, 0x88, 0x3f, 0xb9, 0xa7, 0x61, 0xbd, 0xe3, 0xfb}}; -const string sampleStr("1b4e28ba-2fa1-11d2-883f-b9a761bde3fb"); +boost::array sample = {{0x1b, 0x4e, 0x28, 0xba, 0x2f, 0xa1, 0x11, 0x02, 0x88, 0x3f, 0xb9, 0xa7, 0x61, 0xbd, 0xe3, 0xfb}}; +const string sampleStr("1b4e28ba-2fa1-1102-883f-b9a761bde3fb"); const string zeroStr("00000000-0000-0000-0000-000000000000"); +const string badUuid1("1b4e28ba-2fa1-11d2-883f-b9761bde3fb"); +const string badUuid2("1b4e28ba-2fa1-11d23883f-b9761dbde3fb"); QPID_AUTO_TEST_CASE(testUuidIstream) { Uuid uuid; @@ -63,7 +65,7 @@ QPID_AUTO_TEST_CASE(testUuidIstream) { istringstream is(zeroStr); Uuid zero; is >> zero; - BOOST_CHECK(!in.fail()); + BOOST_CHECK(!is.fail()); BOOST_CHECK_EQUAL(zero, Uuid()); } @@ -80,6 +82,16 @@ QPID_AUTO_TEST_CASE(testUuidOstream) { BOOST_CHECK_EQUAL(os.str(), zeroStr); } +QPID_AUTO_TEST_CASE(testBadUuidIstream) { + Uuid a; + istringstream is(badUuid1); + is >> a; + BOOST_CHECK(!is.good()); + istringstream is2(badUuid2); + is2 >> a; + BOOST_CHECK(!is2.good()); +} + QPID_AUTO_TEST_CASE(testUuidIOstream) { Uuid a(true), b(true); ostringstream os; -- cgit v1.2.1