~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/security/nss/lib/util/utf8.c

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * The contents of this file are subject to the Mozilla Public
 
3
 * License Version 1.1 (the "License"); you may not use this file
 
4
 * except in compliance with the License. You may obtain a copy of
 
5
 * the License at http://www.mozilla.org/MPL/
 
6
 * 
 
7
 * Software distributed under the License is distributed on an "AS
 
8
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 
9
 * implied. See the License for the specific language governing
 
10
 * rights and limitations under the License.
 
11
 * 
 
12
 * The Original Code is the Netscape security libraries.
 
13
 * 
 
14
 * The Initial Developer of the Original Code is Netscape
 
15
 * Communications Corporation.  Portions created by Netscape are 
 
16
 * Copyright (C) 1994-2000 Netscape Communications Corporation.  All
 
17
 * Rights Reserved.
 
18
 * 
 
19
 * Contributor(s):
 
20
 *  John Gardiner Myers <jgmyers@speakeasy.net>
 
21
 * 
 
22
 * Alternatively, the contents of this file may be used under the
 
23
 * terms of the GNU General Public License Version 2 or later (the
 
24
 * "GPL"), in which case the provisions of the GPL are applicable 
 
25
 * instead of those above.  If you wish to allow use of your 
 
26
 * version of this file only under the terms of the GPL and not to
 
27
 * allow others to use your version of this file under the MPL,
 
28
 * indicate your decision by deleting the provisions above and
 
29
 * replace them with the notice and other provisions required by
 
30
 * the GPL.  If you do not delete the provisions above, a recipient
 
31
 * may use your version of this file under either the MPL or the
 
32
 * GPL.
 
33
 */
 
34
 
 
35
#ifdef DEBUG
 
36
static const char CVS_ID[] = "@(#) $RCSfile: utf8.c,v $ $Revision: 1.7 $ $Date: 2004/01/20 19:57:17 $ $Name: FIREFOX_1_0_RELEASE $";
 
37
#endif /* DEBUG */
 
38
 
 
39
#include "seccomon.h"
 
40
#include "secport.h"
 
41
 
 
42
/*
 
43
 * Define this if you want to support UTF-16 in UCS-2
 
44
 */
 
45
#define UTF16
 
46
 
 
47
/*
 
48
 * From RFC 2044:
 
49
 *
 
50
 * UCS-4 range (hex.)           UTF-8 octet sequence (binary)
 
51
 * 0000 0000-0000 007F   0xxxxxxx
 
52
 * 0000 0080-0000 07FF   110xxxxx 10xxxxxx
 
53
 * 0000 0800-0000 FFFF   1110xxxx 10xxxxxx 10xxxxxx
 
54
 * 0001 0000-001F FFFF   11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
 
55
 * 0020 0000-03FF FFFF   111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
 
56
 * 0400 0000-7FFF FFFF   1111110x 10xxxxxx ... 10xxxxxx
 
57
 */  
 
58
 
 
59
/*
 
60
 * From http://www.imc.org/draft-hoffman-utf16
 
61
 *
 
62
 * For U on [0x00010000,0x0010FFFF]:  Let U' = U - 0x00010000
 
63
 *
 
64
 * U' = yyyyyyyyyyxxxxxxxxxx
 
65
 * W1 = 110110yyyyyyyyyy
 
66
 * W2 = 110111xxxxxxxxxx
 
67
 */
 
68
 
 
69
/*
 
70
 * This code is assuming NETWORK BYTE ORDER for the 16- and 32-bit
 
71
 * character values.  If you wish to use this code for working with
 
72
 * host byte order values, define the following:
 
73
 *
 
74
 * #if IS_BIG_ENDIAN
 
75
 * #define L_0 0
 
76
 * #define L_1 1
 
77
 * #define L_2 2
 
78
 * #define L_3 3
 
79
 * #define H_0 0
 
80
 * #define H_1 1
 
81
 * #else / * not everyone has elif * /
 
82
 * #if IS_LITTLE_ENDIAN
 
83
 * #define L_0 3
 
84
 * #define L_1 2
 
85
 * #define L_2 1
 
86
 * #define L_3 0
 
87
 * #define H_0 1
 
88
 * #define H_1 0
 
89
 * #else
 
90
 * #error "PDP and NUXI support deferred"
 
91
 * #endif / * IS_LITTLE_ENDIAN * /
 
92
 * #endif / * IS_BIG_ENDIAN * /
 
93
 */
 
94
 
 
95
#define L_0 0
 
96
#define L_1 1
 
97
#define L_2 2
 
98
#define L_3 3
 
99
#define H_0 0
 
100
#define H_1 1
 
101
 
 
102
PR_IMPLEMENT(PRBool)
 
103
sec_port_ucs4_utf8_conversion_function
 
104
(
 
105
  PRBool toUnicode,
 
106
  unsigned char *inBuf,
 
107
  unsigned int inBufLen,
 
108
  unsigned char *outBuf,
 
109
  unsigned int maxOutBufLen,
 
110
  unsigned int *outBufLen
 
111
)
 
112
{
 
113
#ifndef TEST_UTF8
 
114
  PORT_Assert((unsigned int *)NULL != outBufLen);
 
115
#endif /* TEST_UTF8 */
 
116
 
 
117
  if( toUnicode ) {
 
118
    unsigned int i, len = 0;
 
119
 
 
120
    for( i = 0; i < inBufLen; ) {
 
121
      if( (inBuf[i] & 0x80) == 0x00 ) i += 1;
 
122
      else if( (inBuf[i] & 0xE0) == 0xC0 ) i += 2;
 
123
      else if( (inBuf[i] & 0xF0) == 0xE0 ) i += 3;
 
124
      else if( (inBuf[i] & 0xF8) == 0xF0 ) i += 4;
 
125
      else if( (inBuf[i] & 0xFC) == 0xF8 ) i += 5;
 
126
      else if( (inBuf[i] & 0xFE) == 0xFC ) i += 6;
 
127
      else return PR_FALSE;
 
128
 
 
129
      len += 4;
 
130
    }
 
131
 
 
132
    if( len > maxOutBufLen ) {
 
133
      *outBufLen = len;
 
134
      return PR_FALSE;
 
135
    }
 
136
 
 
137
    len = 0;
 
138
 
 
139
    for( i = 0; i < inBufLen; ) {
 
140
      if( (inBuf[i] & 0x80) == 0x00 ) {
 
141
        /* 0000 0000-0000 007F <- 0xxxxxx */
 
142
        /* 0abcdefg -> 
 
143
           00000000 00000000 00000000 0abcdefg */
 
144
 
 
145
        outBuf[len+L_0] = 0x00;
 
146
        outBuf[len+L_1] = 0x00;
 
147
        outBuf[len+L_2] = 0x00;
 
148
        outBuf[len+L_3] = inBuf[i+0] & 0x7F;
 
149
 
 
150
        i += 1;
 
151
      } else if( (inBuf[i] & 0xE0) == 0xC0 ) {
 
152
 
 
153
        if( (inBuf[i+1] & 0xC0) != 0x80 ) return PR_FALSE;
 
154
 
 
155
        /* 0000 0080-0000 07FF <- 110xxxxx 10xxxxxx */
 
156
        /* 110abcde 10fghijk ->
 
157
           00000000 00000000 00000abc defghijk */
 
158
 
 
159
        outBuf[len+L_0] = 0x00;
 
160
        outBuf[len+L_1] = 0x00;
 
161
        outBuf[len+L_2] = ((inBuf[i+0] & 0x1C) >> 2);
 
162
        outBuf[len+L_3] = ((inBuf[i+0] & 0x03) << 6) | ((inBuf[i+1] & 0x3F) >> 0);
 
163
 
 
164
        i += 2;
 
165
      } else if( (inBuf[i] & 0xF0) == 0xE0 ) {
 
166
 
 
167
        if( (inBuf[i+1] & 0xC0) != 0x80 ) return PR_FALSE;
 
168
        if( (inBuf[i+2] & 0xC0) != 0x80 ) return PR_FALSE;
 
169
 
 
170
        /* 0000 0800-0000 FFFF <- 1110xxxx 10xxxxxx 10xxxxxx */
 
171
        /* 1110abcd 10efghij 10klmnop ->
 
172
           00000000 00000000 abcdefgh ijklmnop */
 
173
 
 
174
        outBuf[len+L_0] = 0x00;
 
175
        outBuf[len+L_1] = 0x00;
 
176
        outBuf[len+L_2] = ((inBuf[i+0] & 0x0F) << 4) | ((inBuf[i+1] & 0x3C) >> 2);
 
177
        outBuf[len+L_3] = ((inBuf[i+1] & 0x03) << 6) | ((inBuf[i+2] & 0x3F) >> 0);
 
178
 
 
179
        i += 3;
 
180
      } else if( (inBuf[i] & 0xF8) == 0xF0 ) {
 
181
 
 
182
        if( (inBuf[i+1] & 0xC0) != 0x80 ) return PR_FALSE;
 
183
        if( (inBuf[i+2] & 0xC0) != 0x80 ) return PR_FALSE;
 
184
        if( (inBuf[i+3] & 0xC0) != 0x80 ) return PR_FALSE;
 
185
 
 
186
        /* 0001 0000-001F FFFF <- 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
 
187
        /* 11110abc 10defghi 10jklmno 10pqrstu -> 
 
188
           00000000 000abcde fghijklm nopqrstu */
 
189
           
 
190
        outBuf[len+L_0] = 0x00;
 
191
        outBuf[len+L_1] = ((inBuf[i+0] & 0x07) << 2) | ((inBuf[i+1] & 0x30) >> 4);
 
192
        outBuf[len+L_2] = ((inBuf[i+1] & 0x0F) << 4) | ((inBuf[i+2] & 0x3C) >> 2);
 
193
        outBuf[len+L_3] = ((inBuf[i+2] & 0x03) << 6) | ((inBuf[i+3] & 0x3F) >> 0);
 
194
 
 
195
        i += 4;
 
196
      } else if( (inBuf[i] & 0xFC) == 0xF8 ) {
 
197
 
 
198
        if( (inBuf[i+1] & 0xC0) != 0x80 ) return PR_FALSE;
 
199
        if( (inBuf[i+2] & 0xC0) != 0x80 ) return PR_FALSE;
 
200
        if( (inBuf[i+3] & 0xC0) != 0x80 ) return PR_FALSE;
 
201
        if( (inBuf[i+4] & 0xC0) != 0x80 ) return PR_FALSE;
 
202
 
 
203
        /* 0020 0000-03FF FFFF <- 111110xx 10xxxxxx ... 10xxxxxx */
 
204
        /* 111110ab 10cdefgh 10ijklmn 10opqrst 10uvwxyz -> 
 
205
           000000ab cdefghij klmnopqr stuvwxyz */
 
206
 
 
207
        outBuf[len+L_0] = inBuf[i+0] & 0x03;
 
208
        outBuf[len+L_1] = ((inBuf[i+1] & 0x3F) << 2) | ((inBuf[i+2] & 0x30) >> 4);
 
209
        outBuf[len+L_2] = ((inBuf[i+2] & 0x0F) << 4) | ((inBuf[i+3] & 0x3C) >> 2);
 
210
        outBuf[len+L_3] = ((inBuf[i+3] & 0x03) << 6) | ((inBuf[i+4] & 0x3F) >> 0);
 
211
 
 
212
        i += 5;
 
213
      } else /* if( (inBuf[i] & 0xFE) == 0xFC ) */ {
 
214
 
 
215
        if( (inBuf[i+1] & 0xC0) != 0x80 ) return PR_FALSE;
 
216
        if( (inBuf[i+2] & 0xC0) != 0x80 ) return PR_FALSE;
 
217
        if( (inBuf[i+3] & 0xC0) != 0x80 ) return PR_FALSE;
 
218
        if( (inBuf[i+4] & 0xC0) != 0x80 ) return PR_FALSE;
 
219
        if( (inBuf[i+5] & 0xC0) != 0x80 ) return PR_FALSE;
 
220
 
 
221
        /* 0400 0000-7FFF FFFF <- 1111110x 10xxxxxx ... 10xxxxxx */
 
222
        /* 1111110a 10bcdefg 10hijklm 10nopqrs 10tuvwxy 10zABCDE -> 
 
223
           0abcdefg hijklmno pqrstuvw xyzABCDE */
 
224
 
 
225
        outBuf[len+L_0] = ((inBuf[i+0] & 0x01) << 6) | ((inBuf[i+1] & 0x3F) >> 0);
 
226
        outBuf[len+L_1] = ((inBuf[i+2] & 0x3F) << 2) | ((inBuf[i+3] & 0x30) >> 4);
 
227
        outBuf[len+L_2] = ((inBuf[i+3] & 0x0F) << 4) | ((inBuf[i+4] & 0x3C) >> 2);
 
228
        outBuf[len+L_3] = ((inBuf[i+4] & 0x03) << 6) | ((inBuf[i+5] & 0x3F) >> 0);
 
229
 
 
230
        i += 6;
 
231
      }
 
232
 
 
233
      len += 4;
 
234
    }
 
235
 
 
236
    *outBufLen = len;
 
237
    return PR_TRUE;
 
238
  } else {
 
239
    unsigned int i, len = 0;
 
240
    PORT_Assert((inBufLen % 4) == 0);
 
241
    if ((inBufLen % 4) != 0) {
 
242
      *outBufLen = 0;
 
243
      return PR_FALSE;
 
244
    }
 
245
 
 
246
    for( i = 0; i < inBufLen; i += 4 ) {
 
247
      if( inBuf[i+L_0] >= 0x04 ) len += 6;
 
248
      else if( (inBuf[i+L_0] > 0x00) || (inBuf[i+L_1] >= 0x20) ) len += 5;
 
249
      else if( inBuf[i+L_1] >= 0x01 ) len += 4;
 
250
      else if( inBuf[i+L_2] >= 0x08 ) len += 3;
 
251
      else if( (inBuf[i+L_2] > 0x00) || (inBuf[i+L_3] >= 0x80) ) len += 2;
 
252
      else len += 1;
 
253
    }
 
254
 
 
255
    if( len > maxOutBufLen ) {
 
256
      *outBufLen = len;
 
257
      return PR_FALSE;
 
258
    }
 
259
 
 
260
    len = 0;
 
261
 
 
262
    for( i = 0; i < inBufLen; i += 4 ) {
 
263
      if( inBuf[i+L_0] >= 0x04 ) {
 
264
        /* 0400 0000-7FFF FFFF -> 1111110x 10xxxxxx ... 10xxxxxx */
 
265
        /* 0abcdefg hijklmno pqrstuvw xyzABCDE ->
 
266
           1111110a 10bcdefg 10hijklm 10nopqrs 10tuvwxy 10zABCDE */
 
267
 
 
268
        outBuf[len+0] = 0xFC | ((inBuf[i+L_0] & 0x40) >> 6);
 
269
        outBuf[len+1] = 0x80 | ((inBuf[i+L_0] & 0x3F) >> 0);
 
270
        outBuf[len+2] = 0x80 | ((inBuf[i+L_1] & 0xFC) >> 2);
 
271
        outBuf[len+3] = 0x80 | ((inBuf[i+L_1] & 0x03) << 4)
 
272
                             | ((inBuf[i+L_2] & 0xF0) >> 4);
 
273
        outBuf[len+4] = 0x80 | ((inBuf[i+L_2] & 0x0F) << 2)
 
274
                             | ((inBuf[i+L_3] & 0xC0) >> 6);
 
275
        outBuf[len+5] = 0x80 | ((inBuf[i+L_3] & 0x3F) >> 0);
 
276
 
 
277
        len += 6;
 
278
      } else if( (inBuf[i+L_0] > 0x00) || (inBuf[i+L_1] >= 0x20) ) {
 
279
        /* 0020 0000-03FF FFFF -> 111110xx 10xxxxxx ... 10xxxxxx */
 
280
        /* 000000ab cdefghij klmnopqr stuvwxyz ->
 
281
           111110ab 10cdefgh 10ijklmn 10opqrst 10uvwxyz */
 
282
 
 
283
        outBuf[len+0] = 0xF8 | ((inBuf[i+L_0] & 0x03) >> 0);
 
284
        outBuf[len+1] = 0x80 | ((inBuf[i+L_1] & 0xFC) >> 2);
 
285
        outBuf[len+2] = 0x80 | ((inBuf[i+L_1] & 0x03) << 4)
 
286
                             | ((inBuf[i+L_2] & 0xF0) >> 4);
 
287
        outBuf[len+3] = 0x80 | ((inBuf[i+L_2] & 0x0F) << 2)
 
288
                             | ((inBuf[i+L_3] & 0xC0) >> 6);
 
289
        outBuf[len+4] = 0x80 | ((inBuf[i+L_3] & 0x3F) >> 0);
 
290
 
 
291
        len += 5;
 
292
      } else if( inBuf[i+L_1] >= 0x01 ) {
 
293
        /* 0001 0000-001F FFFF -> 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
 
294
        /* 00000000 000abcde fghijklm nopqrstu ->
 
295
           11110abc 10defghi 10jklmno 10pqrstu */
 
296
 
 
297
        outBuf[len+0] = 0xF0 | ((inBuf[i+L_1] & 0x1C) >> 2);
 
298
        outBuf[len+1] = 0x80 | ((inBuf[i+L_1] & 0x03) << 4)
 
299
                             | ((inBuf[i+L_2] & 0xF0) >> 4);
 
300
        outBuf[len+2] = 0x80 | ((inBuf[i+L_2] & 0x0F) << 2)
 
301
                             | ((inBuf[i+L_3] & 0xC0) >> 6);
 
302
        outBuf[len+3] = 0x80 | ((inBuf[i+L_3] & 0x3F) >> 0);
 
303
 
 
304
        len += 4;
 
305
      } else if( inBuf[i+L_2] >= 0x08 ) {
 
306
        /* 0000 0800-0000 FFFF -> 1110xxxx 10xxxxxx 10xxxxxx */
 
307
        /* 00000000 00000000 abcdefgh ijklmnop ->
 
308
           1110abcd 10efghij 10klmnop */
 
309
 
 
310
        outBuf[len+0] = 0xE0 | ((inBuf[i+L_2] & 0xF0) >> 4);
 
311
        outBuf[len+1] = 0x80 | ((inBuf[i+L_2] & 0x0F) << 2)
 
312
                             | ((inBuf[i+L_3] & 0xC0) >> 6);
 
313
        outBuf[len+2] = 0x80 | ((inBuf[i+L_3] & 0x3F) >> 0);
 
314
 
 
315
        len += 3;
 
316
      } else if( (inBuf[i+L_2] > 0x00) || (inBuf[i+L_3] >= 0x80) ) {
 
317
        /* 0000 0080-0000 07FF -> 110xxxxx 10xxxxxx */
 
318
        /* 00000000 00000000 00000abc defghijk ->
 
319
           110abcde 10fghijk */
 
320
 
 
321
        outBuf[len+0] = 0xC0 | ((inBuf[i+L_2] & 0x07) << 2)
 
322
                             | ((inBuf[i+L_3] & 0xC0) >> 6);
 
323
        outBuf[len+1] = 0x80 | ((inBuf[i+L_3] & 0x3F) >> 0);
 
324
 
 
325
        len += 2;
 
326
      } else {
 
327
        /* 0000 0000-0000 007F -> 0xxxxxx */
 
328
        /* 00000000 00000000 00000000 0abcdefg ->
 
329
           0abcdefg */
 
330
 
 
331
        outBuf[len+0] = (inBuf[i+L_3] & 0x7F);
 
332
 
 
333
        len += 1;
 
334
      }
 
335
    }
 
336
                            
 
337
    *outBufLen = len;
 
338
    return PR_TRUE;
 
339
  }
 
340
}
 
