| 1 | // |
| 2 | // Array.h |
| 3 | // |
| 4 | // Library: MongoDB |
| 5 | // Package: MongoDB |
| 6 | // Module: ObjectId |
| 7 | // |
| 8 | // Definition of the ObjectId class. |
| 9 | // |
| 10 | // Copyright (c) 2012, Applied Informatics Software Engineering GmbH. |
| 11 | // and Contributors. |
| 12 | // |
| 13 | // SPDX-License-Identifier: BSL-1.0 |
| 14 | // |
| 15 | |
| 16 | |
| 17 | #ifndef MongoDB_ObjectId_INCLUDED |
| 18 | #define MongoDB_ObjectId_INCLUDED |
| 19 | |
| 20 | |
| 21 | #include "Poco/MongoDB/MongoDB.h" |
| 22 | #include "Poco/MongoDB/Element.h" |
| 23 | #include "Poco/Timestamp.h" |
| 24 | |
| 25 | |
| 26 | namespace Poco { |
| 27 | namespace MongoDB { |
| 28 | |
| 29 | |
| 30 | class MongoDB_API ObjectId |
| 31 | /// ObjectId is a 12-byte BSON type, constructed using: |
| 32 | /// |
| 33 | /// - a 4-byte timestamp, |
| 34 | /// - a 3-byte machine identifier, |
| 35 | /// - a 2-byte process id, and |
| 36 | /// - a 3-byte counter, starting with a random value. |
| 37 | /// |
| 38 | /// In MongoDB, documents stored in a collection require a unique _id field that acts |
| 39 | /// as a primary key. Because ObjectIds are small, most likely unique, and fast to generate, |
| 40 | /// MongoDB uses ObjectIds as the default value for the _id field if the _id field is not |
| 41 | /// specified; i.e., the mongod adds the _id field and generates a unique ObjectId to assign |
| 42 | /// as its value. |
| 43 | { |
| 44 | public: |
| 45 | typedef SharedPtr<ObjectId> Ptr; |
| 46 | |
| 47 | explicit ObjectId(const std::string& id); |
| 48 | /// Creates an ObjectId from a string. |
| 49 | /// |
| 50 | /// The string must contain a hexadecimal representation |
| 51 | /// of an object ID. This means a string of 24 characters. |
| 52 | |
| 53 | ObjectId(const ObjectId& copy); |
| 54 | /// Creates an ObjectId by copying another one. |
| 55 | |
| 56 | virtual ~ObjectId(); |
| 57 | /// Destroys the ObjectId. |
| 58 | |
| 59 | Timestamp timestamp() const; |
| 60 | /// Returns the timestamp which is stored in the first four bytes of the id |
| 61 | |
| 62 | std::string toString(const std::string& fmt = "%02x" ) const; |
| 63 | /// Returns the id in string format. The fmt parameter |
| 64 | /// specifies the formatting used for individual members |
| 65 | /// of the ID char array. |
| 66 | |
| 67 | private: |
| 68 | ObjectId(); |
| 69 | |
| 70 | static int fromHex(char c); |
| 71 | static char fromHex(const char* c); |
| 72 | |
| 73 | unsigned char _id[12]; |
| 74 | |
| 75 | friend class BSONWriter; |
| 76 | friend class BSONReader; |
| 77 | friend class Document; |
| 78 | }; |
| 79 | |
| 80 | |
| 81 | // |
| 82 | // inlines |
| 83 | // |
| 84 | inline Timestamp ObjectId::timestamp() const |
| 85 | { |
| 86 | int time; |
| 87 | char* T = (char *) &time; |
| 88 | T[0] = _id[3]; |
| 89 | T[1] = _id[2]; |
| 90 | T[2] = _id[1]; |
| 91 | T[3] = _id[0]; |
| 92 | return Timestamp::fromEpochTime((time_t) time); |
| 93 | } |
| 94 | |
| 95 | |
| 96 | inline int ObjectId::fromHex(char c) |
| 97 | { |
| 98 | if ( '0' <= c && c <= '9' ) |
| 99 | return c - '0'; |
| 100 | if ( 'a' <= c && c <= 'f' ) |
| 101 | return c - 'a' + 10; |
| 102 | if ( 'A' <= c && c <= 'F' ) |
| 103 | return c - 'A' + 10; |
| 104 | return 0xff; |
| 105 | } |
| 106 | |
| 107 | |
| 108 | inline char ObjectId::fromHex(const char* c) |
| 109 | { |
| 110 | return (char)((fromHex(c[0]) << 4 ) | fromHex(c[1])); |
| 111 | } |
| 112 | |
| 113 | |
| 114 | // BSON Embedded Document |
| 115 | // spec: ObjectId |
| 116 | template<> |
| 117 | struct ElementTraits<ObjectId::Ptr> |
| 118 | { |
| 119 | enum { TypeId = 0x07 }; |
| 120 | |
| 121 | static std::string toString(const ObjectId::Ptr& id, |
| 122 | int indent = 0, |
| 123 | const std::string& fmt = "%02x" ) |
| 124 | { |
| 125 | return id->toString(fmt); |
| 126 | } |
| 127 | }; |
| 128 | |
| 129 | |
| 130 | template<> |
| 131 | inline void BSONReader::read<ObjectId::Ptr>(ObjectId::Ptr& to) |
| 132 | { |
| 133 | _reader.readRaw((char*) to->_id, 12); |
| 134 | } |
| 135 | |
| 136 | |
| 137 | template<> |
| 138 | inline void BSONWriter::write<ObjectId::Ptr>(ObjectId::Ptr& from) |
| 139 | { |
| 140 | _writer.writeRaw((char*) from->_id, 12); |
| 141 | } |
| 142 | |
| 143 | |
| 144 | } } // namespace Poco::MongoDB |
| 145 | |
| 146 | |
| 147 | #endif // MongoDB_ObjectId_INCLUDED |
| 148 | |