~ubuntu-branches/ubuntu/quantal/icu/quantal

« back to all changes in this revision

Viewing changes to source/samples/ucnv/convsamp.cpp

  • Committer: Package Import Robot
  • Author(s): Yves Arrouye
  • Date: 2002-03-03 15:31:13 UTC
  • Revision ID: package-import@ubuntu.com-20020303153113-3ssceqlq45xbmbnc
Tags: upstream-2.0-2.1pre20020303
ImportĀ upstreamĀ versionĀ 2.0-2.1pre20020303

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**************************************************************************
 
2
*
 
3
*   Copyright (C) 2000, International Business Machines
 
4
*   Corporation and others.  All Rights Reserved.
 
5
*
 
6
***************************************************************************
 
7
*   file name:  convsamp.c
 
8
*   encoding:   ASCII (7-bit)
 
9
*
 
10
*   created on: 2000may30
 
11
*   created by: Steven R. Loomis
 
12
*
 
13
*   Sample code for the ICU conversion routines.
 
14
*
 
15
* Note: Nothing special is needed to build this sample. Link with
 
16
*       the icu UC and icu I18N libraries. 
 
17
 
18
*       I use 'assert' for error checking, you probably will want
 
19
*       something more flexible.  '***BEGIN SAMPLE***' and 
 
20
*       '***END SAMPLE***' mark pieces suitable for stand alone
 
21
*       code snippets.
 
22
*
 
23
*
 
24
*  Each test can define it's own BUFFERSIZE 
 
25
*
 
26
*/
 
27
 
 
28
#include <stdio.h>
 
29
#include <ctype.h>            /* for isspace, etc.    */
 
30
#include <assert.h>
 
31
#include <string.h>
 
32
#include <stdlib.h>  /* malloc */
 
33
 
 
34
#include "unicode/utypes.h"   /* Basic ICU data types */
 
35
#include "unicode/ucnv.h"     /* C   Converter API    */
 
36
#include "unicode/convert.h"  /* C++ Converter API    */
 
37
#include "unicode/ustring.h"  /* some more string fcns*/
 
38
#include "unicode/uchar.h"    /* char names           */
 
39
#include "unicode/uloc.h"
 
40
 
 
41
 
 
42
#include "flagcb.h"
 
43
 
 
44
/* Some utility functions */
 
45
 
 
46
static const UChar kNone[] = { 0x0000 };
 
47
 
 
48
#define U_ASSERT(x)  { if(U_FAILURE(x)) {fflush(stdout);fflush(stderr); fprintf(stderr, #x " == %s\n", u_errorName(x)); assert(U_SUCCESS(x)); }}
 
49
 
 
50
/* Print a UChar if possible, in seven characters. */
 
51
void prettyPrintUChar(UChar c)
 
52
{
 
53
  if(  (c <= 0x007F) &&
 
54
       (isgraph(c))  ) {
 
55
    printf(" '%c'   ", (char)(0x00FF&c));
 
56
  } else if ( c > 0x007F ) {
 
57
    char buf[1000];
 
58
    UErrorCode status = U_ZERO_ERROR;
 
59
    UTextOffset o;
 
60
    
 
61
    o = u_charName(c, U_UNICODE_CHAR_NAME, buf, 1000, &status);
 
62
    if(U_SUCCESS(status) && (o>0) ) {
 
63
      buf[6] = 0;
 
64
      printf("%7s", buf);
 
65
    } else {
 
66
      o = u_charName(c, U_UNICODE_10_CHAR_NAME, buf, 1000, &status);
 
67
      if(U_SUCCESS(status) && (o>0)) {
 
68
        buf[5] = 0;
 
69
        printf("~%6s", buf);
 
70
      }
 
71
      else {
 
72
        printf(" ??????");
 
73
      }
 
74
    }
 
75
  } else {
 
76
    switch((char)(c & 0x007F)) {
 
77
    case ' ':
 
78
      printf(" ' '   ");
 
79
      break;
 
80
    case '\t':
 
81
      printf(" \\t    ");
 
82
      break;
 
83
    case '\n':
 
84
      printf(" \\n    ");
 
85
      break;
 
86
    default:
 
87
      printf("  _    ");
 
88
      break;
 
89
    }
 
90
  }
 
91
}
 
92
 
 
93
 
 
94
void printUChars(const char  *name = "?", 
 
95
                 const UChar *uch  = kNone,
 
96
                 int32_t     len   = -1 )
 
97
{
 
98
  int32_t i;
 
99
 
 
100
  if( (len == -1) && (uch) ) {
 
101
    len = u_strlen(uch);
 
102
  }
 
103
 
 
104
  printf("%5s: ", name);
 
105
  for( i = 0; i <len; i++) {
 
106
    printf("%-6d ", i);
 
107
  }
 
108
  printf("\n");
 
109
 
 
110
  printf("%5s: ", "uni");
 
111
  for( i = 0; i <len; i++) {
 
112
    printf("\\u%04X ", (int)uch[i]);
 
113
  }
 
114
  printf("\n");
 
115
 
 
116
  printf("%5s:", "ch");
 
117
  for( i = 0; i <len; i++) {
 
118
    prettyPrintUChar(uch[i]);
 
119
  }
 
120
  printf("\n");
 
121
}
 
122
 
 
123
void printString(const char *name, const UnicodeString& string)
 
124
{
 
125
  UChar *uch;
 
126
  int32_t len = string.length();
 
127
  uch = (UChar*)malloc(sizeof(UChar)*(len+1));
 
128
  string.extract(0,len,uch,0);
 
129
  uch[len]=0;
 
130
  printUChars(name, uch, -1);
 
131
  delete(uch);
 
132
}
 
133
 
 
134
void printBytes(const char  *name = "?", 
 
135
                 const char *uch  = "",
 
136
                 int32_t     len   = -1 )
 
137
{
 
138
  int32_t i;
 
139
 
 
140
  if( (len == -1) && (uch) ) {
 
141
    len = strlen(uch);
 
142
  }
 
143
 
 
144
  printf("%5s: ", name);
 
145
  for( i = 0; i <len; i++) {
 
146
    printf("%-4d ", i);
 
147
  }
 
148
  printf("\n");
 
149
 
 
150
  printf("%5s: ", "uni");
 
151
  for( i = 0; i <len; i++) {
 
152
    printf("\\x%02X ", 0x00FF & (int)uch[i]);
 
153
  }
 
154
  printf("\n");
 
155
 
 
156
  printf("%5s:", "ch");
 
157
  for( i = 0; i <len; i++) {
 
158
    if(isgraph(uch[i])) {
 
159
      printf(" '%c' ", (char)uch[i]);
 
160
    } else {
 
161
      printf("     ");
 
162
    }
 
163
  }
 
164
  printf("\n");
 
165
}
 
