我想制作一个用Elixir编写的自定义文件打包器但是我遇到了问题。 我必须匹配一个以字节为单位的数字。例如:
iex(1)> << value :: little-???-size(4), _ :: binary >> = << 1, 0, 0, 0, 255 >>
<< 1, 0, 0, 0, 255 >>
iex(2)> value
1
我知道我可以使用little-size(32)
,但大小是以位为单位。我可以使用bytes-size(4)
,但我得<< 1, 0, 0, 0 >>
。也许有任何方法可以将它们结合起来吗?
我的文件遵循以下语法:
> 4 bytes: number of files
// First file
> 4 bytes: sub-file's name length
> X bytes: sub-file's name
> 4 bytes: sub-file's content length
> X bytes: sub-file's content
// Second file
> 4 bytes: sub-file's name length
> ...
我只想将以下代码合并到只匹配一个模式:
# Get name length
<<
name_length :: bytes-size(4),
rest :: binary
>> = data
name_bytes = name_length * 8
# Get Filename, and buffer size
<<
filename :: size(name_bytes),
buffer_size :: bytes-size(4),
rest :: binary
>> = rest
buffer_bytes = buffer_size * 8
# Get buffer
<<
buffer :: size(buffer_bytes),
rest :: binary
>> = rest
答案 0 :(得分:0)
我刚刚找到答案。如果有些人遇到与我相同的问题,请使用binary-size(size_in_byte)
(有关二进制类型的更多信息,只需将h <<>>
放入iex控制台)。
iex(1)> <<
... name_length :: little-size(32),
... filename :: binary-size(name_length),
... buffer_size :: little-size(32),
... buffer :: binary-size(buffer_size),
... rest :: binary
... >> = data
[ ... some data ... ]
iex(2)> name_length
8
iex(3)> filename
"Toto.txt"
来自iex doc:
[...]
### Unit and Size
The length of the match is equal to the `unit` (a number of bits) times the `size` (the number of repeated segments of length `unit`).
Type | Default Unit
--------- | ------------
`integer` | 1 bit
`float` | 1 bit
`binary` | 8 bits
[...]
For binaries, the default is the size of the binary. Only the last binary in a match can use the default size. All others must have their size specified explicitly, even if the match is unambiguous. For example:
iex> <<name::binary-size(5), " the ", species::binary>> = <<"Frank the Walrus">>
"Frank the Walrus"
iex> {name, species}
{"Frank", "Walrus"}