util/dbuffer.lua
author Matthew Wild <mwild1@gmail.com>
Thu, 20 Aug 2020 15:22:19 +0100
changeset 11032 d7a403060946
parent 10984 eaee72c7afbd
child 11049 8c6bace13229
permissions -rw-r--r--
util.dbuffer: Fix traceback when :collapse() is called on empty buffer
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
10977
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;
10984
eaee72c7afbd util.dbuffer: If no bytes parameter passed to read, return remainder of frontmost chunk
Matthew Wild <mwild1@gmail.com>
parents: 10977
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: 10977
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: 10977
diff changeset
    29
	end
10977
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
10984
eaee72c7afbd util.dbuffer: If no bytes parameter passed to read, return remainder of frontmost chunk
Matthew Wild <mwild1@gmail.com>
parents: 10977
diff changeset
    47
	if requested_bytes and requested_bytes > self._length then
10977
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);
10984
eaee72c7afbd util.dbuffer: If no bytes parameter passed to read, return remainder of frontmost chunk
Matthew Wild <mwild1@gmail.com>
parents: 10977
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: 10977
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: 10977
diff changeset
    54
	elseif chunk then
10977
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
11032
d7a403060946 util.dbuffer: Fix traceback when :collapse() is called on empty buffer
Matthew Wild <mwild1@gmail.com>
parents: 10984
diff changeset
   145
	if not front_chunk or #front_chunk - self.front_consumed >= bytes then
10977
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
};