Binn仕様
June 2, 2023 · View on GitHub
フォーマット
各値は、4つの可能なパラメータで格納されます。
[type][size][count][data]
しかし、ほとんどはオプションです。すべての値で使用されるのはtypeパラメータだけです。以下は、基本データ型に使用されるパラメータのリストです。
boolean, null: [type] int, float (storage: byte, word, dword or qword): [type][data] string, blob: [type][size][data] list, object, map: [type][size][count][data]
各パラメータは、多態的なサイズで格納できます。
| パラメータ | サイズ |
|---|---|
| [type] | 1または2バイト |
| [size] | 1または4バイト |
| [count] | 1または4バイト |
| [data] | nバイト |
[Type]
各値は、データ型から始まるように格納されます。1バイトまたは2バイトを使用できます。最初のバイトは次のように分割されます。
+-------- ストレージタイプ | +----- サブタイプサイズ | | +-- サブタイプ 000 0 0000
ストレージ
最も重要な3ビットは、ストレージタイプに使用されます。データが使用するバイト数に関する情報が含まれています。ストレージタイプは、以下のいずれかになります。
- 追加のバイトなし
- 1バイト
- ワード(2バイト、ビッグエンディアン)
- ダブルワード(4バイト、ビッグエンディアン)
- クワッドワード(8バイト、ビッグエンディアン)
- 文字列(UTF-8、ヌル終端)
- ブロブ
- コンテナ
定数は以下の通りです。
| ストレージ | ビット | 16進数 | 10進数 |
|---|---|---|---|
| NOBYTES | 000 0 0000 | 0x00 | 0 |
| BYTE | 001 0 0000 | 0x20 | 32 |
| WORD | 010 0 0000 | 0x40 | 64 |
| DWORD | 011 0 0000 | 0x60 | 96 |
| QWORD | 100 0 0000 | 0x80 | 128 |
| STRING | 101 0 0000 | 0xA0 | 160 |
| BLOB | 110 0 0000 | 0xC0 | 192 |
| CONTAINER | 111 0 0000 | 0xE0 | 224 |
サブタイプサイズ
次のビットは、タイプが1バイトまたは2バイトを使用するかどうかを示します。
ビットが0の場合、タイプは1バイトのみを使用し、サブタイプは4ビット(0から15)です。
+-------- ストレージタイプ | +----- サブタイプサイズ | | +-- サブタイプ 000 0 0000
ビットが1の場合、タイプに別のバイトが使用され、サブタイプは12ビット(最大4096)です。
+-------- ストレージタイプ
| +----- サブタイプサイズ
| |
000 1 0000 0000 0000
| サブタイプ |
+-------------+
サブタイプ
各ストレージには、最大4096のサブタイプがあります。それらは、そのストレージ空間に格納されている値の種類を保持します。
例: DWORDには、符号付き整数、符号なし整数、単精度浮動小数点数など、さまざまな値が含まれることがあります。ユーザー定義の型も含まれます。
以下は、基本データ型の値で、サブタイプが強調表示されています。
| タイプ | ストレージ | ビット | 16進数 | 10進数 |
|---|---|---|---|---|
| Null | NOBYTES | 0000 0000 | 0x00 | 0 |
| True | NOBYTES | 0000 0001 | 0x01 | 1 |
| False | NOBYTES | 0000 0010 | 0x02 | 2 |
| UInt8 | BYTE | 0010 0000 | 0x20 | 32 |
| Int8 | BYTE | 0010 0001 | 0x21 | 33 |
| UInt16 | WORD | 0100 0000 | 0x40 | 64 |
| Int16 | WORD | 0100 0001 | 0x41 | 65 |
| UInt32 | DWORD | 0110 0000 | 0x60 | 96 |
| Int32 | DWORD | 0110 0001 | 0x61 | 97 |
| Float | DWORD | 0110 0010 | 0x62 | 98 |
| UInt64 | QWORD | 1000 0000 | 0x80 | 128 |
| Int64 | QWORD | 1000 0001 | 0x81 | 129 |
| Double | QWORD | 1000 0010 | 0x82 | 130 |
| Text | STRING | 1010 0000 | 0xA0 | 160 |
| DateTime | STRING | 1010 0001 | 0xA1 | 161 |
| Date | STRING | 1010 0010 | 0xA2 | 162 |
| Time | STRING | 1010 0011 | 0xA3 | 163 |
| DecimalStr | STRING | 1010 0100 | 0xA4 | 164 |
| Blob | BLOB | 1100 0000 | 0xC0 | 192 |
| List | CONTAINER | 1110 0000 | 0xE0 | 224 |
| Map | CONTAINER | 1110 0001 | 0xE1 | 225 |
| Object | CONTAINER | 1110 0010 | 0xE2 | 226 |
ユーザー定義型
アプリケーションは、異なるDateTime型を使用し、値をDWORDまたはQWORDに格納できます。
ストレージ = QWORD (0x80)
サブタイプ = 5 (0x05) [未使用のものを選択]タイプ DateTime = (0x80 | 0x05 => 0x85)
アプリケーションは、Binn構造の中にHTMLを送信し、プレーンテキストと区別するための型を定義できます。
ストレージ = STRING (0xA0)
サブタイプ = 9 (0x09) [未使用のものを選択]タイプ HTML = (0xA0 | 0x09 => 0xA9)
サブタイプが15より大きい場合、新しいバイトを使用し、サブタイプサイズビットを設定する必要があります。
ストレージ = STRING (0xA000)
サブタイプサイズ = (0x0100)
サブタイプ = 21 (0x0015)タイプ HTML = (0xA000 | 0x1000 | 0x0015 => 0xB015)
作成されたタイプパラメータは、ビッグエンディアンとして格納する必要があります。
[サイズ]
このパラメータは、文字列、BLOB、およびコンテナで使用されます。1バイトまたは4バイトを持つことができます。
サイズの最初のビットが0の場合、1バイトのみを使用します。したがって、データサイズが最大127(0x7F)バイトの場合、サイズパラメータは1バイトのみを使用します。
それ以外の場合、最上位ビットが1の4バイトのサイズパラメータが使用されます。これにより、上限が2ギガバイト(0x7FFFFFFF)になります。
| データサイズ | サイズパラメータの使用 |
|---|---|
| <= 127バイト | 1バイト |
| > 127バイト | 4バイト |
小さなサイズが4バイトで格納されていても問題ありません。リーダーはどちらも受け入れる必要があります。
文字列の場合、サイズパラメータにはヌル終端子が含まれません。
コンテナの場合、サイズパラメータにはタイプパラメータが含まれます。これにより、構造全体のサイズが格納されます。
注: バージョン2.0より前では、BLOBのサイズは4バイトでのみ格納され、1バイトのサイズには対応していません。
[カウント]
このパラメータは、コンテナ内のアイテム数を通知するために、コンテナでのみ使用されます。サイズパラメータとまったく同じ形式で、1バイトまたは4バイトを持つことができます。
| カウント | カウントパラメータの使用 |
|---|---|
| <= 127アイテム | 1バイト |
| > 127アイテム | 4バイト |
コンテナ
リスト
リストは、値を次々に格納するコンテナです。
カウントパラメータは、コンテナ内の値の数を通知します。
[123, "test", 2.5, true]
マップ
マップは、整数をキーとして使用する連想配列です。
キーは、符号付き整数として読み取られるビッグエンディアンのDWORD(4バイト)を使用して格納されます。
現在の制限は、INT32_MINからINT32_MAXまでですが、必要に応じて増やすことができます。
カウントパラメータは、コンテナ内のキー/値のペアの数を通知します。
{1: 10, 5: "the value", 7: true}
オブジェクト
オブジェクトは、テキストをキーとして使用する連想配列です。
キーはヌル終端されず、上限は255バイトです。
キーは、キーの長さを示す1バイトを前に付けて格納されます。
カウントパラメータは、コンテナ内のキー/値のペアの数を通知します。
{"id": 1, "name": "John", "points": 30.5, "active": true}
制限
| タイプ | 最小 | 最大 |
|---|---|---|
| 整数 | INT64_MIN | UINT64_MAX |
| 浮動小数点数 | IEEE 754 | |
| 文字列 | 0 | 2 GB |
| BLOB | 0 | 2 GB |
| コンテナ | 4 | 2 GB |
連想配列
| キータイプ | 最小 | 最大 |
|---|---|---|
| 数値 | INT32_MIN | INT32_MAX |
| テキスト | 0 | 255バイト |
サブタイプ: 各ストレージタイプに対して最大4096
例の構造
例えば、{"hello":"world"}のようなJSONデータは次のようにシリアル化されます。
Binn: (17バイト)
\xE2 // [type] オブジェクト(コンテナ) \x11 // [size] コンテナの合計サイズ \x01 // [count] キー/値のペア \x05hello // キー \xA0 // [type] = 文字列 \x05 // [size] world\x00 // [data] (ヌル終端)
3つの整数のリスト:
Json: (14バイト)
[123, -456, 789]
Binn: (11バイト)
\xE0 // [type] リスト(コンテナ) \x0B // [size] コンテナの合計サイズ \x03 // [count] アイテム \x20 // [type] = uint8 \x7B // [data] (123) \x41 // [type] = int16 \xFE\x38 // [data] (-456) \x40 // [type] = uint16 \x03\x15 // [data] (789)
マップ内のリスト:
Json: (25バイト)
{1: "add", 2: [-12345, 6789]}
Binn: (26バイト)
\xE1 // [type] マップ(コンテナ) \x1A // [size] コンテナの合計サイズ \x02 // [count] キー/値のペア \x00\x00\x00\x01 // キー \xA0 // [type] = 文字列 \x03 // [size] add\x00 // [data] (ヌル終端) \x00\x00\x00\x02 // キー \xE0 // [type] リスト(コンテナ) \x09 // [size] コンテナの合計サイズ \x02 // [count] アイテム \x41 // [type] = int16 \xCF\xC7 // [data] (-12345) \x40 // [type] = uint16 \x1A\x85 // [data] (6789)
オブジェクトのリスト:
Json: (47バイト)
[ {"id": 1, "name": "John"}, {"id": 2, "name": "Eric"} ]
Binn: (43バイト)
\xE0 // [type] リスト(コンテナ) \x2B // [size] コンテナの合計サイズ \x02 // [count] アイテム \xE2 // [type] オブジェクト(コンテナ) \x14 // [size] コンテナの合計サイズ \x02 // [count] キー/値のペア \x02id // キー \x20 // [type] = uint8 \x01 // [data] (1) \x04name // キー \xA0 // [type] = 文字列 \x04 // [size] John\x00 // [data] (ヌル終端) \xE2 // [type] オブジェクト(コンテナ) \x14 // [size] コンテナの合計サイズ \x02 // [count] キー/値のペア \x02id // キー \x20 // [type] = uint8 \x02 // [data] (2) \x04name // キー \xA0 // [type] = 文字列 \x04 // [size] Eric\x00 // [data] (ヌル終端)