Jump to content

JsonPrettyChat.lsl - a JSON Pretty Printer


LepreKhaun
 Share

You are about to reply to a thread that has been inactive for 3894 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

So, developing some programs using JSON strings (https://wiki.secondlife.com/wiki/Json_usage_in_LSL) and found a need to check at times to see the structure of it. Came up with this debugging tool.

 

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 (such as having "\s" within it, 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.

[Code edited to correct mishandling of integer and float values within the json struct that had been quoted and should read as strings. Also corrected formatting of Key: Value pairs]

 

////////////////////////////////////////////////////
//    JsonPrettyChat.lsl
//    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
//    A debugging tool for Json construction
//
//    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 jsonString2PrettyChat, 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 struct
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, "");
        }
    }
}

 

 

Harness program, showing usage:

default
{
    state_entry()
    {
        llOwnerSay("Hello, Avatar!");
    }

    touch_start(integer total_number)
    {
        string source;
        source = llList2Json(JSON_ARRAY, ["x", 1, JSON_TRUE]);
        source = llList2Json(JSON_OBJECT, ["x",source,"Y",JSON_FALSE]);
        llMessageLinked (LINK_THIS, 75, source, NULL_KEY);
    }
}

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: }

 

As always, comments, suggestions and constructive critism is welcomed.

 

  • Like 1
Link to comment
Share on other sites

  • 1 month later...
You are about to reply to a thread that has been inactive for 3894 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...