341
 
 
342
PR_IMPLEMENT(PRBool)
 
343
sec_port_ucs2_utf8_conversion_function
 
344
(
 
345
  PRBool toUnicode,
 
346
  unsigned char *inBuf,
 
347
  unsigned int inBufLen,
 
348
  unsigned char *outBuf,
 
349
  unsigned int maxOutBufLen,
 
350
  unsigned int *outBufLen
 
351
)
 
352
{
 
353
#ifndef TEST_UTF8
 
354
  PORT_Assert((unsigned int *)NULL != outBufLen);
 
355
#endif /* TEST_UTF8 */
 
356
 
 
357
  if( toUnicode ) {
 
358
    unsigned int i, len = 0;
 
359
 
 
360
    for( i = 0; i < inBufLen; ) {
 
361
      if( (inBuf[i] & 0x80) == 0x00 ) {
 
362
        i += 1;
 
363
        len += 2;
 
364
      } else if( (inBuf[i] & 0xE0) == 0xC0 ) {
 
365
        i += 2;
 
366
        len += 2;
 
367
      } else if( (inBuf[i] & 0xF0) == 0xE0 ) {
 
368
        i += 3;
 
369
        len += 2;
 
370
#ifdef UTF16
 
371
      } else if( (inBuf[i] & 0xF8) == 0xF0 ) { 
 
372
        i += 4;
 
373
        len += 4;
 
374
 
 
375
        if( (inBuf[i] & 0x04) && 
 
376
            ((inBuf[i] & 0x03) || (inBuf[i+1] & 0x30)) ) {
 
377
          /* Not representable as UTF16 */
 
378
          return PR_FALSE;
 
379
        }
 
380
 
 
381
#endif /* UTF16 */
 
382
      } else return PR_FALSE;
 
383
    }
 
384
 
 
385
    if( len > maxOutBufLen ) {
 
386
      *outBufLen = len;
 
387
      return PR_FALSE;
 
388
    }
 
389
 
 
390
    len = 0;
 
391
 
 
392
    for( i = 0; i < inBufLen; ) {
 
393
      if( (inBuf[i] & 0x80) == 0x00 ) {
 
394
        /* 0000-007F <- 0xxxxxx */
 
395
        /* 0abcdefg -> 00000000 0abcdefg */
 
396
 
 
397
        outBuf[len+H_0] = 0x00;
 
398
        outBuf[len+H_1] = inBuf[i+0] & 0x7F;
 
399
 
 
400
        i += 1;
 
401
        len += 2;
 
402
      } else if( (inBuf[i] & 0xE0) == 0xC0 ) {
 
403
 
 
404
        if( (inBuf[i+1] & 0xC0) != 0x80 ) return PR_FALSE;
 
405
 
 
406
        /* 0080-07FF <- 110xxxxx 10xxxxxx */
 
407
        /* 110abcde 10fghijk -> 00000abc defghijk */
 
408
 
 
409
        outBuf[len+H_0] = ((inBuf[i+0] & 0x1C) >> 2);
 
410
        outBuf[len+H_1] = ((inBuf[i+0] & 0x03) << 6) | ((inBuf[i+1] & 0x3F) >> 0);
 
411
 
 
412
        i += 2;
 
413
        len += 2;
 
414
      } else if( (inBuf[i] & 0xF0) == 0xE0 ) {
 
415
 
 
416
        if( (inBuf[i+1] & 0xC0) != 0x80 ) return PR_FALSE;
 
417
        if( (inBuf[i+2] & 0xC0) != 0x80 ) return PR_FALSE;
 
418
 
 
419
        /* 0800-FFFF <- 1110xxxx 10xxxxxx 10xxxxxx */
 
420
        /* 1110abcd 10efghij 10klmnop -> abcdefgh ijklmnop */
 
421
 
 
422
        outBuf[len+H_0] = ((inBuf[i+0] & 0x0F) << 4) | ((inBuf[i+1] & 0x3C) >> 2);
 
423
        outBuf[len+H_1] = ((inBuf[i+1] & 0x03) << 6) | ((inBuf[i+2] & 0x3F) >> 0);
 
424
 
 
425
        i += 3;
 
426
        len += 2;
 
427
#ifdef UTF16
 
428
      } else if( (inBuf[i] & 0xF8) == 0xF0 ) { 
 
429
        int abcde, BCDE;
 
430
 
 
431
        if( (inBuf[i+1] & 0xC0) != 0x80 ) return PR_FALSE;
 
432
        if( (inBuf[i+2] & 0xC0) != 0x80 ) return PR_FALSE;
 
433
        if( (inBuf[i+3] & 0xC0) != 0x80 ) return PR_FALSE;
 
434
 
 
435
        /* 0001 0000-001F FFFF <- 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
 
436
        /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx -> [D800-DBFF] [DC00-DFFF] */
 
437
           
 
438
        /* 11110abc 10defghi 10jklmno 10pqrstu -> 
 
439
           { Let 0BCDE = abcde - 1 }
 
440
           110110BC DEfghijk 110111lm nopqrstu */
 
441
 
 
442
        abcde = ((inBuf[i+0] & 0x07) << 2) | ((inBuf[i+1] & 0x30) >> 4);
 
443
        BCDE = abcde - 1;
 
444
 
 
445
#ifndef TEST_UTF8
 
446
        PORT_Assert(BCDE < 0x10); /* should have been caught above */
 
447
#endif /* TEST_UTF8 */
 
448
 
 
449
        outBuf[len+0+H_0] = 0xD8 | ((BCDE & 0x0C) >> 2);
 
450
        outBuf[len+0+H_1] = ((BCDE & 0x03) << 6) 
 
451
                      | ((inBuf[i+1] & 0x0F) << 2)
 
452
                      | ((inBuf[i+2] & 0x30) >> 4);
 
453
        outBuf[len+2+H_0] = 0xDC | ((inBuf[i+2] & 0x0C) >> 2);
 
454
        outBuf[len+2+H_1] = ((inBuf[i+2] & 0x03) << 6) | ((inBuf[i+3] & 0x3F) >> 0);
 
455
 
 
456
        i += 4;
 
457
        len += 4;
 
458
#endif /* UTF16 */
 
459
      } else return PR_FALSE;
 
460
    }
 
461
 
 
462
    *outBufLen = len;
 
463
    return PR_TRUE;
 
464
  } else {
 
465
    unsigned int i, len = 0;
 
466
    PORT_Assert((inBufLen % 2) == 0);
 
467
    if ((inBufLen % 2) != 0) {
 
468
      *outBufLen = 0;
 
469
      return PR_FALSE;
 
470
    }
 
471
 
 
472
    for( i = 0; i < inBufLen; i += 2 ) {
 
473
      if( (inBuf[i+H_0] == 0x00) && ((inBuf[i+H_0] & 0x80) == 0x00) ) len += 1;
 
474
      else if( inBuf[i+H_0] < 0x08 ) len += 2;
 
475
#ifdef UTF16
 
476
      else if( ((inBuf[i+0+H_0] & 0xDC) == 0xD8) ) {
 
477
        if( ((inBuf[i+2+H_0] & 0xDC) == 0xDC) && ((inBufLen - i) > 2) ) {
 
478
          i += 2;
 
479
          len += 4;
 
480
        } else {
 
481
          return PR_FALSE;
 
482
        }
 
483
      }
 
484
#endif /* UTF16 */
 
485
      else len += 3;
 
486
    }
 
487
 
 
488
    if( len > maxOutBufLen ) {
 
489
      *outBufLen = len;
 
490
      return PR_FALSE;
 
491
    }
 
492
 
 
493
    len = 0;
 
494
 
 
495
    for( i = 0; i < inBufLen; i += 2 ) {
 
496
      if( (inBuf[i+H_0] == 0x00) && ((inBuf[i+H_1] & 0x80) == 0x00) ) {
 
497
        /* 0000-007F -> 0xxxxxx */
 
498
        /* 00000000 0abcdefg -> 0abcdefg */
 
499
 
 
500
        outBuf[len] = inBuf[i+H_1] & 0x7F;
 
501
 
 
502
        len += 1;
 
503
      } else if( inBuf[i+H_0] < 0x08 ) {
 
504
        /* 0080-07FF -> 110xxxxx 10xxxxxx */
 
505
        /* 00000abc defghijk -> 110abcde 10fghijk */
 
506
 
 
507
        outBuf[len+0] = 0xC0 | ((inBuf[i+H_0] & 0x07) << 2) 
 
508
                             | ((inBuf[i+H_1] & 0xC0) >> 6);
 
509
        outBuf[len+1] = 0x80 | ((inBuf[i+H_1] & 0x3F) >> 0);
 
510
 
 
511
        len += 2;
 
512
#ifdef UTF16
 
513
      } else if( (inBuf[i+H_0] & 0xDC) == 0xD8 ) {
 
514
        int abcde, BCDE;
 
515
 
 
516
#ifndef TEST_UTF8
 
517
        PORT_Assert(((inBuf[i+2+H_0] & 0xDC) == 0xDC) && ((inBufLen - i) > 2));
 
518
#endif /* TEST_UTF8 */
 
519
 
 
520
        /* D800-DBFF DC00-DFFF -> 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
 
521
        /* 110110BC DEfghijk 110111lm nopqrstu ->
 
522
           { Let abcde = BCDE + 1 }
 
523
           11110abc 10defghi 10jklmno 10pqrstu */
 
524
 
 
525
        BCDE = ((inBuf[i+H_0] & 0x03) << 2) | ((inBuf[i+H_1] & 0xC0) >> 6);
 
526
        abcde = BCDE + 1;
 
527
 
 
528
        outBuf[len+0] = 0xF0 | ((abcde & 0x1C) >> 2);
 
529
        outBuf[len+1] = 0x80 | ((abcde & 0x03) << 4) 
 
530
                             | ((inBuf[i+0+H_1] & 0x3C) >> 2);
 
531
        outBuf[len+2] = 0x80 | ((inBuf[i+0+H_1] & 0x03) << 4)
 
532
                             | ((inBuf[i+2+H_0] & 0x03) << 2)
 
533
                             | ((inBuf[i+2+H_1] & 0xC0) >> 6);
 
534
        outBuf[len+3] = 0x80 | ((inBuf[i+2+H_1] & 0x3F) >> 0);
 
535
 
 
536
        i += 2;
 
537
        len += 4;
 
538
#endif /* UTF16 */
 
539
      } else {
 
540
        /* 0800-FFFF -> 1110xxxx 10xxxxxx 10xxxxxx */
 
541
        /* abcdefgh ijklmnop -> 1110abcd 10efghij 10klmnop */
 
542
 
 
543
        outBuf[len+0] = 0xE0 | ((inBuf[i+H_0] & 0xF0) >> 4);
 
544
        outBuf[len+1] = 0x80 | ((inBuf[i+H_0] & 0x0F) << 2) 
 
545
                             | ((inBuf[i+H_1] & 0xC0) >> 6);
 
546
        outBuf[len+2] = 0x80 | ((inBuf[i+H_1] & 0x3F) >> 0);
 
547
 
 
548
        len += 3;
 
549
      }
 
550
    }
 
551
 
 
552
    *outBufLen = len;
 
553
    return PR_TRUE;
 
554
  }
 
555
}
 
556
 
 
557
PRBool
 
558
sec_port_iso88591_utf8_conversion_function
 
559
(
 
560
  const unsigned char *inBuf,
 
561
  unsigned int inBufLen,
 
562
  unsigned char *outBuf,
 
563
  unsigned int maxOutBufLen,
 
564
  unsigned int *outBufLen
 
565
)
 
566
{
 
567
  unsigned int i, len = 0;
 
568
 
 
569
#ifndef TEST_UTF8
 
570
  PORT_Assert((unsigned int *)NULL != outBufLen);
 
571
#endif /* TEST_UTF8 */
 
572
 
 
573
  for( i = 0; i < inBufLen; i++) {
 
574
    if( (inBuf[i] & 0x80) == 0x00 ) len += 1;
 
575
    else len += 2;
 
576
  }
 
577
 
 
578
  if( len > maxOutBufLen ) {
 
579
    *outBufLen = len;
 
580
    return PR_FALSE;
 
581
  }
 
582
 
 
583
  len = 0;
 
584
 
 
585
  for( i = 0; i < inBufLen; i++) {
 
586
    if( (inBuf[i] & 0x80) == 0x00 ) {
 
587
      /* 00-7F -> 0xxxxxxx */
 
588
      /* 0abcdefg -> 0abcdefg */
 
589
 
 
590
      outBuf[len] = inBuf[i];
 
591
      len += 1;
 
592
    } else {
 
593
      /* 80-FF <- 110xxxxx 10xxxxxx */
 
594
      /* 00000000 abcdefgh -> 110000ab 10cdefgh */
 
595
 
 
596
      outBuf[len+0] = 0xC0 | ((inBuf[i] & 0xC0) >> 6);
 
597
      outBuf[len+1] = 0x80 | ((inBuf[i] & 0x3F) >> 0);
 
598
 
 
599
      len += 2;
 
600
    }
 
601
  }
 
602
 
 
603
  *outBufLen = len;
 
604
  return PR_TRUE;
 
605
}
 
