Home | History | Annotate | Download | only in common
      1 /*
      2 ******************************************************************************
      3 *
      4 *   Copyright (C) 1999-2004, International Business Machines
      5 *   Corporation and others.  All Rights Reserved.
      6 *
      7 ******************************************************************************
      8 *
      9 *   uconv_cnv.c:
     10 *   Implements all the low level conversion functions
     11 *   T_UnicodeConverter_{to,from}Unicode_$ConversionType
     12 *
     13 *   Change history:
     14 *
     15 *   06/29/2000  helena      Major rewrite of the callback APIs.
     16 */
     17 
     18 #include "unicode/utypes.h"
     19 
     20 #if !UCONFIG_NO_CONVERSION
     21 
     22 #include "unicode/ucnv_err.h"
     23 #include "unicode/ucnv.h"
     24 #include "unicode/uset.h"
     25 #include "ucnv_cnv.h"
     26 #include "ucnv_bld.h"
     27 #include "cmemory.h"
     28 
     29 U_CFUNC void
     30 ucnv_getCompleteUnicodeSet(const UConverter *cnv,
     31                    const USetAdder *sa,
     32                    UConverterUnicodeSet which,
     33                    UErrorCode *pErrorCode) {
     34     sa->addRange(sa->set, 0, 0x10ffff);
     35 }
     36 
     37 U_CFUNC void
     38 ucnv_getNonSurrogateUnicodeSet(const UConverter *cnv,
     39                                const USetAdder *sa,
     40                                UConverterUnicodeSet which,
     41                                UErrorCode *pErrorCode) {
     42     sa->addRange(sa->set, 0, 0xd7ff);
     43     sa->addRange(sa->set, 0xe000, 0x10ffff);
     44 }
     45 
     46 U_CFUNC void
     47 ucnv_fromUWriteBytes(UConverter *cnv,
     48                      const char *bytes, int32_t length,
     49                      char **target, const char *targetLimit,
     50                      int32_t **offsets,
     51                      int32_t sourceIndex,
     52                      UErrorCode *pErrorCode) {
     53     char *t=*target;
     54     int32_t *o;
     55 
     56     /* write bytes */
     57     if(offsets==NULL || (o=*offsets)==NULL) {
     58         while(length>0 && t<targetLimit) {
     59             *t++=*bytes++;
     60             --length;
     61         }
     62     } else {
     63         /* output with offsets */
     64         while(length>0 && t<targetLimit) {
     65             *t++=*bytes++;
     66             *o++=sourceIndex;
     67             --length;
     68         }
     69         *offsets=o;
     70     }
     71     *target=t;
     72 
     73     /* write overflow */
     74     if(length>0) {
     75         if(cnv!=NULL) {
     76             t=(char *)cnv->charErrorBuffer;
     77             cnv->charErrorBufferLength=(int8_t)length;
     78             do {
     79                 *t++=(uint8_t)*bytes++;
     80             } while(--length>0);
     81         }
     82         *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
     83     }
     84 }
     85 
     86 U_CFUNC void
     87 ucnv_toUWriteUChars(UConverter *cnv,
     88                     const UChar *uchars, int32_t length,
     89                     UChar **target, const UChar *targetLimit,
     90                     int32_t **offsets,
     91                     int32_t sourceIndex,
     92                     UErrorCode *pErrorCode) {
     93     UChar *t=*target;
     94     int32_t *o;
     95 
     96     /* write UChars */
     97     if(offsets==NULL || (o=*offsets)==NULL) {
     98         while(length>0 && t<targetLimit) {
     99             *t++=*uchars++;
    100             --length;
    101         }
    102     } else {
    103         /* output with offsets */
    104         while(length>0 && t<targetLimit) {
    105             *t++=*uchars++;
    106             *o++=sourceIndex;
    107             --length;
    108         }
    109         *offsets=o;
    110     }
    111     *target=t;
    112 
    113     /* write overflow */
    114     if(length>0) {
    115         if(cnv!=NULL) {
    116             t=cnv->UCharErrorBuffer;
    117             cnv->UCharErrorBufferLength=(int8_t)length;
    118             do {
    119                 *t++=*uchars++;
    120             } while(--length>0);
    121         }
    122         *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
    123     }
    124 }
    125 
    126 U_CFUNC void
    127 ucnv_toUWriteCodePoint(UConverter *cnv,
    128                        UChar32 c,
    129                        UChar **target, const UChar *targetLimit,
    130                        int32_t **offsets,
    131                        int32_t sourceIndex,
    132                        UErrorCode *pErrorCode) {
    133     UChar *t;
    134     int32_t *o;
    135 
    136     t=*target;
    137 
    138     if(t<targetLimit) {
    139         if(c<=0xffff) {
    140             *t++=(UChar)c;
    141             c=U_SENTINEL;
    142         } else /* c is a supplementary code point */ {
    143             *t++=U16_LEAD(c);
    144             c=U16_TRAIL(c);
    145             if(t<targetLimit) {
    146                 *t++=(UChar)c;
    147                 c=U_SENTINEL;
    148             }
    149         }
    150 
    151         /* write offsets */
    152         if(offsets!=NULL && (o=*offsets)!=NULL) {
    153             *o++=sourceIndex;
    154             if((*target+1)<t) {
    155                 *o++=sourceIndex;
    156             }
    157             *offsets=o;
    158         }
    159     }
    160 
    161     *target=t;
    162 
    163     /* write overflow from c */
    164     if(c>=0) {
    165         if(cnv!=NULL) {
    166             int8_t i=0;
    167             U16_APPEND_UNSAFE(cnv->UCharErrorBuffer, i, c);
    168             cnv->UCharErrorBufferLength=i;
    169         }
    170         *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
    171     }
    172 }
    173 
    174 #endif
    175