-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathaltBuffer.lua
132 lines (117 loc) · 3.03 KB
/
altBuffer.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
---In case luajit's string.buffer cannot be load successfully,
---use this alternative implementation to keep Zenitha working
---only a minimized implementation which is enough for Zenitha's usage, check the code below for more details
---@class Zenitha.AltBuffer
local altBuffer=setmetatable({},{__index=function(_,k) error("Zenitha.AltBuffer: Invalid method '"..tostring(k).."'") end})
altBuffer.__index=altBuffer
---@class Zenitha.AltBufferRef
---@field src Zenitha.AltBuffer
local altBufRef={}
local type=type
local sub=string.sub
---@param self Zenitha.AltBufferRef
function altBufRef.__index(self,k)
if type(k)=='number' then
k=k+1
if k>#self.src[0] then
self.src:_bake()
end
return sub(self.src[0],k,k)
else
error("Zenitha.AltBufferRef: Invalid method '"..tostring(k).."'")
end
end
function altBuffer.__tostring(self)
self:_bake()
return self[0]
end
function altBuffer.__len(self)
self:_bake()
return #self[0]
end
function altBuffer.__concat(v1,v2)
return
(
type(v1)=='string' and v1 or
type(v1)=='table' and v1._bake and v1:_bake() and v1[0] or
tostring(v1)
)..
(
type(v2)=='string' and v2 or
type(v2)=='table' and v2._bake and v2:_bake() and v2[0] or
tostring(v2)
)
end
function altBuffer.new()
return setmetatable({[0]=""},altBuffer)
end
---@param c string | Zenitha.AltBufferRef
function altBuffer:put(c)
if type(c)=='string' then
if #c>0 then
self[#self+1]=c
end
else
for i=0,#c.src do
if #c.src[i]>0 then
self[#self+1]=c.src[i]
end
end
end
return self
end
local rem=table.remove
function altBuffer:get(c)
if not c then
self[0]=table.concat(self)
for i=1,#self do self[i]=nil end
return self[0]
end
while #self[0]<c and #self>0 do
self[0]=self[0]..rem(self,1)
end
local result
if #self[0]>c then
result=sub(self[0],1,c)
self[0]=sub(self[0],c+1)
else
result=self[0]
self[0]=""
end
return result
end
---@param c number
function altBuffer:skip(c)
if #self[0]>0 then
if c<#self[0] then
self[0]=sub(self[0],c+1)
return
else
c=c-#self[0]
self[0]=""
end
end
while c>0 and #self>0 do
if #self[1]>=c then
self[1]=sub(self[1],c+1)
return
else
c=c-#self[1]
rem(self,1)
end
end
return self
end
function altBuffer:_bake()
if #self>0 then
self[0]=self[0]..table.concat(self)
for i=1,#self do self[i]=nil end
end
return self
end
function altBuffer:ref()
return setmetatable({src=self},altBufRef)
end
function altBuffer:encode() error("Zenitha.AltBuffer: Buffer.encode not implemented") end
function altBuffer:decode() error("Zenitha.AltBuffer: Buffer.decode not implemented") end
return altBuffer