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,
@@ -347,32 +316,31 @@ size_t StringBytes::Write(Isolate* isolate,
347
316
enum encoding encoding,
348
317
int * chars_written) {
349
318
HandleScope scope (isolate);
350
- const char * data = nullptr ;
351
- size_t nbytes = 0 ;
352
- const bool is_extern = GetExternalParts (val, &data, &nbytes);
353
- const size_t external_nbytes = nbytes;
319
+ size_t nbytes;
320
+ int nchars;
321
+
322
+ if (chars_written == nullptr )
323
+ chars_written = &nchars;
354
324
355
325
CHECK (val->IsString () == true );
356
326
Local<String> str = val.As <String>();
357
327
358
- if (nbytes > buflen)
359
- nbytes = buflen;
360
-
361
328
int flags = String::HINT_MANY_WRITES_EXPECTED |
362
329
String::NO_NULL_TERMINATION |
363
330
String::REPLACE_INVALID_UTF8;
364
331
365
332
switch (encoding) {
366
333
case ASCII:
367
334
case LATIN1:
368
- if (is_extern && str->IsOneByte ()) {
369
- memcpy (buf, data, nbytes);
335
+ if (str->IsExternalOneByte ()) {
336
+ auto ext = str->GetExternalOneByteStringResource ();
337
+ nbytes = std::min (buflen, ext->length ());
338
+ memcpy (buf, ext->data (), nbytes);
370
339
} else {
371
340
uint8_t * const dst = reinterpret_cast <uint8_t *>(buf);
372
341
nbytes = str->WriteOneByte (dst, 0 , buflen, flags);
373
342
}
374
- if (chars_written != nullptr )
375
- *chars_written = nbytes;
343
+ *chars_written = nbytes;
376
344
break ;
377
345
378
346
case BUFFER:
@@ -383,14 +351,8 @@ size_t StringBytes::Write(Isolate* isolate,
383
351
case UCS2: {
384
352
size_t nchars;
385
353
386
- if (is_extern && !str->IsOneByte ()) {
387
- memcpy (buf, data, nbytes);
388
- nchars = nbytes / sizeof (uint16_t );
389
- } else {
390
- nbytes = WriteUCS2 (buf, buflen, str, flags, &nchars);
391
- }
392
- if (chars_written != nullptr )
393
- *chars_written = nchars;
354
+ nbytes = WriteUCS2 (buf, buflen, str, flags, &nchars);
355
+ *chars_written = static_cast <int >(nchars);
394
356
395
357
// Node's "ucs2" encoding wants LE character data stored in
396
358
// the Buffer, so we need to reorder on BE platforms. See
@@ -403,27 +365,25 @@ size_t StringBytes::Write(Isolate* isolate,
403
365
}
404
366
405
367
case BASE64:
406
- if (is_extern) {
407
- nbytes = base64_decode (buf, buflen, data, external_nbytes);
368
+ if (str->IsExternalOneByte ()) {
369
+ auto ext = str->GetExternalOneByteStringResource ();
370
+ nbytes = base64_decode (buf, buflen, ext->data (), ext->length ());
408
371
} else {
409
372
String::Value value (str);
410
373
nbytes = base64_decode (buf, buflen, *value, value.length ());
411
374
}
412
- if (chars_written != nullptr ) {
413
- *chars_written = nbytes;
414
- }
375
+ *chars_written = nbytes;
415
376
break ;
416
377
417
378
case HEX:
418
- if (is_extern) {
419
- nbytes = hex_decode (buf, buflen, data, external_nbytes);
379
+ if (str->IsExternalOneByte ()) {
380
+ auto ext = str->GetExternalOneByteStringResource ();
381
+ nbytes = hex_decode (buf, buflen, ext->data (), ext->length ());
420
382
} else {
421
383
String::Value value (str);
422
384
nbytes = hex_decode (buf, buflen, *value, value.length ());
423
385
}
424
- if (chars_written != nullptr ) {
425
- *chars_written = nbytes;
426
- }
386
+ *chars_written = nbytes;
427
387
break ;
428
388
429
389
default :
@@ -500,49 +460,34 @@ size_t StringBytes::Size(Isolate* isolate,
500
460
Local<Value> val,
501
461
enum encoding encoding) {
502
462
HandleScope scope (isolate);
503
- size_t data_size = 0 ;
504
- bool is_buffer = Buffer::HasInstance (val);
505
463
506
- if (is_buffer && (encoding == BUFFER || encoding == LATIN1))
464
+ if (Buffer::HasInstance (val) && (encoding == BUFFER || encoding == LATIN1))
507
465
return Buffer::Length (val);
508
466
509
- const char * data;
510
- if (GetExternalParts (val, &data, &data_size))
511
- return data_size;
512
-
513
467
Local<String> str = val->ToString (isolate);
514
468
515
469
switch (encoding) {
516
470
case ASCII:
517
471
case LATIN1:
518
- data_size = str->Length ();
519
- break ;
472
+ return str->Length ();
520
473
521
474
case BUFFER:
522
475
case UTF8:
523
- data_size = str->Utf8Length ();
524
- break ;
476
+ return str->Utf8Length ();
525
477
526
478
case UCS2:
527
- data_size = str->Length () * sizeof (uint16_t );
528
- break ;
479
+ return str->Length () * sizeof (uint16_t );
529
480
530
481
case BASE64: {
531
482
String::Value value (str);
532
- data_size = base64_decoded_size (*value, value.length ());
533
- break ;
483
+ return base64_decoded_size (*value, value.length ());
534
484
}
535
485
536
486
case HEX:
537
- data_size = str->Length () / 2 ;
538
- break ;
539
-
540
- default :
541
- CHECK (0 && " unknown encoding" );
542
- break ;
487
+ return str->Length () / 2 ;
543
488
}
544
489
545
- return data_size ;
490
+ UNREACHABLE () ;
546
491
}
547
492
548
493
0 commit comments