diff options
author | William Wilgus <me.theuser@yahoo.com> | 2019-09-06 19:24:26 -0500 |
---|---|---|
committer | William Wilgus <me.theuser@yahoo.com> | 2019-09-07 03:10:59 +0200 |
commit | 267d04d2bd2a7681c8bbcfbb655612101440b765 (patch) | |
tree | a518b4c10244cc77a5eee636132031c5a542c00a /apps/plugins/lua/include_lua | |
parent | a3cbd86a5193e5227344db360f45f114fda10aab (diff) | |
download | rockbox-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.lua | 164 |
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 @@ | |||
1 | --[[ Lua rb settings reader | ||
2 | /*************************************************************************** | ||
3 | * __________ __ ___. | ||
4 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
5 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
6 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
7 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
8 | * \/ \/ \/ \/ \/ | ||
9 | * $Id$ | ||
10 | * | ||
11 | * Copyright (C) 2019 William Wilgus | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; either version 2 | ||
16 | * of the License, or (at your option) any later version. | ||
17 | * | ||
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
19 | * KIND, either express or implied. | ||
20 | * | ||
21 | ****************************************************************************/ | ||
22 | ]] | ||
23 | |||
24 | rb.settings = rb.settings or {} | ||
25 | |||
26 | local var = {offset = 1, size = 2, type = 3, fields = 3} | ||
27 | |||
28 | local function bytesLE_n(str) | ||
29 | str = str or "" | ||
30 | local tbyte={str:byte(1, -1)} | ||
31 | local bpos, num = 1, 0 | ||
32 | for k = 1,#tbyte do -- (k = #t, 1, -1 for BE) | ||
33 | num = num + tbyte[k] * bpos | ||
34 | bpos = bpos * 256 --1<<8 | ||
35 | end | ||
36 | return num | ||
37 | end | ||
38 | |||
39 | local function get_var_fields(s_var) | ||
40 | -- converts member string into table | ||
41 | -- var = {offset, size, "type"} | ||
42 | s_var = s_var or "" | ||
43 | local o, s, t = string.match(s_var, "(0x%x+),%s*(%d+),%s*(.+)") | ||
44 | local tvar = {o, s, t} | ||
45 | |||
46 | return #tvar == var.fields and tvar or nil | ||
47 | end | ||
48 | |||
49 | local function format_val(val, var_type) | ||
50 | local ret, num | ||
51 | if var_type == nil then | ||
52 | return nil | ||
53 | elseif var_type == "str" then | ||
54 | -- stop at first null byte, return nil if str doesn't exist | ||
55 | return val and string.match(val, "^%Z+") or nil | ||
56 | end | ||
57 | |||
58 | num = bytesLE_n(val) | ||
59 | if string.find(var_type, "^b") then | ||
60 | if(num <= 0) then | ||
61 | ret = false | ||
62 | else | ||
63 | ret = true | ||
64 | end | ||
65 | elseif string.find(var_type, "^u_[cil]") then | ||
66 | -- Lua integers are signed so we need to do a bit of extra processing | ||
67 | ret = (string.format("%u", num)) | ||
68 | else | ||
69 | ret = num | ||
70 | end | ||
71 | |||
72 | return ret | ||
73 | end | ||
74 | |||
75 | local function dump_struct(t_settings, t_struct, n_elems, t_var) | ||
76 | --Internal function dumps structs | ||
77 | local tdata = {} | ||
78 | |||
79 | local function struct_get_elem(v, elem_offset) | ||
80 | local val, offset, tvar1 | ||
81 | tvar1 = get_var_fields(v) | ||
82 | offset = t_var[var.offset] + tvar1[var.offset] + elem_offset | ||
83 | val = t_settings(offset, tvar1[var.size]) | ||
84 | return format_val(val, tvar1[var.type]) | ||
85 | end | ||
86 | |||
87 | if n_elems > 0 then | ||
88 | -- Array of structs, struct[elems]; | ||
89 | local elemsize = (t_var[var.size] / n_elems) | ||
90 | for i = 0, n_elems - 1 do | ||
91 | tdata[i] = tdata[i] or {} | ||
92 | for k1, v1 in pairs(t_struct) do | ||
93 | tdata[i][k1] = struct_get_elem(v1, (elemsize * i)) | ||
94 | end | ||
95 | end | ||
96 | else | ||
97 | -- single struct, struct; | ||
98 | for k1, v1 in pairs(t_struct) do | ||
99 | tdata[k1] = struct_get_elem(v1, 0) | ||
100 | end | ||
101 | end | ||
102 | return tdata | ||
103 | end | ||
104 | |||
105 | local function get_array_elems(var_type) | ||
106 | --extract the number of elements, returns 0 if not found | ||
107 | local elems = string.match(var_type,".*%[(%d+)%]") | ||
108 | return tonumber(elems) or 0 | ||
109 | end | ||
110 | |||
111 | local function get_struct_name(var_type) | ||
112 | --extract the name of a struct, returns nil if not found | ||
113 | return string.match(var_type,"^s_([^%[%]%s]+)") | ||
114 | end | ||
115 | |||
116 | function rb.settings.read(s_settings, s_var, s_groupname) | ||
117 | local data, val | ||
118 | local tvar = get_var_fields(s_var) | ||
119 | if tvar == nil then return nil end | ||
120 | |||
121 | local elems = get_array_elems(tvar[var.type]) | ||
122 | local structname = get_struct_name(tvar[var.type]) | ||
123 | |||
124 | local tsettings = rb[s_settings] | ||
125 | if not tsettings then error(s_settings .. " does not exist") end | ||
126 | |||
127 | if structname and rb[s_groupname] then | ||
128 | return dump_struct(tsettings, rb[s_groupname][structname], elems, tvar) | ||
129 | end | ||
130 | |||
131 | local voffset, vsize, vtype = tvar[var.offset], tvar[var.size], tvar[var.type] | ||
132 | if elems > 0 then | ||
133 | -- Arrays of values, val[elems]; | ||
134 | data = {} | ||
135 | local elemsize = (vsize / elems) | ||
136 | |||
137 | for i = 0, elems - 1 do | ||
138 | val = tsettings(voffset + (elemsize * i), elemsize) | ||
139 | data[i] = format_val(val, vtype) | ||
140 | end | ||
141 | else | ||
142 | -- Single value, val; | ||
143 | if vtype == "ptr_char" then -- (**char) | ||
144 | vtype = "str" | ||
145 | val = tsettings(voffset, vsize, nil, true) | ||
146 | else | ||
147 | val = tsettings(voffset, vsize) | ||
148 | end | ||
149 | data = format_val(val, vtype) | ||
150 | end | ||
151 | return data | ||
152 | end | ||
153 | |||
154 | function rb.settings.dump(s_settings, s_groupname, s_structname, t_output) | ||
155 | t_output = t_output or {} | ||
156 | local tgroup = rb[s_groupname] | ||
157 | s_structname = s_structname or s_settings | ||
158 | for k, v in pairs(tgroup[s_structname]) do | ||
159 | t_output[k] = rb.settings.read(s_settings, v, s_groupname) | ||
160 | end | ||
161 | return t_output | ||
162 | end | ||
163 | |||
164 | return true | ||