|
43 | 43 | //! ```
|
44 | 44 |
|
45 | 45 | use crate::array::{ArrayTrait, Span, SpanTrait};
|
| 46 | +use crate::bytes_31::split_bytes31; |
46 | 47 | #[allow(unused_imports)]
|
47 | 48 | use crate::bytes_31::{
|
48 | 49 | BYTES_IN_BYTES31, Bytes31Trait, POW_2_128, POW_2_8, U128IntoBytes31, U8IntoBytes31,
|
@@ -658,6 +659,48 @@ pub impl ByteSpanImpl of ByteSpanTrait {
|
658 | 659 | fn is_empty(self: ByteSpan) -> bool {
|
659 | 660 | self.remainder_len == 0 && self.data.len() == 0
|
660 | 661 | }
|
| 662 | + |
| 663 | + /// Converts a `ByteSpan` into a `ByteArray`. |
| 664 | + /// The cast includes trimming the start_offset of the first word of the span (which is created |
| 665 | + /// when slicing). |
| 666 | + /// |
| 667 | + /// Note: creating `ByteArray.data` from `Span` requires allocating a new memory |
| 668 | + /// segment for the returned array, and *O*(*n*) operations to populate the array with the |
| 669 | + /// content of the span (see also `SpanIntoArray`). |
| 670 | + fn to_byte_array(mut self: ByteSpan) -> ByteArray { |
| 671 | + let remainder_len = upcast(self.remainder_len); |
| 672 | + let Some(first_word) = self.data.pop_front() else { |
| 673 | + // Slice is included entirely in the remainder word. |
| 674 | + let len_without_offset: usize = remainder_len - upcast(self.first_char_start_offset); |
| 675 | + let (start_offset_trimmed, _) = split_bytes31( |
| 676 | + self.remainder_word, remainder_len, len_without_offset, |
| 677 | + ); |
| 678 | + return ByteArray { |
| 679 | + data: array![], |
| 680 | + pending_word: start_offset_trimmed, |
| 681 | + pending_word_len: upcast(len_without_offset), |
| 682 | + }; |
| 683 | + }; |
| 684 | + |
| 685 | + let mut ba = Default::default(); |
| 686 | + let n_bytes_to_append = BYTES_IN_BYTES31 - upcast(self.first_char_start_offset); |
| 687 | + let (first_word_no_offset, _) = split_bytes31( |
| 688 | + (*first_word).into(), BYTES_IN_BYTES31, n_bytes_to_append, |
| 689 | + ); |
| 690 | + ba.append_word(first_word_no_offset, n_bytes_to_append); |
| 691 | + |
| 692 | + // Append the rest of the span parts, now that the first word was popped. |
| 693 | + ba.append_from_parts(self.data, self.remainder_word, upcast(self.remainder_len)); |
| 694 | + ba |
| 695 | + } |
| 696 | +} |
| 697 | + |
| 698 | +impl ByteSpanDefault of Default<ByteSpan> { |
| 699 | + fn default() -> ByteSpan { |
| 700 | + ByteSpan { |
| 701 | + data: [].span(), first_char_start_offset: 0, remainder_word: 0, remainder_len: 0, |
| 702 | + } |
| 703 | + } |
661 | 704 | }
|
662 | 705 |
|
663 | 706 | /// Trait for types that can be converted into a `ByteSpan`.
|
|
0 commit comments