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

« back to all changes in this revision

Viewing changes to source/test/cintltst/susctest.c

  • 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
 * COPYRIGHT: 
 
3
 * Copyright (c) 1997-2001, International Business Machines Corporation and
 
4
 * others. All Rights Reserved.
 
5
 ********************************************************************/
 
6
/*
 
7
* File test.c
 
8
*
 
9
* Modification History:
 
10
*
 
11
*   Date        Name        Description
 
12
*   05/17/99    stephen     Creation (ported from java)
 
13
*   09/24/99    stephen     Added new test for data split on decompression.
 
14
*******************************************************************************
 
15
*/
 
16
 
 
17
#include <stdio.h>
 
18
#include <time.h>
 
19
 
 
20
#include "unicode/scsu.h"
 
21
#include "unicode/ustring.h"
 
22
#include "unicode/utypes.h"
 
23
#include "cintltst.h"
 
24
#include "cstring.h"
 
25
#include "cmemory.h"
 
26
 
 
27
#ifdef ICU_SCSU_USE_DEPRECATES
 
28
 
 
29
#ifdef MIN
 
30
#  undef MIN
 
31
#endif
 
32
 
 
33
#define MIN(a,b) (a < b ? a : b)
 
34
 
 
35
#ifdef MAX
 
36
#  undef MAX
 
37
#endif
 
38
 
 
39
#define MAX(a,b) (a > b ? a : b)
 
40
 
 
41
 
 
42
/* Compression modes */
 
43
#define SINGLEBYTEMODE 0
 
44
#define UNICODEMODE 1
 
45
 
 
46
 
 
47
/* Single-byte mode tags */
 
48
#define SDEFINEX 0x0B
 
49
/* 0x0C is a reserved value*/
 
50
#define SRESERVED 0x0C
 
51
#define SQUOTEU 0x0E
 
52
#define SCHANGEU 0x0F
 
53
 
 
54
#define SQUOTE0 0x01
 
55
#define SQUOTE1 0x02
 
56
#define SQUOTE2 0x03
 
57
#define SQUOTE3 0x04
 
58
#define SQUOTE4 0x05
 
59
#define SQUOTE5 0x06
 
60
#define SQUOTE6 0x07
 
61
#define SQUOTE7 0x08
 
62
 
 
63
#define SCHANGE0 0x10
 
64
#define SCHANGE1 0x11
 
65
#define SCHANGE2 0x12
 
66
#define SCHANGE3 0x13
 
67
#define SCHANGE4 0x14
 
68
#define SCHANGE5 0x15
 
69
#define SCHANGE6 0x16
 
70
#define SCHANGE7 0x17
 
71
 
 
72
#define SDEFINE0 0x18
 
73
#define SDEFINE1 0x19
 
74
#define SDEFINE2 0x1A
 
75
#define SDEFINE3 0x1B
 
76
#define SDEFINE4 0x1C
 
77
#define SDEFINE5 0x1D
 
78
#define SDEFINE6 0x1E
 
79
#define SDEFINE7 0x1F
 
80
 
 
81
/* Unicode mode tags */
 
82
#define UCHANGE0 0xE0
 
83
#define UCHANGE1 0xE1
 
84
#define UCHANGE2 0xE2
 
85
#define UCHANGE3 0xE3
 
86
#define UCHANGE4 0xE4
 
87
#define UCHANGE5 0xE5
 
88
#define UCHANGE6 0xE6
 
89
#define UCHANGE7 0xE7
 
90
 
 
91
#define UDEFINE0 0xE8
 
92
#define UDEFINE1 0xE9
 
93
#define UDEFINE2 0xEA
 
94
#define UDEFINE3 0xEB
 
95
#define UDEFINE4 0xEC
 
96
#define UDEFINE5 0xED
 
97
#define UDEFINE6 0xEE
 
98
#define UDEFINE7 0xEF
 
99
 
 
100
#define UQUOTEU 0xF0
 
101
#define UDEFINEX 0xF1
 
102
 
 
103
static int32_t 
 
104
digitvalue(char c)
 
105
{
 
106
  return c - 0x30 - (c >= 0x41 ? (c >= 0x61 ? 39 : 7) : 0);
 
107
}
 
108
 
 
109
static UChar* 
 
110
unescape(const char *s)
 
