A Binson implementation in the Swift language. To be used for iOS, MacOS and Linux projects. Read more about Binson ...
Binson is an exceptionally simple binary data serialization format. It is similar in scope to JSON, but it is faster, more compact, and significantly easier to understand.
For example Binson has full support for double precision floating point numbers (including NaN, inf). There is a one-to-one mapping between a Binson object and its serialized bytes. Useful for cryptographic signatures, hash codes and equals operations.
The bytes of a serialized Binson object follow this [ABNF] syntax.
object = begin *field end
field = string value
value = boolean / integer / double / string / bytes / array / object
array = beginArray *value endArray
string = stringLen utf
bytes = bytesLen raw
boolean = true / false
begin = %x40
end = %x41
beginArray = %x42
endArray = %x43
true = %x44
false = %x45
double = %x46 float64
integer = %x10 int8 / %x11 int16 / %x12 int32 / %x13 int64
stringLen = %x14 int8 / %x15 int16 / %x16 int32
bytesLen = %x18 int8 / %x19 int16 / %x1a int32
float64 = 8OCTET ; double precision floation point number [IEEE-754]
int8 = 1OCTET ; 8-bit signed two's complement integer
int16 = 2OCTET ; 16-bit signed two's complement integer
int32 = 4OCTET ; 32-bit signed two's complement integer
int64 = 8OCTET ; 64-bit signed two's complement integer
utf = *OCTET ; stringLen number of [UTF-8] bytes
raw = *OCTET ; any sequence of bytesLen bytes
Binson is Open Source and managed in Github. Download or clone using this link: github.com/assaabloy-ppi/binson-swift
You can also use various Package managers, e.g. Cocoapods
platform :ios, '11.0'
target 'YourProject' do
pod 'Binson', :git => 'https://github.com/assaabloy-ppi/binson-swift.git', :tag => '2.0'
end
% pod install
The append function returns self, so that you can chain append commands.
let binson = Binson()
.append("c", "u")
.append("i", 1)
.append("z", .object(Binson()))
.append("t", .bytes(Data([0x02, 0x02])))
You are also allowed to use the +=
operator to build the Binson object. But note that the declaration require a var declaration.
var binson = Binson()
binson += ("c", "u")
print(binson.hex)
"0x4014016314017541"
Binson supports the Decodable and Encodable protocols introduced in swift 4.0, through the use of BinsonDecoder and BinsonEncoder. This means that you can use the same modern serialization as with JSON. Some notes though:
- The swift Date type is default serialized as a double representing seconds since unix epoch. This can be changed with the DateEncoding/Decoding/Strategy options on the encoder and decoder.
- Since Binson doesn't handle nil values, optionals that are nil will be skipped.
- Integer values will be encoded as the smallest possible Binson type that fits the value.
struct TestCodable: Codable {
struct NestedTestCodable: Codable {
var string = "Hello"
var double = 23.0992
}
var int = 230
var bool = true
var data = Data([0x02, 0x02, 0x04])
var array = ["co", "u"]
var nested = NestedTestCodable()
var opt: Int? // Will not be encoded when nil
}
let encoder = BinsonEncoder()
let testObj = TestCodable()
let binson = try? encoder.encode(testObj)
print(binson?.json)
{
"array" : [
"co",
"u"
],
"bool" : true,
"data" : "0x020204",
"int" : 230,
"nested" : {
"double" : 23.0992,
"string" : "Hello"
}
}
All Binson objects and Value types support the properties .hex, .json and .data. Data is used for binary serialization e.g. for communication with devices.
print(binson.hex)
"0x4014016314017514016910011401741802020214017a404141"
print(binson.json)
{
"c" : "u",
"i" : 1,
"t" : "0x0202",
"z" : {
}
}
print(binson.data)
Data(25 bytes)
let binson_data = Data([0x40, 0x14, 0x01, 0x7a, 0x40, 0x41, 0x41])
if let binson = try? Binson(data: binson_data) {}
if let binson = try? Binson(hex: "0x4014016314017541") {}
if let binson = try? Binson(jsonString: json) {}
You are allowed to access properties inside a Binson object using the subscript approach.
Instead of
if let i2 = binson.value(key: "d") {
print(i2)
}
using subscripts allow for cleaner code
if let i: Int64 = binson["d"].integerValue {
print(i)
}