Difference between revisions of "LepreKhaun Resident/Json Get Value Safe"

From Second Life Wiki
Jump to navigation Jump to search
(Created page with "<lsl>////////////////////////////// // function string uJsonGetValueSafe (string jsonText, list specifiers) // Same specification as llJsonGetValue() except returns all Strings /…")
 
(Set redirect to right name space.)
 
Line 1: Line 1:
<lsl>//////////////////////////////
#REDIRECT [[User:LepreKhaun_Resident/Json_Get_Value_Safe]]
// function string uJsonGetValueSafe (string jsonText, list specifiers)
// Same specification as llJsonGetValue() except returns all Strings
// enclosed within double quotes and exactly as they appear within jsonText
//
// Version 1.0 by LepreKhaun 9/9/20
// May be freely used, modified and distributed with this header intact.
// Compiled Size = 4,608 bytes
///////////////////////////////
 
string uJsonGetValueSafe (string jsonText, list specifiers)
{
string rString = "";
 
// no need for further processing if not String
if (llJsonValueType(jsonText, specifiers) != JSON_STRING)
{
rString = llJsonGetValue(jsonText, specifiers);
 
// specifiers may be an empty list and we're dealing with simply a JSON_STRING
}
else if (llGetListLength(specifiers) == 0)
{
rString = jsonText;
 
}
else
{
// used for assembling the return string
string char = "";
string prevChar = "";
 
// boolean flag
integer inQuote = FALSE;
 
// used to step through Array/Object Values
// NOTE: Takes valid, compliant Json text for granted
integer inArrayObject = 0;
 
integer iter = 0;
 
// we need to extract the parent of the String Value
list valueSpecifier = llList2List(specifiers, -1, -1);
 
// shorten specifiers to point to parent of the Value
specifiers = llDeleteSubList(specifiers, -1, -1);
 
// extract the parent
jsonText = llJsonGetValue(jsonText, specifiers);
 
if (llGetListEntryType(valueSpecifier, 0) == TYPE_INTEGER)
{
// we're dealing with an array
integer sPos = llList2Integer(valueSpecifier, 0);
 
// used to step through array Values
integer count = 0;
 
// find start of our String Value within array
while (count < sPos)
{
char = llGetSubString(jsonText, ++iter, iter);
if (char == "\"" && prevChar != "\\")
{
inQuote = !inQuote;
}
else if ((char == "[" || char == "{") && !inQuote)
{
++inArrayObject;
}
else if ((char == "]" || char == "}") && !inQuote)
{
--inArrayObject;
}
else if (char == "," && !inQuote && !inArrayObject)
{
++count;
}
prevChar = char;
}
// eat possible white space
while ((rString = llGetSubString(jsonText, ++iter, iter)) != "\""){};
// Now assemble return string
inQuote = TRUE;
prevChar = "";
while (inQuote)
{
char = llGetSubString(jsonText, ++iter, iter);
rString = rString + char;
if (char == "\"" && prevChar != "\\")
{
inQuote = FALSE;
}
prevChar = char;
}
 
}
else
{
// otherwise, we must be dealing with an object
 
// make the key for comparison
string sKey = llList2String(valueSpecifier, 0);
 
// and encode it as a JSON_STRING if it's not
if (llGetSubString(sKey, 0, 0) != "\"")
{
sKey = "\"" + sKey + "\"";
}
// used for a possible "Key" used in comparison
string pKey;
 
integer jtLength = llStringLength(jsonText) - 1;
 
while (iter < jtLength)
{
// go to start of a possible "Key"
while (llGetSubString(jsonText, ++iter, iter) != "\"")
{
};
 
// form pKey
pKey = "\"";
inQuote = TRUE;
while (inQuote)
{
char = llGetSubString(jsonText, ++iter, iter);
pKey = pKey + char;
if (char == "\"" && prevChar != "\\")
{
inQuote = FALSE;
}
prevChar = char;
}
 
// move to start of Value, eating possible white space
while (llGetSubString(jsonText, ++iter, iter) != ":")
{
};
 
char = llEscapeURL(llGetSubString(jsonText, ++iter, iter));
 
while (char == "%20" || char == "%09" || char == "%0a" || char == "%0d")
{
char = llEscapeURL(llGetSubString(jsonText, ++iter, iter));
}
 
char = llUnescapeURL(char);
 
// check "Key" for match with sKey AND start of a String Value
if (pKey == sKey && char == "\"")
{
// assemble Value
prevChar = "";
inQuote = TRUE;
rString = "\"";
 
while (inQuote)
{
char = llGetSubString(jsonText, ++iter, iter);
rString = rString + char;
if (char == "\"" && prevChar != "\\")
{
inQuote = FALSE;
}
prevChar = char;
}
// move to ',' or '}' (next "Key"Value pair or end of object)
while(!(llGetSubString(jsonText, ++iter, iter) == "," || llGetSubString(jsonText, iter, iter) == "}")){};
}
else
{
// eat Value to next Key or end of object
integer inValue = TRUE;
prevChar = "";
inArrayObject = 0;
inQuote = FALSE;
 
while (inValue)
{
char = llGetSubString(jsonText, iter, iter++);
if (char == "\"" && prevChar != "\\")
{
inQuote = !inQuote;
}
else if ((char == "," || char == "}") && !inQuote && !inArrayObject)
{
inValue = FALSE;
--iter;
}
else if ((char == "[" || char == "{") && !inQuote)
{
++inArrayObject;
}
else if ((char == "]" || char == "}") && !inQuote)
{
--inArrayObject;
}
prevChar = char;
}
}
}
}
}
return rString;
}
 
// example usage and comparison
default {
touch_end (integer i){
string jText = "{\"B\":\"Z\",\"C\":[1,\"a\\r\\t\\f\",3],\"A\":\"H\\n\\u23AF\"}";
llOwnerSay(jText); // => '{"B":"Z","C":[1,"a\r\t\f",3],"A":"H\n\u23AF"}'
llOwnerSay(llJsonGetValue(jText, ["A"])); // => 'H' then Unicode character for New Line then 'u23AF'
llOwnerSay(uJsonGetValueSafe(jText, ["A"])); // => "H\n\u23AF"
 
llOwnerSay(llJsonGetValue(jText, ["B"])); // => 'Z'
llOwnerSay(uJsonGetValueSafe(jText, ["B"])); // => "Z"
 
llOwnerSay(llJsonGetValue(jText, ["C"])); // => '[1,"a\r\t\f",3]'
llOwnerSay(uJsonGetValueSafe(jText, ["C"])); // => '[1,"a\r\t\f",3]'
llOwnerSay(llJsonGetValue(jText, ["C", 0])); // => '1'
llOwnerSay(uJsonGetValueSafe(jText, ["C", 0])); // => '1'
 
llOwnerSay(llJsonGetValue(jText, ["C", 1])); // => 'a' then Unicode characters for the escaped sequences
llOwnerSay(uJsonGetValueSafe(jText, ["C", 1])); // => "a\r\t\f"
 
llOwnerSay(llJsonGetValue(jText, ["C", 2])); // => '3'
llOwnerSay(uJsonGetValueSafe(jText, ["C", 2])); // => '3'
}
}</lsl>
 
----
 
<center>== [[User:LepreKhaun_Resident|'''More Json Tips, Tricks and Coding Examples''']] ==</center>

Latest revision as of 17:03, 18 September 2013