Reputation: 4676
I have discovered a quick way to match a frame from a binary. The length matches as an integer and part c (the payload) has as many octets as declared in the length field. (First three octets)
<<length::24, b::48, c::binary-size(length)>> <> rest = buffer
The problem is to get at my frame I need to recombine the parts.
frame = <<length::24, b::48, c::binary>>
Is there anyway to assign the frame variable in the original match. Something like the following. Though this precise version does not work
(frame = <<length::24, _::48, _::binary-size(length)>>) <> rest = buffer
Edit, or some syntax like the following would also make sense
<< frame = <<length::24, _::48, _::binary-size(length)>>, rest::binary>>
Upvotes: 2
Views: 243
Reputation: 4383
I don't understand exactly what part of the header that b::48
signifies.
But anyway, performance wise it's important to consider a couple of things.
etf
representation. Don't reparse it again.I don't know how performant <>
really is. I think it is just shorthand, but it's probably performant enough even if it different.
This bit of code should create and link binary parts and shouldn't create any new binaries. Therefore it is actually quite performant.
<<length::24, b::48, c::binary-size(length), rest::binary>> = buffer
frame = <<length::24, b::48, c::binary>>
If you want to see how I handled this kind of data then take a look at WebSockex.Frame
.
Upvotes: 0
Reputation: 121000
AFAIK, it’s impossible exactly this way, but you might declare a handy helper to avoid repetitive typing:
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
And use it like:
{:ok, frame, rest} = matcher(buffer)
Upvotes: 1