Skip to content

Instantly share code, notes, and snippets.

@Vavius
Created September 4, 2014 14:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Vavius/b3144801f768b0c4ff90 to your computer and use it in GitHub Desktop.
Save Vavius/b3144801f768b0c4ff90 to your computer and use it in GitHub Desktop.
--------------------------------------------------------------------------------
-- JsonStorageEngine.lua
--
-- Store lua tables as json documents
--------------------------------------------------------------------------------
local JsonStorageEngine = {}
JsonStorageEngine.DOCUMENTS_DIR = MOAIEnvironment.documentDirectory or 'docs'
JsonStorageEngine.md5 = 'md5'
JsonStorageEngine.sha1 = 'sha1'
JsonStorageEngine.sha256 = 'sha256'
JsonStorageEngine.sha512 = 'sha512'
local hashFuncNames = {
['md5'] = 'openMD5',
['sha1'] = 'openSHA1',
['sha256'] = 'openSHA256',
['sha512'] = 'openSHA512',
}
local function getHash(str, algorythm)
local hashWriter = MOAIHashWriter.new()
local func = hashFuncNames[algorythm]
assert(func, "Unknow hash algorythm: " .. algorythm)
hashWriter[func](hashWriter)
hashWriter:write(str)
return hashWriter:getHashHex()
end
local digestLengths = {
['md5'] = #getHash('hello', JsonStorageEngine.md5),
['sha1'] = #getHash('hello', JsonStorageEngine.sha1),
['sha256'] = #getHash('hello', JsonStorageEngine.sha256),
['sha512'] = #getHash('hello', JsonStorageEngine.sha512),
}
---
-- Retrieve table from storage
-- @param name storage name. Table is parsed form json file: <documents_directory>/[name].json
-- @param secret (optional) string. If set, then hash protection will be applied using secret
-- @param algorythm hashing algorythm. Default is 'sha256'
-- @return table, valid returns loaded table (or nil if error occurs)
-- valid is a boolean flag indicating if hash check succeeded
function JsonStorageEngine.load(name, secret, algorythm)
algorythm = algorythm or JsonStorageEngine.sha256
local path = string.pathJoin(JsonStorageEngine.DOCUMENTS_DIR, name)
if secret then
return JsonStorageEngine.parseFileSecure(path, secret, algorythm)
else
return JsonStorageEngine.parseFile(path)
end
end
---
-- Save table to json file
-- @param t table to save
-- @param name name of output file
-- @param secret (optional) string for hash protection of contents
-- @return success bool
function JsonStorageEngine.save(t, name, secret, algorythm)
algorythm = algorythm or JsonStorageEngine.sha256
local path = string.pathJoin(JsonStorageEngine.DOCUMENTS_DIR, name)
if secret then
return JsonStorageEngine.dumpFileSecure(t, path, secret, algorythm)
else
return JsonStorageEngine.dumpFile(t, path)
end
end
---
-- some internalls
function JsonStorageEngine.parseFile(path)
local dataBuffer = MOAIDataBuffer.new()
local output
if dataBuffer:load(path) then
output = MOAIJsonParser.decode(dataBuffer:getString())
end
return output
end
function JsonStorageEngine.parseFileSecure(path, secret, algorythm)
local dataBuffer = MOAIDataBuffer.new()
local valid, output
if dataBuffer:load(path) then
local all = dataBuffer:getString()
local hash = string.sub(all, 1, digestLengths[algorythm])
local payload = string.sub(all, 1 + digestLengths[algorythm])
valid = (hash == getHash(payload .. secret, algorythm))
output = MOAIDataBuffer.inflate(payload)
if output then
output = MOAIJsonParser.decode(output)
end
end
return output, valid
end
function JsonStorageEngine.dumpFile(t, path)
local success = false
local json = MOAIJsonParser.encode(t)
if json then
local dataBuffer = MOAIDataBuffer.new()
dataBuffer:setString(json)
success = dataBuffer:save(path)
end
return success
end
function JsonStorageEngine.dumpFileSecure(t, path, secret, algorythm)
local success = false
local json = MOAIJsonParser.encode(t)
if json then
local payload = MOAIDataBuffer.deflate(json)
if payload then
local dataBuffer = MOAIDataBuffer.new()
local hash = getHash(payload .. secret, algorythm)
dataBuffer:setString(hash .. payload)
success = dataBuffer:save(path)
end
end
return success
end
return JsonStorageEngine
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment