4242
4343#include " node_i18n.h"
4444#include " node_external_reference.h"
45- #include " simdutf.h"
4645
4746#if defined(NODE_HAVE_I18N_SUPPORT)
4847
@@ -148,6 +147,7 @@ MaybeLocal<Object> Transcode(Environment* env,
148147 const char * source,
149148 const size_t source_length,
150149 UErrorCode* status) {
150+ *status = U_ZERO_ERROR;
151151 MaybeLocal<Object> ret;
152152 MaybeStackBuffer<char > result;
153153 Converter to (toEncoding);
@@ -170,21 +170,22 @@ MaybeLocal<Object> Transcode(Environment* env,
170170 return ret;
171171}
172172
173- MaybeLocal<Object> TranscodeLatin1ToUcs2 (Environment* env,
174- const char * fromEncoding,
175- const char * toEncoding,
176- const char * source,
177- const size_t source_length,
178- UErrorCode* status) {
173+ MaybeLocal<Object> TranscodeToUcs2 (Environment* env,
174+ const char * fromEncoding,
175+ const char * toEncoding,
176+ const char * source,
177+ const size_t source_length,
178+ UErrorCode* status) {
179+ *status = U_ZERO_ERROR;
180+ MaybeLocal<Object> ret;
179181 MaybeStackBuffer<UChar> destbuf (source_length);
180- auto actual_length =
181- simdutf::convert_latin1_to_utf16le (source, source_length, destbuf.out ());
182- if (actual_length == 0 ) {
183- *status = U_INVALID_CHAR_FOUND;
184- return {};
185- }
186-
187- return Buffer::New (env, &destbuf);
182+ Converter from (fromEncoding);
183+ const size_t length_in_chars = source_length * sizeof (UChar);
184+ ucnv_toUChars (from.conv (), *destbuf, length_in_chars,
185+ source, source_length, status);
186+ if (U_SUCCESS (*status))
187+ ret = ToBufferEndian (env, &destbuf);
188+ return ret;
188189}
189190
190191MaybeLocal<Object> TranscodeFromUcs2 (Environment* env,
@@ -193,11 +194,13 @@ MaybeLocal<Object> TranscodeFromUcs2(Environment* env,
193194 const char * source,
194195 const size_t source_length,
195196 UErrorCode* status) {
197+ *status = U_ZERO_ERROR;
196198 MaybeStackBuffer<UChar> sourcebuf;
197199 MaybeLocal<Object> ret;
198200 Converter to (toEncoding);
199201
200- std::string sub (to.min_char_size (), ' ?' );
202+ size_t sublen = ucnv_getMinCharSize (to.conv ());
203+ std::string sub (sublen, ' ?' );
201204 to.set_subst_chars (sub.c_str ());
202205
203206 const size_t length_in_chars = source_length / sizeof (UChar);
@@ -218,18 +221,26 @@ MaybeLocal<Object> TranscodeUcs2FromUtf8(Environment* env,
218221 const char * source,
219222 const size_t source_length,
220223 UErrorCode* status) {
221- size_t expected_utf16_length =
222- simdutf::utf16_length_from_utf8 (source, source_length);
223- MaybeStackBuffer<UChar> destbuf (expected_utf16_length);
224- auto actual_length =
225- simdutf::convert_utf8_to_utf16le (source, source_length, destbuf.out ());
226-
227- if (actual_length == 0 ) {
228- *status = U_INVALID_CHAR_FOUND;
229- return {};
224+ *status = U_ZERO_ERROR;
225+ MaybeStackBuffer<UChar> destbuf;
226+ int32_t result_length;
227+ u_strFromUTF8 (*destbuf, destbuf.capacity (), &result_length,
228+ source, source_length, status);
229+ MaybeLocal<Object> ret;
230+ if (U_SUCCESS (*status)) {
231+ destbuf.SetLength (result_length);
232+ ret = ToBufferEndian (env, &destbuf);
233+ } else if (*status == U_BUFFER_OVERFLOW_ERROR) {
234+ *status = U_ZERO_ERROR;
235+ destbuf.AllocateSufficientStorage (result_length);
236+ u_strFromUTF8 (*destbuf, result_length, &result_length,
237+ source, source_length, status);
238+ if (U_SUCCESS (*status)) {
239+ destbuf.SetLength (result_length);
240+ ret = ToBufferEndian (env, &destbuf);
241+ }
230242 }
231-
232- return Buffer::New (env, &destbuf);
243+ return ret;
233244}
234245
235246MaybeLocal<Object> TranscodeUtf8FromUcs2 (Environment* env,
@@ -238,25 +249,32 @@ MaybeLocal<Object> TranscodeUtf8FromUcs2(Environment* env,
238249 const char * source,
239250 const size_t source_length,
240251 UErrorCode* status) {
252+ *status = U_ZERO_ERROR;
253+ MaybeLocal<Object> ret;
241254 const size_t length_in_chars = source_length / sizeof (UChar);
242- size_t expected_utf8_length = simdutf::utf8_length_from_utf16le (
243- reinterpret_cast <const char16_t *>(source), length_in_chars);
244-
245- MaybeStackBuffer<char > destbuf (expected_utf8_length);
246- auto actual_length = simdutf::convert_utf16le_to_utf8 (
247- reinterpret_cast <const char16_t *>(source),
248- length_in_chars,
249- destbuf.out ());
250-
251- if (actual_length == 0 ) {
252- *status = U_INVALID_CHAR_FOUND;
253- return {};
255+ int32_t result_length;
256+ MaybeStackBuffer<UChar> sourcebuf;
257+ MaybeStackBuffer<char > destbuf;
258+ CopySourceBuffer (&sourcebuf, source, source_length, length_in_chars);
259+ u_strToUTF8 (*destbuf, destbuf.capacity (), &result_length,
260+ *sourcebuf, length_in_chars, status);
261+ if (U_SUCCESS (*status)) {
262+ destbuf.SetLength (result_length);
263+ ret = ToBufferEndian (env, &destbuf);
264+ } else if (*status == U_BUFFER_OVERFLOW_ERROR) {
265+ *status = U_ZERO_ERROR;
266+ destbuf.AllocateSufficientStorage (result_length);
267+ u_strToUTF8 (*destbuf, result_length, &result_length, *sourcebuf,
268+ length_in_chars, status);
269+ if (U_SUCCESS (*status)) {
270+ destbuf.SetLength (result_length);
271+ ret = ToBufferEndian (env, &destbuf);
272+ }
254273 }
255-
256- return Buffer::New (env, &destbuf);
274+ return ret;
257275}
258276
259- constexpr const char * EncodingName (const enum encoding encoding) {
277+ const char * EncodingName (const enum encoding encoding) {
260278 switch (encoding) {
261279 case ASCII: return " us-ascii" ;
262280 case LATIN1: return " iso8859-1" ;
@@ -266,7 +284,7 @@ constexpr const char* EncodingName(const enum encoding encoding) {
266284 }
267285}
268286
269- constexpr bool SupportedEncoding (const enum encoding encoding) {
287+ bool SupportedEncoding (const enum encoding encoding) {
270288 switch (encoding) {
271289 case ASCII:
272290 case LATIN1:
@@ -291,7 +309,8 @@ void Transcode(const FunctionCallbackInfo<Value>&args) {
291309 switch (fromEncoding) {
292310 case ASCII:
293311 case LATIN1:
294- if (toEncoding == UCS2) tfn = &TranscodeLatin1ToUcs2;
312+ if (toEncoding == UCS2)
313+ tfn = &TranscodeToUcs2;
295314 break ;
296315 case UTF8:
297316 if (toEncoding == UCS2)
0 commit comments