@@ -463,9 +463,10 @@ public struct DBPointer: BSONValue, Codable, Equatable {
463463 }
464464
465465 public func encode( to storage: DocumentStorage , forKey key: String ) throws {
466- var oid = try ObjectId . toLibBSONType ( self . id. oid) // TODO: use the stored bson_oid_t (SWIFT-268)
467- guard bson_append_dbpointer ( storage. pointer, key, Int32 ( key. utf8. count) , self . ref, & oid) else {
468- throw bsonTooLargeError ( value: self , forKey: key)
466+ try withUnsafePointer ( to: id. oid) { oidPtr in
467+ guard bson_append_dbpointer ( storage. pointer, key, Int32 ( key. utf8. count) , self . ref, oidPtr) else {
468+ throw bsonTooLargeError ( value: self , forKey: key)
469+ }
469470 }
470471 }
471472
@@ -490,7 +491,7 @@ public struct DBPointer: BSONValue, Codable, Equatable {
490491 throw wrongIterTypeError ( iter, expected: DBPointer . self)
491492 }
492493
493- return DBPointer ( ref: String ( cString: collectionP) , id: ObjectId ( fromPointer : oidP) )
494+ return DBPointer ( ref: String ( cString: collectionP) , id: ObjectId ( bsonOid : oidP. pointee ) )
494495 }
495496 }
496497}
@@ -870,36 +871,47 @@ public struct ObjectId: BSONValue, Equatable, CustomStringConvertible, Codable {
870871 public var bsonType : BSONType { return . objectId }
871872
872873 /// This `ObjectId`'s data represented as a `String`.
873- public let oid : String
874+ public var hex : String {
875+ var str = Data ( count: 25 )
876+ return str. withUnsafeMutableBytes { ( rawBuffer: UnsafeMutablePointer < Int8 > ) in
877+ withUnsafePointer ( to: self . oid) { oidPtr in
878+ bson_oid_to_string ( oidPtr, rawBuffer)
879+ }
880+ return String ( cString: rawBuffer)
881+ }
882+ }
874883
875884 /// The timestamp used to create this `ObjectId`
876- public let timestamp : UInt32
885+ public var timestamp : UInt32 {
886+ return withUnsafePointer ( to: self . oid) { oidPtr in UInt32 ( bson_oid_get_time_t ( oidPtr) ) }
887+ }
877888
878- /// Initializes a new `ObjectId`.
879- public init ( ) {
880- var oid_t = bson_oid_t ( )
881- bson_oid_init ( & oid_t, nil )
882- self . init ( fromPointer: & oid_t)
889+ public var description : String {
890+ return self . hex
883891 }
884892
885- /// Initializes an `ObjectId` from the provided `String`. Assumes that the given string is a valid ObjectId.
886- /// - SeeAlso: https://github.com/mongodb/specifications/blob/master/source/objectid.rst
887- public init ( fromString oid: String ) {
893+ internal let oid : bson_oid_t
894+
895+ /// Initializes a new `ObjectId`.
896+ public init ( ) {
897+ var oid = bson_oid_t ( )
898+ bson_oid_init ( & oid, nil )
888899 self . oid = oid
889- var oid_t = bson_oid_t ( )
890- bson_oid_init_from_string ( & oid_t, oid)
891- self . timestamp = UInt32 ( bson_oid_get_time_t ( & oid_t) )
892900 }
893901
894- /// Initializes an `ObjectId` from the provided `String`. Returns `nil` if the string is not a valid
895- /// ObjectId.
902+ /// Initializes an `ObjectId` from the provided hex `String`. Returns `nil` if the string is not a valid ObjectId.
896903 /// - SeeAlso: https://github.com/mongodb/specifications/blob/master/source/objectid.rst
897- public init ? ( ifValid oid : String ) {
898- if ! bson_oid_is_valid( oid , oid . utf8. count) {
904+ public init ? ( _ hex : String ) {
905+ guard bson_oid_is_valid ( hex , hex . utf8. count) else {
899906 return nil
900- } else {
901- self . init ( fromString: oid)
902907 }
908+ var oid_t = bson_oid_t ( )
909+ bson_oid_init_from_string ( & oid_t, hex)
910+ self . oid = oid_t
911+ }
912+
913+ internal init ( bsonOid oid_t: bson_oid_t ) {
914+ self . oid = oid_t
903915 }
904916
905917 public init ( from decoder: Decoder ) throws {
@@ -910,35 +922,12 @@ public struct ObjectId: BSONValue, Equatable, CustomStringConvertible, Codable {
910922 throw bsonEncodingUnsupportedError ( value: self , at: to. codingPath)
911923 }
912924
913- /// Initializes an `ObjectId` from an `UnsafePointer<bson_oid_t>` by copying the data
914- /// from it to a `String`
915- internal init ( fromPointer oid_t: UnsafePointer < bson_oid_t > ) {
916- var str = Data ( count: 25 )
917- self . oid = str. withUnsafeMutableBytes { ( bytes: UnsafeMutablePointer < Int8 > ) in
918- bson_oid_to_string ( oid_t, bytes)
919- return String ( cString: bytes)
920- }
921- self . timestamp = UInt32 ( bson_oid_get_time_t ( oid_t) )
922- }
923-
924- /// Returns the provided string as a `bson_oid_t`.
925- /// - Throws:
926- /// - `UserError.invalidArgumentError` if the parameter string does not correspond to a valid `ObjectId`.
927- internal static func toLibBSONType( _ str: String ) throws -> bson_oid_t {
928- var value = bson_oid_t ( )
929- if !bson_oid_is_valid( str, str. utf8. count) {
930- throw UserError . invalidArgumentError ( message: " ObjectId string is invalid " )
931- }
932- bson_oid_init_from_string ( & value, str)
933- return value
934- }
935-
936925 public func encode( to storage: DocumentStorage , forKey key: String ) throws {
937- // create a new bson_oid_t with self.oid
938- var oid = try ObjectId . toLibBSONType ( self . oid)
939926 // encode the bson_oid_t to the bson_t
940- guard bson_append_oid ( storage. pointer, key, Int32 ( key. utf8. count) , & oid) else {
941- throw bsonTooLargeError ( value: self , forKey: key)
927+ try withUnsafePointer ( to: self . oid) { oidPtr in
928+ guard bson_append_oid ( storage. pointer, key, Int32 ( key. utf8. count) , oidPtr) else {
929+ throw bsonTooLargeError ( value: self , forKey: key)
930+ }
942931 }
943932 }
944933
@@ -947,16 +936,16 @@ public struct ObjectId: BSONValue, Equatable, CustomStringConvertible, Codable {
947936 guard let oid = bson_iter_oid ( iterPtr) else {
948937 throw wrongIterTypeError ( iter, expected: ObjectId . self)
949938 }
950- return self . init ( fromPointer : oid)
939+ return self . init ( bsonOid : oid. pointee )
951940 }
952941 }
953942
954- public var description : String {
955- return self . oid
956- }
957-
958943 public static func == ( lhs: ObjectId , rhs: ObjectId ) -> Bool {
959- return lhs. oid == rhs. oid
944+ return withUnsafePointer ( to: lhs. oid) { lhsOidPtr in
945+ withUnsafePointer ( to: rhs. oid) { rhsOidPtr in
946+ bson_oid_equal ( lhsOidPtr, rhsOidPtr)
947+ }
948+ }
960949 }
961950}
962951
0 commit comments