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
31U_CFUNC void
32ucnv_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
42U_CFUNC void
43ucnv_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
54U_CFUNC void
55ucnv_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==nullptr || (o=*offsets)==nullptr) {
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!=nullptr) {
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
94U_CFUNC void
95ucnv_toUWriteUChars(UConverter *cnv,
96 const char16_t *uchars, int32_t length,
97 char16_t **target, const char16_t *targetLimit,
98 int32_t **offsets,
99 int32_t sourceIndex,
100 UErrorCode *pErrorCode) {
101 char16_t *t=*target;
102 int32_t *o;
103
104 /* write UChars */
105 if(offsets==nullptr || (o=*offsets)==nullptr) {
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!=nullptr) {
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
134U_CFUNC void
135ucnv_toUWriteCodePoint(UConverter *cnv,
136 UChar32 c,
137 char16_t **target, const char16_t *targetLimit,
138 int32_t **offsets,
139 int32_t sourceIndex,
140 UErrorCode *pErrorCode) {
141 char16_t *t;
142 int32_t *o;
143
144 t=*target;
145
146 if(t<targetLimit) {
147 if(c<=0xffff) {
148 *t++=(char16_t)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++=(char16_t)c;
155 c=U_SENTINEL;
156 }
157 }
158
159 /* write offsets */
160 if(offsets!=nullptr && (o=*offsets)!=nullptr) {
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!=nullptr) {
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