首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MessagePack允许填充整数吗?

MessagePack允许填充整数吗?
EN

Stack Overflow用户
提问于 2015-02-07 19:39:33
回答 2查看 402关注 0票数 0

我试图使用MessagePack来序列化Erlang和Java中的整数。

在Java中,我能够填充一个包含一个整数的数组,这个数组包含任意数量的0,MessagePack.read()仍然返回正确的值。但是在Erlang,如果有任何额外的零,msgpack:unpack/1就会失败。

例如,msgpack:unpack/1按照预期返回{ok,10}传递了<<10>> works。但是添加额外的零并传递<<10,0,0>>失败,返回{error,not_just_binary}。API中的注释指出,错误意味着一个术语已被解码,但二进制仍然存在。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-02-07 19:39:33

当我查看Erlang的源代码以获得更多的信息来问这个问题时,我注意到了另一个函数msgpack:unpack_stream/1,它返回一个带有第一个解码项的元组,并与无关的二进制文件配对,而不是返回一个错误。这在Java中的行为更接近于read

但是我仍然想知道是否有更好的方法来解决这个问题,比如使用固定长度类型的方法。

票数 0
EN

Stack Overflow用户

发布于 2015-02-08 08:52:14

库msgpack不是用来解码原始二进制文件的,而是以前用msgpack:pack编码的二进制文件。

原因是二进制文件本身没有结构,所以您必须在其中包含一些信息以允许解码。这是像term_to_binary这样的函数使用erlang外部格式所做的:

代码语言:javascript
复制
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和unpack_stream之间的区别是,第一个在二进制中期望一个编码项,而第二个假设后面的二进制包含其他编码项。

当您调用msgpack:unpack(<<10>>)时,它会落在第一个元素小于128个的情况下:在本例中,编码值是值本身。如果您尝试使用大于127的内容,则会得到一个错误:

代码语言:javascript
复制
4> msgpack:unpack(<<10>>).
{ok,10}
5> msgpack:unpack(<<200>>).
{error,incomplete}
6>

当您调用msgpack:unpack_stream(<<10>>)时,它执行完全相同的操作,因此第一个元素被解码,结果为10,其余的二进制文件通过进一步解码得到:

代码语言:javascript
复制
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> 

使用该库的正确方法是首先编码您的消息:

代码语言:javascript
复制
13> Msg = msgpack:pack(<<10,0,0>>).
<<163,10,0,0>>
14> msgpack:unpack(Msg).                 
{ok,<<10,0,0>>}

或者第一个例子:

代码语言:javascript
复制
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,因为不可能修改整数的编码方式。

代码语言:javascript
复制
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).
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28386504

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档