Annotate

util/dbuffer.lua @ 13227:58083329903d

mod_muc_mam: Use period option method
author Kim Alvefur <zash@zash.se>
date Tue, 18 Jul 2023 12:33:51 +0200
parent 12975:d10957394a3c
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
12975
d10957394a3c util: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12763
diff changeset
1 local queue = require "prosody.util.queue";
11104
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
2
11189
0ff148362a3d util.dbuffer: Optimize :sub() and :byte()
Matthew Wild <mwild1@gmail.com>
parents: 11156
diff changeset
3 local s_byte, s_sub = string.byte, string.sub;
11104
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
4 local dbuffer_methods = {};
11196
f243836c449a util.dbuffer: Add __name to metatable
Matthew Wild <mwild1@gmail.com>
parents: 11190
diff changeset
5 local dynamic_buffer_mt = { __name = "dbuffer", __index = dbuffer_methods };
11104
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
6
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
7 function dbuffer_methods:write(data)
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
8 if self.max_size and #data + self._length > self.max_size then
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
9 return nil;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
10 end
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
11 local ok = self.items:push(data);
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
12 if not ok then
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
13 self:collapse();
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
14 ok = self.items:push(data);
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
15 end
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
16 if not ok then
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
17 return nil;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
18 end
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
19 self._length = self._length + #data;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
20 return true;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
21 end
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
22
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
23 function dbuffer_methods:read_chunk(requested_bytes)
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
24 local chunk, consumed = self.items:peek(), self.front_consumed;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
25 if not chunk then return; end
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
26 local chunk_length = #chunk;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
27 local remaining_chunk_length = chunk_length - consumed;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
28 if not requested_bytes then
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
29 requested_bytes = remaining_chunk_length;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
30 end
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
31 if remaining_chunk_length <= requested_bytes then
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
32 self.front_consumed = 0;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
33 self._length = self._length - remaining_chunk_length;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
34 self.items:pop();
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
35 assert(#chunk:sub(consumed + 1, -1) == remaining_chunk_length);
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
36 return chunk:sub(consumed + 1, -1), remaining_chunk_length;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
37 end
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
38 local end_pos = consumed + requested_bytes;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
39 self.front_consumed = end_pos;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
40 self._length = self._length - requested_bytes;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
41 assert(#chunk:sub(consumed + 1, end_pos) == requested_bytes);
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
42 return chunk:sub(consumed + 1, end_pos), requested_bytes;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
43 end
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
44
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
45 function dbuffer_methods:read(requested_bytes)
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
46 local chunks;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
47
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
48 if requested_bytes and requested_bytes > self._length then
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
49 return nil;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
50 end
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
51
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
52 local chunk, read_bytes = self:read_chunk(requested_bytes);
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
53 if not requested_bytes then
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
54 return chunk;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
55 elseif chunk then
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
56 requested_bytes = requested_bytes - read_bytes;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
57 if requested_bytes == 0 then -- Already read everything we need
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
58 return chunk;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
59 end
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
60 chunks = {};
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
61 else
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
62 return nil;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
63 end
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
64
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
65 -- Need to keep reading more chunks
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
66 while chunk do
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
67 table.insert(chunks, chunk);
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
68 if requested_bytes > 0 then
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
69 chunk, read_bytes = self:read_chunk(requested_bytes);
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
70 requested_bytes = requested_bytes - read_bytes;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
71 else
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
72 break;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
73 end
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
74 end
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
75
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
76 return table.concat(chunks);
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
77 end
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
78
11636
11e0a0a08da3 util.dbuffer: Add read_until() method
Matthew Wild <mwild1@gmail.com>
parents: 11196
diff changeset
79 -- Read to, and including, the specified character sequence (return nil if not found)
11e0a0a08da3 util.dbuffer: Add read_until() method
Matthew Wild <mwild1@gmail.com>
parents: 11196
diff changeset
80 function dbuffer_methods:read_until(char)
11e0a0a08da3 util.dbuffer: Add read_until() method
Matthew Wild <mwild1@gmail.com>
parents: 11196
diff changeset
81 local buffer_pos = 0;
11e0a0a08da3 util.dbuffer: Add read_until() method
Matthew Wild <mwild1@gmail.com>
parents: 11196
diff changeset
82 for i, chunk in self.items:items() do
11637
19cddf92fcc2 util.dbuffer: Fix bugs, remove multi-char support (more complex than first thought)
Matthew Wild <mwild1@gmail.com>
parents: 11636
diff changeset
83 local start = 1 + ((i == 1) and self.front_consumed or 0);
11636
11e0a0a08da3 util.dbuffer: Add read_until() method
Matthew Wild <mwild1@gmail.com>
parents: 11196
diff changeset
84 local char_pos = chunk:find(char, start, true);
11e0a0a08da3 util.dbuffer: Add read_until() method
Matthew Wild <mwild1@gmail.com>
parents: 11196
diff changeset
85 if char_pos then
11637
19cddf92fcc2 util.dbuffer: Fix bugs, remove multi-char support (more complex than first thought)
Matthew Wild <mwild1@gmail.com>
parents: 11636
diff changeset
86 return self:read(1 + buffer_pos + char_pos - start);
11636
11e0a0a08da3 util.dbuffer: Add read_until() method
Matthew Wild <mwild1@gmail.com>
parents: 11196
diff changeset
87 end
11637
19cddf92fcc2 util.dbuffer: Fix bugs, remove multi-char support (more complex than first thought)
Matthew Wild <mwild1@gmail.com>
parents: 11636
diff changeset
88 buffer_pos = buffer_pos + #chunk - (start - 1);
11636
11e0a0a08da3 util.dbuffer: Add read_until() method
Matthew Wild <mwild1@gmail.com>
parents: 11196
diff changeset
89 end
11e0a0a08da3 util.dbuffer: Add read_until() method
Matthew Wild <mwild1@gmail.com>
parents: 11196
diff changeset
90 return nil;
11e0a0a08da3 util.dbuffer: Add read_until() method
Matthew Wild <mwild1@gmail.com>
parents: 11196
diff changeset
91 end
11e0a0a08da3 util.dbuffer: Add read_until() method
Matthew Wild <mwild1@gmail.com>
parents: 11196
diff changeset
92
11104
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
93 function dbuffer_methods:discard(requested_bytes)
12763
d26eefe98d09 util.dbuffer: Add efficient shortcuts for discard() in certain cases
Matthew Wild <mwild1@gmail.com>
parents: 12762
diff changeset
94 if self._length == 0 then return true; end
d26eefe98d09 util.dbuffer: Add efficient shortcuts for discard() in certain cases
Matthew Wild <mwild1@gmail.com>
parents: 12762
diff changeset
95 if not requested_bytes or requested_bytes >= self._length then
d26eefe98d09 util.dbuffer: Add efficient shortcuts for discard() in certain cases
Matthew Wild <mwild1@gmail.com>
parents: 12762
diff changeset
96 self.front_consumed = 0;
d26eefe98d09 util.dbuffer: Add efficient shortcuts for discard() in certain cases
Matthew Wild <mwild1@gmail.com>
parents: 12762
diff changeset
97 self._length = 0;
d26eefe98d09 util.dbuffer: Add efficient shortcuts for discard() in certain cases
Matthew Wild <mwild1@gmail.com>
parents: 12762
diff changeset
98 for _ in self.items:consume() do end
d26eefe98d09 util.dbuffer: Add efficient shortcuts for discard() in certain cases
Matthew Wild <mwild1@gmail.com>
parents: 12762
diff changeset
99 return true;
11104
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
100 end
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
101
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
102 local chunk, read_bytes = self:read_chunk(requested_bytes);
12762
79b89f382290 util.dbuffer: Remove redundant code (read_chunk() cannot fail at this point)
Matthew Wild <mwild1@gmail.com>
parents: 11637
diff changeset
103 requested_bytes = requested_bytes - read_bytes;
79b89f382290 util.dbuffer: Remove redundant code (read_chunk() cannot fail at this point)
Matthew Wild <mwild1@gmail.com>
parents: 11637
diff changeset
104 if requested_bytes == 0 then -- Already read everything we need
79b89f382290 util.dbuffer: Remove redundant code (read_chunk() cannot fail at this point)
Matthew Wild <mwild1@gmail.com>
parents: 11637
diff changeset
105 return true;
11104
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
106 end
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
107
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
108 while chunk do
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
109 if requested_bytes > 0 then
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
110 chunk, read_bytes = self:read_chunk(requested_bytes);
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
111 requested_bytes = requested_bytes - read_bytes;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
112 else
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
113 break;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
114 end
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
115 end
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
116 return true;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
117 end
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
118
11189
0ff148362a3d util.dbuffer: Optimize :sub() and :byte()
Matthew Wild <mwild1@gmail.com>
parents: 11156
diff changeset
119 -- Normalize i, j into absolute offsets within the
0ff148362a3d util.dbuffer: Optimize :sub() and :byte()
Matthew Wild <mwild1@gmail.com>
parents: 11156
diff changeset
120 -- front chunk (accounting for front_consumed), and
0ff148362a3d util.dbuffer: Optimize :sub() and :byte()
Matthew Wild <mwild1@gmail.com>
parents: 11156
diff changeset
121 -- ensure there is enough data in the first chunk
0ff148362a3d util.dbuffer: Optimize :sub() and :byte()
Matthew Wild <mwild1@gmail.com>
parents: 11156
diff changeset
122 -- to cover any subsequent :sub() or :byte() operation
0ff148362a3d util.dbuffer: Optimize :sub() and :byte()
Matthew Wild <mwild1@gmail.com>
parents: 11156
diff changeset
123 function dbuffer_methods:_prep_sub(i, j)
11104
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
124 if j == nil then
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
125 j = -1;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
126 end
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
127 if j < 0 then
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
128 j = self._length + (j+1);
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
129 end
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
130 if i < 0 then
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
131 i = self._length + (i+1);
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
132 end
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
133 if i < 1 then
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
134 i = 1;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
135 end
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
136 if j > self._length then
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
137 j = self._length;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
138 end
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
139 if i > j then
11189
0ff148362a3d util.dbuffer: Optimize :sub() and :byte()
Matthew Wild <mwild1@gmail.com>
parents: 11156
diff changeset
140 return nil;
11104
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
141 end
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
142
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
143 self:collapse(j);
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
144
11189
0ff148362a3d util.dbuffer: Optimize :sub() and :byte()
Matthew Wild <mwild1@gmail.com>
parents: 11156
diff changeset
145 if self.front_consumed > 0 then
0ff148362a3d util.dbuffer: Optimize :sub() and :byte()
Matthew Wild <mwild1@gmail.com>
parents: 11156
diff changeset
146 i = i + self.front_consumed;
0ff148362a3d util.dbuffer: Optimize :sub() and :byte()
Matthew Wild <mwild1@gmail.com>
parents: 11156
diff changeset
147 j = j + self.front_consumed;
0ff148362a3d util.dbuffer: Optimize :sub() and :byte()
Matthew Wild <mwild1@gmail.com>
parents: 11156
diff changeset
148 end
0ff148362a3d util.dbuffer: Optimize :sub() and :byte()
Matthew Wild <mwild1@gmail.com>
parents: 11156
diff changeset
149
0ff148362a3d util.dbuffer: Optimize :sub() and :byte()
Matthew Wild <mwild1@gmail.com>
parents: 11156
diff changeset
150 return i, j;
0ff148362a3d util.dbuffer: Optimize :sub() and :byte()
Matthew Wild <mwild1@gmail.com>
parents: 11156
diff changeset
151 end
0ff148362a3d util.dbuffer: Optimize :sub() and :byte()
Matthew Wild <mwild1@gmail.com>
parents: 11156
diff changeset
152
0ff148362a3d util.dbuffer: Optimize :sub() and :byte()
Matthew Wild <mwild1@gmail.com>
parents: 11156
diff changeset
153 function dbuffer_methods:sub(i, j)
0ff148362a3d util.dbuffer: Optimize :sub() and :byte()
Matthew Wild <mwild1@gmail.com>
parents: 11156
diff changeset
154 i, j = self:_prep_sub(i, j);
0ff148362a3d util.dbuffer: Optimize :sub() and :byte()
Matthew Wild <mwild1@gmail.com>
parents: 11156
diff changeset
155 if not i then
0ff148362a3d util.dbuffer: Optimize :sub() and :byte()
Matthew Wild <mwild1@gmail.com>
parents: 11156
diff changeset
156 return "";
0ff148362a3d util.dbuffer: Optimize :sub() and :byte()
Matthew Wild <mwild1@gmail.com>
parents: 11156
diff changeset
157 end
0ff148362a3d util.dbuffer: Optimize :sub() and :byte()
Matthew Wild <mwild1@gmail.com>
parents: 11156
diff changeset
158 return s_sub(self.items:peek(), i, j);
11104
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
159 end
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
160
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
161 function dbuffer_methods:byte(i, j)
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
162 i = i or 1;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
163 j = j or i;
11189
0ff148362a3d util.dbuffer: Optimize :sub() and :byte()
Matthew Wild <mwild1@gmail.com>
parents: 11156
diff changeset
164 i, j = self:_prep_sub(i, j);
0ff148362a3d util.dbuffer: Optimize :sub() and :byte()
Matthew Wild <mwild1@gmail.com>
parents: 11156
diff changeset
165 if not i then
0ff148362a3d util.dbuffer: Optimize :sub() and :byte()
Matthew Wild <mwild1@gmail.com>
parents: 11156
diff changeset
166 return;
0ff148362a3d util.dbuffer: Optimize :sub() and :byte()
Matthew Wild <mwild1@gmail.com>
parents: 11156
diff changeset
167 end
0ff148362a3d util.dbuffer: Optimize :sub() and :byte()
Matthew Wild <mwild1@gmail.com>
parents: 11156
diff changeset
168 return s_byte(self.items:peek(), i, j);
11104
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
169 end
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
170
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
171 function dbuffer_methods:length()
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
172 return self._length;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
173 end
11156
a8ef69f7fc35 util.dbuffer: Expose length as :len() method, like strings
Kim Alvefur <zash@zash.se>
parents: 11104
diff changeset
174 dbuffer_methods.len = dbuffer_methods.length; -- strings have :len()
11104
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
175 dynamic_buffer_mt.__len = dbuffer_methods.length; -- support # operator
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
176
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
177 function dbuffer_methods:collapse(bytes)
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
178 bytes = bytes or self._length;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
179
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
180 local front_chunk = self.items:peek();
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
181
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
182 if not front_chunk or #front_chunk - self.front_consumed >= bytes then
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
183 return;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
184 end
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
185
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
186 local front_chunks = { front_chunk:sub(self.front_consumed+1) };
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
187 local front_bytes = #front_chunks[1];
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
188
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
189 while front_bytes < bytes do
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
190 self.items:pop();
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
191 local chunk = self.items:peek();
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
192 front_bytes = front_bytes + #chunk;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
193 table.insert(front_chunks, chunk);
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
194 end
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
195 self.items:replace(table.concat(front_chunks));
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
196 self.front_consumed = 0;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
197 end
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
198
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
199 local function new(max_size, max_chunks)
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
200 if max_size and max_size <= 0 then
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
201 return nil;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
202 end
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
203 return setmetatable({
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
204 front_consumed = 0;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
205 _length = 0;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
206 max_size = max_size;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
207 items = queue.new(max_chunks or 32);
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
208 }, dynamic_buffer_mt);
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
209 end
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
210
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
211 return {
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
212 new = new;
6632acc96cf6 util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
213 };