Skip to content

Commit 9d0e640

Browse files
committed
Implementing jsonObject with streams api of NSJSONSerialization.
1 parent 099f97a commit 9d0e640

File tree

2 files changed

+605
-58
lines changed

2 files changed

+605
-58
lines changed

Foundation/NSJSONSerialization.swift

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,8 @@ open class JSONSerialization : NSObject {
141141
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.
142142
*/
143143
/// - 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.
144-
open class func jsonObject(with data: Data, options opt: ReadingOptions = []) throws -> Any {
145-
return try data.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> Any in
144+
public class func jsonObject(with data: Data, options opt: ReadingOptions = []) throws -> AnyObject {
145+
return try data.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> AnyObject in
146146
let encoding: String.Encoding
147147
let buffer: UnsafeBufferPointer<UInt8>
148148
if let detected = parseBOM(bytes, length: data.count) {
@@ -157,10 +157,10 @@ open class JSONSerialization : NSObject {
157157
let source = JSONReader.UnicodeSource(buffer: buffer, encoding: encoding)
158158
let reader = JSONReader(source: source)
159159
if let (object, _) = try reader.parseObject(0) {
160-
return object
160+
return object.bridge()
161161
}
162162
else if let (array, _) = try reader.parseArray(0) {
163-
return array
163+
return array.bridge()
164164
}
165165
else if opt.contains(.allowFragments), let (value, _) = try reader.parseValue(0) {
166166
return value
@@ -184,8 +184,20 @@ open class JSONSerialization : NSObject {
184184

185185
/* 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.
186186
*/
187-
open class func jsonObject(with stream: InputStream, options opt: ReadingOptions = []) throws -> AnyObject {
188-
NSUnimplemented()
187+
public class func jsonObject(with stream: InputStream, options opt: ReadingOptions = []) throws -> AnyObject {
188+
var buffer = [UInt8](repeating: 0, count: 1024)
189+
var data = Data()
190+
var bytesRead: Int?
191+
repeat {
192+
bytesRead = 0
193+
if stream.hasBytesAvailable {
194+
bytesRead = stream.read(&buffer, maxLength: buffer.count)
195+
if bytesRead! > 0 {
196+
data.append(&buffer, count: bytesRead!)
197+
}
198+
}
199+
} while bytesRead == buffer.count
200+
return try jsonObject(with: data, options: opt)
189201
}
190202
}
191203

@@ -662,11 +674,11 @@ private struct JSONReader {
662674
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, // 0...9
663675
0x2E, 0x2D, 0x2B, 0x45, 0x65, // . - + E e
664676
]
665-
func parseNumber(_ input: Index) throws -> (Any, Index)? {
666-
func parseTypedNumber(_ address: UnsafePointer<UInt8>, count: Int) -> (Any, IndexDistance)? {
677+
func parseNumber(_ input: Index) throws -> (AnyObject, Index)? {
678+
func parseTypedNumber(_ address: UnsafePointer<UInt8>, count: Int) -> (AnyObject, IndexDistance)? {
667679
let temp_buffer_size = 64
668680
var temp_buffer = [Int8](repeating: 0, count: temp_buffer_size)
669-
return temp_buffer.withUnsafeMutableBufferPointer { (buffer: inout UnsafeMutableBufferPointer<Int8>) -> (Any, IndexDistance)? in
681+
return temp_buffer.withUnsafeMutableBufferPointer { (buffer: inout UnsafeMutableBufferPointer<Int8>) -> (AnyObject, IndexDistance)? in
670682
memcpy(buffer.baseAddress!, address, min(count, temp_buffer_size - 1)) // ensure null termination
671683

672684
let startPointer = buffer.baseAddress!
@@ -685,12 +697,12 @@ private struct JSONReader {
685697
}
686698

687699
if intDistance == doubleDistance {
688-
return (intResult, intDistance)
700+
return (intResult._bridgeToObject(), intDistance)
689701
}
690702
guard doubleDistance > 0 else {
691703
return nil
692704
}
693-
return (doubleResult, doubleDistance)
705+
return (doubleResult._bridgeToObject(), doubleDistance)
694706
}
695707
}
696708

@@ -715,24 +727,24 @@ private struct JSONReader {
715727
}
716728

717729
//MARK: - Value parsing
718-
func parseValue(_ input: Index) throws -> (Any, Index)? {
730+
func parseValue(_ input: Index) throws -> (AnyObject, Index)? {
719731
if let (value, parser) = try parseString(input) {
720-
return (value, parser)
732+
return (value.bridge(), parser)
721733
}
722734
else if let parser = try consumeASCIISequence("true", input: input) {
723-
return (true, parser)
735+
return (true._bridgeToObject(), parser)
724736
}
725737
else if let parser = try consumeASCIISequence("false", input: input) {
726-
return (false, parser)
738+
return (false._bridgeToObject(), parser)
727739
}
728740
else if let parser = try consumeASCIISequence("null", input: input) {
729741
return (NSNull(), parser)
730742
}
731743
else if let (object, parser) = try parseObject(input) {
732-
return (object, parser)
744+
return (object.bridge(), parser)
733745
}
734746
else if let (array, parser) = try parseArray(input) {
735-
return (array, parser)
747+
return (array.bridge(), parser)
736748
}
737749
else if let (number, parser) = try parseNumber(input) {
738750
return (number, parser)

0 commit comments

Comments
 (0)