diff options
Diffstat (limited to 'intl/icu/source/common/ucnv_cnv.c')
-rw-r--r-- | intl/icu/source/common/ucnv_cnv.c | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/intl/icu/source/common/ucnv_cnv.c b/intl/icu/source/common/ucnv_cnv.c new file mode 100644 index 000000000..01f84829d --- /dev/null +++ b/intl/icu/source/common/ucnv_cnv.c @@ -0,0 +1,176 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +/* +****************************************************************************** +* +* 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 |