13 функций · сигнатуры сверены с lib/xtp2.h · проверено libFuzzer

Справочник расширения xtp2

Библиотека кадров бинарного протокола прикладного уровня поверх упорядоченного потока байтов: включается вариантом build.bat xtp; заголовок 32 байта, четыре типа сообщений (REQUEST / RESPONSE / PUSH / EVENT), потоковый инкрементальный разбор и полноценная система limits. Два inline-помощника (xtp2_text / xtp2_wants_reply) остаются в заголовке — скриптовая сторона встраивает их сама.

Формат wire вкратце

раскладка кадра xtp2 (big-endian) ┌──────────────────────────────────────────────┐ │ magic "xtp\2" 4B фиксированный тег + версия │ │ total u32 длина всего кадра │ │ id u64 ID сообщения (связка запрос-ответ) │ │ flags / type / command / params по u16 │ │ body u32 длина тела │ ├──────────────────────────────────────────────┤ │ [key:u16 value:u16] × params таблица длин │ │ данные command · данные параметров · body │ └──────────────────────────────────────────────┘ type: REQUEST / RESPONSE / PUSH / EVENT · запрос с id==0 ответа не требует

Умолчания limits: целый кадр ≤1 МиБ, ≤256 параметров, у длин command/ключа/значения свои потолки — всё ужесточается в xtp2_config (ниже). Ошибки разбора липкие: после ошибки новые сообщения не выдаются до xtp2_reset.

Создание и конфигурация (3)

xtp2_config_init конфигурация

Инициализировать конфигурацию значениями по умолчанию (все limits по умолчанию + стандартный аллокатор).

void xtp2_config_init(xtp2_config *config);
Ограничение: max_packet ∈ [32, UINT32_MAX], остальные limits должны согласовываться с wire

Недопустимая конфигурация (например, слишком малый max_packet) вернёт E_ARGUMENT на create — ужесточение ограничений не откажет молча.

xtp2_create / xtp2_destroy жизненный цикл

Создать / уничтожить обработчик. NULL config — значения по умолчанию.

xtp2_result xtp2_create(const xtp2_config *config, xtp2_processor **out); void xtp2_destroy(xtp2_processor *processor);
Потоки: один обработчик без конкурентности; несколько обработчиков независимыАллокатор: config позволяет внедрить свой realloc (обязан быть потокобезопасным)

Потоковый разбор (2)

xtp2_feed разбор

Инкрементальная подача байтов: за один вызов выдаётся максимум одно сообщение; consumed сообщает, сколько потреблено.

xtp2_result xtp2_feed(xtp2_processor *processor, const void *data, size_t size, size_t *consumed, xtp2_message *message);
Возврат: XTP2_MORE (мало данных) / XTP2_MESSAGE (выдано) / отрицательное (липкая ошибка)Сообщение: выходной параметр со значимой семантикой; использовали в колбэке/цикле — выбросили
Официальное применение (дословно из lib/xtp2.h)сигнатуры из источника
xtp2_processor *rx;
if ( xtp2_create(NULL, &rx) != XTP2_OK ) { ... }
while ( size ) {
    size_t iUsed;
    xtp2_message msg;
    xtp2_result r = xtp2_feed(rx, bytes, size, &iUsed, &msg);
    bytes += iUsed; size -= iUsed;
    if ( r < 0 ) break;                /* липкая ошибка */
    if ( r == XTP2_MESSAGE ) { ... }  /* использовать/скопировать msg и продолжить */
    if ( r == XTP2_MORE ) break;    /* ждать следующую порцию данных */
}

xtp2_finish разбор

Проверка конца потока: при EOF с недоданным полукадром возвращает ошибку (молчаливого отбрасывания нет).

xtp2_result xtp2_finish(xtp2_processor *processor);
Момент: при чтении EOF (закрытие соединения)

Одиночный кадр и кодирование (3)

xtp2_decode разбор

Декодирование одиночного кадра из полного буфера (без инкрементального состояния).

xtp2_result xtp2_decode(xtp2_processor *processor, const void *data, size_t size, const xtp2_limits *limits, xtp2_message *message);
Сценарий: весь кадр уже на руках (память/файл)

xtp2_measure / xtp2_encode кодирование

Сначала измерить, потом писать: measure считает нужное число байтов, encode пишет в буфер. При ошибке выходной буфер не трогается.

xtp2_result xtp2_measure(const xtp2_message *message, const xtp2_limits *limits, size_t *out_size); xtp2_result xtp2_encode(const xtp2_message *message, const xtp2_limits *limits, void *out, size_t out_size);
Дисциплина: источник и приёмник кодирования не перекрываютсяКольцо: decode→encode совпадает байт в байт (инвариант фаззинга)

Параметры и ошибки (5)

xtp2_params / xtp2_param_next параметры

Итератор параметров: взять указатель на голову / перейти к следующей паре key-value span.

xtp2_iter xtp2_params(const xtp2_message *message); bool xtp2_param_next(xtp2_iter *iter, xtp2_span *key, xtp2_span *value);
span: явная длина в байтах, никогда неявный strlen

xtp2_find параметры

Поиск значения параметра по точному бинарному совпадению.

bool xtp2_find(const xtp2_message *message, xtp2_span key, xtp2_span *value);

xtp2_reset / xtp2_error_string состояние

Сбросить липкую ошибку, вернув обработчику переиспользуемость / превратить код ошибки в текст описания.

void xtp2_reset(xtp2_processor *processor); const char *xtp2_error_string(xtp2_result result);
Семантика: ошибка липкая до reset