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
ucnv_getCompleteUnicodeSet(const UConverter * cnv,const USetAdder * sa,UConverterUnicodeSet which,UErrorCode * pErrorCode)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
ucnv_getNonSurrogateUnicodeSet(const UConverter * cnv,const USetAdder * sa,UConverterUnicodeSet which,UErrorCode * pErrorCode)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
ucnv_fromUWriteBytes(UConverter * cnv,const char * bytes,int32_t length,char ** target,const char * targetLimit,int32_t ** offsets,int32_t sourceIndex,UErrorCode * pErrorCode)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
ucnv_toUWriteUChars(UConverter * cnv,const UChar * uchars,int32_t length,UChar ** target,const UChar * targetLimit,int32_t ** offsets,int32_t sourceIndex,UErrorCode * pErrorCode)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
ucnv_toUWriteCodePoint(UConverter * cnv,UChar32 c,UChar ** target,const UChar * targetLimit,int32_t ** offsets,int32_t sourceIndex,UErrorCode * pErrorCode)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