home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / tsw / TSW_3.4.0.exe / Apache2 / admin / utf7.inc < prev    next >
Encoding:
Text File  |  2003-03-16  |  9.1 KB  |  385 lines

  1. <?php
  2. //
  3. //
  4. //      utf7.inc - Routines to encode bytes to UTF7 and decode UTF7 strings
  5. //
  6. //      Copyright (C)  1999, 2002  Ziberex and Torben Rybner
  7. //
  8. //
  9. //      Version 1.01    2002-06-08      19:00
  10. //
  11. //      - Adapted for use in IlohaMail (modified UTF-7 decoding)
  12. //      - Converted from C to PHP4
  13. //
  14. //
  15. //      Version 1.00    1999-09-03      19:00
  16. //
  17. //      - Encodes bytes to UTF7 strings
  18. //          *OutString = '\0';
  19. //          StartBase64Encode();
  20. //          for (CP = InString;  *CP;  CP++)
  21. //            strcat(OutString, Base64Encode(*CP));
  22. //          strcat(OutString, StopBase64Encode());
  23. //      - Decodes Base64 strings to bytes
  24. //          StartBase64Decode();
  25. //          for (CP1 = InString, CP2 = OutString;  *CP1 && (*CP1 != '=');  CP1++)
  26. //            CP2 += Base64Decode(*CP1, CP2);
  27. //          StopBase64Decode();
  28. //
  29.  
  30. $BASE64LENGTH              =  60;
  31.  
  32. $BASE64DECODE_NO_DATA      = -1;
  33. $BASE64DECODE_EMPTY_DATA   = -2;
  34. $BASE64DECODE_INVALID_DATA = -3;
  35.  
  36.  
  37. //
  38. //
  39. //      Used for conversion to UTF7
  40. //
  41. $_ToUTF7 = array
  42. (
  43.  'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
  44.  'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
  45.  'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
  46.  'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', ','
  47. );
  48.  
  49. //
  50. //
  51. //      Used for conversion from UTF7
  52. //      (0x80 => Illegal, 0x40 => CR/LF)
  53. //
  54. $_FromUTF7 = array
  55. (
  56.   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,       // 00 - 07 - Ctrl -
  57.   0x80, 0x80, 0x40, 0x80, 0x80, 0x40, 0x80, 0x80,       // 08 - 0F - Ctrl -
  58.   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,       // 10 - 17 - Ctrl -
  59.   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,       // 18 - 1F - Ctrl -
  60.   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,       // 20 - 27  !"#$%&'
  61.   0x80, 0x80, 0x80, 0x3E, 0x3F, 0x80, 0x80, 0x3F,       // 28 - 2F ()*+,-./
  62.   0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,       // 30 - 37 01234567
  63.   0x3C, 0x3D, 0x80, 0x80, 0x80, 0x00, 0x80, 0x80,       // 38 - 3F 89:;<=>?
  64.   0x80, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,       // 40 - 47 @ABCDEFG
  65.   0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,       // 48 - 4F HIJKLMNO
  66.   0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,       // 50 - 57 PQRSTUVW
  67.   0x17, 0x18, 0x19, 0x80, 0x80, 0x80, 0x80, 0x80,       // 58 - 5F XYZ[\]^_
  68.   0x80, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,       // 60 - 67 `abcdefg
  69.   0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,       // 68 - 6F hijklmno
  70.   0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,       // 70 - 77 pqrstuvw
  71.   0x31, 0x32, 0x33, 0x80, 0x80, 0x80, 0x80, 0x80,       // 78 - 7F xyz{|}~
  72. );
  73.  
  74.  
  75. //
  76. //
  77. //      UTF7EncodeInit:
  78. //
  79. //      Start the encoding of bytes
  80. //
  81. function UTF7EncodeInit(&$Context)
  82. {
  83.   $Context[ "Data" ]  = "";
  84.   $Context[ "Count" ] = 0;
  85.   $Context[ "Pos" ]   = 0;
  86.   $Context[ "State" ] = 0;
  87. } // UTF7EncodeInit
  88.  
  89.  
  90. //
  91. //
  92. //      UTF7EncodeByte:
  93. //
  94. //      Encodes one byte to UTF7
  95. //
  96. function UTF7EncodeByte(&$Context, $Byte)
  97. {
  98.   global $_ToUTF7;
  99.  
  100.   $Byte = ord($Byte);
  101.   switch ($Context[ "State" ])
  102.   {
  103.     case 0:
  104.       // Convert into a byte
  105.       $Context[ "Data" ] = $_ToUTF7[ $Byte >> 2 ];
  106.       $Context[ "Pos" ]++;
  107.       // Save residue for next converted byte
  108.       $Context[ "Residue" ] = ($Byte & 0x03) << 4;
  109.       // This is the first byte in this line
  110.       $Context[ "Count" ] = 1;
  111.       // Next state is 1
  112.       $Context[ "State" ] = 1;
  113.       break;
  114.  
  115.     case 1:
  116.       // Convert into a byte
  117.       $Context[ "Data" ] .= $_ToUTF7[ $Context[ "Residue" ] | ($Byte >> 4) ];
  118.       $Context[ "Pos" ]++;
  119.       // Save residue for next converted byte
  120.       $Context[ "Residue" ] = ($Byte & 0x0F) << 2;
  121.       // Bumb byte counter
  122.       $Context[ "Count" ]++;
  123.       // Next state is 2
  124.       $Context[ "State" ] = 2;
  125.       break;
  126.  
  127.     case 2:
  128.       // Convert into a byte
  129.       $Context[ "Data" ] .= $_ToUTF7[ $Context[ "Residue" ] | ($Byte >> 6) ];
  130.       $Context[ "Pos" ]++;
  131.       // Residue fits precisely into the next byte
  132.       $Context[ "Data" ] .= $_ToUTF7[ $Byte & 0x3F ];
  133.       $Context[ "Pos" ]++;
  134.       // Bumb byte counter
  135.       $Context[ "Count" ]++;
  136.       // Next state is 3
  137.       $Context[ "State" ] = 3;
  138.       break;
  139.  
  140.     case 3:
  141.       // Convert into a byte
  142.       $Context[ "Data" ] .= $_ToUTF7[ $Byte >> 2 ];
  143.       $Context[ "Pos" ]++;
  144.       // Save residue for next converted byte
  145.       $Context[ "Residue" ] = ($Byte & 0x03) << 4;
  146.       // Bumb byte counter
  147.       $Context[ "Count" ]++;
  148.       // Next state is 1
  149.       $Context[ "State" ] = 1;
  150.       break;
  151.  
  152.     default:
  153.       // printf("Internal error in UTF7Encode: State is %d\n", $Context[ "State" ]);
  154.       // exit(1);
  155.       break;
  156.   }
  157. } // UTF7EncodeByte
  158.  
  159.  
  160. //
  161. //
  162. //      UTF7EncodeFinal:
  163. //
  164. //      Terminates the encoding of bytes
  165. //
  166. function UTF7EncodeFinal(&$Context)
  167. {
  168.   if ($Context[ "State" ] == 0)
  169.     return "";
  170.   if ($Context[ "State" ] != 3)
  171.     UTF7EncodeByte($Context, "\0");
  172.   return $Context[ "Data" ];
  173. } // UTF7EncodeFinal
  174.  
  175.  
  176. //
  177. //
  178. //      UTF7EncodeString
  179. //
  180. //      Encodes a string to modified UTF-7 format
  181. //
  182. function UTF7EncodeString($String)
  183. {
  184.   // Not during encoding, yet
  185.   $Encoding = false;
  186.   // Go through the string
  187.   for ($I = 0;  $I < strlen($String);  $I++)
  188.   {
  189.     $Ch = substr($String, $I, 1);
  190.     if (ord($Ch) > 0x7F)
  191.     {
  192.       if (! $Encoding)
  193.       {
  194.         $RetVal .= "&";
  195.         $Encoding = true;
  196.         // Initialise UTF7 context
  197.         UTF7EncodeInit($Context);
  198.       }
  199.       UTF7EncodeByte($Context, "\0");
  200.       UTF7EncodeByte($Context, $Ch);
  201.     }
  202.     elseif ($Ch == "&")
  203.     {
  204.       if (! $Encoding)
  205.       {
  206.         $RetVal .= "&";
  207.         $Encoding = true;
  208.         // Initialise UTF7 context
  209.         UTF7EncodeInit($Context);
  210.       }
  211.       else
  212.       {
  213.         UTF7EncodeByte($Context, "\0");
  214.         UTF7EncodeByte($Context, $Ch);
  215.       }
  216.     }
  217.     else
  218.     {
  219.       if ($Encoding)
  220.       {
  221.         $RetVal .= UTF7EncodeFinal($Context) . "-$Ch";
  222.         $Encoding = false;
  223.       }
  224.       else
  225.         $RetVal .= $Ch;
  226.     }
  227.   }
  228.   if ($Encoding)
  229.     $RetVal .= UTF7EncodeFinal($Context) . "-";
  230.   return $RetVal;
  231. } // UTF7EncodeString
  232.  
  233.  
  234. //
  235. //
  236. //      UTF7DecodeInit:
  237. //
  238. //      Start the decoding of bytes
  239. //
  240. function UTF7DecodeInit(&$Context)
  241. {
  242.   $Context[ "Data" ]  = "";
  243.   $Context[ "State" ] = 0;
  244.   $Context[ "Pos" ]   = 0;
  245. } // UTF7DecodeInit
  246.  
  247.  
  248. //
  249. //
  250. //      UTF7DecodeByte:
  251. //
  252. //      Decodes one character from UTF7
  253. //
  254. function UTF7DecodeByte(&$Context, $Byte)
  255. {
  256.   global $BASE64DECODE_INVALID_DATA;
  257.   global $_FromUTF7;
  258.  
  259.   // Restore bits
  260.   $Byte = $_FromUTF7[ ord($Byte) ];
  261.   // Ignore carriage returns and linefeeds
  262.   if ($Byte == 0x40)
  263.     return "";
  264.   // Invalid byte - Tell caller!
  265.   if ($Byte == 0x80)
  266.     $Context[ "Count" ] = $BASE64DECODE_INVALID_DATA;
  267.   switch ($Context[ "State" ])
  268.   {
  269.     case 0:
  270.       // Save residue
  271.       $Context[ "Residue" ] = $Byte;
  272.       // Initialise count
  273.       $Context[ "Count" ] = 0;
  274.       // Next state
  275.       $Context[ "State" ] = 1;
  276.       break;
  277.  
  278.     case 1:
  279.       // Store byte
  280.       $Context[ "Data" ] .= chr(($Context[ "Residue" ] << 2) | ($Byte >> 4));
  281.       $Context[ "Pos" ]++;
  282.       // Update count
  283.       $Context[ "Count" ]++;
  284.       // Save residue
  285.       $Context[ "Residue" ] = $Byte;
  286.       // Next state
  287.       $Context[ "State" ] = 2;
  288.       break;
  289.  
  290.     case 2:
  291.       // Store byte
  292.       $Context[ "Data" ] .= chr(($Context[ "Residue" ] << 4) | ($Byte >> 2));
  293.       $Context[ "Pos" ]++;
  294.       // Update count
  295.       $Context[ "Count" ]++;
  296.       // Save residue
  297.       $Context[ "Residue" ] = $Byte;
  298.       // Next state
  299.       $Context[ "State" ] = 3;
  300.       break;
  301.  
  302.     case 3:
  303.       // Store byte
  304.       $Context[ "Data" ] .= chr(($Context[ "Residue" ] << 6) | $Byte);
  305.       $Context[ "Pos" ]++;
  306.       // Update count
  307.       $Context[ "Count" ]++;
  308.       // Next state
  309.       $Context[ "State" ] = 4;
  310.       break;
  311.  
  312.     case 4:
  313.       // Save residue
  314.       $Context[ "Residue" ] = $Byte;
  315.       // Next state
  316.       $Context[ "State" ] = 1;
  317.       break;
  318.   }
  319. } // UTF7DecodeByte
  320.  
  321.  
  322. //
  323. //
  324. //      UTF7DecodeFinal:
  325. //
  326. //      Decodes one character from UTF7
  327. //
  328. function UTF7DecodeFinal(&$Context)
  329. {
  330.   // Buffer not empty - Return remainder!
  331.   if ($Context[ "Count" ])
  332.   {
  333.     $Context[ "Pos" ] = 0;
  334.     $Context[ "State" ] = 0;
  335.     return $Context[ "Data" ];
  336.   }
  337.   return "";
  338. } // UTF7DecodeFinal
  339.  
  340.  
  341. //
  342. //
  343. //      UTF7DecodeString
  344. //
  345. //      Converts a string encoded in modified UTF-7 encoding
  346. //      to ISO 8859-1.
  347. //      OBS: Works only for valid ISO 8859-1 characters in the
  348. //      encoded data
  349. //
  350. function UTF7DecodeString($String)
  351. {
  352.   $Decoding = false;
  353.   for ($I = 0;  $I < strlen($String);  $I++)
  354.   {
  355.     $Ch = substr($String, $I, 1);
  356.     if ($Decoding)
  357.     {
  358.       if ($Ch == "-")
  359.       {
  360.         $RetVal .= UTF7DecodeFinal($Context);
  361.         $Decoding = false;
  362.       }
  363.       else
  364.         UTF7DecodeByte($Context, $Ch);
  365.     }
  366.     elseif ($Ch == "&")
  367.     {
  368.       if (($I < strlen($String) - 1) && (substr($String, $I + 1, 1) == "-"))
  369.       {
  370.         $RetVal .= $Ch;
  371.         $I++;
  372.       }
  373.       else
  374.       {
  375.         UTF7DecodeInit($Context);
  376.         $Decoding = true;
  377.       }
  378.     }
  379.     else
  380.       $RetVal .= $Ch;
  381.   }
  382.   return str_replace("\0", "", $RetVal);
  383. } // UTF7DecodeString
  384. ?>
  385.