Software /
code /
prosody
Annotate
util/dbuffer.lua @ 11028:d7a403060946
util.dbuffer: Fix traceback when :collapse() is called on empty buffer
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Thu, 20 Aug 2020 15:22:19 +0100 |
parent | 10980:eaee72c7afbd |
child | 11045:8c6bace13229 |
rev | line source |
---|---|
10973
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
1 local queue = require "util.queue"; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
2 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
3 local dbuffer_methods = {}; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
4 local dynamic_buffer_mt = { __index = dbuffer_methods }; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
5 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
6 function dbuffer_methods:write(data) |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
7 if self.max_size and #data + self._length > self.max_size then |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
8 return nil; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
9 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
10 local ok = self.items:push(data); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
11 if not ok then |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
12 self:collapse(); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
13 ok = self.items:push(data); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
14 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
15 if not ok then |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
16 return nil; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
17 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
18 self._length = self._length + #data; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
19 return true; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
20 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
21 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
22 function dbuffer_methods:read_chunk(requested_bytes) |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
23 local chunk, consumed = self.items:peek(), self.front_consumed; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
24 if not chunk then return; end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
25 local chunk_length = #chunk; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
26 local remaining_chunk_length = chunk_length - consumed; |
10980
eaee72c7afbd
util.dbuffer: If no bytes parameter passed to read, return remainder of frontmost chunk
Matthew Wild <mwild1@gmail.com>
parents:
10973
diff
changeset
|
27 if not requested_bytes then |
eaee72c7afbd
util.dbuffer: If no bytes parameter passed to read, return remainder of frontmost chunk
Matthew Wild <mwild1@gmail.com>
parents:
10973
diff
changeset
|
28 requested_bytes = remaining_chunk_length; |
eaee72c7afbd
util.dbuffer: If no bytes parameter passed to read, return remainder of frontmost chunk
Matthew Wild <mwild1@gmail.com>
parents:
10973
diff
changeset
|
29 end |
10973
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
30 if remaining_chunk_length <= requested_bytes then |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
31 self.front_consumed = 0; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
32 self._length = self._length - remaining_chunk_length; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
33 self.items:pop(); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
34 assert(#chunk:sub(consumed + 1, -1) == remaining_chunk_length); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
35 return chunk:sub(consumed + 1, -1), remaining_chunk_length; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
36 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
37 local end_pos = consumed + requested_bytes; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
38 self.front_consumed = end_pos; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
39 self._length = self._length - requested_bytes; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
40 assert(#chunk:sub(consumed + 1, end_pos) == requested_bytes); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
41 return chunk:sub(consumed + 1, end_pos), requested_bytes; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
42 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
43 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
44 function dbuffer_methods:read(requested_bytes) |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
45 local chunks; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
46 |
10980
eaee72c7afbd
util.dbuffer: If no bytes parameter passed to read, return remainder of frontmost chunk
Matthew Wild <mwild1@gmail.com>
parents:
10973
diff
changeset
|
47 if requested_bytes and requested_bytes > self._length then |
10973
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
48 return nil; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
49 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
50 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
51 local chunk, read_bytes = self:read_chunk(requested_bytes); |
10980
eaee72c7afbd
util.dbuffer: If no bytes parameter passed to read, return remainder of frontmost chunk
Matthew Wild <mwild1@gmail.com>
parents:
10973
diff
changeset
|
52 if not requested_bytes then |
eaee72c7afbd
util.dbuffer: If no bytes parameter passed to read, return remainder of frontmost chunk
Matthew Wild <mwild1@gmail.com>
parents:
10973
diff
changeset
|
53 return chunk; |
eaee72c7afbd
util.dbuffer: If no bytes parameter passed to read, return remainder of frontmost chunk
Matthew Wild <mwild1@gmail.com>
parents:
10973
diff
changeset
|
54 elseif chunk then |
10973
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
55 requested_bytes = requested_bytes - read_bytes; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
56 if requested_bytes == 0 then -- Already read everything we need |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
57 return chunk; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
58 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
59 chunks = {}; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
60 else |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
61 return nil; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
62 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
63 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
64 -- Need to keep reading more chunks |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
65 while chunk do |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
66 table.insert(chunks, chunk); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
67 if requested_bytes > 0 then |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
68 chunk, read_bytes = self:read_chunk(requested_bytes); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
69 requested_bytes = requested_bytes - read_bytes; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
70 else |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
71 break; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
72 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
73 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
74 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
75 return table.concat(chunks); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
76 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
77 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
78 function dbuffer_methods:discard(requested_bytes) |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
79 if requested_bytes > self._length then |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
80 return nil; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
81 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
82 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
83 local chunk, read_bytes = self:read_chunk(requested_bytes); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
84 if chunk then |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
85 requested_bytes = requested_bytes - read_bytes; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
86 if requested_bytes == 0 then -- Already read everything we need |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
87 return true; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
88 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
89 else |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
90 return nil; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
91 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
92 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
93 while chunk do |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
94 if requested_bytes > 0 then |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
95 chunk, read_bytes = self:read_chunk(requested_bytes); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
96 requested_bytes = requested_bytes - read_bytes; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
97 else |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
98 break; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
99 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
100 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
101 return true; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
102 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
103 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
104 function dbuffer_methods:sub(i, j) |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
105 if j == nil then |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
106 j = -1; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
107 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
108 if j < 0 then |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
109 j = self._length + (j+1); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
110 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
111 if i < 0 then |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
112 i = self._length + (i+1); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
113 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
114 if i < 1 then |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
115 i = 1; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
116 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
117 if j > self._length then |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
118 j = self._length; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
119 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
120 if i > j then |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
121 return ""; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
122 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
123 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
124 self:collapse(j); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
125 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
126 return self.items:peek():sub(i, j); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
127 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
128 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
129 function dbuffer_methods:byte(i, j) |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
130 i = i or 1; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
131 j = j or i; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
132 return string.byte(self:sub(i, j), 1, -1); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
133 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
134 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
135 function dbuffer_methods:length() |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
136 return self._length; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
137 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
138 dynamic_buffer_mt.__len = dbuffer_methods.length; -- support # operator |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
139 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
140 function dbuffer_methods:collapse(bytes) |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
141 bytes = bytes or self._length; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
142 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
143 local front_chunk = self.items:peek(); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
144 |
11028
d7a403060946
util.dbuffer: Fix traceback when :collapse() is called on empty buffer
Matthew Wild <mwild1@gmail.com>
parents:
10980
diff
changeset
|
145 if not front_chunk or #front_chunk - self.front_consumed >= bytes then |
10973
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
146 return; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
147 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
148 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
149 local front_chunks = { front_chunk:sub(self.front_consumed+1) }; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
150 local front_bytes = #front_chunks[1]; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
151 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
152 while front_bytes < bytes do |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
153 self.items:pop(); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
154 local chunk = self.items:peek(); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
155 front_bytes = front_bytes + #chunk; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
156 table.insert(front_chunks, chunk); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
157 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
158 self.items:replace(table.concat(front_chunks)); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
159 self.front_consumed = 0; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
160 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
161 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
162 local function new(max_size, max_chunks) |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
163 if max_size and max_size <= 0 then |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
164 return nil; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
165 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
166 return setmetatable({ |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
167 front_consumed = 0; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
168 _length = 0; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
169 max_size = max_size; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
170 items = queue.new(max_chunks or 32); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
171 }, dynamic_buffer_mt); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
172 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
173 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
174 return { |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
175 new = new; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
176 }; |