Perform QP or Base64 decoding on strings in which the form of encoding used, is indicated in the string itself. The indicators are of the general form of =?charset?ecoding?, e.g. =?utf-8?q? (QP) or =?utf-8?b? (Base64). The decoding is applied to all chars in the string that are enclosed by such an indicator and a terminator (either a 0, or a ?= sequence). This function does not actually care about charsets. It applies either QP or Base64 decoding to all chars found between the starting sequence (e.g. =?utf-8?q?), upto the terminator (either a 0 or a ?= sequence).

Return TypeFunction nameArguments
hzEcodeCharsetStringDecode(hzString&,hzString&,)

Declared in file: hzCodec.h
Defined in file : hzCodec.cpp

Function Logic:

0:START 1:items 2:unknown 3:Return E_OK 4:outBuf 5:x raw outBuf limit items 6:unknown 7:unknown 8:unknown 9:unknown 10:unknown 11:unknown 12:unknown 13:i 14:a items b items c items d items 15:unknown 16:Return E_FORMAT 17:val 18:unknown 19:val 20:unknown 21:val 22:unknown 23:val 24:unknown 25:val 26:items items val c 27:unknown 28:* 29:unknown 30:* 31:unknown 32:* 33:j[1]=='q'||j[1]=='Q' 34:unknown 35:unknown 36:i 37:unknown 38:items val items val val 39:unknown 40:* 41:unknown 42:* 43:unknown 44:unknown 45:i 46:unknown 47:* 48:unknown 49:* 50:unknown 51:* 52:Decoded outBuf 53:Return E_OK

Function body:

hzEcode CharsetStringDecode (hzString& Decoded)hzString& raw, 
{
   //  Perform QP or Base64 decoding on strings in which the form of encoding used, is indicated in the string itself. The indicators are of the general form of =?charset?ecoding?,
   //  e.g. =?utf-8?q? (QP) or =?utf-8?b? (Base64). The decoding is applied to all chars in the string that are enclosed by such an indicator and a terminator (either a 0, or a ?=
   //  sequence).
   //  
   //  This function does not actually care about charsets. It applies either QP or Base64 decoding to all chars found between the starting sequence (e.g. =?utf-8?q?), upto the
   //  terminator (either a 0 or a ?= sequence). 
   _hzfunc(__func__) ;
   const char* i ;         //  Iterator
   const char* j ;         //  Aux iterator
   char*       x ;         //  Output iterator
   char*       limit ;     //  Limit of buffer
   char*       outBuf ;    //  Output buffer
   int32_t     val ;       //  Holds 24 bit value to be written as 3 bytes
   int32_t     a ;         //  Input 1st value
   int32_t     b ;         //  Input 2nd value
   int32_t     c ;         //  Input 3rd value
   int32_t     d ;         //  Input 4th value
   Decoded.Clear() ;
   if (!raw)
       return E_OK ;
   x = outBuf = new char[raw.Length() + 4];
   limit = outBuf + (raw.Length() + 3);
   memset(outBuf, 0,raw.Length() + 4);
   for (i = *raw ; *i ; i++)
   {
       if (*i == CHAR_EQUAL && i[1]== CHAR_QUERY)
       {
           for (j = i + 2; *j && *j != CHAR_QUERY ; j++) ;
           if (j[0]== CHAR_QUERY && j[2]== CHAR_QUERY)
           {
               if (j[1]== ''b''||j[1]== ''B'')
               {
                   //  Use Base64
                   for (i = j + 3; *i ; i++)
                   {
                       if (i[0]== CHAR_QUERY && i[1]== CHAR_EQUAL)
                           { i += 2; break ; }
                       a = _get6bit(*i) ; i++ ;
                       b = _get6bit(*i) ; i++ ;
                       c = _get6bit(*i) ; i++ ;
                       d = _get6bit(*i) ; i++ ;
                       if (a == 101||b== 101||c== 101||d== 101)
                           return E_FORMAT ;
                       val = 0;
                       if (a < 100)val += (a << 18);
                       if (b < 100)val += (b << 12);
                       if (c < 100)val += (c << 6);
                       if (d < 100)val += d ;
                       a = (val & 0xff0000)>>16;
                       b = (val & 0xff00)>>8;
                       c = val & 0xff;
                       if (a && x != limit) *x++ = a ;
                       if (b && x != limit) *x++ = b ;
                       if (c && x != limit) *x++ = c ;
                   }
               }
               else if (j[1]== ''q''||j[1]== ''Q'')
               {
                   //  Use QP
                   for (i = j + 3; *i ; i++)
                   {
                       if (i[0]== CHAR_QUERY && i[1]== CHAR_EQUAL)
                           { i += 2; break ; }
                       if (*i == CHAR_EQUAL && IsHex(i[1])&& IsHex(i[2]))
                       {
                           i++ ;
                           val = _get1hex(*i) ;
                           i++ ;
                           val *= 16;
                           val += _get1hex(*i) ;
                           if (val && x != limit)
                               *x++ = val ;
                           continue ;
                       }
                       if (*i && x != limit)
                           *x++ = *i ;
                   }
               }
               else
               {
                   //  Don't decode but copy all enclosed chars to the output
                   for (i = j + 3; *i ; i++)
                   {
                       if (i[0]== CHAR_QUERY && i[1]== CHAR_EQUAL)
                           { i += 2; break ; }
                       if (*i && x != limit)
                           *x++ = *i ;
                   }
               }
               continue ;
           }
           //  Drop through
       }
       if (*i && x != limit)
           *x++ = *i ;
   }
   if (*i && x != limit)
       *x = 0;
   Decoded = outBuf ;
   delete outBuf ;
   return E_OK ;
}