Reading Data into a Struct in Swift

Reading the entire structure from the data does not work because
the struct members are padded to their natural boundary. The
memory layout of struct XPLBeacon is

 A B x x C C C C D D D D

where

 offset    member
  0        A       - majorVersion (UInt8)
  1        B       - minorVersion (UInt8)
  2        x x     - padding
  4        C C C C - applicationHostId (UInt32)
  8        D D D D - versionNumber (UInt32)

and the padding is inserted so that the UInt32 members are
aligned to memory addresses which are a multiple of their size. This is
also confirmed by

print(MemoryLayout<XPLBeacon>.size) // 12

(For more information about alignment in Swift, see
Type Layout).

If you read the entire data into the struct then the bytes are assigned
as follows

 01 02 0A 00 00 00 0B 00 00 00
 A  B  x  x  C  C  C  C  D  D  D  D

which explains why major/minorVersion are correct, but applicationHostId and versionNumber
are wrong. Reading all members separately from the data is the correct solution.

Leave a Comment