0001    // JSONInterchangeDataParser.swift
0002    //
0003    // The MIT License (MIT)
0004    //
0005    // Copyright (c) 2015 Zewo
0006    //
0007    // Permission is hereby granted, free of charge, to any person obtaining a copy
0008    // of this software and associated documentation files (the "Software"), to deal
0009    // in the Software without restriction, including without limitation the rights
0010    // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
0011    // copies of the Software, and to permit persons to whom the Software is
0012    // furnished to do so, subject to the following conditions:
0013    //
0014    // The above copyright notice and this permission notice shall be included in all
0015    // copies or substantial portions of the Software.
0016    //
0017    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0018    // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0019    // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
0020    // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0021    // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
0022    // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
0023    // SOFTWARE.
0024    //
0025    // This file has been modified from its original project Swift-JsonSerializer
0026    
0027    #if os(Linux)
0028        import Glibc
0029    #else
0030        import Darwin.C
0031    #endif
0032    
0033    @_exported import InterchangeData
0034    
0035    enum JSONInterchangeDataParseError
JSONInterchangeDataParser.swift:92
            throw JSONInterchangeDataParseError.ExtraTokenError(
JSONInterchangeDataParser.swift:107
            throw JSONInterchangeDataParseError.InsufficientTokenError(
JSONInterchangeDataParser.swift:122
        case (let c): throw JSONInterchangeDataParseError.UnexpectedTokenError(
JSONInterchangeDataParser.swift:146
            throw JSONInterchangeDataParseError.UnexpectedTokenError(
JSONInterchangeDataParser.swift:164
                    throw JSONInterchangeDataParseError.InvalidStringError(
JSONInterchangeDataParser.swift:176
                    throw JSONInterchangeDataParseError.InvalidStringError(
JSONInterchangeDataParser.swift:189
            throw JSONInterchangeDataParseError.InvalidStringError(
JSONInterchangeDataParser.swift:246
            throw JSONInterchangeDataParseError.InvalidStringError(
JSONInterchangeDataParser.swift:254
            throw JSONInterchangeDataParseError.InvalidNumberError(
JSONInterchangeDataParser.swift:279
                throw JSONInterchangeDataParseError.InvalidNumberError(
JSONInterchangeDataParser.swift:310
                throw JSONInterchangeDataParseError.InvalidNumberError(
JSONInterchangeDataParser.swift:337
                    throw JSONInterchangeDataParseError.UnexpectedTokenError(
JSONInterchangeDataParser.swift:354
                    throw JSONInterchangeDataParseError.UnexpectedTokenError(
JSONInterchangeDataParser.swift:361
                throw JSONInterchangeDataParseError.NonStringKeyError(
JSONInterchangeDataParser.swift:389
                throw JSONInterchangeDataParseError.UnexpectedTokenError(
: ErrorType, CustomStringConvertible { 0036 case UnexpectedTokenError
JSONInterchangeDataParser.swift:45
        case UnexpectedTokenError(let r, let l, let c):
JSONInterchangeDataParser.swift:122
        case (let c): throw JSONInterchangeDataParseError.UnexpectedTokenError(
JSONInterchangeDataParser.swift:146
            throw JSONInterchangeDataParseError.UnexpectedTokenError(
JSONInterchangeDataParser.swift:337
                    throw JSONInterchangeDataParseError.UnexpectedTokenError(
JSONInterchangeDataParser.swift:354
                    throw JSONInterchangeDataParseError.UnexpectedTokenError(
JSONInterchangeDataParser.swift:389
                throw JSONInterchangeDataParseError.UnexpectedTokenError(
(reason: String, lineNumber: Int, columnNumber: Int) 0037 case InsufficientTokenError
JSONInterchangeDataParser.swift:47
        case InsufficientTokenError(let r, let l, let c):
JSONInterchangeDataParser.swift:107
            throw JSONInterchangeDataParseError.InsufficientTokenError(
(reason: String, lineNumber: Int, columnNumber: Int) 0038 case ExtraTokenError
JSONInterchangeDataParser.swift:49
        case ExtraTokenError(let r, let l, let c):
JSONInterchangeDataParser.swift:92
            throw JSONInterchangeDataParseError.ExtraTokenError(
(reason: String, lineNumber: Int, columnNumber: Int) 0039 case NonStringKeyError
JSONInterchangeDataParser.swift:51
        case NonStringKeyError(let r, let l, let c):
JSONInterchangeDataParser.swift:361
                throw JSONInterchangeDataParseError.NonStringKeyError(
(reason: String, lineNumber: Int, columnNumber: Int) 0040 case InvalidStringError
JSONInterchangeDataParser.swift:53
        case InvalidStringError(let r, let l, let c):
JSONInterchangeDataParser.swift:164
                    throw JSONInterchangeDataParseError.InvalidStringError(
JSONInterchangeDataParser.swift:176
                    throw JSONInterchangeDataParseError.InvalidStringError(
JSONInterchangeDataParser.swift:189
            throw JSONInterchangeDataParseError.InvalidStringError(
JSONInterchangeDataParser.swift:246
            throw JSONInterchangeDataParseError.InvalidStringError(
(reason: String, lineNumber: Int, columnNumber: Int) 0041 case InvalidNumberError
JSONInterchangeDataParser.swift:55
        case InvalidNumberError(let r, let l, let c):
JSONInterchangeDataParser.swift:254
            throw JSONInterchangeDataParseError.InvalidNumberError(
JSONInterchangeDataParser.swift:279
                throw JSONInterchangeDataParseError.InvalidNumberError(
JSONInterchangeDataParser.swift:310
                throw JSONInterchangeDataParseError.InvalidNumberError(
(reason: String, lineNumber: Int, columnNumber: Int) 0042 0043 var description: String { 0044 switch self { 0045 case UnexpectedTokenError(let r, let l, let c): 0046 return "UnexpectedTokenError!\nLine: \(l)\nColumn: \(c)]\nReason: \(r)" 0047 case InsufficientTokenError(let r, let l, let c): 0048 return "InsufficientTokenError!\nLine: \(l)\nColumn: \(c)]\nReason: \(r)" 0049 case ExtraTokenError(let r, let l, let c): 0050 return "ExtraTokenError!\nLine: \(l)\nColumn: \(c)]\nReason: \(r)" 0051 case NonStringKeyError(let r, let l, let c): 0052 return "NonStringKeyError!\nLine: \(l)\nColumn: \(c)]\nReason: \(r)" 0053 case InvalidStringError(let r, let l, let c): 0054 return "InvalidStringError!\nLine: \(l)\nColumn: \(c)]\nReason: \(r)" 0055 case InvalidNumberError(let r, let l, let c): 0056 return "InvalidNumberError!\nLine: \(l)\nColumn: \(c)]\nReason: \(r)" 0057 } 0058 } 0059 } 0060 0061 public struct JSONInterchangeDataParser: InterchangeDataParser { 0062 public init() {} 0063 0064 public func parse(data: Data) throws -> InterchangeData { 0065 return try GenericJSONInterchangeDataParser(data).parse() 0066 } 0067 } 0068 0069 class GenericJSONInterchangeDataParser
JSONInterchangeDataParser.swift:103
extension GenericJSONInterchangeDataParser {
<ByteSequence
JSONInterchangeDataParser.swift:70
    typealias Source = ByteSequence
: CollectionType where ByteSequence.Generator.Element == UInt8> { 0070 typealias Source
JSONInterchangeDataParser.swift:71
    typealias Char = Source.Generator.Element
JSONInterchangeDataParser.swift:73
    let source: Source
JSONInterchangeDataParser.swift:74
    var cur: Source.Index
JSONInterchangeDataParser.swift:75
    let end: Source.Index
JSONInterchangeDataParser.swift:80
    init(_ source: Source) {
= ByteSequence 0071 typealias Char
JSONInterchangeDataParser.swift:115
        case Char(ascii: "n"): return try parseSymbol("null", InterchangeData.NullValue)
JSONInterchangeDataParser.swift:116
        case Char(ascii: "t"): return try parseSymbol("true", InterchangeData.BooleanValue(true))
JSONInterchangeDataParser.swift:117
        case Char(ascii: "f"): return try parseSymbol("false", InterchangeData.BooleanValue(false))
JSONInterchangeDataParser.swift:118
        case Char(ascii: "-"), Char(ascii: "0") ... Char(ascii: "9"): return try parseNumber()
JSONInterchangeDataParser.swift:118
        case Char(ascii: "-"), Char(ascii: "0") ... Char(ascii: "9"): return try parseNumber()
JSONInterchangeDataParser.swift:118
        case Char(ascii: "-"), Char(ascii: "0") ... Char(ascii: "9"): return try parseNumber()
JSONInterchangeDataParser.swift:119
        case Char(ascii: "\""): return try parseString()
JSONInterchangeDataParser.swift:120
        case Char(ascii: "{"): return try parseObject()
JSONInterchangeDataParser.swift:121
        case Char(ascii: "["): return try parseArray()
JSONInterchangeDataParser.swift:130
    private var currentChar: Char {
JSONInterchangeDataParser.swift:134
    private var nextChar: Char {
JSONInterchangeDataParser.swift:155
        assert(currentChar == Char(ascii: "\""), "points a double quote")
JSONInterchangeDataParser.swift:161
            case Char(ascii: "\\"):
JSONInterchangeDataParser.swift:182
            case Char(ascii: "\""): break LOOP
JSONInterchangeDataParser.swift:235
        case Char(ascii: "0"): advance()
JSONInterchangeDataParser.swift:236
        case Char(ascii: "1") ... Char(ascii: "9"):
JSONInterchangeDataParser.swift:236
        case Char(ascii: "1") ... Char(ascii: "9"):
JSONInterchangeDataParser.swift:324
        assert(currentChar == Char(ascii: "{"), "points \"{\"")
JSONInterchangeDataParser.swift:373
        assert(currentChar == Char(ascii: "["), "points \"[\"")
JSONInterchangeDataParser.swift:437
    private func isIdentifier(char: Char) -> Bool {
JSONInterchangeDataParser.swift:439
        case Char(ascii: "a") ... Char(ascii: "z"):
JSONInterchangeDataParser.swift:439
        case Char(ascii: "a") ... Char(ascii: "z"):
JSONInterchangeDataParser.swift:453
            case Char(ascii: "\n"):
JSONInterchangeDataParser.swift:466
            case Char(ascii: " "), Char(ascii: "\t"), Char(ascii: "\r"), Char(ascii: "\n"):
JSONInterchangeDataParser.swift:466
            case Char(ascii: " "), Char(ascii: "\t"), Char(ascii: "\r"), Char(ascii: "\n"):
JSONInterchangeDataParser.swift:466
            case Char(ascii: " "), Char(ascii: "\t"), Char(ascii: "\r"), Char(ascii: "\n"):
JSONInterchangeDataParser.swift:466
            case Char(ascii: " "), Char(ascii: "\t"), Char(ascii: "\r"), Char(ascii: "\n"):
= Source.Generator.Element 0072 0073 let source
JSONInterchangeDataParser.swift:81
        self.source = source
JSONInterchangeDataParser.swift:131
        return source[cur]
JSONInterchangeDataParser.swift:135
        return source[cur.successor()]
: Source 0074 var cur
JSONInterchangeDataParser.swift:82
        self.cur = source.startIndex
JSONInterchangeDataParser.swift:89
        if (cur == end) {
JSONInterchangeDataParser.swift:106
        if cur == end {
JSONInterchangeDataParser.swift:131
        return source[cur]
JSONInterchangeDataParser.swift:135
        return source[cur.successor()]
JSONInterchangeDataParser.swift:159
        LOOP: while cur != end {
JSONInterchangeDataParser.swift:163
                if (cur == end) {
JSONInterchangeDataParser.swift:237
            while cur != end {
JSONInterchangeDataParser.swift:267
            while cur != end {
JSONInterchangeDataParser.swift:299
            while cur != end {
JSONInterchangeDataParser.swift:329
        LOOP: while cur != end && !expect("}") {
JSONInterchangeDataParser.swift:379
        LOOP: while cur != end && !expect("]") {
JSONInterchangeDataParser.swift:402
        if cur == end {
JSONInterchangeDataParser.swift:415
        let start = cur
JSONInterchangeDataParser.swift:424
                cur = start
JSONInterchangeDataParser.swift:447
        assert(cur != end, "out of range")
JSONInterchangeDataParser.swift:448
        cur = cur.successor()
JSONInterchangeDataParser.swift:448
        cur = cur.successor()
JSONInterchangeDataParser.swift:450
        if cur != end {
JSONInterchangeDataParser.swift:464
        while cur != end {
: Source.Index 0075 let end
JSONInterchangeDataParser.swift:83
        self.end = source.endIndex
JSONInterchangeDataParser.swift:89
        if (cur == end) {
JSONInterchangeDataParser.swift:106
        if cur == end {
JSONInterchangeDataParser.swift:159
        LOOP: while cur != end {
JSONInterchangeDataParser.swift:163
                if (cur == end) {
JSONInterchangeDataParser.swift:237
            while cur != end {
JSONInterchangeDataParser.swift:267
            while cur != end {
JSONInterchangeDataParser.swift:299
            while cur != end {
JSONInterchangeDataParser.swift:329
        LOOP: while cur != end && !expect("}") {
JSONInterchangeDataParser.swift:379
        LOOP: while cur != end && !expect("]") {
JSONInterchangeDataParser.swift:402
        if cur == end {
JSONInterchangeDataParser.swift:447
        assert(cur != end, "out of range")
JSONInterchangeDataParser.swift:450
        if cur != end {
JSONInterchangeDataParser.swift:464
        while cur != end {
: Source.Index 0076 0077 var lineNumber
JSONInterchangeDataParser.swift:94
                lineNumber: lineNumber,
JSONInterchangeDataParser.swift:109
                lineNumber: lineNumber,
JSONInterchangeDataParser.swift:124
            lineNumber: lineNumber,
JSONInterchangeDataParser.swift:148
                lineNumber: lineNumber,
JSONInterchangeDataParser.swift:166
                        lineNumber: lineNumber,
JSONInterchangeDataParser.swift:178
                        lineNumber: lineNumber,
JSONInterchangeDataParser.swift:191
                lineNumber: lineNumber,
JSONInterchangeDataParser.swift:248
                lineNumber: lineNumber,
JSONInterchangeDataParser.swift:256
                lineNumber: lineNumber,
JSONInterchangeDataParser.swift:281
                    lineNumber: lineNumber,
JSONInterchangeDataParser.swift:312
                    lineNumber: lineNumber,
JSONInterchangeDataParser.swift:339
                        lineNumber: lineNumber,
JSONInterchangeDataParser.swift:356
                        lineNumber: lineNumber,
JSONInterchangeDataParser.swift:363
                    lineNumber: lineNumber,
JSONInterchangeDataParser.swift:391
                    lineNumber: lineNumber,
JSONInterchangeDataParser.swift:416
        let l = lineNumber
JSONInterchangeDataParser.swift:425
                lineNumber = l
JSONInterchangeDataParser.swift:454
                lineNumber += 1
= 1 0078 var columnNumber
JSONInterchangeDataParser.swift:95
                columnNumber: columnNumber
JSONInterchangeDataParser.swift:110
                columnNumber: columnNumber
JSONInterchangeDataParser.swift:125
            columnNumber: columnNumber
JSONInterchangeDataParser.swift:149
                columnNumber: columnNumber
JSONInterchangeDataParser.swift:167
                        columnNumber: columnNumber
JSONInterchangeDataParser.swift:179
                        columnNumber: columnNumber
JSONInterchangeDataParser.swift:192
                columnNumber: columnNumber
JSONInterchangeDataParser.swift:249
                columnNumber: columnNumber
JSONInterchangeDataParser.swift:257
                columnNumber: columnNumber
JSONInterchangeDataParser.swift:282
                    columnNumber: columnNumber
JSONInterchangeDataParser.swift:313
                    columnNumber: columnNumber
JSONInterchangeDataParser.swift:340
                        columnNumber: columnNumber
JSONInterchangeDataParser.swift:357
                        columnNumber: columnNumber
JSONInterchangeDataParser.swift:364
                    columnNumber: columnNumber
JSONInterchangeDataParser.swift:392
                    columnNumber: columnNumber
JSONInterchangeDataParser.swift:417
        let c = columnNumber
JSONInterchangeDataParser.swift:426
                columnNumber = c
JSONInterchangeDataParser.swift:455
                columnNumber = 1
JSONInterchangeDataParser.swift:458
                columnNumber += 1
= 1 0079 0080 init(_ source: Source) { 0081 self.source = source 0082 self.cur = source.startIndex 0083 self.end = source.endIndex 0084 } 0085 0086 func parse() throws -> InterchangeData { 0087 let JSON = try parseValue() 0088 skipWhitespaces() 0089 if (cur == end) { 0090 return JSON 0091 } else { 0092 throw JSONInterchangeDataParseError.ExtraTokenError( 0093 reason: "extra tokens found", 0094 lineNumber: lineNumber, 0095 columnNumber: columnNumber 0096 ) 0097 } 0098 } 0099 } 0100 0101 // MARK: - Private 0102 0103 extension GenericJSONInterchangeDataParser { 0104 private func parseValue() throws -> InterchangeData { 0105 skipWhitespaces() 0106 if cur == end { 0107 throw JSONInterchangeDataParseError.InsufficientTokenError( 0108 reason: "unexpected end of tokens", 0109 lineNumber: lineNumber, 0110 columnNumber: columnNumber 0111 ) 0112 } 0113 0114 switch currentChar { 0115 case Char(ascii: "n"): return try parseSymbol("null", InterchangeData.NullValue) 0116 case Char(ascii: "t"): return try parseSymbol("true", InterchangeData.BooleanValue(true)) 0117 case Char(ascii: "f"): return try parseSymbol("false", InterchangeData.BooleanValue(false)) 0118 case Char(ascii: "-"), Char(ascii: "0") ... Char(ascii: "9"): return try parseNumber() 0119 case Char(ascii: "\""): return try parseString() 0120 case Char(ascii: "{"): return try parseObject() 0121 case Char(ascii: "["): return try parseArray() 0122 case (let c): throw JSONInterchangeDataParseError.UnexpectedTokenError( 0123 reason: "unexpected token: \(c)", 0124 lineNumber: lineNumber, 0125 columnNumber: columnNumber 0126 ) 0127 } 0128 } 0129 0130 private var currentChar
JSONInterchangeDataParser.swift:114
        switch currentChar {
JSONInterchangeDataParser.swift:139
        return Character(UnicodeScalar(currentChar))
JSONInterchangeDataParser.swift:155
        assert(currentChar == Char(ascii: "\""), "points a double quote")
JSONInterchangeDataParser.swift:160
            switch currentChar {
JSONInterchangeDataParser.swift:183
            default: buffer.append(CChar(bitPattern: currentChar))
JSONInterchangeDataParser.swift:202
        let c = UnicodeScalar(currentChar)
JSONInterchangeDataParser.swift:225
            let c = UnicodeScalar(currentChar)
JSONInterchangeDataParser.swift:234
        switch currentChar {
JSONInterchangeDataParser.swift:238
                if let value = digitToInt(currentChar) {
JSONInterchangeDataParser.swift:268
                if let value = digitToInt(currentChar) {
JSONInterchangeDataParser.swift:300
                if let value = digitToInt(currentChar) {
JSONInterchangeDataParser.swift:324
        assert(currentChar == Char(ascii: "{"), "points \"{\"")
JSONInterchangeDataParser.swift:373
        assert(currentChar == Char(ascii: "["), "points \"[\"")
JSONInterchangeDataParser.swift:407
            if target.utf8Start.memory == currentChar {
JSONInterchangeDataParser.swift:423
            if p.memory != currentChar {
JSONInterchangeDataParser.swift:451
            switch currentChar {
JSONInterchangeDataParser.swift:465
            switch currentChar {
: Char { 0131 return source[cur] 0132 } 0133 0134 private var nextChar
JSONInterchangeDataParser.swift:208
            while let d = hexToDigit(nextChar) {
: Char { 0135 return source[cur.successor()] 0136 } 0137 0138 private var currentSymbol
JSONInterchangeDataParser.swift:147
                reason: "expected \"\(target)\" but \(currentSymbol)",
JSONInterchangeDataParser.swift:390
                    reason: "missing comma (,) (token: \(currentSymbol))",
: Character { 0139 return Character(UnicodeScalar(currentChar)) 0140 } 0141 0142 private func parseSymbol(target: StaticString, @autoclosure _ iftrue: Void -> InterchangeData) throws -> InterchangeData { 0143 if expect(target) { 0144 return iftrue() 0145 } else { 0146 throw JSONInterchangeDataParseError.UnexpectedTokenError( 0147 reason: "expected \"\(target)\" but \(currentSymbol)", 0148 lineNumber: lineNumber, 0149 columnNumber: columnNumber 0150 ) 0151 } 0152 } 0153 0154 private func parseString() throws -> InterchangeData { 0155 assert(currentChar == Char(ascii: "\""), "points a double quote") 0156 advance() 0157 var buffer: [CChar] = [] 0158 0159 LOOP: while cur != end { 0160 switch currentChar { 0161 case Char(ascii: "\\"): 0162 advance() 0163 if (cur == end) { 0164 throw JSONInterchangeDataParseError.InvalidStringError( 0165 reason: "unexpected end of a string literal", 0166 lineNumber: lineNumber, 0167 columnNumber: columnNumber 0168 ) 0169 } 0170 0171 if let c = parseEscapedChar() { 0172 for u in String(c).utf8 { 0173 buffer.append(CChar(bitPattern: u)) 0174 } 0175 } else { 0176 throw JSONInterchangeDataParseError.InvalidStringError( 0177 reason: "invalid escape sequence", 0178 lineNumber: lineNumber, 0179 columnNumber: columnNumber 0180 ) 0181 } 0182 case Char(ascii: "\""): break LOOP 0183 default: buffer.append(CChar(bitPattern: currentChar)) 0184 } 0185 advance() 0186 } 0187 0188 if !expect("\"") { 0189 throw JSONInterchangeDataParseError.InvalidStringError( 0190 reason: "missing double quote", 0191 lineNumber: lineNumber, 0192 columnNumber: columnNumber 0193 ) 0194 } 0195 0196 buffer.append(0) 0197 let s = String.fromCString(buffer)! 0198 return .StringValue(s) 0199 } 0200 0201 private func parseEscapedChar
JSONInterchangeDataParser.swift:171
                if let c = parseEscapedChar() {
() -> UnicodeScalar? { 0202 let c = UnicodeScalar(currentChar) 0203 0204 if c == "u" { 0205 var length = 0 0206 var value: UInt32 = 0 0207 0208 while let d = hexToDigit(nextChar) { 0209 advance() 0210 length += 1 0211 0212 if length > 8 { 0213 break 0214 } 0215 0216 value = (value << 4) | d 0217 } 0218 0219 if length < 2 { 0220 return nil 0221 } 0222 0223 return UnicodeScalar(value) 0224 } else { 0225 let c = UnicodeScalar(currentChar) 0226 return unescapeMapping[c] ?? c 0227 } 0228 } 0229 0230 private func parseNumber() throws -> InterchangeData { 0231 let sign = expect("-") ? -1.0 : 1.0 0232 var integer: Int64 = 0 0233 0234 switch currentChar { 0235 case Char(ascii: "0"): advance() 0236 case Char(ascii: "1") ... Char(ascii: "9"): 0237 while cur != end { 0238 if let value = digitToInt(currentChar) { 0239 integer = (integer * 10) + Int64(value) 0240 } else { 0241 break 0242 } 0243 advance() 0244 } 0245 default: 0246 throw JSONInterchangeDataParseError.InvalidStringError( 0247 reason: "missing double quote", 0248 lineNumber: lineNumber, 0249 columnNumber: columnNumber 0250 ) 0251 } 0252 0253 if integer != Int64(Double(integer)) { 0254 throw JSONInterchangeDataParseError.InvalidNumberError( 0255 reason: "too large number", 0256 lineNumber: lineNumber, 0257 columnNumber: columnNumber 0258 ) 0259 } 0260 0261 var fraction: Double = 0.0 0262 0263 if expect(".") { 0264 var factor = 0.1 0265 var fractionLength = 0 0266 0267 while cur != end { 0268 if let value = digitToInt(currentChar) { 0269 fraction += (Double(value) * factor) 0270 factor /= 10 0271 fractionLength += 1 0272 } else { 0273 break 0274 } 0275 advance() 0276 } 0277 0278 if fractionLength == 0 { 0279 throw JSONInterchangeDataParseError.InvalidNumberError( 0280 reason: "insufficient fraction part in number", 0281 lineNumber: lineNumber, 0282 columnNumber: columnNumber 0283 ) 0284 } 0285 } 0286 0287 var exponent: Int64 = 0 0288 0289 if expect("e") || expect("E") { 0290 var expSign: Int64 = 1 0291 0292 if expect("-") { 0293 expSign = -1 0294 } else if expect("+") {} 0295 0296 exponent = 0 0297 var exponentLength = 0 0298 0299 while cur != end { 0300 if let value = digitToInt(currentChar) { 0301 exponent = (exponent * 10) + Int64(value) 0302 exponentLength += 1 0303 } else { 0304 break 0305 } 0306 advance() 0307 } 0308 0309 if exponentLength == 0 { 0310 throw JSONInterchangeDataParseError.InvalidNumberError( 0311 reason: "insufficient exponent part in number", 0312 lineNumber: lineNumber, 0313 columnNumber: columnNumber 0314 ) 0315 } 0316 0317 exponent *= expSign 0318 } 0319 0320 return .NumberValue(sign * (Double(integer) + fraction) * pow(10, Double(exponent))) 0321 } 0322 0323 private func parseObject() throws -> InterchangeData { 0324 assert(currentChar == Char(ascii: "{"), "points \"{\"") 0325 advance() 0326 skipWhitespaces() 0327 var object: [String: InterchangeData] = [:] 0328 0329 LOOP: while cur != end && !expect("}") { 0330 let keyValue = try parseValue() 0331 0332 switch keyValue { 0333 case .StringValue(let key): 0334 skipWhitespaces() 0335 0336 if !expect(":") { 0337 throw JSONInterchangeDataParseError.UnexpectedTokenError( 0338 reason: "missing colon (:)", 0339 lineNumber: lineNumber, 0340 columnNumber: columnNumber 0341 ) 0342 } 0343 0344 skipWhitespaces() 0345 let value = try parseValue() 0346 object[key] = value 0347 skipWhitespaces() 0348 0349 if expect(",") { 0350 break 0351 } else if expect("}") { 0352 break LOOP 0353 } else { 0354 throw JSONInterchangeDataParseError.UnexpectedTokenError( 0355 reason: "missing comma (,)", 0356 lineNumber: lineNumber, 0357 columnNumber: columnNumber 0358 ) 0359 } 0360 default: 0361 throw JSONInterchangeDataParseError.NonStringKeyError( 0362 reason: "unexpected value for object key", 0363 lineNumber: lineNumber, 0364 columnNumber: columnNumber 0365 ) 0366 } 0367 } 0368 0369 return .ObjectValue(object) 0370 } 0371 0372 private func parseArray() throws -> InterchangeData { 0373 assert(currentChar == Char(ascii: "["), "points \"[\"") 0374 advance() 0375 skipWhitespaces() 0376 0377 var array: [InterchangeData] = [] 0378 0379 LOOP: while cur != end && !expect("]") { 0380 let JSON = try parseValue() 0381 skipWhitespaces() 0382 array.append(JSON) 0383 0384 if expect(",") { 0385 continue 0386 } else if expect("]") { 0387 break LOOP 0388 } else { 0389 throw JSONInterchangeDataParseError.UnexpectedTokenError( 0390 reason: "missing comma (,) (token: \(currentSymbol))", 0391 lineNumber: lineNumber, 0392 columnNumber: columnNumber 0393 ) 0394 } 0395 } 0396 0397 return .ArrayValue(array) 0398 } 0399 0400 0401 private func expect
JSONInterchangeDataParser.swift:143
        if expect(target) {
JSONInterchangeDataParser.swift:188
        if !expect("\"") {
JSONInterchangeDataParser.swift:231
        let sign = expect("-") ? -1.0 : 1.0
JSONInterchangeDataParser.swift:263
        if expect(".") {
JSONInterchangeDataParser.swift:289
        if expect("e") || expect("E") {
JSONInterchangeDataParser.swift:289
        if expect("e") || expect("E") {
JSONInterchangeDataParser.swift:292
            if expect("-") {
JSONInterchangeDataParser.swift:294
            } else if expect("+") {}
JSONInterchangeDataParser.swift:329
        LOOP: while cur != end && !expect("}") {
JSONInterchangeDataParser.swift:336
                if !expect(":") {
JSONInterchangeDataParser.swift:349
                if expect(",") {
JSONInterchangeDataParser.swift:351
                } else if expect("}") {
JSONInterchangeDataParser.swift:379
        LOOP: while cur != end && !expect("]") {
JSONInterchangeDataParser.swift:384
            if expect(",") {
JSONInterchangeDataParser.swift:386
            } else if expect("]") {
(target: StaticString) -> Bool { 0402 if cur == end { 0403 return false 0404 } 0405 0406 if !isIdentifier(target.utf8Start.memory) { 0407 if target.utf8Start.memory == currentChar { 0408 advance() 0409 return true 0410 } else { 0411 return false 0412 } 0413 } 0414 0415 let start = cur 0416 let l = lineNumber 0417 let c = columnNumber 0418 0419 var p = target.utf8Start 0420 let endp = p.advancedBy(Int(target.byteSize)) 0421 0422 while p != endp { 0423 if p.memory != currentChar { 0424 cur = start 0425 lineNumber = l 0426 columnNumber = c 0427 return false 0428 } 0429 p += 1 0430 advance() 0431 } 0432 0433 return true 0434 } 0435 0436 // only "true", "false", "null" are identifiers 0437 private func isIdentifier
JSONInterchangeDataParser.swift:406
        if !isIdentifier(target.utf8Start.memory) {
(char: Char) -> Bool { 0438 switch char { 0439 case Char(ascii: "a") ... Char(ascii: "z"): 0440 return true 0441 default: 0442 return false 0443 } 0444 } 0445 0446 private func advance
JSONInterchangeDataParser.swift:156
        advance()
JSONInterchangeDataParser.swift:162
                advance()
JSONInterchangeDataParser.swift:185
            advance()
JSONInterchangeDataParser.swift:209
                advance()
JSONInterchangeDataParser.swift:235
        case Char(ascii: "0"): advance()
JSONInterchangeDataParser.swift:243
                advance()
JSONInterchangeDataParser.swift:275
                advance()
JSONInterchangeDataParser.swift:306
                advance()
JSONInterchangeDataParser.swift:325
        advance()
JSONInterchangeDataParser.swift:374
        advance()
JSONInterchangeDataParser.swift:408
                advance()
JSONInterchangeDataParser.swift:430
            advance()
JSONInterchangeDataParser.swift:471
            advance()
() { 0447 assert(cur != end, "out of range") 0448 cur = cur.successor() 0449 0450 if cur != end { 0451 switch currentChar { 0452 0453 case Char(ascii: "\n"): 0454 lineNumber += 1 0455 columnNumber = 1 0456 0457 default: 0458 columnNumber += 1 0459 } 0460 } 0461 } 0462 0463 private func skipWhitespaces
JSONInterchangeDataParser.swift:88
        skipWhitespaces()
JSONInterchangeDataParser.swift:105
        skipWhitespaces()
JSONInterchangeDataParser.swift:326
        skipWhitespaces()
JSONInterchangeDataParser.swift:334
                skipWhitespaces()
JSONInterchangeDataParser.swift:344
                skipWhitespaces()
JSONInterchangeDataParser.swift:347
                skipWhitespaces()
JSONInterchangeDataParser.swift:375
        skipWhitespaces()
JSONInterchangeDataParser.swift:381
            skipWhitespaces()
() { 0464 while cur != end { 0465 switch currentChar { 0466 case Char(ascii: " "), Char(ascii: "\t"), Char(ascii: "\r"), Char(ascii: "\n"): 0467 break 0468 default: 0469 return 0470 } 0471 advance() 0472 } 0473 } 0474 } 0475