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