Difference between revisions of "User:LepreKhaun Resident/Workaround4Escaped Chars within JsonText"

From Second Life Wiki
Jump to navigation Jump to search
m (8 spaces indent >> 4 spaces indent..... and fixed broken formatting of page by adding a div around lsl code)
((Made while condition more readable))
 
(5 intermediate revisions by 2 users not shown)
Line 1: Line 1:
['''NOTE:''' Pages within my Name Space are a WIP and constantly changing. As my understanding of the problems I attempt to address and the grasp of the subject matter itself deepens, I regularly review what I have written and update the content as better algorithms occur to me.
However, for this process of refinement, improvement and tweaking to result in something that might (hopefully!) benefit the community at large, I ask that comments, suggested improvements, corrections of fact or your own personal style preferences be made ONLY on the Discussion Pages within my Name Space. Thank you!]
=== uList2Json() and uJsonSetValue()===
=== uList2Json() and uJsonSetValue()===


As many of you may be aware, [[LSL Portal|LSL]] has the habit of "enhancing" Strings. This is regarded as a "feature" of the language and usually works out for the best, giving one the option of formatting chatted text by using "\t" and "\n". Unfortunately, one didn't have a way to opt out of this behavior. Put in computereze, LSL simply lacked "raw strings".
As many of you may be aware, LSL has the habit of "enhancing" Strings. This is regarded as a "feature" of the language and usually works out for the best, giving one the option of formatting chatted text by using "\t" and "\n". Unfortunately, one didn't have a way to opt out of this behavior. Put in computereze, LSL simply lacked "raw strings".


This has bedeviled those working with JSON text, either for web communications or developing other uses for it, because some strings just wouldn't encode properly. That is to say, these are all perfectly valid JSON strings that simply couldn't be directly formed with llList2Json() and llJsonSetValue():
This has bedeviled those working with Json text, either for web communications or developing other uses for it, because some strings just wouldn't encode properly. That is to say, these are all perfectly valid Json strings that simply couldn't be directly formed with llList2Json() and llJsonSetValue():
*"\"Go!\" he yelled.\n"
*"\"Go!\" he yelled.\n"
*"She replied \"No!\""
*"She replied \"No!\""
Line 10: Line 14:
*"Control characters are \t\n\r\f\b"
*"Control characters are \t\n\r\f\b"


[[User:LepreKhaun Resident|I]]'ve spent a few weeks studying the problem, [[User:LepreKhaun_Resident/Workaround4Escaped_Chars_within_JsonText_0ld|most of it going about it the wrong way]], but had an epiphany. A one line addition Maestro Linden added to [[Json_usage_in_LSL|Json Usage in LSL]] on the 10th ("LSL strings which both begin and end with "\"" are interpreted literally as JSON strings, while those without are parsed when converted into JSON.") confirmed what I had begun to surmise- a JSON String (being a LSL String that is further enclosed within double quotes) is a "raw string"! Once I had that in hand, the following two functions practically wrote themselves.
I've spent a few weeks studying the problem, [[User:LepreKhaun_Resident/Workaround4Escaped_Chars_within_JsonText_0ld|most of it going about it the wrong way]], but had an epiphany. A one line addition Maestro Linden added to [[Json_usage_in_LSL|Json Usage in LSL]] on the 10th ("LSL strings which both begin and end with "\"" are interpreted literally as JSON strings, while those without are parsed when converted into JSON.") confirmed what I had begun to surmise- a Json String (being a LSL String that is further enclosed within double quotes) is a "raw string"! Once I had that in hand, the following two functions practically wrote themselves.
 