111
{
 
112
  UChar *retval;
 
113
  UChar *alias;
 
114
 
 
115
  retval = (UChar*) calloc(uprv_strlen(s) + 1, sizeof(UChar));
 
116
  if(retval == 0) {
 
117
    log_err("calloc error at line %d - memory error..\n", __LINE__);
 
118
    return 0; /* flag an error */
 
119
  }
 
120
 
 
121
  alias = retval;
 
122
 
 
123
  while(*s != '\0') {
 
124
    if(*s == '\\') {
 
125
      int32_t value;
 
126
      ++s; /* skip '\' */
 
127
      value = digitvalue(*s++);
 
128
      value *= 16;
 
129
      value += digitvalue(*s++);
 
130
      value *= 16;
 
131
      value += digitvalue(*s++);
 
132
      value *= 16;
 
133
      value += digitvalue(*s++);
 
134
 
 
135
      *alias++ = (UChar)value;
 
136
    }
 
137
    else
 
138
      *alias++ = *s++;
 
139
  }
 
140
 
 
141
  *alias = 0x0000;
 
142
 
 
143
  return retval;
 
144
}
 
145
 
 
146
static void
 
147
printChars(const UChar *chars, 
 
148
           int32_t len)
 
149
{
 
150
  int32_t i;
 
151
 
 
152
  for(i = 0; i < len; i++) {
 
153
    printf("%#x ", chars[i]);
 
154
  }
 
155
  puts("");
 
156
}
 
157
 
 
158
 
 
159
/*
 
160
static void 
 
161
printChars2(const UChar *chars, 
 
162
            int32_t len)
 
163
{
 
164
  int32_t i;
 
165
  
 
166
  for(i = 0; i < len; i++) {
 
167
    if(chars[i] < 0x0020 || chars[i] > 0x007E)
 
168
      printf("[%#x]", chars[i]);
 
169
    else
 
170
      printf("%c", chars[i]);
 
171
  }
 
172
  puts("");
 
173
}
 
174
*/
 
175
 
 
176
static void 
 
177
printBytes(const uint8_t *byteBuffer, 
 
178
           int32_t len)
 