166
 
 
167
void printUChar(UChar32 ch32)
 
168
{
 
169
    if(ch32 > 0xFFFF) {
 
170
      printf("ch: U+%06X\n", ch32);
 
171
    }
 
172
    else {
 
173
      UChar ch = (UChar)ch32;
 
174
      printUChars("C", &ch, 1);
 
175
    }
 
176
}
 
177
 
 
178
/*******************************************************************
 
179
  Very simple C++ sample to convert the word 'Moscow' in Russian in Unicode,
 
180
  followed by an exclamation mark (!) into the KOI8-R Russian code page.
 
181
 
 
182
  This example first creates a UnicodeString out of the Unicode chars.
 
183
 
 
184
  targetSize must be set to the amount of space available in the target
 
185
  buffer. After UnicodeConverter::fromUnicodeString() is called, 
 
186
  targetSize will contain the number of bytes in target[] which were
 
187
  used in the resulting codepage.  In this case, there is a 1:1 mapping
 
188
  between the input and output characters. The exclamation mark has the
 
189
  same value in both KOI8-R and Unicode.
 
190
 
 
191
  src: 0      1      2      3      4      5      6     
 
192
  uni: \u041C \u043E \u0441 \u043A \u0432 \u0430 \u0021 
 
193
   ch: CYRILL CYRILL CYRILL CYRILL CYRILL CYRILL   '!'  
 
194
 
 
195
 targ:  0    1    2    3    4    5    6  
 
196
  uni: \xED \xCF \xD3 \xCB \xD7 \xC1 \x21 
 
197
   ch:                                '!' 
 
198
 
 
199
 
 
200
 */
 
201
UErrorCode convsample_01()
 
202
{
 
203
  printf("\n\n==============================================\n"
 
204
         "Sample 01: C++: simple Unicode -> koi8-r conversion\n");
 
205
 
 
206
 
 
207
  // **************************** START SAMPLE *******************
 
208
  // "Moscva!" in cyrillic letters, to be converted to the KOI8-R
 
209
  // Russian code page.
 
210
  UChar source[] = { 0x041C, 0x043E, 0x0441, 0x043A, 0x0432,
 
211
                     0x0430, 0x0021, 0x0000 };
 
212
  char target[100];
 
213
  int32_t targetSize = sizeof(target);
 
214
  UnicodeString myString(source);
 
215
  UErrorCode status = U_ZERO_ERROR;
 
216
 
 
217
  // set up the converter
 
218
  UnicodeConverter conv("koi8-r", status);
 
219
  U_ASSERT(status);
 
220
 
 
221
  // convert to KOI8-R
 
222
  conv.fromUnicodeString(target, targetSize, myString, status);
 
223
  U_ASSERT(status);
 
224
 
 
225
  // ***************************** END SAMPLE ********************
 
226
  
 
227
  // Print it out
 
228
  printUChars("src", source);
 
229
  printf("\n");
 
230
  printBytes("targ", target, targetSize);
 
231
 
 
232
  return U_ZERO_ERROR;
 
233
}
 
234
 
 
235
 
 
236
/******************************************************
 
237
  Similar sample to the preceding one.  Converting FROM unicode 
 
238
  to koi8-r.
 
239
  You must call ucnv_close to clean up the memory used by the
 
240
  converter.
 
241
 
 
242
  'len' returns the number of OUTPUT bytes resulting from the 
 
243
  conversion.
 
244
 */
 
245
 
 
246
UErrorCode convsample_02()
 
247
{
 
248
  printf("\n\n==============================================\n"
 
249
         "Sample 02: C: simple Unicode -> koi8-r conversion\n");
 
250
 
 
251
 
 
252
  // **************************** START SAMPLE *******************
 
253
  // "cat<cat>OK"
 
254
  UChar source[] = { 0x041C, 0x043E, 0x0441, 0x043A, 0x0432,
 
255
                     0x0430, 0x0021, 0x0000 };
 
256
  char target[100];
 
257
  UErrorCode status = U_ZERO_ERROR;
 
258
  UConverter *conv;
 
259
  int32_t     len;
 
260
 
 
261
  // set up the converter
 
262
  conv = ucnv_open("koi8-r", &status);
 
263
  assert(U_SUCCESS(status));
 
264
 
 
265
  // convert to koi8-r
 
266
  len = ucnv_fromUChars(conv, target, 100, source, -1, &status);
 
267
  assert(U_SUCCESS(status));
 
268
 
 
269
  // close the converter
 
270
  ucnv_close(conv);
 
271
 
 
272
  // ***************************** END SAMPLE ********************
 
273
  
 
274
  // Print it out
 
275
  printUChars("src", source);
 
276
  printf("\n");
 
277
  printBytes("targ", target, len);
 
278
 
 
279
  return U_ZERO_ERROR;
 
280
}
 
281
 
 
282
 
 
283
UErrorCode convsample_03()
 
284
{
 
285
  printf("\n\n==============================================\n"
 
286
         "Sample 03: C: print out all converters\n");
 
287
 
 
288
  int32_t count;
 
289
  int32_t i;
 
290
 
 
291
  // **************************** START SAMPLE *******************
 
292
  count = ucnv_countAvailable();
 
293
  printf("Available converters: %d\n", count);
 
294
  
 
295
  for(i=0;i<count;i++) 
 
296
  {
 
297
    printf("%s ", ucnv_getAvailableName(i));
 
298
  }
 
299
 
 
300
  // ***************************** END SAMPLE ********************
 
301
  
 
302
  printf("\n");
 
303
 
 
304
  return U_ZERO_ERROR;
 
305
}
 
306
 
 
307
 
 
308
 
 
309
#define BUFFERSIZE 17 /* make it interesting :) */
 
