4 -- |
4 -- |
5 -- This project is MIT/X11 licensed. Please see the |
5 -- This project is MIT/X11 licensed. Please see the |
6 -- COPYING file in the source package for more information. |
6 -- COPYING file in the source package for more information. |
7 -- |
7 -- |
8 |
8 |
9 local softreq = require "util.dependencies".softreq; |
|
10 local random_bytes = require "util.random".bytes; |
9 local random_bytes = require "util.random".bytes; |
11 |
10 |
12 local bit = require "util.bitcompat"; |
11 local bit = require "util.bitcompat"; |
13 local band = bit.band; |
12 local band = bit.band; |
14 local bor = bit.bor; |
13 local bor = bit.bor; |
15 local lshift = bit.lshift; |
|
16 local rshift = bit.rshift; |
|
17 local sbit = require "util.strbitop"; |
14 local sbit = require "util.strbitop"; |
18 local sxor = sbit.sxor; |
15 local sxor = sbit.sxor; |
19 |
16 |
20 local s_char= string.char; |
17 local s_char = string.char; |
21 local s_pack = string.pack; |
18 local s_pack = require"util.struct".pack; |
22 local s_unpack = string.unpack; |
19 local s_unpack = require"util.struct".unpack; |
23 |
20 |
24 if not s_pack and softreq"struct" then |
21 local function pack_uint16be(x) |
25 s_pack = softreq"struct".pack; |
22 return s_pack(">I2", x); |
26 s_unpack = softreq"struct".unpack; |
23 end |
|
24 local function pack_uint64be(x) |
|
25 return s_pack(">I8", x); |
27 end |
26 end |
28 |
27 |
29 local function read_uint16be(str, pos) |
28 local function read_uint16be(str, pos) |
30 local l1, l2 = str:byte(pos, pos+1); |
29 if type(str) ~= "string" then |
31 return l1*256 + l2; |
30 str, pos = str:sub(pos, pos+1), 1; |
|
31 end |
|
32 return s_unpack(">I2", str, pos); |
32 end |
33 end |
33 -- FIXME: this may lose precision |
|
34 local function read_uint64be(str, pos) |
34 local function read_uint64be(str, pos) |
35 local l1, l2, l3, l4, l5, l6, l7, l8 = str:byte(pos, pos+7); |
35 if type(str) ~= "string" then |
36 local h = lshift(l1, 24) + lshift(l2, 16) + lshift(l3, 8) + l4; |
36 str, pos = str:sub(pos, pos+7), 1; |
37 local l = lshift(l5, 24) + lshift(l6, 16) + lshift(l7, 8) + l8; |
|
38 return h * 2^32 + l; |
|
39 end |
|
40 local function pack_uint16be(x) |
|
41 return s_char(rshift(x, 8), band(x, 0xFF)); |
|
42 end |
|
43 local function get_byte(x, n) |
|
44 return band(rshift(x, n), 0xFF); |
|
45 end |
|
46 local function pack_uint64be(x) |
|
47 local h = band(x / 2^32, 2^32-1); |
|
48 return s_char(get_byte(h, 24), get_byte(h, 16), get_byte(h, 8), band(h, 0xFF), |
|
49 get_byte(x, 24), get_byte(x, 16), get_byte(x, 8), band(x, 0xFF)); |
|
50 end |
|
51 |
|
52 if s_pack then |
|
53 function pack_uint16be(x) |
|
54 return s_pack(">I2", x); |
|
55 end |
37 end |
56 function pack_uint64be(x) |
38 return s_unpack(">I8", str, pos); |
57 return s_pack(">I8", x); |
|
58 end |
|
59 end |
|
60 |
|
61 if s_unpack then |
|
62 function read_uint16be(str, pos) |
|
63 if type(str) ~= "string" then |
|
64 str, pos = str:sub(pos, pos+1), 1; |
|
65 end |
|
66 return s_unpack(">I2", str, pos); |
|
67 end |
|
68 function read_uint64be(str, pos) |
|
69 if type(str) ~= "string" then |
|
70 str, pos = str:sub(pos, pos+7), 1; |
|
71 end |
|
72 return s_unpack(">I8", str, pos); |
|
73 end |
|
74 end |
39 end |
75 |
40 |
76 local function parse_frame_header(frame) |
41 local function parse_frame_header(frame) |
77 if frame:len() < 2 then return; end |
42 if frame:len() < 2 then return; end |
78 |
43 |