01-12-2006 15:56
Hello everyone, I made this pair of list-to-string and string-to-list functions. I thought they might be interesting mainly because the way the string is set up, it will always split into the same number of pieces -- it doesn't use separators, and it retains the types of the original list elements.

Well, have a look, may someone find it useful!

CODE

// list2string and string2list functions...
// For the safest transfers of lists with strings

// By Keknehv Psaltery, 1/12/06 -- Public domain, do whatever you wish (Although I'd prefer if I still get credit)

//Known limitations -- It doesn't preserve a small amount of the floating point data.
//Of course, there is the memory limitation. (I could do some float trimming, but that would make it much slower)

//How it works:
// Instead of using something like llParseString2List with an uncommon separator, these list-strings
// actually have an index of where the strings are, and, as a bonus, it also preserves data types
// The data structure of the string looks like this:
// [index1][type1] [index2][type2] [index3][type3]...[indexN][typeN] [data1][data2][data3]

// So, if you had a list like this: [The, 1, <1, 5.3, 6>, dog], it would look like
// this (without quotation marks) when it passes through the list2string function:
// "00163001910020500503The1<1.000000, 5.300000, 6.000000>dog"
// ====^====^====^====^---_------------------------------___
// ind1|ind2|ind3|ind4|data1 data3 data4
// typ1 typ2 typ3 typ4 data2
// This formatting allows for **any** conceivable data to be transferred.

string padToFour( string inString ) //Outputs the string padded to four characters with spaces on the left
{ //( or cut to four characters -- pad("01234")="1234")
//Note: this function uses a clever trick for efficiency
integer inStringLength = llStringLength( inString ); //The length of the input string
if ( inStringLength < 4 )
return ( llGetSubString( "0000", 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 no possible chance of error
{
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 ) )
+ (string)llGetListEntryType( inList, listElementNum );
lastOffset += llStringLength( llList2String( inList, listElementNum ) );
}

outputString = prefixString + outputString;
return outputString;
}

list string2List( string inString )
{
list outputList;
integer baseOffset = (integer)llGetSubString( inString, 0, 3 );
integer listLength = baseOffset / 5;

integer elementLength;
integer elementType;

integer listElementNum;
for ( listElementNum = 0 ; listElementNum < listLength ; ++listElementNum )
{
elementType = (integer)llGetSubString( inString, listElementNum * 5 + 4, listElementNum * 5 + 4 );
elementLength = (integer)llGetSubString( inString, listElementNum * 5, listElementNum * 5 + 3 )
- baseOffset;

if ( elementType == 1 )
outputList += [ (integer)llGetSubString( inString, baseOffset, baseOffset + elementLength ) ];
else if ( elementType == 2 )
outputList += [ (float)llGetSubString( inString, baseOffset, baseOffset + elementLength ) ];
else if ( elementType == 3 )
outputList += [ llGetSubString( inString, baseOffset, baseOffset + elementLength ) ];
else if ( elementType == 4 )
outputList += [ (key)llGetSubString( inString, baseOffset, baseOffset + elementLength ) ];
else if ( elementType == 5 )
outputList += [ (vector)llGetSubString( inString, baseOffset, baseOffset + elementLength ) ];
else if ( elementType == 6 )
outputList += [ (rotation)llGetSubString( inString, 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, ", " ) + "]" );
}
}