forked from vapor/postgres-kit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPostgreSQLData+FixedWidthInteger.swift
93 lines (88 loc) · 3.67 KB
/
PostgreSQLData+FixedWidthInteger.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
extension FixedWidthInteger {
/// See `PostgreSQLDataConvertible`.
public static func convertFromPostgreSQLData(_ data: PostgreSQLData) throws -> Self {
switch data.storage {
case .binary(let value):
let i: Self?
switch data.type {
case .int2:
guard value.count == 2 else {
throw PostgreSQLError.decode(self, from: data)
}
i = value.as(Int16.self, default: 0).bigEndian.cast(to: Self.self)
case .int4, .regproc:
guard value.count == 4 else {
throw PostgreSQLError.decode(self, from: data)
}
i = value.as(Int32.self, default: 0).bigEndian.cast(to: Self.self)
case .oid:
guard value.count == 4 else {
throw PostgreSQLError.decode(self, from: data)
}
i = value.as(UInt32.self, default: 0).bigEndian.cast(to: Self.self)
case .int8:
guard value.count == 8 else {
throw PostgreSQLError.decode(self, from: data)
}
i = value.as(Int64.self, default: 0).bigEndian.cast(to: Self.self)
case .numeric:
guard let int = try Self(String.convertFromPostgreSQLData(data)) else {
throw PostgreSQLError.decode(Int.self, from: data)
}
i = int
default: throw PostgreSQLError.decode(self, from: data)
}
guard let value = i else {
throw PostgreSQLError.decode(self, from: data)
}
return value
case .text(let string):
switch data.type {
case .char, .bpchar:
guard string.count == 1, let char = Data(string.utf8).as(Int8.self, default: 0).bigEndian.cast(to: Self.self) else {
throw PostgreSQLError.decode(self, from: data)
}
return char
default:
guard let converted = Self(string) else {
throw PostgreSQLError.decode(self, from: data)
}
return converted
}
case .null: throw PostgreSQLError.decode(self, from: data)
}
}
/// See `PostgreSQLDataConvertible`.
public func convertToPostgreSQLData() throws -> PostgreSQLData {
let type: PostgreSQLDataFormat
switch Self.bitWidth {
case 8:
let data: PostgreSQLData?
if Self.isSigned {
data = try cast(to: Int16.self)?.convertToPostgreSQLData()
} else {
data = try cast(to: UInt16.self)?.convertToPostgreSQLData()
}
guard let d = data else {
throw PostgreSQLError(identifier: "singleByteInt", reason: "Could not convert \(Self.self) to PostgreSQLData: \(self)")
}
return d
case 16: type = .int2
case 32: type = .int4
case 64: type = .int8
default: fatalError("Integer bit width not supported: \(Self.bitWidth)")
}
return PostgreSQLData(type, binary: Data.of(bigEndian))
}
/// Safely casts one `FixedWidthInteger` to another.
}
extension Int: PostgreSQLDataConvertible {}
extension Int8: PostgreSQLDataConvertible {}
extension Int16: PostgreSQLDataConvertible {}
extension Int32: PostgreSQLDataConvertible {}
extension Int64: PostgreSQLDataConvertible {}
extension UInt: PostgreSQLDataConvertible {}
extension UInt8: PostgreSQLDataConvertible {}
extension UInt16: PostgreSQLDataConvertible {}
extension UInt32: PostgreSQLDataConvertible {}
extension UInt64: PostgreSQLDataConvertible {}