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
@@ -146,7 +147,6 @@ MaybeLocal<Object> Transcode(Environment* env,
146
147
const char * source,
147
148
const size_t source_length,
148
149
UErrorCode* status) {
149
- *status = U_ZERO_ERROR;
150
150
MaybeLocal<Object> ret;
151
151
MaybeStackBuffer<char > result;
152
152
Converter to (toEncoding);
@@ -169,22 +169,21 @@ MaybeLocal<Object> Transcode(Environment* env,
169
169
return ret;
170
170
}
171
171
172
- MaybeLocal<Object> TranscodeToUcs2 (Environment* env,
173
- const char * fromEncoding,
174
- const char * toEncoding,
175
- const char * source,
176
- const size_t source_length,
177
- UErrorCode* status) {
178
- *status = U_ZERO_ERROR;
179
- MaybeLocal<Object> ret;
172
+ MaybeLocal<Object> TranscodeLatin1ToUcs2 (Environment* env,
173
+ const char * fromEncoding,
174
+ const char * toEncoding,
175
+ const char * source,
176
+ const size_t source_length,
177
+ UErrorCode* status) {
180
178
MaybeStackBuffer<UChar> destbuf (source_length);
181
- Converter from (fromEncoding);
182
- const size_t length_in_chars = source_length * sizeof (UChar);
183
- ucnv_toUChars (from.conv (), *destbuf, length_in_chars,
184
- source, source_length, status);
185
- if (U_SUCCESS (*status))
186
- ret = ToBufferEndian (env, &destbuf);
187
- return ret;
179
+ auto actual_length =
180
+ simdutf::convert_latin1_to_utf16le (source, source_length, destbuf.out ());
181
+ if (actual_length == 0 ) {
182
+ *status = U_INVALID_CHAR_FOUND;
183
+ return {};
184
+ }
185
+
186
+ return Buffer::New (env, &destbuf);
188
187
}
189
188
190
189
MaybeLocal<Object> TranscodeFromUcs2 (Environment* env,
@@ -193,13 +192,11 @@ MaybeLocal<Object> TranscodeFromUcs2(Environment* env,
193
192
const char * source,
194
193
const size_t source_length,
195
194
UErrorCode* status) {
196
- *status = U_ZERO_ERROR;
197
195
MaybeStackBuffer<UChar> sourcebuf;
198
196
MaybeLocal<Object> ret;
199
197
Converter to (toEncoding);
200
198
201
- size_t sublen = ucnv_getMinCharSize (to.conv ());
202
- std::string sub (sublen, ' ?' );
199
+ std::string sub (to.min_char_size (), ' ?' );
203
200
to.set_subst_chars (sub.c_str ());
204
201
205
202
const size_t length_in_chars = source_length / sizeof (UChar);
@@ -220,26 +217,18 @@ MaybeLocal<Object> TranscodeUcs2FromUtf8(Environment* env,
220
217
const char * source,
221
218
const size_t source_length,
222
219
UErrorCode* status) {
223
- *status = U_ZERO_ERROR;
224
- MaybeStackBuffer<UChar> destbuf;
225
- int32_t result_length;
226
- u_strFromUTF8 (*destbuf, destbuf.capacity (), &result_length,
227
- source, source_length, status);
228
- MaybeLocal<Object> ret;
229
- if (U_SUCCESS (*status)) {
230
- destbuf.SetLength (result_length);
231
- ret = ToBufferEndian (env, &destbuf);
232
- } else if (*status == U_BUFFER_OVERFLOW_ERROR) {
233
- *status = U_ZERO_ERROR;
234
- destbuf.AllocateSufficientStorage (result_length);
235
- u_strFromUTF8 (*destbuf, result_length, &result_length,
236
- source, source_length, status);
237
- if (U_SUCCESS (*status)) {
238
- destbuf.SetLength (result_length);
239
- ret = ToBufferEndian (env, &destbuf);
240
- }
220
+ size_t expected_utf16_length =
221
+ simdutf::utf16_length_from_utf8 (source, source_length);
222
+ MaybeStackBuffer<UChar> destbuf (expected_utf16_length);
223
+ auto actual_length =
224
+ simdutf::convert_utf8_to_utf16le (source, source_length, destbuf.out ());
225
+
226
+ if (actual_length == 0 ) {
227
+ *status = U_INVALID_CHAR_FOUND;
228
+ return {};
241
229
}
242
- return ret;
230
+
231
+ return Buffer::New (env, &destbuf);
243
232
}
244
233
245
234
MaybeLocal<Object> TranscodeUtf8FromUcs2 (Environment* env,
@@ -248,32 +237,25 @@ MaybeLocal<Object> TranscodeUtf8FromUcs2(Environment* env,
248
237
const char * source,
249
238
const size_t source_length,
250
239
UErrorCode* status) {
251
- *status = U_ZERO_ERROR;
252
- MaybeLocal<Object> ret;
253
240
const size_t length_in_chars = source_length / sizeof (UChar);
254
- int32_t result_length;
255
- MaybeStackBuffer<UChar> sourcebuf;
256
- MaybeStackBuffer<char > destbuf;
257
- CopySourceBuffer (&sourcebuf, source, source_length, length_in_chars);
258
- u_strToUTF8 (*destbuf, destbuf.capacity (), &result_length,
259
- *sourcebuf, length_in_chars, status);
260
- if (U_SUCCESS (*status)) {
261
- destbuf.SetLength (result_length);
262
- ret = ToBufferEndian (env, &destbuf);
263
- } else if (*status == U_BUFFER_OVERFLOW_ERROR) {
264
- *status = U_ZERO_ERROR;
265
- destbuf.AllocateSufficientStorage (result_length);
266
- u_strToUTF8 (*destbuf, result_length, &result_length, *sourcebuf,
267
- length_in_chars, status);
268
- if (U_SUCCESS (*status)) {
269
- destbuf.SetLength (result_length);
270
- ret = ToBufferEndian (env, &destbuf);
271
- }
241
+ size_t expected_utf8_length = simdutf::utf8_length_from_utf16le (
242
+ reinterpret_cast <const char16_t *>(source), length_in_chars);
243
+
244
+ MaybeStackBuffer<char > destbuf (expected_utf8_length);
245
+ auto actual_length = simdutf::convert_utf16le_to_utf8 (
246
+ reinterpret_cast <const char16_t *>(source),
247
+ length_in_chars,
248
+ destbuf.out ());
249
+
250
+ if (actual_length == 0 ) {
251
+ *status = U_INVALID_CHAR_FOUND;
252
+ return {};
272
253
}
273
- return ret;
254
+
255
+ return Buffer::New (env, &destbuf);
274
256
}
275
257
276
- const char * EncodingName (const enum encoding encoding) {
258
+ constexpr const char * EncodingName (const enum encoding encoding) {
277
259
switch (encoding) {
278
260
case ASCII: return " us-ascii" ;
279
261
case LATIN1: return " iso8859-1" ;
@@ -283,7 +265,7 @@ const char* EncodingName(const enum encoding encoding) {
283
265
}
284
266
}
285
267
286
- bool SupportedEncoding (const enum encoding encoding) {
268
+ constexpr bool SupportedEncoding (const enum encoding encoding) {
287
269
switch (encoding) {
288
270
case ASCII:
289
271
case LATIN1:
@@ -308,8 +290,7 @@ void Transcode(const FunctionCallbackInfo<Value>&args) {
308
290
switch (fromEncoding) {
309
291
case ASCII:
310
292
case LATIN1:
311
- if (toEncoding == UCS2)
312
- tfn = &TranscodeToUcs2;
293
+ if (toEncoding == UCS2) tfn = &TranscodeLatin1ToUcs2;
313
294
break ;
314
295
case UTF8:
315
296
if (toEncoding == UCS2)
0 commit comments