1 // © 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     (void)cnv;
37     (void)which;
38     (void)pErrorCode;
39     sa->addRange(sa->set, 0, 0x10ffff);
40 }
41 
42 U_CFUNC void
ucnv_getNonSurrogateUnicodeSet(const UConverter * cnv,const USetAdder * sa,UConverterUnicodeSet which,UErrorCode * pErrorCode)43 ucnv_getNonSurrogateUnicodeSet(const UConverter *cnv,
44                                const USetAdder *sa,
45                                UConverterUnicodeSet which,
46                                UErrorCode *pErrorCode) {
47     (void)cnv;
48     (void)which;
49     (void)pErrorCode;
50     sa->addRange(sa->set, 0, 0xd7ff);
51     sa->addRange(sa->set, 0xe000, 0x10ffff);
52 }
53 
54 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)55 ucnv_fromUWriteBytes(UConverter *cnv,
56                      const char *bytes, int32_t length,
57                      char **target, const char *targetLimit,
58                      int32_t **offsets,
59                      int32_t sourceIndex,
60                      UErrorCode *pErrorCode) {
61     char *t=*target;
62     int32_t *o;
63 
64     /* write bytes */
65     if(offsets==NULL || (o=*offsets)==NULL) {
66         while(length>0 && t<targetLimit) {
67             *t++=*bytes++;
68             --length;
69         }
70     } else {
71         /* output with offsets */
72         while(length>0 && t<targetLimit) {
73             *t++=*bytes++;
74             *o++=sourceIndex;
75             --length;
76         }
77         *offsets=o;
78     }
79     *target=t;
80 
81     /* write overflow */
82     if(length>0) {
83         if(cnv!=NULL) {
84             t=(char *)cnv->charErrorBuffer;
85             cnv->charErrorBufferLength=(int8_t)length;
86             do {
87                 *t++=(uint8_t)*bytes++;
88             } while(--length>0);
89         }
90         *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
91     }
92 }
93 
94 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)95 ucnv_toUWriteUChars(UConverter *cnv,
96                     const UChar *uchars, int32_t length,
97                     UChar **target, const UChar *targetLimit,
98                     int32_t **offsets,
99                     int32_t sourceIndex,
100                     UErrorCode *pErrorCode) {
101     UChar *t=*target;
102     int32_t *o;
103 
104     /* write UChars */
105     if(offsets==NULL || (o=*offsets)==NULL) {
106         while(length>0 && t<targetLimit) {
107             *t++=*uchars++;
108             --length;
109         }
110     } else {
111         /* output with offsets */
112         while(length>0 && t<targetLimit) {
113             *t++=*uchars++;
114             *o++=sourceIndex;
115             --length;
116         }
117         *offsets=o;
118     }
119     *target=t;
120 
121     /* write overflow */
122     if(length>0) {
123         if(cnv!=NULL) {
124             t=cnv->UCharErrorBuffer;
125             cnv->UCharErrorBufferLength=(int8_t)length;
126             do {
127                 *t++=*uchars++;
128             } while(--length>0);
129         }
130         *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
131     }
132 }
133 
134 U_CFUNC void
ucnv_toUWriteCodePoint(UConverter * cnv,UChar32 c,UChar ** target,const UChar * targetLimit,int32_t ** offsets,int32_t sourceIndex,UErrorCode * pErrorCode)135 ucnv_toUWriteCodePoint(UConverter *cnv,
136                        UChar32 c,
137                        UChar **target, const UChar *targetLimit,
138                        int32_t **offsets,
139                        int32_t sourceIndex,
140                        UErrorCode *pErrorCode) {
141     UChar *t;
142     int32_t *o;
143 
144     t=*target;
145 
146     if(t<targetLimit) {
147         if(c<=0xffff) {
148             *t++=(UChar)c;
149             c=U_SENTINEL;
150         } else /* c is a supplementary code point */ {
151             *t++=U16_LEAD(c);
152             c=U16_TRAIL(c);
153             if(t<targetLimit) {
154                 *t++=(UChar)c;
155                 c=U_SENTINEL;
156             }
157         }
158 
159         /* write offsets */
160         if(offsets!=NULL && (o=*offsets)!=NULL) {
161             *o++=sourceIndex;
162             if((*target+1)<t) {
163                 *o++=sourceIndex;
164             }
165             *offsets=o;
166         }
167     }
168 
169     *target=t;
170 
171     /* write overflow from c */
172     if(c>=0) {
173         if(cnv!=NULL) {
174             int8_t i=0;
175             U16_APPEND_UNSAFE(cnv->UCharErrorBuffer, i, c);
176             cnv->UCharErrorBufferLength=i;
177         }
178         *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
179     }
180 }
181 
182 #endif
183