179
{
 
180
  int32_t curByteIndex = 0;
 
181
  int32_t byteBufferLimit = len;
 
182
  int32_t mode = SINGLEBYTEMODE;
 
183
  int32_t aByte = 0x00;
 
184
  
 
185
  while(curByteIndex < byteBufferLimit) {
 
186
    switch(mode) {  
 
187
    case SINGLEBYTEMODE:
 
188
      while(curByteIndex < byteBufferLimit && mode == SINGLEBYTEMODE) {
 
189
    aByte = byteBuffer[curByteIndex++] & 0xFF;
 
190
    switch(aByte) {
 
191
    default:
 
192
      printf("%#x ", aByte);
 
193
      break;
 
194
      
 
195
      
 
196
      /* quote unicode*/
 
197
    case SQUOTEU:
 
198
      printf("SQUOTEU ");
 
199
      if(curByteIndex < byteBufferLimit)
 
200
        printf("%#x ", byteBuffer[curByteIndex++]);
 
201
      if(curByteIndex < byteBufferLimit)
 
202
        printf("%#x ", byteBuffer[curByteIndex++]);
 
203
      break;
 
204
 
 
205
      /* switch to Unicode mode*/
 
206
    case SCHANGEU:
 
207
      printf("SCHANGEU ");
 
208
      mode = UNICODEMODE;
 
209
      break;
 
210
 
 
211
      /* handle all quote tags*/
 
212
    case SQUOTE0:   case SQUOTE1:   case SQUOTE2:   case SQUOTE3:
 
213
    case SQUOTE4:   case SQUOTE5:   case SQUOTE6:   case SQUOTE7:
 
214
      printf("SQUOTE%d ", aByte - SQUOTE0);
 
215
      if(curByteIndex < byteBufferLimit)
 
216
        printf("%#x ", byteBuffer[curByteIndex++]);
 
217
      break;
 
218
 
 
219
      /* handle all switch tags*/
 
220
    case SCHANGE0:  case SCHANGE1:  case SCHANGE2:  case SCHANGE3:
 
221
    case SCHANGE4:  case SCHANGE5:  case SCHANGE6:  case SCHANGE7:
 
222
      printf("SCHANGE%d ", aByte - SCHANGE0);
 
223
      break;
 
224
      
 
225
      /* handle all define tags*/
 
226
    case SDEFINE0:  case SDEFINE1:  case SDEFINE2:  case SDEFINE3:
 
227
    case SDEFINE4:  case SDEFINE5:  case SDEFINE6:  case SDEFINE7:
 
228
      printf("SDEFINE%d ", aByte - SDEFINE0);
 
229
      if(curByteIndex < byteBufferLimit)
 
230
        printf("%#x ", byteBuffer[curByteIndex++]);
 
231
      break;
 
232
 
 
233
      /* handle define extended tag*/
 
234
    case SDEFINEX:
 
235
      printf("SDEFINEX ");
 
236
      if(curByteIndex < byteBufferLimit)
 
237
        printf("%#x ", byteBuffer[curByteIndex++]);
 
238
      if(curByteIndex < byteBufferLimit)
 
239
        printf("%#x ", byteBuffer[curByteIndex++]);
 
240
      break;
 
241
 
 
242
    } /* end switch*/
 
243
      } /* end while*/
 
244
      break;
 
245
      
 
246
    case UNICODEMODE:
 
247
      while(curByteIndex < byteBufferLimit && mode == UNICODEMODE) {
 
248
 
 
249
    aByte = byteBuffer[curByteIndex++] & 0xFF;
 
250
 
 
251
    switch(aByte) {
 
252
      /* handle all define tags*/
 
253
    case UDEFINE0:  case UDEFINE1:  case UDEFINE2:  case UDEFINE3:
 
254
    case UDEFINE4:  case UDEFINE5:  case UDEFINE6:  case UDEFINE7:
 
255
      printf("UDEFINE%d ", aByte - UDEFINE0);
 
256
      if(curByteIndex < byteBufferLimit)
 
257
        printf("%#x ", byteBuffer[curByteIndex++]);
 
258
      mode = SINGLEBYTEMODE;
 
259
      break;
 
260
 
 
261
      /* handle define extended tag*/
 
262
    case UDEFINEX:
 
263
      printf("UDEFINEX ");
 
264
      if(curByteIndex < byteBufferLimit)
 
265
        printf("%#x ", byteBuffer[curByteIndex++]);
 
266
      if(curByteIndex < byteBufferLimit)
 
267
        printf("%#x ", byteBuffer[curByteIndex++]);
 
268
      break;
 
269
 
 
270
      /* handle all switch tags*/
 
271
    case UCHANGE0:  case UCHANGE1:  case UCHANGE2:  case UCHANGE3:
 
272
    case UCHANGE4:  case UCHANGE5:  case UCHANGE6:  case UCHANGE7:
 
273
      printf("UCHANGE%d ", aByte - UCHANGE0);
 
274
      mode = SINGLEBYTEMODE;
 
275
      break;
 
276
 
 
277
      /* quote unicode*/
 
278
    case UQUOTEU:
 
279
      printf("UQUOTEU ");
 
280
      if(curByteIndex < byteBufferLimit)
 
281
        printf("%#x ", byteBuffer[curByteIndex++]);
 
282
      if(curByteIndex < byteBufferLimit)
 
283
        printf("%#x ", byteBuffer[curByteIndex++]);
 
284
      break;
 
285
      
 
286
    default:
 
287
      printf("%#x ", aByte);
 
288
      if(curByteIndex < byteBufferLimit)
 
289
        printf("%#x ", byteBuffer[curByteIndex++]);
 
290
      break;
 
291
      
 
292
    } /* end switch*/
 
293
      } /* end while*/
 
294
      break;
 
295
      
 
296
    } /* end switch( mode )*/
 
297
  } /* end while*/
 
298
  
 
299
  puts("");
 
300
}
 
301
 
 
302
static UBool
 
303
printDiffs(const UChar *s1, 
 
304
           int32_t s1len, 
 
305
           const UChar *s2, 
 
306
           int32_t s2len)
 
307
{
 
308
  UBool result  = FALSE;
 
309
  int32_t len;
 
310
  int32_t i;
 
311
 
 
312
  if(s1len != s2len) {
 
313
    puts("====================");
 
314
    printf("Length doesn't match: expected %d, got %d\n", s1len, s2len);
 
315
    puts("Expected:");
 
316
    printChars(s1, s1len);
 
317
    puts("Got:");
 
318
    printChars(s2, s2len);
 
319
    result = TRUE;
 
320
  }
 
321
  
 
322
  len = (s1len < s2len ? s1len : s2len);
 
323
  for(i = 0; i < len; ++i) {
 
324
    if(s1[i] != s2[i]) {
 
325
      if(result == FALSE)
 
326
        puts("====================");
 
327
      printf("First difference at char %d\n", i);
 
328
      printf("Exp. char: %#x\n", s1[i]);
 
329
      printf("Got char : %#x\n", s2[i]);
 
330
      puts("Expected:");
 
331
      printChars(s1, s1len);
 
332
      puts("Got:");
 
333
      printChars(s2, s2len);
 
334
      result = TRUE;
 
335
      break;
 
336
    }
 
337
  }
 
338
  
 
339
  return result;
 
340
}
 
