0001    //
0002    //  ObjectiveC.swift
0003    //  PMJSON
0004    //
0005    //  Created by Kevin Ballard on 10/9/15.
0006    //  Copyright © 2016 Postmates.
0007    //
0008    //  Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
0009    //  http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
0010    //  <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
0011    //  option. This file may not be copied, modified, or distributed
0012    //  except according to those terms.
0013    //
0014    
0015    #if os(iOS) || os(OSX) || os(watchOS) || os(tvOS)
0016        
0017        import Foundation
0018        
0019        extension JSON {
0020            /// Decodes an `NSData` as JSON.
0021            /// - Note: Invalid UTF8 sequences in the data are replaced with U+FFFD.
0022            /// - Parameter strict: If `true`, trailing commas in arrays/objects are treated as errors. Default is `false`.
0023            /// - Returns: A `JSON` value.
0024            /// - Throws: `JSONParserError` if the data does not contain valid JSON.
0025            public static func decode(data: NSData, strict: Swift.Bool = false) throws -> JSON {
0026                return try JSON.decode(UTF8Decoder(data: data), strict: strict)
0027            }
0028            
0029            /// Encodes a `JSON` to an `NSData`.
0030            /// - Parameter json: The `JSON` to encode.
0031            /// - Parameter pretty: If `true`, include extra whitespace for formatting. Default is `false`.
0032            /// - Returns: An `NSData` with the JSON representation of *json*.
0033            public static func encodeAsData(json: JSON, pretty: Swift.Bool = false) -> NSData {
0034                struct Output: OutputStreamType {
0035                    let data = NSMutableData()
0036                    func write(string: Swift.String) {
0037                        let oldLen = data.length
0038                        data.increaseLengthBy(string.utf8.count)
0039                        let ptr = UnsafeMutablePointer<UInt8>(data.mutableBytes) + oldLen
0040                        for (i, x) in string.utf8.enumerate() {
0041                            ptr[i] = x
0042                        }
0043                    }
0044                }
0045                var output = Output()
0046                JSON.encode(json, toStream: &output, pretty: pretty)
0047                return output.data
0048            }
0049        }
0050        
0051        extension JSON {
0052            /// Converts a JSON-compatible Foundation object into a `JSON` value.
0053            /// - Note: Deprecated in favor of `init(ns:)`.
0054            /// - Throws: `JSONFoundationError` if the object is not JSON-compatible.
0055            @available(*, deprecated, renamed="init(ns:)")
0056            public init(plist: AnyObject) throws {
0057                try self.init(ns: plist)
0058            }
0059            
0060            /// Converts a JSON-compatible Foundation object into a `JSON` value.
0061            /// - Throws: `JSONFoundationError` if the object is not JSON-compatible.
0062            public init
ObjectiveC.swift:57
            try self.init(ns: plist)
ObjectiveC.swift:99
                    obj[key] = try JSON(ns: value)
ObjectiveC.swift:106
                    ary.append(try JSON(ns: elt))
(ns object: AnyObject) throws { 0063 if object === kCFBooleanTrue { 0064 self = .Bool(true) 0065 return 0066 } else if object === kCFBooleanFalse { 0067 self = .Bool(false) 0068 return 0069 } 0070 switch object { 0071 case is NSNull: 0072 self = .Null 0073 case let n as NSNumber: 0074 let typeChar: UnicodeScalar 0075 let objCType = UnsafePointer<UInt8>(n.objCType) 0076 if objCType == nil || objCType[0] == 0 || objCType[1] != 0 { 0077 typeChar = "?" 0078 } else { 0079 typeChar = UnicodeScalar(objCType[0]) 0080 } 0081 switch typeChar { 0082 case "c", "i", "s", "l", "q", "C", "I", "S", "L", "B": 0083 self = .Int64(n.longLongValue) 0084 case "Q": // unsigned long long 0085 let val = n.unsignedLongLongValue 0086 if val > UInt64(Swift.Int64.max) { 0087 fallthrough 0088 } 0089 self = .Int64(Swift.Int64(val)) 0090 default: 0091 self = .Double(n.doubleValue) 0092 } 0093 case let s as Swift.String: 0094 self = .String(s) 0095 case let dict as NSDictionary: 0096 var obj: [Swift.String: JSON] = Dictionary(minimumCapacity: dict.count) 0097 for (key, value) in dict { 0098 guard let key = key as? Swift.String else { throw JSONFoundationError.NonStringKey } 0099 obj[key] = try JSON(ns: value) 0100 } 0101 self = .Object(JSONObject(obj)) 0102 case let array as NSArray: 0103 var ary: JSONArray = [] 0104 ary.reserveCapacity(array.count) 0105 for elt in array { 0106 ary.append(try JSON(ns: elt)) 0107 } 0108 self = .Array(ary) 0109 default: 0110 throw JSONFoundationError.IncompatibleType 0111 } 0112 } 0113 0114 /// Returns the JSON as a JSON-compatible Foundation object. 0115 /// - Note: Deprecated in favor of `ns`. 0116 @available(*, deprecated, renamed="ns") 0117 public var plist: AnyObject { 0118 return ns 0119 } 0120 0121 /// Returns the JSON as a JSON-compatible Foundation object. 0122 public var ns
ObjectiveC.swift:118
            return ns
ObjectiveC.swift:131
                return ary.map({$0.ns})
ObjectiveC.swift:169
                dict[key] = value.ns
: AnyObject { 0123 switch self { 0124 case .Null: return NSNull() 0125 case .Bool(let b): return b as NSNumber 0126 case .String(let s): return s 0127 case .Int64(let i): return NSNumber(longLong: i) 0128 case .Double(let d): return d 0129 case .Object(let obj): return obj.ns 0130 case .Array(let ary): 0131 return ary.map({$0.ns}) 0132 } 0133 } 0134 0135 /// Returns the JSON as a JSON-compatible Foundation object, discarding any nulls. 0136 /// - Note: Deprecated in favor of `nsNoNull`. 0137 @available(*, deprecated, renamed="nsNoNull") 0138 public var plistNoNull: AnyObject? { 0139 return nsNoNull 0140 } 0141 0142 /// Returns the JSON as a JSON-compatible Foundation object, discarding any nulls. 0143 public var nsNoNull
ObjectiveC.swift:139
            return nsNoNull
ObjectiveC.swift:152
                return ary.flatMap({$0.nsNoNull})
ObjectiveC.swift:185
                if let value = value.nsNoNull {
: AnyObject? { 0144 switch self { 0145 case .Null: return nil 0146 case .Bool(let b): return b as NSNumber 0147 case .String(let s): return s 0148 case .Int64(let i): return NSNumber(longLong: i) 0149 case .Double(let d): return d 0150 case .Object(let obj): return obj.nsNoNull 0151 case .Array(let ary): 0152 return ary.flatMap({$0.nsNoNull}) 0153 } 0154 } 0155 } 0156 0157 extension JSONObject { 0158 /// Returns the JSON as a JSON-compatible dictionary. 0159 /// - Note: Deprecated in favor of `ns`. 0160 @available(*, deprecated, renamed="ns") 0161 public var plist: [NSObject: AnyObject] { 0162 return ns 0163 } 0164 0165 /// Returns the JSON as a JSON-compatible dictionary. 0166 public var ns
ObjectiveC.swift:129
            case .Object(let obj): return obj.ns
ObjectiveC.swift:162
            return ns
: [NSObject: AnyObject] { 0167 var dict: [NSObject: AnyObject] = Dictionary(minimumCapacity: count) 0168 for (key, value) in self { 0169 dict[key] = value.ns 0170 } 0171 return dict 0172 } 0173 0174 /// Returns the JSON as a JSON-compatible dictionary, discarding any nulls. 0175 /// - Note: Deprecated in favor of `nsNoNull`. 0176 @available(*, deprecated, renamed="nsNoNull") 0177 public var plistNoNull: [NSObject: AnyObject] { 0178 return nsNoNull 0179 } 0180 0181 /// Returns the JSON as a JSON-compatible dictionary, discarding any nulls. 0182 public var nsNoNull
ObjectiveC.swift:150
            case .Object(let obj): return obj.nsNoNull
ObjectiveC.swift:178
            return nsNoNull
: [NSObject: AnyObject] { 0183 var dict: [NSObject: AnyObject] = Dictionary(minimumCapacity: count) 0184 for (key, value) in self { 0185 if let value = value.nsNoNull { 0186 dict[key] = value 0187 } 0188 } 0189 return dict 0190 } 0191 } 0192 0193 /// An error that is thrown when converting from `AnyObject` to `JSON`. 0194 /// - Note: Deprecated in favor of `JSONFoundationError`. 0195 /// - SeeAlso: `JSON.init(ns:)` 0196 @available(*, deprecated, renamed="JSONFoundationError") 0197 public typealias JSONPlistError = JSONFoundationError 0198 0199 /// An error that is thrown when converting from `AnyObject` to `JSON`. 0200 /// - SeeAlso: `JSON.init(ns:)` 0201 public enum JSONFoundationError
ObjectiveC.swift:98
                    guard let key = key as? Swift.String else { throw JSONFoundationError.NonStringKey }
ObjectiveC.swift:110
                throw JSONFoundationError.IncompatibleType
ObjectiveC.swift:197
    public typealias JSONPlistError = JSONFoundationError
: ErrorType { 0202 /// Thrown when a non-JSON-compatible type is found. 0203 case IncompatibleType
ObjectiveC.swift:110
                throw JSONFoundationError.IncompatibleType
0204 /// Thrown when a dictionary has a key that is not a string. 0205 case NonStringKey
ObjectiveC.swift:98
                    guard let key = key as? Swift.String else { throw JSONFoundationError.NonStringKey }
0206 } 0207 0208 private struct UTF8Decoder
ObjectiveC.swift:26
            return try JSON.decode(UTF8Decoder(data: data), strict: strict)
: SequenceType { 0209 init
ObjectiveC.swift:26
            return try JSON.decode(UTF8Decoder(data: data), strict: strict)
(data: NSData) { 0210 self.data = data 0211 } 0212 0213 func generate() -> Generator { 0214 return Generator(data: data) 0215 } 0216 0217 private let data
ObjectiveC.swift:210
            self.data = data
ObjectiveC.swift:214
            return Generator(data: data)
: NSData 0218 0219 private struct Generator
ObjectiveC.swift:213
        func generate() -> Generator {
ObjectiveC.swift:214
            return Generator(data: data)
: GeneratorType { 0220 init
ObjectiveC.swift:214
            return Generator(data: data)
(data: NSData) { 0221 self.data = data 0222 let ptr = UnsafeBufferPointer(start: UnsafePointer<UInt8>(data.bytes), count: data.length) 0223 gen = ptr.generate() 0224 utf8 = UTF8() 0225 } 0226 0227 mutating func next() -> UnicodeScalar? { 0228 switch utf8.decode(&gen) { 0229 case .Result(let scalar): return scalar 0230 case .Error: return "\u{FFFD}" 0231 case .EmptyInput: return nil 0232 } 0233 } 0234 0235 private let data
ObjectiveC.swift:221
                self.data = data
: NSData 0236 private var gen
ObjectiveC.swift:223
                gen = ptr.generate()
ObjectiveC.swift:228
                switch utf8.decode(&gen) {
: UnsafeBufferPointerGenerator<UInt8> 0237 private var utf8
ObjectiveC.swift:224
                utf8 = UTF8()
ObjectiveC.swift:228
                switch utf8.decode(&gen) {
: UTF8 0238 } 0239 } 0240 0241 #endif // os(iOS) || os(OSX) || os(watchOS) || os(tvOS) 0242