-
Notifications
You must be signed in to change notification settings - Fork 6
/
ex.lua
148 lines (116 loc) · 3.93 KB
/
ex.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
local bin = require 'bin'
local ffi = require 'ffi'
--[[ For the first: nice hexdump ]]--
-- print hexdump of lua string
print(bin.xd("some binary string"))
--[[ Gives the following output:
[0000] 73 6F 6D 65 20 62 69 6E 61 72 79 20 73 74 72 69 some bin ary stri
[0010] 6E 67 ng
]]
-- Accepts arbitrary pointer and could take length
print(bin.xd(ffi.cast("void *","string"),4))
--[[ Gives the following output:
[0000] 73 74 72 69 stri
]]
-- For compact output there is `hex`
print(bin.hex("some binary string"))
-- 736F6D652062696E61727920737472696E67
--[[ There is also endian conversion functions ]]--
print(bin.htobe16(0x1234)) -- 13330
print(bin.htole16(0x1234)) -- 4660
print(bin.be16toh(0x1234)) -- 13330
print(bin.le16toh(0x1234)) -- 4660
print(bin.htobe32(0x1234)) -- 873594880
print(bin.htole32(0x1234)) -- 4660
print(bin.be32toh(0x1234)) -- 873594880
print(bin.le32toh(0x1234)) -- 4660
print(bin.htobe64(0x1234)) -- 3752061439553044480ULL
print(bin.htole64(0x1234)) -- 4660ULL
print(bin.be64toh(0x1234)) -- 3752061439553044480ULL
print(bin.le64toh(0x1234)) -- 4660ULL
--[[ And buffer objects. Write buffer ]]--
local desired_size = 4096
local buf = bin.buf(desired_size)
print(buf)
-- binbuf<0x31004200>[0/4096]
-- address used/total
-- accepts encoding of integers:
buf:uint8(0xff)
print(buf:hex()) -- FF
buf:uint32(0x12345678)
print(buf:hex()) -- FF78563412
buf:uint32(0x12345678)
-- Also support endianness
buf:uint32be(0x12345678) -- be for big endian
print(buf:hex()) -- FF785634127856341212345678
buf:uint32le(0x12345678) -- le for little endian
print(buf:hex()) -- FF78563412785634121234567878563412
--[[
Complete list of numeric methods:
uint8 int8 uint8be int8le
uint16 int16 uint16be int16le
uint32 int32 uint32be int32le
uint64 int64 uint64be int64le
V = int32le
N = int32be
ber - for BER packed integer (perl pack w)
reb - for reverse BER (big endian)
f float floatbe floatle
d double doublebe doublele <- this one looks so weird ;)
]]
-- buffer may be cleared (reset pos to zero or other pos within buf)
buf:clear(8)
print(buf:hex()) -- FF78563412785634
print(buf) -- binbuf<0x31004200>[8/4096]
buf:clear()
print(buf) -- binbuf<0x31004200>[0/4096]
buf:double(0.123456)
print(buf:hex()) -- FF78563412785634
buf:doublebe(0.123456)
print(buf:hex()) -- BFB67EFACF9ABF3F3FBF9ACFFA7EB6BF
buf:clear()
buf:float(0.123456)
print(buf:hex()) -- 80D6FC3D
buf:floatbe(0.123456)
print(buf:hex()) -- 80D6FC3D3DFCD680
buf:clear()
--[[ Also there is simple :char ]]
buf:char('x') -- !only one char
buf:char(0xfe) -- but also accepts number as byte
print(buf:hex()) -- 78FE
--[[ for strings or buffers there is copy ]]
buf:copy("putme")
buf:copy("notlong",3)
print(buf:dump())
-- [0000] 78 FE 70 75 74 6D 65 6E 6F 74 x.pu tmen ot
buf:clear()
--[[ For manual operation there is :alloc ]]
local nbytes = 5
local p = buf:alloc(nbytes)
ffi.copy(p,"12345",5)
print(buf)
print(buf:dump())
-- binbuf<0x3a801400>[5/4096]
-- [0000] 31 32 33 34 35 1234 5
--[[ If you need raw char data fro buffer, call :pv() ]]
local ptr,len = buf:pv()
local str = ffi.string(ptr,len)
---
--- Inside object real buffer is allocated internally and will be freed with buf destroy
--- If you need to use buffer (for ex for iovec), you must keep reference to buf
--- But since buf is not a pointer to the beginning of char data there is an :export method.
--- It allows to take out character data itself with correct gc-guarded poiner
---
local pv
do
local buf = bin.buf(4096)
buf:copy("test")
local len
pv,len = buf:export()
-- now buffer can't be used anymore for writing data
end
collectgarbage()
-- but pv still points to original data and memory will be freed only when pv will be freed
pv = nil
collectgarbage()
-- now memory was freed. no one should use data under buf or pv