42
42
43
43
#include " node_i18n.h"
44
44
#include " node_external_reference.h"
45
+ #include " simdutf.h"
45
46
46
47
#if defined(NODE_HAVE_I18N_SUPPORT)
47
48
@@ -147,7 +148,6 @@ MaybeLocal<Object> Transcode(Environment* env,
147
148
const char * source,
148
149
const size_t source_length,
149
150
UErrorCode* status) {
150
- *status = U_ZERO_ERROR;
151
151
MaybeLocal<Object> ret;
152
152
MaybeStackBuffer<char > result;
153
153
Converter to (toEncoding);
@@ -170,22 +170,21 @@ MaybeLocal<Object> Transcode(Environment* env,
170
170
return ret;
171
171
}
172
172
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;
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) {
181
179
MaybeStackBuffer<UChar> destbuf (source_length);
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;
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);
189
188
}
190
189
191
190
MaybeLocal<Object> TranscodeFromUcs2 (Environment* env,
@@ -194,13 +193,11 @@ MaybeLocal<Object> TranscodeFromUcs2(Environment* env,
194
193
const char * source,
195
194
const size_t source_length,
196
195
UErrorCode* status) {
197
- *status = U_ZERO_ERROR;
198
196
MaybeStackBuffer<UChar> sourcebuf;
199
197
MaybeLocal<Object> ret;
200
198
Converter to (toEncoding);
201
199
202
- size_t sublen = ucnv_getMinCharSize (to.conv ());
203
- std::string sub (sublen, ' ?' );
200
+ std::string sub (to.min_char_size (), ' ?' );
204
201
to.set_subst_chars (sub.c_str ());
205
202
206
203
const size_t length_in_chars = source_length / sizeof (UChar);
@@ -221,26 +218,18 @@ MaybeLocal<Object> TranscodeUcs2FromUtf8(Environment* env,
221
218
const char * source,
222
219
const size_t source_length,
223
220
UErrorCode* status) {
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
- }
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 {};
242
230
}
243
- return ret;
231
+
232
+ return Buffer::New (env, &destbuf);
244
233
}
245
234
246
235
MaybeLocal<Object> TranscodeUtf8FromUcs2 (Environment* env,
@@ -249,32 +238,25 @@ MaybeLocal<Object> TranscodeUtf8FromUcs2(Environment* env,
249
238
const char * source,
250
239
const size_t source_length,
251
240
UErrorCode* status) {
252
- *status = U_ZERO_ERROR;
253
- MaybeLocal<Object> ret;
254
241
const size_t length_in_chars = source_length / sizeof (UChar);
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
- }
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 {};
273
254
}
274
- return ret;
255
+
256
+ return Buffer::New (env, &destbuf);
275
257
}
276
258
277
- const char * EncodingName (const enum encoding encoding) {
259
+ constexpr const char * EncodingName (const enum encoding encoding) {
278
260
switch (encoding) {
279
261
case ASCII: return " us-ascii" ;
280
262
case LATIN1: return " iso8859-1" ;
@@ -284,7 +266,7 @@ const char* EncodingName(const enum encoding encoding) {
284
266
}
285
267
}
286
268
287
- bool SupportedEncoding (const enum encoding encoding) {
269
+ constexpr bool SupportedEncoding (const enum encoding encoding) {
288
270
switch (encoding) {
289
271
case ASCII:
290
272
case LATIN1:
@@ -309,8 +291,7 @@ void Transcode(const FunctionCallbackInfo<Value>&args) {
309
291
switch (fromEncoding) {
310
292
case ASCII:
311
293
case LATIN1:
312
- if (toEncoding == UCS2)
313
- tfn = &TranscodeToUcs2;
294
+ if (toEncoding == UCS2) tfn = &TranscodeLatin1ToUcs2;
314
295
break ;
315
296
case UTF8:
316
297
if (toEncoding == UCS2)
0 commit comments