@@ -95,6 +95,7 @@ Safety notes:
95
95
*/
96
96
fn of_substr ( str : @str , byte_offset : uint , byte_len : uint ) -> rope {
97
97
if byte_len == 0 u { ret node:: empty; }
98
+ if byte_offset + byte_len > str:: byte_len ( * str) { fail; }
98
99
ret node:: content ( node:: of_substr ( str, byte_offset, byte_len) ) ;
99
100
}
100
101
@@ -702,18 +703,50 @@ mod node {
702
703
}
703
704
704
705
/*
706
+ Function: of_substr
707
+
705
708
Adopt a slice of a string as a node.
706
709
707
710
If the slice is longer than `max_leaf_char_len`, it is logically split
708
711
between as many leaves as necessary. Regardless, the string itself
709
712
is not copied.
710
713
711
- @param byte_start The byte offset where the slice of `str` starts.
712
- @param byte_len The number of bytes from `str` to use.
714
+ Parameters:
715
+ byte_start - The byte offset where the slice of `str` starts.
716
+ byte_len - The number of bytes from `str` to use.
717
+
718
+ Safety note:
719
+ - Behavior is undefined if `byte_start` or `byte_len` do not represent
720
+ valid positions in `str`
713
721
*/
714
722
fn of_substr ( str : @str , byte_start : uint , byte_len : uint ) -> @node {
715
- assert ( byte_len > 0 u) ;
716
- let char_len = str:: char_len_range ( * str, byte_start, byte_len) ;
723
+ ret of_substr_unsafer ( str, byte_start, byte_len,
724
+ str:: char_len_range ( * str, byte_start, byte_len) ) ;
725
+ }
726
+
727
+ /*
728
+ Function: of_substr_unsafer
729
+
730
+ Adopt a slice of a string as a node.
731
+
732
+ If the slice is longer than `max_leaf_char_len`, it is logically split
733
+ between as many leaves as necessary. Regardless, the string itself
734
+ is not copied.
735
+
736
+ byte_start - The byte offset where the slice of `str` starts.
737
+ byte_len - The number of bytes from `str` to use.
738
+ char_len - The number of chars in `str` in the interval
739
+ [byte_start, byte_start+byte_len(
740
+
741
+ Safety note:
742
+ - Behavior is undefined if `byte_start` or `byte_len` do not represent
743
+ valid positions in `str`
744
+ - Behavior is undefined if `char_len` does not accurately represent the
745
+ number of chars between byte_start and byte_start+byte_len
746
+ */
747
+ fn of_substr_unsafer ( str : @str , byte_start : uint , byte_len : uint ,
748
+ char_len : uint ) -> @node {
749
+ assert ( byte_start + byte_len <= str:: byte_len ( * str) ) ;
717
750
let candidate = @leaf ( {
718
751
byte_offset: byte_start,
719
752
byte_len: byte_len,
@@ -784,6 +817,15 @@ mod node {
784
817
}
785
818
786
819
820
+ /*
821
+ Function: tree_from_forest_destructive
822
+
823
+ Concatenate a forest of nodes into one tree.
824
+
825
+ Parameters:
826
+ forest - The forest. This vector is progressively rewritten during
827
+ execution and should be discarded as meaningless afterwards.
828
+ */
787
829
fn tree_from_forest_destructive ( forest : [ mutable @node] ) -> @node {
788
830
let i = 0 u;
789
831
let len = vec:: len ( forest) ;
@@ -796,17 +838,26 @@ mod node {
796
838
let right_len= char_len ( right) ;
797
839
let left_height= height ( left) ;
798
840
let right_height=height ( right) ;
799
- if left_len + right_len > hint_max_leaf_char_len
800
- //TODO: Improve strategy
801
- || left_height >= hint_max_node_height
802
- || right_height >= hint_max_node_height {
841
+ if left_len + right_len > hint_max_leaf_char_len {
803
842
if left_len <= hint_max_leaf_char_len {
804
843
left = flatten ( left) ;
844
+ left_height = height ( left) ;
805
845
}
806
846
if right_len <= hint_max_leaf_char_len {
807
847
right = flatten ( right) ;
848
+ right_height = height ( right) ;
808
849
}
809
850
}
851
+ if left_height >= hint_max_node_height {
852
+ left = of_substr_unsafer ( @serialize_node ( left) ,
853
+ 0 u, byte_len ( left) ,
854
+ left_len) ;
855
+ }
856
+ if right_height >= hint_max_node_height {
857
+ right = of_substr_unsafer ( @serialize_node ( right) ,
858
+ 0 u, byte_len ( right) ,
859
+ right_len) ;
860
+ }
810
861
forest[ i/2 u] = concat2 ( left, right) ;
811
862
i += 2 u;
812
863
}
0 commit comments