606
 
 
607
#ifdef TEST_UTF8
 
608
 
 
609
#include <stdio.h>
 
610
#include <string.h>
 
611
#include <stdlib.h>
 
612
#include <netinet/in.h> /* for htonl and htons */
 
613
 
 
614
/*
 
615
 * UCS-4 vectors
 
616
 */
 
617
 
 
618
struct ucs4 {
 
619
  PRUint32 c;
 
620
  char *utf8;
 
621
};
 
622
 
 
623
/*
 
624
 * UCS-2 vectors
 
625
 */
 
626
 
 
627
struct ucs2 {
 
628
  PRUint16 c;
 
629
  char *utf8;
 
630
};
 
631
 
 
632
#ifdef UTF16
 
633
/*
 
634
 * UTF-16 vectors
 
635
 */
 
636
 
 
637
struct utf16 {
 
638
  PRUint32 c;
 
639
  PRUint16 w[2];
 
640
};
 
641
#endif /* UTF16 */
 
642
 
 
643
 
 
644
/*
 
645
 * UCS-4 vectors
 
646
 */
 
647
 
 
648
struct ucs4 ucs4[] = {
 
649
  { 0x00000001, "\x01" },
 
650
  { 0x00000002, "\x02" },
 
651
  { 0x00000003, "\x03" },
 
652
  { 0x00000004, "\x04" },
 
653
  { 0x00000007, "\x07" },
 
654
  { 0x00000008, "\x08" },
 
655
  { 0x0000000F, "\x0F" },
 
656
  { 0x00000010, "\x10" },
 
657
  { 0x0000001F, "\x1F" },
 
658
  { 0x00000020, "\x20" },
 
659
  { 0x0000003F, "\x3F" },
 
660
  { 0x00000040, "\x40" },
 
661
  { 0x0000007F, "\x7F" },
 
662
          
 
663
  { 0x00000080, "\xC2\x80" },
 
664
  { 0x00000081, "\xC2\x81" },
 
665
  { 0x00000082, "\xC2\x82" },
 
666
  { 0x00000084, "\xC2\x84" },
 
667
  { 0x00000088, "\xC2\x88" },
 
668
  { 0x00000090, "\xC2\x90" },
 
669
  { 0x000000A0, "\xC2\xA0" },
 
670
  { 0x000000C0, "\xC3\x80" },
 
671
  { 0x000000FF, "\xC3\xBF" },
 
672
  { 0x00000100, "\xC4\x80" },
 
673
  { 0x00000101, "\xC4\x81" },
 
674
  { 0x00000102, "\xC4\x82" },
 
675
  { 0x00000104, "\xC4\x84" },
 
676
  { 0x00000108, "\xC4\x88" },
 
677
  { 0x00000110, "\xC4\x90" },
 
678
  { 0x00000120, "\xC4\xA0" },
 
679
  { 0x00000140, "\xC5\x80" },
 
680
  { 0x00000180, "\xC6\x80" },
 
681
  { 0x000001FF, "\xC7\xBF" },
 
682
  { 0x00000200, "\xC8\x80" },
 
683
  { 0x00000201, "\xC8\x81" },
 
684
  { 0x00000202, "\xC8\x82" },
 
685
  { 0x00000204, "\xC8\x84" },
 
686
  { 0x00000208, "\xC8\x88" },
 
687
  { 0x00000210, "\xC8\x90" },
 
688
  { 0x00000220, "\xC8\xA0" },
 
689
  { 0x00000240, "\xC9\x80" },
 
690
  { 0x00000280, "\xCA\x80" },
 
691
  { 0x00000300, "\xCC\x80" },
 
692
  { 0x000003FF, "\xCF\xBF" },
 
693
  { 0x00000400, "\xD0\x80" },
 
694
  { 0x00000401, "\xD0\x81" },
 
695
  { 0x00000402, "\xD0\x82" },
 
696
  { 0x00000404, "\xD0\x84" },
 
697
  { 0x00000408, "\xD0\x88" },
 
698
  { 0x00000410, "\xD0\x90" },
 
699
  { 0x00000420, "\xD0\xA0" },
 
700
  { 0x00000440, "\xD1\x80" },
 
701
  { 0x00000480, "\xD2\x80" },
 
702
  { 0x00000500, "\xD4\x80" },
 
703
  { 0x00000600, "\xD8\x80" },
 
704
  { 0x000007FF, "\xDF\xBF" },
 
705
          
 
706
  { 0x00000800, "\xE0\xA0\x80" },
 
707
  { 0x00000801, "\xE0\xA0\x81" },
 
708
  { 0x00000802, "\xE0\xA0\x82" },
 
709
  { 0x00000804, "\xE0\xA0\x84" },
 
710
  { 0x00000808, "\xE0\xA0\x88" },
 
711
  { 0x00000810, "\xE0\xA0\x90" },
 
712
  { 0x00000820, "\xE0\xA0\xA0" },
 
713
  { 0x00000840, "\xE0\xA1\x80" },
 
714
  { 0x00000880, "\xE0\xA2\x80" },
 
715
  { 0x00000900, "\xE0\xA4\x80" },
 
716
  { 0x00000A00, "\xE0\xA8\x80" },
 
717
  { 0x00000C00, "\xE0\xB0\x80" },
 
718
  { 0x00000FFF, "\xE0\xBF\xBF" },
 
719
  { 0x00001000, "\xE1\x80\x80" },
 
720
  { 0x00001001, "\xE1\x80\x81" },
 
721
  { 0x00001002, "\xE1\x80\x82" },
 
722
  { 0x00001004, "\xE1\x80\x84" },
 
723
  { 0x00001008, "\xE1\x80\x88" },
 
724
  { 0x00001010, "\xE1\x80\x90" },
 
725
  { 0x00001020, "\xE1\x80\xA0" },
 
726
  { 0x00001040, "\xE1\x81\x80" },
 
727
  { 0x00001080, "\xE1\x82\x80" },
 
728
  { 0x00001100, "\xE1\x84\x80" },
 
729
  { 0x00001200, "\xE1\x88\x80" },
 
730
  { 0x00001400, "\xE1\x90\x80" },
 
731
  { 0x00001800, "\xE1\xA0\x80" },
 
732
  { 0x00001FFF, "\xE1\xBF\xBF" },
 
733
  { 0x00002000, "\xE2\x80\x80" },
 
734
  { 0x00002001, "\xE2\x80\x81" },
 
735
  { 0x00002002, "\xE2\x80\x82" },
 
736
  { 0x00002004, "\xE2\x80\x84" },
 
737
  { 0x00002008, "\xE2\x80\x88" },
 
738
  { 0x00002010, "\xE2\x80\x90" },
 
739
  { 0x00002020, "\xE2\x80\xA0" },
 
740
  { 0x00002040, "\xE2\x81\x80" },
 
741
  { 0x00002080, "\xE2\x82\x80" },
 
742
  { 0x00002100, "\xE2\x84\x80" },
 
743
  { 0x00002200, "\xE2\x88\x80" },
 
744
  { 0x00002400, "\xE2\x90\x80" },
 
745
  { 0x00002800, "\xE2\xA0\x80" },
 
746
  { 0x00003000, "\xE3\x80\x80" },
 
747
  { 0x00003FFF, "\xE3\xBF\xBF" },
 
748
  { 0x00004000, "\xE4\x80\x80" },
 
749
  { 0x00004001, "\xE4\x80\x81" },
 
750
  { 0x00004002, "\xE4\x80\x82" },
 
751
  { 0x00004004, "\xE4\x80\x84" },
 
752
  { 0x00004008, "\xE4\x80\x88" },
 
753
  { 0x00004010, "\xE4\x80\x90" },
 
754
  { 0x00004020, "\xE4\x80\xA0" },
 
755
  { 0x00004040, "\xE4\x81\x80" },
 
756
  { 0x00004080, "\xE4\x82\x80" },
 
757
  { 0x00004100, "\xE4\x84\x80" },
 
758
  { 0x00004200, "\xE4\x88\x80" },
 
759
  { 0x00004400, "\xE4\x90\x80" },
 
760
  { 0x00004800, "\xE4\xA0\x80" },
 
761
  { 0x00005000, "\xE5\x80\x80" },
 
762
  { 0x00006000, "\xE6\x80\x80" },
 
763
  { 0x00007FFF, "\xE7\xBF\xBF" },
 
764
  { 0x00008000, "\xE8\x80\x80" },
 
765
  { 0x00008001, "\xE8\x80\x81" },
 
766
  { 0x00008002, "\xE8\x80\x82" },
 
767
  { 0x00008004, "\xE8\x80\x84" },
 
768
  { 0x00008008, "\xE8\x80\x88" },
 
769
  { 0x00008010, "\xE8\x80\x90" },
 
770
  { 0x00008020, "\xE8\x80\xA0" },
 
771
  { 0x00008040, "\xE8\x81\x80" },
 
772
  { 0x00008080, "\xE8\x82\x80" },
 
773
  { 0x00008100, "\xE8\x84\x80" },
 
774
  { 0x00008200, "\xE8\x88\x80" },
 
775
  { 0x00008400, "\xE8\x90\x80" },
 
776
  { 0x00008800, "\xE8\xA0\x80" },
 
777
  { 0x00009000, "\xE9\x80\x80" },
 
778
  { 0x0000A000, "\xEA\x80\x80" },
 
779
  { 0x0000C000, "\xEC\x80\x80" },
 
780
  { 0x0000FFFF, "\xEF\xBF\xBF" },
 
781
          
 
782
  { 0x00010000, "\xF0\x90\x80\x80" },
 
783
  { 0x00010001, "\xF0\x90\x80\x81" },
 
784
  { 0x00010002, "\xF0\x90\x80\x82" },
 
785
  { 0x00010004, "\xF0\x90\x80\x84" },
 
786
  { 0x00010008, "\xF0\x90\x80\x88" },
 
787
  { 0x00010010, "\xF0\x90\x80\x90" },
 
788
  { 0x00010020, "\xF0\x90\x80\xA0" },
 
789
  { 0x00010040, "\xF0\x90\x81\x80" },
 
790
  { 0x00010080, "\xF0\x90\x82\x80" },
 
791
  { 0x00010100, "\xF0\x90\x84\x80" },
 
792
  { 0x00010200, "\xF0\x90\x88\x80" },
 
793
  { 0x00010400, "\xF0\x90\x90\x80" },
 
794
  { 0x00010800, "\xF0\x90\xA0\x80" },
 
795
  { 0x00011000, "\xF0\x91\x80\x80" },
 
796
  { 0x00012000, "\xF0\x92\x80\x80" },
 
797
  { 0x00014000, "\xF0\x94\x80\x80" },
 
798
  { 0x00018000, "\xF0\x98\x80\x80" },
 
799
  { 0x0001FFFF, "\xF0\x9F\xBF\xBF" },
 
800
  { 0x00020000, "\xF0\xA0\x80\x80" },
 
801
  { 0x00020001, "\xF0\xA0\x80\x81" },
 
802
  { 0x00020002, "\xF0\xA0\x80\x82" },
 
803
  { 0x00020004, "\xF0\xA0\x80\x84" },
 
804
  { 0x00020008, "\xF0\xA0\x80\x88" },
 
805
  { 0x00020010, "\xF0\xA0\x80\x90" },
 
806
  { 0x00020020, "\xF0\xA0\x80\xA0" },
 
807
  { 0x00020040, "\xF0\xA0\x81\x80" },
 
808
  { 0x00020080, "\xF0\xA0\x82\x80" },
 
809
  { 0x00020100, "\xF0\xA0\x84\x80" },
 
810
  { 0x00020200, "\xF0\xA0\x88\x80" },
 
811
  { 0x00020400, "\xF0\xA0\x90\x80" },
 
812
  { 0x00020800, "\xF0\xA0\xA0\x80" },
 
813
  { 0x00021000, "\xF0\xA1\x80\x80" },
 
814
  { 0x00022000, "\xF0\xA2\x80\x80" },
 
815
  { 0x00024000, "\xF0\xA4\x80\x80" },
 
816
  { 0x00028000, "\xF0\xA8\x80\x80" },
 
817
  { 0x00030000, "\xF0\xB0\x80\x80" },
 
818
  { 0x0003FFFF, "\xF0\xBF\xBF\xBF" },
 
819
  { 0x00040000, "\xF1\x80\x80\x80" },
 
820
  { 0x00040001, "\xF1\x80\x80\x81" },
 
821
  { 0x00040002, "\xF1\x80\x80\x82" },
 
822
  { 0x00040004, "\xF1\x80\x80\x84" },
 
823
  { 0x00040008, "\xF1\x80\x80\x88" },
 
824
  { 0x00040010, "\xF1\x80\x80\x90" },
 
825
  { 0x00040020, "\xF1\x80\x80\xA0" },
 
826
  { 0x00040040, "\xF1\x80\x81\x80" },
 
827
  { 0x00040080, "\xF1\x80\x82\x80" },
 
828
  { 0x00040100, "\xF1\x80\x84\x80" },
 
829
  { 0x00040200, "\xF1\x80\x88\x80" },
 
830
  { 0x00040400, "\xF1\x80\x90\x80" },
 
831
  { 0x00040800, "\xF1\x80\xA0\x80" },
 
832
  { 0x00041000, "\xF1\x81\x80\x80" },
 
833
  { 0x00042000, "\xF1\x82\x80\x80" },
 
834
  { 0x00044000, "\xF1\x84\x80\x80" },
 
835
  { 0x00048000, "\xF1\x88\x80\x80" },
 
836
  { 0x00050000, "\xF1\x90\x80\x80" },
 
837
  { 0x00060000, "\xF1\xA0\x80\x80" },
 
838
  { 0x0007FFFF, "\xF1\xBF\xBF\xBF" },
 
839
  { 0x00080000, "\xF2\x80\x80\x80" },
 
840
  { 0x00080001, "\xF2\x80\x80\x81" },
 
841
  { 0x00080002, "\xF2\x80\x80\x82" },
 
842
  { 0x00080004, "\xF2\x80\x80\x84" },
 
843
  { 0x00080008, "\xF2\x80\x80\x88" },
 
844
  { 0x00080010, "\xF2\x80\x80\x90" },
 
845
  { 0x00080020, "\xF2\x80\x80\xA0" },
 
846
  { 0x00080040, "\xF2\x80\x81\x80" },
 
847
  { 0x00080080, "\xF2\x80\x82\x80" },
 
848
  { 0x00080100, "\xF2\x80\x84\x80" },
 
849
  { 0x00080200, "\xF2\x80\x88\x80" },
 
850
  { 0x00080400, "\xF2\x80\x90\x80" },
 
851
  { 0x00080800, "\xF2\x80\xA0\x80" },
 
852
  { 0x00081000, "\xF2\x81\x80\x80" },
 
853
  { 0x00082000, "\xF2\x82\x80\x80" },
 
854
  { 0x00084000, "\xF2\x84\x80\x80" },
 
855
  { 0x00088000, "\xF2\x88\x80\x80" },
 
856
  { 0x00090000, "\xF2\x90\x80\x80" },
 
857
  { 0x000A0000, "\xF2\xA0\x80\x80" },
 
858
  { 0x000C0000, "\xF3\x80\x80\x80" },
 
859
  { 0x000FFFFF, "\xF3\xBF\xBF\xBF" },
 
860
  { 0x00100000, "\xF4\x80\x80\x80" },
 
861
  { 0x00100001, "\xF4\x80\x80\x81" },
 
862
  { 0x00100002, "\xF4\x80\x80\x82" },
 
863
  { 0x00100004, "\xF4\x80\x80\x84" },
 
864
  { 0x00100008, "\xF4\x80\x80\x88" },
 
865
  { 0x00100010, "\xF4\x80\x80\x90" },
 
866
  { 0x00100020, "\xF4\x80\x80\xA0" },
 
867
  { 0x00100040, "\xF4\x80\x81\x80" },
 
868
  { 0x00100080, "\xF4\x80\x82\x80" },
 
869
  { 0x00100100, "\xF4\x80\x84\x80" },
 
870
  { 0x00100200, "\xF4\x80\x88\x80" },
 
871
  { 0x00100400, "\xF4\x80\x90\x80" },
 
872
  { 0x00100800, "\xF4\x80\xA0\x80" },
 
873
  { 0x00101000, "\xF4\x81\x80\x80" },
 
874
  { 0x00102000, "\xF4\x82\x80\x80" },
 
875
  { 0x00104000, "\xF4\x84\x80\x80" },
 
876
  { 0x00108000, "\xF4\x88\x80\x80" },
 
877
  { 0x00110000, "\xF4\x90\x80\x80" },
 
878
  { 0x00120000, "\xF4\xA0\x80\x80" },
 
879
  { 0x00140000, "\xF5\x80\x80\x80" },
 
880
  { 0x00180000, "\xF6\x80\x80\x80" },
 
881
  { 0x001FFFFF, "\xF7\xBF\xBF\xBF" },
 
882
          
 
883
  { 0x00200000, "\xF8\x88\x80\x80\x80" },
 
884
  { 0x00200001, "\xF8\x88\x80\x80\x81" },
 
885
  { 0x00200002, "\xF8\x88\x80\x80\x82" },
 
886
  { 0x00200004, "\xF8\x88\x80\x80\x84" },
 
887
  { 0x00200008, "\xF8\x88\x80\x80\x88" },
 
888
  { 0x00200010, "\xF8\x88\x80\x80\x90" },
 
889
  { 0x00200020, "\xF8\x88\x80\x80\xA0" },
 
890
  { 0x00200040, "\xF8\x88\x80\x81\x80" },
 
891
  { 0x00200080, "\xF8\x88\x80\x82\x80" },
 
892
  { 0x00200100, "\xF8\x88\x80\x84\x80" },
 
893
  { 0x00200200, "\xF8\x88\x80\x88\x80" },
 
894
  { 0x00200400, "\xF8\x88\x80\x90\x80" },
 
895
  { 0x00200800, "\xF8\x88\x80\xA0\x80" },
 
896
  { 0x00201000, "\xF8\x88\x81\x80\x80" },
 
897
  { 0x00202000, "\xF8\x88\x82\x80\x80" },
 
898
  { 0x00204000, "\xF8\x88\x84\x80\x80" },
 
899
  { 0x00208000, "\xF8\x88\x88\x80\x80" },
 
900
  { 0x00210000, "\xF8\x88\x90\x80\x80" },
 
901
  { 0x00220000, "\xF8\x88\xA0\x80\x80" },
 
902
  { 0x00240000, "\xF8\x89\x80\x80\x80" },
 
903
  { 0x00280000, "\xF8\x8A\x80\x80\x80" },
 
904
  { 0x00300000, "\xF8\x8C\x80\x80\x80" },
 
905
  { 0x003FFFFF, "\xF8\x8F\xBF\xBF\xBF" },
 
906
  { 0x00400000, "\xF8\x90\x80\x80\x80" },
 
907
  { 0x00400001, "\xF8\x90\x80\x80\x81" },
 
908
  { 0x00400002, "\xF8\x90\x80\x80\x82" },
 
909
  { 0x00400004, "\xF8\x90\x80\x80\x84" },
 
910
  { 0x00400008, "\xF8\x90\x80\x80\x88" },
 
911
  { 0x00400010, "\xF8\x90\x80\x80\x90" },
 
912
  { 0x00400020, "\xF8\x90\x80\x80\xA0" },
 
913
  { 0x00400040, "\xF8\x90\x80\x81\x80" },
 
914
  { 0x00400080, "\xF8\x90\x80\x82\x80" },
 
915
  { 0x00400100, "\xF8\x90\x80\x84\x80" },
 
916
  { 0x00400200, "\xF8\x90\x80\x88\x80" },
 
917
  { 0x00400400, "\xF8\x90\x80\x90\x80" },
 
918
  { 0x00400800, "\xF8\x90\x80\xA0\x80" },
 
919
  { 0x00401000, "\xF8\x90\x81\x80\x80" },
 
920
  { 0x00402000, "\xF8\x90\x82\x80\x80" },
 
921
  { 0x00404000, "\xF8\x90\x84\x80\x80" },
 
922
  { 0x00408000, "\xF8\x90\x88\x80\x80" },
 
923
  { 0x00410000, "\xF8\x90\x90\x80\x80" },
 
924
  { 0x00420000, "\xF8\x90\xA0\x80\x80" },
 
925
  { 0x00440000, "\xF8\x91\x80\x80\x80" },
 
926
  { 0x00480000, "\xF8\x92\x80\x80\x80" },
 
927
  { 0x00500000, "\xF8\x94\x80\x80\x80" },
 
928
  { 0x00600000, "\xF8\x98\x80\x80\x80" },
 
929
  { 0x007FFFFF, "\xF8\x9F\xBF\xBF\xBF" },
 
930
  { 0x00800000, "\xF8\xA0\x80\x80\x80" },
 
931
  { 0x00800001, "\xF8\xA0\x80\x80\x81" },
 
932
  { 0x00800002, "\xF8\xA0\x80\x80\x82" },
 
933
  { 0x00800004, "\xF8\xA0\x80\x80\x84" },
 
934
  { 0x00800008, "\xF8\xA0\x80\x80\x88" },
 
935
  { 0x00800010, "\xF8\xA0\x80\x80\x90" },
 
936
  { 0x00800020, "\xF8\xA0\x80\x80\xA0" },
 
937
  { 0x00800040, "\xF8\xA0\x80\x81\x80" },
 
938
  { 0x00800080, "\xF8\xA0\x80\x82\x80" },
 
939
  { 0x00800100, "\xF8\xA0\x80\x84\x80" },
 
940
  { 0x00800200, "\xF8\xA0\x80\x88\x80" },
 
941
  { 0x00800400, "\xF8\xA0\x80\x90\x80" },
 
942
  { 0x00800800, "\xF8\xA0\x80\xA0\x80" },
 
943
  { 0x00801000, "\xF8\xA0\x81\x80\x80" },
 
944
  { 0x00802000, "\xF8\xA0\x82\x80\x80" },
 
945
  { 0x00804000, "\xF8\xA0\x84\x80\x80" },
 
946
  { 0x00808000, "\xF8\xA0\x88\x80\x80" },
 
947
  { 0x00810000, "\xF8\xA0\x90\x80\x80" },
 
948
  { 0x00820000, "\xF8\xA0\xA0\x80\x80" },
 
949
  { 0x00840000, "\xF8\xA1\x80\x80\x80" },
 
950
  { 0x00880000, "\xF8\xA2\x80\x80\x80" },
 
951
  { 0x00900000, "\xF8\xA4\x80\x80\x80" },
 
952
  { 0x00A00000, "\xF8\xA8\x80\x80\x80" },
 
953
  { 0x00C00000, "\xF8\xB0\x80\x80\x80" },
 
954
  { 0x00FFFFFF, "\xF8\xBF\xBF\xBF\xBF" },
 
955
  { 0x01000000, "\xF9\x80\x80\x80\x80" },
 
956
  { 0x01000001, "\xF9\x80\x80\x80\x81" },
 
957
  { 0x01000002, "\xF9\x80\x80\x80\x82" },
 
958
  { 0x01000004, "\xF9\x80\x80\x80\x84" },
 
959
  { 0x01000008, "\xF9\x80\x80\x80\x88" },
 
960
  { 0x01000010, "\xF9\x80\x80\x80\x90" },
 
961
  { 0x01000020, "\xF9\x80\x80\x80\xA0" },
 
962
  { 0x01000040, "\xF9\x80\x80\x81\x80" },
 
963
  { 0x01000080, "\xF9\x80\x80\x82\x80" },
 
964
  { 0x01000100, "\xF9\x80\x80\x84\x80" },
 
965
  { 0x01000200, "\xF9\x80\x80\x88\x80" },
 
966
  { 0x01000400, "\xF9\x80\x80\x90\x80" },
 
967
  { 0x01000800, "\xF9\x80\x80\xA0\x80" },
 
968
  { 0x01001000, "\xF9\x80\x81\x80\x80" },
 
969
  { 0x01002000, "\xF9\x80\x82\x80\x80" },
 
970
  { 0x01004000, "\xF9\x80\x84\x80\x80" },
 
971
  { 0x01008000, "\xF9\x80\x88\x80\x80" },
 
972
  { 0x01010000, "\xF9\x80\x90\x80\x80" },
 
973
  { 0x01020000, "\xF9\x80\xA0\x80\x80" },
 
974
  { 0x01040000, "\xF9\x81\x80\x80\x80" },
 
975
  { 0x01080000, "\xF9\x82\x80\x80\x80" },
 
976
  { 0x01100000, "\xF9\x84\x80\x80\x80" },
 
977
  { 0x01200000, "\xF9\x88\x80\x80\x80" },
 
978
  { 0x01400000, "\xF9\x90\x80\x80\x80" },
 
979
  { 0x01800000, "\xF9\xA0\x80\x80\x80" },
 
980
  { 0x01FFFFFF, "\xF9\xBF\xBF\xBF\xBF" },
 
981
  { 0x02000000, "\xFA\x80\x80\x80\x80" },
 
982
  { 0x02000001, "\xFA\x80\x80\x80\x81" },
 
983
  { 0x02000002, "\xFA\x80\x80\x80\x82" },
 
984
  { 0x02000004, "\xFA\x80\x80\x80\x84" },
 
985
  { 0x02000008, "\xFA\x80\x80\x80\x88" },
 
986
  { 0x02000010, "\xFA\x80\x80\x80\x90" },
 
987
  { 0x02000020, "\xFA\x80\x80\x80\xA0" },
 
988
  { 0x02000040, "\xFA\x80\x80\x81\x80" },
 
989
  { 0x02000080, "\xFA\x80\x80\x82\x80" },
 
990
  { 0x02000100, "\xFA\x80\x80\x84\x80" },
 
991
  { 0x02000200, "\xFA\x80\x80\x88\x80" },
 
992
  { 0x02000400, "\xFA\x80\x80\x90\x80" },
 
993
  { 0x02000800, "\xFA\x80\x80\xA0\x80" },
 
994
  { 0x02001000, "\xFA\x80\x81\x80\x80" },
 
995
  { 0x02002000, "\xFA\x80\x82\x80\x80" },
 
996
  { 0x02004000, "\xFA\x80\x84\x80\x80" },
 
997
  { 0x02008000, "\xFA\x80\x88\x80\x80" },
 
998
  { 0x02010000, "\xFA\x80\x90\x80\x80" },
 
999
  { 0x02020000, "\xFA\x80\xA0\x80\x80" },
 
1000
  { 0x02040000, "\xFA\x81\x80\x80\x80" },
 
1001
  { 0x02080000, "\xFA\x82\x80\x80\x80" },
 
1002
  { 0x02100000, "\xFA\x84\x80\x80\x80" },
 
1003
  { 0x02200000, "\xFA\x88\x80\x80\x80" },
 
1004
  { 0x02400000, "\xFA\x90\x80\x80\x80" },
 
1005
  { 0x02800000, "\xFA\xA0\x80\x80\x80" },
 
1006
  { 0x03000000, "\xFB\x80\x80\x80\x80" },
 
1007
  { 0x03FFFFFF, "\xFB\xBF\xBF\xBF\xBF" },
 
1008
          
 
1009
  { 0x04000000, "\xFC\x84\x80\x80\x80\x80" },
 
1010
  { 0x04000001, "\xFC\x84\x80\x80\x80\x81" },
 
1011
  { 0x04000002, "\xFC\x84\x80\x80\x80\x82" },
 
1012
  { 0x04000004, "\xFC\x84\x80\x80\x80\x84" },
 
1013
  { 0x04000008, "\xFC\x84\x80\x80\x80\x88" },
 
1014
  { 0x04000010, "\xFC\x84\x80\x80\x80\x90" },
 
1015
  { 0x04000020, "\xFC\x84\x80\x80\x80\xA0" },
 
1016
  { 0x04000040, "\xFC\x84\x80\x80\x81\x80" },
 
1017
  { 0x04000080, "\xFC\x84\x80\x80\x82\x80" },
 
1018
  { 0x04000100, "\xFC\x84\x80\x80\x84\x80" },
 
1019
  { 0x04000200, "\xFC\x84\x80\x80\x88\x80" },
 
1020
  { 0x04000400, "\xFC\x84\x80\x80\x90\x80" },
 
1021
  { 0x04000800, "\xFC\x84\x80\x80\xA0\x80" },
 
1022
  { 0x04001000, "\xFC\x84\x80\x81\x80\x80" },
 
1023
  { 0x04002000, "\xFC\x84\x80\x82\x80\x80" },
 
1024
  { 0x04004000, "\xFC\x84\x80\x84\x80\x80" },
 
1025
  { 0x04008000, "\xFC\x84\x80\x88\x80\x80" },
 
1026
  { 0x04010000, "\xFC\x84\x80\x90\x80\x80" },
 
1027
  { 0x04020000, "\xFC\x84\x80\xA0\x80\x80" },
 
1028
  { 0x04040000, "\xFC\x84\x81\x80\x80\x80" },
 
1029
  { 0x04080000, "\xFC\x84\x82\x80\x80\x80" },
 
1030
  { 0x04100000, "\xFC\x84\x84\x80\x80\x80" },
 
1031
  { 0x04200000, "\xFC\x84\x88\x80\x80\x80" },
 
1032
  { 0x04400000, "\xFC\x84\x90\x80\x80\x80" },
 
1033
  { 0x04800000, "\xFC\x84\xA0\x80\x80\x80" },
 
1034
  { 0x05000000, "\xFC\x85\x80\x80\x80\x80" },
 
1035
  { 0x06000000, "\xFC\x86\x80\x80\x80\x80" },
 
1036
  { 0x07FFFFFF, "\xFC\x87\xBF\xBF\xBF\xBF" },
 
1037
  { 0x08000000, "\xFC\x88\x80\x80\x80\x80" },
 
1038
  { 0x08000001, "\xFC\x88\x80\x80\x80\x81" },
 
1039
  { 0x08000002, "\xFC\x88\x80\x80\x80\x82" },
 
1040
  { 0x08000004, "\xFC\x88\x80\x80\x80\x84" },
 
1041
  { 0x08000008, "\xFC\x88\x80\x80\x80\x88" },
 
1042
  { 0x08000010, "\xFC\x88\x80\x80\x80\x90" },
 
1043
  { 0x08000020, "\xFC\x88\x80\x80\x80\xA0" },
 
1044
  { 0x08000040, "\xFC\x88\x80\x80\x81\x80" },
 
1045
  { 0x08000080, "\xFC\x88\x80\x80\x82\x80" },
 
1046
  { 0x08000100, "\xFC\x88\x80\x80\x84\x80" },
 
1047
  { 0x08000200, "\xFC\x88\x80\x80\x88\x80" },
 
1048
  { 0x08000400, "\xFC\x88\x80\x80\x90\x80" },
 
1049
  { 0x08000800, "\xFC\x88\x80\x80\xA0\x80" },
 
1050
  { 0x08001000, "\xFC\x88\x80\x81\x80\x80" },
 
1051
  { 0x08002000, "\xFC\x88\x80\x82\x80\x80" },
 
1052
  { 0x08004000, "\xFC\x88\x80\x84\x80\x80" },
 
1053
  { 0x08008000, "\xFC\x88\x80\x88\x80\x80" },
 
1054
  { 0x08010000, "\xFC\x88\x80\x90\x80\x80" },
 
1055
  { 0x08020000, "\xFC\x88\x80\xA0\x80\x80" },
 
1056
  { 0x08040000, "\xFC\x88\x81\x80\x80\x80" },
 
1057
  { 0x08080000, "\xFC\x88\x82\x80\x80\x80" },
 
1058
  { 0x08100000, "\xFC\x88\x84\x80\x80\x80" },
 
1059
  { 0x08200000, "\xFC\x88\x88\x80\x80\x80" },
 
1060
  { 0x08400000, "\xFC\x88\x90\x80\x80\x80" },
 
1061
  { 0x08800000, "\xFC\x88\xA0\x80\x80\x80" },
 
1062
  { 0x09000000, "\xFC\x89\x80\x80\x80\x80" },
 
1063
  { 0x0A000000, "\xFC\x8A\x80\x80\x80\x80" },
 
1064
  { 0x0C000000, "\xFC\x8C\x80\x80\x80\x80" },
 
1065
  { 0x0FFFFFFF, "\xFC\x8F\xBF\xBF\xBF\xBF" },
 
1066
  { 0x10000000, "\xFC\x90\x80\x80\x80\x80" },
 
1067
  { 0x10000001, "\xFC\x90\x80\x80\x80\x81" },
 
1068
  { 0x10000002, "\xFC\x90\x80\x80\x80\x82" },
 
1069
  { 0x10000004, "\xFC\x90\x80\x80\x80\x84" },
 
1070
  { 0x10000008, "\xFC\x90\x80\x80\x80\x88" },
 
1071
  { 0x10000010, "\xFC\x90\x80\x80\x80\x90" },
 
1072
  { 0x10000020, "\xFC\x90\x80\x80\x80\xA0" },
 
1073
  { 0x10000040, "\xFC\x90\x80\x80\x81\x80" },
 
1074
  { 0x10000080, "\xFC\x90\x80\x80\x82\x80" },
 
1075
  { 0x10000100, "\xFC\x90\x80\x80\x84\x80" },
 
1076
  { 0x10000200, "\xFC\x90\x80\x80\x88\x80" },
 
1077
  { 0x10000400, "\xFC\x90\x80\x80\x90\x80" },
 
1078
  { 0x10000800, "\xFC\x90\x80\x80\xA0\x80" },
 
1079
  { 0x10001000, "\xFC\x90\x80\x81\x80\x80" },
 
1080
  { 0x10002000, "\xFC\x90\x80\x82\x80\x80" },
 
1081
  { 0x10004000, "\xFC\x90\x80\x84\x80\x80" },
 
1082
  { 0x10008000, "\xFC\x90\x80\x88\x80\x80" },
 
1083
  { 0x10010000, "\xFC\x90\x80\x90\x80\x80" },
 
1084
  { 0x10020000, "\xFC\x90\x80\xA0\x80\x80" },
 
1085
  { 0x10040000, "\xFC\x90\x81\x80\x80\x80" },
 
1086
  { 0x10080000, "\xFC\x90\x82\x80\x80\x80" },
 
1087
  { 0x10100000, "\xFC\x90\x84\x80\x80\x80" },
 
1088
  { 0x10200000, "\xFC\x90\x88\x80\x80\x80" },
 
1089
  { 0x10400000, "\xFC\x90\x90\x80\x80\x80" },
 
1090
  { 0x10800000, "\xFC\x90\xA0\x80\x80\x80" },
 
1091
  { 0x11000000, "\xFC\x91\x80\x80\x80\x80" },
 
1092
  { 0x12000000, "\xFC\x92\x80\x80\x80\x80" },
 
1093
  { 0x14000000, "\xFC\x94\x80\x80\x80\x80" },
 
1094
  { 0x18000000, "\xFC\x98\x80\x80\x80\x80" },
 
1095
  { 0x1FFFFFFF, "\xFC\x9F\xBF\xBF\xBF\xBF" },
 
1096
  { 0x20000000, "\xFC\xA0\x80\x80\x80\x80" },
 
1097
  { 0x20000001, "\xFC\xA0\x80\x80\x80\x81" },
 
1098
  { 0x20000002, "\xFC\xA0\x80\x80\x80\x82" },
 
1099
  { 0x20000004, "\xFC\xA0\x80\x80\x80\x84" },
 
1100
  { 0x20000008, "\xFC\xA0\x80\x80\x80\x88" },
 
1101
  { 0x20000010, "\xFC\xA0\x80\x80\x80\x90" },
 
1102
  { 0x20000020, "\xFC\xA0\x80\x80\x80\xA0" },
 
1103
  { 0x20000040, "\xFC\xA0\x80\x80\x81\x80" },
 
1104
  { 0x20000080, "\xFC\xA0\x80\x80\x82\x80" },
 
1105
  { 0x20000100, "\xFC\xA0\x80\x80\x84\x80" },
 
1106
  { 0x20000200, "\xFC\xA0\x80\x80\x88\x80" },
 
1107
  { 0x20000400, "\xFC\xA0\x80\x80\x90\x80" },
 
1108
  { 0x20000800, "\xFC\xA0\x80\x80\xA0\x80" },
 
1109
  { 0x20001000, "\xFC\xA0\x80\x81\x80\x80" },
 
1110
  { 0x20002000, "\xFC\xA0\x80\x82\x80\x80" },
 
1111
  { 0x20004000, "\xFC\xA0\x80\x84\x80\x80" },
 
1112
  { 0x20008000, "\xFC\xA0\x80\x88\x80\x80" },
 
1113
  { 0x20010000, "\xFC\xA0\x80\x90\x80\x80" },
 
1114
  { 0x20020000, "\xFC\xA0\x80\xA0\x80\x80" },
 
1115
  { 0x20040000, "\xFC\xA0\x81\x80\x80\x80" },
 
1116
  { 0x20080000, "\xFC\xA0\x82\x80\x80\x80" },
 
1117
  { 0x20100000, "\xFC\xA0\x84\x80\x80\x80" },
 
1118
  { 0x20200000, "\xFC\xA0\x88\x80\x80\x80" },
 
1119
  { 0x20400000, "\xFC\xA0\x90\x80\x80\x80" },
 
1120
  { 0x20800000, "\xFC\xA0\xA0\x80\x80\x80" },
 
1121
  { 0x21000000, "\xFC\xA1\x80\x80\x80\x80" },
 
1122
  { 0x22000000, "\xFC\xA2\x80\x80\x80\x80" },
 
1123
  { 0x24000000, "\xFC\xA4\x80\x80\x80\x80" },
 
1124
  { 0x28000000, "\xFC\xA8\x80\x80\x80\x80" },
 
1125
  { 0x30000000, "\xFC\xB0\x80\x80\x80\x80" },
 
1126
  { 0x3FFFFFFF, "\xFC\xBF\xBF\xBF\xBF\xBF" },
 
1127
  { 0x40000000, "\xFD\x80\x80\x80\x80\x80" },
 
1128
  { 0x40000001, "\xFD\x80\x80\x80\x80\x81" },
 
1129
  { 0x40000002, "\xFD\x80\x80\x80\x80\x82" },
 
1130
  { 0x40000004, "\xFD\x80\x80\x80\x80\x84" },
 
1131
  { 0x40000008, "\xFD\x80\x80\x80\x80\x88" },
 
1132
  { 0x40000010, "\xFD\x80\x80\x80\x80\x90" },
 
1133
  { 0x40000020, "\xFD\x80\x80\x80\x80\xA0" },
 
1134
  { 0x40000040, "\xFD\x80\x80\x80\x81\x80" },
 
1135
  { 0x40000080, "\xFD\x80\x80\x80\x82\x80" },
 
1136
  { 0x40000100, "\xFD\x80\x80\x80\x84\x80" },
 
1137
  { 0x40000200, "\xFD\x80\x80\x80\x88\x80" },
 
1138
  { 0x40000400, "\xFD\x80\x80\x80\x90\x80" },
 
1139
  { 0x40000800, "\xFD\x80\x80\x80\xA0\x80" },
 
1140
  { 0x40001000, "\xFD\x80\x80\x81\x80\x80" },
 
1141
  { 0x40002000, "\xFD\x80\x80\x82\x80\x80" },
 
1142
  { 0x40004000, "\xFD\x80\x80\x84\x80\x80" },
 
1143
  { 0x40008000, "\xFD\x80\x80\x88\x80\x80" },
 
1144
  { 0x40010000, "\xFD\x80\x80\x90\x80\x80" },
 
1145
  { 0x40020000, "\xFD\x80\x80\xA0\x80\x80" },
 
1146
  { 0x40040000, "\xFD\x80\x81\x80\x80\x80" },
 
1147
  { 0x40080000, "\xFD\x80\x82\x80\x80\x80" },
 
1148
  { 0x40100000, "\xFD\x80\x84\x80\x80\x80" },
 
1149
  { 0x40200000, "\xFD\x80\x88\x80\x80\x80" },
 
1150
  { 0x40400000, "\xFD\x80\x90\x80\x80\x80" },
 
1151
  { 0x40800000, "\xFD\x80\xA0\x80\x80\x80" },
 
1152
  { 0x41000000, "\xFD\x81\x80\x80\x80\x80" },
 
1153
  { 0x42000000, "\xFD\x82\x80\x80\x80\x80" },
 
1154
  { 0x44000000, "\xFD\x84\x80\x80\x80\x80" },
 
1155
  { 0x48000000, "\xFD\x88\x80\x80\x80\x80" },
 
1156
  { 0x50000000, "\xFD\x90\x80\x80\x80\x80" },
 
1157
  { 0x60000000, "\xFD\xA0\x80\x80\x80\x80" },
 
1158
  { 0x7FFFFFFF, "\xFD\xBF\xBF\xBF\xBF\xBF" }
 
1159
};
 
