Software /
code /
prosody
Annotate
util/dbuffer.lua @ 13122:45458ecaacae
Merge 0.12->trunk
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Wed, 31 May 2023 14:20:45 +0200 |
parent | 12975:d10957394a3c |
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 }; |