310
 
 
311
/*
 
312
  Converting from a codepage to Unicode in bulk..
 
313
  What is the best way to determine the buffer size?
 
314
 
 
315
     The 'buffersize' is in bytes of input.
 
316
    For a given converter, divinding this by the minimum char size
 
317
    give you the maximum number of Unicode characters that could be
 
318
    expected for a given number of input bytes.
 
319
     see: ucnv_getMinCharSize()
 
320
 
 
321
     For example, a single byte codepage like 'Latin-3' has a 
 
322
    minimum char size of 1. (It takes at least 1 byte to represent
 
323
    each Unicode char.) So the unicode buffer has the same number of
 
324
    UChars as the input buffer has bytes.
 
325
 
 
326
     In a strictly double byte codepage such as cp1362 (Windows
 
327
    Korean), the minimum char size is 2. So, only half as many Unicode
 
328
    chars as bytes are needed.
 
329
 
 
330
     This work to calculate the buffer size is an optimization. Any
 
331
    size of input and output buffer can be used, as long as the
 
332
    program handles the following cases: If the input buffer is empty,
 
333
    the source pointer will be equal to sourceLimit.  If the output
 
334
    buffer has overflowed, U_BUFFER_OVERFLOW_ERROR will be returned. 
 
335
 */
 
336
 
 
337
UErrorCode convsample_05()
 
338
{
 
339
  printf("\n\n==============================================\n"
 
340
         "Sample 05: C: count the number of letters in a UTF-8 document\n");
 
341
 
 
342
  FILE *f;
 
343
  int32_t count;
 
344
  char inBuf[BUFFERSIZE];
 
345
  const char *source;
 
346
  const char *sourceLimit;
 
347
  UChar *uBuf;
 
348
  UChar *target;
 
349
  UChar *targetLimit;
 
350
  UChar *p;
 
351
  int32_t uBufSize = 0;
 
352
  UConverter *conv;
 
353
  UErrorCode status = U_ZERO_ERROR;
 
354
  uint32_t letters=0, total=0;
 
355
 
 
356
  f = fopen("data01.txt", "r");
 
357
  if(!f)
 
358
  {
 
359
    fprintf(stderr, "Couldn't open file 'data01.txt' (UTF-8 data file).\n");
 
360
    return U_FILE_ACCESS_ERROR;
 
361
  }
 
362
 
 
363
  // **************************** START SAMPLE *******************
 
364
  conv = ucnv_open("utf-8", &status);
 
365
  assert(U_SUCCESS(status));
 
366
 
 
367
  uBufSize = (BUFFERSIZE/ucnv_getMinCharSize(conv));
 
368
  printf("input bytes %d / min chars %d = %d UChars\n",
 
369
         BUFFERSIZE, ucnv_getMinCharSize(conv), uBufSize);
 
370
  uBuf = (UChar*)malloc(uBufSize * sizeof(UChar));
 
371
  assert(uBuf!=NULL);
 
372
 
 
373
  // grab another buffer's worth
 
374
  while((!feof(f)) && 
 
375
        ((count=fread(inBuf, 1, BUFFERSIZE , f)) > 0) )
 
376
  {
 
377
    // Convert bytes to unicode
 
378
    source = inBuf;
 
379
    sourceLimit = inBuf + count;
 
380
    
 
381
    do
 
382
    {
 
383
        target = uBuf;
 
384
        targetLimit = uBuf + uBufSize;
 
385
        
 
386
        ucnv_toUnicode(conv, &target, targetLimit, 
 
387
                       &source, sourceLimit, NULL,
 
388
                       feof(f)?TRUE:FALSE,         /* pass 'flush' when eof */
 
389
                                   /* is true (when no more data will come) */
 
390
                       &status);
 
391
      
 
392
        if(status == U_BUFFER_OVERFLOW_ERROR)
 
393
        {
 
394
          // simply ran out of space - we'll reset the target ptr the next
 
395
          // time through the loop.
 
396
          status = U_ZERO_ERROR;
 
397
        }
 
398
        else
 
399
        {
 
400
          //  Check other errors here.
 
401
          assert(U_SUCCESS(status));
 
402
          // Break out of the loop (by force)
 
403
        }
 
404
 
 
405
        // Process the Unicode
 
406
        // Todo: handle UTF-16/surrogates
 
407
 
 
408
        for(p = uBuf; p<target; p++)
 
409
        {
 
410
          if(u_isalpha(*p))
 
411
            letters++;
 
412
          total++;
 
413
        }
 
414
    } while (source < sourceLimit); // while simply out of space
 
415
  }
 
416
 
 
417
  printf("%d letters out of %d total UChars.\n", letters, total);
 
418
  
 
419
  // ***************************** END SAMPLE ********************
 
420
  ucnv_close(conv);
 
421
 
 
422
  printf("\n");
 
423
 
 
424
  return U_ZERO_ERROR;
 
425
}
 
426
#undef BUFFERSIZE
 
427
 
 
428
#define BUFFERSIZE 1024
 
429
typedef struct
 
430
{
 
431
  UChar32  codepoint;
 
432
  uint32_t frequency;
 
433
} CharFreqInfo;
 
434
 
 
435
UErrorCode convsample_06()
 
