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