|
3 | 3 | import { BLOCK_MAXSIZE } from "./rt/common";
|
4 | 4 | import { COMPARATOR, SORT } from "./util/sort";
|
5 | 5 | import { ArrayBuffer, ArrayBufferView } from "./arraybuffer";
|
6 |
| -import { itoa, dtoa, itoa_stream, dtoa_stream, MAX_DOUBLE_LENGTH } from "./util/number"; |
| 6 | +import { joinBooleanArray, joinIntegerArray, joinFloatArray, joinStringArray, joinArrays, joinObjectArray } from "./util/string"; |
7 | 7 | import { idof, isArray as builtin_isArray } from "./builtins";
|
8 | 8 | import { E_INDEXOUTOFRANGE, E_INVALIDLENGTH, E_EMPTYARRAY, E_HOLEYARRAY } from "./util/error";
|
9 | 9 |
|
@@ -477,247 +477,18 @@ export class Array<T> extends ArrayBufferView {
|
477 | 477 | }
|
478 | 478 |
|
479 | 479 | join(separator: string = ","): string {
|
480 |
| - if (isBoolean<T>()) return this.join_bool(separator); |
481 |
| - if (isInteger<T>()) return this.join_int(separator); |
482 |
| - if (isFloat<T>()) return this.join_flt(separator); |
483 |
| - if (isString<T>()) return this.join_str(separator); |
484 |
| - if (isArray<T>()) return this.join_arr(separator); |
485 |
| - if (isReference<T>()) return this.join_ref(separator); |
| 480 | + var dataStart = this.dataStart; |
| 481 | + var length = this.length_; |
| 482 | + if (isString<T>()) return joinStringArray(dataStart, length, separator); |
| 483 | + if (isBoolean<T>()) return joinBooleanArray(dataStart, length, separator); |
| 484 | + if (isInteger<T>()) return joinIntegerArray<T>(dataStart, length, separator); |
| 485 | + if (isFloat<T>()) return joinFloatArray<T>(dataStart, length, separator); |
| 486 | + if (isArray<T>()) return joinArrays<T>(dataStart, length, separator); |
| 487 | + if (isReference<T>()) return joinObjectArray<T>(dataStart, length, separator); |
486 | 488 | ERROR("unspported element type");
|
487 | 489 | return <string>unreachable();
|
488 | 490 | }
|
489 | 491 |
|
490 |
| - private join_bool(separator: string = ","): string { |
491 |
| - var lastIndex = this.length_ - 1; |
492 |
| - if (lastIndex < 0) return ""; |
493 |
| - var dataStart = this.dataStart; |
494 |
| - if (!lastIndex) return select("true", "false", load<bool>(dataStart)); |
495 |
| - |
496 |
| - var sepLen = separator.length; |
497 |
| - var valueLen = 5; // max possible length of element len("false") |
498 |
| - var estLen = (valueLen + sepLen) * lastIndex + valueLen; |
499 |
| - var result = changetype<string>(__alloc(estLen << 1, idof<string>())); // retains |
500 |
| - var offset = 0; |
501 |
| - var value: bool; |
502 |
| - for (let i = 0; i < lastIndex; ++i) { |
503 |
| - value = load<bool>(dataStart + i); |
504 |
| - valueLen = 4 + i32(!value); |
505 |
| - memory.copy( |
506 |
| - changetype<usize>(result) + (<usize>offset << 1), |
507 |
| - changetype<usize>(select("true", "false", value)), |
508 |
| - <usize>valueLen << 1 |
509 |
| - ); |
510 |
| - offset += valueLen; |
511 |
| - if (sepLen) { |
512 |
| - memory.copy( |
513 |
| - changetype<usize>(result) + (<usize>offset << 1), |
514 |
| - changetype<usize>(separator), |
515 |
| - <usize>sepLen << 1 |
516 |
| - ); |
517 |
| - offset += sepLen; |
518 |
| - } |
519 |
| - } |
520 |
| - value = load<bool>(dataStart + <usize>lastIndex); |
521 |
| - valueLen = 4 + i32(!value); |
522 |
| - memory.copy( |
523 |
| - changetype<usize>(result) + (<usize>offset << 1), |
524 |
| - changetype<usize>(select("true", "false", value)), |
525 |
| - valueLen << 1 |
526 |
| - ); |
527 |
| - offset += valueLen; |
528 |
| - |
529 |
| - if (estLen > offset) return result.substring(0, offset); |
530 |
| - return result; |
531 |
| - } |
532 |
| - |
533 |
| - private join_int(separator: string = ","): string { |
534 |
| - var lastIndex = this.length_ - 1; |
535 |
| - if (lastIndex < 0) return ""; |
536 |
| - var dataStart = this.dataStart; |
537 |
| - // @ts-ignore: type |
538 |
| - if (!lastIndex) return changetype<string>(itoa<T>(load<T>(dataStart))); // retains |
539 |
| - |
540 |
| - var sepLen = separator.length; |
541 |
| - const valueLen = (sizeof<T>() <= 4 ? 10 : 20) + i32(isSigned<T>()); |
542 |
| - var estLen = (valueLen + sepLen) * lastIndex + valueLen; |
543 |
| - var result = changetype<string>(__alloc(estLen << 1, idof<string>())); // retains |
544 |
| - var offset = 0; |
545 |
| - var value: T; |
546 |
| - for (let i = 0; i < lastIndex; ++i) { |
547 |
| - value = load<T>(dataStart + (<usize>i << alignof<T>())); |
548 |
| - // @ts-ignore: type |
549 |
| - offset += itoa_stream<T>(changetype<usize>(result), offset, value); |
550 |
| - if (sepLen) { |
551 |
| - memory.copy( |
552 |
| - changetype<usize>(result) + (<usize>offset << 1), |
553 |
| - changetype<usize>(separator), |
554 |
| - <usize>sepLen << 1 |
555 |
| - ); |
556 |
| - offset += sepLen; |
557 |
| - } |
558 |
| - } |
559 |
| - value = load<T>(dataStart + (<usize>lastIndex << alignof<T>())); |
560 |
| - // @ts-ignore: type |
561 |
| - offset += itoa_stream<T>(changetype<usize>(result), offset, value); |
562 |
| - if (estLen > offset) return result.substring(0, offset); |
563 |
| - return result; |
564 |
| - } |
565 |
| - |
566 |
| - private join_flt(separator: string = ","): string { |
567 |
| - var lastIndex = this.length_ - 1; |
568 |
| - if (lastIndex < 0) return ""; |
569 |
| - var dataStart = this.dataStart; |
570 |
| - if (!lastIndex) { |
571 |
| - return changetype<string>(dtoa( |
572 |
| - // @ts-ignore: type |
573 |
| - load<T>(dataStart)) |
574 |
| - ); // retains |
575 |
| - } |
576 |
| - |
577 |
| - const valueLen = MAX_DOUBLE_LENGTH; |
578 |
| - var sepLen = separator.length; |
579 |
| - var estLen = (valueLen + sepLen) * lastIndex + valueLen; |
580 |
| - var result = changetype<string>(__alloc(estLen << 1, idof<string>())); // retains |
581 |
| - var offset = 0; |
582 |
| - var value: T; |
583 |
| - for (let i = 0; i < lastIndex; ++i) { |
584 |
| - value = load<T>(dataStart + (<usize>i << alignof<T>())); |
585 |
| - offset += dtoa_stream(changetype<usize>(result), offset, |
586 |
| - // @ts-ignore: type |
587 |
| - value |
588 |
| - ); |
589 |
| - if (sepLen) { |
590 |
| - memory.copy( |
591 |
| - changetype<usize>(result) + (<usize>offset << 1), |
592 |
| - changetype<usize>(separator), |
593 |
| - <usize>sepLen << 1 |
594 |
| - ); |
595 |
| - offset += sepLen; |
596 |
| - } |
597 |
| - } |
598 |
| - value = load<T>(dataStart + (<usize>lastIndex << alignof<T>())); |
599 |
| - offset += dtoa_stream(changetype<usize>(result), offset, |
600 |
| - // @ts-ignore: type |
601 |
| - value |
602 |
| - ); |
603 |
| - if (estLen > offset) return result.substring(0, offset); |
604 |
| - return result; |
605 |
| - } |
606 |
| - |
607 |
| - private join_str(separator: string = ","): string { |
608 |
| - var lastIndex = this.length_ - 1; |
609 |
| - if (lastIndex < 0) return ""; |
610 |
| - var dataStart = this.dataStart; |
611 |
| - if (!lastIndex) return load<string>(dataStart); |
612 |
| - |
613 |
| - var sepLen = separator.length; |
614 |
| - var estLen = 0; |
615 |
| - var value: string | null; |
616 |
| - for (let i = 0, len = lastIndex + 1; i < len; ++i) { |
617 |
| - value = load<string>(dataStart + (<usize>i << alignof<T>())); |
618 |
| - if (value !== null) estLen += value.length; |
619 |
| - } |
620 |
| - var offset = 0; |
621 |
| - var result = changetype<string>(__alloc((estLen + sepLen * lastIndex) << 1, idof<string>())); // retains |
622 |
| - for (let i = 0; i < lastIndex; ++i) { |
623 |
| - value = load<string>(dataStart + (<usize>i << alignof<T>())); |
624 |
| - if (value !== null) { |
625 |
| - let valueLen = changetype<string>(value).length; |
626 |
| - memory.copy( |
627 |
| - changetype<usize>(result) + (<usize>offset << 1), |
628 |
| - changetype<usize>(value), |
629 |
| - <usize>valueLen << 1 |
630 |
| - ); |
631 |
| - offset += valueLen; |
632 |
| - } |
633 |
| - if (sepLen) { |
634 |
| - memory.copy( |
635 |
| - changetype<usize>(result) + (<usize>offset << 1), |
636 |
| - changetype<usize>(separator), |
637 |
| - <usize>sepLen << 1 |
638 |
| - ); |
639 |
| - offset += sepLen; |
640 |
| - } |
641 |
| - } |
642 |
| - value = load<string>(dataStart + (<usize>lastIndex << alignof<T>())); |
643 |
| - if (value !== null) { |
644 |
| - memory.copy( |
645 |
| - changetype<usize>(result) + (<usize>offset << 1), |
646 |
| - changetype<usize>(value), |
647 |
| - <usize>changetype<string>(value).length << 1 |
648 |
| - ); |
649 |
| - } |
650 |
| - return result; |
651 |
| - } |
652 |
| - |
653 |
| - private join_arr(separator: string = ","): string { |
654 |
| - var lastIndex = this.length_ - 1; |
655 |
| - if (lastIndex < 0) return ""; |
656 |
| - |
657 |
| - var result = ""; |
658 |
| - var sepLen = separator.length; |
659 |
| - var base = this.dataStart; |
660 |
| - var value: T; |
661 |
| - if (!lastIndex) { |
662 |
| - value = load<T>(base); |
663 |
| - // @ts-ignore: type |
664 |
| - return value ? value.join(separator) : ""; |
665 |
| - } |
666 |
| - for (let i = 0; i < lastIndex; ++i) { |
667 |
| - value = load<T>(base + (<usize>i << alignof<T>())); |
668 |
| - // @ts-ignore: type |
669 |
| - if (value) result += value.join(separator); |
670 |
| - if (sepLen) result += separator; |
671 |
| - } |
672 |
| - value = load<T>(base + (<usize>lastIndex << alignof<T>())); |
673 |
| - // @ts-ignore: type |
674 |
| - if (value) result += value.join(separator); |
675 |
| - return result; // registered by concatenation (FIXME: lots of garbage) |
676 |
| - } |
677 |
| - |
678 |
| - private join_ref(separator: string = ","): string { |
679 |
| - var lastIndex = this.length_ - 1; |
680 |
| - if (lastIndex < 0) return ""; |
681 |
| - var base = this.dataStart; |
682 |
| - if (!lastIndex) return "[object Object]"; |
683 |
| - |
684 |
| - const valueLen = 15; // max possible length of element len("[object Object]") |
685 |
| - var sepLen = separator.length; |
686 |
| - var estLen = (valueLen + sepLen) * lastIndex + valueLen; |
687 |
| - var result = changetype<string>(__alloc(estLen << 1, idof<string>())); |
688 |
| - var offset = 0; |
689 |
| - var value: T; |
690 |
| - for (let i = 0; i < lastIndex; ++i) { |
691 |
| - value = load<T>(base + (<usize>i << alignof<T>())); |
692 |
| - if (value) { |
693 |
| - memory.copy( |
694 |
| - changetype<usize>(result) + (<usize>offset << 1), |
695 |
| - changetype<usize>("[object Object]"), |
696 |
| - <usize>valueLen << 1 |
697 |
| - ); |
698 |
| - offset += valueLen; |
699 |
| - } |
700 |
| - if (sepLen) { |
701 |
| - memory.copy( |
702 |
| - changetype<usize>(result) + (<usize>offset << 1), |
703 |
| - changetype<usize>(separator), |
704 |
| - <usize>sepLen << 1 |
705 |
| - ); |
706 |
| - offset += sepLen; |
707 |
| - } |
708 |
| - } |
709 |
| - if (load<T>(base + (<usize>lastIndex << alignof<T>()))) { |
710 |
| - memory.copy( |
711 |
| - changetype<usize>(result) + (<usize>offset << 1), |
712 |
| - changetype<usize>("[object Object]"), |
713 |
| - <usize>valueLen << 1 |
714 |
| - ); |
715 |
| - offset += valueLen; |
716 |
| - } |
717 |
| - if (estLen > offset) return result.substring(0, offset); |
718 |
| - return result; |
719 |
| - } |
720 |
| - |
721 | 492 | toString(): string {
|
722 | 493 | return this.join();
|
723 | 494 | }
|
|
0 commit comments