Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

ucnv_cnv.c

00001 /*
00002 *******************************************************************************
00003 *
00004 *   Copyright (C) 2000, International Business Machines
00005 *   Corporation and others.  All Rights Reserved.
00006 *
00007 *******************************************************************************
00008 *
00009 *   uconv_cnv.c:
00010 *   Implements all the low level conversion functions
00011 *   T_UnicodeConverter_{to,from}Unicode_$ConversionType
00012 *
00013 *   Change history:
00014 *
00015 *   06/29/2000  helena      Major rewrite of the callback APIs.
00016 */
00017 
00018 #include "unicode/utypes.h"
00019 #include "unicode/ucnv_err.h"
00020 #include "ucnv_cnv.h"
00021 #include "unicode/ucnv.h"
00022 #include "cmemory.h"
00023 
00024 /*Empties the internal unicode output buffer */
00025 void  flushInternalUnicodeBuffer (UConverter * _this,
00026                                   UChar * myTarget,
00027                                   int32_t * myTargetIndex,
00028                                   int32_t targetLength,
00029                                   int32_t** offsets,
00030                                   UErrorCode * err)
00031 {
00032   int32_t myUCharErrorBufferLength = _this->UCharErrorBufferLength;
00033 
00034   if (myUCharErrorBufferLength <= targetLength)
00035     {
00036       /*we have enough space
00037        *So we just copy the whole Error Buffer in to the output stream*/
00038       uprv_memcpy (myTarget,
00039                   _this->UCharErrorBuffer,
00040                   sizeof (UChar) * myUCharErrorBufferLength);
00041       if (offsets) 
00042         {
00043           int32_t i=0;
00044           for (i=0; i<myUCharErrorBufferLength;i++) (*offsets)[i] = -1; 
00045           *offsets += myUCharErrorBufferLength;
00046         }
00047       *myTargetIndex += myUCharErrorBufferLength;
00048       _this->UCharErrorBufferLength = 0;
00049     }
00050   else
00051     {
00052       /* We don't have enough space so we copy as much as we can
00053        * on the output stream and update the object
00054        * by updating the internal buffer*/
00055       uprv_memcpy (myTarget, _this->UCharErrorBuffer, sizeof (UChar) * targetLength);
00056       if (offsets) 
00057         {
00058           int32_t i=0;
00059           for (i=0; i< targetLength;i++) (*offsets)[i] = -1; 
00060           *offsets += targetLength;
00061         }
00062       uprv_memmove (_this->UCharErrorBuffer,
00063                    _this->UCharErrorBuffer + targetLength,
00064                    sizeof (UChar) * (myUCharErrorBufferLength - targetLength));
00065       _this->UCharErrorBufferLength -= (int8_t) targetLength;
00066       *myTargetIndex = targetLength;
00067       *err = U_BUFFER_OVERFLOW_ERROR;
00068     }
00069 
00070   return;
00071 }
00072 
00073 /*Empties the internal codepage output buffer */
00074 void  flushInternalCharBuffer (UConverter * _this,
00075                                char *myTarget,
00076                                int32_t * myTargetIndex,
00077                                int32_t targetLength,
00078                                int32_t** offsets,
00079                                UErrorCode * err)
00080 {
00081   int32_t myCharErrorBufferLength = _this->charErrorBufferLength;
00082 
00083   /*we have enough space */
00084   if (myCharErrorBufferLength <= targetLength)
00085     {
00086       uprv_memcpy (myTarget, _this->charErrorBuffer, myCharErrorBufferLength);
00087       if (offsets) 
00088         {
00089           int32_t i=0;
00090           for (i=0; i<myCharErrorBufferLength;i++) (*offsets)[i] = -1; 
00091           *offsets += myCharErrorBufferLength;
00092         }
00093 
00094       *myTargetIndex += myCharErrorBufferLength;
00095       _this->charErrorBufferLength = 0;
00096     }
00097   else
00098     /* We don't have enough space so we copy as much as we can
00099      * on the output stream and update the object*/
00100     {
00101       uprv_memcpy (myTarget, _this->charErrorBuffer, targetLength);
00102       if (offsets) 
00103         {
00104           int32_t i=0;
00105           for (i=0; i< targetLength;i++) (*offsets)[i] = -1; 
00106           *offsets += targetLength;
00107         }
00108       uprv_memmove (_this->charErrorBuffer,
00109                    _this->charErrorBuffer + targetLength,
00110                    (myCharErrorBufferLength - targetLength));
00111       _this->charErrorBufferLength -= (int8_t) targetLength;
00112       *myTargetIndex = targetLength;
00113       *err = U_BUFFER_OVERFLOW_ERROR;
00114     }
00115 
00116   return;
00117 }
00118 
00135 U_CFUNC UChar32
00136 ucnv_getUChar32KeepOverflow(UConverter *cnv, const UChar *buffer, int32_t length) {
00137     UChar32 c;
00138     int32_t i;
00139 
00140     if(length<=0) {
00141         return 0xffff;
00142     }
00143 
00144     /* get the first code point in the buffer */
00145     i=0;
00146     UTF_NEXT_CHAR_SAFE_LENIENT(buffer, i, length, c);
00147     if(i<length) {
00148         /* there are UChars left in the buffer that need to go into the overflow buffer */
00149         UChar *overflow=cnv->UCharErrorBuffer;
00150         int32_t j=cnv->UCharErrorBufferLength;
00151 
00152         if(j>0) {
00153             /* move the overflow buffer contents to make room for the extra UChars */
00154             int32_t k;
00155 
00156             cnv->UCharErrorBufferLength=(int8_t)(k=(length-i)+j);
00157             do {
00158                 overflow[--k]=overflow[--j];
00159             } while(j>0);
00160         } else {
00161             cnv->UCharErrorBufferLength=(int8_t)(length-i);
00162         }
00163 
00164         /* copy the remaining UChars to the beginning of the overflow buffer */
00165         do {
00166             overflow[j++]=buffer[i++];
00167         } while(i<length);
00168     }
00169     return c;
00170 }
00171 
00172 /* update target offsets after a callback call */
00173 U_CFUNC int32_t *
00174 ucnv_updateCallbackOffsets(int32_t *offsets, int32_t length, int32_t sourceIndex) {
00175     if(offsets!=NULL) {
00176         if(sourceIndex>=0) {
00177             /* add the sourceIndex to the relative offsets that the callback wrote */
00178             while(length>0) {
00179                 *offsets+=sourceIndex;
00180                 ++offsets;
00181                 --length;
00182             }
00183         } else {
00184             /* sourceIndex==-1, set -1 offsets */
00185             while(length>0) {
00186                 *offsets=-1;
00187                 ++offsets;
00188                 --length;
00189             }
00190         }
00191         return offsets;
00192     } else {
00193         return NULL;
00194     }
00195 }

Generated at Tue Dec 5 10:48:01 2000 for ICU by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000