summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorheav <hheav3@gmail.com>2022-11-14 07:01:17 +0000
committerheav <hheav3@gmail.com>2022-11-14 07:01:17 +0000
commitd32b17b91e0f555608af98124a43c6908ec615a0 (patch)
tree13a4e288312184121233cd2bd6b2fd121a9c19be
add message database thing
-rw-r--r--messagelog.lua116
1 files changed, 116 insertions, 0 deletions
diff --git a/messagelog.lua b/messagelog.lua
new file mode 100644
index 0000000..9f05ab4
--- /dev/null
+++ b/messagelog.lua
@@ -0,0 +1,116 @@
+local function esc(x)
+ local res = ""
+ for i=1, #x do
+ local c = x:sub(i,i)
+ if c == "\\" then
+ res = res .. "\\\\"
+ elseif c == "\01" then
+ res = res .. "\\a"
+ elseif c == "\02" then
+ res = res .. "\\b"
+ elseif c == "|" then
+ res = res .. "\\p"
+ else
+ res = res .. c
+ end
+ end
+ return res
+end
+
+local function unesc(x)
+ local res = ""
+ local i = 1
+ while i <= #x do
+ local c = x:sub(i,i)
+ if c == "\\" then
+ local c2 = x:sub(i+1,i+1)
+ if c2 == "\\" then res = res .. "\\" end
+ if c2 == "a" then res = res .. "\01" end
+ if c2 == "b" then res = res .. "\01" end
+ if c2 == "p" then res = res .. "|" end
+ i = i + 1
+ else
+ res = res .. c
+ end
+ i = i + 1
+ end
+ return res
+end
+
+local function genmsg(msg)
+ return "\01|"..msg.timestamp.."|"..esc(msg.sender).."|"..esc(msg.content).."|"..(msg.parent or "").."|"
+end
+
+local function parsemsg(readable)
+ if readable:read(1) ~= "\01" or readable:read(1) ~= "|" then
+ return false
+ end
+ local section = 0
+ local timestamp = ""
+ local sender = ""
+ local content = ""
+ local parent = ""
+ while true do
+ local c = readable:read(1)
+ if c == nil then
+ return false
+ end
+ if c == "|" then
+ section = section + 1
+ if section == 4 then return {timestamp=timestamp, sender=unesc(sender), content=unesc(content), parent=parent=="" and nil or tonumber(parent)} end
+ elseif section == 0 then
+ timestamp = timestamp .. c
+ elseif section == 1 then
+ sender = sender .. c
+ elseif section == 2 then
+ content = content .. c
+ else
+ parent = parent .. c
+ end
+ end
+end
+
+local function appendmsg(filename,msg)
+ local f = io.open(filename,"ab")
+ local res = f:seek("cur",0)
+ f:write(genmsg(msg))
+ f:close()
+ return res
+end
+
+local function getmsg(filename,id)
+ local f = io.open(filename,"rb")
+ f:seek("set",id)
+ local msg = parsemsg(f)
+ msg.id = id
+ f:close()
+ return msg
+end
+
+local function last_n(filename,n,id)
+ local res = {}
+ local f = io.open(filename,"rb")
+ local i = id or 0
+ while true do
+ i = i - 1
+ local pos = f:seek(id and "set" or "end",i)
+ local c = f:read(1)
+ if not c then
+ local res2 = {}
+ for i=#res,1,-1 do
+ table.insert(res2,res[i])
+ end
+ return res2
+ end
+ if c == "\01" then table.insert(res, getmsg(filename,pos)) end
+ if #res >= n or pos == 0 then
+ local res2 = {}
+ for i=#res,1,-1 do
+ table.insert(res2,res[i])
+ end
+ return res2
+ end
+ end
+end
+
+return {last_n = last_n, getmsg = getmsg, appendmsg = appendmsg} \ No newline at end of file