/* * JSON messaging object * * string save_json(mapping data) * * Turn 'mapping' into a JSON message * Note that the mapping must contain a service and action key with appropriate * (string) values. The return value is the JSON message, or nil in case of an error * * mapping restore_json(string message) * * Return a mapping containing the parsed JSON message * */ #undef DEBUG_JSON #define GRAMMAR "whitespace=/[ ]*/\n\ beginmsg=/{/\n\ endmsg=/}/\n\ kvsep=/:/\n\ pairsep=/,/\n\ string=/\"([^\\\\\"\n]*(\\\\.)*)*\"/\n\ int=/[0-9]+/\n\ msg : beginmsg pairs endmsg\n\ pairs : pair\n\ pairs : pairs pairsep pair\n\ pair : key kvsep value ? wrap_kvpair\n\ key : ustring\n\ value: ustring\n\ value: int\n\ ustring: string ? unquote_string" string save_json(mapping data) { string service; string action; string result; string * keys; int count; int size; if(!data) { error("Empty mapping?"); } service = data["service"]; action = data["action"]; if(!service) { error("Service is a required field"); } if(!action) { error("Action is a required field"); } keys = map_indices(data); keys -= ({ "service", "action" }); result = "{\"service\" : \""+service+"\", \"action\" : \""+action+"\""; for( count = 0, size = sizeof( keys ); count < size; count++ ) { result += ", \""+keys[count]+"\" : \""+data[keys[count]]+"\""; } result += "}"; return result; } mapping restore_json( string message ) { int count; int size; mapping result; mixed * parse_tree; result = ([ ]); parse_tree = parse_string(GRAMMAR,message); if( !parse_tree ) { error( "Bad message format" ); } for( count = 0, size = sizeof( parse_tree ); count < size; count++ ) { if( arrayp( parse_tree[count] ) ) { result[parse_tree[count][0]] = parse_tree[count][1]; #ifdef DEBUG_JSON write( "Setting " + parse_tree[count][0] + " to " + parse_tree[count][1] ); } else { write( dump_value( parse_tree[count] ) ); #endif } } return result; } mixed * wrap_kvpair( mixed * data ) { return ({ ({ data[0] , data[2] }) }); } mixed * unquote_string( mixed * data ) { return ({ data[0][1..strlen(data[0])-2] }); }