Skip to content

Commit 903e12f

Browse files
committed
Implementing jsonObject with streams api of NSJSONSerialization.
1 parent a0a8da3 commit 903e12f

File tree

2 files changed

+604
-57
lines changed

2 files changed

+604
-57
lines changed

Foundation/NSJSONSerialization.swift

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,8 @@ public class JSONSerialization : NSObject {
126126
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.
127127
*/
128128
/// - 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.
129-
public class func jsonObject(with data: Data, options opt: ReadingOptions = []) throws -> Any {
130-
return try data.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> Any in
129+
public class func jsonObject(with data: Data, options opt: ReadingOptions = []) throws -> AnyObject {
130+
return try data.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> AnyObject in
131131
let encoding: String.Encoding
132132
let buffer: UnsafeBufferPointer<UInt8>
133133
if let detected = parseBOM(bytes, length: data.count) {
@@ -142,10 +142,10 @@ public class JSONSerialization : NSObject {
142142
let source = JSONReader.UnicodeSource(buffer: buffer, encoding: encoding)
143143
let reader = JSONReader(source: source)
144144
if let (object, _) = try reader.parseObject(0) {
145-
return object
145+
return object.bridge()
146146
}
147147
else if let (array, _) = try reader.parseArray(0) {
148-
return array
148+
return array.bridge()
149149
}
150150
else if opt.contains(.allowFragments), let (value, _) = try reader.parseValue(0) {
151151
return value
@@ -169,7 +169,19 @@ public class JSONSerialization : NSObject {
169169
/* 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.
170170
*/
171171
public class func jsonObject(with stream: InputStream, options opt: ReadingOptions = []) throws -> AnyObject {
172-
NSUnimplemented()
172+
var buffer = [UInt8](repeating: 0, count: 1024)
173+
var data = Data()
174+
var bytesRead: Int?
175+
repeat {
176+
bytesRead = 0
177+
if stream.hasBytesAvailable {
178+
bytesRead = stream.read(&buffer, maxLength: buffer.count)
179+
if bytesRead! > 0 {
180+
data.append(&buffer, count: bytesRead!)
181+
}
182+
}
183+
} while bytesRead == buffer.count
184+
return try jsonObject(with: data, options: opt)
173185
}
174186
}
175187

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

643655
let startPointer = buffer.baseAddress!
@@ -656,12 +668,12 @@ private struct JSONReader {
656668
}
657669

658670
if intDistance == doubleDistance {
659-
return (intResult, intDistance)
671+
return (intResult._bridgeToObject(), intDistance)
660672
}
661673
guard doubleDistance > 0 else {
662674
return nil
663675
}
664-
return (doubleResult, doubleDistance)
676+
return (doubleResult._bridgeToObject(), doubleDistance)
665677
}
666678
}
667679

@@ -686,24 +698,24 @@ private struct JSONReader {
686698
}
687699

688700
//MARK: - Value parsing
689-
func parseValue(_ input: Index) throws -> (Any, Index)? {
701+
func parseValue(_ input: Index) throws -> (AnyObject, Index)? {
690702
if let (value, parser) = try parseString(input) {
691-
return (value, parser)
703+
return (value.bridge(), parser)
692704
}
693705
else if let parser = try consumeASCIISequence("true", input: input) {
694-
return (true, parser)
706+
return (true._bridgeToObject(), parser)
695707
}
696708
else if let parser = try consumeASCIISequence("false", input: input) {
697-
return (false, parser)
709+
return (false._bridgeToObject(), parser)
698710
}
699711
else if let parser = try consumeASCIISequence("null", input: input) {
700712
return (NSNull(), parser)
701713
}
702714
else if let (object, parser) = try parseObject(input) {
703-
return (object, parser)
715+
return (object.bridge(), parser)
704716
}
705717
else if let (array, parser) = try parseArray(input) {
706-
return (array, parser)
718+
return (array.bridge(), parser)
707719
}
708720
else if let (number, parser) = try parseNumber(input) {
709721
return (number, parser)

0 commit comments

Comments
 (0)