0001    //
0002    //  JsonSerializer.swift
0003    //  JsonSerializer
0004    //
0005    //  Created by Fuji Goro on 2014/09/11.
0006    //  Copyright (c) 2014 Fuji Goro. All rights reserved.
0007    //  License: The MIT License
0008    //
0009    
0010    #if os(Linux)
0011        import Glibc
0012    #else
0013        import Darwin
0014    #endif
0015    
0016    internal final class JsonDeserializer
Json.swift:67
        return try JsonDeserializer(source.utf8).deserialize()
Json.swift:71
        return try JsonDeserializer(source).deserialize()
Json.swift:75
        return try JsonDeserializer(sequence).deserialize()
JsonParser.swift:370
extension JsonDeserializer.Char {
: Parser { 0017 internal typealias ByteSequence
JsonParser.swift:54
    internal required init(_ source: ByteSequence) {
= [UInt8] 0018 internal typealias Char
JsonParser.swift:36
    private var currentChar: Char {
JsonParser.swift:40
    private var nextChar: Char {
JsonParser.swift:80
        case Char(ascii: "n"):
JsonParser.swift:82
        case Char(ascii: "t"):
JsonParser.swift:84
        case Char(ascii: "f"):
JsonParser.swift:86
        case Char(ascii: "-"), Char(ascii: "0") ... Char(ascii: "9"):
JsonParser.swift:86
        case Char(ascii: "-"), Char(ascii: "0") ... Char(ascii: "9"):
JsonParser.swift:86
        case Char(ascii: "-"), Char(ascii: "0") ... Char(ascii: "9"):
JsonParser.swift:88
        case Char(ascii: "\""):
JsonParser.swift:90
        case Char(ascii: "{"):
JsonParser.swift:92
        case Char(ascii: "["):
JsonParser.swift:108
        assert(currentChar == Char(ascii: "\""), "points a double quote")
JsonParser.swift:113
        while cur != end && currentChar != Char(ascii: "\"") {
JsonParser.swift:115
            case Char(ascii: "\\"):
JsonParser.swift:180
        case Char(ascii: "0"):
JsonParser.swift:182
        case Char(ascii: "1") ... Char(ascii: "9"):
JsonParser.swift:182
        case Char(ascii: "1") ... Char(ascii: "9"):
JsonParser.swift:245
        assert(currentChar == Char(ascii: "{"), "points \"{\"")
JsonParser.swift:280
        assert(currentChar == Char(ascii: "["), "points \"[\"")
JsonParser.swift:340
    private func isIdentifier(c: Char) -> Bool {
JsonParser.swift:342
        case Char(ascii: "a") ... Char(ascii: "z"):
JsonParser.swift:342
        case Char(ascii: "a") ... Char(ascii: "z"):
JsonParser.swift:355
        case Char(ascii: "\n"):
JsonParser.swift:370
extension JsonDeserializer.Char {
= UInt8 0019 0020 // MARK: Public Readable 0021 0022 internal private(set) var lineNumber
JsonParser.swift:319
        let l = lineNumber
JsonParser.swift:327
                lineNumber = l
JsonParser.swift:356
            lineNumber += 1
= 1 0023 internal private(set) var columnNumber
JsonParser.swift:320
        let c = columnNumber
JsonParser.swift:328
                columnNumber = c
JsonParser.swift:357
            columnNumber = 1
JsonParser.swift:359
            columnNumber += 1
= 1 0024 0025 // MARK: Source 0026 0027 private let source
JsonParser.swift:37
        return source[cur]
JsonParser.swift:41
        return source[cur.successor()]
JsonParser.swift:55
        self.source = source
: [UInt8] 0028 0029 // MARK: State 0030 0031 private var cur
JsonParser.swift:37
        return source[cur]
JsonParser.swift:41
        return source[cur.successor()]
JsonParser.swift:56
        self.cur = source.startIndex
JsonParser.swift:66
        guard cur == end else {
JsonParser.swift:75
        guard cur != end else {
JsonParser.swift:113
        while cur != end && currentChar != Char(ascii: "\"") {
JsonParser.swift:118
                guard cur != end else {
JsonParser.swift:183
            while let value = digitToInt(currentChar) where cur != end {
JsonParser.swift:196
            while let value = digitToInt(currentChar) where cur != end {
JsonParser.swift:221
            while let value = digitToInt(currentChar) where cur != end {
JsonParser.swift:251
        while cur != end && !expect("}") {
JsonParser.swift:286
        LOOP: while cur != end && !expect("]") {
JsonParser.swift:306
        guard cur != end else { return false }
JsonParser.swift:318
        let start = cur
JsonParser.swift:326
                cur = start // unread
JsonParser.swift:350
        assert(cur != end, "out of range")
JsonParser.swift:351
        cur += 1
JsonParser.swift:352
        guard cur != end else { return }
JsonParser.swift:364
        while cur != end && currentChar.isWhitespace {
: Int 0032 private let end
JsonParser.swift:57
        self.end = source.endIndex
JsonParser.swift:66
        guard cur == end else {
JsonParser.swift:75
        guard cur != end else {
JsonParser.swift:113
        while cur != end && currentChar != Char(ascii: "\"") {
JsonParser.swift:118
                guard cur != end else {
JsonParser.swift:183
            while let value = digitToInt(currentChar) where cur != end {
JsonParser.swift:196
            while let value = digitToInt(currentChar) where cur != end {
JsonParser.swift:221
            while let value = digitToInt(currentChar) where cur != end {
JsonParser.swift:251
        while cur != end && !expect("}") {
JsonParser.swift:286
        LOOP: while cur != end && !expect("]") {
JsonParser.swift:306
        guard cur != end else { return false }
JsonParser.swift:350
        assert(cur != end, "out of range")
JsonParser.swift:352
        guard cur != end else { return }
JsonParser.swift:364
        while cur != end && currentChar.isWhitespace {
: Int 0033 0034 // MARK: Accessors 0035 0036 private var currentChar
JsonParser.swift:45
        return Character(UnicodeScalar(currentChar))
JsonParser.swift:79
        switch currentChar {
JsonParser.swift:108
        assert(currentChar == Char(ascii: "\""), "points a double quote")
JsonParser.swift:113
        while cur != end && currentChar != Char(ascii: "\"") {
JsonParser.swift:114
            switch currentChar {
JsonParser.swift:130
                buffer.append(CChar(bitPattern: currentChar))
JsonParser.swift:150
        let character = UnicodeScalar(currentChar)
JsonParser.swift:179
        switch currentChar {
JsonParser.swift:183
            while let value = digitToInt(currentChar) where cur != end {
JsonParser.swift:196
            while let value = digitToInt(currentChar) where cur != end {
JsonParser.swift:221
            while let value = digitToInt(currentChar) where cur != end {
JsonParser.swift:245
        assert(currentChar == Char(ascii: "{"), "points \"{\"")
JsonParser.swift:280
        assert(currentChar == Char(ascii: "["), "points \"[\"")
JsonParser.swift:310
            if target.utf8Start.memory == currentChar {
JsonParser.swift:325
            if p.memory != currentChar {
JsonParser.swift:354
        switch currentChar {
JsonParser.swift:364
        while cur != end && currentChar.isWhitespace {
: Char { 0037 return source[cur] 0038 } 0039 0040 private var nextChar
JsonParser.swift:159
        while let d = hexToDigit(nextChar) {
: Char { 0041 return source[cur.successor()] 0042 } 0043 0044 private var currentSymbol
JsonParser.swift:101
            throw UnexpectedTokenError("expected \"\(target)\" but \(currentSymbol)", self)
JsonParser.swift:297
                throw UnexpectedTokenError("missing comma (,) (token: \(currentSymbol))", self)
: Character { 0045 return Character(UnicodeScalar(currentChar)) 0046 } 0047 0048 // MARK: Initializer 0049 0050 internal required convenience init
Json.swift:67
        return try JsonDeserializer(source.utf8).deserialize()
Json.swift:75
        return try JsonDeserializer(sequence).deserialize()
<ByteSequence: CollectionType where ByteSequence.Generator.Element == UInt8>(_ sequence: ByteSequence) { 0051 self.init(Array(sequence)) 0052 } 0053 0054 internal required init
Json.swift:71
        return try JsonDeserializer(source).deserialize()
JsonParser.swift:51
        self.init(Array(sequence))
(_ source: ByteSequence) { 0055 self.source = source 0056 self.cur = source.startIndex 0057 self.end = source.endIndex 0058 } 0059 0060 // MARK: Serialize 0061 0062 internal func deserialize
Json.swift:67
        return try JsonDeserializer(source.utf8).deserialize()
Json.swift:71
        return try JsonDeserializer(source).deserialize()
Json.swift:75
        return try JsonDeserializer(sequence).deserialize()
() throws -> Json { 0063 let json = try deserializeNextValue() 0064 skipWhitespaces() 0065 0066 guard cur == end else { 0067 throw ExtraTokenError("extra tokens found", self) 0068 } 0069 0070 return json 0071 } 0072 0073 private func deserializeNextValue
JsonParser.swift:63
        let json = try deserializeNextValue()
JsonParser.swift:252
            guard case let .StringValue(key) = try deserializeNextValue() else {
JsonParser.swift:262
            let value = try deserializeNextValue()
JsonParser.swift:287
            let json = try deserializeNextValue()
() throws -> Json { 0074 skipWhitespaces() 0075 guard cur != end else { 0076 throw InsufficientTokenError("unexpected end of tokens", self) 0077 } 0078 0079 switch currentChar { 0080 case Char(ascii: "n"): 0081 return try parseSymbol("null", Json.NullValue) 0082 case Char(ascii: "t"): 0083 return try parseSymbol("true", Json.BooleanValue(true)) 0084 case Char(ascii: "f"): 0085 return try parseSymbol("false", Json.BooleanValue(false)) 0086 case Char(ascii: "-"), Char(ascii: "0") ... Char(ascii: "9"): 0087 return try parseNumber() 0088 case Char(ascii: "\""): 0089 return try parseString() 0090 case Char(ascii: "{"): 0091 return try parseObject() 0092 case Char(ascii: "["): 0093 return try parseArray() 0094 case let c: 0095 throw UnexpectedTokenError("unexpected token: \(c)", self) 0096 } 0097 } 0098 0099 private func parseSymbol
JsonParser.swift:81
            return try parseSymbol("null", Json.NullValue)
JsonParser.swift:83
            return try parseSymbol("true", Json.BooleanValue(true))
JsonParser.swift:85
            return try parseSymbol("false", Json.BooleanValue(false))
(target: StaticString, @autoclosure _ iftrue: () -> Json) throws -> Json { 0100 guard expect(target) else { 0101 throw UnexpectedTokenError("expected \"\(target)\" but \(currentSymbol)", self) 0102 } 0103 0104 return iftrue() 0105 } 0106 0107 private func parseString
JsonParser.swift:89
            return try parseString()
() throws -> Json { 0108 assert(currentChar == Char(ascii: "\""), "points a double quote") 0109 advance() 0110 0111 var buffer = [CChar]() 0112 0113 while cur != end && currentChar != Char(ascii: "\"") { 0114 switch currentChar { 0115 case Char(ascii: "\\"): 0116 advance() 0117 0118 guard cur != end else { 0119 throw InvalidStringError("unexpected end of a string literal", self) 0120 } 0121 0122 guard let escapedChar = parseEscapedChar() else { 0123 throw InvalidStringError("invalid escape sequence", self) 0124 } 0125 0126 String(escapedChar).utf8.forEach { 0127 buffer.append(CChar(bitPattern: $0)) 0128 } 0129 default: 0130 buffer.append(CChar(bitPattern: currentChar)) 0131 } 0132 0133 advance() 0134 } 0135 0136 guard expect("\"") else { 0137 throw InvalidStringError("missing double quote", self) 0138 } 0139 0140 buffer.append(0) // trailing nul 0141 0142 guard let string = String.fromCString(buffer) else { 0143 throw InvalidStringError("Unable to parse CString", self) 0144 } 0145 0146 return .StringValue(string) 0147 } 0148 0149 private func parseEscapedChar
JsonParser.swift:122
                guard let escapedChar = parseEscapedChar() else {
() -> UnicodeScalar? { 0150 let character = UnicodeScalar(currentChar) 0151 0152 // 'u' indicates unicode 0153 guard character == "u" else { 0154 return unescapeMapping[character] ?? character 0155 } 0156 0157 var length = 0 // 2...8 0158 var value: UInt32 = 0 0159 while let d = hexToDigit(nextChar) { 0160 advance() 0161 length += 1 0162 0163 guard length <= 8 else { break } 0164 value <<= 4 0165 value |= d 0166 } 0167 0168 guard length >= 2 else { return nil } 0169 0170 // TODO: validate the value 0171 return UnicodeScalar(value) 0172 } 0173 0174 // number = [ minus ] int [ frac ] [ exp ] 0175 private func parseNumber
JsonParser.swift:87
            return try parseNumber()
() throws -> Json { 0176 let sign = expect("-") ? -1.0 : 1.0 0177 0178 var integer: Int64 = 0 0179 switch currentChar { 0180 case Char(ascii: "0"): 0181 advance() 0182 case Char(ascii: "1") ... Char(ascii: "9"): 0183 while let value = digitToInt(currentChar) where cur != end { 0184 integer = (integer * 10) + Int64(value) 0185 advance() 0186 } 0187 default: 0188 throw InvalidNumberError("invalid token in number", self) 0189 } 0190 0191 var fraction: Double = 0.0 0192 if expect(".") { 0193 var factor = 0.1 0194 var fractionLength = 0 0195 0196 while let value = digitToInt(currentChar) where cur != end { 0197 fraction += (Double(value) * factor) 0198 factor /= 10 0199 fractionLength += 1 0200 0201 advance() 0202 } 0203 0204 guard fractionLength != 0 else { 0205 throw InvalidNumberError("insufficient fraction part in number", self) 0206 } 0207 } 0208 0209 var exponent: Int64 = 0 0210 if expect("e") || expect("E") { 0211 var expSign: Int64 = 1 0212 if expect("-") { 0213 expSign = -1 0214 } else if expect("+") { 0215 // do nothing 0216 } 0217 0218 exponent = 0 0219 0220 var exponentLength = 0 0221 while let value = digitToInt(currentChar) where cur != end { 0222 exponent = (exponent * 10) + Int64(value) 0223 exponentLength += 1 0224 advance() 0225 } 0226 0227 guard exponentLength != 0 else { 0228 throw InvalidNumberError("insufficient exponent part in number", self) 0229 } 0230 0231 exponent *= expSign 0232 } 0233 0234 return .NumberValue(sign * (Double(integer) + fraction) * pow(10, Double(exponent))) 0235 } 0236 0237 private func parseObject
JsonParser.swift:91
            return try parseObject()
() throws -> Json { 0238 return try getObject() 0239 } 0240 0241 /** 0242 There is a bug in the compiler which makes this function necessary to be called from parseObject 0243 */ 0244 private func getObject
JsonParser.swift:238
        return try getObject()
() throws -> Json { 0245 assert(currentChar == Char(ascii: "{"), "points \"{\"") 0246 advance() 0247 skipWhitespaces() 0248 0249 var object = [String:Json]() 0250 0251 while cur != end && !expect("}") { 0252 guard case let .StringValue(key) = try deserializeNextValue() else { 0253 throw NonStringKeyError("unexpected value for object key", self) 0254 } 0255 0256 skipWhitespaces() 0257 guard expect(":") else { 0258 throw UnexpectedTokenError("missing colon (:)", self) 0259 } 0260 skipWhitespaces() 0261 0262 let value = try deserializeNextValue() 0263 object[key] = value 0264 0265 skipWhitespaces() 0266 0267 guard !expect("}") else { 0268 break 0269 } 0270 0271 guard expect(",") else { 0272 throw UnexpectedTokenError("missing comma (,)", self) 0273 } 0274 } 0275 0276 return .ObjectValue(object) 0277 } 0278 0279 private func parseArray
JsonParser.swift:93
            return try parseArray()
() throws -> Json { 0280 assert(currentChar == Char(ascii: "["), "points \"[\"") 0281 advance() 0282 skipWhitespaces() 0283 0284 var a = Array<Json>() 0285 0286 LOOP: while cur != end && !expect("]") { 0287 let json = try deserializeNextValue() 0288 skipWhitespaces() 0289 0290 a.append(json) 0291 0292 if expect(",") { 0293 continue 0294 } else if expect("]") { 0295 break LOOP 0296 } else { 0297 throw UnexpectedTokenError("missing comma (,) (token: \(currentSymbol))", self) 0298 } 0299 0300 } 0301 0302 return .ArrayValue(a) 0303 } 0304 0305 private func expect
JsonParser.swift:100
        guard expect(target) else {
JsonParser.swift:136
        guard expect("\"") else {
JsonParser.swift:176
        let sign = expect("-") ? -1.0 : 1.0
JsonParser.swift:192
        if expect(".") {
JsonParser.swift:210
        if expect("e") || expect("E") {
JsonParser.swift:210
        if expect("e") || expect("E") {
JsonParser.swift:212
            if expect("-") {
JsonParser.swift:214
            } else if expect("+") {
JsonParser.swift:251
        while cur != end && !expect("}") {
JsonParser.swift:257
            guard expect(":") else {
JsonParser.swift:267
            guard !expect("}") else {
JsonParser.swift:271
            guard expect(",") else {
JsonParser.swift:286
        LOOP: while cur != end && !expect("]") {
JsonParser.swift:292
            if expect(",") {
JsonParser.swift:294
            } else if expect("]") {
(target: StaticString) -> Bool { 0306 guard cur != end else { return false } 0307 0308 if !isIdentifier(target.utf8Start.memory) { 0309 // when single character 0310 if target.utf8Start.memory == currentChar { 0311 advance() 0312 return true 0313 } else { 0314 return false 0315 } 0316 } 0317 0318 let start = cur 0319 let l = lineNumber 0320 let c = columnNumber 0321 0322 var p = target.utf8Start 0323 let endp = p.advancedBy(Int(target.byteSize)) 0324 while p != endp { 0325 if p.memory != currentChar { 0326 cur = start // unread 0327 lineNumber = l 0328 columnNumber = c 0329 return false 0330 } 0331 0332 p += 1 0333 advance() 0334 } 0335 0336 return true 0337 } 0338 0339 // only "true", "false", "null" are identifiers 0340 private func isIdentifier
JsonParser.swift:308
        if !isIdentifier(target.utf8Start.memory) {
(c: Char) -> Bool { 0341 switch c { 0342 case Char(ascii: "a") ... Char(ascii: "z"): 0343 return true 0344 default: 0345 return false 0346 } 0347 } 0348 0349 private func advance
JsonParser.swift:109
        advance()
JsonParser.swift:116
                advance()
JsonParser.swift:133
            advance()
JsonParser.swift:160
            advance()
JsonParser.swift:181
            advance()
JsonParser.swift:185
                advance()
JsonParser.swift:201
                advance()
JsonParser.swift:224
                advance()
JsonParser.swift:246
        advance()
JsonParser.swift:281
        advance()
JsonParser.swift:311
                advance()
JsonParser.swift:333
            advance()
JsonParser.swift:365
            advance()
() { 0350 assert(cur != end, "out of range") 0351 cur += 1 0352 guard cur != end else { return } 0353 0354 switch currentChar { 0355 case Char(ascii: "\n"): 0356 lineNumber += 1 0357 columnNumber = 1 0358 default: 0359 columnNumber += 1 0360 } 0361 } 0362 0363 private func skipWhitespaces
JsonParser.swift:64
        skipWhitespaces()
JsonParser.swift:74
        skipWhitespaces()
JsonParser.swift:247
        skipWhitespaces()
JsonParser.swift:256
            skipWhitespaces()
JsonParser.swift:260
            skipWhitespaces()
JsonParser.swift:265
            skipWhitespaces()
JsonParser.swift:282
        skipWhitespaces()
JsonParser.swift:288
            skipWhitespaces()
() { 0364 while cur != end && currentChar.isWhitespace { 0365 advance() 0366 } 0367 } 0368 } 0369 0370 extension JsonDeserializer.Char { 0371 var isWhitespace
JsonParser.swift:364
        while cur != end && currentChar.isWhitespace {
: Bool { 0372 let type = self.dynamicType 0373 switch self { 0374 case type.init(ascii: " "), type.init(ascii: "\t"), type.init(ascii: "\r"), type.init(ascii: "\n"): 0375 return true 0376 default: 0377 return false 0378 } 0379 } 0380 } 0381 0382 extension CollectionType { 0383 func prefixUntil(@noescape stopCondition: Generator.Element -> Bool) -> Array<Generator.Element> { 0384 var prefix: [Generator.Element] = [] 0385 for element in self { 0386 guard !stopCondition(element) else { return prefix } 0387 prefix.append(element) 0388 } 0389 return prefix 0390 } 0391 } 0392