summaryrefslogtreecommitdiffstats
path: root/apps/plugins/lua/include_lua
diff options
context:
space:
mode:
authorWilliam Wilgus <me.theuser@yahoo.com>2019-09-06 19:24:26 -0500
committerWilliam Wilgus <me.theuser@yahoo.com>2019-09-07 03:10:59 +0200
commit267d04d2bd2a7681c8bbcfbb655612101440b765 (patch)
treea518b4c10244cc77a5eee636132031c5a542c00a /apps/plugins/lua/include_lua
parenta3cbd86a5193e5227344db360f45f114fda10aab (diff)
downloadrockbox-267d04d2bd2a7681c8bbcfbb655612101440b765.tar.gz
rockbox-267d04d2bd2a7681c8bbcfbb655612101440b765.zip
Lua add metadata and settings reading helper module
Adds example scripts for reading track metadata + dumping albumart and rockbox settings settings are now stored as a table of strings rather than a table of tables as it saves ~15 kb of ram without adding much complexity Change-Id: I611c312b2a60ab96e595e4710b17aedbd6c0689b
Diffstat (limited to 'apps/plugins/lua/include_lua')
-rw-r--r--apps/plugins/lua/include_lua/rbsettings.lua164
1 files changed, 164 insertions, 0 deletions
diff --git a/apps/plugins/lua/include_lua/rbsettings.lua b/apps/plugins/lua/include_lua/rbsettings.lua
new file mode 100644
index 0000000000..defdb11b77
--- /dev/null
+++ b/apps/plugins/lua/include_lua/rbsettings.lua
@@ -0,0 +1,164 @@
+--[[ Lua rb settings reader
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2019 William Wilgus
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+]]
+
+rb.settings = rb.settings or {}
+
+local var = {offset = 1, size = 2, type = 3, fields = 3}
+
+local function bytesLE_n(str)
+ str = str or ""
+ local tbyte={str:byte(1, -1)}
+ local bpos, num = 1, 0
+ for k = 1,#tbyte do -- (k = #t, 1, -1 for BE)
+ num = num + tbyte[k] * bpos
+ bpos = bpos * 256 --1<<8
+ end
+ return num
+end
+
+local function get_var_fields(s_var)
+ -- converts member string into table
+ -- var = {offset, size, "type"}
+ s_var = s_var or ""
+ local o, s, t = string.match(s_var, "(0x%x+),%s*(%d+),%s*(.+)")
+ local tvar = {o, s, t}
+
+ return #tvar == var.fields and tvar or nil
+end
+
+local function format_val(val, var_type)
+ local ret, num
+ if var_type == nil then
+ return nil
+ elseif var_type == "str" then
+ -- stop at first null byte, return nil if str doesn't exist
+ return val and string.match(val, "^%Z+") or nil
+ end
+
+ num = bytesLE_n(val)
+ if string.find(var_type, "^b") then
+ if(num <= 0) then
+ ret = false
+ else
+ ret = true
+ end
+ elseif string.find(var_type, "^u_[cil]") then
+ -- Lua integers are signed so we need to do a bit of extra processing
+ ret = (string.format("%u", num))
+ else
+ ret = num
+ end
+
+ return ret
+end
+
+local function dump_struct(t_settings, t_struct, n_elems, t_var)
+ --Internal function dumps structs
+ local tdata = {}
+
+ local function struct_get_elem(v, elem_offset)
+ local val, offset, tvar1
+ tvar1 = get_var_fields(v)
+ offset = t_var[var.offset] + tvar1[var.offset] + elem_offset
+ val = t_settings(offset, tvar1[var.size])
+ return format_val(val, tvar1[var.type])
+ end
+
+ if n_elems > 0 then
+ -- Array of structs, struct[elems];
+ local elemsize = (t_var[var.size] / n_elems)
+ for i = 0, n_elems - 1 do
+ tdata[i] = tdata[i] or {}
+ for k1, v1 in pairs(t_struct) do
+ tdata[i][k1] = struct_get_elem(v1, (elemsize * i))
+ end
+ end
+ else
+ -- single struct, struct;
+ for k1, v1 in pairs(t_struct) do
+ tdata[k1] = struct_get_elem(v1, 0)
+ end
+ end
+ return tdata
+end
+
+local function get_array_elems(var_type)
+ --extract the number of elements, returns 0 if not found
+ local elems = string.match(var_type,".*%[(%d+)%]")
+ return tonumber(elems) or 0
+end
+
+local function get_struct_name(var_type)
+ --extract the name of a struct, returns nil if not found
+ return string.match(var_type,"^s_([^%[%]%s]+)")
+end
+
+function rb.settings.read(s_settings, s_var, s_groupname)
+ local data, val
+ local tvar = get_var_fields(s_var)
+ if tvar == nil then return nil end
+
+ local elems = get_array_elems(tvar[var.type])
+ local structname = get_struct_name(tvar[var.type])
+
+ local tsettings = rb[s_settings]
+ if not tsettings then error(s_settings .. " does not exist") end
+
+ if structname and rb[s_groupname] then
+ return dump_struct(tsettings, rb[s_groupname][structname], elems, tvar)
+ end
+
+ local voffset, vsize, vtype = tvar[var.offset], tvar[var.size], tvar[var.type]
+ if elems > 0 then
+ -- Arrays of values, val[elems];
+ data = {}
+ local elemsize = (vsize / elems)
+
+ for i = 0, elems - 1 do
+ val = tsettings(voffset + (elemsize * i), elemsize)
+ data[i] = format_val(val, vtype)
+ end
+ else
+ -- Single value, val;
+ if vtype == "ptr_char" then -- (**char)
+ vtype = "str"
+ val = tsettings(voffset, vsize, nil, true)
+ else
+ val = tsettings(voffset, vsize)
+ end
+ data = format_val(val, vtype)
+ end
+ return data
+end
+
+function rb.settings.dump(s_settings, s_groupname, s_structname, t_output)
+ t_output = t_output or {}
+ local tgroup = rb[s_groupname]
+ s_structname = s_structname or s_settings
+ for k, v in pairs(tgroup[s_structname]) do
+ t_output[k] = rb.settings.read(s_settings, v, s_groupname)
+ end
+ return t_output
+end
+
+return true