341
 
 
342
/* generate a run of characters in a "window" */
 
343
static void
 
344
randomRun(UChar *target, 
 
345
      int32_t pos, 
 
346
      int32_t len)
 
347
{
 
348
  int32_t offset = (int32_t)(0xFFFF * (double)(rand()/(double)RAND_MAX));
 
349
  int32_t i;
 
350
 
 
351
  /* don't overflow 16 bits*/
 
352
  if(offset > 0xFF80)
 
353
    offset = 0xFF80;
 
354
  
 
355
  for(i = pos; i < pos + len; i++) {
 
356
    target[i] = (UChar) (offset + (int32_t)(0x7F * (double)(rand()/(double)RAND_MAX)));
 
357
  }
 
358
}
 
359
 
 
360
/* generate a string of characters, with simulated runs of characters */
 
361
static UChar* 
 
362
randomChars(int32_t len)
 
363
{
 
364
  UChar *result = 0;
 
365
  int32_t runLen = 0;
 
366
  int32_t used = 0;
 
367
 
 
368
  result = (UChar*) calloc(len, sizeof(UChar));
 
369
  if(result == 0) {
 
370
    log_err("calloc error at line %d.\n", __LINE__);
 
371
    return 0;
 
372
  }
 
373
 
 
374
  while(used < len) {
 
375
    runLen = (int32_t)(30 * (double)(rand()/(double)RAND_MAX));
 
376
    if(used + runLen >= len)
 
377
      runLen = len - used;
 
378
    randomRun(result, used, runLen);
 
379
    used += runLen;
 
380
  }
 
381
  
 
382
  return result;
 
383
}
 
384
 
 
385
static void 
 
386
myTest(const UChar *chars, 
 
387
       int32_t len)
 
388
{
 
389
  UnicodeCompressor myCompressor;
 
390
 
 
391
  /* compression variables */
 
392
  uint8_t *myCompressed  = 0;
 
393
  uint8_t *myCTarget = 0;
 
394
  int32_t myCTargetSize = MAX(512, 3*len);
 
395
  const UChar *myCSource = chars;
 
396
 
 
397
  /* decompression variables */
 
398
  UChar *myDecompressed = 0;
 
399
  UChar *myDTarget = 0;
 
400
  int32_t myDTargetSize = MAX(2*len, 2);
 
401
  const uint8_t *myDSource = 0;
 
402
  
 
403
  /* variables for my compressor */
 
404
  int32_t myByteCount = 0;
 
405
  int32_t myCharCount = 0;
 
406
 
 
407
  /* error code */
 
408
  UErrorCode status = U_ZERO_ERROR;
 
409
 
 
410
 
 
411
  /* allocate memory */
 
412
  myCompressed = (uint8_t*) calloc(myCTargetSize, sizeof(uint8_t));
 
413
  myDecompressed = (UChar*) calloc(myDTargetSize, sizeof(UChar));
 
414
  
 
415
  if(myCompressed == 0 || myDecompressed == 0) {
 
416
    log_err("calloc error at line %d.\n", __LINE__);
 
417
    return;
 
418
  }
 
419
  
 
420
  /* init compressor */
 
421
  scsu_init(&myCompressor);
 
422
 
 
423
  /* compress */
 
424
  myCTarget = myCompressed;
 
425
  scsu_compress(&myCompressor,
 
426
        &myCTarget,
 
427
        myCTarget + myCTargetSize,
 
428
        &myCSource,
 
429
        myCSource + len,
 
430
        &status);
 
431
 
 
432
  if(U_FAILURE(status)) {
 
433
    log_err("Failing status code at line %d.\n", __LINE__);
 
434
    return;
 
435
  }
 
436
 
 
437
  myByteCount = (myCTarget - myCompressed);
 
438
 
 
439
  /* reset */
 
440
  scsu_reset(&myCompressor);
 
441
 
 
442
  /* decompress */
 
443
  myDTarget = myDecompressed;
 
444
  myDSource = myCompressed;
 
445
  scsu_decompress(&myCompressor,
 
446
          &myDTarget,
 
447
          myDTarget + myDTargetSize,
 
448
          &myDSource,
 
449
          myDSource + myByteCount,
 
450
          &status);
 
451
 
 
452
  if(U_FAILURE(status)) {
 
453
    log_err("Failing status code at line %d.\n", __LINE__);
 
454
    return;
 
455
  }
 
456
  
 
457
  myCharCount = (myDTarget - myDecompressed);
 
458
 
 
459
  /* find differences */
 
460
  if( printDiffs(chars, len, myDecompressed, myCharCount) == FALSE) {
 
461
    /*printf("%d chars ===> %d bytes ===> %d chars (%f)\n", len, 
 
462
      myByteCount, myCharCount, (double)(myByteCount/(myCharCount*2.0)));*/
 
463
  }
 
464
  else {
 
465
    puts("Compressed:");
 
466
    printBytes(myCompressed, myByteCount);
 
467
  }
 
468
 
 
469
  /* clean up */
 
470
  free(myCompressed);
 
471
  free(myDecompressed);
 
472
}
 
