JSON parser ?

May 4, 2009 at 11:11am

JSON parser ?

Is there somebody out there who worked on a JSON parser in Javascript ? I don’t fully understand things on json.org, so maybe someone already got examples on how to implement JSON in Javascript for Max ?

How to use it ? What to do with the json2.js ? the json_parse.js ?

How to load a .maxpat into a JSON Object ?

best wishes

f.e

#43660
May 5, 2009 at 6:10am

I haven’t tried but it looks like you should be able to copy the contents of json_parse.js (http://www.json.org/json_parse.js) into the top of your max js file (since Max js does not have an include file function), and then somewhere after that code you call:

var myObject = json_parse(myJsonText);

You may also want to try this one: http://code.google.com/p/json-sans-eval/source/browse/trunk/src/json_sans_eval.js which claims to be faster, see http://code.google.com/p/json-sans-eval/
That one looks like you call

var myObject = jsonParse(myJsonText);

If you don’t care about security, you can just do:

var myObject = eval('(' + myJSONtext + ')');

But since Max js can do file I/O, there is a very real security risk here: if you load in untrusted JSON someone could potentially wipe your hard drive or install malware (probably unlikely though?). In any case, it’s for this reason I would not use json2.js either, it falls back to eval() in some cases so there’s probably a security hole there.

#156695
May 5, 2009 at 7:19am

Thanks a lot Adam. I was precisely wondering about the includes in a js. Now i got my answer. I’ll try with the sans_eval, then.

best wishes

f.e

#156696
Nov 28, 2009 at 1:33am

I’m struggling with something similar currently. Did you get this up and running smoothly with any of the parsing methods?

lh

#156697
Nov 28, 2009 at 8:07pm

i am using this code without any problem.

http://www.json.org/json2.js

#156698
Nov 29, 2009 at 4:34pm

Ah, it seems my problem is with importing files to read. I’ve tried a few things: chopping the whitespace, escaping quotes etc. If I parse the text then output it to a message and send it back in it works fine, but not if I do all from within the code. The json2 code is throwing the final error indicating the input is malformed but I’m not sure where along the line this is happening. Is there anything I should look out for when reading a JSON file into my [js] line by line then JSON.parse()-ing it?

lh

#156699
Nov 29, 2009 at 6:13pm

i also use the JSON format to store data into a textfile and read
it afterwards.

my datastructures are moredimensional arraays containing
ints, floats and strings.

i am using the js method: readFile()

the problem with this method is, that you get problems,
if there are more than 2000 chars inside your file.

but you can read it in chunk parts.
only tested in max 4.6.3.
perhaps this is fixed in max5 …

short example:

whichFilePath is the file you want to read.

theFlag = fileExists( whichFilePath );

if ( theFlag == 0 ){
return “”
}

f = new File( whichFilePath, “readwrite”, []);
f.open( whichFilePath );

theMaxChars = 1800;
theDivisions = f.eof / theMaxChars;

f.position = 0;
theContent = “”;
for ( var i=0; i

theNewStringContent = f.readstring( theMaxChars );
theContent = theContent + theNewStringContent;
f.position = theMaxChars * (i+1);
}
f.close()
return theContent

#156700
Dec 1, 2009 at 4:01pm

Here is some code I wrote for the same purpose some months ago (reading and writing .json setup files from disc).

At the bottom is a minified version of the json2 parser.

/**
* Loads the setup file and initializes the setup object.
*/
function loadSetup() {

/*
* Look for a setup file in the same folder as the patch.
*/
var folder = new Folder(stripFileName(patcher.filepath));
var endings = SETUP_FILE_ENDINGS;

var setupFile = new File();

for ( ;!folder.end; folder.next() ) {
for (i in endings) {

/*
* Match files in folders with the given name and endings.
*/
var name = SETUP_FILE_NAME + "." + endings[i];
if (folder.filename == name) {

var fullName = folder.pathname + DIRECTORY_SEPARATOR + name;

/*
* Found, open file.
*/
setupFile = new File(fullName);
loadedSetupFile = name;

// setupFile.byteorder = SETUP_BYTEORDER;
setupFile.linebreak = SETUP_LINEBREAK_STYLE;
}
}
}

if (!setupFile.isopen) {
throw "Could not read setupFile file.";
}

/*
* Init a string buffer for the contents of the file.
*/
var setupBuf = "";

/*
* Read file in chunks.
*/
while (setupFile.position < setupFile.eof) {
var setupBuf = setupBuf + setupFile.readline(256) + LINE_BREAK;
}

/*
* Prepare code for parsing.
*/
setupBuf = (removeComments(setupBuf));
setupBuf = (compressWhiteSpace(setupBuf));

/*
* Run in standard JSON parser.
*/
setup = JSON.parse(setupBuf, null);
}

/**
* Removes JavaScript comments from a string.
*/
function removeComments(s) {

var lines, i, t;

/*
* Remove '//' comments from each line.
*/
lines = s.split("n");
t = "";
for (i = 0; i < lines.length; i++)
t += lines[i].replace(/([^x2f]*)x2fx2f.*$/, "$1");

/*
* Replace newline characters with spaces.
*/
t = t.replace(/(.*)n(.*)/g, "$1 $2");

/*
* Remove C-style comments.
*/
lines = t.split("*/");
t = "";
for (i = 0; i < lines.length; i++)
t += lines[i].replace(/(.*)x2fx2a(.*)$/g, "$1 ");

return t;
}

/**
* Removes whitespace from a string.
*/
function compressWhiteSpace(s) {

/*
* Condense white space.
*/
s = s.replace(/s+/g, " ");
s = s.replace(/^s(.*)/, "$1");
s = s.replace(/(.*)s$/, "$1");

/*
* Remove uneccessary white space around operators, braces and parentices.
*/
s = s.replace(/s([x21x25x26x28x29x2ax2bx2cx2dx2fx3ax3bx3cx3dx3ex3fx5bx5dx5cx7bx7cx7dx7e])/g, "$1");
s = s.replace(/([x21x25x26x28x29x2ax2bx2cx2dx2fx3ax3bx3cx3dx3ex3fx5bx5dx5cx7bx7cx7dx7e])s/g, "$1");
return s;
}

/*
* JSON parser
* From http://json.org/json2.js
*/

/*
* Note: mind js semicolon insertion. Do NOT edit line breaks.
*/
if(!this.JSON){JSON={};}
(function(){function f(n){return n<10?'0'+n:n;}
if(typeof Date.prototype.toJSON!=='function'){Date.prototype.toJSON=function(key){return this.getUTCFullYear()+'-'+
f(this.getUTCMonth()+1)+'-'+
f(this.getUTCDate())+'T'+
f(this.getUTCHours())+':'+
f(this.getUTCMinutes())+':'+
f(this.getUTCSeconds())+'Z';};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(key){return this.valueOf();};}
var cx=/[u0000u00adu0600-u0604u070fu17b4u17b5u200c-u200fu2028-u202fu2060-u206fufeffufff0-uffff]/g,escapable=/[\"x00-x1fx7f-x9fu00adu0600-u0604u070fu17b4u17b5u200c-u200fu2028-u202fu2060-u206fufeffufff0-uffff]/g,gap,indent,meta={'b':'\b','t':'\t','n':'\n','f':'\f','r':'\r','"':'\"','\':'\\'},rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==='string'?c:'\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4);})+'"':'"'+string+'"';}
function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==='object'&&typeof value.toJSON==='function'){value=value.toJSON(key);}
if(typeof rep==='function'){value=rep.call(holder,key,value);}
switch(typeof value){case'string':return quote(value);case'number':return isFinite(value)?String(value):'null';case'boolean':case'null':return String(value);case'object':if(!value){return'null';}
gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==='[object Array]'){length=value.length;for(i=0;i
v=partial.length===0?'[]':gap?'[n'+gap+
partial.join(',n'+gap)+'n'+
mind+']':'['+partial.join(',')+']';gap=mind;return v;}
if(rep&&typeof rep==='object'){length=rep.length;for(i=0;i
v=partial.length===0?'{}':gap?'{n'+gap+partial.join(',n'+gap)+'n'+
mind+'}':'{'+partial.join(',')+'}';gap=mind;return v;}}
if(typeof JSON.stringify!=='function'){JSON.stringify=function(value,replacer,space){var i;gap='';indent='';if(typeof space==='number'){for(i=0;i
rep=replacer;if(replacer&&typeof replacer!=='function'&&(typeof replacer!=='object'||typeof replacer.length!=='number')){throw new Error('JSON.stringify');}
return str('',{'':value});};}
if(typeof JSON.parse!=='function'){JSON.parse=function(text,reviver){var j;function walk(holder,key){var k,v,value=holder[key];if(value&&typeof value==='object'){for(k in value){if(Object.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v;}else{delete value[k];}}}}
return reviver.call(holder,key,value);}
cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return'\u'+
('0000'+a.charCodeAt(0).toString(16)).slice(-4);});}
if(/^[],:{}s]*$/.test(text.replace(/\(?:["\/bfnrt]|u[0-9a-fA-F]{4})/g,'@').replace(/"[^"\nr]*"|true|false|null|-?d+(?:.d*)?(?:[eE][+-]?d+)?/g,']').replace(/(?:^|:|,)(?:s*[)+/g,''))){j=eval('('+text+')');return typeof reviver==='function'?walk({'':j},''):j;}
throw new SyntaxError('JSON.parse');};}}());
/*
* End parser
*/

#156701
Dec 1, 2009 at 4:03pm

Darn, why does the new board remove trailing whitespace inside tags...?

#156702

You must be logged in to reply to this topic.