@@ -29,7 +29,7 @@ internal struct JSONParser {
29
29
}
30
30
}
31
31
#endif
32
-
32
+
33
33
// ensure only white space is remaining
34
34
var whitespace = 0
35
35
while let next = reader. peek ( offset: whitespace) {
@@ -41,7 +41,7 @@ internal struct JSONParser {
41
41
throw JSONError . unexpectedCharacter ( ascii: next, characterIndex: reader. readerIndex + whitespace)
42
42
}
43
43
}
44
-
44
+
45
45
return value
46
46
}
47
47
@@ -107,15 +107,15 @@ internal struct JSONParser {
107
107
default :
108
108
break
109
109
}
110
-
110
+
111
111
var array = [ JSONValue] ( )
112
112
array. reserveCapacity ( 10 )
113
-
113
+
114
114
// parse values
115
115
while true {
116
116
let value = try parseValue ( )
117
117
array. append ( value)
118
-
118
+
119
119
// consume the whitespace after the value before the comma
120
120
let ascii = try reader. consumeWhitespace ( )
121
121
switch ascii {
@@ -161,7 +161,7 @@ internal struct JSONParser {
161
161
default :
162
162
break
163
163
}
164
-
164
+
165
165
var object = [ String: JSONValue] ( )
166
166
object. reserveCapacity ( 20 )
167
167
@@ -174,7 +174,7 @@ internal struct JSONParser {
174
174
reader. moveReaderIndex ( forwardBy: 1 )
175
175
try reader. consumeWhitespace ( )
176
176
object [ key] = try self . parseValue ( )
177
-
177
+
178
178
let commaOrBrace = try reader. consumeWhitespace ( )
179
179
switch commaOrBrace {
180
180
case . _closebrace:
@@ -196,26 +196,26 @@ internal struct JSONParser {
196
196
}
197
197
198
198
extension JSONParser {
199
-
199
+
200
200
struct DocumentReader {
201
201
let array : [ UInt8 ]
202
202
203
203
private( set) var readerIndex : Int = 0
204
-
204
+
205
205
private var readableBytes : Int {
206
206
self . array. endIndex - self . readerIndex
207
207
}
208
-
208
+
209
209
var isEOF : Bool {
210
210
self . readerIndex >= self . array. endIndex
211
211
}
212
-
212
+
213
213
214
214
init ( array: [ UInt8 ] ) {
215
215
self . array = array
216
216
}
217
217
218
- subscript( bounds : Range < Int > ) -> ArraySlice < UInt8 > {
218
+ subscript< R : RangeExpression < Int > > ( bounds : R ) -> ArraySlice < UInt8 > {
219
219
self . array [ bounds]
220
220
}
221
221
@@ -234,14 +234,14 @@ extension JSONParser {
234
234
guard self . readerIndex + offset < self . array. endIndex else {
235
235
return nil
236
236
}
237
-
237
+
238
238
return self . array [ self . readerIndex + offset]
239
239
}
240
-
240
+
241
241
mutating func moveReaderIndex( forwardBy offset: Int ) {
242
242
self . readerIndex += offset
243
243
}
244
-
244
+
245
245
@discardableResult
246
246
mutating func consumeWhitespace( ) throws -> UInt8 {
247
247
var whitespace = 0
@@ -255,18 +255,18 @@ extension JSONParser {
255
255
return ascii
256
256
}
257
257
}
258
-
258
+
259
259
throw JSONError . unexpectedEndOfFile
260
260
}
261
-
261
+
262
262
mutating func readString( ) throws -> String {
263
263
try self . readUTF8StringTillNextUnescapedQuote ( )
264
264
}
265
-
265
+
266
266
mutating func readNumber( ) throws -> String {
267
267
try self . parseNumber ( )
268
268
}
269
-
269
+
270
270
mutating func readBool( ) throws -> Bool {
271
271
switch self . read ( ) {
272
272
case UInt8 ( ascii: " t " ) :
@@ -314,11 +314,11 @@ extension JSONParser {
314
314
throw JSONError . unexpectedCharacter ( ascii: self . peek ( offset: - 1 ) !, characterIndex: self . readerIndex - 1 )
315
315
}
316
316
}
317
-
317
+
318
318
// MARK: - Private Methods -
319
319
320
320
// MARK: String
321
-
321
+
322
322
enum EscapedSequenceError : Swift . Error {
323
323
case expectedLowSurrogateUTF8SequenceAfterHighSurrogate( index: Int )
324
324
case unexpectedEscapedCharacter( ascii: UInt8 , index: Int )
@@ -339,10 +339,10 @@ extension JSONParser {
339
339
self . moveReaderIndex ( forwardBy: copy + 1 )
340
340
guard var result = output else {
341
341
// if we don't have an output string we create a new string
342
- return try Self . makeString ( self [ stringStartIndex ..< stringStartIndex + copy] )
342
+ return try makeString ( at : stringStartIndex ..< stringStartIndex + copy)
343
343
}
344
344
// if we have an output string we append
345
- result += try Self . makeString ( self [ stringStartIndex ..< stringStartIndex + copy] )
345
+ result += try makeString ( at : stringStartIndex ..< stringStartIndex + copy)
346
346
return result
347
347
348
348
case 0 ... 31 :
@@ -352,17 +352,17 @@ extension JSONParser {
352
352
// through U+001F).
353
353
var string = output ?? " "
354
354
let errorIndex = self . readerIndex + copy
355
- string += try Self . makeString ( self . array [ stringStartIndex ... errorIndex] )
355
+ string += try makeString ( at : stringStartIndex ... errorIndex)
356
356
throw JSONError . unescapedControlCharacterInString ( ascii: byte, in: string, index: errorIndex)
357
357
358
358
case UInt8 ( ascii: " \\ " ) :
359
359
self . moveReaderIndex ( forwardBy: copy)
360
360
if output != nil {
361
- output! += try Self . makeString ( self . array [ stringStartIndex ..< stringStartIndex + copy] )
361
+ output! += try makeString ( at : stringStartIndex ..< stringStartIndex + copy)
362
362
} else {
363
- output = try Self . makeString ( self . array [ stringStartIndex ..< stringStartIndex + copy] )
363
+ output = try makeString ( at : stringStartIndex ..< stringStartIndex + copy)
364
364
}
365
-
365
+
366
366
let escapedStartIndex = self . readerIndex
367
367
368
368
do {
@@ -371,13 +371,13 @@ extension JSONParser {
371
371
stringStartIndex = self . readerIndex
372
372
copy = 0
373
373
} catch EscapedSequenceError . unexpectedEscapedCharacter( let ascii, let failureIndex) {
374
- output! += try Self . makeString ( array [ escapedStartIndex ..< self . readerIndex] )
374
+ output! += try makeString ( at : escapedStartIndex ..< self . readerIndex)
375
375
throw JSONError . unexpectedEscapedCharacter ( ascii: ascii, in: output!, index: failureIndex)
376
376
} catch EscapedSequenceError . expectedLowSurrogateUTF8SequenceAfterHighSurrogate( let failureIndex) {
377
- output! += try Self . makeString ( array [ escapedStartIndex ..< self . readerIndex] )
377
+ output! += try makeString ( at : escapedStartIndex ..< self . readerIndex)
378
378
throw JSONError . expectedLowSurrogateUTF8SequenceAfterHighSurrogate ( in: output!, index: failureIndex)
379
379
} catch EscapedSequenceError . couldNotCreateUnicodeScalarFromUInt32( let failureIndex, let unicodeScalarValue) {
380
- output! += try Self . makeString ( array [ escapedStartIndex ..< self . readerIndex] )
380
+ output! += try makeString ( at : escapedStartIndex ..< self . readerIndex)
381
381
throw JSONError . couldNotCreateUnicodeScalarFromUInt32 (
382
382
in: output!, index: failureIndex, unicodeScalarValue: unicodeScalarValue
383
383
)
@@ -392,9 +392,10 @@ extension JSONParser {
392
392
throw JSONError . unexpectedEndOfFile
393
393
}
394
394
395
- private static func makeString< Bytes: Collection > ( _ bytes: Bytes ) throws -> String where Bytes. Element == UInt8 {
396
- guard let str = String ( bytes: bytes, encoding: . utf8) else {
397
- throw JSONError . cannotConvertInputDataToUTF8
395
+ private func makeString< R: RangeExpression < Int > > ( at range: R ) throws -> String {
396
+ let raw = array [ range]
397
+ guard let str = String ( bytes: raw, encoding: . utf8) else {
398
+ throw JSONError . invalidUTF8Sequence ( Data ( raw) , characterIndex: range. relative ( to: array) . lowerBound)
398
399
}
399
400
return str
400
401
}
@@ -510,9 +511,9 @@ extension JSONParser {
510
511
return nil
511
512
}
512
513
}
513
-
514
+
514
515
// MARK: Numbers
515
-
516
+
516
517
private enum ControlCharacter {
517
518
case operand
518
519
case decimalPoint
@@ -546,7 +547,7 @@ extension JSONParser {
546
547
}
547
548
548
549
var numberchars = 1
549
-
550
+
550
551
// parse everything else
551
552
while let byte = self . peek ( offset: numberchars) {
552
553
switch byte {
@@ -619,32 +620,32 @@ extension JSONParser {
619
620
}
620
621
621
622
extension UInt8 {
622
-
623
+
623
624
internal static let _space = UInt8 ( ascii: " " )
624
625
internal static let _return = UInt8 ( ascii: " \r " )
625
626
internal static let _newline = UInt8 ( ascii: " \n " )
626
627
internal static let _tab = UInt8 ( ascii: " \t " )
627
-
628
+
628
629
internal static let _colon = UInt8 ( ascii: " : " )
629
630
internal static let _comma = UInt8 ( ascii: " , " )
630
-
631
+
631
632
internal static let _openbrace = UInt8 ( ascii: " { " )
632
633
internal static let _closebrace = UInt8 ( ascii: " } " )
633
-
634
+
634
635
internal static let _openbracket = UInt8 ( ascii: " [ " )
635
636
internal static let _closebracket = UInt8 ( ascii: " ] " )
636
-
637
+
637
638
internal static let _quote = UInt8 ( ascii: " \" " )
638
639
internal static let _backslash = UInt8 ( ascii: " \\ " )
639
-
640
+
640
641
}
641
642
642
643
extension Array where Element == UInt8 {
643
-
644
+
644
645
internal static let _true = [ UInt8 ( ascii: " t " ) , UInt8 ( ascii: " r " ) , UInt8 ( ascii: " u " ) , UInt8 ( ascii: " e " ) ]
645
646
internal static let _false = [ UInt8 ( ascii: " f " ) , UInt8 ( ascii: " a " ) , UInt8 ( ascii: " l " ) , UInt8 ( ascii: " s " ) , UInt8 ( ascii: " e " ) ]
646
647
internal static let _null = [ UInt8 ( ascii: " n " ) , UInt8 ( ascii: " u " ) , UInt8 ( ascii: " l " ) , UInt8 ( ascii: " l " ) ]
647
-
648
+
648
649
}
649
650
650
651
enum JSONError : Swift . Error , Equatable {
@@ -660,4 +661,5 @@ enum JSONError: Swift.Error, Equatable {
660
661
case numberWithLeadingZero( index: Int )
661
662
case numberIsNotRepresentableInSwift( parsed: String )
662
663
case singleFragmentFoundButNotAllowed
664
+ case invalidUTF8Sequence( Data , characterIndex: Int )
663
665
}
0 commit comments