436
{
 
437
  printf("\n\n==============================================\n"
 
438
         "Sample 06: C: frequency distribution of letters in a UTF-8 document\n");
 
439
 
 
440
  FILE *f;
 
441
  int32_t count;
 
442
  char inBuf[BUFFERSIZE];
 
443
  const char *source;
 
444
  const char *sourceLimit;
 
445
  UChar *uBuf;
 
446
  int32_t uBufSize = 0;
 
447
  UConverter *conv;
 
448
  UErrorCode status = U_ZERO_ERROR;
 
449
  uint32_t letters=0, total=0;
 
450
 
 
451
  CharFreqInfo   *info;
 
452
  UChar32   charCount = 0x10000;  /* increase this if you want to handle non bmp.. todo: automatically bump it.. */
 
453
  UChar32   p;
 
454
 
 
455
  uint32_t ie = 0;
 
456
  uint32_t gh = 0;
 
457
  UChar32 l = 0;
 
458
 
 
459
  f = fopen("data06.txt", "r");
 
460
  if(!f)
 
461
  {
 
462
    fprintf(stderr, "Couldn't open file 'data06.txt' (UTF-8 data file).\n");
 
463
    return U_FILE_ACCESS_ERROR;
 
464
  }
 
465
 
 
466
  info = (CharFreqInfo*)malloc(sizeof(CharFreqInfo) * charCount);
 
467
  if(!info)
 
468
  {
 
469
    fprintf(stderr, " Couldn't allocate %d bytes for freq counter\n", sizeof(CharFreqInfo)*charCount);
 
470
  }
 
471
 
 
472
  /* reset frequencies */
 
473
  for(p=0;p<charCount;p++)
 
474
  {
 
475
    info[p].codepoint = p;
 
476
    info[p].frequency = 0;
 
477
  }
 
478
 
 
479
  // **************************** START SAMPLE *******************
 
480
  conv = ucnv_open("utf-8", &status);
 
481
  assert(U_SUCCESS(status));
 
482
 
 
483
  uBufSize = (BUFFERSIZE/ucnv_getMinCharSize(conv));
 
484
  printf("input bytes %d / min chars %d = %d UChars\n",
 
485
         BUFFERSIZE, ucnv_getMinCharSize(conv), uBufSize);
 
486
  uBuf = (UChar*)malloc(uBufSize * sizeof(UChar));
 
487
  assert(uBuf!=NULL);
 
488
 
 
489
  // grab another buffer's worth
 
490
  while((!feof(f)) && 
 
491
        ((count=fread(inBuf, 1, BUFFERSIZE , f)) > 0) )
 
492
  {
 
493
    // Convert bytes to unicode
 
494
    source = inBuf;
 
495
    sourceLimit = inBuf + count;
 
496
    
 
497
    while(source < sourceLimit)
 
498
    {
 
499
      p = ucnv_getNextUChar(conv, &source, sourceLimit, &status);
 
500
      if(U_FAILURE(status))
 
501
      {
 
502
        fprintf(stderr, "%s @ %d\n", u_errorName(status), total);
 
503
        status = U_ZERO_ERROR;
 
504
        continue;
 
505
      }
 
506
      U_ASSERT(status);
 
507
      total++;
 
508
 
 
509
      if(u_isalpha(p))
 
510
        letters++;
 
511
 
 
512
      if((u_tolower(l) == 'i') && (u_tolower(p) == 'e'))
 
513
        ie++;
 
514
 
 
515
      if((u_tolower(l) == 'g') && (u_tolower(p) == 0x0127))
 
516
        gh++;
 
517
 
 
518
      if(p>charCount)
 
519
      {
 
520
        fprintf(stderr, "U+%06X: oh.., we only handle BMP characters so far.. redesign!\n", p);
 
521
        return U_UNSUPPORTED_ERROR;
 
522
      }
 
523
      info[p].frequency++;
 
524
      l = p;
 
525
    }
 
526
  }
 
527
 
 
528
  fclose(f);
 
529
  ucnv_close(conv);
 
530
 
 
531
  printf("%d letters out of %d total UChars.\n", letters, total);
 
532
  printf("%d ie digraphs, %d gh digraphs.\n", ie, gh);
 
533
 
 
534
  // now, we could sort it..
 
535
 
 
536
  //  qsort(info, charCount, sizeof(info[0]), charfreq_compare);
 
537
 
 
538
  for(p=0;p<charCount;p++)
 
539
  {
 
540
    if(info[p].frequency)
 
541
    {
 
542
      printf("% 5d U+%06X ", info[p].frequency, p);
 
543
      if(p <= 0xFFFF)
 
544
      {
 
545
        prettyPrintUChar((UChar)p);
 
546
      }
 
547
      printf("\n");
 
548
    }
 
549
  }
 
550
  free(info);
 
551
  // ***************************** END SAMPLE ********************
 
552
 
 
553
  printf("\n");
 
554
 
 
555
  return U_ZERO_ERROR;
 
556
}
 
557
#undef BUFFERSIZE
 
558
 
 
559
 
 
560
/*******************************************************************
 
561
  Very simple C++ sample to convert a string into Unicode from SJIS
 
562
 
 
563
  This example creates a UnicodeString out of the chars.
 
564
 
 
565
 */
 
566
UErrorCode convsample_11()
 
567
{
 
568
  printf("\n\n==============================================\n"
 
569
         "Sample 11: C++: simple sjis -> Unicode conversion\n");
 
570
 
 
571
 
 
572
  // **************************** START SAMPLE *******************
 
573
 
 
574
  char source[] = { 0x63, 0x61, 0x74, (char)0x94, 0x4C, (char)0x82, 0x6E, (char)0x82, 0x6A, 0x00 };
 
575
  int32_t sourceSize = sizeof(source);
 
576
  UnicodeString target;
 
577
  UErrorCode status = U_ZERO_ERROR;
 
578
 
 
579
  // set up the converter
 
580
  UnicodeConverter conv("shift_jis", status);
 
581
  assert(U_SUCCESS(status));
 
582
 
 
583
  // convert from JIS
 
584
  conv.toUnicodeString(target, source, sourceSize, status);
 
585
  assert(U_SUCCESS(status));
 
586
 
 
587
  // ***************************** END SAMPLE ********************
 
588
  
 
589
  // Print it out
 
590
  printBytes("src", source, sourceSize);
 
591
  printf("\n");
 
592
  printString("targ", target );
 
593
  printf("\n");
 
594
 
 
595
  return U_ZERO_ERROR;
 
596
}
 
597
 
 
598
 
 
599
/******************************************************
 
600
  Similar sample to the preceding one. 
 
601
  You must call ucnv_close to clean up the memory used by the
 
602
  converter.
 
603
 
 
604
  'len' returns the number of OUTPUT bytes resulting from the 
 
605
  conversion.
 
606
 */
 
607
 
 
608
UErrorCode convsample_12()
 
609
{
 
610
  printf("\n\n==============================================\n"
 
611
         "Sample 12: C: simple sjis -> unicode conversion\n");
 
612
 
 
613
 
 
614
  // **************************** START SAMPLE *******************
 
615
 
 
616
  char source[] = { 0x63, 0x61, 0x74, (char)0x94, 0x4C, (char)0x82, 0x6E, (char)0x82, 0x6A, 0x00 };
 
617
  UChar target[100];
 
618
  UErrorCode status = U_ZERO_ERROR;
 
619
  UConverter *conv;
 
620
  int32_t     len;
 
621
 
 
622
  // set up the converter
 
623
  conv = ucnv_open("shift_jis", &status);
 
624
  assert(U_SUCCESS(status));
 
625
 
 
626
  // convert to Unicode
 
627
  // Note: we can use strlen, we know it's an 8 bit null terminated codepage
 
628
  target[6] = 0xFDCA;
 
629
  len = ucnv_toUChars(conv, target, 100, source, strlen(source), &status);
 
630
  U_ASSERT(status);
 
631
  // close the converter
 
632
  ucnv_close(conv);
 
633
 
 
634
  // ***************************** END SAMPLE ********************
 
635
  
 
636
  // Print it out
 
637
  printBytes("src", source, strlen(source) );
 
638
  printf("\n");
 
639
  printUChars("targ", target, len);
 
640
 
 
641
  return U_ZERO_ERROR;
 
642
}
 
