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
29 U_CFUNC void
ucnv_getCompleteUnicodeSet(const UConverter * cnv,const USetAdder * sa,UConverterUnicodeSet which,UErrorCode * pErrorCode)30 ucnv_getCompleteUnicodeSet(const UConverter *cnv,
31 const USetAdder *sa,
32 UConverterUnicodeSet which,
33 UErrorCode *pErrorCode) {
34 sa->addRange(sa->set, 0, 0x10ffff);
35 }
36
37 U_CFUNC void
ucnv_getNonSurrogateUnicodeSet(const UConverter * cnv,const USetAdder * sa,UConverterUnicodeSet which,UErrorCode * pErrorCode)38 ucnv_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
46 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)47 ucnv_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
86 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)87 ucnv_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
126 U_CFUNC void
ucnv_toUWriteCodePoint(UConverter * cnv,UChar32 c,UChar ** target,const UChar * targetLimit,int32_t ** offsets,int32_t sourceIndex,UErrorCode * pErrorCode)127 ucnv_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