473
 
 
474
/* tweak these; COMPRESSIONBUFFERSIZE must not be less than 4, and
 
475
   DECOMPRESSIONBUFFERSIZE must not be less than 2 */
 
476
#define COMPRESSIONBUFFERSIZE 4
 
477
#define DECOMPRESSIONBUFFERSIZE 2
 
478
 
 
479
static void 
 
480
myMultipassTest(const UChar *chars, 
 
481
        int32_t len)
 
482
{
 
483
  UnicodeCompressor myCompressor;
 
484
 
 
485
  /* compression variables */
 
486
  uint8_t myCompressionBuffer [COMPRESSIONBUFFERSIZE];
 
487
  uint8_t *myCompressed  = 0;
 
488
  uint8_t *myCTarget = 0;
 
489
  int32_t myCTargetSize = MAX(512, 3 * len);
 
490
  const UChar *myCSource = chars;
 
491
  const UChar *myCSourceAlias = 0;
 
492
 
 
493
  /* decompression variables */
 
494
  UChar myDecompressionBuffer [DECOMPRESSIONBUFFERSIZE];
 
495
  UChar *myDecompressed = 0;
 
496
  UChar *myDTarget = 0;
 
497
  int32_t myDTargetSize = MAX(2 * len, 2);
 
498
  const uint8_t *myDSource = 0;
 
499
  const uint8_t *myDSourceAlias = 0;
 
500
 
 
501
  /* counts */
 
502
  int32_t totalCharsCompressed    = 0;
 
503
  int32_t totalBytesWritten       = 0;
 
504
 
 
505
  int32_t totalBytesDecompressed  = 0;
 
506
  int32_t totalCharsWritten       = 0;
 
507
 
 
508
  /* error code */
 
509
  UErrorCode status = U_ZERO_ERROR;
 
510
 
 
511
  /* allocate memory */
 
512
  myCompressed = (uint8_t*) calloc(myCTargetSize, sizeof(uint8_t));
 
513
  myDecompressed = (UChar*) calloc(myDTargetSize, sizeof(UChar));
 
514
 
 
515
  if(myCompressed == 0 || myDecompressed == 0) {
 
516
    log_err("calloc error at line %d.\n", __LINE__);
 
517
    return ;
 
518
  }
 
519
 
 
520
  /* init compressor */
 
521
  scsu_init(&myCompressor);
 
522
 
 
523
  /* perform the compression in a loop */
 
524
  do {      
 
525
    status = U_ZERO_ERROR;
 
526
    myCTarget = myCompressionBuffer;    
 
527
    myCSourceAlias = myCSource;
 
528
 
 
529
    scsu_compress(&myCompressor,
 
530
          &myCTarget,
 
531
          myCTarget + COMPRESSIONBUFFERSIZE,
 
532
          &myCSource,
 
533
          chars + len,
 
534
          &status);
 
535
 
 
536
    if(status != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(status)) {
 
537
      log_err("Failing status code at line %d.\n", __LINE__);
 
538
      return;
 
539
    }
 
540
 
 
541
    /* copy the newly-compressed chunk to the target */
 
542
    uprv_memcpy(myCompressed + totalBytesWritten,
 
543
       myCompressionBuffer,
 
544
       sizeof(uint8_t) * (myCTarget - myCompressionBuffer));
 
545
 
 
546
    /*      printf("Compression pass complete.  Compressed %d chars into %d bytes\n",
 
547
        (myCSource - myCSourceAlias), (myCTarget - myCompressionBuffer));*/
 
548
 
 
549
    /* update pointers */
 
550
    totalCharsCompressed = (myCSource - chars);
 
551
 
 
552
    totalBytesWritten += (myCTarget - myCompressionBuffer);
 
553
 
 
554
  } while(status == U_BUFFER_OVERFLOW_ERROR/*totalCharsCompressed < len*/);
 
555
 
 
556
  /* reset */
 
557
  scsu_reset(&myCompressor);
 
558
 
 
559
  /* set up decompression params */
 
560
  myDSource = myCompressed;
 
561
 
 
562
  /* perform the decompression in a loop */
 
563
  do {
 
564
    status = U_ZERO_ERROR;
 
565
    myDTarget = myDecompressionBuffer;
 
566
    myDSourceAlias = myDSource;
 
567
    
 
568
    scsu_decompress(&myCompressor,
 
569
            &myDTarget,
 
570
            myDTarget + DECOMPRESSIONBUFFERSIZE,
 
571
            &myDSource,
 
572
            myCompressed + totalBytesWritten,
 
573
            &status);
 
574
 
 
575
    if(status != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(status)) {
 
576
      log_err("Failing status code at line %d.\n", __LINE__);
 
577
      return;
 
578
    }
 
579
    
 
580
    /* copy the newly-decompressed chunk to the target */
 
581
    uprv_memcpy(myDecompressed + totalCharsWritten,
 
582
       myDecompressionBuffer,
 
583
       sizeof(UChar) * (myDTarget - myDecompressionBuffer));
 
584
 
 
585
    /*    printf("Decompression pass complete.  Decompressed %d bytes into %d chars\n",
 
586
      (myDSource - myDSourceAlias), (myDTarget - myDecompressionBuffer));*/
 
587
    
 
588
    /* update pointers */
 
589
    totalBytesDecompressed = (myDSource - myCompressed);
 
590
 
 
591
    totalCharsWritten += (myDTarget - myDecompressionBuffer);
 
592
  
 
593
  } while(status == U_BUFFER_OVERFLOW_ERROR/*totalBytesDecompressed < totalBytesWritten*/);
 
594
  
 
595
  /* find differences */
 
596
  if( printDiffs(chars, len, myDecompressed, totalCharsWritten) == FALSE) {
 
597
    /*printf("%d chars ===> %d bytes ===> %d chars (%f) (MP)\n", len, 
 
598
       totalBytesWritten, totalCharsWritten,
 
599
       (double)(totalBytesWritten/(totalCharsWritten*2.0)));*/
 
600
  }
 
601
  else {
 
602
    puts("Compressed:");
 
603
    printBytes(myCompressed, totalBytesWritten);
 
604
  }
 
605
 
 
606
  /* clean up */
 
607
  free(myCompressed);
 
608
  free(myDecompressed);
 
609
}
 
