@@ -21,12 +21,10 @@ struct ServerEventParser: EventParser {
2121 self . mode = mode
2222 }
2323
24- static let lf : UInt8 = 0x0A
25- static let cr : UInt8 = 0x0D
26- static let colon : UInt8 = 0x3A
2724
2825 mutating func parse( _ data: Data ) -> [ EVEvent ] {
29- let ( separatedMessages, remainingData) = splitBuffer ( for: buffer + data)
26+ let ( separatedMessages, remainingData) = ( buffer + data) . split ( separators: doubleSeparators)
27+
3028 buffer = remainingData
3129 return parseBuffer ( for: separatedMessages)
3230 }
@@ -37,83 +35,4 @@ struct ServerEventParser: EventParser {
3735
3836 return messages
3937 }
40-
41- private func splitBuffer( for data: Data ) -> ( completeData: [ Data ] , remainingData: Data ) {
42- let separators : [ [ UInt8 ] ] = [ [ Self . cr, Self . cr] , [ Self . lf, Self . lf] , [ Self . cr, Self . lf, Self . cr, Self . lf] ]
43-
44- // find last range of our separator, most likely to be fast enough
45- let ( chosenSeparator, lastSeparatorRange) = findLastSeparator ( in: data, separators: separators)
46- guard let separator = chosenSeparator, let lastSeparator = lastSeparatorRange else {
47- return ( [ ] , data)
48- }
49-
50- // chop everything before the last separator, going forward, O(n) complexity
51- let bufferRange = data. startIndex ..< lastSeparator. upperBound
52- let remainingRange = lastSeparator. upperBound ..< data. endIndex
53- let rawMessages : [ Data ] = if #available( macOS 13 . 0 , iOS 16 . 0 , watchOS 9 . 0 , tvOS 16 . 0 , visionOS 1 . 0 , * ) {
54- data [ bufferRange] . split ( separator: separator)
55- } else {
56- data [ bufferRange] . split ( by: separator)
57- }
58-
59- // now clean up the messages and return
60- let cleanedMessages = rawMessages. map { cleanMessageData ( $0) }
61- return ( cleanedMessages, data [ remainingRange] )
62- }
63-
64- private func findLastSeparator( in data: Data , separators: [ [ UInt8 ] ] ) -> ( [ UInt8 ] ? , Range < Data . Index > ? ) {
65- var chosenSeparator : [ UInt8 ] ?
66- var lastSeparatorRange : Range < Data . Index > ?
67- for separator in separators {
68- if let range = data. lastRange ( of: separator) {
69- if lastSeparatorRange == nil || range. upperBound > lastSeparatorRange!. upperBound {
70- chosenSeparator = separator
71- lastSeparatorRange = range
72- }
73- }
74- }
75- return ( chosenSeparator, lastSeparatorRange)
76- }
77-
78- private func cleanMessageData( _ messageData: Data ) -> Data {
79- var cleanData = messageData
80-
81- // remove trailing CR/LF characters from the end
82- while !cleanData. isEmpty, cleanData. last == Self . cr || cleanData. last == Self . lf {
83- cleanData = cleanData. dropLast ( )
84- }
85-
86- // also clean internal lines within each message to remove trailing \r
87- let cleanedLines = cleanData. split ( separator: Self . lf)
88- . map { line in line. trimming ( while: { $0 == Self . cr } ) }
89- . joined ( separator: [ Self . lf] )
90-
91- return Data ( cleanedLines)
92- }
93- }
94-
95- fileprivate extension Data {
96- @available ( macOS, deprecated: 13.0 , obsoleted: 13.0 , message: " This method is not recommended on macOS 13.0+ " )
97- @available ( iOS, deprecated: 16.0 , obsoleted: 16.0 , message: " This method is not recommended on iOS 16.0+ " )
98- @available ( watchOS, deprecated: 9.0 , obsoleted: 9.0 , message: " This method is not recommended on watchOS 9.0+ " )
99- @available ( tvOS, deprecated: 16.0 , obsoleted: 16.0 , message: " This method is not recommended on tvOS 16.0+ " )
100- @available ( visionOS, deprecated: 1.0 , obsoleted: 1.1 , message: " This method is not recommended on visionOS 1.0+ " )
101- func split( by separator: [ UInt8 ] ) -> [ Data ] {
102- var chunks : [ Data ] = [ ]
103- var pos = startIndex
104- // Find next occurrence of separator after current position
105- while let r = self [ pos... ] . range ( of: Data ( separator) ) {
106- // Append if non-empty
107- if r. lowerBound > pos {
108- chunks. append ( self [ pos..< r. lowerBound] )
109- }
110- // Update current position
111- pos = r. upperBound
112- }
113- // Append final chunk, if non-empty
114- if pos < endIndex {
115- chunks. append ( self [ pos..< endIndex] )
116- }
117- return chunks
118- }
11938}
0 commit comments