匹配精灵二进制中的多个部分,用于解析HTTP/2.0帧



我发现了一种匹配二进制框架的快速方法。长度与整数匹配,并且C部分(有效载荷(具有与长度字段中所声明的八位钟一样多。(前三个八位(

<<length::24, b::48, c::binary-size(length)>> <> rest = buffer

问题是要在我的框架上重新组合零件。

frame = <<length::24, b::48, c::binary>>

无论如何都可以在原始匹配中分配帧变量。类似以下内容。尽管此精确版本不起作用

(frame = <<length::24, _::48, _::binary-size(length)>>) <> rest = buffer

编辑,或类似以下语法也有意义

<< frame = <<length::24, _::48, _::binary-size(length)>>, rest::binary>>

afaik,这是不可能的,但是您可能会声明一个方便的助手以避免重复打字:

def matcher(buffer)
  with <<length::24, b::48, c::binary-size(length), rest::binary>> <- buffer do 
    {:ok, <<length::24, b::48, c::binary-size(length)>>, rest}
  else
    other -> {:error, other}
  end
end

并将其像:

{:ok, frame, rest} = matcher(buffer)

我不明白 b::48表示标题的哪个部分。

但是无论如何,明智的是考虑几件事很重要。

  1. 您不是通过返回框架二进制的表演者。如果您已经解析了框架并知道它已经完成,请以etf表示。不要再重新恢复它。
  2. 一行不一定更具性能。这都是关于以某些方式组合和提取二进制零件的全部。
  3. 功能定义中的模式匹配也非常性能,对不同的代码路径尽可能多地进行操作。

我不知道<>的表现如何。我认为这只是速记,但即使有所不同,它也可能足够。

这一点代码应创建并链接二进制零件,并且不应创建任何新的二进制文件。因此,它实际上是相当性能的。

<<length::24, b::48, c::binary-size(length), rest::binary>> = buffer
frame = <<length::24, b::48, c::binary>>

如果您想查看我如何处理此类数据,请看一下WebSockex.Frame

最新更新