1160
 
 
1161
/*
 
1162
 * UCS-2 vectors
 
1163
 */
 
1164
 
 
1165
struct ucs2 ucs2[] = {
 
1166
  { 0x0001, "\x01" },
 
1167
  { 0x0002, "\x02" },
 
1168
  { 0x0003, "\x03" },
 
1169
  { 0x0004, "\x04" },
 
1170
  { 0x0007, "\x07" },
 
1171
  { 0x0008, "\x08" },
 
1172
  { 0x000F, "\x0F" },
 
1173
  { 0x0010, "\x10" },
 
1174
  { 0x001F, "\x1F" },
 
1175
  { 0x0020, "\x20" },
 
1176
  { 0x003F, "\x3F" },
 
1177
  { 0x0040, "\x40" },
 
1178
  { 0x007F, "\x7F" },
 
1179
          
 
1180
  { 0x0080, "\xC2\x80" },
 
1181
  { 0x0081, "\xC2\x81" },
 
1182
  { 0x0082, "\xC2\x82" },
 
1183
  { 0x0084, "\xC2\x84" },
 
1184
  { 0x0088, "\xC2\x88" },
 
1185
  { 0x0090, "\xC2\x90" },
 
1186
  { 0x00A0, "\xC2\xA0" },
 
1187
  { 0x00C0, "\xC3\x80" },
 
1188
  { 0x00FF, "\xC3\xBF" },
 
1189
  { 0x0100, "\xC4\x80" },
 
1190
  { 0x0101, "\xC4\x81" },
 
1191
  { 0x0102, "\xC4\x82" },
 
1192
  { 0x0104, "\xC4\x84" },
 
1193
  { 0x0108, "\xC4\x88" },
 
1194
  { 0x0110, "\xC4\x90" },
 
1195
  { 0x0120, "\xC4\xA0" },
 
1196
  { 0x0140, "\xC5\x80" },
 
1197
  { 0x0180, "\xC6\x80" },
 
1198
  { 0x01FF, "\xC7\xBF" },
 
1199
  { 0x0200, "\xC8\x80" },
 
1200
  { 0x0201, "\xC8\x81" },
 
1201
  { 0x0202, "\xC8\x82" },
 
1202
  { 0x0204, "\xC8\x84" },
 
1203
  { 0x0208, "\xC8\x88" },
 
1204
  { 0x0210, "\xC8\x90" },
 
1205
  { 0x0220, "\xC8\xA0" },
 
1206
  { 0x0240, "\xC9\x80" },
 
1207
  { 0x0280, "\xCA\x80" },
 
1208
  { 0x0300, "\xCC\x80" },
 
1209
  { 0x03FF, "\xCF\xBF" },
 
1210
  { 0x0400, "\xD0\x80" },
 
1211
  { 0x0401, "\xD0\x81" },
 
1212
  { 0x0402, "\xD0\x82" },
 
1213
  { 0x0404, "\xD0\x84" },
 
1214
  { 0x0408, "\xD0\x88" },
 
1215
  { 0x0410, "\xD0\x90" },
 
1216
  { 0x0420, "\xD0\xA0" },
 
1217
  { 0x0440, "\xD1\x80" },
 
1218
  { 0x0480, "\xD2\x80" },
 
1219
  { 0x0500, "\xD4\x80" },
 
1220
  { 0x0600, "\xD8\x80" },
 
1221
  { 0x07FF, "\xDF\xBF" },
 
1222
          
 
1223
  { 0x0800, "\xE0\xA0\x80" },
 
1224
  { 0x0801, "\xE0\xA0\x81" },
 
1225
  { 0x0802, "\xE0\xA0\x82" },
 
1226
  { 0x0804, "\xE0\xA0\x84" },
 
1227
  { 0x0808, "\xE0\xA0\x88" },
 
1228
  { 0x0810, "\xE0\xA0\x90" },
 
1229
  { 0x0820, "\xE0\xA0\xA0" },
 
1230
  { 0x0840, "\xE0\xA1\x80" },
 
1231
  { 0x0880, "\xE0\xA2\x80" },
 
1232
  { 0x0900, "\xE0\xA4\x80" },
 
1233
  { 0x0A00, "\xE0\xA8\x80" },
 
1234
  { 0x0C00, "\xE0\xB0\x80" },
 
1235
  { 0x0FFF, "\xE0\xBF\xBF" },
 
1236
  { 0x1000, "\xE1\x80\x80" },
 
1237
  { 0x1001, "\xE1\x80\x81" },
 
1238
  { 0x1002, "\xE1\x80\x82" },
 
1239
  { 0x1004, "\xE1\x80\x84" },
 
1240
  { 0x1008, "\xE1\x80\x88" },
 
1241
  { 0x1010, "\xE1\x80\x90" },
 
1242
  { 0x1020, "\xE1\x80\xA0" },
 
1243
  { 0x1040, "\xE1\x81\x80" },
 
1244
  { 0x1080, "\xE1\x82\x80" },
 
1245
  { 0x1100, "\xE1\x84\x80" },
 
1246
  { 0x1200, "\xE1\x88\x80" },
 
1247
  { 0x1400, "\xE1\x90\x80" },
 
1248
  { 0x1800, "\xE1\xA0\x80" },
 
1249
  { 0x1FFF, "\xE1\xBF\xBF" },
 
1250
  { 0x2000, "\xE2\x80\x80" },
 
1251
  { 0x2001, "\xE2\x80\x81" },
 
1252
  { 0x2002, "\xE2\x80\x82" },
 
1253
  { 0x2004, "\xE2\x80\x84" },
 
1254
  { 0x2008, "\xE2\x80\x88" },
 
1255
  { 0x2010, "\xE2\x80\x90" },
 
1256
  { 0x2020, "\xE2\x80\xA0" },
 
1257
  { 0x2040, "\xE2\x81\x80" },
 
1258
  { 0x2080, "\xE2\x82\x80" },
 
1259
  { 0x2100, "\xE2\x84\x80" },
 
1260
  { 0x2200, "\xE2\x88\x80" },
 
1261
  { 0x2400, "\xE2\x90\x80" },
 
1262
  { 0x2800, "\xE2\xA0\x80" },
 
1263
  { 0x3000, "\xE3\x80\x80" },
 
1264
  { 0x3FFF, "\xE3\xBF\xBF" },
 
1265
  { 0x4000, "\xE4\x80\x80" },
 
1266
  { 0x4001, "\xE4\x80\x81" },
 
1267
  { 0x4002, "\xE4\x80\x82" },
 
1268
  { 0x4004, "\xE4\x80\x84" },
 
1269
  { 0x4008, "\xE4\x80\x88" },
 
1270
  { 0x4010, "\xE4\x80\x90" },
 
1271
  { 0x4020, "\xE4\x80\xA0" },
 
1272
  { 0x4040, "\xE4\x81\x80" },
 
1273
  { 0x4080, "\xE4\x82\x80" },
 
1274
  { 0x4100, "\xE4\x84\x80" },
 
1275
  { 0x4200, "\xE4\x88\x80" },
 
1276
  { 0x4400, "\xE4\x90\x80" },
 
1277
  { 0x4800, "\xE4\xA0\x80" },
 
1278
  { 0x5000, "\xE5\x80\x80" },
 
1279
  { 0x6000, "\xE6\x80\x80" },
 
1280
  { 0x7FFF, "\xE7\xBF\xBF" },
 
1281
  { 0x8000, "\xE8\x80\x80" },
 
1282
  { 0x8001, "\xE8\x80\x81" },
 
1283
  { 0x8002, "\xE8\x80\x82" },
 
1284
  { 0x8004, "\xE8\x80\x84" },
 
1285
  { 0x8008, "\xE8\x80\x88" },
 
1286
  { 0x8010, "\xE8\x80\x90" },
 
1287
  { 0x8020, "\xE8\x80\xA0" },
 
1288
  { 0x8040, "\xE8\x81\x80" },
 
1289
  { 0x8080, "\xE8\x82\x80" },
 
1290
  { 0x8100, "\xE8\x84\x80" },
 
1291
  { 0x8200, "\xE8\x88\x80" },
 
1292
  { 0x8400, "\xE8\x90\x80" },
 
1293
  { 0x8800, "\xE8\xA0\x80" },
 
1294
  { 0x9000, "\xE9\x80\x80" },
 
1295
  { 0xA000, "\xEA\x80\x80" },
 
1296
  { 0xC000, "\xEC\x80\x80" },
 
1297
  { 0xFFFF, "\xEF\xBF\xBF" }
 
1298
 
 
1299
};
 
