[swift-users] appending packed bytes to [UInt8]

Kelvin Ma kelvin13ma at gmail.com
Wed Jan 10 18:07:39 CST 2018


I’ve asked similar questions in the past and everyone said this is not
valid Swift, not the least because the compiler can pad structs and
rearrange its layout. For example if there were only 3 UInt8s, the stride
should be 15, not 16 as they need to be packed densely. since they are
misaligned you also can’t use load and store (they will trap)


On Wed, Jan 10, 2018 at 4:27 PM, Jens Persson <jens at bitcycle.com> wrote:

> I'm not sure what you mean by "I need the buffer to be a vector /.../" but
> perhaps this may be of some help:
>
> struct S {
>     var x: Float
>     var y: Float
>     var z: Float
>     var r: UInt8
>     var g: UInt8
>     var b: UInt8
>     var a: UInt8
> }
> var buf = S(x: 0.1, y: 1.2, z: 2.3, r: 11, g: 22, b: 33, a: 44)
> print(MemoryLayout<S>.stride) // 16
> withUnsafeMutableBytes(of: &buf) { ptr in
>     print("x:", ptr.load(fromByteOffset: 0, as: Float.self)) // 0.1
>     print("y:", ptr.load(fromByteOffset: 4, as: Float.self)) // 1.2
>     print("z:", ptr.load(fromByteOffset: 8, as: Float.self)) // 2.3
>     print("r:", ptr.load(fromByteOffset: 12, as: UInt8.self)) // 11
>     print("g:", ptr.load(fromByteOffset: 13, as: UInt8.self)) // 22
>     print("b:", ptr.load(fromByteOffset: 14, as: UInt8.self)) // 33
>     print("a:", ptr.load(fromByteOffset: 15, as: UInt8.self)) // 44
> }
>
> NOTE however that the memory layout of Swift-structs is not guaranteed to
> remain like this and is thus not future-proof, although I think that
> if/when things changes, there will be some way to tell the compiler that
> you want the memory to be this "expected" "C-like" layout.
>
> /Jens
>
>
> On Wed, Jan 10, 2018 at 10:03 PM, Kelvin Ma via swift-users <
> swift-users at swift.org> wrote:
>
>> I want to create a buffer with the layout
>>
>> 0           4           8           12      13      14      15      16
>> [   x:Float   |   y:Float   |   z:Float   | r:UInt8 | g:UInt8 | b:UInt8
>> | _:UInt8 ]
>>
>> Normally, I’d use UnsafeRawBufferPointer for this, but I need the buffer
>> to be a vector (i.e. with append(_:)), and for it to return a
>> Swift-managed Array<UInt8>. How should I do this? The project does not
>> use Foundation.
>>
>> _______________________________________________
>> swift-users mailing list
>> swift-users at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-users
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20180110/bd2f0e9b/attachment.html>


More information about the swift-users mailing list