Skip to content

Commit

Permalink
Added Utils.readStorageJSON and relaxed JSON parser
Browse files Browse the repository at this point in the history
  • Loading branch information
gfwilliams committed Nov 23, 2023
1 parent 4422e4a commit c97b785
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 9 deletions.
8 changes: 8 additions & 0 deletions js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,14 @@ function iframeSetup(options) {
id : msg.id
});
});
} else if (msg.type=="readstoragejson") {
Comms.readFile(msg.filename).then(function(result) {
iframe.contentWindow.postMessage({
type : "readstoragejsonrsp",
data : Utils.parseRJSON(result),
id : msg.id
});
});
} else if (msg.type=="writestorage") {
Progress.show({title:`Uploading ${JSON.stringify(msg.filename)}`,sticky:true});
Comms.writeFile(msg.filename, msg.data).then(function() {
Expand Down
73 changes: 72 additions & 1 deletion js/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,76 @@ function atobSafe(input) {
return output;
}


// parse relaxed JSON which Espruino's writeJSON uses for settings/etc (returns undefined on failure)
function parseRJSON(str) {
let lex = Espruino.Core.Utils.getLexer(str);
let tok = lex.next();
function match(s) {
if (tok.str!=s) throw new Error("Expecting "+s+" got "+JSON.stringify(tok.str));
tok = lex.next();
}

function recurse() {
let final = "";
while (tok!==undefined) {
if (tok.type == "NUMBER") {
let v = parseFloat(tok.str);
tok = lex.next();
return v;
}
if (tok.str == "-") {
tok = lex.next();
let v = -parseFloat(tok.str);
tok = lex.next();
return v;
}
if (tok.type == "STRING") {
let v = tok.value;
tok = lex.next();
return v;
}
if (tok.type == "ID") switch (tok.str) {
case "true" : tok = lex.next(); return true;
case "false" : tok = lex.next(); return false;
case "null" : tok = lex.next(); return null;
}
if (tok.str == "[") {
tok = lex.next();
let arr = [];
while (tok.str != ']') {
arr.push(recurse());
if (tok.str != ']') match(",");
}
match("]");
return arr;
}
if (tok.str == "{") {
tok = lex.next();
let obj = {};
while (tok.str != '}') {
let key = tok.type=="STRING" ? tok.value : tok.str;
tok = lex.next();
match(":");
obj[key] = recurse();
if (tok.str != '}') match(",");
}
match("}");
return obj;
}
match("EOF");
}
}

let json = undefined;
try {
json = recurse();
} catch (e) {
console.log("RJSON parse error", e);
}
return json;
}

var Utils = {
Const : Const,
DEVICEINFO : DEVICEINFO,
Expand All @@ -409,7 +479,8 @@ var Utils = {
isAppUpdateable : isAppUpdateable,
versionLess : versionLess,
debounce : debounce,
atobSafe : atobSafe
atobSafe : atobSafe, // version of 'window.atob' that doesn't fail on 'not correctly encoded' strings
parseRJSON : parseRJSON // parse relaxed JSON which Espruino's writeJSON uses for settings/etc (returns undefined on failure)
};

if ("undefined"!=typeof module)
Expand Down
21 changes: 17 additions & 4 deletions lib/customize.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,17 @@ Puck.eval(data,callback)
There is also:
Util.readStorageFile(filename,callback)
Util.eraseStorageFile(filename,callback)
Util.showModal(title)
Util.hideModal()
Util.close() // close this window
Util.readStorage(filename,callback) // read a file from the Bangle, callback with string
Util.readStorageJSON(filename,callback) // read a file from the Bangle and parse JSON, callback with parsed object
Util.writeStorage(filename,data, callback) // write a file to the Bangle, callback when done
Util.eraseStorage(filename,callback) // erase a file on the Bangle
Util.readStorageFile(filename,callback) // read a StorageFile (not just a normal file)
Util.eraseStorageFile(filename,callback) // erase a StorageFile
saveFile(filename, mimeType, dataAsString) // pop up a dialog to save a file (needs it a mimeType like "application/json")
Util.saveCSV(filename, csvData) // pop up a dialog to save a CSV file of data
Util.showModal(title) // show a modal screen over everything in this window
Util.hideModal() // hide the modal from showModal
*/
function sendCustomizedApp(app) {
console.log("<CUSTOM> sending app");
Expand Down Expand Up @@ -99,6 +106,11 @@ const Util = {
__idlookup[__id] = callback;
window.postMessage({type:"readstorage",filename:filename,id:__id});
},
readStorageJSON : function(filename,callback) {
__id++;
__idlookup[__id] = callback;
window.postMessage({type:"readstoragejson",filename:filename,id:__id});
},
writeStorage : function(filename,data,callback) {
__id++;
__idlookup[__id] = callback;
Expand Down Expand Up @@ -167,6 +179,7 @@ window.addEventListener("message", function(event) {
msg.type=="writersp" ||
msg.type=="readstoragefilersp" ||
msg.type=="readstoragersp" ||
msg.type=="readstoragejsonrsp" ||
msg.type=="writestoragersp") {
let cb = __idlookup[msg.id];
delete __idlookup[msg.id];
Expand Down
21 changes: 17 additions & 4 deletions lib/interface.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,17 @@ Puck.eval(data,callback)
There is also:
Util.readStorageFile(filename,callback)
Util.eraseStorageFile(filename,callback)
Util.showModal(title)
Util.hideModal()
Util.close() // close this window
Util.readStorage(filename,callback) // read a file from the Bangle, callback with string
Util.readStorageJSON(filename,callback) // read a file from the Bangle and parse JSON, callback with parsed object
Util.writeStorage(filename,data, callback) // write a file to the Bangle, callback when done
Util.eraseStorage(filename,callback) // erase a file on the Bangle
Util.readStorageFile(filename,callback) // read a StorageFile (not just a normal file)
Util.eraseStorageFile(filename,callback) // erase a StorageFile
saveFile(filename, mimeType, dataAsString) // pop up a dialog to save a file (needs it a mimeType like "application/json")
Util.saveCSV(filename, csvData) // pop up a dialog to save a CSV file of data
Util.showModal(title) // show a modal screen over everything in this window
Util.hideModal() // hide the modal from showModal
*/
let __id = 0, __idlookup = [];
const Puck = {
Expand Down Expand Up @@ -76,6 +83,11 @@ const Util = {
__idlookup[__id] = callback;
window.postMessage({type:"readstorage",filename:filename,id:__id});
},
readStorageJSON : function(filename,callback) {
__id++;
__idlookup[__id] = callback;
window.postMessage({type:"readstoragejson",filename:filename,id:__id});
},
writeStorage : function(filename,data,callback) {
__id++;
__idlookup[__id] = callback;
Expand Down Expand Up @@ -144,6 +156,7 @@ window.addEventListener("message", function(event) {
msg.type=="writersp" ||
msg.type=="readstoragefilersp" ||
msg.type=="readstoragersp" ||
msg.type=="readstoragejsonrsp" ||
msg.type=="writestoragersp") {
let cb = __idlookup[msg.id];
delete __idlookup[msg.id];
Expand Down

0 comments on commit c97b785

Please sign in to comment.