1300
 
 
1301
#ifdef UTF16
 
1302
/*
 
1303
 * UTF-16 vectors
 
1304
 */
 
1305
 
 
1306
struct utf16 utf16[] = {
 
1307
  { 0x00010000, { 0xD800, 0xDC00 } },
 
1308
  { 0x00010001, { 0xD800, 0xDC01 } },
 
1309
  { 0x00010002, { 0xD800, 0xDC02 } },
 
1310
  { 0x00010003, { 0xD800, 0xDC03 } },
 
1311
  { 0x00010004, { 0xD800, 0xDC04 } },
 
1312
  { 0x00010007, { 0xD800, 0xDC07 } },
 
1313
  { 0x00010008, { 0xD800, 0xDC08 } },
 
1314
  { 0x0001000F, { 0xD800, 0xDC0F } },
 
1315
  { 0x00010010, { 0xD800, 0xDC10 } },
 
1316
  { 0x0001001F, { 0xD800, 0xDC1F } },
 
1317
  { 0x00010020, { 0xD800, 0xDC20 } },
 
1318
  { 0x0001003F, { 0xD800, 0xDC3F } },
 
1319
  { 0x00010040, { 0xD800, 0xDC40 } },
 
1320
  { 0x0001007F, { 0xD800, 0xDC7F } },
 
1321
  { 0x00010080, { 0xD800, 0xDC80 } },
 
1322
  { 0x00010081, { 0xD800, 0xDC81 } },
 
1323
  { 0x00010082, { 0xD800, 0xDC82 } },
 
1324
  { 0x00010084, { 0xD800, 0xDC84 } },
 
1325
  { 0x00010088, { 0xD800, 0xDC88 } },
 
1326
  { 0x00010090, { 0xD800, 0xDC90 } },
 
1327
  { 0x000100A0, { 0xD800, 0xDCA0 } },
 
1328
  { 0x000100C0, { 0xD800, 0xDCC0 } },
 
1329
  { 0x000100FF, { 0xD800, 0xDCFF } },
 
1330
  { 0x00010100, { 0xD800, 0xDD00 } },
 
1331
  { 0x00010101, { 0xD800, 0xDD01 } },
 
1332
  { 0x00010102, { 0xD800, 0xDD02 } },
 
1333
  { 0x00010104, { 0xD800, 0xDD04 } },
 
1334
  { 0x00010108, { 0xD800, 0xDD08 } },
 
1335
  { 0x00010110, { 0xD800, 0xDD10 } },
 
1336
  { 0x00010120, { 0xD800, 0xDD20 } },
 
1337
  { 0x00010140, { 0xD800, 0xDD40 } },
 
1338
  { 0x00010180, { 0xD800, 0xDD80 } },
 
1339
  { 0x000101FF, { 0xD800, 0xDDFF } },
 
1340
  { 0x00010200, { 0xD800, 0xDE00 } },
 
1341
  { 0x00010201, { 0xD800, 0xDE01 } },
 
1342
  { 0x00010202, { 0xD800, 0xDE02 } },
 
1343
  { 0x00010204, { 0xD800, 0xDE04 } },
 
1344
  { 0x00010208, { 0xD800, 0xDE08 } },
 
1345
  { 0x00010210, { 0xD800, 0xDE10 } },
 
1346
  { 0x00010220, { 0xD800, 0xDE20 } },
 
1347
  { 0x00010240, { 0xD800, 0xDE40 } },
 
1348
  { 0x00010280, { 0xD800, 0xDE80 } },
 
1349
  { 0x00010300, { 0xD800, 0xDF00 } },
 
1350
  { 0x000103FF, { 0xD800, 0xDFFF } },
 
1351
  { 0x00010400, { 0xD801, 0xDC00 } },
 
1352
  { 0x00010401, { 0xD801, 0xDC01 } },
 
1353
  { 0x00010402, { 0xD801, 0xDC02 } },
 
1354
  { 0x00010404, { 0xD801, 0xDC04 } },
 
1355
  { 0x00010408, { 0xD801, 0xDC08 } },
 
1356
  { 0x00010410, { 0xD801, 0xDC10 } },
 
1357
  { 0x00010420, { 0xD801, 0xDC20 } },
 
1358
  { 0x00010440, { 0xD801, 0xDC40 } },
 
1359
  { 0x00010480, { 0xD801, 0xDC80 } },
 
1360
  { 0x00010500, { 0xD801, 0xDD00 } },
 
1361
  { 0x00010600, { 0xD801, 0xDE00 } },
 
1362
  { 0x000107FF, { 0xD801, 0xDFFF } },
 
1363
  { 0x00010800, { 0xD802, 0xDC00 } },
 
1364
  { 0x00010801, { 0xD802, 0xDC01 } },
 
1365
  { 0x00010802, { 0xD802, 0xDC02 } },
 
1366
  { 0x00010804, { 0xD802, 0xDC04 } },
 
1367
  { 0x00010808, { 0xD802, 0xDC08 } },
 
1368
  { 0x00010810, { 0xD802, 0xDC10 } },
 
1369
  { 0x00010820, { 0xD802, 0xDC20 } },
 
1370
  { 0x00010840, { 0xD802, 0xDC40 } },
 
1371
  { 0x00010880, { 0xD802, 0xDC80 } },
 
1372
  { 0x00010900, { 0xD802, 0xDD00 } },
 
1373
  { 0x00010A00, { 0xD802, 0xDE00 } },
 
1374
  { 0x00010C00, { 0xD803, 0xDC00 } },
 
1375
  { 0x00010FFF, { 0xD803, 0xDFFF } },
 
1376
  { 0x00011000, { 0xD804, 0xDC00 } },
 
1377
  { 0x00011001, { 0xD804, 0xDC01 } },
 
1378
  { 0x00011002, { 0xD804, 0xDC02 } },
 
1379
  { 0x00011004, { 0xD804, 0xDC04 } },
 
1380
  { 0x00011008, { 0xD804, 0xDC08 } },
 
1381
  { 0x00011010, { 0xD804, 0xDC10 } },
 
1382
  { 0x00011020, { 0xD804, 0xDC20 } },
 
1383
  { 0x00011040, { 0xD804, 0xDC40 } },
 
1384
  { 0x00011080, { 0xD804, 0xDC80 } },
 
1385
  { 0x00011100, { 0xD804, 0xDD00 } },
 
1386
  { 0x00011200, { 0xD804, 0xDE00 } },
 
1387
  { 0x00011400, { 0xD805, 0xDC00 } },
 
1388
  { 0x00011800, { 0xD806, 0xDC00 } },
 
1389
  { 0x00011FFF, { 0xD807, 0xDFFF } },
 
1390
  { 0x00012000, { 0xD808, 0xDC00 } },
 
1391
  { 0x00012001, { 0xD808, 0xDC01 } },
 
1392
  { 0x00012002, { 0xD808, 0xDC02 } },
 
1393
  { 0x00012004, { 0xD808, 0xDC04 } },
 
1394
  { 0x00012008, { 0xD808, 0xDC08 } },
 
1395
  { 0x00012010, { 0xD808, 0xDC10 } },
 
1396
  { 0x00012020, { 0xD808, 0xDC20 } },
 
1397
  { 0x00012040, { 0xD808, 0xDC40 } },
 
1398
  { 0x00012080, { 0xD808, 0xDC80 } },
 
1399
  { 0x00012100, { 0xD808, 0xDD00 } },
 
1400
  { 0x00012200, { 0xD808, 0xDE00 } },
 
1401
  { 0x00012400, { 0xD809, 0xDC00 } },
 
1402
  { 0x00012800, { 0xD80A, 0xDC00 } },
 
1403
  { 0x00013000, { 0xD80C, 0xDC00 } },
 
1404
  { 0x00013FFF, { 0xD80F, 0xDFFF } },
 
1405
  { 0x00014000, { 0xD810, 0xDC00 } },
 
1406
  { 0x00014001, { 0xD810, 0xDC01 } },
 
1407
  { 0x00014002, { 0xD810, 0xDC02 } },
 
1408
  { 0x00014004, { 0xD810, 0xDC04 } },
 
1409
  { 0x00014008, { 0xD810, 0xDC08 } },
 
1410
  { 0x00014010, { 0xD810, 0xDC10 } },
 
1411
  { 0x00014020, { 0xD810, 0xDC20 } },
 
1412
  { 0x00014040, { 0xD810, 0xDC40 } },
 
1413
  { 0x00014080, { 0xD810, 0xDC80 } },
 
1414
  { 0x00014100, { 0xD810, 0xDD00 } },
 
1415
  { 0x00014200, { 0xD810, 0xDE00 } },
 
1416
  { 0x00014400, { 0xD811, 0xDC00 } },
 
1417
  { 0x00014800, { 0xD812, 0xDC00 } },
 
1418
  { 0x00015000, { 0xD814, 0xDC00 } },
 
1419
  { 0x00016000, { 0xD818, 0xDC00 } },
 
1420
  { 0x00017FFF, { 0xD81F, 0xDFFF } },
 
1421
  { 0x00018000, { 0xD820, 0xDC00 } },
 
1422
  { 0x00018001, { 0xD820, 0xDC01 } },
 
1423
  { 0x00018002, { 0xD820, 0xDC02 } },
 
1424
  { 0x00018004, { 0xD820, 0xDC04 } },
 
1425
  { 0x00018008, { 0xD820, 0xDC08 } },
 
1426
  { 0x00018010, { 0xD820, 0xDC10 } },
 
1427
  { 0x00018020, { 0xD820, 0xDC20 } },
 
1428
  { 0x00018040, { 0xD820, 0xDC40 } },
 
1429
  { 0x00018080, { 0xD820, 0xDC80 } },
 
1430
  { 0x00018100, { 0xD820, 0xDD00 } },
 
1431
  { 0x00018200, { 0xD820, 0xDE00 } },
 
1432
  { 0x00018400, { 0xD821, 0xDC00 } },
 
1433
  { 0x00018800, { 0xD822, 0xDC00 } },
 
1434
  { 0x00019000, { 0xD824, 0xDC00 } },
 
1435
  { 0x0001A000, { 0xD828, 0xDC00 } },
 
1436
  { 0x0001C000, { 0xD830, 0xDC00 } },
 
1437
  { 0x0001FFFF, { 0xD83F, 0xDFFF } },
 
1438
  { 0x00020000, { 0xD840, 0xDC00 } },
 
1439
  { 0x00020001, { 0xD840, 0xDC01 } },
 
1440
  { 0x00020002, { 0xD840, 0xDC02 } },
 
1441
  { 0x00020004, { 0xD840, 0xDC04 } },
 
1442
  { 0x00020008, { 0xD840, 0xDC08 } },
 
1443
  { 0x00020010, { 0xD840, 0xDC10 } },
 
1444
  { 0x00020020, { 0xD840, 0xDC20 } },
 
1445
  { 0x00020040, { 0xD840, 0xDC40 } },
 
1446
  { 0x00020080, { 0xD840, 0xDC80 } },
 
1447
  { 0x00020100, { 0xD840, 0xDD00 } },
 
1448
  { 0x00020200, { 0xD840, 0xDE00 } },
 
1449
  { 0x00020400, { 0xD841, 0xDC00 } },
 
1450
  { 0x00020800, { 0xD842, 0xDC00 } },
 
1451
  { 0x00021000, { 0xD844, 0xDC00 } },
 
1452
  { 0x00022000, { 0xD848, 0xDC00 } },
 
1453
  { 0x00024000, { 0xD850, 0xDC00 } },
 
1454
  { 0x00028000, { 0xD860, 0xDC00 } },
 
1455
  { 0x0002FFFF, { 0xD87F, 0xDFFF } },
 
1456
  { 0x00030000, { 0xD880, 0xDC00 } },
 
1457
  { 0x00030001, { 0xD880, 0xDC01 } },
 
1458
  { 0x00030002, { 0xD880, 0xDC02 } },
 
1459
  { 0x00030004, { 0xD880, 0xDC04 } },
 
1460
  { 0x00030008, { 0xD880, 0xDC08 } },
 
1461
  { 0x00030010, { 0xD880, 0xDC10 } },
 
1462
  { 0x00030020, { 0xD880, 0xDC20 } },
 
1463
  { 0x00030040, { 0xD880, 0xDC40 } },
 
1464
  { 0x00030080, { 0xD880, 0xDC80 } },
 
1465
  { 0x00030100, { 0xD880, 0xDD00 } },
 
1466
  { 0x00030200, { 0xD880, 0xDE00 } },
 
1467
  { 0x00030400, { 0xD881, 0xDC00 } },
 
1468
  { 0x00030800, { 0xD882, 0xDC00 } },
 
1469
  { 0x00031000, { 0xD884, 0xDC00 } },
 
1470
  { 0x00032000, { 0xD888, 0xDC00 } },
 
1471
  { 0x00034000, { 0xD890, 0xDC00 } },
 
1472
  { 0x00038000, { 0xD8A0, 0xDC00 } },
 
1473
  { 0x0003FFFF, { 0xD8BF, 0xDFFF } },
 
1474
  { 0x00040000, { 0xD8C0, 0xDC00 } },
 
1475
  { 0x00040001, { 0xD8C0, 0xDC01 } },
 
1476
  { 0x00040002, { 0xD8C0, 0xDC02 } },
 
1477
  { 0x00040004, { 0xD8C0, 0xDC04 } },
 
1478
  { 0x00040008, { 0xD8C0, 0xDC08 } },
 
1479
  { 0x00040010, { 0xD8C0, 0xDC10 } },
 
1480
  { 0x00040020, { 0xD8C0, 0xDC20 } },
 
1481
  { 0x00040040, { 0xD8C0, 0xDC40 } },
 
1482
  { 0x00040080, { 0xD8C0, 0xDC80 } },
 
1483
  { 0x00040100, { 0xD8C0, 0xDD00 } },
 
1484
  { 0x00040200, { 0xD8C0, 0xDE00 } },
 
1485
  { 0x00040400, { 0xD8C1, 0xDC00 } },
 
1486
  { 0x00040800, { 0xD8C2, 0xDC00 } },
 
1487
  { 0x00041000, { 0xD8C4, 0xDC00 } },
 
1488
  { 0x00042000, { 0xD8C8, 0xDC00 } },
 
1489
  { 0x00044000, { 0xD8D0, 0xDC00 } },
 
1490
  { 0x00048000, { 0xD8E0, 0xDC00 } },
 
1491
  { 0x0004FFFF, { 0xD8FF, 0xDFFF } },
 
1492
  { 0x00050000, { 0xD900, 0xDC00 } },
 
1493
  { 0x00050001, { 0xD900, 0xDC01 } },
 
1494
  { 0x00050002, { 0xD900, 0xDC02 } },
 
1495
  { 0x00050004, { 0xD900, 0xDC04 } },
 
1496
  { 0x00050008, { 0xD900, 0xDC08 } },
 
1497
  { 0x00050010, { 0xD900, 0xDC10 } },
 
1498
  { 0x00050020, { 0xD900, 0xDC20 } },
 
1499
  { 0x00050040, { 0xD900, 0xDC40 } },
 
1500
  { 0x00050080, { 0xD900, 0xDC80 } },
 
1501
  { 0x00050100, { 0xD900, 0xDD00 } },
 
1502
  { 0x00050200, { 0xD900, 0xDE00 } },
 
1503
  { 0x00050400, { 0xD901, 0xDC00 } },
 
1504
  { 0x00050800, { 0xD902, 0xDC00 } },
 
1505
  { 0x00051000, { 0xD904, 0xDC00 } },
 
1506
  { 0x00052000, { 0xD908, 0xDC00 } },
 
1507
  { 0x00054000, { 0xD910, 0xDC00 } },
 
1508
  { 0x00058000, { 0xD920, 0xDC00 } },
 
1509
  { 0x00060000, { 0xD940, 0xDC00 } },
 
1510
  { 0x00070000, { 0xD980, 0xDC00 } },
 
1511
  { 0x0007FFFF, { 0xD9BF, 0xDFFF } },
 
1512
  { 0x00080000, { 0xD9C0, 0xDC00 } },
 
1513
  { 0x00080001, { 0xD9C0, 0xDC01 } },
 
1514
  { 0x00080002, { 0xD9C0, 0xDC02 } },
 
1515
  { 0x00080004, { 0xD9C0, 0xDC04 } },
 
1516
  { 0x00080008, { 0xD9C0, 0xDC08 } },
 
1517
  { 0x00080010, { 0xD9C0, 0xDC10 } },
 
1518
  { 0x00080020, { 0xD9C0, 0xDC20 } },
 
1519
  { 0x00080040, { 0xD9C0, 0xDC40 } },
 
1520
  { 0x00080080, { 0xD9C0, 0xDC80 } },
 
1521
  { 0x00080100, { 0xD9C0, 0xDD00 } },
 
1522
  { 0x00080200, { 0xD9C0, 0xDE00 } },
 
1523
  { 0x00080400, { 0xD9C1, 0xDC00 } },
 
1524
  { 0x00080800, { 0xD9C2, 0xDC00 } },
 
1525
  { 0x00081000, { 0xD9C4, 0xDC00 } },
 
1526
  { 0x00082000, { 0xD9C8, 0xDC00 } },
 
1527
  { 0x00084000, { 0xD9D0, 0xDC00 } },
 
1528
  { 0x00088000, { 0xD9E0, 0xDC00 } },
 
1529
  { 0x0008FFFF, { 0xD9FF, 0xDFFF } },
 
1530
  { 0x00090000, { 0xDA00, 0xDC00 } },
 
1531
  { 0x00090001, { 0xDA00, 0xDC01 } },
 
1532
  { 0x00090002, { 0xDA00, 0xDC02 } },
 
1533
  { 0x00090004, { 0xDA00, 0xDC04 } },
 
1534
  { 0x00090008, { 0xDA00, 0xDC08 } },
 
1535
  { 0x00090010, { 0xDA00, 0xDC10 } },
 
1536
  { 0x00090020, { 0xDA00, 0xDC20 } },
 
1537
  { 0x00090040, { 0xDA00, 0xDC40 } },
 
1538
  { 0x00090080, { 0xDA00, 0xDC80 } },
 
1539
  { 0x00090100, { 0xDA00, 0xDD00 } },
 
1540
  { 0x00090200, { 0xDA00, 0xDE00 } },
 
1541
  { 0x00090400, { 0xDA01, 0xDC00 } },
 
1542
  { 0x00090800, { 0xDA02, 0xDC00 } },
 
1543
  { 0x00091000, { 0xDA04, 0xDC00 } },
 
1544
  { 0x00092000, { 0xDA08, 0xDC00 } },
 
1545
  { 0x00094000, { 0xDA10, 0xDC00 } },
 
1546
  { 0x00098000, { 0xDA20, 0xDC00 } },
 
1547
  { 0x000A0000, { 0xDA40, 0xDC00 } },
 
1548
  { 0x000B0000, { 0xDA80, 0xDC00 } },
 
1549
  { 0x000C0000, { 0xDAC0, 0xDC00 } },
 
1550
  { 0x000D0000, { 0xDB00, 0xDC00 } },
 
1551
  { 0x000FFFFF, { 0xDBBF, 0xDFFF } },
 
1552
  { 0x0010FFFF, { 0xDBFF, 0xDFFF } }
 
1553
 
 
1554
};
 
