User:LepreKhaun Resident/Json Pretty Printer

From Second Life Wiki
Jump to navigation Jump to search

JsonPrettyChat.lsl - a JSON Pretty Printer

This is a stand alone debugging tool for working with JSON objects. It acts like all JSON pretty printers and outputs to llOwnerSay(). This is NOT a JSON validator, meaning it may well "pretty print" your string even if your strings within it are mal-formed json constructions (such as having "\s" within it or empty values such as "[,,,]", which breaks strict JSON compliance). But, it will separate your strings out for visual inspection.

It uses recursion A LOT so will likely crash if you have a very large JSON structure. However, it'll have worked it up to a point where you can determine where it hit the stack heap collision, and you simply need to break parts of the JSON string out to continue deeper into it.

It expects a link message with the JSON string as the third parameter. The second parameter is used as a "channel ID" (defaults to 75 as written). If this conflicts with your existing link messaging system, I'd expect you should see how to modify the code to suit yourself.

<lsl> //////////////////////////////////////////////////// // JsonPrettyChat.lsl // // A debugging tool for Json construction // Version 1.2 by LepreKhaun -- 2013-07-10 // Corrected mishandling of quoted numbers. // Corrected formatting of Key values in json objects. // Version 1.0 Released -- 2013-07-09 // // Usage: Place this stand-alone script within object containing program // you wish to debug and address it with // llMessageLinked ( integer LINK_SET, integer MESSAGE_CHANNEL, string json, key NULL_KEY ); // at the point(s) you wish to review the JSON string. ////////////////////////////////////////////////////

// Used as a "channel ID' for link messages integer MESSAGE_CHANNEL = 75;

// How deep we are in the json structure integer LEVEL = 0;

// User functions chatThis (string message) { string indent = ""; integer iter = LEVEL;

while (iter--){ indent += "\t"; } llOwnerSay (indent + message); }

handleValue (string prePend, string value, string apPend) { // JSON Value Type string valueType = llJsonValueType(value, []);

if (valueType == JSON_FALSE) { chatThis (prePend + "false" + apPend); } else if (valueType == JSON_TRUE) { chatThis (prePend + "true" + apPend); } else if (valueType == JSON_NULL) { chatThis (prePend + "null" + apPend); } else if (valueType == JSON_NUMBER) { chatThis (prePend + value + apPend); } else if (valueType == JSON_ARRAY) { chatThis (prePend + "["); ++LEVEL; handleJsonArray (value); --LEVEL; chatThis ("]" + apPend); } else if (valueType == JSON_OBJECT) { chatThis (prePend + "{"); ++LEVEL; handleJsonObject (value); --LEVEL; chatThis ("}" + apPend); // NOTE: Once back in list form, all strings evaluate to JSON_INVALID // because of having their enclosing double quotes (") stripped, So... } else { // We'll treat it as a String chatThis (prePend + value + apPend); } }

handleJsonArray (string jsonArray) { list valueList = llJson2List(jsonArray); integer iter = 0; integer listLength = llGetListLength(valueList);

while (iter<listLength) { string value = llList2String(valueList, iter); if (llJsonValueType(jsonArray,[iter])== JSON_STRING) value = "\"" + value + "\""; if (++iter == listLength) handleValue ("", value, ""); else handleValue ("", value, ","); } }

handleJsonObject (string jsonObject) { list valueList = llJson2List(jsonObject); integer iter = 0; integer listLength = llGetListLength(valueList); while (iter<listLength) { string myKey = llList2String(valueList, iter); string value = llList2String(valueList, ++iter); if (llJsonValueType(jsonObject,[myKey])== JSON_STRING) value = "\"" + value + "\""; myKey = "\"" + myKey + "\": ";

if (++iter == listLength) handleValue (myKey, value, ""); else handleValue (myKey, value, ","); } }

// Main Program default { state_entry() { llOwnerSay ("Hello, " + llKey2Name(llGetOwner())); llOwnerSay ("Json Pretty Chat awaits your JSON string"); llOwnerSay ("Use " + (string)MESSAGE_CHANNEL + " for the second paramater of"); llOwnerSay ("llMessageLinked\(\) and supply your JSON string in the third."); }

link_message(integer sender_number, integer number, string message, key id) { if (number == MESSAGE_CHANNEL) { llOwnerSay("Pretty Chat of: " + message); handleValue("", message, ""); } } } </lsl>

Harness program, showing usage: <lsl> default {

   state_entry()
   {
       llOwnerSay("Hello, Avatar!");
   }
   touch_start(integer total_number)
   {
       // Used as a "channel ID' for link messages
       integer MESSAGE_CHANNEL = 75;
       string source = llList2Json(JSON_OBJECT, ["x",llList2Json(JSON_ARRAY, ["x", 1, JSON_TRUE]),"Y",JSON_FALSE]);
       llMessageLinked (LINK_THIS, MESSAGE_CHANNEL, source, NULL_KEY);
   }

} </lsl>

Outputs:

Object: Hello, LepreKhaun Resident
Object: Json Pretty Chat is waiting for your JSON string
Object: Use 75 for the second paramater of
Object: llMessageLinked() and supply your JSON string in the third.

// Harness program checking in.
Object: Hello, Avatar!

// Result of touch_start()
Object: Pretty Chat of: {"x":["x",1,true],"Y":false}
Object: {
Object:     "x": [
Object:         "x",
Object:         1,
Object:         true
Object:     ],
Object:     "Y": false
Object: }