In Swift 4:
Jest kilka rzeczy do rozważenia przy wyodrębnianiu wartości całkowitych ze strumienia Data
. Signedness i Endianess. Więc wymyśliłem funkcję w rozszerzeniu do Data
, która podaje Signedness z typu liczby całkowitej, którą chcesz wyodrębnić i przekazuje Endianess i Index
jako parametry. Typy liczb całkowitych, które można wyodrębnić, są zgodne z protokołem FixedWidthInteger
.
przypomnienia: Funkcja ta sprawdza, czy zakres Index
znajduje się wewnątrz granic bufora Data
więc może ulec awarii w zależności od rozmiaru, typu wyodrębnione w stosunku do końca bufora.
extension Data {
enum Endianness {
case BigEndian
case LittleEndian
}
func scanValue<T: FixedWidthInteger>(at index: Data.Index, endianess: Endianness) -> T {
let number: T = self.subdata(in: index..<index + MemoryLayout<T>.size).withUnsafeBytes({ $0.pointee })
switch endianess {
case .BigEndian:
return number.bigEndian
case .LittleEndian:
return number.littleEndian
}
}
}
przykład:
let data = Data(bytes: [0xFF,0x1F,0x1F,0xFF])
let number1 = data.scanValue(at: 0, endianess: .LittleEndian) as UInt16
let number2 = data.scanValue(at: 0, endianess: .BigEndian) as UInt16
let number3: Int16 = data.scanValue(at: 2, endianess: .LittleEndian)
let number4: Int16 = data.scanValue(at: 2, endianess: .BigEndian)
Wyniki:
number1 is 8191
number2 is 65311
number3 is -225
number4 is 8191
Obserwuj wywołania funkcji, aby sprawdzić, jaki typ wywodu został pobrany. Oczywiście Endianess nie ma sensu dla Int8
lub UInt8
, ale funkcja działa zgodnie z oczekiwaniami.
W razie potrzeby wartości można później przenieść na numer Int
.
Absolutnie doskonały! Dziękuję Ci! – dhint4
lub 'sizeofValue (losowe)' – newacct
W Swift3: sizeof (NSInteger) staje się MemoryLayout. Rozmiar i println zostaje wydrukowany. –
parleer