A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 167 lines 5.2 kB view raw
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 24rb.settings = rb.settings or {} 25 26local var = {offset = 1, size = 2, type = 3, fields = 3} 27 28local 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 37end 38 39local 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 47end 48 49local 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 73end 74 75local 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 103end 104 105local 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 109end 110 111local 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]+)") 114end 115 116function 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 152end 153 154function rb.settings.dump(s_settings, s_groupname, s_structname, t_output, fn_filter) 155 t_output = t_output or {} 156 fn_filter = fn_filter or function(s,k) return true end 157 local tgroup = rb[s_groupname] 158 s_structname = s_structname or s_settings 159 for k, v in pairs(tgroup[s_structname]) do 160 if fn_filter(s_structname, k) then 161 t_output[k] = rb.settings.read(s_settings, v, s_groupname) 162 end 163 end 164 return t_output 165end 166 167return true