Skip to content

Commit 06d0314

Browse files
committed
Implementing jsonObject with streams api of NSJSONSerialization.
1 parent 541f035 commit 06d0314

File tree

2 files changed

+603
-57
lines changed

2 files changed

+603
-57
lines changed

Foundation/NSJSONSerialization.swift

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,8 @@ public class JSONSerialization : NSObject {
125125
The data must be in one of the 5 supported encodings listed in the JSON specification: UTF-8, UTF-16LE, UTF-16BE, UTF-32LE, UTF-32BE. The data may or may not have a BOM. The most efficient encoding to use for parsing is UTF-8, so if you have a choice in encoding the data passed to this method, use UTF-8.
126126
*/
127127
/// - Experiment: Note that the return type of this function is different than on Darwin Foundation (Any instead of AnyObject). This is likely to change once we have a more complete story for bridging in place.
128-
public class func jsonObject(with data: Data, options opt: ReadingOptions = []) throws -> Any {
129-
return try data.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> Any in
128+
public class func jsonObject(with data: Data, options opt: ReadingOptions = []) throws -> AnyObject {
129+
return try data.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> AnyObject in
130130
let encoding: String.Encoding
131131
let buffer: UnsafeBufferPointer<UInt8>
132132
if let detected = parseBOM(bytes, length: data.count) {
@@ -141,10 +141,10 @@ public class JSONSerialization : NSObject {
141141
let source = JSONReader.UnicodeSource(buffer: buffer, encoding: encoding)
142142
let reader = JSONReader(source: source)
143143
if let (object, _) = try reader.parseObject(0) {
144-
return object
144+
return object.bridge()
145145
}
146146
else if let (array, _) = try reader.parseArray(0) {
147-
return array
147+
return array.bridge()
148148
}
149149
else if opt.contains(.allowFragments), let (value, _) = try reader.parseValue(0) {
150150
return value
@@ -168,7 +168,19 @@ public class JSONSerialization : NSObject {
168168
/* Create a JSON object from JSON data stream. The stream should be opened and configured. All other behavior of this method is the same as the JSONObjectWithData:options:error: method.
169169
*/
170170
public class func jsonObject(with stream: InputStream, options opt: ReadingOptions = []) throws -> AnyObject {
171-
NSUnimplemented()
171+
var buffer = [UInt8](repeating: 0, count: 1024)
172+
var data = Data()
173+
var numRead: Int?
174+
repeat {
175+
numRead = 0
176+
if stream.hasBytesAvailable {
177+
numRead = stream.read(&buffer, maxLength: buffer.count)
178+
if numRead > 0 {
179+
data.append(&buffer, count: numRead!)
180+
}
181+
}
182+
} while numRead == buffer.count
183+
return try jsonObject(with: data, options: opt)
172184
}
173185
}
174186

@@ -632,11 +644,11 @@ private struct JSONReader {
632644
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, // 0...9
633645
0x2E, 0x2D, 0x2B, 0x45, 0x65, // . - + E e
634646
]
635-
func parseNumber(_ input: Index) throws -> (Any, Index)? {
636-
func parseTypedNumber(_ address: UnsafePointer<UInt8>, count: Int) -> (Any, IndexDistance)? {
647+
func parseNumber(_ input: Index) throws -> (AnyObject, Index)? {
648+
func parseTypedNumber(_ address: UnsafePointer<UInt8>, count: Int) -> (AnyObject, IndexDistance)? {
637649
let temp_buffer_size = 64
638650
var temp_buffer = [UInt8](repeating: 0, count: temp_buffer_size)
639-
return temp_buffer.withUnsafeMutableBufferPointer { (buffer: inout UnsafeMutableBufferPointer<UInt8>) -> (Any, IndexDistance)? in
651+
return temp_buffer.withUnsafeMutableBufferPointer { (buffer: inout UnsafeMutableBufferPointer<UInt8>) -> (AnyObject, IndexDistance)? in
640652
memcpy(buffer.baseAddress!, address, min(count, temp_buffer_size - 1)) // ensure null termination
641653

642654
let startPointer = UnsafePointer<Int8>(buffer.baseAddress!)
@@ -655,12 +667,12 @@ private struct JSONReader {
655667
}
656668

657669
if intDistance == doubleDistance {
658-
return (intResult, intDistance)
670+
return (intResult._bridgeToObject(), intDistance)
659671
}
660672
guard doubleDistance > 0 else {
661673
return nil
662674
}
663-
return (doubleResult, doubleDistance)
675+
return (doubleResult._bridgeToObject(), doubleDistance)
664676
}
665677
}
666678

@@ -685,24 +697,24 @@ private struct JSONReader {
685697
}
686698

687699
//MARK: - Value parsing
688-
func parseValue(_ input: Index) throws -> (Any, Index)? {
700+
func parseValue(_ input: Index) throws -> (AnyObject, Index)? {
689701
if let (value, parser) = try parseString(input) {
690-
return (value, parser)
702+
return (value.bridge(), parser)
691703
}
692704
else if let parser = try consumeASCIISequence("true", input: input) {
693-
return (true, parser)
705+
return (true._bridgeToObject(), parser)
694706
}
695707
else if let parser = try consumeASCIISequence("false", input: input) {
696-
return (false, parser)
708+
return (false._bridgeToObject(), parser)
697709
}
698710
else if let parser = try consumeASCIISequence("null", input: input) {
699711
return (NSNull(), parser)
700712
}
701713
else if let (object, parser) = try parseObject(input) {
702-
return (object, parser)
714+
return (object.bridge(), parser)
703715
}
704716
else if let (array, parser) = try parseArray(input) {
705-
return (array, parser)
717+
return (array.bridge(), parser)
706718
}
707719
else if let (number, parser) = try parseNumber(input) {
708720
return (number, parser)

0 commit comments

Comments
 (0)