User talk:Becky Pippen/Text Storage
		
		
		
		
		
		Jump to navigation
		Jump to search
		
		
	
Memory optimized versions
Someone recently asked for a more memory efficient version so I hacked one together. It could be made faster by using two loops, and pealing off characters in bigger groups more infrequently.
<lsl>string encode15BitsToChar(integer num) {
   // Check the incoming range
   if (num < 0 || num >= 0x8000) {
       // illegal input -- do whatever is appropriate
       return "�";
   }
   // Bias the incoming numeric value by 0x1000 to avoid illegal Unicode codes:
   num += 0x1000;
   // construct UTF-8 layout:
   num = 0xE0808000 | (num << 12) | ((num << 10) & 0x3f0000) | ((num << 8) & 0x3f00);
   // Convert the UTF-8 into a 16-bit Unicode character:
   return llGetSubString(llBase64ToString(llIntegerToBase64(num)), 0, 0);
}
integer decodeCharTo15Bits(string ch) {
   integer val = llBase64ToInteger(llStringToBase64(ch));
   if((val & 0xE0000000) ^ 0xE0000000)
       return -1; //The character is not 3 bytes.
   return  ((val & 0x0f000000) >> 12) +
           ((val & 0x003f0000) >> 10) +
           ((val & 0x00003f00) >>  8) - 0x1000;
}
string compressAscii(string s) {
integer len = llStringLength(s);
   // Append a space if needed to make s an even number of chars
   if (len & 1) {
       s += " ";
   }
   string encodedChars = "";
   while( (len -= 2) > -2 ) {
       string chars = llGetSubString(s, 0, 1);
       s = llGetSubString(s, 2, 0x7ffffff0);
       encodedChars += encode15BitsToChar(
           charToUnicodeIdNumber(chars) << 7 |
           charToUnicodeIdNumber(llGetSubString(chars, 1, 1)));
   }
return encodedChars;
}
string uncompressAscii(string s) {
string result = "";
   integer len = llStringLength(s);
   while ( 0 <= --len ) {
       integer cInt15 = decodeCharTo15Bits(llGetSubString(s, 0, 0));
       s = llGetSubString(s, 1, 0x7ffffff0);
       result += llGetSubString(llBase64ToString(llIntegerToBase64(
                           ((cInt15 << 17) & 0x7f000000) | 
                           ((cInt15 << 16) & 0x007f0000)
                   )), 0, 1);
   }
return result;
}</lsl>