diff --git a/lib/solvitdb.lua b/lib/solvitdb.lua index dd3ea54..4f7181e 100644 --- a/lib/solvitdb.lua +++ b/lib/solvitdb.lua @@ -27,6 +27,59 @@ local function readPat(handle, patLength) return packages end +local function insert(readHandle, writeHandle, data) + --NOTE: writeHandle must be in append ("a") mode + local chunkLength = 512 + if #data > 512 then + chunkLength = #data + end + buf2 = data + while true do + buf1 = readHandle:read(chunkLength) + writeHandle:write(buf2) + if not buf1 then + break + end + buf2 = buf1 + end +end + +local function remove(filePath, location, length) + local chunkLength = 512 + if length > 512 then + chunkLength = length + end + -- The file has to get shortened, so I have no choice but to do these shenanigans + local readHandle = assert(fs.open(filePath, "r")) + local tmpFilePath = filePath .. ".tmp" + local writeHandle = assert(fs.open(tmpFilePath, "w")) + local i = 0 + while true do + local readAmount = chunkLength + if readAmount > location - i then + readAmount = location - i + end + if readAmount == 0 then + break + end + local data = readHandle:read(readAmount) + i = i + readAmount + assert(writeHandle:write(data)) + end + readHandle:seek(length) + while true do + local data = readHandle:read(chunkLength) + if not data then + break + end + assert(writeHandle:write(data)) + end + readHandle:close() + writeHandle:close() + fs.rename(tmpFilePath, filePath) + fs.remove(tmpFilePath) +end + function solvitdb.create(path) checkArg(1, path, "string") local handle = assert(fs.open(path, "w")) @@ -38,7 +91,30 @@ function solvitdb.set(path, name, data) checkArg(1, path, "string") checkArg(2, name, "string") checkArg(3, data, "table") - local handle = checkValidityAndOpen(path) + local readHandle, patLength = checkValidityAndOpen(path) + local pat = readPat(readHandle, patLength) + if pat[name] then + + else + local writeHandle = assert(fs.open(path, "a")) + writeHandle:seek("end") + local newPackageLocation = writeHandle:seek() - patLength - 8 + if newPackageLocation > 4294967295 then + -- The above is the 32 bit unsigned integer limit + error("DB too large") + end + writeHandle:write("Pdguess-what-time-it-is;its-soup-time.\n") + writeHandle:seek("set", patLength + 8) -- + 8 because that's the length of the header + local patData = ("%s.%s;"):format(name, string.pack(" 4294967295 then + error("PAT too large") + end + writeHandle:write(string.pack("