Software /
code /
prosody
Annotate
util/dbuffer.lua @ 12591:494577d883ff
util.table: Fix inaccurate comment
Probably a duplicate of the comment next to Lmove, recorded by mistake
Lpack can probably be removed at some point in the near future once we
are confident it is not used anywhere.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Mon, 11 Jul 2022 20:02:10 +0200 |
parent | 11637:19cddf92fcc2 |
child | 12762:79b89f382290 |
rev | line source |
---|---|
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
|
1 local queue = require "util.queue"; |
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) |
6632acc96cf6
util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
94 if 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
|
95 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
|
96 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
|
97 |
6632acc96cf6
util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
98 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
|
99 if 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
|
100 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
|
101 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
|
102 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
|
103 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
|
104 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
|
105 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
|
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 }; |