@@ -73,6 +73,14 @@ const enum MessageCodes {
73
73
74
74
export type MessageCallback = ( msg : BackendMessage ) => void
75
75
76
+ interface CombinedBuffer {
77
+ combinedBuffer : Buffer
78
+ combinedBufferOffset : number
79
+ combinedBufferLength : number
80
+ combinedBufferFullLength : number
81
+ reuseRemainingBuffer : boolean
82
+ }
83
+
76
84
export class Parser {
77
85
private remainingBuffer : Buffer = emptyBuffer
78
86
private remainingBufferLength : number = 0
@@ -88,6 +96,41 @@ export class Parser {
88
96
}
89
97
90
98
public parse ( buffer : Buffer , callback : MessageCallback ) {
99
+ const {
100
+ combinedBuffer,
101
+ combinedBufferOffset,
102
+ combinedBufferLength,
103
+ reuseRemainingBuffer,
104
+ combinedBufferFullLength,
105
+ } = this . mergeBuffer ( buffer )
106
+ let offset = combinedBufferOffset
107
+ while ( offset + HEADER_LENGTH <= combinedBufferFullLength ) {
108
+ // code is 1 byte long - it identifies the message type
109
+ const code = combinedBuffer [ offset ]
110
+
111
+ // length is 1 Uint32BE - it is the length of the message EXCLUDING the code
112
+ const length = combinedBuffer . readUInt32BE ( offset + CODE_LENGTH )
113
+
114
+ const fullMessageLength = CODE_LENGTH + length
115
+
116
+ if ( fullMessageLength + offset <= combinedBufferFullLength ) {
117
+ const message = this . handlePacket ( offset + HEADER_LENGTH , code , length , combinedBuffer )
118
+ callback ( message )
119
+ offset += fullMessageLength
120
+ } else {
121
+ break
122
+ }
123
+ }
124
+ this . consumeBuffer ( {
125
+ combinedBuffer,
126
+ combinedBufferOffset : offset ,
127
+ combinedBufferLength,
128
+ reuseRemainingBuffer,
129
+ combinedBufferFullLength,
130
+ } )
131
+ }
132
+
133
+ private mergeBuffer ( buffer : Buffer ) : CombinedBuffer {
91
134
let combinedBuffer = buffer
92
135
let combinedBufferLength = buffer . byteLength
93
136
let combinedBufferOffset = 0
@@ -125,39 +168,37 @@ export class Parser {
125
168
combinedBufferLength = this . remainingBufferLength = newLength
126
169
combinedBufferOffset = this . remainingBufferOffset
127
170
}
128
- const fullLength = combinedBufferOffset + combinedBufferLength
129
- let offset = combinedBufferOffset
130
- while ( offset + HEADER_LENGTH <= fullLength ) {
131
- // code is 1 byte long - it identifies the message type
132
- const code = combinedBuffer [ offset ]
133
-
134
- // length is 1 Uint32BE - it is the length of the message EXCLUDING the code
135
- const length = combinedBuffer . readUInt32BE ( offset + CODE_LENGTH )
136
-
137
- const fullMessageLength = CODE_LENGTH + length
138
-
139
- if ( fullMessageLength + offset <= fullLength ) {
140
- const message = this . handlePacket ( offset + HEADER_LENGTH , code , length , combinedBuffer )
141
- callback ( message )
142
- offset += fullMessageLength
143
- } else {
144
- break
145
- }
171
+ const combinedBufferFullLength = combinedBufferOffset + combinedBufferLength
172
+ return {
173
+ combinedBuffer,
174
+ combinedBufferOffset,
175
+ combinedBufferLength,
176
+ reuseRemainingBuffer,
177
+ combinedBufferFullLength,
146
178
}
147
- if ( offset === fullLength ) {
179
+ }
180
+
181
+ private consumeBuffer ( {
182
+ combinedBufferOffset,
183
+ combinedBufferFullLength,
184
+ reuseRemainingBuffer,
185
+ combinedBuffer,
186
+ combinedBufferLength,
187
+ } : CombinedBuffer ) {
188
+ if ( combinedBufferOffset === combinedBufferFullLength ) {
148
189
// No more use for the buffer
149
190
this . remainingBuffer = emptyBuffer
150
191
this . remainingBufferLength = 0
151
192
this . remainingBufferOffset = 0
152
193
} else {
153
- this . remainingBufferLength = fullLength - offset
194
+ this . remainingBufferLength = combinedBufferFullLength - combinedBufferOffset
154
195
if ( reuseRemainingBuffer ) {
155
196
// Adjust the cursors of remainingBuffer
156
- this . remainingBufferOffset = offset
197
+ this . remainingBufferOffset = combinedBufferOffset
157
198
} else {
158
199
// To avoid side effects, copy the remaining part of the new buffer to remainingBuffer with extra space for next buffer
159
200
this . remainingBuffer = Buffer . allocUnsafe ( combinedBufferLength * 2 )
160
- combinedBuffer . copy ( this . remainingBuffer , 0 , offset )
201
+ combinedBuffer . copy ( this . remainingBuffer , 0 , combinedBufferOffset )
161
202
this . remainingBufferOffset = 0
162
203
}
163
204
}
0 commit comments