~ubuntu-branches/ubuntu/maverick/ilohamail/maverick

« back to all changes in this revision

Viewing changes to IlohaMail/include/utf7.inc

  • Committer: Bazaar Package Importer
  • Author(s): Joerg Jaspert
  • Date: 2004-02-04 13:44:37 UTC
  • Revision ID: james.westby@ubuntu.com-20040204134437-kz8j3ui2qa7oq8z2
Tags: upstream-0.8.12
ImportĀ upstreamĀ versionĀ 0.8.12

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
?>