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: Parser { 0017 internal typealias ByteSequence
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 {= [UInt8] 0018 internal typealias Char
JsonParser.swift:54 internal required init(_ source: ByteSequence) {= UInt8 0019 0020 // MARK: Public Readable 0021 0022 internal private(set) var lineNumber
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 {= 1 0023 internal private(set) var columnNumber
JsonParser.swift:319 let l = lineNumberJsonParser.swift:327 lineNumber = lJsonParser.swift:356 lineNumber += 1= 1 0024 0025 // MARK: Source 0026 0027 private let source
JsonParser.swift:320 let c = columnNumberJsonParser.swift:328 columnNumber = cJsonParser.swift:357 columnNumber = 1JsonParser.swift:359 columnNumber += 1: [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:55 self.source = source: Int 0032 private let end
JsonParser.swift:37 return source[cur]JsonParser.swift:41 return source[cur.successor()]JsonParser.swift:56 self.cur = source.startIndexJsonParser.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 = curJsonParser.swift:326 cur = start // unreadJsonParser.swift:350 assert(cur != end, "out of range")JsonParser.swift:351 cur += 1JsonParser.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:57 self.end = source.endIndexJsonParser.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 {: Char { 0037 return source[cur] 0038 } 0039 0040 private var nextChar
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 { 0041 return source[cur.successor()] 0042 } 0043 0044 private var currentSymbol
JsonParser.swift:159 while let d = hexToDigit(nextChar) {: Character { 0045 return Character(UnicodeScalar(currentChar)) 0046 } 0047 0048 // MARK: Initializer 0049 0050 internal required convenience init
JsonParser.swift:101 throw UnexpectedTokenError("expected \"\(target)\" but \(currentSymbol)", self)JsonParser.swift:297 throw UnexpectedTokenError("missing comma (,) (token: \(currentSymbol))", self)<ByteSequence: CollectionType where ByteSequence.Generator.Element == UInt8>(_ sequence: ByteSequence) { 0051 self.init(Array(sequence)) 0052 } 0053 0054 internal required init
Json.swift:67 return try JsonDeserializer(source.utf8).deserialize()Json.swift:75 return try JsonDeserializer(sequence).deserialize()(_ 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:71 return try JsonDeserializer(source).deserialize()JsonParser.swift:51 self.init(Array(sequence))() 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
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 { 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: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()(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: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))() 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:89 return try parseString()() -> 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:122 guard let escapedChar = parseEscapedChar() else {() 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:87 return try parseNumber()() 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:91 return try parseObject()() 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:238 return try getObject()() 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:93 return try parseArray()(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:100 guard expect(target) else {JsonParser.swift:136 guard expect("\"") else {JsonParser.swift:176 let sign = expect("-") ? -1.0 : 1.0JsonParser.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("]") {(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:308 if !isIdentifier(target.utf8Start.memory) {() { 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: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()() { 0364 while cur != end && currentChar.isWhitespace { 0365 advance() 0366 } 0367 } 0368 } 0369 0370 extension JsonDeserializer.Char { 0371 var isWhitespace
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(): 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
JsonParser.swift:364 while cur != end && currentChar.isWhitespace {