4 // utf7.inc - Routines to encode bytes to UTF7 and decode UTF7 strings
6 // Copyright (C) 1999, 2002 Ziberex and Torben Rybner
9 // Version 1.01 2002-06-08 19:00
11 // - Adapted for use in IlohaMail (modified UTF-7 decoding)
12 // - Converted from C to PHP4
15 // Version 1.00 1999-09-03 19:00
17 // - Encodes bytes to UTF7 strings
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();
32 $BASE64DECODE_NO_DATA = -1;
33 $BASE64DECODE_EMPTY_DATA = -2;
34 $BASE64DECODE_INVALID_DATA = -3;
39 // Used for conversion to UTF7
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', '+', ','
51 // Used for conversion from UTF7
52 // (0x80 => Illegal, 0x40 => CR/LF)
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{|}~
79 // Start the encoding of bytes
81 function UTF7EncodeInit(&$Context)
83 $Context[ "Data" ] = "";
84 $Context[ "Count" ] = 0;
85 $Context[ "Pos" ] = 0;
86 $Context[ "State" ] = 0;
94 // Encodes one byte to UTF7
96 function UTF7EncodeByte(&$Context, $Byte)
101 switch ($Context[ "State" ])
104 // Convert into a byte
105 $Context[ "Data" ] = $_ToUTF7[ $Byte >> 2 ];
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;
112 $Context[ "State" ] = 1;
116 // Convert into a byte
117 $Context[ "Data" ] .= $_ToUTF7[ $Context[ "Residue" ] | ($Byte >> 4) ];
119 // Save residue for next converted byte
120 $Context[ "Residue" ] = ($Byte & 0x0F) << 2;
122 $Context[ "Count" ]++;
124 $Context[ "State" ] = 2;
128 // Convert into a byte
129 $Context[ "Data" ] .= $_ToUTF7[ $Context[ "Residue" ] | ($Byte >> 6) ];
131 // Residue fits precisely into the next byte
132 $Context[ "Data" ] .= $_ToUTF7[ $Byte & 0x3F ];
135 $Context[ "Count" ]++;
137 $Context[ "State" ] = 3;
141 // Convert into a byte
142 $Context[ "Data" ] .= $_ToUTF7[ $Byte >> 2 ];
144 // Save residue for next converted byte
145 $Context[ "Residue" ] = ($Byte & 0x03) << 4;
147 $Context[ "Count" ]++;
149 $Context[ "State" ] = 1;
153 // printf("Internal error in UTF7Encode: State is %d\n", $Context[ "State" ]);
164 // Terminates the encoding of bytes
166 function UTF7EncodeFinal(&$Context)
168 if ($Context[ "State" ] == 0)
170 if ($Context[ "State" ] != 3)
171 UTF7EncodeByte($Context, "\0");
172 return $Context[ "Data" ];
180 // Encodes a string to modified UTF-7 format
182 function UTF7EncodeString($String)
184 // Not during encoding, yet
186 // Go through the string
187 for ($I = 0; $I < strlen($String); $I++)
189 $Ch = substr($String, $I, 1);
196 // Initialise UTF7 context
197 UTF7EncodeInit($Context);
199 UTF7EncodeByte($Context, "\0");
200 UTF7EncodeByte($Context, $Ch);
208 // Initialise UTF7 context
209 UTF7EncodeInit($Context);
213 UTF7EncodeByte($Context, "\0");
214 UTF7EncodeByte($Context, $Ch);
221 $RetVal .= UTF7EncodeFinal($Context) . "-$Ch";
229 $RetVal .= UTF7EncodeFinal($Context) . "-";
231 } // UTF7EncodeString
238 // Start the decoding of bytes
240 function UTF7DecodeInit(&$Context)
242 $Context[ "Data" ] = "";
243 $Context[ "State" ] = 0;
244 $Context[ "Pos" ] = 0;
252 // Decodes one character from UTF7
254 function UTF7DecodeByte(&$Context, $Byte)
256 global $BASE64DECODE_INVALID_DATA;
260 $Byte = $_FromUTF7[ ord($Byte) ];
261 // Ignore carriage returns and linefeeds
264 // Invalid byte - Tell caller!
266 $Context[ "Count" ] = $BASE64DECODE_INVALID_DATA;
267 switch ($Context[ "State" ])
271 $Context[ "Residue" ] = $Byte;
273 $Context[ "Count" ] = 0;
275 $Context[ "State" ] = 1;
280 $Context[ "Data" ] .= chr(($Context[ "Residue" ] << 2) | ($Byte >> 4));
283 $Context[ "Count" ]++;
285 $Context[ "Residue" ] = $Byte;
287 $Context[ "State" ] = 2;
292 $Context[ "Data" ] .= chr(($Context[ "Residue" ] << 4) | ($Byte >> 2));
295 $Context[ "Count" ]++;
297 $Context[ "Residue" ] = $Byte;
299 $Context[ "State" ] = 3;
304 $Context[ "Data" ] .= chr(($Context[ "Residue" ] << 6) | $Byte);
307 $Context[ "Count" ]++;
309 $Context[ "State" ] = 4;
314 $Context[ "Residue" ] = $Byte;
316 $Context[ "State" ] = 1;
326 // Decodes one character from UTF7
328 function UTF7DecodeFinal(&$Context)
330 // Buffer not empty - Return remainder!
331 if ($Context[ "Count" ])
333 $Context[ "Pos" ] = 0;
334 $Context[ "State" ] = 0;
335 return $Context[ "Data" ];
345 // Converts a string encoded in modified UTF-7 encoding
347 // OBS: Works only for valid ISO 8859-1 characters in the
350 function UTF7DecodeString($String)
353 for ($I = 0; $I < strlen($String); $I++)
355 $Ch = substr($String, $I, 1);
360 $RetVal .= UTF7DecodeFinal($Context);
364 UTF7DecodeByte($Context, $Ch);
368 if (($I < strlen($String) - 1) && (substr($String, $I + 1, 1) == "-"))
375 UTF7DecodeInit($Context);
382 return str_replace("\0", "", $RetVal);
383 } // UTF7DecodeString