ucnv_cnv.c revision c73f511526464f8e56c242df80552e9b0d94ae3d
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 29U_CFUNC void 30ucnv_getCompleteUnicodeSet(const UConverter *cnv, 31 const USetAdder *sa, 32 UConverterUnicodeSet which, 33 UErrorCode *pErrorCode) { 34 sa->addRange(sa->set, 0, 0x10ffff); 35} 36 37U_CFUNC void 38ucnv_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 46U_CFUNC void 47ucnv_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 86U_CFUNC void 87ucnv_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 126U_CFUNC void 127ucnv_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