1555
#endif /* UTF16 */
 
1556
 
 
1557
static void
 
1558
dump_utf8
 
1559
(
 
1560
  char *word,
 
1561
  unsigned char *utf8,
 
1562
  char *end
 
1563
)
 
1564
{
 
1565
  fprintf(stdout, "%s ", word);
 
1566
  for( ; *utf8; utf8++ ) {
 
1567
    fprintf(stdout, "%02.2x ", (unsigned int)*utf8);
 
1568
  }
 
1569
  fprintf(stdout, "%s", end);
 
1570
}
 
1571
 
 
1572
static PRBool
 
1573
test_ucs4_chars
 
1574
(
 
1575
  void
 
1576
)
 
1577
{
 
1578
  PRBool rv = PR_TRUE;
 
1579
  int i;
 
1580
 
 
1581
  for( i = 0; i < sizeof(ucs4)/sizeof(ucs4[0]); i++ ) {
 
1582
    struct ucs4 *e = &ucs4[i];
 
1583
    PRBool result;
 
1584
    unsigned char utf8[8];
 
1585
    unsigned int len = 0;
 
1586
    PRUint32 back = 0;
 
1587
 
 
1588
    (void)memset(utf8, 0, sizeof(utf8));
 
1589
    
 
1590
    result = sec_port_ucs4_utf8_conversion_function(PR_FALSE, 
 
1591
      (unsigned char *)&e->c, sizeof(e->c), utf8, sizeof(utf8), &len);
 
1592
 
 
1593
    if( !result ) {
 
1594
      fprintf(stdout, "Failed to convert UCS-4 0x%08.8x to UTF-8\n", e->c);
 
1595
      rv = PR_FALSE;
 
1596
      continue;
 
1597
    }
 
1598
 
 
1599
    if( (len >= sizeof(utf8)) ||
 
1600
        (strlen(e->utf8) != len) ||
 
1601
        (utf8[len] = '\0', 0 != strcmp(e->utf8, utf8)) ) {
 
1602
      fprintf(stdout, "Wrong conversion of UCS-4 0x%08.8x to UTF-8: ", e->c);
 
1603
      dump_utf8("expected", e->utf8, ", ");
 
1604
      dump_utf8("received", utf8, "\n");
 
1605
      rv = PR_FALSE;
 
1606
      continue;
 
1607
    }
 
1608
 
 
1609
    result = sec_port_ucs4_utf8_conversion_function(PR_TRUE,
 
1610
      utf8, len, (unsigned char *)&back, sizeof(back), &len);
 
1611
 
 
1612
    if( !result ) {
 
1613
      dump_utf8("Failed to convert UTF-8", utf8, "to UCS-4\n");
 
1614
      rv = PR_FALSE;
 
1615
      continue;
 
1616
    }
 
1617
 
 
1618
    if( (sizeof(back) != len) || (e->c != back) ) {
 
1619
      dump_utf8("Wrong conversion of UTF-8", utf8, " to UCS-4:");
 
1620
      fprintf(stdout, "expected 0x%08.8x, received 0x%08.8x\n", e->c, back);
 
1621
      rv = PR_FALSE;
 
1622
      continue;
 
1623
    }
 
1624
  }
 
1625
 
 
1626
  return rv;
 
1627
}
 