610
 
 
611
static const char *fTestCases [] = {
 
612
  "Hello \\9292 \\9192 World!",
 
613
  "Hell\\0429o \\9292 \\9192 W\\00e4rld!",
 
614
  "Hell\\0429o \\9292 \\9292W\\00e4rld!",
 
615
  
 
616
  "\\0648\\06c8", /* catch missing reset*/
 
617
  "\\0648\\06c8",
 
618
  
 
619
  "\\4444\\E001", /* lowest quotable*/
 
620
  "\\4444\\f2FF", /* highest quotable*/
 
621
  "\\4444\\f188\\4444",
 
622
  "\\4444\\f188\\f288",
 
623
  "\\4444\\f188abc\\0429\\f288",
 
624
  "\\9292\\2222",
 
625
  "Hell\\0429\\04230o \\9292 \\9292W\\00e4\\0192rld!",
 
626
  "Hell\\0429o \\9292 \\9292W\\00e4rld!",
 
627
  "Hello World!123456",
 
628
  "Hello W\\0081\\011f\\0082!", /* Latin 1 run*/
 
629
  
 
630
  "abc\\0301\\0302",  /* uses SQn for u301 u302*/
 
631
  "abc\\4411d",      /* uses SQU*/
 
632
  "abc\\4411\\4412d",/* uses SCU*/
 
633
  "abc\\0401\\0402\\047f\\00a5\\0405", /* uses SQn for ua5*/
 
634
  "\\9191\\9191\\3041\\9191\\3041\\3041\\3000", /* SJIS like data*/
 
635
  "\\9292\\2222",
 
636
  "\\9191\\9191\\3041\\9191\\3041\\3041\\3000",
 
637
  "\\9999\\3051\\300c\\9999\\9999\\3060\\9999\\3065\\3065\\3065\\300c",
 
638
  "\\3000\\266a\\30ea\\30f3\\30b4\\53ef\\611b\\3044\\3084\\53ef\\611b\\3044\\3084\\30ea\\30f3\\30b4\\3002",
 
639
  
 
640
  "", /* empty input*/
 
641
  "\\0000", /* smallest BMP character*/
 
642
  "\\FFFF", /* largest BMP character*/
 
643
  
 
644
  "\\d800\\dc00", /* smallest surrogate*/
 
645
  "\\d8ff\\dcff", /* largest surrogate pair*/
 
646
  
 
647
  /* regression tests*/
 
648
  "\\6441\\b413\\a733\\f8fe\\eedb\\587f\\195f\\4899\\f23d\\49fd\\0aac\\5792\\fc22\\fc3c\\fc46\\00aa",
 
649
  "\\00df\\01df\\f000\\dbff\\dfff\\000d\n\\0041\\00df\\0401\\015f\\00df\\01df\\f000\\dbff\\dfff",
 
650
  "\\30f9\\8321\\05e5\\181c\\d72b\\2019\\99c9\\2f2f\\c10c\\82e1\\2c4d\\1ebc\\6013\\66dc\\bbde\\94a5\\4726\\74af\\3083\\55b9\\000c",
 
651
  "\\0041\\00df\\0401\\015f",
 
652
  "\\9066\\2123abc",
 
653
  "\\d266\\43d7\\\\e386\\c9c0\\4a6b\\9222\\901f\\7410\\a63f\\539b\\9596\\482e\\9d47\\cfe4\\7b71\\c280\\f26a\\982f\\862a\\4edd\\f513\\fda6\\869d\\2ee0\\a216\\3ff6\\3c70\\89c0\\9576\\d5ec\\bfda\\6cca\\5bb3\\bcea\\554c\\914e\\fa4a\\ede3\\2990\\d2f5\\2729\\5141\\0f26\\ccd8\\5413\\d196\\bbe2\\51b9\\9b48\\0dc8\\2195\\21a2\\21e9\\00e4\\9d92\\0bc0\\06c5",
 
654
  "\\f95b\\2458\\2468\\0e20\\f51b\\e36e\\bfc1\\0080\\02dd\\f1b5\\0cf3\\6059\\7489",
 
655
  0
 
656
 
 
657
};
 
