@@ -76,7 +76,7 @@ public final class GenericStreamReader : StreamReader {
76
76
}
77
77
78
78
public func readData< T> ( size: Int , allowReadingLess: Bool , updateReadPosition: Bool , _ handler: ( UnsafeRawBufferPointer ) throws -> T ) throws -> T {
79
- let ret = try readDataNoCurrentPosIncrement ( size: size, allowReadingLess : allowReadingLess)
79
+ let ret = try readDataNoCurrentPosIncrement ( size: size, readContraints : allowReadingLess ? . readUntilSizeOrStreamEnd : . getExactSize )
80
80
if updateReadPosition {
81
81
currentReadPosition += ret. count
82
82
bufferValidLength -= ret. count
@@ -95,7 +95,7 @@ public final class GenericStreamReader : StreamReader {
95
95
var searchOffset = 0
96
96
repeat {
97
97
assert ( bufferValidLength - searchOffset >= 0 , " INTERNAL LOGIC ERROR " )
98
- var bufferStart = buffer + bufferStartPos
98
+ let bufferStart = buffer + bufferStartPos
99
99
let bufferSearchData = UnsafeRawBufferPointer ( start: bufferStart + searchOffset, count: bufferValidLength - searchOffset)
100
100
if let match = matchDelimiters ( inData: bufferSearchData, usingMatchingMode: matchingMode, includeDelimiter: includeDelimiter, minDelimiterLength: minDelimiterLength, withUnmatchedDelimiters: & unmatchedDelimiters, matchedDatas: & matchedDatas) {
101
101
let returnedLength = searchOffset + match. length
@@ -110,44 +110,12 @@ public final class GenericStreamReader : StreamReader {
110
110
/* No confirmed match. We have to continue reading the data! */
111
111
searchOffset = max ( 0 , bufferValidLength - maxDelimiterLength + 1 )
112
112
113
- if bufferStartPos + bufferValidLength >= bufferSize {
114
- /* The buffer is not big enough to hold new data... Let's move the
115
- * data to the beginning of the buffer or create a new buffer. */
116
- if bufferStartPos > 0 {
117
- /* We can move the data to the beginning of the buffer. */
118
- assert ( bufferStart != buffer)
119
- buffer. copyMemory ( from: bufferStart, byteCount: bufferValidLength)
120
- bufferStart = buffer
121
- bufferStartPos = 0
122
- } else {
123
- /* The buffer is not big enough anymore. We need to create a new,
124
- * bigger one. */
125
- assert ( bufferStartPos == 0 )
126
-
127
- let oldBuffer = buffer
128
-
129
- bufferSize += bufferSizeIncrement
130
- buffer = UnsafeMutableRawPointer . allocate ( byteCount: bufferSize, alignment: MemoryLayout< UInt8> . alignment)
131
- buffer. copyMemory ( from: bufferStart, byteCount: bufferValidLength)
132
- bufferStart = buffer
133
-
134
- oldBuffer. deallocate ( )
135
- }
136
- }
137
-
138
- /* Let's read from the stream now! */
139
- let sizeToRead : Int
140
- let unmaxedSizeToRead = bufferSize - ( bufferStartPos + bufferValidLength) /* The remaining space in the buffer */
141
- if let maxTotalReadBytesCount = readSizeLimit { sizeToRead = min ( unmaxedSizeToRead, max ( 0 , maxTotalReadBytesCount - totalReadBytesCount) /* Number of bytes remaining allowed to be read */) }
142
- else { sizeToRead = unmaxedSizeToRead}
143
-
144
- assert ( sizeToRead >= 0 )
145
- if sizeToRead == 0 { /* End of the (allowed) data */break }
146
- let sizeRead = try sourceStream. read ( bufferStart + bufferValidLength, maxLength: sizeToRead)
113
+ let sizeInBufferBeforeRead = bufferValidLength
114
+ let sizeRemainingInBuffer = bufferSize - ( bufferStartPos + bufferValidLength)
115
+ let sizeToRead = ( sizeRemainingInBuffer > 0 ? sizeRemainingInBuffer : bufferSizeIncrement)
116
+ let sizeRead = try readDataNoCurrentPosIncrement ( size: sizeInBufferBeforeRead + sizeToRead, readContraints: . readFromStreamMaxOnce) . count - sizeInBufferBeforeRead
147
117
guard sizeRead > 0 else { /* End of the data */break }
148
- bufferValidLength += sizeRead
149
- totalReadBytesCount += sizeRead
150
- assert ( readSizeLimit == nil || totalReadBytesCount <= readSizeLimit!)
118
+ assert ( sizeRead >= 0 )
151
119
} while true
152
120
153
121
if let match = findBestMatch ( fromMatchedDatas: matchedDatas, usingMatchingMode: matchingMode) {
@@ -194,10 +162,20 @@ public final class GenericStreamReader : StreamReader {
194
162
/** The total number of bytes read from the source stream. */
195
163
private var totalReadBytesCount = 0
196
164
197
- private func readDataNoCurrentPosIncrement( size: Int , allowReadingLess: Bool ) throws -> UnsafeRawBufferPointer {
165
+ private enum ReadContraints {
166
+ case getExactSize
167
+ case readUntilSizeOrStreamEnd
168
+ case readFromStreamMaxOnce
169
+
170
+ var allowReadingLess : Bool {
171
+ return self != . getExactSize
172
+ }
173
+ }
174
+
175
+ private func readDataNoCurrentPosIncrement( size: Int , readContraints: ReadContraints ) throws -> UnsafeRawBufferPointer {
198
176
let allowedToBeRead = readSizeLimit. flatMap { $0 - currentReadPosition }
199
177
if let allowedToBeRead = allowedToBeRead, allowedToBeRead <= size {
200
- guard allowReadingLess else {
178
+ guard readContraints . allowReadingLess else {
201
179
throw StreamReaderError . notEnoughData ( wouldReachReadSizeLimit: true )
202
180
}
203
181
if allowedToBeRead == 0 {
@@ -207,7 +185,7 @@ public final class GenericStreamReader : StreamReader {
207
185
208
186
/* We constrain the size to the maximum allowed to be read. */
209
187
let size = allowedToBeRead. flatMap { min ( size, $0) } ?? size
210
- return try readDataNoCurrentPosIncrementAssumingSizeIsConstrainedToAllowed ( size: size, allowReadingLess : allowReadingLess )
188
+ return try readDataNoCurrentPosIncrementAssumingSizeIsConstrainedToAllowed ( size: size, readContraints : readContraints )
211
189
}
212
190
213
191
/**
@@ -218,18 +196,17 @@ public final class GenericStreamReader : StreamReader {
218
196
219
197
- Parameter size: The size of the data to return. Assumed to be small enough
220
198
not to break the `readSizeLimit` contract.
221
- - Parameter allowReadingLess: If `true`, this method may read less data than
222
- asked in the `dataSize` parameter.
199
+ - Parameter readContraints: Read contraints on the stream.
223
200
- Throws: `StreamReaderError` in case of error.
224
201
- Returns: The read data from the buffer or the stream if necessary. */
225
- private func readDataNoCurrentPosIncrementAssumingSizeIsConstrainedToAllowed( size: Int , allowReadingLess : Bool ) throws -> UnsafeRawBufferPointer {
202
+ private func readDataNoCurrentPosIncrementAssumingSizeIsConstrainedToAllowed( size: Int , readContraints : ReadContraints ) throws -> UnsafeRawBufferPointer {
226
203
let bufferStart = buffer + bufferStartPos
227
204
228
205
switch size {
229
206
case let s where s <= bufferSize - bufferStartPos:
230
207
/* The buffer is big enough to hold the size we want to read, from
231
208
* buffer start pos. */
232
- return try readDataNoCurrentPosIncrementAssumingSizeIsConstrainedToAllowedAndBufferIsBigEnough ( dataSize: size, allowReadingLess : allowReadingLess )
209
+ return try readDataNoCurrentPosIncrementAssumingSizeIsConstrainedToAllowedAndBufferIsBigEnough ( dataSize: size, readContraints : readContraints )
233
210
234
211
case let s where s <= defaultBufferSize:
235
212
/* The default sized buffer is enough to hold the size we want to read.
@@ -247,15 +224,15 @@ public final class GenericStreamReader : StreamReader {
247
224
buffer. copyMemory ( from: bufferStart, byteCount: bufferValidLength)
248
225
}
249
226
bufferStartPos = 0
250
- return try readDataNoCurrentPosIncrementAssumingSizeIsConstrainedToAllowedAndBufferIsBigEnough ( dataSize: size, allowReadingLess : allowReadingLess )
227
+ return try readDataNoCurrentPosIncrementAssumingSizeIsConstrainedToAllowedAndBufferIsBigEnough ( dataSize: size, readContraints : readContraints )
251
228
252
229
case let s where s <= bufferSize:
253
230
/* The current buffer total size is enough to hold the size we want to
254
231
* read. However, we must relocate data in the buffer so the buffer
255
232
* start position is 0. */
256
233
buffer. copyMemory ( from: bufferStart, byteCount: bufferValidLength)
257
234
bufferStartPos = 0
258
- return try readDataNoCurrentPosIncrementAssumingSizeIsConstrainedToAllowedAndBufferIsBigEnough ( dataSize: size, allowReadingLess : allowReadingLess )
235
+ return try readDataNoCurrentPosIncrementAssumingSizeIsConstrainedToAllowedAndBufferIsBigEnough ( dataSize: size, readContraints : readContraints )
259
236
260
237
default :
261
238
/* The buffer is not big enough to hold the data we want to read. We
@@ -268,7 +245,7 @@ public final class GenericStreamReader : StreamReader {
268
245
bufferStartPos = 0
269
246
oldBuffer. deallocate ( )
270
247
271
- return try readDataNoCurrentPosIncrementAssumingSizeIsConstrainedToAllowedAndBufferIsBigEnough ( dataSize: size, allowReadingLess : allowReadingLess )
248
+ return try readDataNoCurrentPosIncrementAssumingSizeIsConstrainedToAllowedAndBufferIsBigEnough ( dataSize: size, readContraints : readContraints )
272
249
}
273
250
}
274
251
@@ -282,11 +259,10 @@ public final class GenericStreamReader : StreamReader {
282
259
limit is reached.
283
260
284
261
- Parameter dataSize: The size of the data to return.
285
- - Parameter allowReadingLess: If `true`, this method may read less data than
286
- asked in the `dataSize` parameter.
262
+ - Parameter readContraints: Read contraints on the stream.
287
263
- Throws: `StreamReaderError` in case of error.
288
264
- Returns: The read data from the buffer or the stream if necessary. */
289
- private func readDataNoCurrentPosIncrementAssumingSizeIsConstrainedToAllowedAndBufferIsBigEnough( dataSize size: Int , allowReadingLess : Bool ) throws -> UnsafeRawBufferPointer {
265
+ private func readDataNoCurrentPosIncrementAssumingSizeIsConstrainedToAllowedAndBufferIsBigEnough( dataSize size: Int , readContraints : ReadContraints ) throws -> UnsafeRawBufferPointer {
290
266
assert ( bufferSize - bufferStartPos >= size)
291
267
292
268
let bufferStart = buffer + bufferStartPos
@@ -304,14 +280,15 @@ public final class GenericStreamReader : StreamReader {
304
280
totalReadBytesCount += sizeRead
305
281
assert ( readSizeLimit == nil || totalReadBytesCount <= readSizeLimit!)
306
282
283
+ if readContraints == . readFromStreamMaxOnce { break }
307
284
guard sizeRead > 0 else {
308
- if allowReadingLess { break }
309
- else { throw StreamReaderError . notEnoughData ( wouldReachReadSizeLimit: false ) }
285
+ if readContraints . allowReadingLess { break }
286
+ else { throw StreamReaderError . notEnoughData ( wouldReachReadSizeLimit: false ) }
310
287
}
311
288
} while bufferValidLength < size /* Reading until we have enough data in the buffer. */
312
289
}
313
290
314
- assert ( allowReadingLess || bufferValidLength >= size)
291
+ assert ( readContraints . allowReadingLess || bufferValidLength >= size)
315
292
return UnsafeRawBufferPointer ( start: bufferStart, count: min ( bufferValidLength, size) )
316
293
}
317
294
0 commit comments