Unescape

From Second Life Wiki
Revision as of 10:31, 20 September 2013 by Strife Onizuka (talk | contribs)
Jump to navigation Jump to search

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

<lsl>//===================================================// // 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]));
   }

}</lsl>