forked from vapor/postgres-kit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPostgreSQLMessageParser.swift
53 lines (45 loc) · 1.55 KB
/
PostgreSQLMessageParser.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
import Async
import Bits
import Foundation
/// Byte-stream parser for `PostgreSQLMessage`
final class PostgreSQLMessageParser: TranslatingStream {
/// See `TranslatingStream.Input`
typealias Input = ByteBuffer
/// See `TranslatingStream.Output`
typealias Output = PostgreSQLMessage
/// Data being worked on currently.
var buffered: Data
/// Excess data waiting to be parsed.
var excess: Data?
/// Creates a new `PostgreSQLMessageParser`.
init() {
buffered = Data()
}
/// See TranslatingStream.translate
func translate(input: ByteBuffer) throws -> Future<TranslatingStreamResult<PostgreSQLMessage>> {
let result: TranslatingStreamResult<PostgreSQLMessage>
if let excess = self.excess {
self.excess = nil
result = try parse(data: excess)
} else {
result = try parse(data: Data(input))
}
return Future(result)
}
/// Parses the data, setting `excess` or requesting more data if insufficient.
func parse(data: Data) throws -> TranslatingStreamResult<PostgreSQLMessage> {
let data = buffered + data
guard let (message, remaining) = try PostgreSQLMessageDecoder().decode(data) else {
buffered.append(data)
return .insufficient
}
buffered = .init()
if remaining > 0 {
let start = data.count - remaining
excess = data[start..<data.count]
return .excess(message)
} else {
return .sufficient(message)
}
}
}