<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Aug 15, 2016, at 3:05 PM, Dave Reed via swift-users <<a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">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.<br class=""><br class=""><br class=""> /// Creates a `JSONParser` ready to parse UTF-8 encoded `NSData`.<br class=""> ///<br class=""> /// If the data is mutable, it is copied before parsing. The data's lifetime<br class=""> /// is extended for the duration of parsing.<br class=""> init(utf8Data inData: Data) {<br class=""> let data = (inData as NSData).copy() as! Data<br class=""> let buffer = UnsafeBufferPointer(start: UnsafePointer<UInt8>((data as NSData).bytes), count: data.count)<br class=""> self.init(buffer: buffer, owner: data)<br class=""> }<br class=""><br class="">And this case appears to be going from a String to UnsafeBufferPointer<Uint8><br class=""><br class=""><br class=""> /// Creates a `JSONParser` from the code units represented by the `string`.<br class=""> ///<br class=""> /// The synthesized string is lifetime-extended for the duration of parsing.<br class=""> init(string: String) {<br class=""> let codePoints = string.nulTerminatedUTF8<br class=""> let buffer = codePoints.withUnsafeBufferPointer { nulTerminatedBuffer in<br class=""> // don't want to include the nul termination in the buffer - trim it off<br class=""> UnsafeBufferPointer(start: nulTerminatedBuffer.baseAddress, count: nulTerminatedBuffer.count - 1)<br class=""> }<br class=""> self.init(buffer: buffer, owner: codePoints)<br class=""> }<br class=""><br class="">}<br class=""><br class=""><br class="">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.<br class=""><br class="">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.<br class=""><br class="">Thanks,<br class="">Dave Reed</div></div></blockquote></div><div class=""><br class=""></div><div class=""><div class="">I'm too late to help, but just to follow up...</div><div class=""><br class=""></div><div class="">If you're wondering how to migrate pointer conversion like this to 3.0:</div><div class=""><br class=""></div><div class=""> UnsafePointer<UInt8>(data.bytes)</div><div class=""><br class=""></div><div class=""> UnsafeBufferPointer(start: nulTerminatedBuffer.baseAddress,</div><div class=""> count: nulTerminatedBuffer.count - 1)</div><div class=""><br class=""></div><div class="">then there's a quick explanation <a href="https://gist.github.com/atrick/0283ae0e284610fd21ad6ed3f454a585" class="">here</a>.</div><div class=""><br class=""></div><div class="">The proposal that Zach posted has more background:</div><div class=""><a href="https://github.com/apple/swift-evolution/blob/master/proposals/0107-unsaferawpointer.md" class="">https://github.com/apple/swift-evolution/blob/master/proposals/0107-unsaferawpointer.md</a></div><div class=""><br class=""></div><div class="">You can get something working easily enough with pointer bitcasts or binding memory, but converting UnsafePointers is not something you should be doing here.</div><div class=""><br class=""></div><div class="">If the JSON parser has its own copy of the data, then it should simply have its own array:</div><div class=""><br class=""></div><div class=""> private let input: [UInt8]</div><div class=""> //deleted private let owner: Any?</div><div class=""><br class=""></div><div class=""> init(utf8Data inData: Data) {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>input = [UInt8](inData)</div><div class=""> }</div><div class=""><br class=""></div><div class=""> init(string: String) {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>input = [UInt8](string.utf8)</div><div class=""> }</div><div class=""><br class=""></div><div class="">If the JSON parser wanted to operate on data that is owned by someone else, then we need something like the UnsafeBytes type proposed here:</div><div class=""><br class=""></div><div class=""><a href="https://github.com/atrick/swift-evolution/blob/unsafebytes/proposals/NNNN-UnsafeBytes.md#detailed-design" class="">https://github.com/atrick/swift-evolution/blob/unsafebytes/proposals/NNNN-UnsafeBytes.md#detailed-design</a></div><div class=""><br class=""></div><div class=""> private let input: UnsafeBytes</div><div class=""> private let owner: Any?</div><div class=""><br class=""></div><div class=""> init(utf8Data inData: Data) {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>// Data should directly provide a</div><div class=""> // withUnsafeBytes<T>(_ body: (UnsafeBytes) -> R)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>input = inData.withUnsafeBytes { (p: UnsafePointer<UInt8>) in</div><div class=""> UnsafeBytes(start: UnsafeRawPointer(p), count: inData.count) }</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>owner = inData</div><div class=""> }</div><div class=""><br class=""></div><div class="">Although, in the case of String input you still need to create a copy:</div><div class=""><br class=""></div><div class=""> init(string: String) {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let utf8Array = [UInt8](string.utf8)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>input = utf8Array.withUnsafeBytes { $0 }</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>owner = utf8Array</div><div class=""> }</div><div class=""><br class=""></div><div class="">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.</div></div><div class=""><br class=""></div><div class="">-Andy</div></body></html>