<div>
<div><lsl>//////////////////////////////
<lsl>
//////////////////////////////
// function string uList2Json (string type, list values)
// function string uList2Json (string type, list values)
// This function takes the exact same parameters as
// This function takes the exact same parameters as
Line 30: Line 33:
string uList2Json (string type, list values)
string uList2Json (string type, list values)
{
{
    integer iter = -1;
    integer listLength = llGetListLength(values);


    // Step through list, hitting every other item if JSON_OBJECT
integer iter = -1;
    while ((iter = ++iter + (type == JSON_OBJECT)) < listLength)
integer listLength = llGetListLength(values);
        // necessary so we don't choke on next if test
        if (llGetListEntryType(values, iter) == TYPE_STRING)
// Step through list, hitting every other item if JSON_OBJECT
            // make sure it is not a JSON_* Value or a Number
integer step = 1 + (type == JSON_OBJECT);
            if (llJsonValueType(llList2String(values, iter), []) == JSON_INVALID)
while ((iter += step) < listLength)
                values = llListReplaceList(values, ["\"" + llList2String(values, iter) + "\""], iter, iter);
// necessary so we don't choke on next if test
if (llGetListEntryType(values, iter) == TYPE_STRING)
// make sure it is not a JSON_* Value or a Number
if (llJsonValueType(llList2String(values, iter), []) == JSON_INVALID)
values = llListReplaceList(values, ["\"" + llList2String(values, iter) + "\""], iter, iter);


    return llList2Json(type, values);
return llList2Json(type, values);
}
}


//////////////////////////////
//////////////////////////////
Line 64: Line 69:
string uJsonSetValue(string json, list specifiers, string value)
string uJsonSetValue(string json, list specifiers, string value)
{
{
    // We don't want to change the string representation of  
// We don't want to change the string representation of  
    // an integer, a float or any Json Value Type
// an integer, a float or any Json Value Type
    if (llJsonValueType(value, []) == JSON_INVALID)
if (llJsonValueType(value, []) == JSON_INVALID)
        value = "\"" + value + "\"";
value = "\"" + value + "\"";
    return llJsonSetValue(json, specifiers, value);
return llJsonSetValue(json, specifiers, value);
}
}


Line 75: Line 80:
// Examples showing usage
// Examples showing usage
///////////
///////////
 
default
default
{
{
    touch_end(integer i)
touch_end(integer i)
    {
{
        string temp;
string temp;
        string jsonText;
string jsonText;
 
        // To encode '{"A":"\"Go!\" he yelled.\nShe replied \"No!\"","Z":"\\escaped \\ slosh\\"}'
// To encode '{"A":"\"Go!\" he yelled.\nShe replied \"No!\"","Z":"\\escaped \\ slosh\\"}'
        jsonText = uList2Json (JSON_OBJECT, [
jsonText = uList2Json (JSON_OBJECT, [
                "A", "\\\"Go!\\\" he yelled.\\nShe replied \\\"No!\\\"",  
"A", "\\\"Go!\\\" he yelled.\\nShe replied \\\"No!\\\"",  
                "Z", "\\\\escaped \\\\ slosh\\\\"
"Z", "\\\\escaped \\\\ slosh\\\\"         //"//wiki syntax highlighter kludge
                ]);
]);
        llOwnerSay(jsonText);
llOwnerSay(jsonText);
 
        // To encode '{"Control Chars":"\b\r\f\n\t and Windows uses \r\n for EOL","©":"\u00A9"}'
// To encode '{"Control Chars":"\b\r\f\n\t and Windows uses \r\n for EOL","©":"\u00A9"}'
        jsonText = uList2Json(JSON_OBJECT, [
jsonText = uList2Json(JSON_OBJECT, [
                "Control Chars", "\\b\\r\\f\\n\\t and Windows uses \\r\\n for EOL",  
"Control Chars", "\\b\\r\\f\\n\\t and Windows uses \\r\\n for EOL",  
                "©", "\\u00A9"
"©", "\\u00A9"
                ]);
]);
        llOwnerSay(jsonText);
llOwnerSay(jsonText);
 
        // To encode '["WebSite","http:\/\/my.com\/ask.php?what%20is%20it","\t"]'
// To encode '["WebSite","http:\/\/my.com\/ask.php?what%20is%20it","\t"]'
        jsonText = uList2Json(JSON_ARRAY, [
jsonText = uList2Json(JSON_ARRAY, [
                "WebSite",
"WebSite",
                "http:\\/\\/my.com\\/ask.php?what%20is%20it",
"http:\\/\\/my.com\\/ask.php?what%20is%20it",
                "\\t"
"\\t"
                ]);
]);
        llOwnerSay(jsonText);
llOwnerSay(jsonText);
 
        // Make a Json object...
        temp = uList2Json(JSON_OBJECT, [
                "A", 99,
                "Z", "88]",
                "C", JSON_TRUE
                ]);
        // ... add it to end of the array ...
        jsonText = uJsonSetValue(jsonText, [JSON_APPEND], temp);
        // ... change our web address ...
        jsonText = uJsonSetValue(jsonText, [1], "http:\\/\\/www.google.com");
        // ... change that TAB in the third spot to PI
        jsonText = uJsonSetValue(jsonText, [2], (string)PI);
        // ... and add a new "Key":Value pair to our object
        jsonText = uJsonSetValue(jsonText, [3, "New"], ((string)PI + "\\n"));


        //  ["WebSite","http:\/\/www.google.com",3.141593,{"A":99,"C":true,"New":"3.141593\n","Z":"88]"}]
// Make a Json object...
        llOwnerSay(jsonText);
temp = uList2Json(JSON_OBJECT, [
   
"A", 99,
    }
"Z", "88]",
}
"C", JSON_TRUE
</lsl>
]);
</div>
// ... add it to end of the array ...
jsonText = uJsonSetValue(jsonText, [JSON_APPEND], temp);
// ... change our web address ...
jsonText = uJsonSetValue(jsonText, [1], "http:\\/\\/www.google.com");
// ... change that TAB in the third spot to PI
jsonText = uJsonSetValue(jsonText, [2], (string)PI);
// ... and add a new "Key":Value pair to our object
jsonText = uJsonSetValue(jsonText, [3, "New"], ((string)PI + "\\n"));
//  ["WebSite","http:\/\/www.google.com",3.141593,{"A":99,"C":true,"New":"3.141593\n","Z":"88]"}]
llOwnerSay(jsonText);
 
}
}</lsl></div>


