rastrillo / native Public

Clone
git clone https://amadan.net/rastrillo/native

Plain git — no account needed to clone.

Download

Download this file

1import Foundation
2
3/// Bound before decoding: AsyncBytes.lines can allocate an unbounded line.
4/// Package access so ScriptedTransport frames streams exactly as NativeHTTP does.
5package struct NativeStreamLines {
6 private var buffer = Data()
7 private var eventBytes = 0
8 private var afterCR = false
9 private var firstLine = true
10 let lineLimit: Int
11 let eventLimit: Int
12
13 package init(lineLimit: Int = 256 * 1024, eventLimit: Int = 1024 * 1024) {
14 self.lineLimit = lineLimit
15 self.eventLimit = eventLimit
16 }
17
18 package mutating func append(_ byte: UInt8) throws -> String? {
19 if afterCR {
20 afterCR = false
21 if byte == 10 { return nil }
22 }
23 if byte == 10 || byte == 13 {
24 afterCR = byte == 13
25 guard var line = String(data: buffer, encoding: .utf8) else {
26 throw NativeClientError.message("The live connection returned invalid text.")
27 }
28 if firstLine {
29 firstLine = false
30 if line.hasPrefix("\u{FEFF}") { line.removeFirst() }
31 }
32 buffer.removeAll(keepingCapacity: true)
33 if line.isEmpty { eventBytes = 0 }
34 return line
35 }
36 guard buffer.count < lineLimit, eventBytes < eventLimit else {
37 throw NativeClientError.message("The live update is too large. Reconnect to refresh it.")
38 }
39 buffer.append(byte)
40 eventBytes += 1
41 return nil
42 }
43}
44