From d32b17b91e0f555608af98124a43c6908ec615a0 Mon Sep 17 00:00:00 2001 From: heav Date: Mon, 14 Nov 2022 07:01:17 +0000 Subject: add message database thing --- messagelog.lua | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 messagelog.lua 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 -- cgit v1.2.3