@@ -59,7 +59,6 @@ const { |
59 | 59 | compare: _compare, |
60 | 60 | compareOffset, |
61 | 61 | copy: _copy, |
62 | | - createFromString, |
63 | 62 | fill: bindingFill, |
64 | 63 | isAscii: bindingIsAscii, |
65 | 64 | isUtf8: bindingIsUtf8, |
@@ -150,11 +149,12 @@ const constants = ObjectDefineProperties({}, { |
150 | 149 | }); |
151 | 150 |
|
152 | 151 | Buffer.poolSize = 8 * 1024; |
153 | | -let poolSize, poolOffset, allocPool; |
| 152 | +let poolSize, poolOffset, allocPool, allocBuffer; |
154 | 153 |
|
155 | 154 | function createPool() { |
156 | 155 | poolSize = Buffer.poolSize; |
157 | | - allocPool = createUnsafeBuffer(poolSize).buffer; |
| 156 | + allocBuffer = createUnsafeBuffer(poolSize); |
| 157 | + allocPool = allocBuffer.buffer; |
158 | 158 | markAsUntransferable(allocPool); |
159 | 159 | poolOffset = 0; |
160 | 160 | } |
@@ -442,38 +442,49 @@ function allocate(size) { |
442 | 442 | } |
443 | 443 |
|
444 | 444 | function fromStringFast(string, ops) { |
445 | | - const length = ops.byteLength(string); |
| 445 | + const maxLength = Buffer.poolSize >>> 1; |
446 | 446 |
|
447 | | - if (length >= (Buffer.poolSize >>> 1)) |
448 | | - return createFromString(string, ops.encodingVal); |
| 447 | + let length = string.length; // Min length |
| 448 | + |
| 449 | + if (length >= maxLength) |
| 450 | + return createFromString(string, ops); |
| 451 | + |
| 452 | + length *= 4; // Max length (4 bytes per character) |
| 453 | + |
| 454 | + if (length >= maxLength) |
| 455 | + length = ops.byteLength(string); // Actual length |
| 456 | + |
| 457 | + if (length >= maxLength) |
| 458 | + return createFromString(string, ops, length); |
449 | 459 |
|
450 | 460 | if (length > (poolSize - poolOffset)) |
451 | 461 | createPool(); |
452 | | - let b = new FastBuffer(allocPool, poolOffset, length); |
453 | | - const actual = ops.write(b, string, 0, length); |
454 | | - if (actual !== length) { |
455 | | - // byteLength() may overestimate. That's a rare case, though. |
456 | | - b = new FastBuffer(allocPool, poolOffset, actual); |
457 | | - } |
| 462 | + |
| 463 | + const actual = ops.write(allocBuffer, string, poolOffset, length); |
| 464 | + const b = new FastBuffer(allocPool, poolOffset, actual); |
| 465 | + |
458 | 466 | poolOffset += actual; |
459 | 467 | alignPool(); |
460 | 468 | return b; |
461 | 469 | } |
462 | 470 |
|
| 471 | +function createFromString(string, ops, length = ops.byteLength(string)) { |
| 472 | + const buf = Buffer.allocUnsafeSlow(length); |
| 473 | + const actual = ops.write(buf, string, 0, length); |
| 474 | + return actual < length ? new FastBuffer(buf.buffer, 0, actual) : buf; |
| 475 | +} |
| 476 | + |
463 | 477 | function fromString(string, encoding) { |
464 | 478 | let ops; |
465 | | - if (typeof encoding !== 'string' || encoding.length === 0) { |
466 | | - if (string.length === 0) |
467 | | - return new FastBuffer(); |
| 479 | + if (!encoding || encoding === 'utf8') { |
468 | 480 | ops = encodingOps.utf8; |
469 | 481 | } else { |
470 | 482 | ops = getEncodingOps(encoding); |
471 | 483 | if (ops === undefined) |
472 | 484 | throw new ERR_UNKNOWN_ENCODING(encoding); |
473 | | - if (string.length === 0) |
474 | | - return new FastBuffer(); |
475 | 485 | } |
476 | | - return fromStringFast(string, ops); |
| 486 | + |
| 487 | + return string.length === 0 ? new FastBuffer() : fromStringFast(string, ops); |
477 | 488 | } |
478 | 489 |
|
479 | 490 | function fromArrayBuffer(obj, byteOffset, length) { |
|