local M = {}
local has_strbuffer, strbuffer = pcall(require, 'string.buffer')
if has_strbuffer then
M.new = strbuffer.new
function M.len(buf)
return #buf
end
return M
end
local StrBuffer = {}
StrBuffer.__index = StrBuffer
function StrBuffer:tostring()
if #self.buf > 1 then
self.buf = { table.concat(self.buf) }
end
if self.skip_ptr > 0 then
if self.buf[1] then
self.buf[1] = self.buf[1]:sub(self.skip_ptr + 1)
self.len = self.len - self.skip_ptr
end
self.skip_ptr = 0
end
return self.buf[1] or ''
end
StrBuffer.__tostring = StrBuffer.tostring
function StrBuffer:_peak(n)
local skip, buf1 = self.skip_ptr, self.buf[1]
if buf1 and (n + skip) < #buf1 then
return buf1:sub(skip + 1, skip + n)
end
return self:tostring():sub(1, n)
end
function StrBuffer:put(chunk)
local s = tostring(chunk)
self.buf[#self.buf + 1] = s
self.len = self.len + #s
return self
end
function StrBuffer:set(str)
return self:reset():put(str)
end
function StrBuffer:get(n)
n = n or self.len
local r = self:_peak(n)
self:skip(n)
return r
end
function StrBuffer:skip(n)
self.skip_ptr = math.min(self.len, self.skip_ptr + n)
return self
end
function StrBuffer:reset()
self.buf = {}
self.skip_ptr = 0
self.len = 0
return self
end
function M.new()
return setmetatable({}, StrBuffer):reset()
end
function M.len(buf)
return buf.len - buf.skip_ptr
end
return M