Вам необходимо зарезервировать первые 16 байтов (4 байта для каждого числового свойства, поскольку все они 32-битные).Хвост данных будет использоваться для свойства данных someData
, которое может иметь любой размер:
struct Another {
// UInt32 - A 32-bit unsigned integer value type. You will need 4 bytes for each property
// 4 + 4 = 8 Bytes
let imgCount, resetFlag: UInt32
// Float - A single-precision, floating-point value type. Again 4 bytes for each property
// 4 + 4 = 8 Bytes
let focalX, focalY: Float
// the data can have any size this will be all bytes from index 16 until the end of the file
let someData: Data
}
Для преобразования числовых типов в данные и обратно вы можете использовать следующие помощники:
extension Numeric {
var data: Data {
var source = self
return Data(bytes: &source, count: MemoryLayout<Self>.size)
}
}
extension Data {
func object<T>() -> T {
return withUnsafeBytes { $0.pointee }
}
}
Теперь вам просто нужно создать собственный инициализатор для декодирования ваших данных итерируя по вашим данным и установить соответствующие значения свойств.
extension Another {
init(_ data: Data) {
var startIndex = data.startIndex
var endIndex = startIndex.advanced(by: MemoryLayout<UInt32>.size)
let imgCountRange = startIndex..<endIndex
self.imgCount = data[imgCountRange].object()
startIndex = endIndex
endIndex = startIndex.advanced(by: MemoryLayout<UInt32>.size)
let resetFlagRange = startIndex..<endIndex
self.resetFlag = data[resetFlagRange].object()
startIndex = endIndex
endIndex = startIndex.advanced(by: MemoryLayout<Float>.size)
let focalXRange = startIndex..<endIndex
self.focalX = data[focalXRange].object()
startIndex = endIndex
endIndex = startIndex.advanced(by: MemoryLayout<Float>.size)
let focalYRange = startIndex..<endIndex
self.focalY = data[focalYRange].object()
self.someData = data[endIndex...]
}
}
Кодировать вашу структуру будет намного проще:
extension Another {
var data: Data {
return imgCount.data + resetFlag.data + focalX.data + focalY.data + someData
}
}
Тестирование:
let obj1 = Another(imgCount: 1, resetFlag: 2, focalX: 3.4, focalY: 5.6, someData: Data([0,1,2,3,4,5,6,7,8,9,10]))
let obj2 = Another(imgCount: 3, resetFlag: 4, focalX: 5.6, focalY: 7.8, someData: Data([10,11,12,13,14,15,16,17,18,19,20,21,22]))
let obj1Data = obj1.data
print(obj1Data) // 27 bytes
let obj1FromData = Another(obj1Data)
print(obj1FromData)
let obj2Data = obj2.data
print(obj2Data) // 29 bytes
let obj2FromData = Another(obj2Data)
print(obj2FromData)
Будет напечатано
27 байтов
Другое (imgCount: 1, resetFlag: 2, focalX: 3.4, focalY: 5.6, someData: 11 байтов)
29 байтов
Другой (imgCount: 3, resetFlag: 4, focalX: 5.6, focalY: 7.8, некоторые данные: 13 байтов)