I'm trying to convert the following code (from the Big Nerd Ranch's Freddy JSON parser) that works in Xcode 8 beta 5 and convert it to work with beta 6. Essentially it appears it needs to take a Data object and convert it to a UnsafeBufferPointer<UInt8> if I understand it correctly.
/// Creates a `JSONParser` ready to parse UTF-8 encoded `NSData`.
///
/// If the data is mutable, it is copied before parsing. The data's lifetime
/// is extended for the duration of parsing.
init(utf8Data inData: Data) {
let data = (inData as NSData).copy() as! Data
let buffer = UnsafeBufferPointer(start: UnsafePointer<UInt8>((data as NSData).bytes), count: data.count)
self.init(buffer: buffer, owner: data)
}
And this case appears to be going from a String to UnsafeBufferPointer<Uint8>
/// Creates a `JSONParser` from the code units represented by the `string`.
///
/// The synthesized string is lifetime-extended for the duration of parsing.
init(string: String) {
let codePoints = string.nulTerminatedUTF8
let buffer = codePoints.withUnsafeBufferPointer { nulTerminatedBuffer in
// don't want to include the nul termination in the buffer - trim it off
UnsafeBufferPointer(start: nulTerminatedBuffer.baseAddress, count: nulTerminatedBuffer.count - 1)
}
self.init(buffer: buffer, owner: codePoints)
}
}
I understand pointers from my C/C++/Objective-C days but I don't yet understand the various Swift pointer types. Any help is appreciated.
Note: I don't work for Big Nerd Ranch. I'm just trying to use the code and better understand the various Swift pointer types.
On Mon, Aug 15, 2016, at 03:05 PM, Dave Reed via swift-users wrote:
I'm trying to convert the following code (from the Big Nerd Ranch's
Freddy JSON parser) that works in Xcode 8 beta 5 and convert it to work
with beta 6. Essentially it appears it needs to take a Data object and
convert it to a UnsafeBufferPointer<UInt8> if I understand it correctly.
/// Creates a `JSONParser` ready to parse UTF-8 encoded `NSData`.
///
/// If the data is mutable, it is copied before parsing. The data's
lifetime
/// is extended for the duration of parsing.
init(utf8Data inData: Data) {
let data = (inData as NSData).copy() as! Data
let buffer = UnsafeBufferPointer(start:
UnsafePointer<UInt8>((data as NSData).bytes), count: data.count)
self.init(buffer: buffer, owner: data)
}
And this case appears to be going from a String to
UnsafeBufferPointer<Uint8>
/// Creates a `JSONParser` from the code units represented by the
`string`.
///
/// The synthesized string is lifetime-extended for the duration of
parsing.
init(string: String) {
let codePoints = string.nulTerminatedUTF8
let buffer = codePoints.withUnsafeBufferPointer {
nulTerminatedBuffer in
// don't want to include the nul termination in the buffer -
trim it off
UnsafeBufferPointer(start: nulTerminatedBuffer.baseAddress,
count: nulTerminatedBuffer.count - 1)
}
self.init(buffer: buffer, owner: codePoints)
}
}
I understand pointers from my C/C++/Objective-C days but I don't yet
understand the various Swift pointer types. Any help is appreciated.
Note: I don't work for Big Nerd Ranch. I'm just trying to use the code
and better understand the various Swift pointer types.
The proposal that Zach posted has more background:
You can get something working easily enough with pointer bitcasts or binding memory, but converting UnsafePointers is not something you should be doing here.
If the JSON parser has its own copy of the data, then it should simply have its own array:
private let input: [UInt8]
//deleted private let owner: Any?
Note that passing a String as an argument of type UnsafePointer<UInt8> works, but should never be done when calling Swift code. The lifetime of that pointer doesn't outlive the call.
-Andy
···
On Aug 15, 2016, at 3:05 PM, Dave Reed via swift-users <swift-users@swift.org> wrote:
I'm trying to convert the following code (from the Big Nerd Ranch's Freddy JSON parser) that works in Xcode 8 beta 5 and convert it to work with beta 6. Essentially it appears it needs to take a Data object and convert it to a UnsafeBufferPointer<UInt8> if I understand it correctly.
/// Creates a `JSONParser` ready to parse UTF-8 encoded `NSData`.
///
/// If the data is mutable, it is copied before parsing. The data's lifetime
/// is extended for the duration of parsing.
init(utf8Data inData: Data) {
let data = (inData as NSData).copy() as! Data
let buffer = UnsafeBufferPointer(start: UnsafePointer<UInt8>((data as NSData).bytes), count: data.count)
self.init(buffer: buffer, owner: data)
}
And this case appears to be going from a String to UnsafeBufferPointer<Uint8>
/// Creates a `JSONParser` from the code units represented by the `string`.
///
/// The synthesized string is lifetime-extended for the duration of parsing.
init(string: String) {
let codePoints = string.nulTerminatedUTF8
let buffer = codePoints.withUnsafeBufferPointer { nulTerminatedBuffer in
// don't want to include the nul termination in the buffer - trim it off
UnsafeBufferPointer(start: nulTerminatedBuffer.baseAddress, count: nulTerminatedBuffer.count - 1)
}
self.init(buffer: buffer, owner: codePoints)
}
}
I understand pointers from my C/C++/Objective-C days but I don't yet understand the various Swift pointer types. Any help is appreciated.
Note: I don't work for Big Nerd Ranch. I'm just trying to use the code and better understand the various Swift pointer types.
Ah, I think I now see the difference between a UnsafeBufferPointer (it essentially holds the address an array of data) vs. a UnsafePointer (it holds the address where one piece of data is stored), but I'll still need to read the final documentation when it's done.
Dave
···
On Aug 15, 2016, at 9:15 PM, Zach Waldowski via swift-users <swift-users@swift.org> wrote:
On Mon, Aug 15, 2016, at 03:05 PM, Dave Reed via swift-users wrote:
I'm trying to convert the following code (from the Big Nerd Ranch's
Freddy JSON parser) that works in Xcode 8 beta 5 and convert it to work
with beta 6. Essentially it appears it needs to take a Data object and
convert it to a UnsafeBufferPointer<UInt8> if I understand it correctly.
/// Creates a `JSONParser` ready to parse UTF-8 encoded `NSData`.
///
/// If the data is mutable, it is copied before parsing. The data's
lifetime
/// is extended for the duration of parsing.
init(utf8Data inData: Data) {
let data = (inData as NSData).copy() as! Data
let buffer = UnsafeBufferPointer(start:
UnsafePointer<UInt8>((data as NSData).bytes), count: data.count)
self.init(buffer: buffer, owner: data)
}
And this case appears to be going from a String to
UnsafeBufferPointer<Uint8>
/// Creates a `JSONParser` from the code units represented by the
`string`.
///
/// The synthesized string is lifetime-extended for the duration of
parsing.
init(string: String) {
let codePoints = string.nulTerminatedUTF8
let buffer = codePoints.withUnsafeBufferPointer {
nulTerminatedBuffer in
// don't want to include the nul termination in the buffer -
trim it off
UnsafeBufferPointer(start: nulTerminatedBuffer.baseAddress,
count: nulTerminatedBuffer.count - 1)
}
self.init(buffer: buffer, owner: codePoints)
}
}
I understand pointers from my C/C++/Objective-C days but I don't yet
understand the various Swift pointer types. Any help is appreciated.
Note: I don't work for Big Nerd Ranch. I'm just trying to use the code
and better understand the various Swift pointer types.