| /* |
| ****************************************************************************** |
| * |
| * 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, |
| const USetAdder *sa, |
| UConverterUnicodeSet which, |
| UErrorCode *pErrorCode) { |
| sa->addRange(sa->set, 0, 0x10ffff); |
| } |
| |
| U_CFUNC void |
| ucnv_getNonSurrogateUnicodeSet(const UConverter *cnv, |
| const 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 |