643
 
 
644
 
 
645
/******************************************************************
 
646
   C: Convert from codepage to Unicode one at a time. 
 
647
*/
 
648
  
 
649
UErrorCode convsample_13()
 
650
{
 
651
  printf("\n\n==============================================\n"
 
652
         "Sample 13: C: simple Big5 -> unicode conversion, char at a time\n");
 
653
 
 
654
 
 
655
  const char sourceChars[] = { 0x7a, 0x68, 0x3d, (char)0xa4, (char)0xa4, (char)0xa4, (char)0xe5, (char)0x2e };
 
656
  //  const char sourceChars[] = { 0x7a, 0x68, 0x3d, 0xe4, 0xb8, 0xad, 0xe6, 0x96, 0x87, 0x2e };
 
657
  const char *source, *sourceLimit;
 
658
  UChar32 target;
 
659
  UErrorCode status = U_ZERO_ERROR;
 
660
  UConverter *conv = NULL;
 
661
  int32_t srcCount=0;
 
662
  int32_t dstCount=0;
 
663
  
 
664
  srcCount = sizeof(sourceChars);
 
665
 
 
666
  conv = ucnv_open("Big5", &status);
 
667
  U_ASSERT(status);
 
668
 
 
669
  source = sourceChars;
 
670
  sourceLimit = sourceChars + sizeof(sourceChars);
 
671
 
 
672
  // **************************** START SAMPLE *******************
 
673
 
 
674
 
 
675
  printBytes("src",source,sourceLimit-source);
 
676
 
 
677
  while(source < sourceLimit)
 
678
  {
 
679
    puts("");
 
680
    target = ucnv_getNextUChar (conv,
 
681
                                &source,
 
682
                                sourceLimit,
 
683
                                &status);
 
684
    
 
685
    //    printBytes("src",source,sourceLimit-source);
 
686
    U_ASSERT(status);
 
687
    printUChar(target);
 
688
    dstCount++;
 
689
  }
 
690
  
 
691
  
 
692
  // ************************** END SAMPLE *************************
 
693
  
 
694
  printf("src=%d bytes, dst=%d uchars\n", srcCount, dstCount);
 
695
  ucnv_close(conv);
 
696
 
 
697
  return U_ZERO_ERROR;
 
698
}
 
699
 
 
700
 
 
701
 
 
702
 
 
703
UBool convsample_20_didSubstitute(const char *source)
 
704
{
 
705
  UChar uchars[100];
 
706
  char bytes[100];
 
707
  UConverter *conv = NULL;
 
708
  UErrorCode status = U_ZERO_ERROR;
 
709
  uint32_t len, len2;
 
710
  
 
711
  FromUFLAGContext context;
 
712
 
 
713
  printf("\n\n==============================================\n"
 
714
         "Sample 20: C: Test for substitution using callbacks\n");
 
715
 
 
716
  /* print out the original source */
 
717
  printBytes("src", source);
 
718
  printf("\n");
 
719
 
 
720
  /* First, convert from UTF8 to unicode */
 
721
  conv = ucnv_open("utf-8", &status);
 
722
  U_ASSERT(status);
 
723
 
 
724
  len = ucnv_toUChars(conv, uchars, 100, source, strlen(source), &status);
 
725
  U_ASSERT(status);
 
726
 
 
727
  printUChars("uch", uchars, len);
 
728
  printf("\n");
 
729
 
 
730
  /* Now, close the converter */
 
731
  ucnv_close(conv);
 
732
 
 
733
  /* Now, convert to windows-1252 */
 
734
  conv = ucnv_open("windows-1252", &status);
 
735
  U_ASSERT(status);
 
736
 
 
737
  /* Converter starts out with the SUBSTITUTE callback set. */
 
738
 
 
739
  /* initialize our callback */
 
740
  context.subCallback = NULL;
 
741
  context.subContext  = NULL;
 
742
  context.flag        = FALSE;
 
743
 
 
744
  /* Set our special callback */
 
745
  ucnv_setFromUCallBack(conv,
 
746
                        UCNV_FROM_U_CALLBACK_FLAG,
 
747
                        &context,
 
748
                        &context.subCallback,
 
749
                        &context.subContext,
 
750
                        &status);
 
751
  U_ASSERT(status);
 
752
 
 
753
  len2 = ucnv_fromUChars(conv, bytes, 100, uchars, len, &status);
 
754
  U_ASSERT(status);
 
755
 
 
756
  ucnv_close(conv);
 
757
 
 
758
  /* print out the original source */
 
759
  printBytes("bytes", bytes, len2);
 
760
 
 
761
  return context.flag; /* true if callback was called */
 
762
}
 
763
 
 
764
UErrorCode convsample_20()
 
765
{
 
766
  const char *sample1 = "abc\xdf\xbf";
 
767
  const char *sample2 = "abc_def";
 
768
 
 
769
 
 
770
  if(convsample_20_didSubstitute(sample1))
 
771
  {
 
772
    printf("DID substitute.\n******\n");
 
773
  }
 
774
  else
 
775
  {
 
776
    printf("Did NOT substitute.\n*****\n");
 
777
  }
 
778
 
 
779
  if(convsample_20_didSubstitute(sample2))
 
780
  {
 
781
    printf("DID substitute.\n******\n");
 
782
  }
 
783
  else
 
784
  {
 
785
    printf("Did NOT substitute.\n*****\n");
 
786
  }
 
787
 
 
788
  return U_ZERO_ERROR;
 
789
}
 
790
 
 
791
//  40-  C, cp37 -> UTF16 [data02.bin -> data40.utf16]
 