658
 
 
659
static unsigned long gTotalChars;
 
660
 
 
661
 
 
662
 
 
663
/* Decompress the two segments */
 
664
static UChar*
 
665
segment_test(uint8_t *segment1,
 
666
         int32_t seg1Len,
 
667
         uint8_t *segment2,
 
668
         int32_t seg2Len)
 
669
{
 
670
    UErrorCode status = U_ZERO_ERROR;
 
671
    UnicodeCompressor myDecompressor;
 
672
 
 
673
    const uint8_t *seg1 = segment1;
 
674
    const uint8_t *seg2 = segment2;
 
675
 
 
676
    int32_t charBufferCap = 2*(seg1Len + seg2Len);
 
677
    UChar *charBuffer = (UChar*) malloc(sizeof(UChar) * charBufferCap);
 
678
 
 
679
    UChar *target = charBuffer;
 
680
    int32_t outCount = 0, count1 = 0, count2 = 0;
 
681
 
 
682
 
 
683
    scsu_init(&myDecompressor);
 
684
 
 
685
    scsu_decompress(&myDecompressor, &target, charBuffer + charBufferCap,
 
686
            &seg1, segment1 + seg1Len, &status);
 
687
 
 
688
    count1 = seg1 - segment1;
 
689
 
 
690
    /*    println("Segment 1 (" + segment1.length + " bytes) " +
 
691
      "decompressed into " + count1  + " chars");
 
692
      println("Bytes consumed: " + bytesRead[0]);
 
693
 
 
694
      print("Got chars: ");
 
695
      println(System.out, charBuffer, 0, count1);*/
 
696
 
 
697
    /*s.append(charBuffer, 0, count1);*/
 
698
 
 
699
    scsu_decompress(&myDecompressor, &target,
 
700
            charBuffer + charBufferCap,
 
701
            &seg2, segment2 + seg2Len, &status);
 
702
 
 
703
    count2 = seg2 - segment2;
 
704
 
 
705
    outCount = (target - charBuffer);
 
706
 
 
707
    /*    println("Segment 2 (" + segment2.length + " bytes) " +
 
708
      "decompressed into " + count2  + " chars");
 
709
      println("Bytes consumed: " + bytesRead[0]);
 
710
 
 
711
      print("Got chars: ");
 
712
      println(System.out, charBuffer, count1, count2);*/
 
713
    
 
714
    /*s.append(charBuffer, count1, count2);*/
 
715
    
 
716
    /*print("Result: ");
 
717
      println(System.out, charBuffer, 0, count1 + count2);
 
718
      println("====================");*/
 
719
    
 
720
    charBuffer [ outCount ] = 0x0000;
 
721
    return charBuffer;
 
722
}
 
723
 
 
724
 
 
725
static void
 
726
TestSCSU(void) 
 
