00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "unicode/utypes.h"
00020 #include "cmemory.h"
00021 #include "ucmp16.h"
00022 #include "ucmp8.h"
00023 #include "unicode/ucnv_err.h"
00024 #include "ucnv_bld.h"
00025 #include "unicode/ucnv.h"
00026 #include "ucnv_cnv.h"
00027 #include "unicode/ustring.h"
00028 #include "cstring.h"
00029
00030
00031
00032 U_CFUNC void T_UConverter_fromUnicode_EBCDIC_STATEFUL(UConverterFromUnicodeArgs * args,
00033 UErrorCode * err);
00034
00035 U_CFUNC void T_UConverter_fromUnicode_EBCDIC_STATEFUL_OFFSETS_LOGIC (UConverterFromUnicodeArgs * args,
00036 UErrorCode * err);
00037
00038 U_CFUNC void T_UConverter_toUnicode_EBCDIC_STATEFUL(UConverterToUnicodeArgs * args,
00039 UErrorCode * err);
00040
00041 U_CFUNC void T_UConverter_toUnicode_EBCDIC_STATEFUL_OFFSETS_LOGIC (UConverterToUnicodeArgs * args,
00042 UErrorCode * err);
00043
00044
00045 U_CFUNC UChar32 T_UConverter_getNextUChar_EBCDIC_STATEFUL (UConverterToUnicodeArgs * args,
00046 UErrorCode * err);
00047
00048
00049
00050 U_CFUNC void
00051 _DBCSLoad(UConverterSharedData *sharedData, const uint8_t *raw, UErrorCode *pErrorCode);
00052
00053 U_CFUNC void
00054 _DBCSUnload(UConverterSharedData *sharedData);
00055
00056
00057
00058
00059
00060 U_CFUNC void T_UConverter_toUnicode_EBCDIC_STATEFUL (UConverterToUnicodeArgs *args,
00061 UErrorCode * err)
00062 {
00063 char *mySource = (char *) args->source;
00064 UChar *myTarget = args->target;
00065 int32_t mySourceIndex = 0;
00066 int32_t myTargetIndex = 0;
00067 int32_t targetLength = args->targetLimit - args->target;
00068 int32_t sourceLength = args->sourceLimit - args->source;
00069 CompactShortArray *myToUnicode = NULL;
00070 UChar targetUniChar = 0x0000;
00071 UChar mySourceChar = 0x0000;
00072 int32_t myMode = args->converter->mode;
00073
00074 myToUnicode = &(args->converter->sharedData->table->dbcs.toUnicode);
00075 while (mySourceIndex < sourceLength)
00076 {
00077 if (myTargetIndex < targetLength)
00078 {
00079
00080 mySourceChar = (unsigned char) (args->source[mySourceIndex++]);
00081 if (mySourceChar == UCNV_SI) myMode = UCNV_SI;
00082 else if (mySourceChar == UCNV_SO) myMode = UCNV_SO;
00083 else if ((myMode == UCNV_SO) &&
00084 (args->converter->toUnicodeStatus == 0x00))
00085 {
00086 args->converter->toUnicodeStatus = (unsigned char) mySourceChar;
00087 }
00088 else
00089 {
00090
00091
00092
00093
00094 if (args->converter->toUnicodeStatus != 0x00)
00095 {
00096 mySourceChar |= (UChar) (args->converter->toUnicodeStatus << 8);
00097 args->converter->toUnicodeStatus = 0x00;
00098 }
00099 else mySourceChar &= 0x00FF;
00100
00101
00102 targetUniChar = (UChar) ucmp16_getu (myToUnicode, mySourceChar);
00103
00104
00105 if (targetUniChar < 0xfffe)
00106 {
00107
00108 args->target[myTargetIndex++] = targetUniChar;
00109 }
00110
00111 else
00112 {
00113 const char* saveSource = args->source;
00114 UChar* saveTarget = args->target;
00115 int32_t *saveOffsets = args->offsets;
00116 UConverterCallbackReason reason;
00117
00118 if (targetUniChar == 0xfffe)
00119 {
00120 reason = UCNV_UNASSIGNED;
00121 *err = U_INVALID_CHAR_FOUND;
00122 }
00123 else
00124 {
00125 reason = UCNV_ILLEGAL;
00126 *err = U_ILLEGAL_CHAR_FOUND;
00127 }
00128
00129 if (mySourceChar > 0xff)
00130 {
00131 args->converter->invalidCharLength = 2;
00132 args->converter->invalidCharBuffer[0] = (char) (mySourceChar >> 8);
00133 args->converter->invalidCharBuffer[1] = (char) mySourceChar;
00134 }
00135 else
00136 {
00137 args->converter->invalidCharLength = 1;
00138 args->converter->invalidCharBuffer[0] = (char) mySourceChar;
00139 }
00140 args->converter->mode = myMode;
00141 args->target += myTargetIndex;
00142 args->source += mySourceIndex;
00143 ToU_CALLBACK_MACRO(args->converter->toUContext,
00144 args,
00145 args->converter->invalidCharBuffer,
00146 args->converter->invalidCharLength,
00147 reason,
00148 err);
00149
00150 myMode = args->converter->mode;
00151 args->source = saveSource;
00152 args->target = saveTarget;
00153 args->offsets = saveOffsets;
00154 myMode = args->converter->mode;
00155 if (U_FAILURE (*err)) break;
00156 args->converter->invalidCharLength = 0;
00157 }
00158 }
00159 }
00160 else
00161 {
00162 *err = U_BUFFER_OVERFLOW_ERROR;
00163 break;
00164 }
00165 }
00166
00167
00168
00169
00170 if (args->converter->toUnicodeStatus
00171 && (mySourceIndex == sourceLength)
00172 && (args->flush == TRUE))
00173 {
00174 if (U_SUCCESS(*err))
00175 {
00176 *err = U_TRUNCATED_CHAR_FOUND;
00177 args->converter->toUnicodeStatus = 0x00;
00178 }
00179 }
00180
00181 args->target += myTargetIndex;
00182 args->source += mySourceIndex;
00183 args->converter->mode = myMode;
00184
00185 return;
00186 }
00187
00188 U_CFUNC void T_UConverter_toUnicode_EBCDIC_STATEFUL_OFFSETS_LOGIC (UConverterToUnicodeArgs * args,
00189 UErrorCode * err)
00190 {
00191 char *mySource = (char *) args->source;
00192 UChar *myTarget = args->target;
00193 int32_t mySourceIndex = 0;
00194 int32_t myTargetIndex = 0;
00195 int32_t targetLength = args->targetLimit - args->target;
00196 int32_t sourceLength = args->sourceLimit - args->source;
00197 CompactShortArray *myToUnicode = NULL;
00198 UChar targetUniChar = 0x0000;
00199 UChar mySourceChar = 0x0000;
00200 int32_t myMode = args->converter->mode;
00201
00202 myToUnicode = &args->converter->sharedData->table->dbcs.toUnicode;
00203
00204 while (mySourceIndex < sourceLength)
00205 {
00206 if (myTargetIndex < targetLength)
00207 {
00208
00209 mySourceChar = (unsigned char) (args->source[mySourceIndex++]);
00210 if (mySourceChar == UCNV_SI) myMode = UCNV_SI;
00211 else if (mySourceChar == UCNV_SO) myMode = UCNV_SO;
00212 else if ((myMode == UCNV_SO) &&
00213 (args->converter->toUnicodeStatus == 0x00))
00214 {
00215 args->converter->toUnicodeStatus = (unsigned char) mySourceChar;
00216 }
00217 else
00218 {
00219
00220
00221
00222
00223 if (args->converter->toUnicodeStatus != 0x00)
00224 {
00225 mySourceChar |= (UChar) (args->converter->toUnicodeStatus << 8);
00226 args->converter->toUnicodeStatus = 0x00;
00227 }
00228 else mySourceChar &= 0x00FF;
00229
00230
00231 targetUniChar = (UChar) ucmp16_getu (myToUnicode, mySourceChar);
00232
00233
00234 if (targetUniChar < 0xfffe)
00235 {
00236
00237 {
00238 if(myMode == UCNV_SO)
00239 args->offsets[myTargetIndex] = mySourceIndex-2;
00240 else
00241 args->offsets[myTargetIndex] = mySourceIndex-1;
00242 }
00243 args->target[myTargetIndex++] = targetUniChar;
00244 }
00245 else
00246 {
00247 int32_t currentOffset = args->offsets[myTargetIndex-1] + 2;
00248 int32_t My_i = myTargetIndex;
00249 const char* saveSource = args->source;
00250 UChar* saveTarget = args->target;
00251 int32_t *saveOffsets = args->offsets;
00252 UConverterCallbackReason reason;
00253
00254 if (targetUniChar == 0xfffe)
00255 {
00256 reason = UCNV_UNASSIGNED;
00257 *err = U_INVALID_CHAR_FOUND;
00258 }
00259 else
00260 {
00261 reason = UCNV_ILLEGAL;
00262 *err = U_ILLEGAL_CHAR_FOUND;
00263 }
00264
00265 if (mySourceChar > 0xFF)
00266 {
00267 args->converter->invalidCharLength = 2;
00268 args->converter->invalidCharBuffer[0] = (char) (mySourceChar >> 8);
00269 args->converter->invalidCharBuffer[1] = (char) mySourceChar;
00270 }
00271 else
00272 {
00273 args->converter->invalidCharLength = 1;
00274 args->converter->invalidCharBuffer[0] = (char) mySourceChar;
00275 }
00276 args->converter->mode = myMode;
00277
00278 args->target = args->target + myTargetIndex;
00279 args->source = args->source + mySourceIndex;
00280 args->offsets = args->offsets?args->offsets+myTargetIndex:0;
00281
00282 ToU_CALLBACK_OFFSETS_LOGIC_MACRO(args->converter->toUContext,
00283 args,
00284 args->source,
00285 1,
00286 reason,
00287 err);
00288
00289 args->source = saveSource;
00290 args->target = saveTarget;
00291 myMode = args->converter->mode;
00292 if (U_FAILURE (*err)) break;
00293 args->converter->invalidCharLength = 0;
00294 myMode = args->converter->mode;
00295 }
00296 }
00297 }
00298 else
00299 {
00300 *err = U_BUFFER_OVERFLOW_ERROR;
00301 break;
00302 }
00303 }
00304
00305
00306
00307
00308 if (args->converter->toUnicodeStatus
00309 && (mySourceIndex == sourceLength)
00310 && (args->flush == TRUE))
00311 {
00312 if (U_SUCCESS(*err))
00313 {
00314 *err = U_TRUNCATED_CHAR_FOUND;
00315 args->converter->toUnicodeStatus = 0x00;
00316 }
00317 }
00318
00319 args->target += myTargetIndex;
00320 args->source += mySourceIndex;
00321 args->converter->mode = myMode;
00322
00323 return;
00324 }
00325
00326 U_CFUNC void T_UConverter_fromUnicode_EBCDIC_STATEFUL (UConverterFromUnicodeArgs * args,
00327 UErrorCode * err)
00328
00329 {
00330 const UChar *mySource = args->source;
00331 unsigned char *myTarget = (unsigned char *) args->target;
00332 int32_t mySourceIndex = 0;
00333 int32_t myTargetIndex = 0;
00334 int32_t targetLength = args->targetLimit - args->target;
00335 int32_t sourceLength = args->sourceLimit - args->source;
00336 CompactShortArray *myFromUnicode = NULL;
00337 UChar targetUniChar = 0x0000;
00338 UChar mySourceChar = 0x0000;
00339 UBool isTargetUCharDBCS = (UBool)args->converter->fromUnicodeStatus;
00340 UBool oldIsTargetUCharDBCS = isTargetUCharDBCS;
00341
00342 myFromUnicode = &args->converter->sharedData->table->dbcs.fromUnicode;
00343
00344 while (mySourceIndex < sourceLength)
00345 {
00346 if (myTargetIndex < targetLength)
00347 {
00348 mySourceChar = (UChar) args->source[mySourceIndex++];
00349 targetUniChar = (UChar) ucmp16_getu (myFromUnicode, mySourceChar);
00350 oldIsTargetUCharDBCS = isTargetUCharDBCS;
00351 isTargetUCharDBCS = (UBool)(targetUniChar>0x00FF);
00352
00353 if (targetUniChar != missingCharMarker)
00354 {
00355 if (oldIsTargetUCharDBCS != isTargetUCharDBCS)
00356 {
00357 if (isTargetUCharDBCS) args->target[myTargetIndex++] = UCNV_SO;
00358 else args->target[myTargetIndex++] = UCNV_SI;
00359
00360
00361 if ((!isTargetUCharDBCS)&&(myTargetIndex+1 >= targetLength))
00362 {
00363 args->converter->charErrorBuffer[args->converter->charErrorBufferLength++] = (char) targetUniChar;
00364 *err = U_BUFFER_OVERFLOW_ERROR;
00365 break;
00366 }
00367 else if (myTargetIndex+1 >= targetLength)
00368 {
00369 args->converter->charErrorBuffer[0] = (char) (targetUniChar >> 8);
00370 args->converter->charErrorBuffer[1] = (char)(targetUniChar & 0x00FF);
00371 args->converter->charErrorBufferLength = 2;
00372 *err = U_BUFFER_OVERFLOW_ERROR;
00373 break;
00374 }
00375
00376 }
00377
00378 if (!isTargetUCharDBCS)
00379 {
00380 args->target[myTargetIndex++] = (char) targetUniChar;
00381 }
00382 else
00383 {
00384 args->target[myTargetIndex++] = (char) (targetUniChar >> 8);
00385 if (myTargetIndex < targetLength)
00386 {
00387 args->target[myTargetIndex++] = (char) targetUniChar;
00388 }
00389 else
00390 {
00391 args->converter->charErrorBuffer[0] = (char) targetUniChar;
00392 args->converter->charErrorBufferLength = 1;
00393 *err = U_BUFFER_OVERFLOW_ERROR;
00394 break;
00395 }
00396 }
00397 }
00398 else
00399 {
00400 const UChar* saveSource = args->source;
00401 char* saveTarget = args->target;
00402 int32_t *saveOffsets = args->offsets;
00403
00404 isTargetUCharDBCS = oldIsTargetUCharDBCS;
00405 *err = U_INVALID_CHAR_FOUND;
00406 args->converter->invalidUCharBuffer[0] = (UChar) mySourceChar;
00407 args->converter->invalidUCharLength = 1;
00408
00409 args->converter->fromUnicodeStatus = (int32_t)isTargetUCharDBCS;
00410 args->target += myTargetIndex;
00411 args->source += mySourceIndex;
00412 FromU_CALLBACK_MACRO(args->converter->fromUContext,
00413 args,
00414 args->converter->invalidUCharBuffer,
00415 1,
00416 (UChar32) mySourceChar,
00417 UCNV_UNASSIGNED,
00418 err);
00419 args->source = saveSource;
00420 args->target = saveTarget;
00421 args->offsets = saveOffsets;
00422 isTargetUCharDBCS = (UBool) args->converter->fromUnicodeStatus;
00423 if (U_FAILURE (*err)) break;
00424 args->converter->invalidUCharLength = 0;
00425 }
00426 }
00427 else
00428 {
00429 *err = U_BUFFER_OVERFLOW_ERROR;
00430 break;
00431 }
00432
00433 }
00434
00435
00436 args->target += myTargetIndex;
00437 args->source += mySourceIndex;
00438
00439 args->converter->fromUnicodeStatus = (int32_t)isTargetUCharDBCS;
00440
00441 return;
00442 }
00443
00444 U_CFUNC void T_UConverter_fromUnicode_EBCDIC_STATEFUL_OFFSETS_LOGIC (UConverterFromUnicodeArgs * args,
00445 UErrorCode * err)
00446
00447 {
00448 const UChar *mySource = args->source;
00449 unsigned char *myTarget = (unsigned char *) args->target;
00450 int32_t mySourceIndex = 0;
00451 int32_t myTargetIndex = 0;
00452 int32_t targetLength = args->targetLimit - args->target;
00453 int32_t sourceLength = args->sourceLimit - args->source;
00454 CompactShortArray *myFromUnicode = NULL;
00455 UChar targetUniChar = 0x0000;
00456 UChar mySourceChar = 0x0000;
00457 UBool isTargetUCharDBCS = (UBool)args->converter->fromUnicodeStatus;
00458 UBool oldIsTargetUCharDBCS = isTargetUCharDBCS;
00459
00460 myFromUnicode = &args->converter->sharedData->table->dbcs.fromUnicode;
00461
00462 while (mySourceIndex < sourceLength)
00463 {
00464 if (myTargetIndex < targetLength)
00465 {
00466 mySourceChar = (UChar) args->source[mySourceIndex++];
00467 targetUniChar = (UChar) ucmp16_getu (myFromUnicode, mySourceChar);
00468 oldIsTargetUCharDBCS = isTargetUCharDBCS;
00469 isTargetUCharDBCS =(UBool) (targetUniChar>0x00FF);
00470
00471 if (targetUniChar != missingCharMarker)
00472 {
00473 if (oldIsTargetUCharDBCS != isTargetUCharDBCS)
00474 {
00475 args->offsets[myTargetIndex] = mySourceIndex-1;
00476 if (isTargetUCharDBCS) args->target[myTargetIndex++] = UCNV_SO;
00477 else args->target[myTargetIndex++] = UCNV_SI;
00478
00479
00480 if ((!isTargetUCharDBCS)&&(myTargetIndex+1 >= targetLength))
00481 {
00482 args->converter->charErrorBuffer[0] = (char) targetUniChar;
00483 args->converter->charErrorBufferLength = 1;
00484 *err = U_BUFFER_OVERFLOW_ERROR;
00485 break;
00486 }
00487 else if (myTargetIndex+1 >= targetLength)
00488 {
00489 args->converter->charErrorBuffer[0] = (char) (targetUniChar >> 8);
00490 args->converter->charErrorBuffer[1] = (char) (targetUniChar & 0x00FF);
00491 args->converter->charErrorBufferLength = 2;
00492 *err = U_BUFFER_OVERFLOW_ERROR;
00493 break;
00494 }
00495 }
00496
00497 if (!isTargetUCharDBCS)
00498 {
00499 args->offsets[myTargetIndex] = mySourceIndex-1;
00500 args->target[myTargetIndex++] = (char) targetUniChar;
00501 }
00502 else
00503 {
00504 args->offsets[myTargetIndex] = mySourceIndex-1;
00505 args->target[myTargetIndex++] = (char) (targetUniChar >> 8);
00506 if (myTargetIndex < targetLength)
00507 {
00508 args->offsets[myTargetIndex] = mySourceIndex-1;
00509 args->target[myTargetIndex++] = (char) targetUniChar;
00510 }
00511 else
00512 {
00513 args->converter->charErrorBuffer[0] = (char) targetUniChar;
00514 args->converter->charErrorBufferLength = 1;
00515 *err = U_BUFFER_OVERFLOW_ERROR;
00516 break;
00517 }
00518 }
00519 }
00520 else
00521 {
00522 int32_t currentOffset = args->offsets[myTargetIndex-1]+1;
00523 char * saveTarget = args->target;
00524 const UChar* saveSource = args->source;
00525 int32_t *saveOffsets = args->offsets;
00526 *err = U_INVALID_CHAR_FOUND;
00527 args->converter->invalidUCharBuffer[0] = (UChar) mySourceChar;
00528 args->converter->invalidUCharLength = 1;
00529
00530
00531 args->converter->fromUnicodeStatus = (int32_t)isTargetUCharDBCS;
00532 args->target += myTargetIndex;
00533 args->source += mySourceIndex;
00534 args->offsets = args->offsets?args->offsets+myTargetIndex:0;
00535 FromU_CALLBACK_OFFSETS_LOGIC_MACRO(args->converter->fromUContext,
00536 args,
00537 args->converter->invalidUCharBuffer,
00538 1,
00539 (UChar32)mySourceChar,
00540 UCNV_UNASSIGNED,
00541 err);
00542 isTargetUCharDBCS = (UBool)(args->converter->fromUnicodeStatus);
00543 args->source = saveSource;
00544 args->target = saveTarget;
00545 args->offsets = saveOffsets;
00546 isTargetUCharDBCS = (UBool)(args->converter->fromUnicodeStatus);
00547 if (U_FAILURE (*err)) break;
00548 args->converter->invalidUCharLength = 0;
00549 }
00550 }
00551 else
00552 {
00553 *err = U_BUFFER_OVERFLOW_ERROR;
00554 break;
00555 }
00556
00557 }
00558
00559
00560 args->target += myTargetIndex;
00561 args->source += mySourceIndex;
00562
00563 args->converter->fromUnicodeStatus = (int32_t)isTargetUCharDBCS;
00564
00565 return;
00566 }
00567
00568 U_CFUNC UChar32 T_UConverter_getNextUChar_EBCDIC_STATEFUL(UConverterToUnicodeArgs* args,
00569 UErrorCode* err)
00570 {
00571 UChar myUChar;
00572 char const *sourceInitial = args->source;
00573
00574
00575
00576 if (args->source >= args->sourceLimit)
00577 {
00578 *err = U_INDEX_OUTOFBOUNDS_ERROR;
00579 return 0xffff;
00580 }
00581
00582
00583
00584 while ((*(args->source) == UCNV_SI) || (*(args->source) == UCNV_SO))
00585 {
00586 args->converter->mode = *(args->source);
00587 args->source++;
00588 sourceInitial = args->source;
00589
00590
00591 if (args->source >= args->sourceLimit)
00592 {
00593 *err = U_INDEX_OUTOFBOUNDS_ERROR;
00594 return 0xffff;
00595 }
00596 }
00597
00598 if (args->converter->mode == UCNV_SI)
00599 {
00600 myUChar = ucmp16_getu( (&(args->converter->sharedData->table->dbcs.toUnicode)),
00601 ((UChar)(uint8_t)(*(args->source))));
00602 args->source++;
00603 }
00604 else
00605 {
00606
00607
00608 if ((args->source + 2) > args->sourceLimit)
00609 {
00610 *err = U_TRUNCATED_CHAR_FOUND;
00611 return 0xffff;
00612 }
00613
00614 myUChar = ucmp16_getu( (&(args->converter->sharedData->table->dbcs.toUnicode)),
00615 (((UChar)(uint8_t)((*(args->source))) << 8) |((uint8_t)*(args->source+1))) );
00616
00617 args->source += 2;
00618 }
00619
00620 if (myUChar < 0xfffe) return myUChar;
00621 else
00622 {
00623
00624 UChar* myUCharPtr = &myUChar;
00625 UConverterCallbackReason reason;
00626
00627 if (myUChar == 0xfffe)
00628 {
00629 reason = UCNV_UNASSIGNED;
00630 *err = U_INVALID_CHAR_FOUND;
00631 }
00632 else
00633 {
00634 reason = UCNV_ILLEGAL;
00635 *err = U_ILLEGAL_CHAR_FOUND;
00636 }
00637
00638
00639
00640 args->target = myUCharPtr;
00641 args->targetLimit = myUCharPtr + 1;
00642
00643 args->converter->fromCharErrorBehaviour(args->converter->toUContext,
00644 args,
00645 sourceInitial,
00646 args->source - sourceInitial,
00647 reason,
00648 err);
00649
00650
00651 if (*err == U_BUFFER_OVERFLOW_ERROR) *err = U_ZERO_ERROR;
00652
00653 return myUChar;
00654 }
00655 }
00656
00657 static const UConverterImpl _EBCDICStatefulImpl={
00658 UCNV_EBCDIC_STATEFUL,
00659
00660 _DBCSLoad,
00661 _DBCSUnload,
00662
00663 NULL,
00664 NULL,
00665 NULL,
00666
00667 T_UConverter_toUnicode_EBCDIC_STATEFUL,
00668 T_UConverter_toUnicode_EBCDIC_STATEFUL_OFFSETS_LOGIC,
00669 T_UConverter_fromUnicode_EBCDIC_STATEFUL,
00670 T_UConverter_fromUnicode_EBCDIC_STATEFUL_OFFSETS_LOGIC,
00671 T_UConverter_getNextUChar_EBCDIC_STATEFUL,
00672
00673 NULL,
00674 NULL
00675 };
00676
00677
00678
00679
00680
00681 const UConverterSharedData _EBCDICStatefulData={
00682 sizeof(UConverterSharedData), 1,
00683 NULL, NULL, NULL, FALSE, &_EBCDICStatefulImpl,
00684 0
00685 };