792
 
 
793
#define BUFFERSIZE 17 /* make it interesting :) */
 
794
 
 
795
UErrorCode convsample_40()
 
796
{
 
797
  printf("\n\n==============================================\n"
 
798
    "Sample 40: C: convert data02.bin from cp37 to UTF16 [data40.utf16]\n");
 
799
 
 
800
  FILE *f;
 
801
  FILE *out;
 
802
  int32_t count;
 
803
  char inBuf[BUFFERSIZE];
 
804
  const char *source;
 
805
  const char *sourceLimit;
 
806
  UChar *uBuf;
 
807
  UChar *target;
 
808
  UChar *targetLimit;
 
809
  int32_t uBufSize = 0;
 
810
  UConverter *conv = NULL;
 
811
  UErrorCode status = U_ZERO_ERROR;
 
812
  uint32_t inbytes=0, total=0;
 
813
 
 
814
  f = fopen("data02.bin", "rb");
 
815
  if(!f)
 
816
  {
 
817
    fprintf(stderr, "Couldn't open file 'data02.bin' (cp37 data file).\n");
 
818
    return U_FILE_ACCESS_ERROR;
 
819
  }
 
820
 
 
821
  out = fopen("data40.utf16", "wb");
 
822
  if(!out)
 
823
  {
 
824
    fprintf(stderr, "Couldn't create file 'data40.utf16'.\n");
 
825
    return U_FILE_ACCESS_ERROR;
 
826
  }
 
827
 
 
828
  // **************************** START SAMPLE *******************
 
829
  conv = ucnv_openCCSID(37, UCNV_IBM, &status);
 
830
  assert(U_SUCCESS(status));
 
831
 
 
832
  uBufSize = (BUFFERSIZE/ucnv_getMinCharSize(conv));
 
833
  printf("input bytes %d / min chars %d = %d UChars\n",
 
834
         BUFFERSIZE, ucnv_getMinCharSize(conv), uBufSize);
 
835
  uBuf = (UChar*)malloc(uBufSize * sizeof(UChar));
 
836
  assert(uBuf!=NULL);
 
837
 
 
838
  // grab another buffer's worth
 
839
  while((!feof(f)) && 
 
840
        ((count=fread(inBuf, 1, BUFFERSIZE , f)) > 0) )
 
841
  {
 
842
    inbytes += count;
 
843
 
 
844
    // Convert bytes to unicode
 
845
    source = inBuf;
 
846
    sourceLimit = inBuf + count;
 
847
    
 
848
    do
 
849
    {
 
850
        target = uBuf;
 
851
        targetLimit = uBuf + uBufSize;
 
852
        
 
853
        ucnv_toUnicode( conv, &target, targetLimit, 
 
854
                       &source, sourceLimit, NULL,
 
855
                       feof(f)?TRUE:FALSE,         /* pass 'flush' when eof */
 
856
                                   /* is true (when no more data will come) */
 
857
                         &status);
 
858
      
 
859
        if(status == U_BUFFER_OVERFLOW_ERROR)
 
860
        {
 
861
          // simply ran out of space - we'll reset the target ptr the next
 
862
          // time through the loop.
 
863
          status = U_ZERO_ERROR;
 
864
        }
 
865
        else
 
866
        {
 
867
          //  Check other errors here.
 
868
          assert(U_SUCCESS(status));
 
869
          // Break out of the loop (by force)
 
870
        }
 
871
 
 
872
        // Process the Unicode
 
873
        // Todo: handle UTF-16/surrogates
 
874
        assert(fwrite(uBuf, sizeof(uBuf[0]), (target-uBuf), out) ==
 
875
               (size_t)(target-uBuf));
 
876
        total += (target-uBuf);
 
877
    } while (source < sourceLimit); // while simply out of space
 
878
  }
 
879
 
 
880
  printf("%d bytes in,  %d UChars out.\n", inbytes, total);
 
881
  
 
882
  // ***************************** END SAMPLE ********************
 
883
  ucnv_close(conv);
 
884
 
 
885
  fclose(f);
 
886
  fclose(out);
 
887
  printf("\n");
 
888
 
 
889
  return U_ZERO_ERROR;
 
890
}
 
891
#undef BUFFERSIZE
 
892
 
 
893
//        convsample_41();  // C++, cp37 -> UTF16 [data02.bin -> data41.utf16]
 
894
 
 
895
#define BUFFERSIZE 17 /* make it interesting :) */
 
896
 
 
897
UErrorCode convsample_41()
 