1628
 
 
1629
static PRBool
 
1630
test_ucs2_chars
 
1631
(
 
1632
  void
 
1633
)
 
1634
{
 
1635
  PRBool rv = PR_TRUE;
 
1636
  int i;
 
1637
 
 
1638
  for( i = 0; i < sizeof(ucs2)/sizeof(ucs2[0]); i++ ) {
 
1639
    struct ucs2 *e = &ucs2[i];
 
1640
    PRBool result;
 
1641
    unsigned char utf8[8];
 
1642
    unsigned int len = 0;
 
1643
    PRUint16 back = 0;
 
1644
 
 
1645
    (void)memset(utf8, 0, sizeof(utf8));
 
1646
    
 
1647
    result = sec_port_ucs2_utf8_conversion_function(PR_FALSE,
 
1648
      (unsigned char *)&e->c, sizeof(e->c), utf8, sizeof(utf8), &len);
 
1649
 
 
1650
    if( !result ) {
 
1651
      fprintf(stdout, "Failed to convert UCS-2 0x%04.4x to UTF-8\n", e->c);
 
1652
      rv = PR_FALSE;
 
1653
      continue;
 
1654
    }
 
1655
 
 
1656
    if( (len >= sizeof(utf8)) ||
 
1657
        (strlen(e->utf8) != len) ||
 
1658
        (utf8[len] = '\0', 0 != strcmp(e->utf8, utf8)) ) {
 
1659
      fprintf(stdout, "Wrong conversion of UCS-2 0x%04.4x to UTF-8: ", e->c);
 
1660
      dump_utf8("expected", e->utf8, ", ");
 
1661
      dump_utf8("received", utf8, "\n");
 
1662
      rv = PR_FALSE;
 
1663
      continue;
 
1664
    }
 
1665
 
 
1666
    result = sec_port_ucs2_utf8_conversion_function(PR_TRUE,
 
1667
      utf8, len, (unsigned char *)&back, sizeof(back), &len);
 
1668
 
 
1669
    if( !result ) {
 
1670
      dump_utf8("Failed to convert UTF-8", utf8, "to UCS-2\n");
 
1671
      rv = PR_FALSE;
 
1672
      continue;
 
1673
    }
 
1674
 
 
1675
    if( (sizeof(back) != len) || (e->c != back) ) {
 
1676
      dump_utf8("Wrong conversion of UTF-8", utf8, "to UCS-2:");
 
1677
      fprintf(stdout, "expected 0x%08.8x, received 0x%08.8x\n", e->c, back);
 
1678
      rv = PR_FALSE;
 
1679
      continue;
 
1680
    }
 
1681
  }
 
1682
 
 
1683
  return rv;
 
1684
}
 
1685
 
 
1686
#ifdef UTF16
 
1687
static PRBool
 
1688
test_utf16_chars
 
1689
(
 
1690
  void
 
1691
)
 
1692
{
 
1693
  PRBool rv = PR_TRUE;
 
1694
  int i;
 
1695
 
 
1696
  for( i = 0; i < sizeof(utf16)/sizeof(utf16[0]); i++ ) {
 
1697
    struct utf16 *e = &utf16[i];
 
1698
    PRBool result;
 
1699
    unsigned char utf8[8];
 
1700
    unsigned int len = 0;
 
1701
    PRUint32 back32 = 0;
 
1702
    PRUint16 back[2];
 
1703
 
 
1704
    (void)memset(utf8, 0, sizeof(utf8));
 
1705
    
 
1706
    result = sec_port_ucs2_utf8_conversion_function(PR_FALSE, 
 
1707
      (unsigned char *)&e->w[0], sizeof(e->w), utf8, sizeof(utf8), &len);
 
1708
 
 
1709
    if( !result ) {
 
1710
      fprintf(stdout, "Failed to convert UTF-16 0x%04.4x 0x%04.4x to UTF-8\n", 
 
1711
              e->w[0], e->w[1]);
 
1712
      rv = PR_FALSE;
 
1713
      continue;
 
1714
    }
 
1715
 
 
1716
    result = sec_port_ucs4_utf8_conversion_function(PR_TRUE,
 
1717
      utf8, len, (unsigned char *)&back32, sizeof(back32), &len);
 
1718
 
 
1719
    if( 4 != len ) {
 
1720
      fprintf(stdout, "Failed to convert UTF-16 0x%04.4x 0x%04.4x to UTF-8: "
 
1721
              "unexpected len %d\n", e->w[0], e->w[1], len);
 
1722
      rv = PR_FALSE;
 
1723
      continue;
 
1724
    }
 
1725
 
 
1726
    utf8[len] = '\0'; /* null-terminate for printing */
 
1727
 
 
1728
    if( !result ) {
 
1729
      dump_utf8("Failed to convert UTF-8", utf8, "to UCS-4 (utf-16 test)\n");
 
1730
      rv = PR_FALSE;
 
1731
      continue;
 
1732
    }
 
1733
 
 
1734
    if( (sizeof(back32) != len) || (e->c != back32) ) {
 
1735
      fprintf(stdout, "Wrong conversion of UTF-16 0x%04.4x 0x%04.4x ", 
 
1736
              e->w[0], e->w[1]);
 
1737
      dump_utf8("to UTF-8", utf8, "and then to UCS-4: ");
 
1738
      if( sizeof(back32) != len ) {
 
1739
        fprintf(stdout, "len is %d\n", len);
 
1740
      } else {
 
1741
        fprintf(stdout, "expected 0x%08.8x, received 0x%08.8x\n", e->c, back32);
 
1742
      }
 
1743
      rv = PR_FALSE;
 
1744
      continue;
 
1745
    }
 
1746
 
 
1747
    (void)memset(utf8, 0, sizeof(utf8));
 
1748
    back[0] = back[1] = 0;
 
1749
 
 
1750
    result = sec_port_ucs4_utf8_conversion_function(PR_FALSE,
 
1751
      (unsigned char *)&e->c, sizeof(e->c), utf8, sizeof(utf8), &len);
 
1752
 
 
1753
    if( !result ) {
 
1754
      fprintf(stdout, "Failed to convert UCS-4 0x%08.8x to UTF-8 (utf-16 test)\n",
 
1755
              e->c);
 
1756
      rv = PR_FALSE;
 
1757
      continue;
 
1758
    }
 
1759
 
 
1760
    result = sec_port_ucs2_utf8_conversion_function(PR_TRUE,
 
1761
      utf8, len, (unsigned char *)&back[0], sizeof(back), &len);
 
1762
 
 
1763
    if( 4 != len ) {
 
1764
      fprintf(stdout, "Failed to convert UCS-4 0x%08.8x to UTF-8: "
 
1765
              "unexpected len %d\n", e->c, len);
 
1766
      rv = PR_FALSE;
 
1767
      continue;
 
1768
    }
 
1769
 
 
1770
    utf8[len] = '\0'; /* null-terminate for printing */
 
1771
 
 
1772
    if( !result ) {
 
1773
      dump_utf8("Failed to convert UTF-8", utf8, "to UTF-16\n");
 
1774
      rv = PR_FALSE;
 
1775
      continue;
 
1776
    }
 
1777
 
 
1778
    if( (sizeof(back) != len) || (e->w[0] != back[0]) || (e->w[1] != back[1]) ) {
 
1779
      fprintf(stdout, "Wrong conversion of UCS-4 0x%08.8x to UTF-8", e->c);
 
1780
      dump_utf8("", utf8, "and then to UTF-16:");
 
1781
      if( sizeof(back) != len ) {
 
1782
        fprintf(stdout, "len is %d\n", len);
 
1783
      } else {
 
1784
        fprintf(stdout, "expected 0x%04.4x 0x%04.4x, received 0x%04.4x 0x%04.4xx\n",
 
1785
                e->w[0], e->w[1], back[0], back[1]);
 
1786
      }
 
1787
      rv = PR_FALSE;
 
1788
      continue;
 
1789
    }
 
1790
  }
 
1791
 
 
1792
  return rv;
 
1793
}
 
1794
#endif /* UTF16 */
 
1795
 
 
1796
static PRBool
 
1797
test_iso88591_chars
 
1798
(
 
1799
  void
 
1800
)
 
