Forums > Javascript

JSON parser ?


f.e
May 4, 2009 | 11:11 am

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


May 5, 2009 | 6:10 am

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.



f.e
May 5, 2009 | 7:19 am

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


November 28, 2009 | 1:33 am

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

lh


November 28, 2009 | 8:07 pm

i am using this code without any problem.

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


November 29, 2009 | 4:34 pm

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


November 29, 2009 | 6:13 pm

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


December 1, 2009 | 4:01 pm

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
*/


December 1, 2009 | 4:03 pm

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


Viewing 9 posts - 1 through 9 (of 9 total)