@@ -279,13 +279,15 @@ size_t StringBytes::Write(Isolate* isolate,
279
279
int * chars_written) {
280
280
HandleScope scope (isolate);
281
281
const char * data = nullptr ;
282
- size_t len = 0 ;
283
- bool is_extern = GetExternalParts (isolate, val, &data, &len );
284
- size_t extlen = len ;
282
+ size_t nbytes = 0 ;
283
+ const bool is_extern = GetExternalParts (isolate, val, &data, &nbytes );
284
+ const size_t external_nbytes = nbytes ;
285
285
286
286
CHECK (val->IsString () == true );
287
287
Local<String> str = val.As <String>();
288
- len = len < buflen ? len : buflen;
288
+
289
+ if (nbytes > buflen)
290
+ nbytes = buflen;
289
291
290
292
int flags = String::HINT_MANY_WRITES_EXPECTED |
291
293
String::NO_NULL_TERMINATION |
@@ -295,67 +297,65 @@ size_t StringBytes::Write(Isolate* isolate,
295
297
case ASCII:
296
298
case BINARY:
297
299
case BUFFER:
298
- if (is_extern)
299
- memcpy (buf, data, len);
300
- else
301
- len = str->WriteOneByte (reinterpret_cast <uint8_t *>(buf),
302
- 0 ,
303
- buflen,
304
- flags);
300
+ if (is_extern && str->IsOneByte ()) {
301
+ memcpy (buf, data, nbytes);
302
+ } else {
303
+ uint8_t * const dst = reinterpret_cast <uint8_t *>(buf);
304
+ nbytes = str->WriteOneByte (dst, 0 , buflen, flags);
305
+ }
305
306
if (chars_written != nullptr )
306
- *chars_written = len ;
307
+ *chars_written = nbytes ;
307
308
break ;
308
309
309
310
case UTF8:
310
- if (is_extern)
311
- // TODO(tjfontaine) should this validate invalid surrogate pairs as
312
- // well?
313
- memcpy (buf, data, len);
314
- else
315
- len = str->WriteUtf8 (buf, buflen, chars_written, flags);
311
+ nbytes = str->WriteUtf8 (buf, buflen, chars_written, flags);
316
312
break ;
317
313
318
- case UCS2:
319
- if (is_extern)
320
- memcpy (buf, data, len);
321
- else
322
- len = str->Write (reinterpret_cast <uint16_t *>(buf), 0 , buflen, flags);
314
+ case UCS2: {
315
+ uint16_t * const dst = reinterpret_cast <uint16_t *>(buf);
316
+ size_t nchars;
317
+ if (is_extern && !str->IsOneByte ()) {
318
+ memcpy (buf, data, nbytes);
319
+ nchars = nbytes / sizeof (*dst);
320
+ } else {
321
+ nchars = buflen / sizeof (*dst);
322
+ nchars = str->Write (dst, 0 , nchars, flags);
323
+ nbytes = nchars * sizeof (*dst);
324
+ }
323
325
if (IsBigEndian ()) {
324
326
// Node's "ucs2" encoding wants LE character data stored in
325
327
// the Buffer, so we need to reorder on BE platforms. See
326
328
// http://nodejs.org/api/buffer.html regarding Node's "ucs2"
327
329
// encoding specification
328
- uint16_t * buf16 = reinterpret_cast <uint16_t *>(buf);
329
- for (size_t i = 0 ; i < len; i++) {
330
- buf16[i] = (buf16[i] << 8 ) | (buf16[i] >> 8 );
331
- }
330
+ for (size_t i = 0 ; i < nchars; i++)
331
+ dst[i] = dst[i] << 8 | dst[i] >> 8 ;
332
332
}
333
333
if (chars_written != nullptr )
334
- *chars_written = len;
335
- len = len * sizeof (uint16_t );
334
+ *chars_written = nchars;
336
335
break ;
336
+ }
337
337
338
338
case BASE64:
339
339
if (is_extern) {
340
- len = base64_decode (buf, buflen, data, extlen );
340
+ nbytes = base64_decode (buf, buflen, data, external_nbytes );
341
341
} else {
342
342
String::Value value (str);
343
- len = base64_decode (buf, buflen, *value, value.length ());
343
+ nbytes = base64_decode (buf, buflen, *value, value.length ());
344
344
}
345
345
if (chars_written != nullptr ) {
346
- *chars_written = len ;
346
+ *chars_written = nbytes ;
347
347
}
348
348
break ;
349
349
350
350
case HEX:
351
351
if (is_extern) {
352
- len = hex_decode (buf, buflen, data, extlen );
352
+ nbytes = hex_decode (buf, buflen, data, external_nbytes );
353
353
} else {
354
354
String::Value value (str);
355
- len = hex_decode (buf, buflen, *value, value.length ());
355
+ nbytes = hex_decode (buf, buflen, *value, value.length ());
356
356
}
357
357
if (chars_written != nullptr ) {
358
- *chars_written = len * 2 ;
358
+ *chars_written = nbytes ;
359
359
}
360
360
break ;
361
361
@@ -364,7 +364,7 @@ size_t StringBytes::Write(Isolate* isolate,
364
364
break ;
365
365
}
366
366
367
- return len ;
367
+ return nbytes ;
368
368
}
369
369
370
370
0 commit comments