Now, if I can just get the retrieval worked out as simply... ;=)
Now, if I can just get the retrieval worked out as simply... ;=)
----


 
<center>== [[User:LepreKhaun_Resident|'''More Json Tips, Tricks and Coding Examples''']] ==</center>
<center>See [[User:LepreKhaun Resident|LepreKhaun Resident]]'s page for '''more JSON tips, tricks and coding examples'''.</center>

Latest revision as of 19:44, 15 October 2013

[NOTE: Pages within my Name Space are a WIP and constantly changing. As my understanding of the problems I attempt to address and the grasp of the subject matter itself deepens, I regularly review what I have written and update the content as better algorithms occur to me.

However, for this process of refinement, improvement and tweaking to result in something that might (hopefully!) benefit the community at large, I ask that comments, suggested improvements, corrections of fact or your own personal style preferences be made ONLY on the Discussion Pages within my Name Space. Thank you!]

uList2Json() and uJsonSetValue()

As many of you may be aware, LSL has the habit of "enhancing" Strings. This is regarded as a "feature" of the language and usually works out for the best, giving one the option of formatting chatted text by using "\t" and "\n". Unfortunately, one didn't have a way to opt out of this behavior. Put in computereze, LSL simply lacked "raw strings".

This has bedeviled those working with Json text, either for web communications or developing other uses for it, because some strings just wouldn't encode properly. That is to say, these are all perfectly valid Json strings that simply couldn't be directly formed with llList2Json() and llJsonSetValue():

  • "\"Go!\" he yelled.\n"
  • "She replied \"No!\""
  • "Copyright symbol is \u00A9"
  • "oops]"
  • "Control characters are \t\n\r\f\b"

I've spent a few weeks studying the problem, most of it going about it the wrong way, but had an epiphany. A one line addition Maestro Linden added to Json Usage in LSL on the 10th ("LSL strings which both begin and end with "\"" are interpreted literally as JSON strings, while those without are parsed when converted into JSON.") confirmed what I had begun to surmise- a Json String (being a LSL String that is further enclosed within double quotes) is a "raw string"! Once I had that in hand, the following two functions practically wrote themselves.


<lsl>//////////////////////////////

// function string uList2Json (string type, list values) // This function takes the exact same parameters as // llList2Json() but correctly encodes all possible strings // including those with escape characters within them. // // Initial strings must escape all instances of the // desired escape character itself // (ie "\\t" => '\t', "\\\\" => '\\', "\\/" => '\/') // as well as any double quotes ("\\\"" => '\"') // // Version 1.0 by LepreKhaun 9/19/2013 // May be freely used, modified and distributed with this header intact. /////////////////////////////// string uList2Json (string type, list values) {

integer iter = -1; integer listLength = llGetListLength(values);

// Step through list, hitting every other item if JSON_OBJECT integer step = 1 + (type == JSON_OBJECT); while ((iter += step) < listLength) // necessary so we don't choke on next if test if (llGetListEntryType(values, iter) == TYPE_STRING) // make sure it is not a JSON_* Value or a Number if (llJsonValueType(llList2String(values, iter), []) == JSON_INVALID) values = llListReplaceList(values, ["\"" + llList2String(values, iter) + "\""], iter, iter);

return llList2Json(type, values); }

////////////////////////////// // function string uJsonSetValue ( string json, list specifiers, string value ) // This function takes the exact same parameters as // llJsonSetValue() but correctly encodes all possible strings // including those with escape characters within them. // // Initial strings must escape all instances of the // desired escape character itself // (ie "\\t" => '\t', "\\\\" => '\\', "\\/" => '\/') // as well as any double quotes ("\\\"" => '\"') // // NOTE: To encode a Float or Integer as a String // within the Json text, enclose it with escaped quotes // (ie '"3"' => '3' BUT '"\"3\""' => '"3"') // // Version 1.0 by LepreKhaun 9/19/2013 // May be freely used, modified and distributed with this header intact. /////////////////////////////// string uJsonSetValue(string json, list specifiers, string value) { // We don't want to change the string representation of // an integer, a float or any Json Value Type if (llJsonValueType(value, []) == JSON_INVALID) value = "\"" + value + "\""; return llJsonSetValue(json, specifiers, value); }


/////////// // Examples showing usage ///////////

default { touch_end(integer i) { string temp; string jsonText;

// To encode '{"A":"\"Go!\" he yelled.\nShe replied \"No!\"","Z":"\\escaped \\ slosh\\"}' jsonText = uList2Json (JSON_OBJECT, [ "A", "\\\"Go!\\\" he yelled.\\nShe replied \\\"No!\\\"", "Z", "\\\\escaped \\\\ slosh\\\\" //"//wiki syntax highlighter kludge ]); llOwnerSay(jsonText);

// To encode '{"Control Chars":"\b\r\f\n\t and Windows uses \r\n for EOL","©":"\u00A9"}' jsonText = uList2Json(JSON_OBJECT, [ "Control Chars", "\\b\\r\\f\\n\\t and Windows uses \\r\\n for EOL", "©", "\\u00A9" ]); llOwnerSay(jsonText);

// To encode '["WebSite","http:\/\/my.com\/ask.php?what%20is%20it","\t"]' jsonText = uList2Json(JSON_ARRAY, [ "WebSite", "http:\\/\\/my.com\\/ask.php?what%20is%20it", "\\t" ]); llOwnerSay(jsonText);

// Make a Json object... temp = uList2Json(JSON_OBJECT, [ "A", 99, "Z", "88]", "C", JSON_TRUE ]); // ... add it to end of the array ... jsonText = uJsonSetValue(jsonText, [JSON_APPEND], temp); // ... change our web address ... jsonText = uJsonSetValue(jsonText, [1], "http:\\/\\/www.google.com"); // ... change that TAB in the third spot to PI jsonText = uJsonSetValue(jsonText, [2], (string)PI); // ... and add a new "Key":Value pair to our object jsonText = uJsonSetValue(jsonText, [3, "New"], ((string)PI + "\\n"));

// ["WebSite","http:\/\/www.google.com",3.141593,{"A":99,"C":true,"New":"3.141593\n","Z":"88]"}] llOwnerSay(jsonText);

}

}</lsl>

Now, if I can just get the retrieval worked out as simply... ;=)


== More Json Tips, Tricks and Coding Examples ==