|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |