Table of Contents

About

Encodes the first level of a JSON string to key-value data. This function behaves the same way that llJson2List does, such that the first level of JSON is taken as the key and sub-levels as values. In other words, for a JSON string of:

{
    "position" : "<1, 1, 0>",
    "toggle" : {
        "on", "c"
    }
}

the keys will be position and toggle and their corresponding values will be:

<1, 1, 0>

for position, respectively:

               {
        "on", "c"
    }

for the value of toggle.

Code-wise, the function implements a JSON parser to which we append wasKeyValueEncode (see equivalence).

Example Usage

When the function is called with:

        string input = 
        "{
            \"position\":\"<1, 1, 0>\",
            \"toggle\": {
                \"on\",\"c\"
            },
            \"man\":\"eater\",
            \"heating\": {
                \"setting\":\"off\"
            },
            \"cool\":\"stuff\"
        }";
        llOwnerSay("WAS: " + wasJSONToKeyValueData(input));

it will print the output:

[06:13]  Object: WAS: position=<1, 1, 0>&toggle={
                "on","c"
            }&man=eater&heating={
                "setting":"off"
            }&cool=stuff

This is similar to llJson2List which converts a JSON string to a flat LSL list.

Equivalence

Note that calling:

string data = wasJSONToKeyValueData(input);

is equivalent to:

string data = wasKeyValueEncode(llJson2List(input));

Code

This script was tested and works on OpenSim version 0.7.4!

///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2014 Wizardry and Steamworks - License: CC BY 2.0    //
///////////////////////////////////////////////////////////////////////////
string wasJSONToKeyValueData(string JSON) {
    list output = [];
    list symbols = [];
    string data = "";
    integer level = 1;
    // parse JSON
    do {
        string c = llGetSubString(JSON, 0, 0);
        // we are at an object start
        if(c == "{") {
            if(level > 1) {
                data += c;
            }
            // increment the level
            ++level;
            // add the symbol
            symbols += c;
            // and continue
            jump continue;
        }
        // we are at an object end
        if(c == "}") {
            // decrement the level
            --level;
            if(level > 1) {
                data += c;
                output += data;
                data = "";
            }
            // pop symbols
            string s = llList2String(symbols, -1);
            symbols = llDeleteSubList(symbols, -1, -1);
            // got an object start
            if(s == "{") {
                // so continue
                jump continue;
            }
            // error
            return JSON_INVALID;
        }
        // we are at data end or data start
        if(c == "\"") {
            if(level > 2) {
                data += "\"";
                jump continue;
            }
            // pop symbols
            string s = llList2String(symbols, -1);
            symbols = llDeleteSubList(symbols, -1, -1);
            // if we are at data end
            if(s == "\"") {
                // add the data to the output
                output += data;
                // flush data
                data = "";
                // and continue
                jump continue;
            }
            // we are not a the end of data
            // add the symbol back
            symbols += s;
            // add the current character
            symbols += c;
            // and continue
            jump continue;
        }
        if(level > 2) {
            data += c;
            jump continue;
        }
        // pop symbols
        string s = llList2String(symbols, -1);
        symbols = llDeleteSubList(symbols, -1, -1);
        if(s == "\"") {  
            data += c;
            symbols += s;
            jump continue;
        }
        symbols += s;
@continue;
        JSON = llDeleteSubString(JSON, 0, 0);
    } while(llStringLength(JSON) != 0);
    // now encode to key-value data
    list k = llList2ListStrided(output, 0, -1, 2);
    list v = llList2ListStrided(llDeleteSubList(output, 0, 0), 0, -1, 2);
    output = [];
    do {
        output += llList2String(k, 0) + "=" + llList2String(v, 0);
        k = llDeleteSubList(k, 0, 0);
        v = llDeleteSubList(v, 0, 0);
    } while(llGetListLength(k) != 0);
    return llDumpList2String(output, "&");
}