LINUX.ORG.RU

Многослойное кодирование/декодирование

 , multilayer,


0

1

Иногда мне нужно переслать CBOR или JSON - и хотелось бы указать получателю, в каком же формате отправлены данные.

Иногда хочется пожать CBOR сверху, и указать уже два тега: 1) данные архивированы, таким-то образом, 2) данные представлены в CBOR

Иногда хочется вообще странного: 1) Преобразовать в CBOR; 2) Сжать; 3) Передать в «безопасной» кодировке Base64, которая не сломает, например, Protocol::Redis::XS

Сейчас я активно пользуюсь своим пакетом Tag::DeCoder, который читает 4-х байтовый тег в начале строки («{CB}» - значит CBOR, «{JS}» - JSON и т.д.) и декодирует, либо кодирует данные с нужным тегом.

Но для многослойного кодирования уже не хотелось бы пользоваться чисто perl'овым кодом или же код должен быть очень хорошо продуман с точки зрения скорости кодирования/декодирования.

Понятно, что можно и свой модуль дописать, это на коленке абы как сделать было быстрее, чем сюда написать.

Просто - вдруг уже есть что-то подобное? Обычно всё, что мне хотелось бы - «не нужно» или есть что-то громоздкое и заумное, что «все пацаны на районе уже 100 лет используют и только ты в танке». Но мало ли, вдруг не я один такой странный. Искал - не нашёл. Возможно, искал не так.

ОТВЕТ:

Сделал сам: https://github.com/DRVTiny/Tag--DeCoder

★★★★★

Ответ на: комментарий от annulen

https://metacpan.org/pod/Data::Serializer

- похож, но модульность не реализована и сама идея какая-то мутная на самом деле: что ещё за compress и прочие словечки типа DES, MD5? Какая разница, как и для чего преобразуются данные - ты ж просто дай унифицированный интерфейс, а там уж кому надо разберётся, в каком порядке и что преобразовывать. Набор совместимых сериализаторов тоже не в дугу...

Придётся, видимо, самому клепать. Базовый вариант Tag::DeCoder'а для поддержки многослойной сериализации добавил, теперь нужно модульность запилить - и будет счастье. А то беда с кучей ненужных модулей, подгружаемых просто потому, что «может пригодится».

DRVTiny ★★★★★ ()

По-моему от лукавого это все. Универсального контейнера для JSON и CBOR в природе нет, поэтому «универсальному сериализатору» придется опеределить свой, со всеми вытекающим последствиями включая отношение граждан к NIH'ам и НЁХ'ам.

К тому же если передавать эти пакеты по http, то тип информации описывается MIME, и остается только запустить нужный декодер

annulen ★★★★★ ()
Ответ на: комментарий от annulen

Кстати, если вдруг хочется не велосипедного контейнера, то можно заюзать multipart/related aka MHTML. Он конечно громоздкий, зато в нем лежат такие же MIME-типы как и в HTTP-ответах, что дает надежду на какое-то обобщение. Модули для разбора и генерации на cpan есть

annulen ★★★★★ ()

Узнал о существовании CBOR из этого треда. Загуглил, просмотрел описание. В описании упоминается специальный тег, 55799, который используется как раз как магическая строка. Добавляй этот тег в начало CBOR-сообщений, тогда сможешь по первому байту отличать от JSON.

i-rinat ★★★★★ ()
Ответ на: комментарий от annulen

Нужно как-то... более прямолинейно :)

В идеале хотелось бы быстрого кодирования/раскодирования структуры данных, завёрнутых в пару-тройку преобразований, на деле реализуемых XS-модулями.

Пока в собственной реализации вижу одну проблему: авторегистрацию кодеров/декодеров. Проблема возникает не тогда, когда они регистрирутся, а тогда, когда кто-то берёт эти данные и собирается их «раскодировать: нужна какая-то магия, которая позволит определить, что для тега „CB“ требуется подгрузить именно модуль для CBOR. Надо подумать :) Пока приходит в голову либо парсинг, либо подгрузка помощью require по имени тега. Но если делать по имени тега, My::Beautiful::Package::CB - такое имя выглядит как-то хреново.

DRVTiny ★★★★★ ()
Ответ на: комментарий от DRVTiny

Вот видишь, ты уже создаешь свой контейнер, а значит, с вероятностью близкой к 100%, никто кроме тебя этим модулем пользоваться не будет

annulen ★★★★★ ()
Ответ на: комментарий от annulen

annulen, прости за оффтопик, но вдруг вспомнишь. Где найти доку по конструкции \(substr($str,OFFSET)) . Я помню, что на конференции в Mail,ru рассказывали о живительной силе ссылки на substr, поскольку такая ссылка указывает на кусок исходной строки, а не на скопированный куда-либо кусок.

Интересно почитать подробнее, поскольку как раз для декодирования строк с заголовком это мега-актуально.

DRVTiny ★★★★★ ()
Ответ на: комментарий от DRVTiny

Но вообще я никогда не занимался перлом профессионально, так только несколько мкросервисов на работе написал и в пару опенсорс-проектов поконтрибьютил :) Так что мб в чем-то не прав

annulen ★★★★★ ()
Ответ на: комментарий от annulen

Вынес из Tag::DeCoder'а все процедуры кодирования/декодирования в конкретных форматах, сделал их все Tag::DeCoder::$TAG'ами.

Итоговый код самого пакета - ажно 46 строк.

Классы кодеров дают стандартизованный интерфейс в виде методов encode/decode - поэтому для того же CBOR весь код такого класса состоит из «package Module::Name; use base 'CBOR::XS'; 1;»

Проверил - неплохо работает, но как всегда с perl'ом бывает весь лютый геморрой - в bytes vs. utf8, так что тут явно грабли потенциально должны быть. Но пока порадовало то, что CBOR+Zlib+Base64 даёт результат, легко транспортируемый куда угодно и при этом очень компактный.

DRVTiny ★★★★★ ()
Ответ на: комментарий от annulen

Просто повертел substr так и сяк - если не копировать явно слайс в другую переменную, то вообще ОК. В т.ч. передача substr в функцию приводит к передаче именно ссылки на подстроку, а не к созданию копии и передаче ссылки на неё, это очень отрадно.

DRVTiny ★★★★★ ()
Последнее исправление: DRVTiny (всего исправлений: 1)
Ответ на: комментарий от annulen

Ну вот ты совсем хочешь погубить во мне ленивого человека? :(

DRVTiny ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.