Unescape

From Second Life Wiki
Revision as of 04:46, 24 April 2015 by Innula Zenovka (talk | contribs) (fixed broken lsl formatting)
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Takes a string and unescapes "\" style escape codes

Code Replace
\\ \
\" "
\s single space
\n new line
\t 4 spaces (tab)
\uxxxx xxxx is a 4 char hex string, of the unicode character 0000xxxx
\Uxxxxxxxx xxxxxxxx is am 8 char hex string, of the unicode character xxxxxxxx
\hXxxx... X is a hex character, it's value is the number of pairs of hex characters that follow it, xxx is a raw byte array of utf-8 characters, be sure they are valid characters
//===================================================//
//                 Combined Library                  //
//             "Jan  2 2008", "04:48:12"             //
//  Copyright (C) 2004-2007, Strife Onizuka (cc-by)  //
//    http://creativecommons.org/licenses/by/3.0/    //
//===================================================//
//{

string Unescape(string a)//Mono Safe, LSO Safe
{
    string  b = a;
    integer c = -1;
    integer d;
    integer e;
    integer f = 0; 
    string g;
    while(d = (-~(llSubStringIndex(b, "\\"))))    //"    //wiki highlighter bug
    {
        c += d;
        if(2 < (e = llSubStringIndex("uUhts\"q\\n",llGetSubString(b,d,d))))
            a = llInsertString(llDeleteSubString(a,c, (-~(c))), c, llGetSubString("     \"\"\\\n",e * (e != 3), e));
        else if(e==2)//hx[11,22,33,44,55,66,77,88,99,AA,BB,CC,DD,EE,FF]
        {
            if((f = llStringLength(b)) <= ((d) - ~(e = ((integer)("0x"+llGetSubString(b,(-~(d)),(-~(d)))) << 1))))
            {
                e = (f - d) & -2;
                b += "0";//a pad may be needed.
            }
            g = "";//flush the buffer.
            if((f = e))//this may look like a mistake, it's not
            {
                do
                    g = "%"+llGetSubString(b,d + e, ((d) - ~(e))) + g;
                while((e -= 2));//(e-=2) > 0, e should always be even
            }
            a = llInsertString(llDeleteSubString(a,c, 2 + f + c),c, g = llUnescapeURL(g));
            c += (~-(llStringLength(g)));//add to c so we don't accidentily unescape result
        }
        else if(~e)// \uXXXX or  \UXXXXXXXX
        {
            a = llDeleteSubString(a, c, ((e = 4 << e) - ~(c)));
            if(0 < (e = ((integer)("0x"+(llGetSubString(b, (-~(d)), d + e))))))
            {
                f = llCeil((llLog(e) / 0.69314718055994530941723212145818));
                f = (e >= 0x80) * ((f) + ~((((1 << f) - e) > 0))) / 5;//adjust
                g = "%" + byte2hex((e >> (6 * f)) | ((0x3F80 >> f) << !f));
                while (f)
                    g += "%" + byte2hex((((e >> (6 * (f = ~-f))) | 0x80) & 0xBF));
                a = llInsertString(a, c, llUnescapeURL(g));
            }
        }
        b = llDeleteSubString(a,0,c);
    }
    return a;
}

string byte2hex(integer x)//Mono Safe, LSO Safe
{//Helper function for use with unicode characters.
    integer y = (x >> 4) & 0xF;
    return llGetSubString(hexc, y, y) + llGetSubString(hexc, x & 0xF, x & 0xF);
}//This function would benefit greatly from the DUP opcode, it would remove 19 bytes.

string hexc="0123456789ABCDEF";

//}</lsl>

<lsl>//Testbed
default
{
    state_entry()
    {
        llOwnerSay((string)llGetFreeMemory());
        string a = "-\\h3414243\\h3444546\\\"\\uFFFD";
        string d = Unescape(a);
        llOwnerSay(llList2CSV([a, d]));
    }
}