727
{
 
728
  UChar *chars = 0;
 
729
  int32_t len = 0;
 
730
  int32_t i;
 
731
 
 
732
  /* multi-segment test data */
 
733
 
 
734
  /* compressed segment breaking on a define window sequence */
 
735
  /*                       B     o     o     t     h     SD1  */
 
736
  uint8_t segment1a [] = { 0x42, 0x6f, 0x6f, 0x74, 0x68, 0x19 };
 
737
  /*                       IDX   ,           S     .          */
 
738
  uint8_t segment1b [] = { 0x01, 0x2c, 0x20, 0x53, 0x2e };
 
739
  /* expected result */
 
740
  UChar result1 [] = { 0x0042, 0x006f, 0x006f, 0x0074, 0x0068, 
 
741
               0x002c, 0x0020, 0x0053, 0x002e, 0x0000 };
 
742
 
 
743
  /* compressed segment breaking on a quote unicode sequence */
 
744
  /*                       B     o     o     t     SQU        */
 
745
  uint8_t segment2a [] = { 0x42, 0x6f, 0x6f, 0x74, 0x0e, 0x00 };
 
746
 
 
747
  /*                       h     ,           S     .          */
 
748
  uint8_t segment2b [] = { 0x68, 0x2c, 0x20, 0x53, 0x2e };
 
749
  /* expected result */
 
750
  UChar result2 [] = { 0x0042, 0x006f, 0x006f, 0x0074, 0x0068, 
 
751
               0x002c, 0x0020, 0x0053, 0x002e, 0x0000 };
 
752
 
 
753
  /* compressed segment breaking on a quote unicode sequence */
 
754
  /*                       SCU   UQU                         */
 
755
  uint8_t segment3a [] = { 0x0f, 0xf0, 0x00 };
 
756
    
 
757
  /*                       B                                 */
 
758
  uint8_t segment3b [] = { 0x42 };
 
759
  /* expected result */
 
760
  UChar result3 [] = { 0x0042, 0x0000 };
 
761
 
 
762
 
 
763
  chars = segment_test(segment1a, 6, segment1b, 5);
 
764
  if(u_strcmp(chars, result1)) {
 
765
    log_err("Failure in multisegment 1\n");
 
766
  }
 
767
  free(chars);
 
768
 
 
769
  chars = segment_test(segment2a, 6, segment2b, 5);
 
770
  if(u_strcmp(chars, result2)) {
 
771
    log_err("Failure in multisegment 2\n");
 
772
  }
 
773
  free(chars);
 
774
 
 
775
  chars = segment_test(segment3a, 3, segment3b, 1);
 
776
  if(u_strcmp(chars, result3)) {
 
777
    log_err("Failure in multisegment 3\n");
 
778
  }
 
779
  free(chars);
 
780
 
 
781
  /* initialize char count */
 
782
  gTotalChars = 0;
 
783
 
 
784
  /* initialize random number generator */
 
785
  srand(time(0));
 
786
  
 
787
  for(i = 0; fTestCases[i] != 0; i++) {
 
788
    
 
789
    chars = unescape(fTestCases[i]);
 
790
    if(!chars) {
 
791
      return; /* memory error */
 
792
    }
 
793
 
 
794
    len = u_strlen(chars);
 
795
 
 
796
    /*printChars2(chars, len);*/
 
797
 
 
798
    myTest(chars, len);
 
799
    myMultipassTest(chars, len);
 
800
 
 
801
    
 
802
    free(chars);
 
803
    gTotalChars += len;
 
804
  }
 
805
 
 
806
  /*puts("==============================");*/
 
807
    i=0;
 
808
  while(i<=1000) {
 
809
    len = (int32_t)(1000 * (double)(rand()/(double)RAND_MAX));
 
810
    if(len == 0) /* 0-length malloc will fail */
 
811
      len = 10;
 
812
    chars = randomChars(len);
 
813
    if(!chars)
 
814
    {
 
815
      log_err("scsutest aborted.\n");
 
816
      return; 
 
817
    }
 
818
    myTest(chars, len);
 
819
    myMultipassTest(chars, len);
 
820
    free(chars);
 
821
    gTotalChars += len;
 
822
    i++;
 
823
  }
 
824
}
 
825
#endif
 
826
 
 
827
void addSCSUTest(TestNode** root);
 
828
 
 
829
void
 
830
addSCSUTest(TestNode** root)
 
831
{
 
832
#ifdef ICU_SCSU_USE_DEPRECATES
 
833
  addTest(root, &TestSCSU, "scsutest/TestSCSU");
 
834
#endif
 
835
}