[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: API Design
- From: tobias@...
- Date: Mon, 18 Sep 2017 23:03:28 +0200
It was thus said that the Great Sean Conner <sean@conman.org> once stated:
It was thus said that the Great tobias@justdreams.de once stated:
I'm designing a library which has a Buffer module that allows to
contain binary data. Think of it as a string just with less features
:-P
There was a heated discussion about this back in 2014:
http://lua-users.org/lists/lua-l/2014-08/msg00819.html
I wrote test code (it's still available) to test that a buffer userdata
would be faster than Lua immutable strings. Immutable strings were faster,
but like I said, I could have done something wrong.
I don't think there is a 'right' answer, but to all those people who
work with this kind of stuff, what would feel more natural to you?
Also, does Segment( offset, length ) makes more sense than Segment(
length, offset ) ?
When I work with this kind of data, I either pass it to C for parsing (Lua
5.1), use string.unpack() (Lua 5.3) or LPeg, depending upon the type of
data. For building data, it's either string concatenation, C (binary
packets under Lua 5.1) or string.pack() (Lua 5.3).
-spc (Coroutines never did get back to me about my code ... )
I never tested it myself, so thanks for the code!
The main reason why I have a buffer module is not just for mutable network
buffers. I do have a binary packer/parser that works on Buffer,Segments and
Lua strings alike, however, when you pass it a buffer it can do simple writes
which makes it really convenient:
Pack = require( "t.Pack" )
Buffer = require( "t.Buffer" )
-- this uses the same identifiers as string.pack
-- `r` is a signed bit-sized integer, `R` is un-signed, `v` is boolean
p = Pack(
{ threeUInt = '>I3' }
, { twoIntegs = '<i2' }
, { twoBytes = Pack(
{ signedByte = 'b' }
, { unsignByte = 'B' }
) }
, { bits = Pack( 'r4','R7',Pack( 'r3', 8
),'r15','v','v','R1','R1','r1','r1' ) }
, { tail = '>I5<I4h' }
)
s = 'AbCdEfGhIjKlMnOpQrStVwxy'
-- 'execution' of a packer allows for read or write operations
print( p.bits[3][4]( s ) )
-3
for i,v in pairs( p.bits[3] ) do print( i, v(s) ) end
1 2
2 2
3 -2
4 -3
5 1
6 1
7 3
8 3
-- fails, because s is immutable
p.bits[3][4]( s, 2 )
stdin:1: bad argument #2 to '?' (Can't write value to string type)
stack traceback:
[C]: in field '?'
stdin:1: in main chunk
[C]: in ?
sz = Pack.getSize( p ) -- size in bytes, #p gets the number of elements
b = Buffer( sz )
b:toHex()
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-- buffers are mutable
p.bits[3][4]( b, 2 )
p.bits[6]( b, true )
b:toHex( )
00 00 00 00 00 00 00 00 00 04 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00