|  | /* | 
|  | ****************************************************************************** | 
|  | * | 
|  | *   Copyright (C) 1999-2004, International Business Machines | 
|  | *   Corporation and others.  All Rights Reserved. | 
|  | * | 
|  | ****************************************************************************** | 
|  | * | 
|  | *   uconv_cnv.c: | 
|  | *   Implements all the low level conversion functions | 
|  | *   T_UnicodeConverter_{to,from}Unicode_$ConversionType | 
|  | * | 
|  | *   Change history: | 
|  | * | 
|  | *   06/29/2000  helena      Major rewrite of the callback APIs. | 
|  | */ | 
|  |  | 
|  | #include "unicode/utypes.h" | 
|  |  | 
|  | #if !UCONFIG_NO_CONVERSION | 
|  |  | 
|  | #include "unicode/ucnv_err.h" | 
|  | #include "unicode/ucnv.h" | 
|  | #include "unicode/uset.h" | 
|  | #include "ucnv_cnv.h" | 
|  | #include "ucnv_bld.h" | 
|  | #include "cmemory.h" | 
|  |  | 
|  | U_CFUNC void | 
|  | ucnv_getCompleteUnicodeSet(const UConverter *cnv, | 
|  | USetAdder *sa, | 
|  | UConverterUnicodeSet which, | 
|  | UErrorCode *pErrorCode) { | 
|  | sa->addRange(sa->set, 0, 0x10ffff); | 
|  | } | 
|  |  | 
|  | U_CFUNC void | 
|  | ucnv_getNonSurrogateUnicodeSet(const UConverter *cnv, | 
|  | USetAdder *sa, | 
|  | UConverterUnicodeSet which, | 
|  | UErrorCode *pErrorCode) { | 
|  | sa->addRange(sa->set, 0, 0xd7ff); | 
|  | sa->addRange(sa->set, 0xe000, 0x10ffff); | 
|  | } | 
|  |  | 
|  | U_CFUNC void | 
|  | ucnv_fromUWriteBytes(UConverter *cnv, | 
|  | const char *bytes, int32_t length, | 
|  | char **target, const char *targetLimit, | 
|  | int32_t **offsets, | 
|  | int32_t sourceIndex, | 
|  | UErrorCode *pErrorCode) { | 
|  | char *t=*target; | 
|  | int32_t *o; | 
|  |  | 
|  | /* write bytes */ | 
|  | if(offsets==NULL || (o=*offsets)==NULL) { | 
|  | while(length>0 && t<targetLimit) { | 
|  | *t++=*bytes++; | 
|  | --length; | 
|  | } | 
|  | } else { | 
|  | /* output with offsets */ | 
|  | while(length>0 && t<targetLimit) { | 
|  | *t++=*bytes++; | 
|  | *o++=sourceIndex; | 
|  | --length; | 
|  | } | 
|  | *offsets=o; | 
|  | } | 
|  | *target=t; | 
|  |  | 
|  | /* write overflow */ | 
|  | if(length>0) { | 
|  | if(cnv!=NULL) { | 
|  | t=(char *)cnv->charErrorBuffer; | 
|  | cnv->charErrorBufferLength=(int8_t)length; | 
|  | do { | 
|  | *t++=(uint8_t)*bytes++; | 
|  | } while(--length>0); | 
|  | } | 
|  | *pErrorCode=U_BUFFER_OVERFLOW_ERROR; | 
|  | } | 
|  | } | 
|  |  | 
|  | U_CFUNC void | 
|  | ucnv_toUWriteUChars(UConverter *cnv, | 
|  | const UChar *uchars, int32_t length, | 
|  | UChar **target, const UChar *targetLimit, | 
|  | int32_t **offsets, | 
|  | int32_t sourceIndex, | 
|  | UErrorCode *pErrorCode) { | 
|  | UChar *t=*target; | 
|  | int32_t *o; | 
|  |  | 
|  | /* write UChars */ | 
|  | if(offsets==NULL || (o=*offsets)==NULL) { | 
|  | while(length>0 && t<targetLimit) { | 
|  | *t++=*uchars++; | 
|  | --length; | 
|  | } | 
|  | } else { | 
|  | /* output with offsets */ | 
|  | while(length>0 && t<targetLimit) { | 
|  | *t++=*uchars++; | 
|  | *o++=sourceIndex; | 
|  | --length; | 
|  | } | 
|  | *offsets=o; | 
|  | } | 
|  | *target=t; | 
|  |  | 
|  | /* write overflow */ | 
|  | if(length>0) { | 
|  | if(cnv!=NULL) { | 
|  | t=cnv->UCharErrorBuffer; | 
|  | cnv->UCharErrorBufferLength=(int8_t)length; | 
|  | do { | 
|  | *t++=*uchars++; | 
|  | } while(--length>0); | 
|  | } | 
|  | *pErrorCode=U_BUFFER_OVERFLOW_ERROR; | 
|  | } | 
|  | } | 
|  |  | 
|  | U_CFUNC void | 
|  | ucnv_toUWriteCodePoint(UConverter *cnv, | 
|  | UChar32 c, | 
|  | UChar **target, const UChar *targetLimit, | 
|  | int32_t **offsets, | 
|  | int32_t sourceIndex, | 
|  | UErrorCode *pErrorCode) { | 
|  | UChar *t; | 
|  | int32_t *o; | 
|  |  | 
|  | t=*target; | 
|  |  | 
|  | if(t<targetLimit) { | 
|  | if(c<=0xffff) { | 
|  | *t++=(UChar)c; | 
|  | c=U_SENTINEL; | 
|  | } else /* c is a supplementary code point */ { | 
|  | *t++=U16_LEAD(c); | 
|  | c=U16_TRAIL(c); | 
|  | if(t<targetLimit) { | 
|  | *t++=(UChar)c; | 
|  | c=U_SENTINEL; | 
|  | } | 
|  | } | 
|  |  | 
|  | /* write offsets */ | 
|  | if(offsets!=NULL && (o=*offsets)!=NULL) { | 
|  | *o++=sourceIndex; | 
|  | if((*target+1)<t) { | 
|  | *o++=sourceIndex; | 
|  | } | 
|  | *offsets=o; | 
|  | } | 
|  | } | 
|  |  | 
|  | *target=t; | 
|  |  | 
|  | /* write overflow from c */ | 
|  | if(c>=0) { | 
|  | if(cnv!=NULL) { | 
|  | int8_t i=0; | 
|  | U16_APPEND_UNSAFE(cnv->UCharErrorBuffer, i, c); | 
|  | cnv->UCharErrorBufferLength=i; | 
|  | } | 
|  | *pErrorCode=U_BUFFER_OVERFLOW_ERROR; | 
|  | } | 
|  | } | 
|  |  | 
|  | #endif |