Files
clover/apps/ios/cleverrc/BinUtils.swift
Oleg Kalachev 571c12061e Track 411 files into repository.
- untracked .gitattributes
- untracked .gitignore
- untracked apps/ios/.gitignore
- untracked apps/ios/cleverrc.xcodeproj/project.pbxproj
- untracked apps/ios/cleverrc.xcodeproj/project.xcworkspace/contents.xcworkspacedata
- untracked apps/ios/cleverrc.xcworkspace/contents.xcworkspacedata
- untracked apps/ios/cleverrc/AppDelegate.swift
- untracked apps/ios/cleverrc/Assets.xcassets/AppIcon.appiconset/cleverios180-1.png
- untracked apps/ios/cleverrc/Assets.xcassets/AppIcon.appiconset/cleverios180.png
- untracked apps/ios/cleverrc/Assets.xcassets/AppIcon.appiconset/Contents.json
- untracked apps/ios/cleverrc/Assets.xcassets/Contents.json
- untracked apps/ios/cleverrc/Assets.xcassets/Image.imageset/Contents.json
- untracked apps/ios/cleverrc/Base.lproj/LaunchScreen.storyboard
- untracked apps/ios/cleverrc/Base.lproj/Main.storyboard
- untracked apps/ios/cleverrc/BinUtils.swift
- untracked apps/ios/cleverrc/clever.svg
- untracked apps/ios/cleverrc/index.html
- untracked apps/ios/cleverrc/Info.plist
- untracked apps/ios/cleverrc/main.css
- untracked apps/ios/cleverrc/main.js
- untracked apps/ios/cleverrc/README.md
- untracked apps/ios/cleverrc/roslib.js
- untracked apps/ios/cleverrc/telemetry.js
- untracked apps/ios/cleverrc/ViewController.swift
- untracked apps/ios/Podfile
- untracked apps/ios/Podfile.lock
- untracked apps/ios/README.md
- untracked aruco_pose/CMakeLists.txt
- untracked aruco_pose/nodelet_plugins.xml
- untracked aruco_pose/package.xml
- untracked aruco_pose/src/aruco_pose.cpp
- untracked aruco_pose/src/fix.cpp
- untracked assets/11_1.png
- untracked assets/11_2.png
- untracked assets/11_3.png
- untracked assets/11_4.png
- untracked assets/11_5.png
- untracked assets/13_1.png
- untracked assets/13_10.png
- untracked assets/13_11.png
- untracked assets/13_2.png
- untracked assets/13_3.jpg
- untracked assets/13_4.png
- untracked assets/13_5.png
- untracked assets/13_6.png
- untracked assets/13_7.png
- untracked assets/13_8.png
- untracked assets/13_9.png
- untracked assets/15_1.png
- untracked assets/15_2.png
- untracked assets/15_3.png
- untracked assets/15_4.png
- untracked assets/15_5.png
- untracked assets/15_6.png
- untracked assets/15_7.png
- untracked assets/16_1.png
- untracked assets/16_2.png
- untracked assets/16_3.png
- untracked assets/16_4.png
- untracked assets/1_1.png
- untracked assets/1_10.png
- untracked assets/1_11.png
- untracked assets/1_12.png
- untracked assets/1_13.png
- untracked assets/1_2.png
- untracked assets/1_3.png
- untracked assets/1_4.png
- untracked assets/1_5.png
- untracked assets/1_6.png
- untracked assets/1_7.png
- untracked assets/1_8.png
- untracked assets/1_9.png
- untracked assets/2_1.png
- untracked assets/2_2.png
- untracked assets/2_3.png
- untracked assets/2_4.png
- untracked assets/2_5.png
- untracked assets/2_6.png
- untracked assets/2_7.png
- untracked assets/2_8.png
- untracked assets/2_9.png
- untracked assets/4_1.png
- untracked assets/4_2.png
- untracked assets/4_3.png
- untracked assets/4_4.png
- untracked assets/4_5.png
- untracked assets/4_6.png
- untracked assets/7_1.png
- untracked assets/7_2.png
- untracked assets/7_3.png
- untracked assets/7_4.png
- untracked assets/8_1.png
- untracked assets/8_2.png
- untracked assets/8_3.png
- untracked assets/8_4.png
- untracked assets/8_5.png
- untracked assets/8_6.png
- untracked assets/9_1.png
- untracked assets/9_2.png
- untracked assets/addEqipment.jpg
- untracked assets/airframeSetup.jpg
- untracked assets/allElements.png
- untracked assets/attentionSave.jpg
- untracked assets/brrc2205.png
- untracked assets/brrc2205on.png
- untracked assets/brrc2205ondeck.png
- untracked assets/calibrateaxcel.jpg
- untracked assets/calibrateaxcelstart.jpg
- untracked assets/calibratecompass.jpg
- untracked assets/calibrateESC.jpg
- untracked assets/calibrategyro.jpg
- untracked assets/calibratePIDparams.jpg
- untracked assets/calibrateView.jpg
- untracked assets/calibrateViewStart.jpg
- untracked assets/casebattery.png
- untracked assets/chooseSwitch.jpg
- untracked assets/Clever main.png
- untracked assets/clever.jpg
- untracked assets/Clevermain.png
- untracked assets/connectBattery.png
- untracked assets/connectingRadio.png
- untracked assets/connectionESCtoReceiver.png
- untracked assets/connectionLost.jpg
- untracked assets/connectionOK.jpg
- untracked assets/connectionPixhawk.png
- untracked assets/consistofTransmitter.jpg
- untracked assets/cutwire14AWG.jpg
- untracked assets/escDYSzap.png
- untracked assets/escWires.png
- untracked assets/explosion.png
- untracked assets/firmwarePX4.jpg
- untracked assets/flightModes.jpg
- untracked assets/helphand.jpg
- untracked assets/holderLegs.png
- untracked assets/isoViewmountHolder.png
- untracked assets/jumper.png
- untracked assets/keep.png
- untracked assets/lockradio.jpg
- untracked assets/lockradio.png
- untracked assets/lowsafeDeck.png
- untracked assets/mainWindow.jpg
- untracked assets/motorsTopview.png
- untracked assets/mount5vconnector.png
- untracked assets/mountAntenna.png
- untracked assets/mountBeams.png
- untracked assets/mountBottomDeck.png
- untracked assets/mountHolder.png
- untracked assets/mountPDB.png
- untracked assets/mountReceiverDeck.png
- untracked assets/mountReceiverStud.png
- untracked assets/mountxt60pinsocket.png
- untracked assets/notmoveslider.jpg
- untracked assets/pixhawk.png
- untracked assets/radioTransmitter.png
- untracked assets/readyBatteryholder.png
- untracked assets/receiver5V.png
- untracked assets/receiverPPM.png
- untracked assets/resolderingESC.png
- untracked assets/safehighRadial.png
- untracked assets/safeLegs.png
- untracked assets/safelowRadial.png
- untracked assets/safetybyassem.png
- untracked assets/safetyINflight.png
- untracked assets/safetyPower.png
- untracked assets/safetyPreflight.png
- untracked assets/soldering5VTOpdb.png
- untracked assets/solderingBrrc2205ondeckTOescDYSzap.png
- untracked assets/solderingPowerwires.png
- untracked assets/solderingxt60socketTOpdb.png
- untracked assets/stand.jpg
- untracked assets/startPDBtest.jpg
- untracked assets/testMotors.png
- untracked assets/topESCcaseview.png
- untracked assets/topPreview.png
- untracked assets/topviewmountPDB.png
- untracked assets/topviewpixhawk.png
- untracked assets/turnoffSafetyswitch.jpg
- untracked assets/xt60pinsocket.jpg
- untracked assets/zap.jpg
- untracked assets/zapPDBtest.jpg
- untracked clever/camera_info/fisheye_cam_320.yaml
- untracked clever/camera_info/fisheye_cam_640.yaml
- untracked clever/CMakeLists.txt
- untracked clever/launch/arduino.launch
- untracked clever/launch/aruco.launch
- untracked clever/launch/clever.launch
- untracked clever/launch/copter_visualization.launch
- untracked clever/launch/fpv_camera.launch
- untracked clever/launch/main_camera.launch
- untracked clever/launch/mavros.launch
- untracked clever/launch/sitl.launch
- untracked clever/launch/web_server.launch
- untracked clever/nodelet_plugins.xml
- untracked clever/package.xml
- untracked clever/requirements.txt
- untracked clever/src/aruco_vpe.cpp
- untracked clever/src/fcu_horiz.cpp
- untracked clever/src/fpv_camera
- untracked clever/src/global_local.py
- untracked clever/src/rc.cpp
- untracked clever/src/simple_offboard.py
- untracked clever/src/util.h
- untracked clever/src/util.py
- untracked clever/src/web_server.py
- untracked clever/srv/GetTelemetry.srv
- untracked clever/srv/Navigate.srv
- untracked clever/srv/SetAttitude.srv
- untracked clever/srv/SetAttitudeYawRate.srv
- untracked clever/srv/SetPosition.srv
- untracked clever/srv/SetPositionGlobal.srv
- untracked clever/srv/SetPositionGlobalYawRate.srv
- untracked clever/srv/SetPositionYawRate.srv
- untracked clever/srv/SetRates.srv
- untracked clever/srv/SetRatesYaw.srv
- untracked clever/srv/SetVelocity.srv
- untracked clever/srv/SetVelocityYawRate.srv
- untracked deploy/clever.service
- untracked deploy/clever_arudino.tar.gz
- untracked deploy/generate_ros_lib
- untracked deploy/roscore.env
- untracked deploy/roscore.service
- modified docs/3g.md
- modified docs/assemble.md
- untracked docs/deck.md
- modified docs/etcher.md
- modified docs/frames.md
- modified docs/les1.md
- modified docs/les11.md
- modified docs/les13.md
- modified docs/les15.md
- modified docs/les16.md
- modified docs/les2.md
- modified docs/les4.md
- modified docs/les7.md
- modified docs/les8.md
- modified docs/les9.md
- modified docs/modes.md
- untracked docs/powerConnection.md
- modified docs/radioerrors.md
- modified docs/radioerrors1.md
- modified docs/safety.md
- modified docs/setup.md
- modified docs/simple_offboard.md
- modified docs/tb.md
- untracked docs/testConnection.md
- modified docs/wifi.md
- untracked docs/zap.md
- removed gpsmd.md
- untracked image/apps.sh
- untracked image/git_release.py
- untracked image/iface.sh
- untracked image/image-config.sh
- untracked image/Jenkinsfile
- untracked image/ros.sh
- untracked image/yadisk.py
- removed img/11_1.png
- removed img/11_2.png
- removed img/11_3.png
- removed img/11_4.png
- removed img/11_5.png
- removed img/13_1.png
- removed img/13_10.png
- removed img/13_11.png
- removed img/13_2.png
- removed img/13_3.jpg
- removed img/13_4.png
- removed img/13_5.png
- removed img/13_6.png
- removed img/13_7.png
- removed img/13_8.png
- removed img/13_9.png
- removed img/15_1.png
- removed img/15_2.png
- removed img/15_3.png
- removed img/15_4.png
- removed img/15_5.png
- removed img/15_6.png
- removed img/15_7.png
- removed img/16_1.png
- removed img/16_2.png
- removed img/16_3.png
- removed img/16_4.png
- removed img/1_1.png
- removed img/1_10.png
- removed img/1_11.png
- removed img/1_12.png
- removed img/1_13.png
- removed img/1_2.png
- removed img/1_3.png
- removed img/1_4.png
- removed img/1_5.png
- removed img/1_6.png
- removed img/1_7.png
- removed img/1_8.png
- removed img/1_9.png
- removed img/2_1.png
- removed img/2_2.png
- removed img/2_3.png
- removed img/2_4.png
- removed img/2_5.png
- removed img/2_6.png
- removed img/2_7.png
- removed img/2_8.png
- removed img/2_9.png
- removed img/4_1.png
- removed img/4_2.png
- removed img/4_3.png
- removed img/4_4.png
- removed img/4_5.png
- removed img/4_6.png
- removed img/7_1.png
- removed img/7_2.png
- removed img/7_3.png
- removed img/7_4.png
- removed img/8_1.png
- removed img/8_2.png
- removed img/8_3.png
- removed img/8_4.png
- removed img/8_5.png
- removed img/8_6.png
- removed img/9_1.png
- removed img/9_2.png
- removed img/addEqipment.jpg
- removed img/airframeSetup.jpg
- removed img/allElements.png
- removed img/attentionSave.jpg
- removed img/brrc2205.png
- removed img/brrc2205on.png
- removed img/brrc2205ondeck.png
- removed img/calibrateaxcel.jpg
- removed img/calibrateaxcelstart.jpg
- removed img/calibratecompass.jpg
- removed img/calibrateESC.jpg
- removed img/calibrategyro.jpg
- removed img/calibratePIDparams.jpg
- removed img/calibrateView.jpg
- removed img/calibrateViewStart.jpg
- removed img/casebattery.png
- removed img/chooseSwitch.jpg
- removed img/Clever main.png
- removed img/clever.jpg
- removed img/Clevermain.png
- removed img/connectBattery.png
- removed img/connectingRadio.png
- removed img/connectionESCtoReceiver.png
- removed img/connectionLost.jpg
- removed img/connectionOK.jpg
- removed img/connectionPixhawk.png
- removed img/consistofTransmitter.jpg
- removed img/cutwire14AWG.jpg
- removed img/escDYSzap.png
- removed img/escWires.png
- removed img/explosion.png
- removed img/firmwarePX4.jpg
- removed img/flightModes.jpg
- removed img/helphand.jpg
- removed img/holderLegs.png
- removed img/isoViewmountHolder.png
- removed img/jumper.png
- removed img/keep.png
- removed img/lockradio.jpg
- removed img/lockradio.png
- removed img/lowsafeDeck.png
- removed img/mainWindow.jpg
- removed img/motorsTopview.png
- removed img/mount5vconnector.png
- removed img/mountAntenna.png
- removed img/mountBeams.png
- removed img/mountBottomDeck.png
- removed img/mountHolder.png
- removed img/mountPDB.png
- removed img/mountReceiverDeck.png
- removed img/mountReceiverStud.png
- removed img/mountxt60pinsocket.png
- removed img/notmoveslider.jpg
- removed img/pixhawk.png
- removed img/radioTransmitter.png
- removed img/readyBatteryholder.png
- removed img/receiver5V.png
- removed img/receiverPPM.png
- removed img/resolderingESC.png
- removed img/safehighRadial.png
- removed img/safeLegs.png
- removed img/safelowRadial.png
- removed img/safetybyassem.png
- removed img/safetyINflight.png
- removed img/safetyPower.png
- removed img/safetyPreflight.png
- removed img/soldering5VTOpdb.png
- removed img/solderingBrrc2205ondeckTOescDYSzap.png
- removed img/solderingPowerwires.png
- removed img/solderingxt60socketTOpdb.png
- removed img/stand.jpg
- removed img/startPDBtest.jpg
- removed img/testMotors.png
- removed img/topESCcaseview.png
- removed img/topPreview.png
- removed img/topviewmountPDB.png
- removed img/topviewpixhawk.png
- removed img/turnoffSafetyswitch.jpg
- removed img/xt60pinsocket.jpg
- removed img/zap.jpg
- removed img/zapPDBtest.jpg
- removed notes/deck.md
- removed notes/powerConnection.md
- removed notes/testConnection.md
- removed notes/zap.md
- removed primeri-programm.md
- modified README.md
- removed sborka.md
- removed sitl.md