1801
{
 
1802
  PRBool rv = PR_TRUE;
 
1803
  int i;
 
1804
 
 
1805
  for( i = 0; i < sizeof(ucs2)/sizeof(ucs2[0]); i++ ) {
 
1806
    struct ucs2 *e = &ucs2[i];
 
1807
    PRBool result;
 
1808
    unsigned char iso88591;
 
1809
    unsigned char utf8[3];
 
1810
    unsigned int len = 0;
 
1811
 
 
1812
    if (e->c > 0xFF) continue;
 
1813
 
 
1814
    (void)memset(utf8, 0, sizeof(utf8));
 
1815
    iso88591 = e->c;
 
1816
    
 
1817
    result = sec_port_iso88591_utf8_conversion_function(&iso88591,
 
1818
      1, utf8, sizeof(utf8), &len);
 
1819
 
 
1820
    if( !result ) {
 
1821
      fprintf(stdout, "Failed to convert ISO-8859-1 0x%02.2x to UTF-8\n", iso88591);
 
1822
      rv = PR_FALSE;
 
1823
      continue;
 
1824
    }
 
1825
 
 
1826
    if( (len >= sizeof(utf8)) ||
 
1827
        (strlen(e->utf8) != len) ||
 
1828
        (utf8[len] = '\0', 0 != strcmp(e->utf8, utf8)) ) {
 
1829
      fprintf(stdout, "Wrong conversion of ISO-8859-1 0x%02.2x to UTF-8: ", iso88591);
 
1830
      dump_utf8("expected", e->utf8, ", ");
 
1831
      dump_utf8("received", utf8, "\n");
 
1832
      rv = PR_FALSE;
 
1833
      continue;
 
1834
    }
 
1835
 
 
1836
  }
 
1837
 
 
1838
  return rv;
 
1839
}
 
1840
 
 
1841
static PRBool
 
1842
test_zeroes
 
1843
(
 
1844
  void
 
1845
)
 
1846
{
 
1847
  PRBool rv = PR_TRUE;
 
1848
  PRBool result;
 
1849
  PRUint32 lzero = 0;
 
1850
  PRUint16 szero = 0;
 
1851
  unsigned char utf8[8];
 
1852
  unsigned int len = 0;
 
1853
  PRUint32 lback = 1;
 
1854
  PRUint16 sback = 1;
 
1855
 
 
1856
  (void)memset(utf8, 1, sizeof(utf8));
 
1857
 
 
1858
  result = sec_port_ucs4_utf8_conversion_function(PR_FALSE, 
 
1859
    (unsigned char *)&lzero, sizeof(lzero), utf8, sizeof(utf8), &len);
 
1860
 
 
1861
  if( !result ) {
 
1862
    fprintf(stdout, "Failed to convert UCS-4 0x00000000 to UTF-8\n");
 
1863
    rv = PR_FALSE;
 
1864
  } else if( 1 != len ) {
 
1865
    fprintf(stdout, "Wrong conversion of UCS-4 0x00000000: len = %d\n", len);
 
1866
    rv = PR_FALSE;
 
1867
  } else if( '\0' != *utf8 ) {
 
1868
    fprintf(stdout, "Wrong conversion of UCS-4 0x00000000: expected 00 ,"
 
1869
            "received %02.2x\n", (unsigned int)*utf8);
 
1870
    rv = PR_FALSE;
 
1871
  }
 
1872
 
 
1873
  result = sec_port_ucs4_utf8_conversion_function(PR_TRUE,
 
1874
    "", 1, (unsigned char *)&lback, sizeof(lback), &len);
 
1875
 
 
1876
  if( !result ) {
 
1877
    fprintf(stdout, "Failed to convert UTF-8 00 to UCS-4\n");
 
1878
    rv = PR_FALSE;
 
1879
  } else if( 4 != len ) {
 
1880
    fprintf(stdout, "Wrong conversion of UTF-8 00 to UCS-4: len = %d\n", len);
 
1881
    rv = PR_FALSE;
 
1882
  } else if( 0 != lback ) {
 
1883
    fprintf(stdout, "Wrong conversion of UTF-8 00 to UCS-4: "
 
1884
            "expected 0x00000000, received 0x%08.8x\n", lback);
 
1885
    rv = PR_FALSE;
 
1886
  }
 
1887
 
 
1888
  (void)memset(utf8, 1, sizeof(utf8));
 
1889
 
 
1890
  result = sec_port_ucs2_utf8_conversion_function(PR_FALSE, 
 
1891
    (unsigned char *)&szero, sizeof(szero), utf8, sizeof(utf8), &len);
 
1892
 
 
1893
  if( !result ) {
 
1894
    fprintf(stdout, "Failed to convert UCS-2 0x0000 to UTF-8\n");
 
1895
    rv = PR_FALSE;
 
1896
  } else if( 1 != len ) {
 
1897
    fprintf(stdout, "Wrong conversion of UCS-2 0x0000: len = %d\n", len);
 
1898
    rv = PR_FALSE;
 
1899
  } else if( '\0' != *utf8 ) {
 
1900
    fprintf(stdout, "Wrong conversion of UCS-2 0x0000: expected 00 ,"
 
1901
            "received %02.2x\n", (unsigned int)*utf8);
 
1902
    rv = PR_FALSE;
 
1903
  }
 
1904
 
 
1905
  result = sec_port_ucs2_utf8_conversion_function(PR_TRUE,
 
1906
    "", 1, (unsigned char *)&sback, sizeof(sback), &len);
 
1907
 
 
1908
  if( !result ) {
 
1909
    fprintf(stdout, "Failed to convert UTF-8 00 to UCS-2\n");
 
1910
    rv = PR_FALSE;
 
1911
  } else if( 2 != len ) {
 
1912
    fprintf(stdout, "Wrong conversion of UTF-8 00 to UCS-2: len = %d\n", len);
 
1913
    rv = PR_FALSE;
 
1914
  } else if( 0 != sback ) {
 
1915
    fprintf(stdout, "Wrong conversion of UTF-8 00 to UCS-2: "
 
1916
            "expected 0x0000, received 0x%04.4x\n", sback);
 
1917
    rv = PR_FALSE;
 
1918
  }
 
1919
 
 
1920
  return rv;
 
1921
}
 
1922
 
 
1923
static PRBool
 
1924
test_multichars
 
1925
(
 
1926
  void
 
1927
)
 
1928
{
 
1929
  int i;
 
1930
  unsigned int len, lenout;
 
1931
  PRUint32 *ucs4s;
 
1932
  char *ucs4_utf8;
 
1933
  PRUint16 *ucs2s;
 
1934
  char *ucs2_utf8;
 
1935
  void *tmp;
 
1936
  PRBool result;
 
1937
 
 
1938
  ucs4s = (PRUint32 *)calloc(sizeof(ucs4)/sizeof(ucs4[0]), sizeof(PRUint32));
 
1939
  ucs2s = (PRUint16 *)calloc(sizeof(ucs2)/sizeof(ucs2[0]), sizeof(PRUint16));
 
1940
 
 
1941
  if( ((PRUint32 *)NULL == ucs4s) || ((PRUint16 *)NULL == ucs2s) ) {
 
1942
    fprintf(stderr, "out of memory\n");
 
1943
    exit(1);
 
1944
  }
 
1945
 
 
1946
  len = 0;
 
1947
  for( i = 0; i < sizeof(ucs4)/sizeof(ucs4[0]); i++ ) {
 
1948
    ucs4s[i] = ucs4[i].c;
 
1949
    len += strlen(ucs4[i].utf8);
 
1950
  }
 
1951
 
 
1952
  ucs4_utf8 = (char *)malloc(len);
 
1953
 
 
1954
  len = 0;
 
1955
  for( i = 0; i < sizeof(ucs2)/sizeof(ucs2[0]); i++ ) {
 
1956
    ucs2s[i] = ucs2[i].c;
 
1957
    len += strlen(ucs2[i].utf8);
 
1958
  }
 
1959
 
 
1960
  ucs2_utf8 = (char *)malloc(len);
 
1961
 
 
1962
  if( ((char *)NULL == ucs4_utf8) || ((char *)NULL == ucs2_utf8) ) {
 
1963
    fprintf(stderr, "out of memory\n");
 
1964
    exit(1);
 
1965
  }
 
1966
 
 
1967
  *ucs4_utf8 = '\0';
 
1968
  for( i = 0; i < sizeof(ucs4)/sizeof(ucs4[0]); i++ ) {
 
1969
    strcat(ucs4_utf8, ucs4[i].utf8);
 
1970
  }
 
1971
 
 
1972
  *ucs2_utf8 = '\0';
 
1973
  for( i = 0; i < sizeof(ucs2)/sizeof(ucs2[0]); i++ ) {
 
1974
    strcat(ucs2_utf8, ucs2[i].utf8);
 
1975
  }
 
1976
 
 
1977
  /* UTF-8 -> UCS-4 */
 
1978
  len = sizeof(ucs4)/sizeof(ucs4[0]) * sizeof(PRUint32);
 
1979
  tmp = calloc(len, 1);
 
1980
  if( (void *)NULL == tmp ) {
 
1981
    fprintf(stderr, "out of memory\n");
 
1982
    exit(1);
 
1983
  }
 
1984
 
 
1985
  result = sec_port_ucs4_utf8_conversion_function(PR_TRUE,
 
1986
    ucs4_utf8, strlen(ucs4_utf8), tmp, len, &lenout);
 
1987
  if( !result ) {
 
1988
    fprintf(stdout, "Failed to convert much UTF-8 to UCS-4\n");
 
1989
    goto done;
 
1990
  }
 
1991
 
 
1992
  if( lenout != len ) {
 
1993
    fprintf(stdout, "Unexpected length converting much UTF-8 to UCS-4\n");
 
1994
    goto loser;
 
1995
  }
 
1996
 
 
1997
  if( 0 != memcmp(ucs4s, tmp, len) ) {
 
1998
    fprintf(stdout, "Wrong conversion of much UTF-8 to UCS-4\n");
 
1999
    goto loser;
 
2000
  }
 
2001
 
 
2002
  free(tmp); tmp = (void *)NULL;
 
2003
 
 
2004
  /* UCS-4 -> UTF-8 */
 
2005
  len = strlen(ucs4_utf8);
 
2006
  tmp = calloc(len, 1);
 
2007
  if( (void *)NULL == tmp ) {
 
2008
    fprintf(stderr, "out of memory\n");
 
2009
    exit(1);
 
2010
  }
 
2011
 
 
2012
  result = sec_port_ucs4_utf8_conversion_function(PR_FALSE,
 
2013
    (unsigned char *)ucs4s, sizeof(ucs4)/sizeof(ucs4[0]) * sizeof(PRUint32), 
 
2014
    tmp, len, &lenout);
 
2015
  if( !result ) {
 
2016
    fprintf(stdout, "Failed to convert much UCS-4 to UTF-8\n");
 
2017
    goto done;
 
2018
  }
 
2019
 
 
2020
  if( lenout != len ) {
 
2021
    fprintf(stdout, "Unexpected length converting much UCS-4 to UTF-8\n");
 
2022
    goto loser;
 
2023
  }
 
2024
 
 
2025
  if( 0 != strncmp(ucs4_utf8, tmp, len) ) {
 
2026
    fprintf(stdout, "Wrong conversion of much UCS-4 to UTF-8\n");
 
2027
    goto loser;
 
2028
  }
 
2029
 
 
2030
  free(tmp); tmp = (void *)NULL;
 
2031
 
 
2032
  /* UTF-8 -> UCS-2 */
 
2033
  len = sizeof(ucs2)/sizeof(ucs2[0]) * sizeof(PRUint16);
 
2034
  tmp = calloc(len, 1);
 
2035
  if( (void *)NULL == tmp ) {
 
2036
    fprintf(stderr, "out of memory\n");
 
2037
    exit(1);
 
2038
  }
 
2039
 
 
2040
  result = sec_port_ucs2_utf8_conversion_function(PR_TRUE,
 
2041
    ucs2_utf8, strlen(ucs2_utf8), tmp, len, &lenout);
 
2042
  if( !result ) {
 
2043
    fprintf(stdout, "Failed to convert much UTF-8 to UCS-2\n");
 
2044
    goto done;
 
2045
  }
 
2046
 
 
2047
  if( lenout != len ) {
 
2048
    fprintf(stdout, "Unexpected length converting much UTF-8 to UCS-2\n");
 
2049
    goto loser;
 
2050
  }
 
2051
 
 
2052
  if( 0 != memcmp(ucs2s, tmp, len) ) {
 
2053
    fprintf(stdout, "Wrong conversion of much UTF-8 to UCS-2\n");
 
2054
    goto loser;
 
2055
  }
 
2056
 
 
2057
  free(tmp); tmp = (void *)NULL;
 
2058
 
 
2059
  /* UCS-2 -> UTF-8 */
 
2060
  len = strlen(ucs2_utf8);
 
2061
  tmp = calloc(len, 1);
 
2062
  if( (void *)NULL == tmp ) {
 
2063
    fprintf(stderr, "out of memory\n");
 
2064
    exit(1);
 
2065
  }
 
2066
 
 
2067
  result = sec_port_ucs2_utf8_conversion_function(PR_FALSE,
 
2068
    (unsigned char *)ucs2s, sizeof(ucs2)/sizeof(ucs2[0]) * sizeof(PRUint16), 
 
2069
    tmp, len, &lenout);
 
2070
  if( !result ) {
 
2071
    fprintf(stdout, "Failed to convert much UCS-2 to UTF-8\n");
 
2072
    goto done;
 
2073
  }
 
2074
 
 
2075
  if( lenout != len ) {
 
2076
    fprintf(stdout, "Unexpected length converting much UCS-2 to UTF-8\n");
 
2077
    goto loser;
 
2078
  }
 
2079
 
 
2080
  if( 0 != strncmp(ucs2_utf8, tmp, len) ) {
 
2081
    fprintf(stdout, "Wrong conversion of much UCS-2 to UTF-8\n");
 
2082
    goto loser;
 
2083
  }
 
2084
 
 
2085
#ifdef UTF16
 
2086
  /* implement me */
 
2087
#endif /* UTF16 */
 
2088
 
 
2089
  result = PR_TRUE;
 
2090
  goto done;
 
2091
 
 
2092
 loser:
 
2093
  result = PR_FALSE;
 
2094
 done:
 
2095
  free(ucs4s);
 
2096
  free(ucs4_utf8);
 
2097
  free(ucs2s);
 
2098
  free(ucs2_utf8);
 
2099
  if( (void *)NULL != tmp ) free(tmp);
 
2100
  return result;
 
2101
}
 
2102
 
 
2103
void
 
2104
byte_order
 
2105
(
 
2106
  void
 
2107
)
 
2108
{
 
2109
  /*
 
2110
   * The implementation (now) expects the 16- and 32-bit characters
 
2111
   * to be in network byte order, not host byte order.  Therefore I
 
2112
   * have to byteswap all those test vectors above.  hton[ls] may be
 
2113
   * functions, so I have to do this dynamically.  If you want to 
 
2114
   * use this code to do host byte order conversions, just remove
 
2115
   * the call in main() to this function.
 
2116
   */
 
2117
 
 
2118
  int i;
 
2119
 
 
2120
  for( i = 0; i < sizeof(ucs4)/sizeof(ucs4[0]); i++ ) {
 
2121
    struct ucs4 *e = &ucs4[i];
 
2122
    e->c = htonl(e->c);
 
2123
  }
 
2124
 
 
2125
  for( i = 0; i < sizeof(ucs2)/sizeof(ucs2[0]); i++ ) {
 
2126
    struct ucs2 *e = &ucs2[i];
 
2127
    e->c = htons(e->c);
 
2128
  }
 
2129
 
 
2130
#ifdef UTF16
 
2131
  for( i = 0; i < sizeof(utf16)/sizeof(utf16[0]); i++ ) {
 
2132
    struct utf16 *e = &utf16[i];
 
2133
    e->c = htonl(e->c);
 
2134
    e->w[0] = htons(e->w[0]);
 
2135
    e->w[1] = htons(e->w[1]);
 
2136
  }
 
2137
#endif /* UTF16 */
 
2138
 
 
2139
  return;
 
2140
}
 
2141
 
 
2142
int
 
2143
main
 
2144
(
 
2145
  int argc,
 
2146
  char *argv[]
 
2147
)
 
2148
{
 
2149
  byte_order();
 
2150
 
 
2151
  if( test_ucs4_chars() &&
 
2152
      test_ucs2_chars() &&
 
2153
#ifdef UTF16
 
2154
      test_utf16_chars() &&
 
2155
#endif /* UTF16 */
 
2156
      test_iso88591_chars() &&
 
2157
      test_zeroes() &&
 
2158
      test_multichars() &&
 
2159
      PR_TRUE ) {
 
2160
    fprintf(stderr, "PASS\n");
 
2161
    return 1;
 
2162
  } else {
 
2163
    fprintf(stderr, "FAIL\n");
 
2164
    return 0;
 
2165
  }
 
2166
}
 
2167
 
 
2168
#endif /* TEST_UTF8 */