+--- Checks whether the given table contains the given value.
+-- @param table Table value
+-- @param value Value to search within the given table
+-- @return Boolean indicating whether the given value occurs within table
+function contains(table, value)
+ for k, v in pairs(table) do
+ if value == v then
+ return k
+ end
+ end
+ return false
+end
+
+--- Update values in given table with the values from the second given table.
+-- Both table are - in fact - merged together.
+-- @param t Table which should be updated
+-- @param updates Table containing the values to update
+-- @return Always nil
+function update(t, updates)
+ for k, v in pairs(updates) do
+ t[k] = v
+ end
+end
+
+--- Clones the given object and return it's copy.
+-- @param object Table value to clone
+-- @param deep Boolean indicating whether to do recursive cloning
+-- @return Cloned table value
+function clone(object, deep)
+ local copy = {}
+
+ for k, v in pairs(object) do
+ if deep and type(v) == "table" then
+ v = clone(v, deep)
+ end
+ copy[k] = v
+ end
+
+ setmetatable(copy, getmetatable(object))
+
+ return copy
+end
+
+
+--- Create a dynamic table which automatically creates subtables.
+-- @return Dynamic Table
+function dtable()
+ return setmetatable({}, { __index =
+ function(tbl, key)
+ return rawget(tbl, key)
+ or rawget(rawset(tbl, key, dtable()), key)
+ end
+ })
+end
+
+
+-- Serialize the contents of a table value.
+function _serialize_table(t)
+ local data = ""
+ for k, v in pairs(t) do
+ k = serialize_data(k)
+ v = serialize_data(v)
+ data = data .. ( #data > 0 and ", " or "" ) ..
+ '[' .. k .. '] = ' .. v
+ end
+ return data
+end
+
+--- Recursively serialize given data to lua code, suitable for restoring
+-- with loadstring().
+-- @param val Value containing the data to serialize
+-- @return String value containing the serialized code
+-- @see restore_data
+-- @see get_bytecode
+function serialize_data(val)
+ if val == nil then
+ return "nil"
+ elseif type(val) == "number" then
+ return val
+ elseif type(val) == "string" then
+ return string.format("%q", val)
+ elseif type(val) == "boolean" then
+ return val and "true" or "false"
+ elseif type(val) == "function" then
+ return string.format("loadstring(%q)", get_bytecode(val))
+ elseif type(val) == "table" then
+ return "{ " .. _serialize_table(val) .. " }"
+ else
+ return '"[unhandled data type:' .. type(val) .. ']"'
+ end
+end
+
+--- Restore data previously serialized with serialize_data().
+-- @param str String containing the data to restore
+-- @return Value containing the restored data structure
+-- @see serialize_data
+-- @see get_bytecode
+function restore_data(str)
+ return loadstring("return " .. str)()
+end
+
+
+--
+-- Byte code manipulation routines
+--
+
+--- Return the current runtime bytecode of the given data. The byte code
+-- will be stripped before it is returned.
+-- @param val Value to return as bytecode
+-- @return String value containing the bytecode of the given data
+function get_bytecode(val)
+ local code
+
+ if type(val) == "function" then
+ code = string.dump(val)
+ else
+ code = string.dump( loadstring( "return " .. serialize_data(val) ) )
+ end
+
+ return code and strip_bytecode(code)
+end
+
+--- Strips unnescessary lua bytecode from given string. Information like line
+-- numbers and debugging numbers will be discarded. Original version by
+-- Peter Cawley (http://lua-users.org/lists/lua-l/2008-02/msg01158.html)
+-- @param code String value containing the original lua byte code
+-- @return String value containing the stripped lua byte code
+function strip_bytecode(code)
+ local version, format, endian, int, size, ins, num, lnum = code:byte(5, 12)