Don't click here unless you want to be banned.

LSL Wiki : ExampleSafeListConversion

HomePage :: PageIndex :: RecentChanges :: RecentlyCommented :: UserSettings :: You are crawl338.us.archive.org
These are (yet more) functions to convert lists to strings and back. However, these functions have two main advantages.
1) It retains the types of the list data
2) It can't be fooled -- it doesn't rely on obscure character strings

// 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.

// Edited by Ardy Lay, January 25th, 2009
// I liked the concept but the code was not completed.
// Does it work now?

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 * 5;
    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 );
        integer a = (integer)llGetSubString( inString,  listElementNum    * 5,  listElementNum    * 5 + 3 );
        integer b = (integer)llGetSubString( inString, (listElementNum+1) * 5, (listElementNum+1) * 5 + 3 );
        if (b == 0) b = llStringLength(inString);
        elementLength = b-a;
//        llOwnerSay(
//        "Element    "+(string)listElementNum+
//        " Type      "+(string)elementType+
//        " Begins at "+(string)a+
//        " ends at   "+(string)b+
//        " length    "+(string)elementLength);
        
        if      ( elementType == 1 )
            outputList += [ (integer)llGetSubString( inString, a, b-1 ) ];
        else if ( elementType == 2 )
            outputList += [ (float)llGetSubString( inString, a, b-1 ) ];
        else if ( elementType == 3 )
            outputList += [ llGetSubString( inString, a, b-1 ) ];
        else if ( elementType == 4 )
            outputList += [ (key)llGetSubString( inString, a, b-1 ) ];
        else if ( elementType == 5 )
            outputList += [ (vector)llGetSubString( inString, a, b-1 ) ];
        else if ( elementType == 6 )
            outputList += [ (rotation)llGetSubString( inString, a, b-1 ) ];
    }
    
    return outputList;
}

default
{
    state_entry()
    {
        llListen(2, "Source", "", "");
    }
    listen(integer channel, string name, key id, string message)
    {
        llOwnerSay(message);
        list reversedL2S = string2List( message );
        llOwnerSay( "Reversed list = [" + llDumpList2String( reversedL2S, ", " ) + "]" );
    }
    touch_start( integer num )
    {
        list testList = [ "The", "red", "dog", 9, <1,2,3>, PI, llGetOwner() ];
        llOwnerSay( "testList = [" + llDumpList2String( testList, ", " ) + "]" );

        string testList2String = list2String( testList );
        llOwnerSay( "testList2String = \"" + testList2String + "\"" );
        
        list reversedL2S = string2List( testList2String );
        llOwnerSay( "Reversed list = [" + llDumpList2String( reversedL2S, ", " ) + "]" );
        llOwnerSay("<-break->");
    }
}

It should work now. -- January 25th, 2009 -- Ardy Lay
There is no comment on this page. [Display comments/form]