898
{
 
899
  printf("\n\n==============================================\n"
 
900
         "Sample 41: C++: convert data02.bin from cp37 to UTF16 [data41.utf16]\n");
 
901
 
 
902
  FILE *f;
 
903
  FILE *out;
 
904
  int32_t count;
 
905
  char inBuf[BUFFERSIZE];
 
906
  const char *source;
 
907
  const char *sourceLimit;
 
908
  UChar *uBuf;
 
909
  UChar *target;
 
910
  UChar *targetLimit;
 
911
  int32_t uBufSize = 0;
 
912
  UnicodeConverter *conv;
 
913
  UErrorCode status = U_ZERO_ERROR;
 
914
  uint32_t inbytes=0, total=0;
 
915
 
 
916
  f = fopen("data02.bin", "rb");
 
917
  if(!f)
 
918
  {
 
919
    fprintf(stderr, "Couldn't open file 'data02.bin' (cp37 data file).\n");
 
920
    return U_FILE_ACCESS_ERROR;
 
921
  }
 
922
 
 
923
  out = fopen("data41.utf16", "wb");
 
924
  if(!out)
 
925
  {
 
926
    fprintf(stderr, "Couldn't create file 'data41.utf16'.\n");
 
927
    return U_FILE_ACCESS_ERROR;
 
928
  }
 
929
 
 
930
  // **************************** START SAMPLE *******************
 
931
  conv = new UnicodeConverter(37, UCNV_IBM, status);
 
932
  assert(U_SUCCESS(status));
 
933
 
 
934
  uBufSize = (BUFFERSIZE/conv->getMinBytesPerChar());
 
935
  //uBufSize = 4;
 
936
  printf("input bytes %d / min chars %d = %d UChars\n",
 
937
         BUFFERSIZE, conv->getMinBytesPerChar(), uBufSize);
 
938
  uBuf = (UChar*)malloc(uBufSize * sizeof(UChar));
 
939
  assert(uBuf!=NULL);
 
940
 
 
941
  // grab another buffer's worth
 
942
  while((!feof(f)) && 
 
943
        ((count=fread(inBuf, 1, BUFFERSIZE , f)) > 0) )
 
944
  {
 
945
    inbytes += count;
 
946
 
 
947
    // Convert bytes to unicode
 
948
    source = inBuf;
 
949
    sourceLimit = inBuf + count;
 
950
    
 
951
    do
 
952
    {
 
953
        target = uBuf;
 
954
        targetLimit = uBuf + uBufSize;
 
955
        
 
956
        conv->toUnicode( target, targetLimit, 
 
957
                       source, sourceLimit, NULL,
 
958
                       feof(f)?TRUE:FALSE,         /* pass 'flush' when eof */
 
959
                                   /* is true (when no more data will come) */
 
960
                         status);
 
961
      
 
962
        if(status == U_BUFFER_OVERFLOW_ERROR)
 
963
        {
 
964
          // simply ran out of space - we'll reset the target ptr the next
 
965
          // time through the loop.
 
966
          status = U_ZERO_ERROR;
 
967
        }
 
968
        else
 
969
        {
 
970
          //  Check other errors here.
 
971
          assert(U_SUCCESS(status));
 
972
          // Break out of the loop (by force)
 
973
        }
 
974
 
 
975
        // Process the Unicode
 
976
        // Todo: handle UTF-16/surrogates
 
977
        assert(fwrite(uBuf, sizeof(uBuf[0]), (target-uBuf), out) ==
 
978
               (size_t)(target-uBuf));
 
979
        total += (target-uBuf);
 
980
 
 
981
        fprintf(stderr, "srcLeft=%d, wrote %d, err %s\n",
 
982
                sourceLimit - source, target-uBuf, u_errorName(status));
 
983
 
 
984
    } while (source < sourceLimit); // while simply out of space
 
985
  }
 
986
 
 
987
  printf("%d bytes in,  %d UChars out.\n", inbytes, total);
 
988
  
 
989
  // ***************************** END SAMPLE ********************
 
990
  delete conv;
 
991
 
 
992
  fclose(f);
 
993
  fclose(out);
 
994
  printf("\n");
 
995
 
 
996
  return U_ZERO_ERROR;
 
997
}
 
998
#undef BUFFERSIZE
 
999
 
 
1000
 
 
1001
 
 
1002
//  46-  C, UTF16 -> latin2 [data41.utf16 -> data46.out]
 
1003
 
 
1004
#define BUFFERSIZE 24 /* make it interesting :) */
 
1005
 
 
1006
UErrorCode convsample_46()
 
1007
{
 
1008
  printf("\n\n==============================================\n"
 
1009
    "Sample 46: C: convert data41.utf16 from UTF16 to latin2 [data46.out]\n");
 
1010
 
 
1011
  FILE *f;
 
1012
  FILE *out;
 
1013
  int32_t count;
 
1014
  UChar inBuf[BUFFERSIZE];
 
1015
  const UChar *source;
 
1016
  const UChar *sourceLimit;
 
1017
  char *buf;
 
1018
  char *target;
 
1019
  char *targetLimit;
 
1020
 
 
1021
  int32_t bufSize = 0;
 
1022
  UConverter *conv = NULL;
 
1023
  UErrorCode status = U_ZERO_ERROR;
 
1024
  uint32_t inchars=0, total=0;
 
1025
 
 
1026
  f = fopen("data41.utf16", "rb");
 
1027
  if(!f)
 
1028
  {
 
1029
    fprintf(stderr, "Couldn't open file 'data41.utf16' (did you run convsample_41() ?)\n");
 
1030
    return U_FILE_ACCESS_ERROR;
 
1031
  }
 
1032
 
 
1033
  out = fopen("data46.out", "wb");
 
1034
  if(!out)
 
1035
  {
 
1036
    fprintf(stderr, "Couldn't create file 'data46.out'.\n");
 
1037
    return U_FILE_ACCESS_ERROR;
 
1038
  }
 
1039
 
 
1040
  // **************************** START SAMPLE *******************
 
1041
  conv = ucnv_open( "iso-8859-2", &status);
 
1042
  assert(U_SUCCESS(status));
 
1043
 
 
1044
  bufSize = (BUFFERSIZE*ucnv_getMaxCharSize(conv));
 
1045
  printf("input UChars[16] %d * max charsize %d = %d bytes output buffer\n",
 
1046
         BUFFERSIZE, ucnv_getMaxCharSize(conv), bufSize);
 
1047
  buf = (char*)malloc(bufSize * sizeof(char));
 
1048
  assert(buf!=NULL);
 
1049
 
 
1050
  // grab another buffer's worth
 
1051
  while((!feof(f)) && 
 
1052
        ((count=fread(inBuf, sizeof(UChar), BUFFERSIZE , f)) > 0) )
 
1053
  {
 
1054
    inchars += count;
 
1055
 
 
1056
    // Convert bytes to unicode
 
1057
    source = inBuf;
 
1058
    sourceLimit = inBuf + count;
 
1059
    
 
1060
    do
 
1061
    {
 
1062
        target = buf;
 
1063
        targetLimit = buf + bufSize;
 
1064
        
 
1065
        ucnv_fromUnicode( conv, &target, targetLimit, 
 
1066
                       &source, sourceLimit, NULL,
 
1067
                       feof(f)?TRUE:FALSE,         /* pass 'flush' when eof */
 
1068
                                   /* is true (when no more data will come) */
 
1069
                         &status);
 
1070
      
 
1071
        if(status == U_BUFFER_OVERFLOW_ERROR)
 
1072
        {
 
1073
          // simply ran out of space - we'll reset the target ptr the next
 
1074
          // time through the loop.
 
1075
          status = U_ZERO_ERROR;
 
1076
        }
 
1077
        else
 
1078
        {
 
1079
          //  Check other errors here.
 
1080
          assert(U_SUCCESS(status));
 
1081
          // Break out of the loop (by force)
 
1082
        }
 
1083
 
 
1084
        // Process the Unicode
 
1085
        assert(fwrite(buf, sizeof(buf[0]), (target-buf), out) ==
 
1086
               (size_t)(target-buf));
 
1087
        total += (target-buf);
 
1088
    } while (source < sourceLimit); // while simply out of space
 
1089
  }
 
1090
 
 
1091
  printf("%d Uchars (%d bytes) in, %d chars out.\n", inchars, inchars * sizeof(UChar), total);
 
1092
  
 
1093
  // ***************************** END SAMPLE ********************
 
1094
  ucnv_close(conv);
 
1095
 
 
1096
  fclose(f);
 
1097
  fclose(out);
 
1098
  printf("\n");
 
1099
 
 
1100
  return U_ZERO_ERROR;
 
1101
}
 
