Библиотека msgpack не предназначена для декодирования исходных двоичных файлов, но двоичные файлы, которые ранее были закодированы с помощью msgpack: pack.
Причина в том, что двоичный файл не имеет структуры сам по себе, поэтому вы должны включить в него некоторую информацию, чтобы разрешить декодирование. Это то, что функция, как term_to_binary делает, используя Эрланга внешний формат:
1> B = term_to_binary({12,atom,[$a,$l,$i,$s,$t]}).
<<131,104,3,97,12,100,0,4,97,116,111,109,107,0,5,97,108,
105,115,116>>
2> binary_to_term(B).
{12,atom,"alist"}
Библиотека msgpack позволяет использовать другой метод кодирования.
Приходит к вашей проблеме. Разница между распаковкой и unpack_stream заключается в том, что первые ожидают один единственный закодированный термин в двоичном выражении, а второй предположим, что конечный двоичный код содержит другие закодированные термины.
, когда вы вызываете msgpack:unpack(<<10>>)
, он попадает в случай, когда первый элемент меньше 128: в этом случае кодированное значение является самим значением. Если бы вы пытались что-то большее, чем 127, вы получили ошибку:
4> msgpack:unpack(<<10>>).
{ok,10}
5> msgpack:unpack(<<200>>).
{error,incomplete}
6>
при вызове msgpack:unpack_stream(<<10>>)
, это делает точно то же самое, так что первый элемент декодируется, в результате 10, а остальная часть двоичный обеспечиваются сюда дальнейшее декодирование:
8> {A,Rest} = msgpack:unpack_stream(<<10,0>>).
{10,<<0>>}
9> msgpack:unpack_stream(Rest).
{0,<<>>}
10> msgpack:unpack_stream(<<200,0>>).
{error,incomplete}
11> msgpack:unpack_stream(<<200,0,0>>).
{error,incomplete}
12> msgpack:unpack_stream(<<200,0,0,0>>).
{error,{badarg,{bad_ext,200}}}
13>
Правильный способ использовать библиотеку, чтобы закодировать первые ваше сообщение:
13> Msg = msgpack:pack(<<10,0,0>>).
<<163,10,0,0>>
14> msgpack:unpack(Msg).
{ok,<<10,0,0>>}
или в первом примере:
24> Msg1 = msgpack:pack(msgpack:term_to_binary({12,atom,[$a,$l,$i,$s,$t]})).
<<183,199,20,131,131,104,3,97,12,100,0,4,97,116,111,109,
107,0,5,97,108,105,115,116>>
25> {ok,Rep1} = msgpack:unpack(Msg1).
{ok,<<199,20,131,131,104,3,97,12,100,0,4,97,116,111,109,
107,0,5,97,108,105,115,116>>}
26> msgpack:binary_to_term(Rep1).
{12,atom,"alist"}
27>
[править]
здесь является предложение добавить отступы и распаковщик, что обнаружить его. Он использует unpack_stream, потому что невозможно изменить способ кодирования целого.
Packer = fun(X, Opt) -> {ok, {12,<<>>}} end,
Unpacker = fun(12, _) -> {ok, padding} end,
Opt = [{ext,{Packer,Unpacker}}],
Pad = fun(B) -> Size = 10 - size(B), SB = Size*8,<<B/binary,16#C7,Size,12,0:SB>> end,
R = msgpack:pack(256897),
Var = Pad(R),
{I,Rest} = msgpack:unpack_stream(Var,Opt),
{padding,<<>>} = msgpack:unpack_stream(Rest,Opt).
Большая часть вашего ответа основана на убеждении, что я пытался декодировать случайные двоичные файлы ...которого я не был. Я полностью понимаю, что 0-127 - это единственные значения, которые кодируют 1 байт в кодировке MessagePack. Я выбрал 10 как удобное значение для вопроса, потому что у него нет значимой текстовой кодировки для erlang для печати в виде битовой строки. –
Мой вопрос в том, есть ли способ обозначить целое число с фиксированной шириной (или дополнением). Использование 'unpack_stream' работает, как я упоминал ниже, но это не то же самое, что фиксированный термин ширины, он игнорирует дополнение, которое я добавляю вручную. Я бы предпочел не добавлять дополнения, которые могут мешать определенным значениям. –
Ну, если вы добавите некоторое конечное значение в кодированное сообщение, вы просто испортите его. Как я уже сказал, паровая версия здесь предназначена для обработки потока термина, декодирования первого и предоставления остальных для дальнейшего декодирования; в его контексте добавленный 0 можно интерпретировать как дополнительные члены, равные 0. Бинарники работают на уровне байтов, нет необходимости добавлять байты заполнения. Замечание: целые числа не имеют фиксированной длины в erlang, малые целые числа кодируются по 28 бит (32 бита) или 60 бит (64 бита) и беззвучно используют большое числозначение (слова 3..N), когда они становятся больше , – Pascal