UnsafeMutableRawPointer use examples?

UnsafeMutableRawPointer was introduced in the latest Xcode beta 6. Are there any examples of how to use UnsafeMutableRawPointer? I'm interested in the case where I need to create or decode network data packets where the one byte might indicate the type (int16, int32, cstring, network order, etc.) of the following bytes.

Replies

To start, I recommend a close reading of the Swift Evolution proposal, SE-0107 UnsafeRawPointer API.

With regards your specific situation, one option would be to use

load(fromeByteOffset:as:)
, as you’ll find discussed in the Raw buffer of unknown type section of SE-0107. If that doesn’t work for you, can you post some more details about your specific requirements.

Just FYI, I long ago gave up on the notion of mapping C (or Swift) data structures to network protocol formats; you inevitably end up falling into weird language or platform specific pitfalls. These days I parse network packets byte-by-byte. Swift’s ability to do low-if-not-zero-cost abstractions makes this quite palatable. I’ve pasted an example of this at the end of this post.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
private class Input {
    let bytes: [UInt8]

    … lots of other stuff …

    func parseUInt16() throws -> UInt16 {
        return UInt16(try self.parseUInt(2))
    }

    func parseUInt32() throws -> UInt32 {
        return UInt32(try self.parseUInt(4))
    }

    func parseUInt(_ size: Int) throws -> UInt64 {
        precondition(size > 0)
        precondition(size <= 8)
        guard self.cursor + size <= limit else {
            try self.throwEOF()
        }
        var accumulator: UInt64 = 0
        for i in 0..<size {
            let shift = (size - i - 1) * 8
            accumulator |= UInt64(self.bytes[self.cursor + i]) << UInt64(shift)
        }
        self.cursor += size
        return accumulator
    }

    @noreturn func throwEOF() throws {
        if self.base == 0 {
            throw ParseError.unexpectedOfPacket
        } else {
            throw ParseError.unexpectedEndOfResource(offset: self.limit, resourceOffset: self.base)
        }
    }

    var base: Int
    var cursor: Int
    var limit: Int
    var atEOF: Bool { return self.cursor == self.limit }
}