1102
#undef BUFFERSIZE
 
1103
 
 
1104
#define BUFFERSIZE 219
 
1105
 
 
1106
UErrorCode convsample_47()
 
1107
{
 
1108
  printf("\n\n==============================================\n"
 
1109
         "Sample 47: C++: convert data40.utf16 from UTF16 to latin2 [data47.out]\n");
 
1110
 
 
1111
  FILE *f;
 
1112
  FILE *out;
 
1113
  int32_t count;
 
1114
  UChar inBuf[BUFFERSIZE];
 
1115
  const UChar *source;
 
1116
  const UChar *sourceLimit;
 
1117
  char *buf;
 
1118
  char *target;
 
1119
  char *targetLimit;
 
1120
 
 
1121
  int32_t bufSize = 0;
 
1122
  UnicodeConverter *conv = NULL;
 
1123
  UErrorCode status = U_ZERO_ERROR;
 
1124
  uint32_t inchars=0, total=0;
 
1125
 
 
1126
  f = fopen("data40.utf16", "rb");
 
1127
  if(!f)
 
1128
  {
 
1129
    fprintf(stderr, "Couldn't open file 'data40.utf16' (Did you run convsample_40() ?)\n");
 
1130
    return U_FILE_ACCESS_ERROR;
 
1131
  }
 
1132
 
 
1133
  out = fopen("data47.out", "wb");
 
1134
  if(!out)
 
1135
  {
 
1136
    fprintf(stderr, "Couldn't create file 'data47.out'.\n");
 
1137
    return U_FILE_ACCESS_ERROR;
 
1138
  }
 
1139
 
 
1140
 
 
1141
  // **************************** START SAMPLE *******************
 
1142
  conv = new UnicodeConverter( "iso-8859-2", status);
 
1143
  assert(U_SUCCESS(status));
 
1144
 
 
1145
  bufSize = (BUFFERSIZE*conv->getMaxBytesPerChar());
 
1146
  printf("input UChars[16] %d * max charsize %d = %d bytes output buffer\n",
 
1147
         BUFFERSIZE, conv->getMaxBytesPerChar(), bufSize);
 
1148
  buf = (char*)malloc(bufSize * sizeof(char));
 
1149
  assert(buf!=NULL);
 
1150
 
 
1151
  // grab another buffer's worth
 
1152
  while((!feof(f)) && 
 
1153
        ((count=fread(inBuf, sizeof(UChar), BUFFERSIZE , f)) > 0) )
 
1154
  {
 
1155
    inchars += count;
 
1156
 
 
1157
    // Convert bytes to unicode
 
1158
    source = inBuf;
 
1159
    sourceLimit = inBuf + count;
 
1160
    
 
1161
    do
 
1162
    {
 
1163
        target = buf;
 
1164
        targetLimit = buf + bufSize;
 
1165
        
 
1166
        conv->fromUnicode( target, targetLimit, 
 
1167
                source, sourceLimit, NULL,
 
1168
                           feof(f)?TRUE:FALSE,         /* pass 'flush' when eof */
 
1169
                           /* is true (when no more data will come) */
 
1170
                           status);
 
1171
        
 
1172
        if(status == U_BUFFER_OVERFLOW_ERROR)
 
1173
        {
 
1174
          // simply ran out of space - we'll reset the target ptr the next
 
1175
          // time through the loop.
 
1176
          status = U_ZERO_ERROR;
 
1177
        }
 
1178
        else
 
1179
        {
 
1180
          //  Check other errors here.
 
1181
          assert(U_SUCCESS(status));
 
1182
          // Break out of the loop (by force)
 
1183
        }
 
1184
 
 
1185
        // Process the Unicode
 
1186
        assert(fwrite(buf, sizeof(buf[0]), (target-buf), out) ==
 
1187
               (size_t)(target-buf));
 
1188
        total += (target-buf);
 
1189
    } while (source < sourceLimit); // while simply out of space
 
1190
  }
 
1191
 
 
1192
  printf("%d Uchars (%d bytes) in, %d chars out.\n", inchars, inchars * sizeof(UChar), total);
 
1193
  
 
1194
  // ***************************** END SAMPLE ********************
 
1195
  delete conv;
 
1196
 
 
1197
  fclose(f);
 
1198
  fclose(out);
 
1199
  printf("\n");
 
1200
 
 
1201
  return U_ZERO_ERROR;
 
1202
}
 
1203
#undef BUFFERSIZE
 
1204
 
 
1205
 
 
1206
/* main */
 
1207
 
 
1208
int main()
 
1209
{
 
1210
 
 
1211
  printf("Default Converter=%s\n", ucnv_getDefaultName() );
 
1212
  
 
1213
    convsample_01();  // C++, u->koi8r, conv
 
1214
    convsample_02();  // C  , u->koi8r, conv
 
1215
    convsample_03();  // C,   iterate
 
1216
 //  convsample_04();  /* not written yet */
 
1217
    convsample_05();  // C,  utf8->u, getNextUChar
 
1218
    convsample_06(); // C freq counter thingy
 
1219
    convsample_11();  // C++, sjis->u, conv
 
1220
    convsample_12();  // C,  sjis->u, conv
 
1221
    convsample_13();  // C,  big5->u, getNextU
 
1222
  
 
1223
    convsample_20();  // C, callback
 
1224
  
 
1225
    convsample_40();  // C,   cp37 -> UTF16 [data02.bin -> data40.utf16]
 
1226
    convsample_41();  // C++, cp37 -> UTF16 [data02.bin -> data41.utf16]
 
1227
  
 
1228
    convsample_46();  // C,  UTF16 -> latin3 [data41.utf16 -> data46.out]
 
1229
    convsample_47();  // C++,UTF16 -> latin3 [data40.utf16 -> data47.out]
 
1230
        
 
1231
   return 0;
 
1232
}