In Swift 4:
Ci sono un paio di cose da considerare quando si estrae un valore intero da un flusso Data
. Signedness e Endianess. Così ho trovato una funzione in un'estensione a Data
che deduce Signedness dal tipo di intero che si desidera estrarre e passa Endianess e Index
come parametri. I tipi di numeri interi che possono essere estratti sono tutti conformi al protocollo FixedWidthInteger
.
app: Questa funzione non controlla se la gamma Index
è all'interno dei limiti del buffer Data
quindi potrebbe bloccarsi a seconda della dimensione del tipo l'estratto in relazione alla fine del buffer.
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
}
}
}
Esempio:
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)
Risultati:
number1 is 8191
number2 is 65311
number3 is -225
number4 is 8191
Osservare le chiamate di funzione per vedere come viene inferito il tipo da estrarre. Naturalmente Endianess non ha senso per Int8
o UInt8
, ma la funzione funziona come previsto.
I valori possono essere espressi in seguito su Int
se necessario.
fonte
2017-09-14 02:18:42
Assolutamente perfetto! Grazie! – dhint4
o 'sizeofValue (random)' – newacct
In Swift3: sizeof (NSInteger) diventa MemoryLayout. Size e println diventano stampati. –
parleer