Skip to content

Commit

Permalink
Start developing Decimal128
Browse files Browse the repository at this point in the history
  • Loading branch information
Joannis committed Jan 12, 2023
1 parent d4582d8 commit 1e98bdf
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 8 deletions.
7 changes: 5 additions & 2 deletions Sources/BSON/Document/Document+Cache.swift
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,14 @@ extension Document {
case .int32:
return self.storage.getInteger(at: offset, endianness: .little, as: Int32.self)
case .decimal128:
guard let slice = storage.getBytes(at: offset, length: 16) else {
guard
let low: UInt64 = storage.getInteger(at: offset),
let high: UInt64 = storage.getInteger(at: offset)
else {
return nil
}

return Decimal128(slice)
return Decimal128(low: low, high: high)
}
}
}
3 changes: 2 additions & 1 deletion Sources/BSON/Document/Document+Dictionary.swift
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,8 @@ extension Document: ExpressibleByDictionaryLiteral {
storage.writeInteger(int, endianness: .little)
case let decimal128 as Decimal128:
writeKey(.decimal128)
storage.writeBytes(decimal128.storage)
storage.writeInteger(decimal128.low)
storage.writeInteger(decimal128.high)
case is MaxKey: // 0x7F
writeKey(.maxKey)
case is MinKey: // 0xFF
Expand Down
28 changes: 23 additions & 5 deletions Sources/BSON/Types/Decimal128.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,30 @@ import NIOCore
///
/// OpenKitten BSON currently does not support the handling of Decimal128 values. The type is a stub and provides no API. It serves as a point for future implementation.
public struct Decimal128: Primitive, Hashable {
var storage: [UInt8]
private static let exponentBitCount: UInt64 = 14
private static let exponentBitMask: Int = 0b1111_1111_1111_11
private static let significandBitCount: UInt64 = 110
private static let nanBits = 0b11111
private static let infinityBits = 0b11110

internal init(_ storage: [UInt8]) {
Swift.assert(storage.count == 16)

self.storage = storage
public var isNegative: Bool {
high >> 58 == 1
}

public var isInfinity: Bool {
high >> 58 & 0b011111 == Self.infinityBits
}

public var isNaN: Bool {
high >> 58 & 0b011111 == Self.nanBits
}

let low: UInt64
let high: UInt64

internal init(low: UInt64, high: UInt64) {
self.low = low
self.high = high
}

public func encode(to encoder: Encoder) throws {
Expand Down

0 comments on commit 1e98bdf

Please sign in to comment.