Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- (C) 2012 Sandre S. (firstname at gmail)
- --
- -- Licensed under the Apache License, Version 2.0 (the "License");
- -- you may not use this file except in compliance with the License.
- -- You may obtain a copy of the License at
- --
- -- http://www.apache.org/licenses/LICENSE-2.0
- --
- -- Unless required by applicable law or agreed to in writing, software
- -- distributed under the License is distributed on an "AS IS" BASIS,
- -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- -- See the License for the specific language governing permissions and
- -- limitations under the License.
- --
- -- Default configuration
- local BaseDirectory = "/.vault"
- local DefaultMode = "append"
- local DefaultHybridN = 200
- -- data -> Lua conversion
- local validTypes = {}
- validTypes['string'] = function(str)
- return string.format("%q", str)
- end
- validTypes['number'] = function(num)
- local srep = tostring(num)
- if srep == "inf" then
- return "math.huge"
- end
- return srep
- end
- validTypes['boolean'] = tostring
- validTypes['nil'] = function() return 'nil' end
- --- Converts stuff to a Lua representation
- -- @param obj The object to turn into Lua code
- local function toLua(val)
- local sType = type(val)
- if validTypes[sType] then
- return validTypes[sType](val)
- end
- end
- local LineTemplate = "t[%s] = %s"
- local FileTemplate = [[
- local arg = {...}
- local t = arg[1]
- if type(t) ~= "table" then
- error("Data script didn't recieve a table to transfer values to!")
- end
- -- Begin data
- ]]
- local function genLine(k, v)
- return string.format(LineTemplate, toLua(k), toLua(v))
- end
- local function genWhole(tData)
- local cData = {FileTemplate }
- for k, v in pairs(tData) do
- table.insert(cData, genLine(k, v))
- end
- return table.concat(cData, "\n")
- end -- /Data -> Lua conversion
- -- Proxy management
- local Proxies = {}
- local ProxyNames = {} -- Reverse lookup
- local ProxyConf = {} -- Configuration (HybridN, Mode, File, CurrentHybridN, ???)
- local ProxyRaw = {} -- Raw tables
- do
- local weakKey, weakValue = {__mode = "k"}, {__mode = "v"}
- setmetatable(Proxies, weakValue)
- setmetatable(ProxyNames, weakKey)
- setmetatable(ProxyConf, weakKey)
- setmetatable(ProxyRaw, weakKey)
- end -- Allow unreferenced proxies to be GC'd, even if they are registered here.
- local function registerProxy(sName, proxy, conf, raw)
- Proxies[sName] = proxy
- ProxyNames[proxy] = sName
- ProxyConf[proxy] = conf
- ProxyRaw[proxy] = raw
- end -- /Proxy management
- -- File functions
- local function validateDirectory(sDir)
- if not fs.exists(sDir) then
- return fs.makeDir(sDir)
- end
- end
- local function resolveFile(sName)
- return BaseDirectory .. "/" .. sName
- end
- local function dumpFile(sFile)
- local handle = fs.open(sFile, "r")
- local sData = handle.readAll()
- handle.close()
- return sData
- end
- local function createFile(sFile)
- local handle = fs.open(sFile, "w")
- handle.write(FileTemplate)
- handle.close()
- end
- local function loadRaw(conf)
- local sData = dumpFile(conf.File)
- return loadstring(sData)(conf.raw)
- end
- local writeModes = {}
- function writeModes.none() end -- Empty function for ignoring
- local function dsFlush(conf)
- local sData = genWhole(conf.raw)
- local handle = fs.open(conf.File, "w")
- handle.write(sData)
- handle.close()
- end
- local function wmAppend(conf, k, v)
- local handle = fs.open(conf.File, "a")
- handle.writeLine(genLine(k, v))
- handle.close()
- end
- writeModes.append = wmAppend
- function writeModes.hybrid(conf, k, v)
- local n = conf.CurrentHybridN
- if n >= conf.HybridN then
- conf.CurrentHybridN = 0
- dsFlush(conf)
- return
- end
- conf.CurrentHybridN = n + 1
- return wmAppend(conf, k, v)
- end
- -- dsObject functions
- local function dsNewIndex(self, k, v)
- local conf, raw = ProxyConf[self], ProxyRaw[self]
- -- Some type checking
- if not validTypes[type(k)] or not validTypes[type(v)] then
- error("Attempting to put invalid type in vault table", 2)
- end
- if raw[k] == v then
- -- Avoid some needless writing
- return
- end
- raw[k] = v
- return writeModes[conf.Mode](conf, k, v)
- end
- local function cloneConfig(sFile, raw, proxy)
- return {Mode = DefaultMode, HybridN = DefaultHybridN, CurrentHybridN = 0, File = sFile, raw = raw, proxy = proxy}
- end
- local function newdsObject(sName, sFile)
- if not sFile then
- sFile = resolveFile(sName)
- end
- local raw = {}
- local proxy = {}
- local conf = cloneConfig(sFile, raw, proxy)
- registerProxy(sName, proxy, conf, raw)
- -- Load data or create a new file if it doesn't exist
- if fs.exists(conf.File) then
- loadRaw(conf)
- else
- createFile(conf.File)
- end
- setmetatable(proxy, {__index = raw, __newindex = dsNewIndex})
- return proxy
- end
- function open(sName)
- if Proxies[sName] then
- return Proxies[sName]
- end
- return newdsObject(sName)
- end
- --- The name the handle will be referenced by
- -- @param sName
- -- @param sFile The specific file name to open
- --
- function openFile(sName, sFile)
- if Proxies[sName] then
- if ProxyConf[Proxies[sName]].File == sFile then
- return Proxies[sName]
- end
- return false, "name taken"
- end
- return newdsObject(sName, sFile)
- end
- function setMode(dsObj, sMode)
- if not writeModes[sMode] then
- error("vault.setMode(): Invalid mode")
- end
- ProxyConf[dsObj].Mode = sMode
- end
- function getRaw(dsObj)
- return ProxyRaw[dsObj]
- end
- function setDir(sDirectory)
- validateDirectory(sDirectory)
- BaseDirectory = sDirectory
- end
- function setHybridN(dsObj, n)
- local conf = ProxyConf[dsObj]
- conf.HybridN = n
- end
- function getDir()
- return BaseDirectory
- end
- function getFile(dsObj)
- return ProxyConf[dsObj].File
- end
- function flush(dsObj)
- local conf = ProxyConf[dsObj]
- conf.CurrentHybridN = 0
- dsFlush(conf)
- end
- function reload(dsObj)
- local conf = ProxyConf[dsObj]
- local raw = conf.raw
- local temp = {}
- for k, v in pairs(raw) do
- temp[k] = true
- end
- for k, v in pairs(temp) do
- raw[k] = nil
- end
- loadRaw(conf)
- end
Advertisement
Add Comment
Please, Sign In to add comment