08-21-2005 13:09
I have made two functions that will allow lists to be passed as strings with no possibility for error. For more information on how this works, please examine the script.

This does not provide utitilities to use strings as lists; they are only intended for transfers.

I **think** I squashed all of the bugs in it, but there might be more. Comments are appreciated.
CODE

// list2String and string2List functions
// For the safest transfers of lists with strings

// By Keknehv Psaltery, 7/16/05

//These functions are public domain.

//Known limitations:

// 1) It will, as with any other function, blow up if it receives an exceedingly
// large amount of data
// 2) It does not preserve the types of the list members when it converts them
// to a list. This means that llList2Integer() won't work; you'll have to
// use (integer)llList2String() to do that.


//How it works:
// Instead of using something like llParseString2List with a rare separator, these list-strings
// actually have an index of where the strings are. The data structure of the string looks like this:
// [index1][index2][index3]...[indexN][data1][data2][data3]

// So, if you had a list like this: ["The","red","dog"], it would look like
// this (without quotation marks) when it passes through the list2string function:
// " 12 15 18Thereddog"

string padToFour( string inString ) //Outputs the string padded to four characters with spaces on the left
{ //( or cut to four characters, from the left )
//Note: this function uses a clever trick for efficiency
// Basically, it counts the number of characters in the input string, and then adds
// the necessary number of characters to result in the desired length
integer inStringLength = llStringLength( inString ); //The length of the input string
if ( inStringLength < 4 )
return ( llGetSubString( " ", 0, 3 - inStringLength ) + inString );
else if ( inStringLength == 4 )
return inString;
else
return llGetSubString( inString, inStringLength - 4, inStringLength );
}

string list2String( list inList ) //Converts a list to a string, with total safety.
{
string outputString = llDumpList2String( inList, "" );
integer listLength = llGetListLength( inList );
integer baseOffset = listLength * 4;
integer lastOffset;
string prefixString;

integer listElementNum;
for ( listElementNum = 0 ; listElementNum < listLength ; ++listElementNum )
{
prefixString += padToFour( (string)( baseOffset + lastOffset ) );
lastOffset += llStringLength( llList2String( inList, listElementNum ) );
}

outputString = prefixString + outputString;
return outputString;
}

list string2List( string inList )
{
list outputList;
integer listLength = (integer)llGetSubString( inList, 0, 3 ) / 4;
integer baseOffset = listLength * 4;
integer elementLength;

integer listElementNum;
for ( listElementNum = 0 ; listElementNum < listLength ; ++listElementNum )
{
elementLength = (integer)llGetSubString( inList, listElementNum * 4, ( listElementNum * 4 ) + 3 ) - baseOffset;
outputList += [ llGetSubString( inList, baseOffset, baseOffset + elementLength ) ];
}

return outputList;
}

default
{
touch_start( integer num )
{
list testList = [ "The", "red", "dog" ];
llOwnerSay( "testList = [" + llDumpList2String( testList, ", " ) + "]" );
string testList2String = list2String( testList );
llOwnerSay( "testList2String = \"" + testList2String + "\"" );
list reversedL2S = string2List( testList2String );
llOwnerSay( "Reversed list = [" + llDumpList2String( testList, ", " ) + "]" );
}
}


(I don't know if this should be in the script library, or how to get it into there... help would be appreciated)