Y3 Codec: базовый формат (инварианты)
Обзор
Версия Draft-01 (v202007). Данный протокол определяет форматы отдельных сообщений.
Содержание
Формат пакета Y3-кодека
Определяет форматы сообщений.
Условные обозначения
Диаграммы пакетов и фреймов в этом документе используют специальный формат. Цель этого формата — обобщить, а не определить элементы протокола. Прозой определяются полные семантика и детали структур.
Сложные поля называются, затем следует список полей, заключённых в пару соответствующих фигурных скобок. Каждое поле в этом списке разделяется запятыми.
Отдельные поля включают информацию о длине, а также указания на фиксированное значение, возможность выбора или повторения. Отдельные поля используют следующие условные обозначения, все длины указаны в битах:
x (A): указывает, что x имеет длину A бит;
x (i): указывает, что x использует переменную длину кодирования в integer-encoding;
x (A..B): указывает, что x может иметь любую длину от A до B; A можно опустить, чтобы указать минимум ноль бит, и B можно опустить, чтобы не устанавливать верхний предел; значения в этом формате всегда заканчиваются на границе октета;
x (?) = C: указывает, что x имеет фиксированное значение C;
x (?) = C..D: указывает, что значение x находится в диапазоне от C до D включительно;
[x (E)]: указывает, что x является необязательным (и имеет длину E);
x (E)...: указывает, что x повторяется ноль или более раз (и каждый экземпляр имеет длину E).
В этом документе используются значения сетевого байтового порядка (то есть с прямым порядком байтов). Поля размещаются, начиная с старших битов каждого байта.
По соглашению отдельные поля ссылаются на сложное поле, используя имя сложного поля.
Например:
Пример структуры {
Однобитовое поле (1),
7-битное поле с фиксированным значением (7) = 61,
Поле с переменной длиной целого числа (i),
Произвольное поле (..),
Переменное поле (8..24),
Поле минимальной длины (16..),
Поле максимальной длины (..128),
[Необязательное поле (64)],
Повторяющееся поле (8) ...,
}
Формат TLV
0 7
+--------+
| Тег |
+--------+--------+--------+--------+
| Длина (PVarUInt32) |
+--------+--------+--------+--------+
| ...
+--------+--------+--------+--------+
| Полезная нагрузка значений |
+--------+--------+--------+--------+
| ...
+--------+--------+--------+--------+
Базовый пакет {
Тег (8),
Длина (8..),
Значение (8) ...,
}
Тег {
Тип флага (1),
Флаг массива (1),
Идентификатор последовательности (6),
}
Фиксированная длина 8 бит (1 байт):
8 7 6 0
+------------------------+
| F | A | SeqID |
+------------------------+
Длина описывает длину байтов значения данного пакета, которая является переменной длиной PVarUInt32.
Значение хранит значение данного пакета. При декодировании пользователь должен указать конкретный тип данных для его декодирования.
Означает, что его значение является базовым типом данных.
Означает, что его значение содержит по крайней мере один NodePacket или PrimitivePacket, поэтому дочерние узлы объединяются в окончательный Value данного NodePacket в соответствии с кодировкой TLV.
Если мы хотим преобразовать этот объект формата JSON в Y3:
{
"age" : 5,
"summary": {
"name": "CELLA",
"create": "Y3"
}
}
Сначала определите структуру сообщения, как это делает файл .proto:
Primitive Packet, Tag=0x01 -> "age", тип значения pvarint.
Node Packet, Tag=0x82 -> "summary", этот узел содержит два примитивных пакета:
Primitive Packet, Tag=0x03 -> "name", тип значения string.
Primitive Packet, Tag=0x04 -> "create", тип значения string.
**Использование:**
1. Используйте `Tag = 0x01`, чтобы описать `age`, его значение — целое число `2`, используйте тип `pvarint` при кодировании.
2. Используйте `Tag = 0x82`, чтобы описать `summary`, его полезная нагрузка требует анализа.
3. Используйте `Tag = 0x03`, чтобы описать `name`, его значение — строка `CELLA`.
4. Используйте `Tag = 0x04`, чтобы описать `create`, его значение — строка `Y3`.
**Кодирование:**
0x01 -> Tag=0x01 означает ключ="age" примитивный пакет. 0x01 -> Длина значения равна 1 (тип pvarint, 0x01=1, означает, что следующий 1 байт является полезной нагрузкой значения). 0x05 -> 0x05 — это тип pvarint, который представляет целое число 5. 0x82 -> Tag=0x82 означает ключ="summary" узловой пакет. 0x0B -> Длина значения составляет 11 (тип pvarint, 0x0B=11, означает, что следующие 11 байтов являются полезной нагрузкой значения). 0x03 -> Tag=0x03 означает ключ="name" примитивный пакет. 0x05 -> Длина значения равна 5 (тип pvarint, 0x05=5, означает, что следующие 5 байтов являются полезной нагрузкой значения). 0x43 0x45 0x4C 0x4C 0x41 -> UTF-8 строка для "CELLA". 0x04 -> Tag=0x04 означает ключ="create" примитивный пакет. 0x02 -> Длина значения равна 2 (тип pvarint, 0x02=2, означает, что следующими 2 байтами являются полезная нагрузка значения). 0x59 0x33 -> UTF-8 строка для "Y3".
Будет закодировано как:
`0x01 0x01 0x05 0x82 0x0B 0x03 0x05 0x43 0x45 0x4C 0x4C 0x41 0x04 0x02 0x59 0x33`
## Система типов ##
Поддерживаются следующие типы данных:
1. String.
1. Binary.
1. Boolean.
1. PVarInt32.
1. PVarUInt32.
1. PVarInt64.
1. PVarUInt64.
1. VarFloat32.
1. VarFloat64.
### String
UTF-8 строка.
### Binary
Сырые байты.
### Pvarint
`P-var-int` представляет собой переменную длину целого числа:
* «P» — для «заполнения знакового бита».
* «var» — для переменной длины.
* «int» — для целого числа.
8 7 6 0 +---+---+----------------+ | C |(S)| payloads | +---+---+----------------+
* Big-Endian.
* C `0x80` представляет `Continuation Bit`, если этот бит равен `1`, значит, следующий байт необходимо прочитать следующим, если этот бит равен `0`, значит, это последний байт значения.
* (S) `0x40` представляет как `Signed Bit` для Signed-Integer. для Unsigned-Integer это бит данных.
* С битом знака совпадают непрерывные старшие биты, остальные биты заполняются битом знака.
~~~
PVarInt32 Value {
Continuation Bit (1),
Signed Bit (1),
Payloads (6..),
}
PVarUInt32 Value {
Continuation Bit (1),
Payloads (7..),
}
~~~
#### Пример Pvarint
Значение `i32` `511` в десятичной системе представлено в двоичном виде как `0000 0000 0000 0000 0000 0001 1111 1111`, оно использует 4 байта. Когда мы кодируем его в Pvarint, есть 4 шага:
1. Действительные байты: `xxxx xxx0 1111 1111`.
2. Заполнение всех `x` как знаковый бит `0`: `0000 0001 1111 1111`.
3. Выбор 7-битов в качестве битов значения: `y000 0011 y111 1111`.
4. Изменение MSB как `1`, кроме последнего байта: `1000 0011 0111 1111`.
Значение `i32` `-1` в десятичной системе представлено в двоичном виде как `1111 1111 1111 1111 1111 1111 1111 1111`, оно использует 4 байта. Когда мы кодируем его в Pvarint, есть 4 шага:
1. Действительные байты: `xxxx xx11`.
2. Заполнение всех `x` как знаковый бит `1`: `1111 1111`.
3. Выбор 7-битов в качестве битов значения: `y111 1111`.
4. Изменение MSB как `1`, кроме последнего байта: `0111 1111`.
### Boolean
Значение типа `PVarUInt32` представляет `0` или `1` в 1 байте.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )