27
27
28
28
#include < limits.h>
29
29
#include < string.h> // memcpy
30
+
31
+ #include < algorithm>
30
32
#include < vector>
31
33
32
34
// When creating strings >= this length v8's gc spins up and consumes
@@ -269,39 +271,6 @@ static size_t hex_decode(char* buf,
269
271
}
270
272
271
273
272
- bool StringBytes::GetExternalParts (Local<Value> val,
273
- const char ** data,
274
- size_t * len) {
275
- if (Buffer::HasInstance (val)) {
276
- *data = Buffer::Data (val);
277
- *len = Buffer::Length (val);
278
- return true ;
279
- }
280
-
281
- if (!val->IsString ())
282
- return false ;
283
-
284
- Local<String> str = val.As <String>();
285
-
286
- if (str->IsExternalOneByte ()) {
287
- const String::ExternalOneByteStringResource* ext;
288
- ext = str->GetExternalOneByteStringResource ();
289
- *data = ext->data ();
290
- *len = ext->length ();
291
- return true ;
292
-
293
- } else if (str->IsExternal ()) {
294
- const String::ExternalStringResource* ext;
295
- ext = str->GetExternalStringResource ();
296
- *data = reinterpret_cast <const char *>(ext->data ());
297
- *len = ext->length () * sizeof (*ext->data ());
298
- return true ;
299
- }
300
-
301
- return false ;
302
- }
303
-
304
-
305
274
size_t StringBytes::WriteUCS2 (char * buf,
306
275
size_t buflen,
307
276
Local<String> str,
@@ -351,32 +320,31 @@ size_t StringBytes::Write(Isolate* isolate,
351
320
enum encoding encoding,
352
321
int * chars_written) {
353
322
HandleScope scope (isolate);
354
- const char * data = nullptr ;
355
- size_t nbytes = 0 ;
356
- const bool is_extern = GetExternalParts (val, &data, &nbytes);
357
- const size_t external_nbytes = nbytes;
323
+ size_t nbytes;
324
+ int nchars;
325
+
326
+ if (chars_written == nullptr )
327
+ chars_written = &nchars;
358
328
359
329
CHECK (val->IsString () == true );
360
330
Local<String> str = val.As <String>();
361
331
362
- if (nbytes > buflen)
363
- nbytes = buflen;
364
-
365
332
int flags = String::HINT_MANY_WRITES_EXPECTED |
366
333
String::NO_NULL_TERMINATION |
367
334
String::REPLACE_INVALID_UTF8;
368
335
369
336
switch (encoding) {
370
337
case ASCII:
371
338
case LATIN1:
372
- if (is_extern && str->IsOneByte ()) {
373
- memcpy (buf, data, nbytes);
339
+ if (str->IsExternalOneByte ()) {
340
+ auto ext = str->GetExternalOneByteStringResource ();
341
+ nbytes = std::min (buflen, ext->length ());
342
+ memcpy (buf, ext->data (), nbytes);
374
343
} else {
375
344
uint8_t * const dst = reinterpret_cast <uint8_t *>(buf);
376
345
nbytes = str->WriteOneByte (dst, 0 , buflen, flags);
377
346
}
378
- if (chars_written != nullptr )
379
- *chars_written = nbytes;
347
+ *chars_written = nbytes;
380
348
break ;
381
349
382
350
case BUFFER:
@@ -387,14 +355,8 @@ size_t StringBytes::Write(Isolate* isolate,
387
355
case UCS2: {
388
356
size_t nchars;
389
357
390
- if (is_extern && !str->IsOneByte ()) {
391
- memcpy (buf, data, nbytes);
392
- nchars = nbytes / sizeof (uint16_t );
393
- } else {
394
- nbytes = WriteUCS2 (buf, buflen, str, flags, &nchars);
395
- }
396
- if (chars_written != nullptr )
397
- *chars_written = nchars;
358
+ nbytes = WriteUCS2 (buf, buflen, str, flags, &nchars);
359
+ *chars_written = static_cast <int >(nchars);
398
360
399
361
// Node's "ucs2" encoding wants LE character data stored in
400
362
// the Buffer, so we need to reorder on BE platforms. See
@@ -407,27 +369,25 @@ size_t StringBytes::Write(Isolate* isolate,
407
369
}
408
370
409
371
case BASE64:
410
- if (is_extern) {
411
- nbytes = base64_decode (buf, buflen, data, external_nbytes);
372
+ if (str->IsExternalOneByte ()) {
373
+ auto ext = str->GetExternalOneByteStringResource ();
374
+ nbytes = base64_decode (buf, buflen, ext->data (), ext->length ());
412
375
} else {
413
376
String::Value value (str);
414
377
nbytes = base64_decode (buf, buflen, *value, value.length ());
415
378
}
416
- if (chars_written != nullptr ) {
417
- *chars_written = nbytes;
418
- }
379
+ *chars_written = nbytes;
419
380
break ;
420
381
421
382
case HEX:
422
- if (is_extern) {
423
- nbytes = hex_decode (buf, buflen, data, external_nbytes);
383
+ if (str->IsExternalOneByte ()) {
384
+ auto ext = str->GetExternalOneByteStringResource ();
385
+ nbytes = hex_decode (buf, buflen, ext->data (), ext->length ());
424
386
} else {
425
387
String::Value value (str);
426
388
nbytes = hex_decode (buf, buflen, *value, value.length ());
427
389
}
428
- if (chars_written != nullptr ) {
429
- *chars_written = nbytes;
430
- }
390
+ *chars_written = nbytes;
431
391
break ;
432
392
433
393
default :
@@ -504,49 +464,34 @@ size_t StringBytes::Size(Isolate* isolate,
504
464
Local<Value> val,
505
465
enum encoding encoding) {
506
466
HandleScope scope (isolate);
507
- size_t data_size = 0 ;
508
- bool is_buffer = Buffer::HasInstance (val);
509
467
510
- if (is_buffer && (encoding == BUFFER || encoding == LATIN1))
468
+ if (Buffer::HasInstance (val) && (encoding == BUFFER || encoding == LATIN1))
511
469
return Buffer::Length (val);
512
470
513
- const char * data;
514
- if (GetExternalParts (val, &data, &data_size))
515
- return data_size;
516
-
517
471
Local<String> str = val->ToString (isolate);
518
472
519
473
switch (encoding) {
520
474
case ASCII:
521
475
case LATIN1:
522
- data_size = str->Length ();
523
- break ;
476
+ return str->Length ();
524
477
525
478
case BUFFER:
526
479
case UTF8:
527
- data_size = str->Utf8Length ();
528
- break ;
480
+ return str->Utf8Length ();
529
481
530
482
case UCS2:
531
- data_size = str->Length () * sizeof (uint16_t );
532
- break ;
483
+ return str->Length () * sizeof (uint16_t );
533
484
534
485
case BASE64: {
535
486
String::Value value (str);
536
- data_size = base64_decoded_size (*value, value.length ());
537
- break ;
487
+ return base64_decoded_size (*value, value.length ());
538
488
}
539
489
540
490
case HEX:
541
- data_size = str->Length () / 2 ;
542
- break ;
543
-
544
- default :
545
- CHECK (0 && " unknown encoding" );
546
- break ;
491
+ return str->Length () / 2 ;
547
492
}
548
493
549
- return data_size ;
494
+ UNREACHABLE () ;
550
495
}
551
496
552
497
0 commit comments