Software /
code /
prosody
Annotate
util/dbuffer.lua @ 11111:55d8612ac357 0.11
mod_websocket: Continue to process data already in the buffer after an error occurs
Previously any error, or even a normal websocket close frame, would return early,
leaving potentially entire frames in the buffer unprocessed and then discarded.
This change stops processing new data, but returns an existing processed data up
to the point of the error/close.
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Mon, 28 Sep 2020 16:36:12 +0100 |
parent | 11104:6632acc96cf6 |
child | 11114:6a608ecb3471 |
child | 11156:a8ef69f7fc35 |
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 |
6632acc96cf6
util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
3 local dbuffer_methods = {}; |
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 dynamic_buffer_mt = { __index = dbuffer_methods }; |
6632acc96cf6
util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
5 |
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 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
|
7 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
|
8 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
|
9 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
|
10 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
|
11 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
|
12 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
|
13 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
|
14 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
|
15 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
|
16 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
|
17 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
|
18 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
|
19 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
|
20 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
|
21 |
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 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
|
23 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
|
24 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
|
25 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
|
26 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
|
27 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
|
28 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
|
29 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
|
30 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
|
31 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
|
32 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
|
33 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
|
34 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
|
35 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
|
36 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
|
37 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
|
38 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
|
39 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
|
40 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
|
41 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
|
42 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
|
43 |
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 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
|
45 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
|
46 |
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 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
|
48 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
|
49 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
|
50 |
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 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
|
52 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
|
53 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
|
54 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
|
55 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
|
56 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
|
57 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
|
58 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
|
59 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
|
60 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
|
61 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
|
62 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
|
63 |
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 -- 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
|
65 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
|
66 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
|
67 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
|
68 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
|
69 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
|
70 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
|
71 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
|
72 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
|
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 |
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 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
|
76 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
|
77 |
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 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
|
79 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
|
80 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
|
81 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
|
82 |
6632acc96cf6
util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
83 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
|
84 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
|
85 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
|
86 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
|
87 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
|
88 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
|
89 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
|
90 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
|
91 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
|
92 |
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 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
|
94 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
|
95 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
|
96 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
|
97 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
|
98 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
|
99 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
|
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 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
|
102 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
|
103 |
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 function dbuffer_methods:sub(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
|
105 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
|
106 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
|
107 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
|
108 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
|
109 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
|
110 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
|
111 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
|
112 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
|
113 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
|
114 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
|
115 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
|
116 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
|
117 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
|
118 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
|
119 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
|
120 if i > j 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
|
121 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
|
122 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
|
123 |
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 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
|
125 |
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 return self.items:peek():sub(self.front_consumed+1):sub(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
|
127 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
|
128 |
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 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
|
130 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
|
131 j = j or i; |
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 return string.byte(self:sub(i, j), 1, -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
|
133 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
|
134 |
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 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
|
136 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
|
137 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
|
138 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
|
139 |
6632acc96cf6
util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
140 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
|
141 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
|
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 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
|
144 |
6632acc96cf6
util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
145 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
|
146 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
|
147 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
|
148 |
6632acc96cf6
util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
149 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
|
150 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
|
151 |
6632acc96cf6
util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
152 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
|
153 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
|
154 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
|
155 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
|
156 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
|
157 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
|
158 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
|
159 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
|
160 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
|
161 |
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 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
|
163 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
|
164 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
|
165 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
|
166 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
|
167 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
|
168 _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
|
169 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
|
170 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
|
171 }, 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
|
172 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
|
173 |
6632acc96cf6
util.dbuffer: Fix :sub() not working with partially-consumed chunks (thanks Zash for test case)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
174 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
|
175 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
|
176 }; |