@@ -679,27 +679,22 @@ impl [u8] {
679679 let mut read_offset = 0 ;
680680 let mut write_offset = 0 ;
681681
682- let mut buffer = [ 0 ; 4 ] ;
683682 while let Some ( ( codepoint, width) ) =
684683 unsafe { core:: str:: next_code_point_with_width ( & mut self [ read_offset..] . iter ( ) ) }
685684 {
686685 read_offset += width;
686+ dump_queue ( & mut queue, & mut self [ ..read_offset] , & mut write_offset) ;
687687 let lowercase_char = unsafe { char:: from_u32_unchecked ( codepoint) } ;
688688 for c in lowercase_char. to_uppercase ( ) {
689- let l = c. len_utf8 ( ) ;
690- c. encode_utf8 ( & mut buffer) ;
691- queue. extend ( & buffer[ ..l] ) ;
692- }
693- while write_offset < read_offset {
694- match queue. pop_front ( ) {
695- Some ( b) => {
696- self [ write_offset] = b;
697- write_offset += 1 ;
698- }
699- None => break ,
700- }
689+ encode_to_slice_or_else_to_queue (
690+ c,
691+ & mut queue,
692+ & mut self [ ..read_offset] ,
693+ & mut write_offset,
694+ ) ;
701695 }
702696 }
697+ dump_queue ( & mut queue, & mut self [ ..read_offset] , & mut write_offset) ;
703698 assert_eq ! ( read_offset, self . len( ) ) ;
704699 if write_offset < read_offset { Ok ( write_offset) } else { Err ( queue) }
705700 }
@@ -715,12 +710,12 @@ impl [u8] {
715710 let mut read_offset = 0 ;
716711 let mut write_offset = 0 ;
717712
718- let mut buffer = [ 0 ; 4 ] ;
719713 let mut final_sigma_automata = FinalSigmaAutomata :: new ( ) ;
720714 while let Some ( ( codepoint, width) ) =
721715 unsafe { core:: str:: next_code_point_with_width ( & mut self [ read_offset..] . iter ( ) ) }
722716 {
723717 read_offset += width;
718+ dump_queue ( & mut queue, & mut self [ ..read_offset] , & mut write_offset) ;
724719 let uppercase_char = unsafe { char:: from_u32_unchecked ( codepoint) } ;
725720 if uppercase_char == 'Σ' {
726721 // Σ maps to σ, except at the end of a word where it maps to ς.
@@ -729,27 +724,25 @@ impl [u8] {
729724 let is_word_final =
730725 final_sigma_automata. is_accepting ( ) && !case_ignorable_then_cased ( rest. chars ( ) ) ;
731726 let sigma_lowercase = if is_word_final { 'ς' } else { 'σ' } ;
732- let l = sigma_lowercase. len_utf8 ( ) ;
733- sigma_lowercase. encode_utf8 ( & mut buffer) ;
734- queue. extend ( & buffer[ ..l] ) ;
727+ encode_to_slice_or_else_to_queue (
728+ sigma_lowercase,
729+ & mut queue,
730+ & mut self [ ..read_offset] ,
731+ & mut write_offset,
732+ ) ;
735733 } else {
736734 for c in uppercase_char. to_lowercase ( ) {
737- let l = c. len_utf8 ( ) ;
738- c. encode_utf8 ( & mut buffer) ;
739- queue. extend ( & buffer[ ..l] ) ;
735+ encode_to_slice_or_else_to_queue (
736+ c,
737+ & mut queue,
738+ & mut self [ ..read_offset] ,
739+ & mut write_offset,
740+ ) ;
740741 }
741742 }
742743 final_sigma_automata. step ( uppercase_char) ;
743- while write_offset < read_offset {
744- match queue. pop_front ( ) {
745- Some ( b) => {
746- self [ write_offset] = b;
747- write_offset += 1 ;
748- }
749- None => break ,
750- }
751- }
752744 }
745+ dump_queue ( & mut queue, & mut self [ ..read_offset] , & mut write_offset) ;
753746 assert_eq ! ( read_offset, self . len( ) ) ;
754747 return if write_offset < read_offset { Ok ( write_offset) } else { Err ( queue) } ;
755748
@@ -764,6 +757,33 @@ impl [u8] {
764757 }
765758}
766759
760+ fn encode_to_slice_or_else_to_queue (
761+ c : char ,
762+ queue : & mut VecDeque < u8 > ,
763+ slice : & mut [ u8 ] ,
764+ write_offset : & mut usize ,
765+ ) {
766+ let mut buffer = [ 0 ; 4 ] ;
767+ let len = c. encode_utf8 ( & mut buffer) . len ( ) ;
768+ let writable_slice = & mut slice[ * write_offset..] ;
769+ let direct_copy_length = core:: cmp:: min ( len, writable_slice. len ( ) ) ;
770+ writable_slice[ ..direct_copy_length] . copy_from_slice ( & buffer[ ..direct_copy_length] ) ;
771+ * write_offset += direct_copy_length;
772+ queue. extend ( & buffer[ direct_copy_length..len] ) ;
773+ }
774+
775+ fn dump_queue ( queue : & mut VecDeque < u8 > , slice : & mut [ u8 ] , write_offset : & mut usize ) {
776+ while * write_offset < slice. len ( ) {
777+ match queue. pop_front ( ) {
778+ Some ( b) => {
779+ slice[ * write_offset] = b;
780+ * write_offset += 1 ;
781+ }
782+ None => break ,
783+ }
784+ }
785+ }
786+
767787#[ derive( Clone ) ]
768788enum FinalSigmaAutomata {
769789 Init ,
0 commit comments