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