Auto commit by GitBook Editor
2018-02-19 22:22:08 +03:00

454 lines
13 KiB
Swift
Vendored

//
// BinUtils.swift
// BinUtils
//
// Created by Nicolas Seriot on 12/03/16.
// Copyright © 2016 Nicolas Seriot. All rights reserved.
//
import Foundation
import CoreFoundation
// MARK: protocol UnpackedType
public protocol Unpackable {}
extension NSString: Unpackable {}
extension Bool: Unpackable {}
extension Int: Unpackable {}
extension Double: Unpackable {}
// MARK: protocol DataConvertible
protocol DataConvertible {}
extension DataConvertible {
init?(data: Data) {
guard data.count == MemoryLayout<Self>.size else { return nil }
self = data.withUnsafeBytes { $0.pointee }
}
init?(bytes: [UInt8]) {
let data = Data(bytes:bytes)
self.init(data:data)
}
var data: Data {
var value = self
return Data(buffer: UnsafeBufferPointer(start: &value, count: 1))
}
}
extension Bool : DataConvertible { }
extension Int8 : DataConvertible { }
extension Int16 : DataConvertible { }
extension Int32 : DataConvertible { }
extension Int64 : DataConvertible { }
extension UInt8 : DataConvertible { }
extension UInt16 : DataConvertible { }
extension UInt32 : DataConvertible { }
extension UInt64 : DataConvertible { }
extension Float32 : DataConvertible { }
extension Float64 : DataConvertible { }
// MARK: String extension
extension String {
subscript (from:Int, to:Int) -> String {
return NSString(string: self).substring(with: NSMakeRange(from, to-from))
}
}
// MARK: Data extension
extension Data {
var bytes : [UInt8] {
return self.withUnsafeBytes {
[UInt8](UnsafeBufferPointer(start: $0, count: self.count))
}
}
}
// MARK: functions
public func hexlify(_ data:Data) -> String {
// similar to hexlify() in Python's binascii module
// https://docs.python.org/2/library/binascii.html
var s = String()
var byte: UInt8 = 0
for i in 0 ..< data.count {
NSData(data: data).getBytes(&byte, range: NSMakeRange(i, 1))
s = s.appendingFormat("%02x", byte)
}
return s as String
}
public func unhexlify(_ string:String) -> Data? {
// similar to unhexlify() in Python's binascii module
// https://docs.python.org/2/library/binascii.html
let s = string.uppercased().replacingOccurrences(of: " ", with: "")
let nonHexCharacterSet = CharacterSet(charactersIn: "0123456789ABCDEF").inverted
if let range = s.rangeOfCharacter(from: nonHexCharacterSet) {
print("-- found non hex character at range \(range)")
return nil
}
var data = Data(capacity: s.count / 2)
for i in stride(from: 0, to:s.count, by:2) {
let byteString = s[i, i+2]
let byte = UInt8(byteString.withCString { strtoul($0, nil, 16) })
data.append([byte] as [UInt8], count: 1)
}
return data
}
func readIntegerType<T:DataConvertible>(_ type:T.Type, bytes:[UInt8], loc:inout Int) -> T {
let size = MemoryLayout<T>.size
let sub = Array(bytes[loc..<(loc+size)])
loc += size
return T(bytes: sub)!
}
func readFloatingPointType<T:DataConvertible>(_ type:T.Type, bytes:[UInt8], loc:inout Int, isBigEndian:Bool) -> T {
let size = MemoryLayout<T>.size
let sub = Array(bytes[loc..<(loc+size)])
loc += size
let sub_ = isBigEndian ? sub.reversed() : sub
return T(bytes: sub_)!
}
func isBigEndianFromMandatoryByteOrderFirstCharacter(_ format:String) -> Bool {
guard let firstChar = format.first else { assertionFailure("empty format"); return false }
let s = NSString(string: String(firstChar))
let c = s.substring(to: 1)
if c == "@" { assertionFailure("native size and alignment is unsupported") }
if c == "=" || c == "<" { return false }
if c == ">" || c == "!" { return true }
assertionFailure("format '\(format)' first character must be among '=<>!'")
return false
}
// akin to struct.calcsize(fmt)
func numberOfBytesInFormat(_ format:String) -> Int {
var numberOfBytes = 0
var n = 0 // repeat counter
var mutableFormat = format
while !mutableFormat.isEmpty {
let c = mutableFormat.remove(at: mutableFormat.startIndex)
if let i = Int(String(c)) , 0...9 ~= i {
if n > 0 { n *= 10 }
n += i
continue
}
if c == "s" {
numberOfBytes += max(n,1)
n = 0
continue
}
for _ in 0..<max(n,1) {
switch(c) {
case "@", "<", "=", ">", "!", " ":
()
case "c", "b", "B", "x", "?":
numberOfBytes += 1
case "h", "H":
numberOfBytes += 2
case "i", "l", "I", "L", "f":
numberOfBytes += 4
case "q", "Q", "d":
numberOfBytes += 8
case "P":
numberOfBytes += MemoryLayout<Int>.size
default:
assertionFailure("-- unsupported format \(c)")
}
}
n = 0
}
return numberOfBytes
}
func formatDoesMatchDataLength(_ format:String, data:Data) -> Bool {
let sizeAccordingToFormat = numberOfBytesInFormat(format)
let dataLength = data.count
if sizeAccordingToFormat != dataLength {
print("format \"\(format)\" expects \(sizeAccordingToFormat) bytes but data is \(dataLength) bytes")
return false
}
return true
}
/*
pack() and unpack() should behave as Python's struct module https://docs.python.org/2/library/struct.html BUT:
- native size and alignment '@' is not supported
- as a consequence, the byte order specifier character is mandatory and must be among "=<>!"
- native byte order '=' assumes a little-endian system (eg. Intel x86)
- Pascal strings 'p' and native pointers 'P' are not supported
*/
public enum BinUtilsError: Error {
case formatDoesMatchDataLength(format:String, dataSize:Int)
case unsupportedFormat(character:Character)
}
public func pack(_ format:String, _ objects:[Any], _ stringEncoding:String.Encoding=String.Encoding.windowsCP1252) -> Data {
var objectsQueue = objects
var mutableFormat = format
var mutableData = Data()
var isBigEndian = false
let firstCharacter = mutableFormat.remove(at: mutableFormat.startIndex)
switch(firstCharacter) {
case "<", "=":
isBigEndian = false
case ">", "!":
isBigEndian = true
case "@":
assertionFailure("native size and alignment '@' is unsupported'")
default:
assertionFailure("unsupported format chacracter'")
}
var n = 0 // repeat counter
while !mutableFormat.isEmpty {
let c = mutableFormat.remove(at: mutableFormat.startIndex)
if let i = Int(String(c)) , 0...9 ~= i {
if n > 0 { n *= 10 }
n += i
continue
}
var o : Any = 0
if c == "s" {
o = objectsQueue.remove(at: 0)
guard let stringData = (o as! String).data(using: .utf8) else { assertionFailure(); return Data() }
var bytes = stringData.bytes
let expectedSize = max(1, n)
// pad ...
while bytes.count < expectedSize { bytes.append(0x00) }
// ... or trunk
if bytes.count > expectedSize { bytes = Array(bytes[0..<expectedSize]) }
assert(bytes.count == expectedSize)
if isBigEndian { bytes = bytes.reversed() }
mutableData.append(bytes, count: bytes.count)
n = 0
continue
}
for _ in 0..<max(n,1) {
var bytes : [UInt8] = []
if c != "x" {
o = objectsQueue.removeFirst()
}
switch(c) {
case "?":
bytes = (o as! Bool) ? [0x01] : [0x00]
case "c":
let charAsString = (o as! NSString).substring(to: 1)
guard let data = charAsString.data(using: stringEncoding) else {
assertionFailure("cannot decode character \(charAsString) using encoding \(stringEncoding)")
return Data()
}
bytes = data.bytes
case "b":
bytes = Int8(truncatingIfNeeded:o as! Int).data.bytes
case "h":
bytes = Int16(truncatingIfNeeded:o as! Int).data.bytes
case "i", "l":
bytes = Int32(truncatingIfNeeded:o as! Int).data.bytes
case "q", "Q":
bytes = Int64(o as! Int).data.bytes
case "B":
bytes = UInt8(truncatingIfNeeded:o as! Int).data.bytes
case "H":
bytes = UInt16(truncatingIfNeeded:o as! Int).data.bytes
case "I", "L":
bytes = UInt32(truncatingIfNeeded:o as! Int).data.bytes
case "f":
bytes = Float32(o as! Double).data.bytes
case "d":
bytes = Float64(o as! Double).data.bytes
case "x":
bytes = [0x00]
default:
assertionFailure("Unsupported packing format: \(c)")
}
if isBigEndian { bytes = bytes.reversed() }
let data = Data(bytes)
mutableData.append(data)
}
n = 0
}
return mutableData
}
public func unpack(_ format:String, _ data:Data, _ stringEncoding:String.Encoding=String.Encoding.windowsCP1252) throws -> [Unpackable] {
assert(CFByteOrderGetCurrent() == 1 /* CFByteOrderLittleEndian */, "\(#file) assumes little endian, but host is big endian")
let isBigEndian = isBigEndianFromMandatoryByteOrderFirstCharacter(format)
if formatDoesMatchDataLength(format, data: data) == false {
throw BinUtilsError.formatDoesMatchDataLength(format:format, dataSize:data.count)
}
var a : [Unpackable] = []
var loc = 0
let bytes = data.bytes
var n = 0 // repeat counter
var mutableFormat = format
mutableFormat.remove(at: mutableFormat.startIndex) // consume byte-order specifier
while !mutableFormat.isEmpty {
let c = mutableFormat.remove(at: mutableFormat.startIndex)
if let i = Int(String(c)) , 0...9 ~= i {
if n > 0 { n *= 10 }
n += i
continue
}
if c == "s" {
let length = max(n,1)
let sub = Array(bytes[loc..<loc+length])
guard let s = NSString(bytes: sub, length: length, encoding: stringEncoding.rawValue) else {
assertionFailure("-- not a string: \(sub)")
return []
}
a.append(s)
loc += length
n = 0
continue
}
for _ in 0..<max(n,1) {
var o : Unpackable?
switch(c) {
case "c":
let optionalString = NSString(bytes: [bytes[loc]], length: 1, encoding: String.Encoding.utf8.rawValue)
loc += 1
guard let s = optionalString else { assertionFailure(); return [] }
o = s
case "b":
let r = readIntegerType(Int8.self, bytes:bytes, loc:&loc)
o = Int(r)
case "B":
let r = readIntegerType(UInt8.self, bytes:bytes, loc:&loc)
o = Int(r)
case "?":
let r = readIntegerType(Bool.self, bytes:bytes, loc:&loc)
o = r ? true : false
case "h":
let r = readIntegerType(Int16.self, bytes:bytes, loc:&loc)
o = Int(isBigEndian ? Int16(bigEndian: r) : r)
case "H":
let r = readIntegerType(UInt16.self, bytes:bytes, loc:&loc)
o = Int(isBigEndian ? UInt16(bigEndian: r) : r)
case "i":
fallthrough
case "l":
let r = readIntegerType(Int32.self, bytes:bytes, loc:&loc)
o = Int(isBigEndian ? Int32(bigEndian: r) : r)
case "I":
fallthrough
case "L":
let r = readIntegerType(UInt32.self, bytes:bytes, loc:&loc)
o = Int(isBigEndian ? UInt32(bigEndian: r) : r)
case "q":
let r = readIntegerType(Int64.self, bytes:bytes, loc:&loc)
o = Int(isBigEndian ? Int64(bigEndian: r) : r)
case "Q":
let r = readIntegerType(UInt64.self, bytes:bytes, loc:&loc)
o = Int(isBigEndian ? UInt64(bigEndian: r) : r)
case "f":
let r = readFloatingPointType(Float32.self, bytes:bytes, loc:&loc, isBigEndian:isBigEndian)
o = Double(r)
case "d":
let r = readFloatingPointType(Float64.self, bytes:bytes, loc:&loc, isBigEndian:isBigEndian)
o = Double(r)
case "x":
loc += 1
case " ":
()
default:
throw BinUtilsError.unsupportedFormat(character:c)
}
if let o = o { a.append(o) }
}
n = 0
}
return a
}