diff --git a/MongoDB/include/Poco/MongoDB/ObjectId.h b/MongoDB/include/Poco/MongoDB/ObjectId.h index 59845dcf5..aa85a2907 100644 --- a/MongoDB/include/Poco/MongoDB/ObjectId.h +++ b/MongoDB/include/Poco/MongoDB/ObjectId.h @@ -46,8 +46,12 @@ class MongoDB_API ObjectId public: typedef SharedPtr Ptr; - ObjectId(const std::string& id = ""); - /// Constructor + ObjectId(const std::string& id); + /// Constructor. The string must contain a hexidecimal representation + /// of an object id. This means a string of 24 characters. + + ObjectId(const ObjectId& copy); + /// Copy constructor. virtual ~ObjectId(); /// Destructor @@ -61,10 +65,19 @@ public: /// of the ID char array. private: + + ObjectId(); + /// Constructor. Creates an empty Id + unsigned char _id[12]; friend class BSONWriter; friend class BSONReader; + friend class Document; + + static int fromHex(char c); + + static char fromHex(const char* c); }; @@ -79,6 +92,21 @@ inline Timestamp ObjectId::timestamp() const return Timestamp::fromEpochTime((time_t) time); } +inline int ObjectId::fromHex(char c) +{ + if ( '0' <= c && c <= '9' ) + return c - '0'; + if ( 'a' <= c && c <= 'f' ) + return c - 'a' + 10; + if ( 'A' <= c && c <= 'F' ) + return c - 'A' + 10; + return 0xff; +} + +inline char ObjectId::fromHex(const char* c) +{ + return (char)((fromHex(c[0]) << 4 ) | fromHex(c[1])); +} // BSON Embedded Document // spec: ObjectId @@ -89,7 +117,7 @@ struct ElementTraits static std::string toString(const ObjectId::Ptr& id, int indent = 0, - const std::string& fmt = "%x") + const std::string& fmt = "%02x") { return id->toString(fmt); } diff --git a/MongoDB/src/ObjectId.cpp b/MongoDB/src/ObjectId.cpp index 257fa1c18..0111c7af7 100644 --- a/MongoDB/src/ObjectId.cpp +++ b/MongoDB/src/ObjectId.cpp @@ -15,7 +15,6 @@ // SPDX-License-Identifier: BSL-1.0 // - #include "Poco/MongoDB/ObjectId.h" #include "Poco/Format.h" @@ -23,21 +22,26 @@ namespace Poco { namespace MongoDB { +ObjectId::ObjectId() +{ + memset(_id, 0, sizeof(_id)); +} ObjectId::ObjectId(const std::string& id) { - if (id.size() == 12) - { - std::string::const_iterator it = id.begin(); - std::string::const_iterator end = id.end(); - for (int i = 0; i < 12; ++it, ++i) _id[i] = *it; - } - else if (id.size()) - { - throw Poco::InvalidArgumentException("ID must be 12 characters long."); + poco_assert_dbg(id.size() == 24); + + const char *p = id.c_str(); + for (std::size_t i = 0; i < 12; ++i) { + _id[i] = fromHex(p); + p += 2; } } +ObjectId::ObjectId(const ObjectId& copy) +{ + memcpy(_id, copy._id, sizeof(_id)); +} ObjectId::~ObjectId() { diff --git a/MongoDB/testsuite/src/MongoDBTest.cpp b/MongoDB/testsuite/src/MongoDBTest.cpp index 6ee5731d6..09024c75c 100644 --- a/MongoDB/testsuite/src/MongoDBTest.cpp +++ b/MongoDB/testsuite/src/MongoDBTest.cpp @@ -402,21 +402,7 @@ void MongoDBTest::testConnectionPool() void MongoDBTest::testObjectID() { - std::string str; - str.append(1, (char) 0x53); - str.append(1, (char) 0x6A); - str.append(1, (char) 0xEE); - str.append(1, (char) 0xBB); - str.append(1, (char) 0xA0); - str.append(1, (char) 0x81); - str.append(1, (char) 0xDE); - str.append(1, (char) 0x68); - str.append(1, (char) 0x15); - str.append(1, (char) 0x00); - str.append(1, (char) 0x00); - str.append(1, (char) 0x02); - - ObjectId oid(str); + ObjectId oid("536aeebba081de6815000002"); std::string str2 = oid.toString(); assert(str2 == "536aeebba081de6815000002"); }