Difference between revisions of "List2CSV"

From Second Life Wiki
Jump to navigation Jump to search
Line 1: Line 1:
{{LSL Header}}
{{LSL Header}}
==List2CSV and CSV2List==
Includes escaping all characters, including comma and spaces, so the list that comes out should be just like the list that's sent in.
<lsl>
<lsl>
//Thanks LSL Wiki's llCSV2List article, and the string libs on the SL wiki
//Thanks to:
//    http://lslwiki.net/lslwiki/wakka.php?wakka=llCSV2List
//    https://wiki.secondlife.com/wiki/Library_Combined_Library


string strReplace(string str, string search, string replace) {
string strReplace(string str, string search, string replace) {
Line 29: Line 35:
string unescapeString(string s)
string unescapeString(string s)
{
{
    //backslash must be last when unescaping
     string final = s;
     string final = s;
     final = strReplace(final, "/c", ",");
     final = strReplace(final, "/c", ",");
Line 36: Line 41:
     final = strReplace(final, "/s", " ");
     final = strReplace(final, "/s", " ");


     //this one must be last.
     //backslash must be last when unescaping
     final = strReplace(final, "/b", "/");
     final = strReplace(final, "/b", "/");
     return final;
     return final;

Revision as of 18:16, 12 November 2008

List2CSV and CSV2List

Includes escaping all characters, including comma and spaces, so the list that comes out should be just like the list that's sent in.

<lsl> //Thanks to: // http://lslwiki.net/lslwiki/wakka.php?wakka=llCSV2List // https://wiki.secondlife.com/wiki/Library_Combined_Library

string strReplace(string str, string search, string replace) {

   return llDumpList2String(llParseStringKeepNulls((str = "") + str, [search], []), replace);

}

string escapeString(string s) {

   //I'm using forward slashes because backslashes are sepcial chars in lsl
   //    so reading this would be a pain.
   //escape / to /b
   //escape , to /c
   //escape < to /l
   //escape > to /r
   //escape space to /s
   string final = s;
   //backslash must be first when escaping
   final = strReplace(final, "/", "/b");
   
   final = strReplace(final, ",", "/c");
   final = strReplace(final, "<", "/l");
   final = strReplace(final, ">", "/r");
   final = strReplace(final, " ", "/s");
   return final;    

}

string unescapeString(string s) {

   string final = s;
   final = strReplace(final, "/c", ",");
   final = strReplace(final, "/l", "<");
   final = strReplace(final, "/r", ">");
   final = strReplace(final, "/s", " ");
   //backslash must be last when unescaping
   final = strReplace(final, "/b", "/");
   return final;

}


string List2TypeCSV(list input) { // converts a list to a CSV string with type information prepended to each item

   integer     i;
   list        output;
   integer     len;
   len=llGetListLength(input); //this can shave seconds off long lists
   for (i = 0; i < len; i++) {
       output += [llGetListEntryType(input, i)] + escapeString((string)llList2List(input, i, i));
   }
   
   return llList2CSV(output);

}

list TypeCSV2List(string inputstring) { // converts a CSV string created with List2TypeCSV back to a list with the correct type information

   integer     i;
   list        input;
   list        output;
   integer     len;
   
   input = llCSV2List(inputstring);
   len=llGetListLength(input);
   for (i = 0; i < len; i += 2) {
       string value = unescapeString(llList2String(input, i + 1));
       if (llList2Integer(input, i) == TYPE_INTEGER) output += (integer)value;
       else if (llList2Integer(input, i) == TYPE_FLOAT) output += (float)value;
       else if (llList2Integer(input, i) == TYPE_STRING) output += value;
       else if (llList2Integer(input, i) == TYPE_KEY) output += (key)value;
       else if (llList2Integer(input, i) == TYPE_VECTOR) output += (vector)value;
       else if (llList2Integer(input, i) == TYPE_ROTATION) output += (rotation)value;
   }
   
   return output;

}

testWithValue(string evilString) {

       list    l;
       string  s;
       
               l = [ 1, 2, evilString, 5 ];
       
       s = List2TypeCSV(l);
       
       l = TypeCSV2List(s);
       
       if (llGetListEntryType(l, 0) != TYPE_INTEGER) llOwnerSay("Bad! 0");
       if (llGetListEntryType(l, 1) != TYPE_INTEGER) llOwnerSay("Bad! 1");
       if (llGetListEntryType(l, 2) != TYPE_STRING) llOwnerSay("Bad! 2");
       if (llGetListEntryType(l, 3) != TYPE_INTEGER) llOwnerSay("Bad! 3");
       
       if (llList2Integer(l, 0) != 1) llOwnerSay("Bad! 0b");
       if (llList2Integer(l, 1) != 2) llOwnerSay("Bad! 1b");
       if (llList2String(l, 2) != evilString) llOwnerSay("Bad! 2b");
       if (llList2Integer(l, 3) != 5) llOwnerSay("Bad! 3b");

}

default {

   state_entry() {
       
       testWithValue("3,4");
       testWithValue("3<4");
       testWithValue("3>4");
       testWithValue("3/4");
       llOwnerSay("Done!");
   }

} </lsl>