home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / Programming / ICU / src / icu / source / common / ucnv_cnv.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-10-19  |  90.8 KB  |  3,439 lines

  1. /*
  2.    ********************************************************************************
  3.    *                                                                              *
  4.    * COPYRIGHT:                                                                   *
  5.    *   (C) Copyright International Business Machines Corporation, 1998            *
  6.    *   Licensed Material - Program-Property of IBM - All Rights Reserved.         *
  7.    *   US Government Users Restricted Rights - Use, duplication, or disclosure    *
  8.    *   restricted by GSA ADP Schedule Contract with IBM Corp.                     *
  9.    *                                                                              *
  10.    ********************************************************************************
  11.    *
  12.    *
  13.    *   uconv_cnv.c:
  14.    *   Implements all the low level conversion functions
  15.    *   T_UnicodeConverter_{to,from}Unicode_$ConversionType
  16.    *
  17.  */
  18.  
  19. #include "utypes.h"
  20. #include "uhash.h"
  21. #include "ucmp16.h"
  22. #include "ucmp8.h"
  23. #include "ucnv_bld.h"
  24. #include "ucnv_err.h"
  25. #include "ucnv_cnv.h"
  26. #include "ucnv.h"
  27. #include "cmemory.h"
  28.  
  29. #ifdef Debug
  30. #include <stdio.h>
  31. #endif
  32.  
  33.  
  34.  
  35.  
  36.  
  37. void flushInternalUnicodeBuffer (UConverter * _this,
  38.                  UChar * myTarget,
  39.                  int32_t * myTargetIndex,
  40.                  int32_t targetLength,
  41.                  int32_t** offsets,
  42.                  UErrorCode * err);
  43.  
  44. void flushInternalCharBuffer (UConverter * _this,
  45.                   char *myTarget,
  46.                   int32_t * myTargetIndex,
  47.                   int32_t targetLength,
  48.                   int32_t** offsets,
  49.                   UErrorCode * err);
  50.  
  51. #define FromU_CALLBACK_MACRO(_this, myTarget, myTargetIndex, targetLimit, mySource, mySourceIndex, sourceLimit, offsets, flush, err) \
  52.           if (_this->fromUCharErrorBehaviour == (UConverterFromUCallback) UCNV_FROM_U_CALLBACK_STOP) break;\
  53.           else \
  54.         { \
  55.           char *myTargetCopy = myTarget + myTargetIndex; \
  56.           const UChar *mySourceCopy = mySource + mySourceIndex; \
  57.           /*copies current values for the ErrorFunctor to update */ \
  58.           /*Calls the ErrorFunctor */ \
  59.           _this->fromUCharErrorBehaviour (_this, \
  60.                           (char **) &myTargetCopy, \
  61.                           targetLimit, \
  62.                           (const UChar **) &mySourceCopy, \
  63.                           sourceLimit, \
  64.                           offsets, \
  65.                           flush, \
  66.                           err); \
  67.           /*Update the local Indexes so that the conversion can restart at the right points */ \
  68.           mySourceIndex = (mySourceCopy - mySource) ; \
  69.           myTargetIndex = (char*)myTargetCopy - (char*)myTarget ; \
  70.                 }
  71.  
  72. #define ToU_CALLBACK_MACRO(_this, myTarget, myTargetIndex, targetLimit, mySource, mySourceIndex, sourceLimit, offsets, flush, err) \
  73.               if (_this->fromCharErrorBehaviour == (UConverterToUCallback) UCNV_TO_U_CALLBACK_STOP) break; \
  74.               else \
  75.                 { \
  76.                   UChar *myTargetCopy = myTarget + myTargetIndex; \
  77.                   const char *mySourceCopy = mySource + mySourceIndex; \
  78.                   /*Calls the ErrorFunctor */ \
  79.                   _this->fromCharErrorBehaviour (_this, \
  80.                                                  &myTargetCopy, \
  81.                                                  targetLimit, \
  82.                                               (const char **) &mySourceCopy, \
  83.                                                  sourceLimit, \
  84.                                                  offsets, \
  85.                                                  flush, \
  86.                                                  err); \
  87.                   /*Update the local Indexes so that the conversion can restart at the right points */ \
  88.                   mySourceIndex = ((char*)mySourceCopy - (char*)mySource); \
  89.                   myTargetIndex = (myTargetCopy - myTarget); \
  90.                 }
  91.  
  92. #define FromU_CALLBACK_OFFSETS_LOGIC_MACRO(_this, myTarget, myTargetIndex, targetLimit, mySource, mySourceIndex, sourceLimit, offsets, flush, err) \
  93.           if (_this->fromUCharErrorBehaviour == (UConverterFromUCallback) UCNV_FROM_U_CALLBACK_STOP) break;\
  94.           else \
  95.         { \
  96.           char *myTargetCopy = myTarget + myTargetIndex; \
  97.           const UChar *mySourceCopy = mySource + mySourceIndex; \
  98.          int32_t My_i = myTargetIndex; \
  99.           /*copies current values for the ErrorFunctor to update */ \
  100.           /*Calls the ErrorFunctor */ \
  101.           _this->fromUCharErrorBehaviour (_this, \
  102.                           (char **) &myTargetCopy, \
  103.                           targetLimit, \
  104.                           (const UChar **) &mySourceCopy, \
  105.                           sourceLimit, \
  106.                           offsets + myTargetIndex, \
  107.                           flush, \
  108.                           err); \
  109.           /*Update the local Indexes so that the conversion can restart at the right points */ \
  110.            mySourceIndex = mySourceCopy - mySource ; \
  111.           myTargetIndex = (char*)myTargetCopy - (char*)myTarget ; \
  112.           for (;My_i < myTargetIndex;My_i++) offsets[My_i] += currentOffset  ;    \
  113.         }
  114.  
  115.  
  116.  
  117. #define ToU_CALLBACK_OFFSETS_LOGIC_MACRO(_this, myTarget, myTargetIndex, targetLimit, mySource, mySourceIndex, sourceLimit, offsets, flush, err) \
  118.               if (_this->fromCharErrorBehaviour == (UConverterToUCallback) UCNV_TO_U_CALLBACK_STOP) break; \
  119.               else \
  120.                 { \
  121.                   UChar *myTargetCopy = myTarget + myTargetIndex; \
  122.                   const char *mySourceCopy = mySource + mySourceIndex; \
  123.                   int32_t My_i = myTargetIndex; \
  124.                   _this->fromCharErrorBehaviour (_this, \
  125.                                                  &myTargetCopy, \
  126.                                                  targetLimit, \
  127.                                               (const char **) &mySourceCopy, \
  128.                                                  sourceLimit, \
  129.                                                  offsets + myTargetIndex, \
  130.                                                  flush, \
  131.                                                  err); \
  132.                   /*Update the local Indexes so that the conversion can restart at the right points */ \
  133.                   mySourceIndex = (char *)mySourceCopy - (char*)mySource; \
  134.           myTargetIndex = ((UChar*)myTargetCopy - (UChar*)myTarget);  \
  135.           for (;My_i < myTargetIndex;My_i++) {offsets[My_i] += currentOffset  ;   } \
  136.                 }
  137.  
  138.                  
  139.  
  140. /* UTF-8 Conversion DATA
  141.  *   for more information see Unicode Strandard 2.0 , Transformation Formats Appendix A-9
  142.  */
  143. const uint32_t kReplacementCharacter = 0x0000FFFD;
  144. const uint32_t kMaximumUCS2 = 0x0000FFFF;
  145. const uint32_t kMaximumUTF16 = 0x0010FFFF;
  146. const uint32_t kMaximumUCS4 = 0x7FFFFFFF;
  147. const int8_t halfShift = 10;
  148. const uint32_t halfBase = 0x0010000;
  149. const uint32_t halfMask = 0x3FF;
  150. const uint32_t kSurrogateHighStart = 0xD800;
  151. const uint32_t kSurrogateHighEnd = 0xDBFF;
  152. const uint32_t kSurrogateLowStart = 0xDC00;
  153. const uint32_t kSurrogateLowEnd = 0xDFFF;
  154.  
  155. const uint32_t offsetsFromUTF8[7] = {0,
  156.   (uint32_t) 0x00000000, (uint32_t) 0x00003080, (uint32_t) 0x000E2080,
  157.   (uint32_t) 0x03C82080, (uint32_t) 0xFA082080, (uint32_t) 0x82082080
  158. };
  159.  
  160. #define ESC_2022 0x1B /*ESC*/
  161. typedef enum 
  162. {
  163.   INVALID_2022 = -1, /*Doesn't correspond to a valid iso 2022 escape sequence*/
  164.   VALID_NON_TERMINAL_2022 = 0, /*so far corresponds to a valid iso 2022 escape sequence*/
  165.   VALID_TERMINAL_2022 = 1, /*corresponds to a valid iso 2022 escape sequence*/
  166.   VALID_MAYBE_TERMINAL_2022 = 2 /*so far matches one iso 2022 escape sequence, but by adding more characters might match another escape sequence*/
  167. } UCNV_TableStates_2022;
  168.  
  169. /*Below are the 3 arrays depicting a state transition table*/
  170. int8_t normalize_esq_chars_2022[256] = {
  171.          0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
  172.         ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
  173.         ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,1      ,0      ,0
  174.         ,0      ,0      ,0      ,0      ,0      ,0      ,4      ,7      ,0      ,0
  175.         ,2      ,0      ,0      ,0      ,0      ,3      ,0      ,6      ,0      ,0
  176.         ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
  177.         ,0      ,0      ,0      ,0      ,5      ,8      ,9      ,10     ,11     ,12
  178.         ,13     ,14     ,15     ,16     ,17     ,18     ,19     ,20     ,0      ,0
  179.         ,0      ,0      ,21     ,0      ,0      ,0      ,0      ,0      ,0      ,0
  180.         ,22     ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
  181.         ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
  182.         ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
  183.         ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
  184.         ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
  185.         ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
  186.         ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
  187.         ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
  188.         ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
  189.         ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
  190.         ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
  191.         ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
  192.         ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
  193.         ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
  194.         ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
  195.         ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
  196.         ,0      ,0      ,0      ,0      ,0      ,0};
  197. #define MAX_STATES_2022 54
  198. int32_t escSeqStateTable_Key_2022[MAX_STATES_2022] = {
  199.          1      ,34     ,36     ,39     ,1093   ,1096   ,1097   ,1098   ,1099   ,1100
  200.         ,1101   ,1102   ,1103   ,1104   ,1105   ,1106   ,1109   ,1154   ,1157   ,1160
  201.         ,1161   ,1254   ,1257   ,35105  ,36933  ,36936  ,36937  ,36938  ,36939  ,36940
  202.         ,36942  ,36943  ,36944  ,36945  ,36946  ,36947  ,36948  ,40133  ,40136  ,40138
  203.         ,40139  ,40140  ,40141  ,1123363        ,35947624       ,35947625       ,35947626       ,35947627       ,35947629       ,35947630
  204.         ,35947631       ,35947635       ,35947636       ,35947638};
  205.  
  206. const char* escSeqStateTable_Result_2022[MAX_STATES_2022] = {
  207.          NULL   ,NULL   ,NULL   ,NULL    ,"latin1"    ,"latin1"    ,"latin1"    ,"ibm-865"    ,"ibm-865"    ,"ibm-865"
  208.     ,"ibm-865"    ,"ibm-865"    ,"ibm-865"    ,"ibm-895"    ,"ibm-943"    ,"latin1"    ,"latin1"        ,NULL    ,"ibm-955"    ,"ibm-367"
  209.     ,"ibm-952"  ,NULL    ,"UTF8"        ,NULL    ,"ibm-955"    ,"bm-367"    ,"ibm-952"    ,"ibm-949"    ,"ibm-953"    ,"ibm-1383"
  210.     ,"ibm-952"    ,"ibm-964"    ,"ibm-964"    ,"ibm-964"    ,"ibm-964"    ,"ibm-964"    ,"ibm-964"    ,"UTF16"    ,"UTF16"    ,"UTF16"
  211.     ,"UTF16"    ,"UTF16"    ,"UTF16"    ,NULL    ,"latin1"    ,"ibm-912"    ,"ibm-913"    ,"ibm-914"    ,"ibm-813"    ,"ibm-1089"
  212.     ,"ibm-920"    ,"ibm-915"    ,"ibm-915"    ,"latin1"};
  213.  
  214. UCNV_TableStates_2022 escSeqStateTable_Value_2022[MAX_STATES_2022] = {
  215.          VALID_NON_TERMINAL_2022        ,VALID_NON_TERMINAL_2022        ,VALID_NON_TERMINAL_2022        ,VALID_NON_TERMINAL_2022        ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022    ,VALID_MAYBE_TERMINAL_2022      ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022
  216.         ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022    ,VALID_NON_TERMINAL_2022        ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022
  217.         ,VALID_TERMINAL_2022    ,VALID_NON_TERMINAL_2022        ,VALID_TERMINAL_2022    ,VALID_NON_TERMINAL_2022        ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022
  218.         ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022
  219.         ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022    ,VALID_NON_TERMINAL_2022        ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022
  220.         ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022    ,VALID_TERMINAL_2022};
  221.  
  222. /*for 2022 looks ahead in the stream
  223.  *to determine the longest possible convertible
  224.  *data stream*/
  225. static const char* getEndOfBuffer_2022(const char* source,
  226.                        const char* sourceLimit,
  227.                        bool_t flush); 
  228. /*runs through a state machine to determine the escape sequence - codepage correspondance
  229.  *changes the pointer pointed to be _this->extraInfo*/
  230. static  void changeState_2022(UConverter* _this,
  231.                  const char** source, 
  232.                  const char* sourceLimit,
  233.                  bool_t flush,
  234.                  UErrorCode* err); 
  235.  
  236. UCNV_TableStates_2022 getKey_2022(char source,
  237.                   int32_t* key,
  238.                   int32_t* offset);
  239.  
  240. /* END OF UTF-8 Conversion DATA */
  241.  
  242. const int8_t bytesFromUTF8[256] = {
  243.   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  244.   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  245.   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  246.   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  247.   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  248.   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  249.   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  250.   3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0
  251. };
  252.  
  253. const unsigned char firstByteMark[7] = {0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC};
  254. #define missingCharMarker 0xFFFF
  255. #define missingUCharMarker 0xFFFD
  256.  
  257.  
  258.  
  259. void T_UConverter_toUnicode_SBCS (UConverter * _this,
  260.                   UChar ** target,
  261.                   const UChar * targetLimit,
  262.                   const char **source,
  263.                   const char *sourceLimit,
  264.                   int32_t *offsets,
  265.                   bool_t flush,
  266.                   UErrorCode * err)
  267. {
  268.   char *mySource = (char *) *source;
  269.   UChar *myTarget = *target;
  270.   int32_t mySourceIndex = 0;
  271.   int32_t myTargetIndex = 0;
  272.   int32_t targetLength = targetLimit - myTarget;
  273.   int32_t sourceLength = sourceLimit - (char *) mySource;
  274.   UChar *myToUnicode = NULL;
  275.   UChar targetUniChar = 0x0000;
  276.   
  277.   myToUnicode = _this->sharedData->table->sbcs.toUnicode;
  278.  
  279.   while (mySourceIndex < sourceLength)
  280.     {
  281.  
  282.       /*writing the UniChar to the output stream */
  283.       if (myTargetIndex < targetLength)
  284.     {
  285.       /*gets the corresponding UniChar */
  286.       targetUniChar = myToUnicode[(unsigned char) mySource[mySourceIndex++]];
  287.  
  288.       if (targetUniChar != missingUCharMarker)
  289.         {
  290.           /* writes the UniChar to the output stream */
  291.           myTarget[myTargetIndex++] = targetUniChar;
  292.         }
  293.       else
  294.         {
  295.           *err = U_INVALID_CHAR_FOUND;
  296.           _this->invalidCharBuffer[0] = (char) mySource[mySourceIndex - 1];
  297.           _this->invalidCharLength = 1;
  298.  
  299.           ToU_CALLBACK_MACRO(_this,
  300.                  myTarget,
  301.                  myTargetIndex, 
  302.                  targetLimit,
  303.                  mySource, 
  304.                  mySourceIndex,
  305.                  sourceLimit,
  306.                  offsets,
  307.                  flush,
  308.                  err);
  309.           
  310.           if (U_FAILURE (*err)) break;
  311.           _this->invalidCharLength = 0;
  312.         }
  313.     }
  314.       else
  315.     {
  316.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  317.       break;
  318.     }
  319.     }
  320.   
  321.   *target += myTargetIndex;
  322.   *source += mySourceIndex;
  323.  
  324.   return;
  325. }
  326.  
  327.  
  328. void   T_UConverter_toUnicode_DBCS (UConverter * _this,
  329.                     UChar ** target,
  330.                     const UChar * targetLimit,
  331.                     const char **source,
  332.                     const char *sourceLimit,
  333.                     int32_t *offsets,
  334.                     bool_t flush,
  335.                     UErrorCode * err)
  336. {
  337.   const char *mySource = ( char *) *source;
  338.   UChar *myTarget = *target;
  339.   int32_t mySourceIndex = 0;
  340.   int32_t myTargetIndex = 0;
  341.   int32_t targetLength = targetLimit - myTarget;
  342.   int32_t sourceLength = sourceLimit - (char *) mySource;
  343.   CompactShortArray *myToUnicode = NULL;
  344.   UChar targetUniChar = 0x0000;
  345.   UChar mySourceChar = 0x0000;
  346.  
  347.   myToUnicode = _this->sharedData->table->dbcs.toUnicode;
  348.  
  349.   while (mySourceIndex < sourceLength)
  350.     {
  351.       if (myTargetIndex < targetLength)
  352.     {
  353.       /*gets the corresponding UniChar */
  354.       mySourceChar = (unsigned char) mySource[mySourceIndex++];
  355.  
  356.       /*We have no internal state, we should */
  357.       if (_this->toUnicodeStatus == 0x00)
  358.         {
  359.           _this->toUnicodeStatus = (unsigned char) mySourceChar;
  360.         }
  361.       else
  362.         {
  363.           if (_this->toUnicodeStatus != 0x00)
  364.         {
  365.           mySourceChar = (UChar) ((_this->toUnicodeStatus << 8) | (mySourceChar & 0x00FF));
  366.           _this->toUnicodeStatus = 0x00;
  367.         }
  368.  
  369.           targetUniChar = (UChar) ucmp16_getu (myToUnicode, mySourceChar);
  370.  
  371.           /*writing the UniChar to the output stream */
  372.           if (targetUniChar != missingUCharMarker)
  373.         {
  374.           /*writes the UniChar to the output stream */
  375.           myTarget[myTargetIndex++] = targetUniChar;
  376.         }
  377.           else
  378.         {
  379.           *err = U_INVALID_CHAR_FOUND;
  380.           _this->invalidCharBuffer[0] = (char) (mySourceChar >> 8);
  381.           _this->invalidCharBuffer[1] = (char) mySourceChar;
  382.           _this->invalidCharLength = 2;
  383.           
  384.           ToU_CALLBACK_MACRO(_this,
  385.                      myTarget,
  386.                      myTargetIndex, 
  387.                      targetLimit,
  388.                      mySource, 
  389.                      mySourceIndex,
  390.                      sourceLimit,
  391.                      offsets,
  392.                      flush,
  393.                      err);
  394.  
  395.           if (U_FAILURE (*err))   break;
  396.           _this->invalidCharLength = 0;
  397.         }
  398.         }
  399.     }
  400.       else
  401.     {
  402.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  403.       break;
  404.     }
  405.     }
  406.  
  407.   /*If at the end of conversion we are still carrying state information
  408.    *flush is TRUE, we can deduce that the input stream is truncated
  409.    */
  410.   if ((flush == TRUE)
  411.       && (mySourceIndex == sourceLength)
  412.       && (_this->toUnicodeStatus != 0x00))
  413.     {
  414.        
  415.       if (U_SUCCESS(*err)) 
  416.     {
  417.       *err = U_TRUNCATED_CHAR_FOUND;
  418.       _this->toUnicodeStatus = 0x00;
  419.     }
  420.     }
  421.  
  422.   *target += myTargetIndex;
  423.   *source += mySourceIndex;
  424.  
  425.   return;
  426. }
  427.  
  428.  
  429.  
  430. void  T_UConverter_toUnicode_LATIN_1 (UConverter * _this,
  431.                       UChar ** target,
  432.                       const UChar * targetLimit,
  433.                       const char **source,
  434.                       const char *sourceLimit,
  435.                       int32_t *offsets,
  436.                       bool_t flush,
  437.                       UErrorCode * err)
  438. {
  439.   unsigned char *mySource = (unsigned char *) *source;
  440.   UChar *myTarget = *target;
  441.   int32_t sourceLength = sourceLimit - (char *) mySource;
  442.   int32_t readLen = 0;
  443.   int32_t i = 0;
  444.  
  445.   /*Since there is no risk of encountering illegal Chars
  446.    *we need to pad our latin1 chars to create Unicode codepoints
  447.    *we need to go as far a min(targetLen, sourceLen)
  448.    *in case we don't have enough buffer space
  449.    *we set the error flag accordingly
  450.    */
  451.   if ((targetLimit - *target) < sourceLength)
  452.     {
  453.       readLen = targetLimit - *target;
  454.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  455.     }
  456.   else
  457.     {
  458.       readLen = sourceLimit - (char *) mySource;
  459.     }
  460.  
  461.   for (i = 0; i < readLen; i++) myTarget[i] = (UChar) mySource[i];
  462.  
  463.   *target += i;
  464.   *source += i;
  465.   return;
  466. }
  467.  
  468. void   T_UConverter_fromUnicode_LATIN_1 (UConverter * _this,
  469.                      char **target,
  470.                      const char *targetLimit,
  471.                      const UChar ** source,
  472.                      const UChar * sourceLimit,
  473.                      int32_t *offsets,
  474.                      bool_t flush,
  475.                      UErrorCode * err)
  476. {
  477.   const UChar *mySource = *source;
  478.   unsigned char *myTarget = (unsigned char *) *target;
  479.   int32_t mySourceIndex = 0;
  480.   int32_t myTargetIndex = 0;
  481.   int32_t targetLength = targetLimit - (char *) myTarget;
  482.   int32_t sourceLength = sourceLimit - mySource;
  483.  
  484.   /*writing the char to the output stream */
  485.   while (mySourceIndex < sourceLength)
  486.     {
  487.  
  488.       if (myTargetIndex < targetLength)
  489.     {
  490.       if (mySource[mySourceIndex] < 0x0100)
  491.         {
  492.           /*writes the char to the output stream */
  493.           myTarget[myTargetIndex++] = (char) mySource[mySourceIndex++];
  494.         }
  495.       else
  496.         {
  497.           *err = U_INVALID_CHAR_FOUND;
  498.           _this->invalidUCharBuffer[0] = (UChar) mySource[mySourceIndex++];
  499.           _this->invalidUCharLength = 1;
  500.  
  501. /* Needed explicit cast for myTarget on MVS to make compiler happy - JJD */
  502.           FromU_CALLBACK_MACRO(_this,
  503.                    (char *)myTarget, 
  504.                    myTargetIndex,
  505.                    targetLimit, 
  506.                    mySource,
  507.                    mySourceIndex, 
  508.                    sourceLimit,
  509.                    offsets, 
  510.                    flush, 
  511.                    err);
  512.  
  513.           if (U_FAILURE (*err)) break;
  514.           _this->invalidUCharLength = 0;
  515.         }
  516.     }
  517.       else
  518.     {
  519.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  520.       break;
  521.     }
  522.     }
  523.  
  524.   *target += myTargetIndex;
  525.   *source += mySourceIndex;;
  526.  
  527.   return;
  528. }
  529.  
  530.  
  531. void T_UConverter_fromUnicode_SBCS (UConverter * _this,
  532.                  char **target,
  533.                  const char *targetLimit,
  534.                  const UChar ** source,
  535.                  const UChar * sourceLimit,
  536.                  int32_t *offsets,
  537.                  bool_t flush,
  538.                  UErrorCode * err)
  539. {
  540.   const UChar *mySource = *source;
  541.   unsigned char *myTarget = (unsigned char *) *target;
  542.   int32_t mySourceIndex = 0;
  543.   int32_t myTargetIndex = 0;
  544.   int32_t targetLength = targetLimit - (char *) myTarget;
  545.   int32_t sourceLength = sourceLimit - mySource;
  546.   CompactByteArray *myFromUnicode;
  547.   unsigned char targetChar = 0x00;
  548.  
  549.   myFromUnicode = _this->sharedData->table->sbcs.fromUnicode;
  550.  
  551.   /*writing the char to the output stream */
  552.   while (mySourceIndex < sourceLength)
  553.     {
  554.       targetChar = ucmp8_getu (myFromUnicode, mySource[mySourceIndex]);
  555.  
  556.       if (myTargetIndex < targetLength)
  557.     {
  558.       mySourceIndex++;
  559.       if (targetChar != 0 || !mySource[mySourceIndex - 1])
  560.         {
  561.           /*writes the char to the output stream */
  562.           myTarget[myTargetIndex++] = targetChar;
  563.         }
  564.       else
  565.         {
  566.  
  567.           *err = U_INVALID_CHAR_FOUND;
  568.           _this->invalidUCharBuffer[0] = (UChar)mySource[mySourceIndex - 1];
  569.           _this->invalidUCharLength = 1;
  570.  
  571. /* Needed explicit cast for myTarget on MVS to make compiler happy - JJD */
  572.           FromU_CALLBACK_MACRO(_this,
  573.                    (char *)myTarget, 
  574.                    myTargetIndex,
  575.                    targetLimit, 
  576.                    mySource,
  577.                    mySourceIndex, 
  578.                    sourceLimit,
  579.                    offsets, 
  580.                    flush, 
  581.                    err);
  582.           if (U_FAILURE (*err))
  583.         {
  584.           break;
  585.         }
  586.           _this->invalidUCharLength = 0;
  587.         }
  588.     }
  589.       else
  590.     {
  591.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  592.       break;
  593.     }
  594.  
  595.     }
  596.  
  597.   *target += myTargetIndex;
  598.   *source += mySourceIndex;
  599.  
  600.  
  601.   return;
  602. }
  603.  
  604. void T_UConverter_toUnicode_EBCDIC_STATEFUL (UConverter * _this,
  605.                          UChar ** target,
  606.                          const UChar * targetLimit,
  607.                          const char **source,
  608.                          const char *sourceLimit,
  609.                          int32_t *offsets,
  610.                          bool_t flush,
  611.                          UErrorCode * err)
  612. {
  613.   const char *mySource = *source;
  614.   UChar *myTarget = *target;
  615.   int32_t mySourceIndex = 0;
  616.   int32_t myTargetIndex = 0;
  617.   int32_t targetLength = targetLimit - myTarget;
  618.   int32_t sourceLength = sourceLimit - mySource;
  619.   CompactShortArray *myToUnicode = NULL;
  620.   UChar targetUniChar = 0x0000;
  621.   UChar mySourceChar = 0x0000;
  622.   int32_t myMode = _this->mode;
  623.  
  624.  
  625.   myToUnicode = _this->sharedData->table->dbcs.toUnicode;
  626.  
  627.     while (mySourceIndex < sourceLength)
  628.     {
  629.       if (myTargetIndex < targetLength)
  630.     {
  631.       /*gets the corresponding UniChar */
  632.       mySourceChar = (unsigned char) (mySource[mySourceIndex++]);
  633.       if (mySourceChar == UCNV_SI) myMode = UCNV_SI;
  634.       else if (mySourceChar == UCNV_SO) myMode = UCNV_SO;
  635.      else if ((myMode == UCNV_SO) &&
  636.           (_this->toUnicodeStatus == 0x00))
  637.         {
  638.           _this->toUnicodeStatus = (unsigned char) mySourceChar;
  639.         }
  640.       else
  641.         {
  642.           /*In case there is a state, we update the source char
  643.            *by concatenating the previous char with the current
  644.            *one
  645.            */
  646.           if (_this->toUnicodeStatus != 0x00)
  647.         {
  648.           mySourceChar |= (UChar) (_this->toUnicodeStatus << 8);
  649.           _this->toUnicodeStatus = 0x00;
  650.         }
  651.           else mySourceChar &= 0x00FF;
  652.  
  653.           /*gets the corresponding Unicode codepoint */
  654.           targetUniChar = (UChar) ucmp16_getu (myToUnicode, mySourceChar);
  655.  
  656.           /*writing the UniChar to the output stream */
  657.           if (targetUniChar != missingUCharMarker)
  658.         {
  659.           /*writes the UniChar to the output stream */
  660.           myTarget[myTargetIndex++] = targetUniChar;
  661.         }
  662.           else
  663.         {
  664.           *err = U_INVALID_CHAR_FOUND;
  665.           if (mySourceChar > 0xff)
  666.             {
  667.               _this->invalidCharLength = 2;
  668.               _this->invalidCharBuffer[0] = (char) (mySourceChar >> 8);
  669.               _this->invalidCharBuffer[1] = (char) mySourceChar;
  670.             }
  671.           else
  672.             {
  673.               _this->invalidCharLength = 1;
  674.               _this->invalidCharBuffer[0] = (char) mySourceChar;
  675.             }
  676.           _this->mode = myMode;
  677.           ToU_CALLBACK_MACRO(_this,
  678.                      myTarget,
  679.                      myTargetIndex, 
  680.                      targetLimit,
  681.                      mySource, 
  682.                      mySourceIndex,
  683.                      sourceLimit,
  684.                      offsets,
  685.                      flush,
  686.                      err);
  687.  
  688.           if (U_FAILURE (*err))  break;
  689.           _this->invalidCharLength = 0;
  690.         }
  691.         }
  692.     }
  693.       else
  694.     {
  695.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  696.       break;
  697.     }
  698.     }
  699.  
  700.   /*If at the end of conversion we are still carrying state information
  701.    *flush is TRUE, we can deduce that the input stream is truncated
  702.    */
  703.     if (_this->toUnicodeStatus
  704.     && (mySourceIndex == sourceLength)
  705.     && (flush == TRUE))
  706.       {
  707.     if (U_SUCCESS(*err)) 
  708.       {
  709.         *err = U_TRUNCATED_CHAR_FOUND;
  710.         _this->toUnicodeStatus = 0x00;
  711.       }
  712.       }
  713.  
  714.   *target += myTargetIndex;
  715.   *source += mySourceIndex;
  716.   _this->mode = myMode;
  717.  
  718.   return;
  719. }
  720.  
  721.  
  722. void T_UConverter_toUnicode_EBCDIC_STATEFUL_OFFSETS_LOGIC (UConverter * _this,
  723.                                UChar ** target,
  724.                                const UChar * targetLimit,
  725.                                const char **source,
  726.                                const char *sourceLimit,
  727.                                int32_t *offsets,
  728.                                bool_t flush,
  729.                                UErrorCode * err)
  730. {
  731.   const char *mySource = *source;
  732.   UChar *myTarget = *target;
  733.   int32_t mySourceIndex = 0;
  734.   int32_t myTargetIndex = 0;
  735.   int32_t targetLength = targetLimit - myTarget;
  736.   int32_t sourceLength = sourceLimit - mySource;
  737.   CompactShortArray *myToUnicode = NULL;
  738.   UChar targetUniChar = 0x0000;
  739.   UChar mySourceChar = 0x0000;
  740.   int32_t myMode = _this->mode;
  741.   int32_t* originalOffsets = offsets;
  742.  
  743.  
  744.   myToUnicode = _this->sharedData->table->dbcs.toUnicode;
  745.  
  746.     while (mySourceIndex < sourceLength)
  747.     {
  748.       if (myTargetIndex < targetLength)
  749.     {
  750.       /*gets the corresponding UniChar */
  751.       mySourceChar = (unsigned char) (mySource[mySourceIndex++]);
  752.       if (mySourceChar == UCNV_SI) myMode = UCNV_SI;
  753.       else if (mySourceChar == UCNV_SO) myMode = UCNV_SO;
  754.       else if ((myMode == UCNV_SO) &&
  755.            (_this->toUnicodeStatus == 0x00))
  756.         {
  757.           _this->toUnicodeStatus = (unsigned char) mySourceChar;
  758.         }
  759.       else
  760.         {
  761.           /*In case there is a state, we update the source char
  762.            *by concatenating the previous char with the current
  763.            *one
  764.            */
  765.           if (_this->toUnicodeStatus != 0x00)
  766.         {
  767.           mySourceChar |= (UChar) (_this->toUnicodeStatus << 8);
  768.           _this->toUnicodeStatus = 0x00;
  769.         }
  770.           else mySourceChar &= 0x00FF;
  771.  
  772.           /*gets the corresponding Unicode codepoint */
  773.           targetUniChar = (UChar) ucmp16_getu (myToUnicode, mySourceChar);
  774.  
  775.           /*writing the UniChar to the output stream */
  776.           if (targetUniChar != missingUCharMarker)
  777.         {
  778.           /*writes the UniChar to the output stream */
  779.           {
  780.             if(myMode == UCNV_SO)
  781.              offsets[myTargetIndex] = mySourceIndex-2; /* double byte */
  782.             else
  783.              offsets[myTargetIndex] = mySourceIndex-1; /* single byte */
  784.           }
  785.           myTarget[myTargetIndex++] = targetUniChar;
  786.         }
  787.           else
  788.         {
  789.           int32_t currentOffset = offsets[myTargetIndex-1] + 2;/* Because mySourceIndex was already incremented */
  790.           
  791.           *err = U_INVALID_CHAR_FOUND;
  792.           if (mySourceChar > 0xFF)
  793.             {
  794.               _this->invalidCharLength = 2;
  795.               _this->invalidCharBuffer[0] = (char) (mySourceChar >> 8);
  796.               _this->invalidCharBuffer[1] = (char) mySourceChar;
  797.             }
  798.           else
  799.             {
  800.               _this->invalidCharLength = 1;
  801.               _this->invalidCharBuffer[0] = (char) mySourceChar;
  802.             }
  803.           _this->mode = myMode;
  804.           ToU_CALLBACK_OFFSETS_LOGIC_MACRO(_this,
  805.                            myTarget,
  806.                            myTargetIndex, 
  807.                            targetLimit,
  808.                            mySource, 
  809.                            mySourceIndex,
  810.                            sourceLimit,
  811.                            offsets,
  812.                            flush,
  813.                            err);
  814.           
  815.           
  816.           if (U_FAILURE (*err))   break;
  817.           _this->invalidCharLength = 0;
  818.         }
  819.         }
  820.     }
  821.       else
  822.     {
  823.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  824.       break;
  825.     }
  826.     }
  827.  
  828.   /*If at the end of conversion we are still carrying state information
  829.    *flush is TRUE, we can deduce that the input stream is truncated
  830.    */
  831.     if (_this->toUnicodeStatus
  832.     && (mySourceIndex == sourceLength)
  833.     && (flush == TRUE))
  834.       {
  835.     if (U_SUCCESS(*err)) 
  836.       {
  837.         *err = U_TRUNCATED_CHAR_FOUND;
  838.         _this->toUnicodeStatus = 0x00;
  839.       }
  840.       }
  841.  
  842.   *target += myTargetIndex;
  843.   *source += mySourceIndex;
  844.   _this->mode = myMode;
  845.  
  846.   return;
  847. }
  848.  
  849.  
  850. void T_UConverter_toUnicode_MBCS (UConverter * _this,
  851.                    UChar ** target,
  852.                    const UChar * targetLimit,
  853.                    const char **source,
  854.                    const char *sourceLimit,
  855.                    int32_t *offsets,
  856.                    bool_t flush,
  857.                    UErrorCode * err)
  858. {
  859.   const char *mySource = *source;
  860.   UChar *myTarget = *target;
  861.   int32_t mySourceIndex = 0;
  862.   int32_t myTargetIndex = 0;
  863.   int32_t targetLength = targetLimit - myTarget;
  864.   int32_t sourceLength = sourceLimit - mySource;
  865.   CompactShortArray *myToUnicode = NULL;
  866.   UChar targetUniChar = 0x0000;
  867.   UChar mySourceChar = 0x0000;
  868.   bool_t *myStarters = NULL;
  869.  
  870.  
  871.  
  872.  
  873.   myToUnicode = _this->sharedData->table->mbcs.toUnicode;
  874.   myStarters = _this->sharedData->table->mbcs.starters;
  875.  
  876.   while (mySourceIndex < sourceLength)
  877.     {
  878.       if (myTargetIndex < targetLength)
  879.     {
  880.       /*gets the corresponding UniChar */
  881.       mySourceChar = (unsigned char) (mySource[mySourceIndex++]);
  882.  
  883.  
  884.       if (myStarters[(uint8_t) mySourceChar] &&
  885.           (_this->toUnicodeStatus == 0x00))
  886.         {
  887.           _this->toUnicodeStatus = (unsigned char) mySourceChar;
  888.         }
  889.       else
  890.         {
  891.           /*In case there is a state, we update the source char
  892.            *by concatenating the previous char with the current
  893.            *one
  894.            */
  895.  
  896.           if (_this->toUnicodeStatus != 0x00)
  897.         {
  898.           mySourceChar |= (UChar) (_this->toUnicodeStatus << 8);
  899.  
  900.           _this->toUnicodeStatus = 0x00;
  901.         }
  902.  
  903.           /*gets the corresponding Unicode codepoint */
  904.           targetUniChar = (UChar) ucmp16_getu (myToUnicode, mySourceChar);
  905.  
  906.           /*writing the UniChar to the output stream */
  907.           if (targetUniChar != missingUCharMarker)
  908.         {
  909.           myTarget[myTargetIndex++] = targetUniChar;
  910.           
  911.         }
  912.           else
  913.         {
  914.           *err = U_INVALID_CHAR_FOUND;
  915.           if (mySourceChar > 0xff)
  916.             {
  917.               _this->invalidCharLength = 2;
  918.               _this->invalidCharBuffer[0] = (char) (mySourceChar >> 8);
  919.               _this->invalidCharBuffer[1] = (char) mySourceChar;
  920.             }
  921.           else
  922.             {
  923.               _this->invalidCharLength = 1;
  924.               _this->invalidCharBuffer[0] = (char) mySourceChar;
  925.             }
  926.           
  927.           ToU_CALLBACK_MACRO(_this,
  928.                      myTarget,
  929.                      myTargetIndex, 
  930.                      targetLimit,
  931.                      mySource, 
  932.                      mySourceIndex,
  933.                      sourceLimit,
  934.                      offsets,
  935.                      flush,
  936.                      err);
  937.  
  938.           if (U_FAILURE (*err))    break;
  939.           _this->invalidCharLength = 0;
  940.         }
  941.         }
  942.     }
  943.       else
  944.     {
  945.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  946.       break;
  947.     }
  948.     }
  949.  
  950.   /*If at the end of conversion we are still carrying state information
  951.    *flush is TRUE, we can deduce that the input stream is truncated
  952.    */
  953.   if (_this->toUnicodeStatus
  954.       && (mySourceIndex == sourceLength)
  955.       && (flush == TRUE))
  956.     {
  957.       if (U_SUCCESS(*err)) 
  958.     {
  959.       *err = U_TRUNCATED_CHAR_FOUND; 
  960.       _this->toUnicodeStatus = 0x00;
  961.     }
  962.     }
  963.  
  964.   *target += myTargetIndex;
  965.   *source += mySourceIndex;
  966.  
  967.   return;
  968. }
  969.  
  970. void T_UConverter_toUnicode_MBCS_OFFSETS_LOGIC (UConverter * _this,
  971.                         UChar ** target,
  972.                         const UChar * targetLimit,
  973.                         const char **source,
  974.                         const char *sourceLimit,
  975.                         int32_t *offsets,
  976.                         bool_t flush,
  977.                         UErrorCode * err)
  978. {
  979.   const char *mySource = *source;
  980.   UChar *myTarget = *target;
  981.   int32_t mySourceIndex = 0;
  982.   int32_t myTargetIndex = 0;
  983.   int32_t targetLength = targetLimit - myTarget;
  984.   int32_t sourceLength = sourceLimit - mySource;
  985.   CompactShortArray *myToUnicode = NULL;
  986.   UChar targetUniChar = 0x0000;
  987.   UChar mySourceChar = 0x0000;
  988.   UChar oldMySourceChar;
  989.   bool_t *myStarters = NULL;
  990.   int32_t* originalOffsets = offsets;
  991.  
  992.  
  993.  
  994.   myToUnicode = _this->sharedData->table->mbcs.toUnicode;
  995.   myStarters = _this->sharedData->table->mbcs.starters;
  996.  
  997.   while (mySourceIndex < sourceLength)
  998.     {
  999.       if (myTargetIndex < targetLength)
  1000.     {
  1001.       /*gets the corresponding UniChar */
  1002.       mySourceChar = (unsigned char) (mySource[mySourceIndex++]);
  1003.  
  1004.  
  1005.       if (myStarters[(uint8_t) mySourceChar] &&
  1006.           (_this->toUnicodeStatus == 0x00))
  1007.         {
  1008.           _this->toUnicodeStatus = (unsigned char) mySourceChar;
  1009.         }
  1010.       else
  1011.         {
  1012.           /*In case there is a state, we update the source char
  1013.            *by concatenating the previous char with the current
  1014.            *one
  1015.            */
  1016.  
  1017.           if (_this->toUnicodeStatus != 0x00)
  1018.         {
  1019.           mySourceChar |= (UChar) (_this->toUnicodeStatus << 8);
  1020.  
  1021.           _this->toUnicodeStatus = 0x00;
  1022.         }
  1023.  
  1024.           /*gets the corresponding Unicode codepoint */
  1025.           targetUniChar = (UChar) ucmp16_getu (myToUnicode, mySourceChar);
  1026.           
  1027.  
  1028.           /*writing the UniChar to the output stream */
  1029.           if (targetUniChar != missingUCharMarker)
  1030.         {
  1031.           /*writes the UniChar to the output stream */
  1032.           {
  1033.               
  1034.  
  1035.                if (targetUniChar > 0x00FF)
  1036.              offsets[myTargetIndex] = mySourceIndex -2; /* double byte character - make the offset point to the first char */
  1037.             else
  1038.              offsets[myTargetIndex] = mySourceIndex -1 ;  /* single byte char. Offset is OK */
  1039.             
  1040.  
  1041.           }
  1042.           myTarget[myTargetIndex++] = targetUniChar;
  1043.         oldMySourceChar  = mySourceChar;
  1044.  
  1045.         }
  1046.           else
  1047.         {
  1048.               int32_t currentOffset = offsets[myTargetIndex-1] + ((oldMySourceChar>0x00FF)?2:1);
  1049.               
  1050.           *err = U_INVALID_CHAR_FOUND;
  1051.           if (mySourceChar > 0xff)
  1052.             {
  1053.               _this->invalidCharLength = 2;
  1054.               _this->invalidCharBuffer[0] = (char) (mySourceChar >> 8);
  1055.               _this->invalidCharBuffer[1] = (char) mySourceChar;
  1056.             }
  1057.           else
  1058.             {
  1059.               _this->invalidCharLength = 1;
  1060.               _this->invalidCharBuffer[0] = (char) mySourceChar;
  1061.             }
  1062.  
  1063.           ToU_CALLBACK_OFFSETS_LOGIC_MACRO(_this,
  1064.                            myTarget,
  1065.                            myTargetIndex, 
  1066.                            targetLimit,
  1067.                            mySource, 
  1068.                            mySourceIndex,
  1069.                            sourceLimit,
  1070.                            offsets,
  1071.                            flush,
  1072.                            err);
  1073.           
  1074.           if (U_FAILURE (*err))    break;
  1075.           _this->invalidCharLength = 0;
  1076.         }
  1077.         }
  1078.     }
  1079.       else
  1080.     {
  1081.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  1082.       break;
  1083.     }
  1084.     }
  1085.  
  1086.   /*If at the end of conversion we are still carrying state information
  1087.    *flush is TRUE, we can deduce that the input stream is truncated
  1088.    */
  1089.   if (_this->toUnicodeStatus
  1090.       && (mySourceIndex == sourceLength)
  1091.       && (flush == TRUE))
  1092.     {
  1093.       if (U_SUCCESS(*err)) 
  1094.     {
  1095.       *err = U_TRUNCATED_CHAR_FOUND; 
  1096.       _this->toUnicodeStatus = 0x00;
  1097.     }
  1098.     }
  1099.  
  1100.   *target += myTargetIndex;
  1101.   *source += mySourceIndex;
  1102.  
  1103.   return;
  1104. }
  1105.  
  1106.  
  1107. void T_UConverter_fromUnicode_EBCDIC_STATEFUL (UConverter * _this,
  1108.                            char **target,
  1109.                            const char *targetLimit,
  1110.                            const UChar ** source,
  1111.                            const UChar * sourceLimit,
  1112.                            int32_t *offsets,
  1113.                            bool_t flush,
  1114.                            UErrorCode * err)
  1115.  
  1116. {
  1117.   const UChar *mySource = *source;
  1118.   char *myTarget = *target;
  1119.   int32_t mySourceIndex = 0;
  1120.   int32_t myTargetIndex = 0;
  1121.   int32_t targetLength = targetLimit - myTarget;
  1122.   int32_t sourceLength = sourceLimit - mySource;
  1123.   CompactShortArray *myFromUnicode = NULL;
  1124.   UChar targetUniChar = 0x0000;
  1125.   int8_t targetUniCharByteNum = 0;
  1126.   UChar mySourceChar = 0x0000;
  1127.   bool_t isTargetUCharDBCS = (bool_t)_this->fromUnicodeStatus;
  1128.   bool_t oldIsTargetUCharDBCS = isTargetUCharDBCS;
  1129.   myFromUnicode = _this->sharedData->table->dbcs.fromUnicode;
  1130.   
  1131.   /*writing the char to the output stream */
  1132.   while (mySourceIndex < sourceLength)
  1133.     {
  1134.       if (myTargetIndex < targetLength)
  1135.     {
  1136.       mySourceChar = (UChar) mySource[mySourceIndex++];
  1137.       targetUniChar = (UChar) ucmp16_getu (myFromUnicode, mySourceChar);
  1138.       oldIsTargetUCharDBCS = isTargetUCharDBCS;
  1139.       isTargetUCharDBCS = (targetUniChar>0x00FF);
  1140.       
  1141.       if (targetUniChar != missingCharMarker)
  1142.         {
  1143.           if (oldIsTargetUCharDBCS != isTargetUCharDBCS)
  1144.         {
  1145.           if (isTargetUCharDBCS) myTarget[myTargetIndex++] = UCNV_SO;
  1146.           else myTarget[myTargetIndex++] = UCNV_SI;
  1147.           
  1148.           
  1149.           if ((!isTargetUCharDBCS)&&(myTargetIndex+1 >= targetLength))
  1150.             {
  1151.               _this->charErrorBuffer[0] = (char) targetUniChar;
  1152.               _this->charErrorBufferLength = 1;
  1153.               *err = U_INDEX_OUTOFBOUNDS_ERROR;
  1154.               break;
  1155.             }
  1156.           else if (myTargetIndex+1 >= targetLength)
  1157.             {
  1158.                _this->charErrorBuffer[0] = (char) (targetUniChar >> 8);
  1159.               _this->charErrorBuffer[1] = (char) targetUniChar & 0x00FF;
  1160.               _this->charErrorBufferLength = 2;
  1161.               *err = U_INDEX_OUTOFBOUNDS_ERROR;
  1162.               break;
  1163.             }
  1164.           
  1165.         }
  1166.           
  1167.           if (!isTargetUCharDBCS)
  1168.         {
  1169.           myTarget[myTargetIndex++] = (char) targetUniChar;
  1170.         }
  1171.           else
  1172.         {
  1173.           myTarget[myTargetIndex++] = (char) (targetUniChar >> 8);
  1174.           if (myTargetIndex < targetLength)
  1175.             {
  1176.               myTarget[myTargetIndex++] = (char) targetUniChar;
  1177.             }
  1178.           else
  1179.             {
  1180.               _this->charErrorBuffer[0] = (char) targetUniChar;
  1181.               _this->charErrorBufferLength = 1;
  1182.               *err = U_INDEX_OUTOFBOUNDS_ERROR;
  1183.               break;
  1184.             }
  1185.         }
  1186.         }
  1187.       else
  1188.         {
  1189.           isTargetUCharDBCS = oldIsTargetUCharDBCS;
  1190.           *err = U_INVALID_CHAR_FOUND;
  1191.           _this->invalidUCharBuffer[0] = (UChar) mySourceChar;
  1192.           _this->invalidUCharLength = 1;
  1193.  
  1194.           _this->fromUnicodeStatus = (int32_t)isTargetUCharDBCS;
  1195.           FromU_CALLBACK_MACRO(_this,
  1196.                    myTarget, 
  1197.                    myTargetIndex,
  1198.                    targetLimit, 
  1199.                    mySource,
  1200.                    mySourceIndex, 
  1201.                    sourceLimit,
  1202.                    offsets, 
  1203.                    flush, 
  1204.                    err);
  1205.  
  1206.           if (U_FAILURE (*err)) break;
  1207.           _this->invalidUCharLength = 0;
  1208.         }
  1209.     }
  1210.       else
  1211.     {
  1212.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  1213.       break;
  1214.     }
  1215.  
  1216.     }
  1217.  
  1218.  
  1219.   *target += myTargetIndex;
  1220.   *source += mySourceIndex;
  1221.   
  1222.   _this->fromUnicodeStatus = (int32_t)isTargetUCharDBCS;
  1223.  
  1224.   return;
  1225. }
  1226.  
  1227. void T_UConverter_fromUnicode_EBCDIC_STATEFUL_OFFSETS_LOGIC (UConverter * _this,
  1228.                                  char **target,
  1229.                                  const char *targetLimit,
  1230.                                  const UChar ** source,
  1231.                                  const UChar * sourceLimit,
  1232.                                  int32_t *offsets,
  1233.                                  bool_t flush,
  1234.                                  UErrorCode * err)
  1235.  
  1236. {
  1237.   const UChar *mySource = *source;
  1238.   char *myTarget = *target;
  1239.   int32_t mySourceIndex = 0;
  1240.   int32_t myTargetIndex = 0;
  1241.   int32_t targetLength = targetLimit - myTarget;
  1242.   int32_t sourceLength = sourceLimit - mySource;
  1243.   CompactShortArray *myFromUnicode = NULL;
  1244.   UChar targetUniChar = 0x0000;
  1245.   int8_t targetUniCharByteNum = 0;
  1246.   UChar mySourceChar = 0x0000;
  1247.   bool_t isTargetUCharDBCS = (bool_t)_this->fromUnicodeStatus;
  1248.   bool_t oldIsTargetUCharDBCS = isTargetUCharDBCS;
  1249.   int32_t* originalOffsets = offsets;
  1250.   
  1251.   myFromUnicode = _this->sharedData->table->dbcs.fromUnicode;
  1252.   
  1253.   /*writing the char to the output stream */
  1254.   while (mySourceIndex < sourceLength)
  1255.     {
  1256.       if (myTargetIndex < targetLength)
  1257.     {
  1258.       mySourceChar = (UChar) mySource[mySourceIndex++];
  1259.       targetUniChar = (UChar) ucmp16_getu (myFromUnicode, mySourceChar);
  1260.       oldIsTargetUCharDBCS = isTargetUCharDBCS;
  1261.       isTargetUCharDBCS = (targetUniChar>0x00FF);
  1262.       
  1263.       if (targetUniChar != missingCharMarker)
  1264.         {
  1265.           if (oldIsTargetUCharDBCS != isTargetUCharDBCS)
  1266.         {
  1267.           offsets[myTargetIndex] = mySourceIndex-1;
  1268.           if (isTargetUCharDBCS) myTarget[myTargetIndex++] = UCNV_SO;
  1269.           else myTarget[myTargetIndex++] = UCNV_SI;
  1270.           
  1271.           
  1272.           if ((!isTargetUCharDBCS)&&(myTargetIndex+1 >= targetLength))
  1273.             {
  1274.               _this->charErrorBuffer[0] = (char) targetUniChar;
  1275.               _this->charErrorBufferLength = 1;
  1276.               *err = U_INDEX_OUTOFBOUNDS_ERROR;
  1277.               break;
  1278.             }
  1279.           else if (myTargetIndex+1 >= targetLength)
  1280.             {
  1281.                _this->charErrorBuffer[0] = (char) (targetUniChar >> 8);
  1282.               _this->charErrorBuffer[1] = (char) targetUniChar & 0x00FF;
  1283.               _this->charErrorBufferLength = 2;
  1284.               *err = U_INDEX_OUTOFBOUNDS_ERROR;
  1285.               break;
  1286.             }
  1287.         }
  1288.           
  1289.           if (!isTargetUCharDBCS)
  1290.         {
  1291.            offsets[myTargetIndex] = mySourceIndex-1;
  1292.           myTarget[myTargetIndex++] = (char) targetUniChar;
  1293.         }
  1294.           else
  1295.         {
  1296.            offsets[myTargetIndex] = mySourceIndex-1;
  1297.           myTarget[myTargetIndex++] = (char) (targetUniChar >> 8);
  1298.           if (myTargetIndex < targetLength)
  1299.             {
  1300.                offsets[myTargetIndex] = mySourceIndex-1;
  1301.               myTarget[myTargetIndex++] = (char) targetUniChar;
  1302.             }
  1303.           else
  1304.             {
  1305.               _this->charErrorBuffer[0] = (char) targetUniChar;
  1306.               _this->charErrorBufferLength = 1;
  1307.               *err = U_INDEX_OUTOFBOUNDS_ERROR;
  1308.               break;
  1309.             }
  1310.         }
  1311.         }
  1312.       else
  1313.         {
  1314.           int32_t currentOffset = offsets[myTargetIndex-1]+1;
  1315.           *err = U_INVALID_CHAR_FOUND;
  1316.           _this->invalidUCharBuffer[0] = (UChar) mySourceChar;
  1317.           _this->invalidUCharLength = 1;
  1318.  
  1319.           /* Breaks out of the loop since behaviour was set to stop */
  1320.           _this->fromUnicodeStatus = (int32_t)isTargetUCharDBCS;
  1321.           FromU_CALLBACK_OFFSETS_LOGIC_MACRO(_this,
  1322.                          myTarget, 
  1323.                          myTargetIndex,
  1324.                          targetLimit, 
  1325.                          mySource,
  1326.                          mySourceIndex, 
  1327.                          sourceLimit,
  1328.                          offsets, 
  1329.                          flush, 
  1330.                          err);
  1331.           
  1332.           if (U_FAILURE (*err))    break;
  1333.           _this->invalidUCharLength = 0;
  1334.         }
  1335.     }
  1336.       else
  1337.     {
  1338.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  1339.       break;
  1340.     }
  1341.  
  1342.     }
  1343.  
  1344.  
  1345.   *target += myTargetIndex;
  1346.   *source += mySourceIndex;;
  1347.   
  1348.   _this->fromUnicodeStatus = (int32_t)isTargetUCharDBCS;
  1349.  
  1350.   return;
  1351. }
  1352.  
  1353. void   T_UConverter_fromUnicode_MBCS (UConverter * _this,
  1354.                       char **target,
  1355.                       const char *targetLimit,
  1356.                       const UChar ** source,
  1357.                       const UChar * sourceLimit,
  1358.                       int32_t *offsets,
  1359.                       bool_t flush,
  1360.                       UErrorCode * err)
  1361.  
  1362. {
  1363.   const UChar *mySource = *source;
  1364.   char *myTarget = *target;
  1365.   int32_t mySourceIndex = 0;
  1366.   int32_t myTargetIndex = 0;
  1367.   int32_t targetLength = targetLimit - myTarget;
  1368.   int32_t sourceLength = sourceLimit - mySource;
  1369.   CompactShortArray *myFromUnicode = NULL;
  1370.   UChar targetUniChar = 0x0000;
  1371.   int8_t targetUniCharByteNum = 0;
  1372.   UChar mySourceChar = 0x0000;
  1373.  
  1374.   myFromUnicode = _this->sharedData->table->mbcs.fromUnicode;
  1375.  
  1376.   /*writing the char to the output stream */
  1377.   while (mySourceIndex < sourceLength)
  1378.     {
  1379.       if (myTargetIndex < targetLength)
  1380.     {
  1381.       mySourceChar = (UChar) mySource[mySourceIndex++];
  1382.       targetUniChar = (UChar) ucmp16_getu (myFromUnicode, mySourceChar);
  1383.  
  1384.  
  1385.       if (targetUniChar != missingCharMarker)
  1386.         {
  1387.           if (targetUniChar <= 0x00FF)
  1388.         {
  1389.           myTarget[myTargetIndex++] = (char) targetUniChar;
  1390.         }
  1391.           else
  1392.         {
  1393.           myTarget[myTargetIndex++] = (char) (targetUniChar >> 8);
  1394.           if (myTargetIndex < targetLength)
  1395.             {
  1396.               myTarget[myTargetIndex++] = (char) targetUniChar;
  1397.             }
  1398.           else
  1399.             {
  1400.               _this->charErrorBuffer[0] = (char) targetUniChar;
  1401.               _this->charErrorBufferLength = 1;
  1402.               *err = U_INDEX_OUTOFBOUNDS_ERROR;
  1403.             }
  1404.         }
  1405.         }
  1406.       else
  1407.         {
  1408.           *err = U_INVALID_CHAR_FOUND;
  1409.           _this->invalidUCharBuffer[0] = (UChar) mySourceChar;
  1410.           _this->invalidUCharLength = 1;
  1411.  
  1412.           FromU_CALLBACK_MACRO(_this,
  1413.                    myTarget, 
  1414.                    myTargetIndex,
  1415.                    targetLimit, 
  1416.                    mySource,
  1417.                    mySourceIndex, 
  1418.                    sourceLimit,
  1419.                    offsets, 
  1420.                    flush, 
  1421.                    err);
  1422.  
  1423.           if (U_FAILURE (*err)) break;
  1424.           _this->invalidUCharLength = 0;
  1425.         }
  1426.     }
  1427.       else
  1428.     {
  1429.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  1430.       break;
  1431.     }
  1432.       
  1433.     }
  1434.  
  1435.  
  1436.   *target += myTargetIndex;
  1437.   *source += mySourceIndex;;
  1438.  
  1439.  
  1440.   return;
  1441. }
  1442.  
  1443. void   T_UConverter_fromUnicode_MBCS_OFFSETS_LOGIC (UConverter * _this,
  1444.                             char **target,
  1445.                             const char *targetLimit,
  1446.                             const UChar ** source,
  1447.                             const UChar * sourceLimit,
  1448.                             int32_t *offsets,
  1449.                             bool_t flush,
  1450.                             UErrorCode * err)
  1451.  
  1452. {
  1453.   const UChar *mySource = *source;
  1454.   char *myTarget = *target;
  1455.   int32_t mySourceIndex = 0;
  1456.   int32_t myTargetIndex = 0;
  1457.   int32_t targetLength = targetLimit - myTarget;
  1458.   int32_t sourceLength = sourceLimit - mySource;
  1459.   CompactShortArray *myFromUnicode = NULL;
  1460.   UChar targetUniChar = 0x0000;
  1461.   int8_t targetUniCharByteNum = 0;
  1462.   UChar mySourceChar = 0x0000;
  1463.   int32_t* originalOffsets = offsets;
  1464.  
  1465.   myFromUnicode = _this->sharedData->table->mbcs.fromUnicode;
  1466.  
  1467.   
  1468.  
  1469.   /*writing the char to the output stream */
  1470.   while (mySourceIndex < sourceLength)
  1471.     {
  1472.       if (myTargetIndex < targetLength)
  1473.     {
  1474.       mySourceChar = (UChar) mySource[mySourceIndex++];
  1475.       targetUniChar = (UChar) ucmp16_getu (myFromUnicode, mySourceChar);
  1476.  
  1477.       if (targetUniChar != missingCharMarker)
  1478.         {
  1479.           if (targetUniChar <= 0x00FF)
  1480.         {
  1481.            offsets[myTargetIndex] = mySourceIndex-1;
  1482.           myTarget[myTargetIndex++] = (char) targetUniChar;
  1483.  
  1484.         }
  1485.           else
  1486.         {
  1487.            offsets[myTargetIndex] = mySourceIndex-1;
  1488.           myTarget[myTargetIndex++] = (char) (targetUniChar >> 8);
  1489.           if (myTargetIndex < targetLength)
  1490.             {
  1491.                offsets[myTargetIndex] = mySourceIndex-1;
  1492.               myTarget[myTargetIndex++] = (char) targetUniChar;
  1493.             }
  1494.           else
  1495.             {
  1496.               _this->charErrorBuffer[0] = (char) targetUniChar;
  1497.               _this->charErrorBufferLength = 1;
  1498.               *err = U_INDEX_OUTOFBOUNDS_ERROR;
  1499.             }
  1500.         }
  1501.         }
  1502.       else
  1503.         {
  1504.           int32_t currentOffset = mySourceIndex -1;
  1505.           int32_t* offsetsAnchor = offsets;
  1506.           
  1507.           *err = U_INVALID_CHAR_FOUND;
  1508.           _this->invalidUCharBuffer[0] = (UChar) mySourceChar;
  1509.           _this->invalidUCharLength = 1;
  1510.  
  1511.           FromU_CALLBACK_OFFSETS_LOGIC_MACRO(_this,
  1512.                          myTarget, 
  1513.                          myTargetIndex,
  1514.                          targetLimit, 
  1515.                          mySource,
  1516.                          mySourceIndex, 
  1517.                          sourceLimit,
  1518.                          offsets, 
  1519.                          flush, 
  1520.                          err);
  1521.           
  1522.           if (U_FAILURE (*err)) break;
  1523.           _this->invalidUCharLength = 0;
  1524.         }
  1525.     }
  1526.       else
  1527.     {
  1528.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  1529.       break;
  1530.     }
  1531.  
  1532.     }
  1533.  
  1534.  
  1535.   *target += myTargetIndex;
  1536.   *source += mySourceIndex;;
  1537.  
  1538.  
  1539.   return;
  1540. }
  1541. void T_UConverter_fromUnicode_ISO_2022(UConverter* _this,
  1542.                        char** target,
  1543.                        const char* targetLimit,
  1544.                        const UChar** source,
  1545.                        const UChar* sourceLimit,
  1546.                        int32_t *offsets,
  1547.                        bool_t flush,
  1548.                        UErrorCode* err)
  1549. {
  1550.   char const* targetStart = *target;
  1551.   T_UConverter_fromUnicode_UTF8(_this,
  1552.                 target,
  1553.                 targetLimit,
  1554.                 source,
  1555.                 sourceLimit,
  1556.                 NULL,
  1557.                 flush,
  1558.                 err);
  1559. }
  1560.  
  1561.  
  1562. void T_UConverter_fromUnicode_ISO_2022_OFFSETS_LOGIC(UConverter* _this,
  1563.                              char** target,
  1564.                              const char* targetLimit,
  1565.                              const UChar** source,
  1566.                              const UChar* sourceLimit,
  1567.                              int32_t *offsets,
  1568.                              bool_t flush,
  1569.                              UErrorCode* err)
  1570. {
  1571.  
  1572.   char const* targetStart = *target;
  1573.   T_UConverter_fromUnicode_UTF8_OFFSETS_LOGIC(_this,
  1574.                           target,
  1575.                           targetLimit,
  1576.                           source,
  1577.                           sourceLimit,
  1578.                           offsets,
  1579.                           flush,
  1580.                           err);
  1581.   {
  1582.     int32_t len = *target - targetStart;
  1583.     int32_t i;
  1584.     /* icu_memmove(offsets+3, offsets, len);   MEMMOVE SEEMS BROKEN --srl */
  1585.     
  1586.     for(i=len-1;i>=0;i--)    offsets[i] = offsets[i];
  1587.     
  1588.   }
  1589. }
  1590.  
  1591. UCNV_TableStates_2022 getKey_2022(char c,
  1592.                   int32_t* key,
  1593.                   int32_t* offset)
  1594. {
  1595.   int32_t togo = *key;
  1596.   int32_t low = 0;
  1597.   int32_t hi = MAX_STATES_2022;
  1598.   int32_t oldmid;
  1599.   
  1600.   if (*key == 0)  togo = normalize_esq_chars_2022[c];
  1601.   else
  1602.     {
  1603.       togo <<= 5;
  1604.       togo += normalize_esq_chars_2022[c];
  1605.     }
  1606.   
  1607.   while (hi != low)  /*binary search*/
  1608.     {
  1609.       register int32_t mid = (hi+low) >> 1; /*Finds median*/
  1610.       
  1611.       if (mid == oldmid) break;
  1612.       if (escSeqStateTable_Key_2022[mid] > togo)  hi = mid;
  1613.       else if (escSeqStateTable_Key_2022[mid] < togo)  low = mid;
  1614.       else /*we found it*/
  1615.     {
  1616.       *key = togo;
  1617.       *offset = mid;
  1618. #ifdef Debug
  1619.         printf("found at @ %d\n", mid);
  1620. #endif /*Debug*/
  1621.       return escSeqStateTable_Value_2022[mid];
  1622.     }
  1623.       oldmid = mid;
  1624.       
  1625.     }
  1626.  
  1627. #ifdef Debug  
  1628.   printf("Could not find \"%d\" for %X\n", togo, c);
  1629. #endif /*Debug*/
  1630.   *key = 0;
  1631.   *offset = 0;
  1632.   
  1633.  
  1634.   return INVALID_2022;
  1635. }
  1636.  
  1637. void changeState_2022(UConverter* _this,
  1638.               const char** source, 
  1639.               const char* sourceLimit,
  1640.               bool_t flush,
  1641.               UErrorCode* err)
  1642. {
  1643.   UConverter* myUConverter;
  1644.   uint32_t key = _this->toUnicodeStatus;
  1645.   UCNV_TableStates_2022 value;
  1646.   UConverterDataISO2022* myData2022 = ((UConverterDataISO2022*)_this->extraInfo);
  1647.   const char* chosenConverterName = NULL;
  1648.   int32_t offset;
  1649.   
  1650.   /*Close the old Converter*/
  1651.   if (_this->mode == UCNV_SO) ucnv_close(myData2022->currentConverter);
  1652.   myData2022->currentConverter = NULL;
  1653.   _this->mode = UCNV_SI;
  1654.   
  1655.   /*In case we were in the process of consuming an escape sequence
  1656.     we need to reprocess it */
  1657.   
  1658.   do
  1659.     {
  1660. #ifdef Debug
  1661.       printf("Pre Stage: char = %x, key = %d, value =%d\n", **source, key, value);
  1662.       fflush(stdout);
  1663. #endif /*Debug*/
  1664. /* Needed explicit cast for key on MVS to make compiler happy - JJD */
  1665.       value = getKey_2022(**source,(int32_t *) &key, &offset);
  1666. #ifdef Debug
  1667.       printf("Post Stage: char = %x, key = %d, value =%d\n", **source, key, value);
  1668.       fflush(stdout);
  1669. #endif /*Debug*/
  1670.       switch (value)
  1671.     {
  1672.     case VALID_NON_TERMINAL_2022 : 
  1673.       {
  1674. #ifdef Debug
  1675.         puts("VALID_NON_TERMINAL_2022");
  1676. #endif /*Debug*/
  1677.       };break;
  1678.       
  1679.     case VALID_TERMINAL_2022:
  1680.       {
  1681. #ifdef Debug
  1682.         puts("VALID_TERMINAL_2022");
  1683. #endif /*Debug*/
  1684.         chosenConverterName = escSeqStateTable_Result_2022[offset];
  1685.         key = 0;
  1686.         goto DONE;
  1687.       };break;
  1688.       
  1689.     case INVALID_2022:
  1690.       {
  1691. #ifdef Debug        
  1692.         puts("INVALID_2022");
  1693. #endif /*Debug*/
  1694.         _this->toUnicodeStatus = 0;
  1695.         *err = U_ILLEGAL_CHAR_FOUND;
  1696.         return;
  1697.       }
  1698.       
  1699.     case VALID_MAYBE_TERMINAL_2022:
  1700.       {
  1701.         const char* mySource = (*source + 1);
  1702.         int32_t myKey = key;
  1703.         UCNV_TableStates_2022 myValue = value;
  1704.         int32_t myOffset;
  1705. #ifdef Debug        
  1706.         puts("VALID_MAYBE_TERMINAL_2022");
  1707. #endif /*Debug*/
  1708.  
  1709.         while ((mySource < sourceLimit) && 
  1710.            ((myValue == VALID_MAYBE_TERMINAL_2022)||(myValue == VALID_NON_TERMINAL_2022)))
  1711.           {
  1712. #ifdef Debug
  1713.         printf("MAYBE value = %d myKey = %d %X\n", myValue, myKey, *mySource);
  1714. #endif /*Debug*/
  1715.         myValue = getKey_2022(*(mySource++), &myKey, &myOffset);
  1716.           }
  1717. #ifdef Debug        
  1718.         printf("myValue = %d\n", myValue);
  1719. #endif /*Debug*/
  1720.         switch (myValue)
  1721.           {
  1722.           case INVALID_2022:
  1723.         {
  1724.           /*Backs off*/
  1725. #ifdef Debug        
  1726.           puts("VALID_MAYBE_TERMINAL INVALID");
  1727.           printf("offset = %d\n", offset);
  1728. #endif /*Debug*/
  1729.           chosenConverterName = escSeqStateTable_Result_2022[offset];
  1730.           value = VALID_TERMINAL_2022;
  1731. #ifdef Debug        
  1732.           printf("%d\n", offset);
  1733.           fflush(stdout);
  1734. #endif /*Debug*/
  1735.           goto DONE;
  1736.         };break;
  1737.           
  1738.           case VALID_TERMINAL_2022:
  1739.         {
  1740.           /*uses longer escape sequence*/
  1741. #ifdef Debug
  1742.           puts("VALID_MAYBE_TERMINAL TERMINAL");
  1743. #endif /*Debug*/
  1744.           *source = mySource-1; /*deals with the overshot in the while above*/
  1745.           chosenConverterName = escSeqStateTable_Result_2022[myOffset];
  1746.           key = 0;
  1747.           value = VALID_TERMINAL_2022;
  1748.           goto DONE;
  1749.         };break;
  1750.           
  1751.           case VALID_NON_TERMINAL_2022: 
  1752. #ifdef Debug
  1753.         puts("VALID_MAYBE_TERMINAL NON_TERMINAL");
  1754. #endif /*Debug*/
  1755.           case VALID_MAYBE_TERMINAL_2022:
  1756.         {
  1757. #ifdef Debug
  1758.           puts("VALID_MAYBE_TERMINAL MAYBE_TERMINAL");
  1759. #endif /*Debug*/
  1760.           if (flush) 
  1761.             {
  1762.               /*Backs off*/
  1763.               chosenConverterName = escSeqStateTable_Result_2022[offset];
  1764.               value = VALID_TERMINAL_2022;
  1765.               key = 0;
  1766.               goto DONE;
  1767.             }
  1768.           else
  1769.             {
  1770.               key = myKey;
  1771.               value = VALID_NON_TERMINAL_2022;
  1772.             }
  1773.         };break;
  1774.           };break;
  1775.       };break;
  1776.     }
  1777.     }  while ((*source)++ <= sourceLimit);
  1778.   
  1779.  DONE:
  1780.   _this->toUnicodeStatus = key;
  1781.   
  1782.   if ((value == VALID_NON_TERMINAL_2022) || (value == VALID_MAYBE_TERMINAL_2022)) 
  1783.     {
  1784. #ifdef Debug
  1785.       printf("Out: current **source = %X", **source);
  1786. #endif
  1787.  
  1788.       return;
  1789.     }
  1790.   if (value > 0) myData2022->currentConverter = myUConverter = ucnv_open(chosenConverterName, err);
  1791.   {
  1792. #ifdef Debug
  1793.     printf("Error = %d open \"%s\"\n", *err, chosenConverterName);
  1794. #endif /*Debug*/
  1795.     if (U_SUCCESS(*err)) 
  1796.       {
  1797.     /*Customize the converter with the attributes set on the 2022 converter*/
  1798.     myUConverter->fromUCharErrorBehaviour = _this->fromUCharErrorBehaviour;
  1799.     myUConverter->fromCharErrorBehaviour = _this->fromCharErrorBehaviour;
  1800.     icu_memcpy(myUConverter->subChar, 
  1801.            _this->subChar,
  1802.            myUConverter->subCharLen = _this->subCharLen);
  1803.     
  1804.     _this->mode = UCNV_SO;
  1805.       }
  1806.   }
  1807.  
  1808.   
  1809.   return;
  1810. }
  1811.  
  1812. /*Checks the first 3 characters of the buffer against valid 2022 escape sequences
  1813.  *if the match we return a pointer to the initial start of the sequence otherwise
  1814.  *we return sourceLimit
  1815.  */
  1816. const char* getEndOfBuffer_2022(const char* source,
  1817.                 const char* sourceLimit,
  1818.                 bool_t flush)
  1819. {
  1820.   const char* mySource = source;
  1821.   
  1822.   if (source >= sourceLimit) return sourceLimit;
  1823.   
  1824.   do
  1825.     {
  1826.       if (*mySource == ESC_2022)
  1827.     {
  1828.       int8_t i;
  1829.       int32_t key = 0;
  1830.       int32_t offset;
  1831.       UCNV_TableStates_2022 value = VALID_NON_TERMINAL_2022;
  1832.       
  1833.       for (i=0; 
  1834.            (mySource+i < sourceLimit)&&(value == VALID_NON_TERMINAL_2022);
  1835.            i++) 
  1836.         {
  1837.           value =  getKey_2022(*(mySource+i), &key, &offset);
  1838. #ifdef Debug
  1839.           printf("Look ahead value = %d\n", value);
  1840. #endif /*Debug*/
  1841.         }
  1842.       if (value > 0) return mySource;
  1843.       if ((value == VALID_NON_TERMINAL_2022)&&(!flush) ) return sourceLimit;
  1844.     }
  1845.     }
  1846.   while (mySource++ < sourceLimit);
  1847.   
  1848.   return sourceLimit;
  1849. }
  1850.           
  1851.   
  1852.  
  1853. void T_UConverter_toUnicode_ISO_2022(UConverter* _this,
  1854.                      UChar** target,
  1855.                      const UChar* targetLimit,
  1856.                      const char** source,
  1857.                      const char* sourceLimit,
  1858.                      int32_t *offsets,
  1859.                      bool_t flush,
  1860.                      UErrorCode* err)
  1861. {
  1862.   int32_t base = 0;
  1863.   const char* mySourceLimit;
  1864.   char const* sourceStart;
  1865.   
  1866.   /*Arguments Check*/
  1867.   if (U_FAILURE(*err)) return;
  1868.   if ((_this == NULL) || (targetLimit < *target) || (sourceLimit < *source))
  1869.     {
  1870.       *err = U_ILLEGAL_ARGUMENT_ERROR;
  1871.       return;
  1872.     }
  1873.   
  1874.   for (;;)
  1875.     {
  1876.  
  1877.        mySourceLimit =  getEndOfBuffer_2022(*source, sourceLimit, flush); 
  1878.       
  1879.  
  1880.       /*Find the end of the buffer e.g : Next Escape Seq | end of Buffer*/
  1881.       if (_this->mode == UCNV_SO) /*Already doing some conversion*/
  1882.     {
  1883.       const UChar* myTargetStart = *target;
  1884. #ifdef Debug
  1885.       printf("source %X\n mySourceLimit %X\n sourceLimit %X\n", *source, mySourceLimit, sourceLimit); 
  1886. #endif /*Debug*/
  1887.       
  1888.       ucnv_toUnicode(((UConverterDataISO2022*)(_this->extraInfo))->currentConverter,
  1889.              target,
  1890.              targetLimit,
  1891.              source,
  1892.              mySourceLimit,
  1893.              NULL,
  1894.              flush,
  1895.              err);
  1896.  
  1897.       
  1898. #ifdef Debug      
  1899.       puts("---------------------------> CONVERTED");
  1900.       printf("source %X\n mySourceLimit %X\n sourceLimit %X\n", *source, mySourceLimit, sourceLimit); 
  1901.       printf("err =%d", *err);
  1902. #endif /*Debug*/
  1903.     }
  1904.       /*-Done with buffer with entire buffer
  1905.     -Error while converting
  1906.       */
  1907.     
  1908.       if (U_FAILURE(*err) || (*source == sourceLimit)) return;
  1909. #ifdef Debug            
  1910.       puts("Got Here!");
  1911.       fflush(stdout);
  1912. #endif /*Debug*/
  1913.       sourceStart = *source;
  1914.       changeState_2022(_this,
  1915.                source, 
  1916.                sourceLimit,
  1917.                flush,
  1918.                err);
  1919.       (*source)++;
  1920.  
  1921.     }
  1922.   
  1923.   return;
  1924. }
  1925.  
  1926. void T_UConverter_toUnicode_ISO_2022_OFFSETS_LOGIC(UConverter* _this,
  1927.                            UChar** target,
  1928.                            const UChar* targetLimit,
  1929.                            const char** source,
  1930.                            const char* sourceLimit,
  1931.                            int32_t *offsets,
  1932.                            bool_t flush,
  1933.                            UErrorCode* err)
  1934. {
  1935.   int32_t myOffset=0;
  1936.   int32_t base = 0;
  1937.   const char* mySourceLimit;
  1938.   char const* sourceStart;
  1939.   
  1940.   /*Arguments Check*/
  1941.   if (U_FAILURE(*err)) return;
  1942.   if ((_this == NULL) || (targetLimit < *target) || (sourceLimit < *source))
  1943.     {
  1944.       *err = U_ILLEGAL_ARGUMENT_ERROR;
  1945.       return;
  1946.     }
  1947.   
  1948.   for (;;)
  1949.     {
  1950.  
  1951.       mySourceLimit =  getEndOfBuffer_2022(*source, sourceLimit, flush); 
  1952.       /*Find the end of the buffer e.g : Next Escape Seq | end of Buffer*/
  1953.  
  1954.       if (_this->mode == UCNV_SO) /*Already doing some conversion*/
  1955.     {
  1956.       const UChar* myTargetStart = *target;
  1957. #ifdef Debug
  1958.       printf("source %X\n mySourceLimit %X\n sourceLimit %X\n", *source, mySourceLimit, sourceLimit); 
  1959. #endif /*Debug*/
  1960.       
  1961.       ucnv_toUnicode(((UConverterDataISO2022*)(_this->extraInfo))->currentConverter,
  1962.              target,
  1963.              targetLimit,
  1964.              source,
  1965.              mySourceLimit,
  1966.              offsets,
  1967.              flush,
  1968.              err);
  1969.       
  1970.         {
  1971.           int32_t lim =  *target - myTargetStart;
  1972.           int32_t i = 0;
  1973.           for (i=base; i < lim;i++)    offsets[i] += myOffset;
  1974.           base += lim;
  1975.         }
  1976.       
  1977. #ifdef Debug      
  1978.       puts("---------------------------> CONVERTED");
  1979.       printf("source %X\n mySourceLimit %X\n sourceLimit %X\n", *source, mySourceLimit, sourceLimit); 
  1980.       printf("err =%d", *err);
  1981. #endif /*Debug*/
  1982.     }
  1983.  
  1984.       /*-Done with buffer with entire buffer
  1985.     -Error while converting
  1986.       */
  1987.     
  1988.       if (U_FAILURE(*err) || (*source == sourceLimit)) return;
  1989. #ifdef Debug            
  1990.       puts("Got Here!");
  1991.       fflush(stdout);
  1992. #endif /*Debug*/
  1993.       sourceStart = *source;
  1994.       changeState_2022(_this,
  1995.                source, 
  1996.                sourceLimit,
  1997.                flush,
  1998.                err);
  1999.        (*source)++;
  2000.        myOffset += *source - sourceStart;
  2001.  
  2002.     }
  2003.   
  2004.   return;
  2005. }
  2006.  
  2007.  
  2008.  
  2009.  
  2010.  
  2011.  
  2012. void   T_UConverter_fromUnicode_DBCS (UConverter * _this,
  2013.                       char **target,
  2014.                       const char *targetLimit,
  2015.                       const UChar ** source,
  2016.                       const UChar * sourceLimit,
  2017.                       int32_t *offsets,
  2018.                       bool_t flush,
  2019.                       UErrorCode * err)
  2020. {
  2021.   const UChar *mySource = *source;
  2022.   unsigned char *myTarget = (unsigned char *) *target;
  2023.   int32_t mySourceIndex = 0;
  2024.   int32_t myTargetIndex = 0;
  2025.   int32_t targetLength = targetLimit - (char *) myTarget;
  2026.   int32_t sourceLength = sourceLimit - mySource;
  2027.   CompactShortArray *myFromUnicode = NULL;
  2028.   UChar targetUniChar = 0x0000;
  2029.   UChar mySourceChar = 0x0000;
  2030.  
  2031.   myFromUnicode = _this->sharedData->table->dbcs.fromUnicode;
  2032.  
  2033.   /*writing the char to the output stream */
  2034.   while (mySourceIndex < sourceLength)
  2035.     {
  2036.  
  2037.       if (myTargetIndex < targetLength)
  2038.     {
  2039.       mySourceChar = (UChar) mySource[mySourceIndex++];
  2040.  
  2041.       /*Gets the corresponding codepoint */
  2042.       targetUniChar = (UChar) ucmp16_getu (myFromUnicode, mySourceChar);
  2043.       if (targetUniChar != missingCharMarker)
  2044.         {
  2045.           /*writes the char to the output stream */
  2046.           myTarget[myTargetIndex++] = (char) (targetUniChar >> 8);
  2047.           if (myTargetIndex < targetLength)
  2048.         {
  2049.           myTarget[myTargetIndex++] = (char) targetUniChar;
  2050.         }
  2051.           else
  2052.         {
  2053.           _this->charErrorBuffer[0] = (char) targetUniChar;
  2054.           _this->charErrorBufferLength = 1;
  2055.           *err = U_INDEX_OUTOFBOUNDS_ERROR;
  2056.         }
  2057.         }
  2058.       else
  2059.         {
  2060.           *err = U_INVALID_CHAR_FOUND;
  2061.           _this->invalidUCharBuffer[0] = (UChar) mySourceChar;
  2062.           _this->invalidUCharLength = 1;
  2063.  
  2064.  
  2065. /* Needed explicit cast for myTarget on MVS to make compiler happy - JJD */
  2066.           FromU_CALLBACK_MACRO(_this,
  2067.                    (char *)myTarget, 
  2068.                    myTargetIndex,
  2069.                    targetLimit, 
  2070.                    mySource,
  2071.                    mySourceIndex, 
  2072.                    sourceLimit,
  2073.                    offsets, 
  2074.                    flush, 
  2075.                    err);
  2076.  
  2077.           if (U_FAILURE (*err)) break;
  2078.           _this->invalidUCharLength = 0;
  2079.         }
  2080.     }
  2081.       else
  2082.     {
  2083.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  2084.       break;
  2085.     }
  2086.     }
  2087.  
  2088.   *target += myTargetIndex;
  2089.   *source += mySourceIndex;;
  2090.  
  2091.  
  2092.   return;
  2093. }
  2094.  
  2095. void T_UConverter_fromUnicode_UTF8 (UConverter * _this,
  2096.                     char **target,
  2097.                     const char *targetLimit,
  2098.                     const UChar ** source,
  2099.                     const UChar * sourceLimit,
  2100.                     int32_t *offsets,
  2101.                     bool_t flush,
  2102.                     UErrorCode * err)
  2103. {
  2104.   const UChar *mySource = *source;
  2105.   unsigned char *myTarget = (unsigned char *) *target;
  2106.   int32_t mySourceIndex = 0;
  2107.   int32_t myTargetIndex = 0;
  2108.   int32_t targetLength = targetLimit - (char *) myTarget;
  2109.   int32_t sourceLength = sourceLimit - mySource;
  2110.   int8_t targetCharByteNum = 0;
  2111.   UChar mySourceChar = 0x0000;
  2112.   uint32_t ch;
  2113.   int16_t bytesToWrite = 0;
  2114.   uint32_t ch2, i;
  2115.   char temp[4];
  2116.  
  2117.   if (_this->fromUnicodeStatus)
  2118.     {
  2119.       ch = _this->fromUnicodeStatus;
  2120.       _this->fromUnicodeStatus = 0;
  2121.       goto lowsurogate;
  2122.     }
  2123.   while (mySourceIndex < sourceLength)
  2124.     {
  2125.       if (myTargetIndex < targetLength)
  2126.     {
  2127.       bytesToWrite = 0;
  2128.       ch = mySource[mySourceIndex++];
  2129.  
  2130.       if (ch < 0x80)    /* Single byte */
  2131.         {
  2132.           myTarget[myTargetIndex++] = (char) ch;
  2133.         }
  2134.       else if (ch < 0x800)    /* Double byte */
  2135.         {
  2136.           myTarget[myTargetIndex++] = (char) ((ch >> 6) | 0xc0);
  2137.           if (myTargetIndex < targetLength)
  2138.         {
  2139.           myTarget[myTargetIndex++] = (char) ((ch & 0x3f) | 0x80);
  2140.         }
  2141.           else
  2142.         {
  2143.           _this->charErrorBuffer[0] = (char) ((ch & 0x3f) | 0x80);
  2144.           _this->charErrorBufferLength = 1;
  2145.           *err = U_INDEX_OUTOFBOUNDS_ERROR;
  2146.         }
  2147.         }
  2148.       else
  2149.         /* Check for surogates */
  2150.         {
  2151.           if ((ch >= kSurrogateHighStart) && (ch <= kSurrogateHighEnd))
  2152.         {
  2153.         lowsurogate:
  2154.           if (mySourceIndex < sourceLength && !flush)
  2155.             {
  2156.               ch2 = mySource[mySourceIndex];
  2157.               if ((ch2 >= kSurrogateLowStart) && (ch2 <= kSurrogateLowEnd))
  2158.             {
  2159.               ch = ((ch - kSurrogateHighStart) << halfShift) + (ch2 - kSurrogateLowStart) + halfBase;
  2160.               ++mySourceIndex;
  2161.             }
  2162.             }
  2163.         }
  2164.           if (ch < 0x10000)
  2165.         {
  2166.           bytesToWrite = 3;
  2167.           temp[0] = (char) ((ch >> 12) | 0xe0);
  2168.           temp[1] = (char) ((ch >> 6) & 0x3f | 0x80);
  2169.           temp[2] = (char) (ch & 0x3f | 0x80);
  2170.         }
  2171.           else
  2172.         {
  2173.           bytesToWrite = 4;
  2174.           temp[0] = (char) ((ch >> 18) | 0xf0);
  2175.           temp[1] = (char) ((ch >> 12) & 0x3f | 0xe0);
  2176.           temp[2] = (char) ((ch >> 6) & 0x3f | 0x80);
  2177.           temp[3] = (char) (ch & 0x3f | 0x80);
  2178.         }
  2179.           for (i = 0; i < bytesToWrite; i++)
  2180.         {
  2181.           if (myTargetIndex < targetLength)
  2182.             {
  2183.               myTarget[myTargetIndex++] = temp[i];
  2184.             }
  2185.           else
  2186.             {
  2187.               _this->charErrorBuffer[_this->charErrorBufferLength++] = temp[i];
  2188.               *err = U_INDEX_OUTOFBOUNDS_ERROR;
  2189.             }
  2190.         }
  2191.         }
  2192.     }
  2193.       else
  2194.     {
  2195.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  2196.       break;
  2197.     }
  2198.  
  2199.     }
  2200.  
  2201.   *target += myTargetIndex;
  2202.   *source += mySourceIndex;
  2203.  
  2204.   return;
  2205. }
  2206.  
  2207. void T_UConverter_fromUnicode_UTF8_OFFSETS_LOGIC (UConverter * _this,
  2208.                           char **target,
  2209.                           const char *targetLimit,
  2210.                           const UChar ** source,
  2211.                           const UChar * sourceLimit,
  2212.                           int32_t *offsets,
  2213.                           bool_t flush,
  2214.                           UErrorCode * err)
  2215. {
  2216.   const UChar *mySource = *source;
  2217.   unsigned char *myTarget = (unsigned char *) *target;
  2218.   int32_t mySourceIndex = 0;
  2219.   int32_t myTargetIndex = 0;
  2220.   int32_t targetLength = targetLimit - (char *) myTarget;
  2221.   int32_t sourceLength = sourceLimit - mySource;
  2222.   int8_t targetCharByteNum = 0;
  2223.   UChar mySourceChar = 0x0000;
  2224.   uint32_t ch;
  2225.   int16_t bytesToWrite = 0;
  2226.   uint32_t ch2, i;
  2227.   char temp[4];
  2228.  
  2229.   if (_this->fromUnicodeStatus)
  2230.     {
  2231.       ch = _this->fromUnicodeStatus;
  2232.       _this->fromUnicodeStatus = 0;
  2233.       goto lowsurogate;
  2234.     }
  2235.   while (mySourceIndex < sourceLength)
  2236.     {
  2237.       if (myTargetIndex < targetLength)
  2238.     {
  2239.       bytesToWrite = 0;
  2240.       ch = mySource[mySourceIndex++];
  2241.  
  2242.       if (ch < 0x80)    /* Single byte */
  2243.         {
  2244.            offsets[myTargetIndex] = mySourceIndex-1;
  2245.           myTarget[myTargetIndex++] = (char) ch;
  2246.         }
  2247.       else if (ch < 0x800)    /* Double byte */
  2248.         {
  2249.            offsets[myTargetIndex] = mySourceIndex-1;
  2250.           myTarget[myTargetIndex++] = (char) ((ch >> 6) | 0xc0);
  2251.           if (myTargetIndex < targetLength)
  2252.         {
  2253.            offsets[myTargetIndex] = mySourceIndex-1;
  2254.           myTarget[myTargetIndex++] = (char) ((ch & 0x3f) | 0x80);
  2255.         }
  2256.           else
  2257.         {
  2258.           _this->charErrorBuffer[0] = (char) ((ch & 0x3f) | 0x80);
  2259.           _this->charErrorBufferLength = 1;
  2260.           *err = U_INDEX_OUTOFBOUNDS_ERROR;
  2261.         }
  2262.         }
  2263.       else
  2264.         /* Check for surogates */
  2265.         {
  2266.           if ((ch >= kSurrogateHighStart) && (ch <= kSurrogateHighEnd))
  2267.         {
  2268.         lowsurogate:
  2269.           if (mySourceIndex < sourceLength && !flush)
  2270.             {
  2271.               ch2 = mySource[mySourceIndex];
  2272.               if ((ch2 >= kSurrogateLowStart) && (ch2 <= kSurrogateLowEnd))
  2273.             {
  2274.               ch = ((ch - kSurrogateHighStart) << halfShift) + (ch2 - kSurrogateLowStart) + halfBase;
  2275.               ++mySourceIndex;
  2276.             }
  2277.             }
  2278.         }
  2279.           if (ch < 0x10000)
  2280.         {
  2281.           bytesToWrite = 3;
  2282.           temp[0] = (char) ((ch >> 12) | 0xe0);
  2283.           temp[1] = (char) ((ch >> 6) & 0x3f | 0x80);
  2284.           temp[2] = (char) (ch & 0x3f | 0x80);
  2285.         }
  2286.           else
  2287.         {
  2288.           bytesToWrite = 4;
  2289.           temp[0] = (char) ((ch >> 18) | 0xf0);
  2290.           temp[1] = (char) ((ch >> 12) & 0x3f | 0xe0);
  2291.           temp[2] = (char) ((ch >> 6) & 0x3f | 0x80);
  2292.           temp[3] = (char) (ch & 0x3f | 0x80);
  2293.         }
  2294.           for (i = 0; i < bytesToWrite; i++)
  2295.         {
  2296.           if (myTargetIndex < targetLength)
  2297.             {
  2298.                offsets[myTargetIndex] = mySourceIndex-1;
  2299.               myTarget[myTargetIndex++] = temp[i];
  2300.             }
  2301.           else
  2302.             {
  2303.               _this->charErrorBuffer[_this->charErrorBufferLength++] = temp[i];
  2304.               *err = U_INDEX_OUTOFBOUNDS_ERROR;
  2305.             }
  2306.         }
  2307.         }
  2308.     }
  2309.       else
  2310.     {
  2311.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  2312.       break;
  2313.     }
  2314.  
  2315.     }
  2316.  
  2317.   *target += myTargetIndex;
  2318.   *source += mySourceIndex;
  2319.  
  2320.   return;
  2321. }
  2322.  
  2323.  
  2324. void  T_UConverter_fromUnicode_UTF16_BE (UConverter * _this,
  2325.                      char **target,
  2326.                      const char *targetLimit,
  2327.                      const UChar ** source,
  2328.                      const UChar * sourceLimit,
  2329.                      int32_t *offsets,
  2330.                      bool_t flush,
  2331.                      UErrorCode * err)
  2332. {
  2333.   const UChar *mySource = *source;
  2334.   unsigned char *myTarget = (unsigned char *) *target;
  2335.   int32_t mySourceIndex = 0;
  2336.   int32_t myTargetIndex = 0;
  2337.   int32_t targetLength = targetLimit - (char *) myTarget;
  2338.   int32_t sourceLength = sourceLimit - mySource;
  2339.   UChar mySourceChar;
  2340.  
  2341.   /*writing the char to the output stream */
  2342.   while (mySourceIndex < sourceLength)
  2343.     {
  2344.  
  2345.       if (myTargetIndex < targetLength)
  2346.     {
  2347.       mySourceChar = (UChar) mySource[mySourceIndex++];
  2348.       myTarget[myTargetIndex++] = (char) (mySourceChar >> 8);
  2349.       if (myTargetIndex < targetLength)
  2350.         {
  2351.           myTarget[myTargetIndex++] = (char) mySourceChar;
  2352.         }
  2353.       else
  2354.         {
  2355.           _this->charErrorBuffer[0] = (char) mySourceChar;
  2356.           _this->charErrorBufferLength = 1;
  2357.           *err = U_INDEX_OUTOFBOUNDS_ERROR;
  2358.         }
  2359.     }
  2360.       else
  2361.     {
  2362.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  2363.       break;
  2364.     }
  2365.     }
  2366.  
  2367.   *target += myTargetIndex;
  2368.   *source += mySourceIndex;;
  2369.  
  2370.   return;
  2371. }
  2372.  
  2373. void   T_UConverter_fromUnicode_UTF16_LE (UConverter * _this,
  2374.                       char **target,
  2375.                       const char *targetLimit,
  2376.                       const UChar ** source,
  2377.                       const UChar * sourceLimit,
  2378.                       int32_t *offsets,
  2379.                       bool_t flush,
  2380.                       UErrorCode * err)
  2381. {
  2382.   const UChar *mySource = *source;
  2383.   unsigned char *myTarget = (unsigned char *) *target;
  2384.   int32_t mySourceIndex = 0;
  2385.   int32_t myTargetIndex = 0;
  2386.   int32_t targetLength = targetLimit - (char *) myTarget;
  2387.   int32_t sourceLength = sourceLimit - mySource;
  2388.   UChar mySourceChar;
  2389.  
  2390.  
  2391.   /*writing the char to the output stream */
  2392.   while (mySourceIndex < sourceLength)
  2393.     {
  2394.  
  2395.       if (myTargetIndex < targetLength)
  2396.     {
  2397.       mySourceChar = (UChar) mySource[mySourceIndex++];
  2398.       myTarget[myTargetIndex++] = (char) mySourceChar;
  2399.       if (myTargetIndex < targetLength)
  2400.         {
  2401.           myTarget[myTargetIndex++] = (char) (mySourceChar >> 8);
  2402.         }
  2403.       else
  2404.         {
  2405.           _this->charErrorBuffer[0] = (char) (mySourceChar >> 8);
  2406.           _this->charErrorBufferLength = 1;
  2407.           *err = U_INDEX_OUTOFBOUNDS_ERROR;
  2408.         }
  2409.     }
  2410.       else
  2411.     {
  2412.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  2413.       break;
  2414.     }
  2415.     }
  2416.  
  2417.   *target += myTargetIndex;
  2418.   *source += mySourceIndex;;
  2419.  
  2420.   return;
  2421. }
  2422.  
  2423. void T_UConverter_toUnicode_UTF16_BE (UConverter * _this,
  2424.                       UChar ** target,
  2425.                       const UChar * targetLimit,
  2426.                       const char **source,
  2427.                       const char *sourceLimit,
  2428.                       int32_t *offsets,
  2429.                       bool_t flush,
  2430.                       UErrorCode * err)
  2431. {
  2432.   const unsigned char *mySource = (unsigned char *) *source;
  2433.   UChar *myTarget = *target;
  2434.   int32_t mySourceIndex = 0;
  2435.   int32_t myTargetIndex = 0;
  2436.   int32_t targetLength = targetLimit - myTarget;
  2437.   int32_t sourceLength = sourceLimit - (char *) mySource;
  2438.   UChar mySourceChar = 0x0000;
  2439.   UChar oldmySourceChar = 0x0000;
  2440.  
  2441.  
  2442.   while (mySourceIndex < sourceLength)
  2443.     {
  2444.       if (myTargetIndex < targetLength)
  2445.     {
  2446.       /*gets the corresponding UChar */
  2447.       mySourceChar = (unsigned char) mySource[mySourceIndex++];
  2448.        oldmySourceChar = mySourceChar;
  2449.       if (_this->toUnicodeStatus == 0)
  2450.         {
  2451.           _this->toUnicodeStatus = (unsigned char) mySourceChar == 0x00 ? 0xFFFF : mySourceChar;
  2452.         }
  2453.       else
  2454.         {
  2455.           if (_this->toUnicodeStatus != 0xFFFF)
  2456.         mySourceChar = (UChar) ((_this->toUnicodeStatus << 8) | mySourceChar);
  2457.           _this->toUnicodeStatus = 0;
  2458.  
  2459.  
  2460.  
  2461.           myTarget[myTargetIndex++] = mySourceChar;
  2462.  
  2463.         }
  2464.     }
  2465.       else
  2466.      {
  2467.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  2468.       break;
  2469.     }
  2470.     }
  2471.  
  2472.   if (U_SUCCESS(*err) && flush
  2473.       && (mySourceIndex == sourceLength)
  2474.       && (_this->toUnicodeStatus != 0x00))
  2475.     {
  2476.       if (U_SUCCESS(*err)) 
  2477.     {
  2478.       *err = U_TRUNCATED_CHAR_FOUND;
  2479.       _this->toUnicodeStatus = 0x00;
  2480.     }
  2481.     }
  2482.   
  2483.   *target += myTargetIndex;
  2484.   *source += mySourceIndex;
  2485.  
  2486.   return;
  2487. }
  2488.  
  2489. void  T_UConverter_toUnicode_UTF16_LE (UConverter * _this,
  2490.                        UChar ** target,
  2491.                        const UChar * targetLimit,
  2492.                        const char **source,
  2493.                        const char *sourceLimit,
  2494.                        int32_t *offsets,
  2495.                        bool_t flush,
  2496.                        UErrorCode * err)
  2497. {
  2498.   const unsigned char *mySource = (unsigned char *) *source;
  2499.   UChar *myTarget = *target;
  2500.   int32_t mySourceIndex = 0;
  2501.   int32_t myTargetIndex = 0;
  2502.   int32_t targetLength = targetLimit - myTarget;
  2503.   int32_t sourceLength = sourceLimit - (char *) mySource;
  2504.   CompactShortArray *myToUnicode = NULL;
  2505.   UChar targetUniChar = 0x0000;
  2506.   UChar mySourceChar = 0x0000;
  2507.  
  2508.   while (mySourceIndex < sourceLength)
  2509.     {
  2510.       if (myTargetIndex < targetLength)
  2511.     {
  2512.       /*gets the corresponding UniChar */
  2513.       mySourceChar = (unsigned char) mySource[mySourceIndex++];
  2514.  
  2515.       if (_this->toUnicodeStatus == 0x00)
  2516.         {
  2517.           _this->toUnicodeStatus = (unsigned char) mySourceChar == 0x00 ? 0xFFFF : mySourceChar;
  2518.         }
  2519.       else
  2520.         {
  2521.           if (_this->toUnicodeStatus == 0xFFFF)
  2522.         mySourceChar = (UChar) (mySourceChar << 8);
  2523.           else
  2524.         {
  2525.           mySourceChar <<= 8;
  2526.           mySourceChar |= (UChar) (_this->toUnicodeStatus);
  2527.         }
  2528.           _this->toUnicodeStatus = 0x00;
  2529.           myTarget[myTargetIndex++] = mySourceChar;
  2530.         }
  2531.     }
  2532.       else
  2533.     {
  2534.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  2535.       break;
  2536.     }
  2537.     }
  2538.  
  2539.  
  2540.   if (U_SUCCESS(*err) && flush
  2541.       && (mySourceIndex == sourceLength)
  2542.       && (_this->toUnicodeStatus != 0x00))
  2543.     {
  2544.       if (U_SUCCESS(*err)) 
  2545.     {
  2546.       *err = U_TRUNCATED_CHAR_FOUND; 
  2547.       _this->toUnicodeStatus = 0x00;
  2548.     }
  2549.     }
  2550.   
  2551.   *target += myTargetIndex;
  2552.   *source += mySourceIndex;
  2553.   
  2554.  
  2555.   return;
  2556. }
  2557.  
  2558. void T_UConverter_toUnicode_UTF8 (UConverter * _this,
  2559.                   UChar ** target,
  2560.                   const UChar * targetLimit,
  2561.                   const char **source,
  2562.                   const char *sourceLimit,
  2563.                   int32_t *offsets,
  2564.                   bool_t flush,
  2565.                   UErrorCode * err)
  2566. {
  2567.   const unsigned char *mySource = (unsigned char *) *source;
  2568.   UChar *myTarget = *target;
  2569.   int32_t mySourceIndex = 0;
  2570.   int32_t myTargetIndex = 0;
  2571.   int32_t targetLength = targetLimit - myTarget;
  2572.   int32_t sourceLength = sourceLimit - (char *) mySource;
  2573.   uint32_t ch = 0 ,
  2574.            ch2 =0 ,
  2575.            i =0;            /* Index into the current # of bytes consumed in the current sequence */
  2576.   uint32_t inBytes = 0;  /* Total number of bytes in the current UTF8 sequence */
  2577.   
  2578.   if (_this->toUnicodeStatus)
  2579.     {
  2580.       i = _this->invalidCharLength;   /* restore # of bytes consumed */
  2581.       inBytes = _this->toUnicodeStatus; /* Restore size of current sequence */
  2582.  
  2583.       ch = _this->mode; /*Stores the previously calculated ch from a previous call*/
  2584.       _this->toUnicodeStatus = 0;
  2585.       _this->invalidCharLength = 0;
  2586.       goto morebytes;
  2587.     }
  2588.  
  2589.  
  2590.   while (mySourceIndex < sourceLength)
  2591.     {
  2592.       if (myTargetIndex < targetLength)
  2593.     {
  2594.       ch = 0;
  2595.       ch = ((uint32_t)mySource[mySourceIndex++]) & 0x000000FF;
  2596.       if (ch < 0x80)    /* Simple case */
  2597.         {
  2598.           myTarget[myTargetIndex++] = (UChar) ch;
  2599.         }
  2600.       else
  2601.         {
  2602.           /* store the first char */
  2603.  
  2604.           inBytes = bytesFromUTF8[ch]; /* lookup current sequence length */
  2605.           _this->invalidCharBuffer[0] = (char)ch;
  2606.           i = 1;
  2607.  
  2608.         morebytes:
  2609.           for (; i < inBytes; i++)
  2610.         {
  2611.           {
  2612.             if (mySourceIndex >= sourceLength)
  2613.               {
  2614.             if (flush)
  2615.               {
  2616.                 if (U_SUCCESS(*err)) 
  2617.                   {
  2618.                 *err = U_TRUNCATED_CHAR_FOUND;
  2619.                 _this->toUnicodeStatus = 0x00;
  2620.                   }
  2621.               }
  2622.             else
  2623.               {
  2624.                 _this->toUnicodeStatus = inBytes;
  2625.                 _this->invalidCharLength = (int8_t)i;
  2626.               }
  2627.             goto donefornow;
  2628.               }
  2629.             _this->invalidCharBuffer[i] = (char) (ch2 = (((uint32_t)mySource[mySourceIndex++]) & 0x000000FF));
  2630.             if ((ch2 & 0xC0) != 0x80)    /* Invalid trailing byte */
  2631.               break;
  2632.           }
  2633.           ch <<= 6;
  2634.           ch += ch2;
  2635.         }
  2636.  
  2637.  
  2638.           ch -= offsetsFromUTF8[inBytes];
  2639.  
  2640.           if (i == inBytes && ch <= kMaximumUTF16) 
  2641.         {
  2642.           if (ch <= kMaximumUCS2) 
  2643.             {
  2644.               myTarget[myTargetIndex++] = (UChar) ch;
  2645.             }
  2646.           else
  2647.             {
  2648.               ch -= halfBase;
  2649.               myTarget[myTargetIndex++] = (UChar) ((ch >> halfShift) + kSurrogateHighStart);
  2650.               ch = (ch & halfMask) + kSurrogateLowStart;
  2651.               if (myTargetIndex < targetLength)
  2652.             {
  2653.               myTarget[myTargetIndex++] = (char)ch;
  2654.             }
  2655.               else
  2656.             {
  2657.               _this->invalidUCharBuffer[0] = (UChar) ch;
  2658.               _this->invalidUCharLength = 1;
  2659.               *err = U_INDEX_OUTOFBOUNDS_ERROR;
  2660.             }
  2661.             }
  2662.         }
  2663.           else
  2664.         {
  2665.           *err = U_ILLEGAL_CHAR_FOUND;
  2666.           _this->invalidCharLength = (int8_t)i;
  2667.           
  2668. #ifdef Debug
  2669.           printf("inbytes %d\n, _this->invalidCharLength = %d,\n mySource[mySourceIndex]=%X\n", inBytes, _this->invalidCharLength, mySource[mySourceIndex]);
  2670. #endif
  2671. /* Needed explicit cast for mySource on MVS to make compiler happy - JJD */
  2672.           ToU_CALLBACK_MACRO(_this,
  2673.                      myTarget,
  2674.                      myTargetIndex, 
  2675.                      targetLimit,
  2676.                      (const char *)mySource, 
  2677.                      mySourceIndex,
  2678.                      sourceLimit,
  2679.                      offsets,
  2680.                      flush,
  2681.                      err);
  2682.           if (U_FAILURE (*err))   break;
  2683.           _this->invalidCharLength = 0;
  2684.         }
  2685.         }
  2686.     }
  2687.       else
  2688.     /* End of target buffer */
  2689.     {
  2690.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  2691.       break;
  2692.     }
  2693.     }
  2694.  
  2695. donefornow:
  2696.   *target += myTargetIndex;
  2697.   *source += mySourceIndex;
  2698.   _this->mode = ch; /*stores a partially calculated target*/
  2699. }
  2700.  
  2701. void T_UConverter_toUnicode_UTF8_OFFSETS_LOGIC (UConverter * _this,
  2702.                         UChar ** target,
  2703.                         const UChar * targetLimit,
  2704.                         const char **source,
  2705.                         const char *sourceLimit,
  2706.                         int32_t *offsets,
  2707.                         bool_t flush,
  2708.                         UErrorCode * err)
  2709. {
  2710.   const unsigned char *mySource = (unsigned char *) *source;
  2711.   UChar *myTarget = *target;
  2712.   int32_t mySourceIndex = 0;
  2713.   int32_t myTargetIndex = 0;
  2714.   int32_t targetLength = targetLimit - myTarget;
  2715.   int32_t sourceLength = sourceLimit - (char *) mySource;
  2716.   uint32_t ch = 0, ch2 = 0, i = 0;
  2717.   uint32_t inBytes = 0;
  2718.   int32_t* originalOffsets = offsets;
  2719.  
  2720.  
  2721.   
  2722.   if (_this->toUnicodeStatus)
  2723.     {
  2724.       i = _this->invalidCharLength;
  2725.       inBytes = _this->toUnicodeStatus;
  2726.       _this->toUnicodeStatus = 0;
  2727.       ch = _this->mode;
  2728.       goto morebytes;
  2729.     }
  2730.  
  2731.   while (mySourceIndex < sourceLength)
  2732.     {
  2733.       if (myTargetIndex < targetLength)
  2734.     {
  2735.       ch = mySource[mySourceIndex++];
  2736.       if (ch < 0x80)    /* Simple case */
  2737.         {
  2738.            offsets[myTargetIndex] = mySourceIndex-1;
  2739.           myTarget[myTargetIndex++] = (UChar) ch;
  2740.         }
  2741.       else
  2742.         {
  2743.           inBytes = bytesFromUTF8[ch];
  2744.           _this->invalidCharBuffer[0] = (char)ch;
  2745.           i = 1;
  2746.  
  2747.         morebytes:
  2748.           for (; i < inBytes; i++)
  2749.         {
  2750.           {
  2751.             if (mySourceIndex >= sourceLength)
  2752.               {
  2753.             if (flush)
  2754.               {
  2755.                 if (U_SUCCESS(*err)) 
  2756.                   {
  2757.                 *err = U_TRUNCATED_CHAR_FOUND;
  2758.                 _this->toUnicodeStatus = 0x00;
  2759.                   }
  2760.               }
  2761.             else
  2762.               {
  2763.                 _this->toUnicodeStatus = inBytes;
  2764.                 _this->invalidCharLength = (int8_t)i;
  2765.               }
  2766.             goto donefornow;
  2767.               }
  2768.             _this->invalidCharBuffer[i] = (char) (ch2 = mySource[mySourceIndex++]);
  2769.             if ((ch2 & 0xC0) != 0x80)    /* Invalid trailing byte */
  2770.               break;
  2771.           }
  2772.           ch <<= 6;
  2773.           ch += ch2;
  2774.         }
  2775.  
  2776.           ch -= offsetsFromUTF8[inBytes];
  2777.           if (i == inBytes && ch <= kMaximumUTF16)
  2778.         {
  2779.           if (ch <= kMaximumUCS2) {
  2780.  
  2781.              offsets[myTargetIndex] = mySourceIndex-3;
  2782.             myTarget[myTargetIndex++] = (UChar) ch;
  2783.  
  2784.           }
  2785.           else
  2786.             {
  2787.               ch -= halfBase;
  2788.                offsets[myTargetIndex] = mySourceIndex-4;
  2789.               myTarget[myTargetIndex++] = (UChar) ((ch >> halfShift) + kSurrogateHighStart);
  2790.               ch = (ch & halfMask) + kSurrogateLowStart;
  2791.               if (myTargetIndex < targetLength)
  2792.             {
  2793.                offsets[myTargetIndex] = mySourceIndex-4;
  2794.               myTarget[myTargetIndex++] = (char)ch;
  2795.             }
  2796.               else
  2797.             {
  2798.               _this->invalidUCharBuffer[0] = (UChar) ch;
  2799.               _this->invalidUCharLength = 1;
  2800.               *err = U_INDEX_OUTOFBOUNDS_ERROR;
  2801.             }
  2802.             }
  2803.         }
  2804.           else
  2805.         {
  2806.           int32_t currentOffset = offsets[myTargetIndex-1];
  2807.  
  2808.           *err = U_ILLEGAL_CHAR_FOUND;
  2809.           _this->invalidCharLength = (int8_t)i;
  2810.           
  2811. /* Needed explicit cast for mySource on MVS to make compiler happy - JJD */
  2812.           ToU_CALLBACK_OFFSETS_LOGIC_MACRO(_this,
  2813.                            myTarget,
  2814.                            myTargetIndex, 
  2815.                            targetLimit,
  2816.                            (const char *)mySource, 
  2817.                            mySourceIndex,
  2818.                            sourceLimit,
  2819.                            offsets,
  2820.                            flush,
  2821.                            err);
  2822.  
  2823.           
  2824.           if (U_FAILURE (*err))   break;
  2825.           _this->invalidCharLength = 0;
  2826.         }
  2827.         }
  2828.     }
  2829.       else
  2830.     /* End of target buffer */
  2831.     {
  2832.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  2833.       break;
  2834.     }
  2835.     }
  2836.  
  2837. donefornow:
  2838.   *target += myTargetIndex;
  2839.   *source += mySourceIndex;
  2840.   _this->mode = ch;
  2841.  
  2842. }
  2843.  
  2844. /*Empties the internal unicode output buffer */
  2845. void  flushInternalUnicodeBuffer (UConverter * _this,
  2846.                   UChar * myTarget,
  2847.                   int32_t * myTargetIndex,
  2848.                   int32_t targetLength,
  2849.                   int32_t** offsets,
  2850.                   UErrorCode * err)
  2851. {
  2852.   int32_t myUCharErrorBufferLength = _this->UCharErrorBufferLength;
  2853.  
  2854.   if (myUCharErrorBufferLength <= targetLength)
  2855.     {
  2856.       /*we have enough space
  2857.        *So we just copy the whole Error Buffer in to the output stream*/
  2858.       icu_memcpy (myTarget,
  2859.           _this->UCharErrorBuffer,
  2860.           sizeof (UChar) * myUCharErrorBufferLength);
  2861.       if (offsets) 
  2862.     {
  2863.       int32_t i=0;
  2864.       for (i=0; i<myUCharErrorBufferLength;i++) (*offsets)[i] = -1; 
  2865.       *offsets += myUCharErrorBufferLength;
  2866.     }
  2867.       *myTargetIndex += myUCharErrorBufferLength;
  2868.       _this->UCharErrorBufferLength = 0;
  2869.     }
  2870.   else
  2871.     {
  2872.       /* We don't have enough space so we copy as much as we can
  2873.        * on the output stream and update the object
  2874.        * by updating the internal buffer*/
  2875.       icu_memcpy (myTarget, _this->UCharErrorBuffer, sizeof (UChar) * targetLength);
  2876.       if (offsets) 
  2877.     {
  2878.       int32_t i=0;
  2879.       for (i=0; i< targetLength;i++) (*offsets)[i] = -1; 
  2880.       *offsets += targetLength;
  2881.     }
  2882.       icu_memmove (_this->UCharErrorBuffer,
  2883.            _this->UCharErrorBuffer + targetLength,
  2884.            sizeof (UChar) * (myUCharErrorBufferLength - targetLength));
  2885.       _this->UCharErrorBufferLength -= (int8_t) targetLength;
  2886.       *myTargetIndex = targetLength;
  2887.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  2888.     }
  2889.  
  2890.   return;
  2891. }
  2892.  
  2893. /*Empties the internal codepage output buffer */
  2894. void  flushInternalCharBuffer (UConverter * _this,
  2895.                    char *myTarget,
  2896.                    int32_t * myTargetIndex,
  2897.                    int32_t targetLength,
  2898.                    int32_t** offsets,
  2899.                    UErrorCode * err)
  2900. {
  2901.   int32_t myCharErrorBufferLength = _this->charErrorBufferLength;
  2902.  
  2903.   /*we have enough space */
  2904.   if (myCharErrorBufferLength <= targetLength)
  2905.     {
  2906.       icu_memcpy (myTarget, _this->charErrorBuffer, myCharErrorBufferLength);
  2907.       if (offsets) 
  2908.     {
  2909.       int32_t i=0;
  2910.       for (i=0; i<myCharErrorBufferLength;i++) (*offsets)[i] = -1; 
  2911.       *offsets += myCharErrorBufferLength;
  2912.     }
  2913.  
  2914.       *myTargetIndex += myCharErrorBufferLength;
  2915.       _this->charErrorBufferLength = 0;
  2916.     }
  2917.   else
  2918.     /* We don't have enough space so we copy as much as we can
  2919.      * on the output stream and update the object*/
  2920.     {
  2921.       icu_memcpy (myTarget, _this->charErrorBuffer, targetLength);
  2922.       if (offsets) 
  2923.     {
  2924.       int32_t i=0;
  2925.       for (i=0; i< targetLength;i++) (*offsets)[i] = -1; 
  2926.       *offsets += targetLength;
  2927.     }
  2928.       icu_memmove (_this->charErrorBuffer,
  2929.            _this->charErrorBuffer + targetLength,
  2930.            (myCharErrorBufferLength - targetLength));
  2931.       _this->charErrorBufferLength -= (int8_t) targetLength;
  2932.       *myTargetIndex = targetLength;
  2933.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  2934.     }
  2935.  
  2936.   return;
  2937. }
  2938.  
  2939.  
  2940.  
  2941. UChar T_UConverter_getNextUChar_SBCS(UConverter* converter,
  2942.                            const char** source,
  2943.                            const char* sourceLimit,
  2944.                            UErrorCode* err)
  2945. {
  2946.   UChar myUChar;
  2947.  
  2948.   
  2949.   if ((*source)+1 > sourceLimit) 
  2950.     {
  2951.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  2952.       return 0xFFFD;
  2953.     }
  2954.   
  2955.   
  2956.   /*Gets the corresponding codepoint*/
  2957.   myUChar = converter->sharedData->table->sbcs.toUnicode[(unsigned char)*((*source)++)];
  2958.   
  2959.   if (myUChar != 0xFFFD) return myUChar;
  2960.   else
  2961.     {      
  2962.       UChar* myUCharPtr = &myUChar;
  2963.       const char* sourceFinal = *source;
  2964.       
  2965.       *err = U_INVALID_CHAR_FOUND;
  2966.       
  2967.       /*Calls the ErrorFunctor after rewinding the input buffer*/
  2968.       (*source)--;
  2969.       /*It's is very likely that the ErrorFunctor will write to the
  2970.        *internal buffers */
  2971.       converter->fromCharErrorBehaviour(converter,
  2972.                     &myUCharPtr,
  2973.                     myUCharPtr + 1,
  2974.                     &sourceFinal,
  2975.                     sourceLimit,
  2976.                     NULL,
  2977.                     TRUE,
  2978.                     err);
  2979.  
  2980.       /*makes the internal caching transparent to the user*/
  2981.       if (*err == U_INDEX_OUTOFBOUNDS_ERROR) *err = U_ZERO_ERROR;
  2982.       
  2983.       return myUChar;
  2984.     }
  2985. }
  2986.  
  2987. UChar T_UConverter_getNextUChar_LATIN_1(UConverter* converter,
  2988.                           const char** source,
  2989.                           const char* sourceLimit,
  2990.                           UErrorCode* err)
  2991. {
  2992.   
  2993.   /* Empties the internal buffers if need be
  2994.    * In this case since ErrorFunctors are never called 
  2995.    * (LATIN_1 is a subset of Unicode)
  2996.    */
  2997.   
  2998.   if ((*source)+1 > sourceLimit) 
  2999.     {
  3000.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  3001.       return 0xFFFD;
  3002.     }
  3003.   
  3004.   return  (UChar)*((*source)++);
  3005. }
  3006.  
  3007. UChar T_UConverter_getNextUChar_ISO_2022(UConverter* converter,
  3008.                      const char** source,
  3009.                      const char* sourceLimit,
  3010.                      UErrorCode* err)
  3011. {
  3012.   const char* mySourceLimit;
  3013.   /*Arguments Check*/
  3014.   if  (sourceLimit < *source)
  3015.     {
  3016.       *err = U_ILLEGAL_ARGUMENT_ERROR;
  3017.       return 0xFFFD;
  3018.     }
  3019.   
  3020.   for (;;)
  3021.     {
  3022.       mySourceLimit =  getEndOfBuffer_2022(*source, sourceLimit, TRUE); 
  3023.       /*Find the end of the buffer e.g : Next Escape Seq | end of Buffer*/
  3024.       if (converter->mode == UCNV_SO) /*Already doing some conversion*/
  3025.     {
  3026.       
  3027.       return ucnv_getNextUChar(((UConverterDataISO2022*)(converter->extraInfo))->currentConverter,
  3028.                    source,
  3029.                    mySourceLimit,
  3030.                    err);
  3031.       
  3032.  
  3033.     }
  3034.       /*-Done with buffer with entire buffer
  3035.     -Error while converting
  3036.       */
  3037.       
  3038.  
  3039.       changeState_2022(converter,
  3040.                source, 
  3041.                sourceLimit,
  3042.                TRUE,
  3043.                err);
  3044.       (*source)++;
  3045.     }
  3046.   
  3047.   return 0xFFFD;
  3048. }
  3049.  
  3050. UChar T_UConverter_getNextUChar_DBCS(UConverter* converter,
  3051.                            const char** source,
  3052.                            const char* sourceLimit,
  3053.                            UErrorCode* err)
  3054. {
  3055.   UChar myUChar;
  3056.   
  3057.   /*Checks boundaries and set appropriate error codes*/
  3058.   if ((*source)+2 > sourceLimit) 
  3059.     {
  3060.       if ((*source) >= sourceLimit)
  3061.     {
  3062.       /*Either caller has reached the end of the byte stream*/
  3063.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  3064.     }
  3065.       else if (((*source)+1) == sourceLimit)
  3066.     {
  3067.       /* a character was cut in half*/
  3068.       *err = U_TRUNCATED_CHAR_FOUND;
  3069.     }
  3070.       
  3071.       return 0xFFFD;
  3072.     }
  3073.   
  3074.   /*Gets the corresponding codepoint*/
  3075.   myUChar = ucmp16_getu(converter->sharedData->table->dbcs.toUnicode,
  3076.             ((UChar)((**source)) << 8) |((uint8_t)*((*source)+1)));
  3077.   
  3078.   /*update the input pointer*/
  3079.   *source += 2;
  3080.   if (myUChar != 0xFFFD) return myUChar;
  3081.   else
  3082.     {      
  3083.       UChar* myUCharPtr = &myUChar;
  3084.       const char* sourceFinal = *source;
  3085.  
  3086.       /*Calls the ErrorFunctor after rewinding the input buffer*/
  3087.       (*source) -= 2;
  3088.       
  3089.       *err = U_INVALID_CHAR_FOUND;
  3090.     
  3091.       /*It's is very likely that the ErrorFunctor will write to the
  3092.        *internal buffers */
  3093.       converter->fromCharErrorBehaviour(converter,
  3094.                     &myUCharPtr,
  3095.                     myUCharPtr + 1,
  3096.                     &sourceFinal,
  3097.                     sourceLimit,
  3098.                     NULL,
  3099.                     TRUE,
  3100.                     err);
  3101.       /*makes the internal caching transparent to the user*/
  3102.       if (*err == U_INDEX_OUTOFBOUNDS_ERROR) *err = U_ZERO_ERROR;
  3103.  
  3104.       return myUChar;
  3105.     }
  3106.  
  3107. UChar T_UConverter_getNextUChar_MBCS(UConverter* converter,
  3108.                            const char** source,
  3109.                            const char* sourceLimit,
  3110.                            UErrorCode* err)
  3111. {
  3112.   UChar myUChar;
  3113.   char const *sourceInitial = *source;
  3114.   /*safe keeps a ptr to the beginning in case we need to step back*/
  3115.   
  3116.   /*Input boundary check*/
  3117.   if ((*source)+1 > sourceLimit) 
  3118.     {
  3119.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  3120.       return 0xFFFD;
  3121.     }
  3122.   
  3123.   /*Checks to see if the byte is a lead*/
  3124.   if (converter->sharedData->table->mbcs.starters[(uint8_t)**source] == FALSE)
  3125.     {
  3126.       /*Not lead byte: we update the source ptr and get the codepoint*/
  3127.       myUChar = ucmp16_getu(converter->sharedData->table->mbcs.toUnicode,
  3128.                 (UChar)(**source));
  3129.       (*source)++;
  3130.     }
  3131.   else
  3132.     {
  3133.       /*Lead byte: we Build the codepoint and get the corresponding character
  3134.        * and update the source ptr*/
  3135.       if ((*source + 2) > sourceLimit) 
  3136.     {
  3137.       *err = U_TRUNCATED_CHAR_FOUND;
  3138.       return 0xFFFD;
  3139.     }
  3140.  
  3141.       myUChar = ucmp16_getu(converter->sharedData->table->mbcs.toUnicode,
  3142.                 ((UChar)((**source)) << 8) |((uint8_t)*((*source)+1)));
  3143.  
  3144.       (*source) += 2;
  3145.     }
  3146.   
  3147.   if (myUChar != 0xFFFD) return myUChar;
  3148.   else
  3149.     {      
  3150.       /*rewinds source*/
  3151.       const char* sourceFinal = *source;
  3152.       UChar* myUCharPtr = &myUChar;
  3153.       
  3154.       *err = U_INVALID_CHAR_FOUND;
  3155.       *source = sourceInitial;
  3156.       
  3157.       /*It's is very likely that the ErrorFunctor will write to the
  3158.        *internal buffers */
  3159.       converter->fromCharErrorBehaviour(converter,
  3160.                     &myUCharPtr,
  3161.                     myUCharPtr + 1,
  3162.                     &sourceFinal,
  3163.                     sourceLimit,
  3164.                     NULL,
  3165.                     TRUE,
  3166.                     err);
  3167.       
  3168.       /*makes the internal caching transparent to the user*/
  3169.       if (*err == U_INDEX_OUTOFBOUNDS_ERROR) *err = U_ZERO_ERROR;
  3170.       
  3171.       return myUChar;
  3172.     }
  3173.  
  3174. UChar T_UConverter_getNextUChar_EBCDIC_STATEFUL(UConverter* converter,
  3175.                         const char** source,
  3176.                         const char* sourceLimit,
  3177.                         UErrorCode* err)
  3178. {
  3179.   UChar myUChar;
  3180.   char const *sourceInitial = *source;
  3181.   /*safe keeps a ptr to the beginning in case we need to step back*/
  3182.   
  3183.   /*Input boundary check*/
  3184.   if ((*source)+1 > sourceLimit) 
  3185.     {
  3186.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  3187.       return 0xFFFD;
  3188.     }
  3189.   
  3190.   /*Checks to see if with have SI/SO shifters
  3191.    if we do we change the mode appropriately and we consume the byte*/
  3192.   if ((**source == UCNV_SI) || (**source == UCNV_SO)) 
  3193.     {
  3194.       converter->mode = **source;
  3195.       (*source)++;
  3196.       
  3197.       /*Rechecks boundary after consuming the shift sequence*/
  3198.       if ((*source)+1 > sourceLimit) 
  3199.     {
  3200.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  3201.       return 0xFFFD;
  3202.     }
  3203.     }
  3204.   
  3205.   if (converter->mode == UCNV_SI)
  3206.     {
  3207.       /*Not lead byte: we update the source ptr and get the codepoint*/
  3208.       myUChar = ucmp16_getu(converter->sharedData->table->dbcs.toUnicode,
  3209.                 (UChar)(**source));
  3210.       (*source)++;
  3211.     }
  3212.   else
  3213.     {
  3214.       /*Lead byte: we Build the codepoint and get the corresponding character
  3215.        * and update the source ptr*/
  3216.       if ((*source + 2) > sourceLimit) 
  3217.     {
  3218.       *err = U_TRUNCATED_CHAR_FOUND;
  3219.       return 0xFFFD;
  3220.     }
  3221.  
  3222.       myUChar = ucmp16_getu(converter->sharedData->table->dbcs.toUnicode,
  3223.                 ((UChar)((**source)) << 8) |((uint8_t)*((*source)+1)));
  3224.  
  3225.       (*source) += 2;
  3226.     }
  3227.   
  3228.   if (myUChar != 0xFFFD) return myUChar;
  3229.   else
  3230.     {      
  3231.       /*rewinds source*/
  3232.       const char* sourceFinal = *source;
  3233.       UChar* myUCharPtr = &myUChar;
  3234.       
  3235.       *err = U_INVALID_CHAR_FOUND;
  3236.       *source = sourceInitial;
  3237.       
  3238.       /*It's is very likely that the ErrorFunctor will write to the
  3239.        *internal buffers */
  3240.       converter->fromCharErrorBehaviour(converter,
  3241.                     &myUCharPtr,
  3242.                     myUCharPtr + 1,
  3243.                     &sourceFinal,
  3244.                     sourceLimit,
  3245.                     NULL,
  3246.                     TRUE,
  3247.                     err);
  3248.       
  3249.       /*makes the internal caching transparent to the user*/
  3250.       if (*err == U_INDEX_OUTOFBOUNDS_ERROR) *err = U_ZERO_ERROR;
  3251.       
  3252.       return myUChar;
  3253.     }
  3254.  
  3255. UChar T_UConverter_getNextUChar_UTF16_BE(UConverter* converter,
  3256.                            const char** source,
  3257.                            const char* sourceLimit,
  3258.                            UErrorCode* err)
  3259. {
  3260.   UChar myUChar;
  3261.   /*Checks boundaries and set appropriate error codes*/
  3262.   if ((*source)+2 > sourceLimit) 
  3263.     {
  3264.       if ((*source) >= sourceLimit)
  3265.     {
  3266.       /*Either caller has reached the end of the byte stream*/
  3267.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  3268.     }
  3269.       else if (((*source)+1) == sourceLimit)
  3270.     {
  3271.       /* a character was cut in half*/
  3272.       *err = U_TRUNCATED_CHAR_FOUND;
  3273.     }
  3274.       
  3275.       return 0xFFFD;
  3276.     }
  3277.   
  3278.   
  3279.   /*Gets the corresponding codepoint*/
  3280.  
  3281.   myUChar = ((uint16_t)((**source)) << 8) |((uint8_t)*((*source)+1));
  3282.   *source += 2;
  3283.   return myUChar;
  3284.  
  3285.  
  3286. UChar T_UConverter_getNextUChar_UTF16_LE(UConverter* converter,
  3287.                            const char** source,
  3288.                            const char* sourceLimit,
  3289.                            UErrorCode* err)
  3290. {
  3291.   UChar myUChar;
  3292.   /*Checks boundaries and set appropriate error codes*/
  3293.   if ((*source)+2 > sourceLimit) 
  3294.     {
  3295.       if ((*source) >= sourceLimit)
  3296.     {
  3297.       /*Either caller has reached the end of the byte stream*/
  3298.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  3299.     }
  3300.       else if (((*source)+1) == sourceLimit)
  3301.     {
  3302.       /* a character was cut in half*/
  3303.       *err = U_TRUNCATED_CHAR_FOUND;
  3304.     }
  3305.       
  3306.       return 0xFFFD;
  3307.     }
  3308.   
  3309.  
  3310.   /*Gets the corresponding codepoint*/
  3311.   myUChar =  ((uint16_t)*((*source)+1) << 8) |((uint8_t)((**source)));
  3312.   /*updates the source*/
  3313.   *source += 2;  
  3314.   return myUChar;
  3315.  
  3316. UChar T_UConverter_getNextUChar_UTF8(UConverter* converter,
  3317.                            const char** source,
  3318.                            const char* sourceLimit,
  3319.                            UErrorCode* err)
  3320. {
  3321.   UChar myUChar;
  3322.   /*safe keeps a ptr to the beginning in case we need to step back*/
  3323.   char const *sourceInitial = *source;
  3324.   uint16_t extraBytesToWrite = 1;
  3325.   uint8_t myByte;
  3326.   uint32_t ch = 0x00000000;
  3327.   int8_t isLegalSequence = 1;
  3328.  
  3329.   /*Input boundary check*/
  3330.   if ((*source)+1 > sourceLimit) 
  3331.     {
  3332.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  3333.       return 0xFFFD;
  3334.     }
  3335.   
  3336.   
  3337.   extraBytesToWrite = (uint16_t)bytesFromUTF8[(uint8_t)**source];
  3338.  
  3339.   if (extraBytesToWrite > 4) goto CALL_ERROR_FUNCTION;
  3340.   
  3341.  
  3342.   /*The byte sequence is longer than the buffer area passed*/
  3343.  
  3344.   if ((*source + extraBytesToWrite) > sourceLimit)
  3345.     {
  3346.       *err = U_TRUNCATED_CHAR_FOUND;
  3347.       return 0xFFFD;
  3348.     }
  3349.   else
  3350.     {
  3351.       switch(extraBytesToWrite)
  3352.     {     
  3353.       /* note: code falls through cases! (sic)*/ 
  3354.     case 5: ch += *((*source)++); ch <<= 6;
  3355.     case 4: ch += (myByte = (uint8_t)*((*source)++)); ch <<= 6;
  3356.       if ((myByte & 0xC0) == 0) 
  3357.         {
  3358.           isLegalSequence = 0;
  3359.           break;
  3360.         }
  3361.     case 3: ch += (myByte = *((*source)++)); ch <<= 6;
  3362.       if ((myByte & 0xC0) == 0) 
  3363.         {
  3364.           isLegalSequence = 0;
  3365.           break;
  3366.         }
  3367.     case 2: ch += (myByte = *((*source)++)); ch <<= 6;
  3368.       if ((myByte & 0xC0) == 0) 
  3369.         {
  3370.           isLegalSequence = 0;
  3371.           break;
  3372.         }
  3373.     case 1: ch += (myByte = *((*source)++)); ch <<= 6;
  3374.       if ((myByte & 0xC0) == 0) 
  3375.         {
  3376.           isLegalSequence = 0;
  3377.           break;
  3378.         }
  3379.     case 0: ch += (myByte = *((*source)++));
  3380.       if ((myByte & 0xC0) == 0) 
  3381.         {
  3382.           isLegalSequence = 0;
  3383.         }
  3384.     };
  3385.     }
  3386.   ch -= offsetsFromUTF8[extraBytesToWrite];
  3387.  
  3388.   
  3389.   if (isLegalSequence == 0) goto CALL_ERROR_FUNCTION;
  3390.   
  3391.   /*we got a UCS-2 Character*/
  3392.   if (ch <= kMaximumUCS2)  return (UChar)ch;
  3393.   /*character out of bounds*/
  3394.   else if (ch >= kMaximumUTF16)      goto CALL_ERROR_FUNCTION;
  3395.   /*Surrogates found*/
  3396.   else 
  3397.     {
  3398.       ch -= halfBase;
  3399.       /*stores the 2nd surrogate inside the converter for the next call*/
  3400.       converter->UCharErrorBuffer[0] = (UChar)((ch >> halfShift) + kSurrogateHighStart);
  3401.       converter->UCharErrorBufferLength = 1;
  3402.       
  3403.       /*returns the 1st surrogate*/
  3404.       return  (UChar)((ch & halfMask) + kSurrogateLowStart);
  3405.     }
  3406.   
  3407.   
  3408.  CALL_ERROR_FUNCTION:
  3409.   {      
  3410.     /*rewinds source*/
  3411.     const char* sourceFinal = *source;
  3412.     UChar* myUCharPtr = &myUChar;
  3413.     
  3414.     *err = U_ILLEGAL_CHAR_FOUND;
  3415.     *source = sourceInitial;
  3416.     
  3417.     /*It's is very likely that the ErrorFunctor will write to the
  3418.      *internal buffers */
  3419.     converter->fromCharErrorBehaviour(converter,
  3420.                       &myUCharPtr,
  3421.                       myUCharPtr + 1,
  3422.                       &sourceFinal,
  3423.                       sourceLimit,
  3424.                       NULL,
  3425.                       TRUE,
  3426.                       err);
  3427.     
  3428.     /*makes the internal caching transparent to the user*/
  3429.     if (*err == U_INDEX_OUTOFBOUNDS_ERROR) *err = U_ZERO_ERROR;
  3430.     
  3431.     return myUChar;
  3432.   }
  3433.