@@ -692,46 +692,52 @@ public void CopyFrom(ArraySegment<byte> buffer)
692
692
CopyFrom( buffer . Array , buffer . Offset , buffer . Count ) ;
693
693
}
694
694
695
- public void CopyFrom( byte [ ] data , int offset , int count )
695
+ public unsafe void CopyFrom( byte [ ] data , int offset , int count )
696
696
{
697
697
Debug. Assert ( _block != null ) ;
698
698
Debug. Assert ( _block . Next == null ) ;
699
699
Debug. Assert ( _block . End == _index ) ;
700
-
701
- var pool = _block. Pool ;
700
+
702
701
var block = _block;
703
702
var blockIndex = _index;
703
+ var bytesLeftInBlock = block. BlockEndOffset - blockIndex ;
704
704
705
- var bufferIndex = offset ;
706
- var remaining = count ;
707
- var bytesLeftInBlock = block . Data . Offset + block . Data . Count - blockIndex ;
705
+ if ( bytesLeftInBlock >= count )
706
+ {
707
+ _index = blockIndex + count ;
708
+ Buffer. BlockCopy ( data , offset , block . Array , blockIndex , count ) ;
709
+ block. End = _index ;
710
+ return ;
711
+ }
708
712
709
- while ( remaining > 0 )
713
+ do
710
714
{
711
715
if ( bytesLeftInBlock == 0 )
712
716
{
713
- var nextBlock = pool. Lease( ) ;
714
- block . End = blockIndex ;
717
+ var nextBlock = block. Pool. Lease( ) ;
718
+ blockIndex = nextBlock . Data . Offset ;
719
+ bytesLeftInBlock = nextBlock . Data . Count ;
715
720
block . Next = nextBlock ;
716
721
block = nextBlock ;
717
-
718
- blockIndex = block . Data . Offset ;
719
- bytesLeftInBlock = block . Data . Count ;
720
722
}
721
723
722
- var bytesToCopy = remaining < bytesLeftInBlock ? remaining : bytesLeftInBlock ;
723
-
724
- Buffer . BlockCopy ( data , bufferIndex , block . Array , blockIndex , bytesToCopy ) ;
725
-
726
- blockIndex += bytesToCopy ;
727
- bufferIndex += bytesToCopy ;
728
- remaining -= bytesToCopy ;
729
- bytesLeftInBlock -= bytesToCopy ;
730
- }
731
-
732
- block . End = blockIndex ;
733
- _block = block ;
734
- _index = blockIndex ;
724
+ if ( count > bytesLeftInBlock )
725
+ {
726
+ count -= bytesLeftInBlock ;
727
+ Buffer . BlockCopy ( data , offset , block . Array , blockIndex , bytesLeftInBlock ) ;
728
+ offset += bytesLeftInBlock ;
729
+ block . End = blockIndex + bytesLeftInBlock ;
730
+ bytesLeftInBlock = 0 ;
731
+ }
732
+ else
733
+ {
734
+ _index = blockIndex + count ;
735
+ Buffer . BlockCopy ( data , offset , block . Array , blockIndex , count ) ;
736
+ block . End = _index ;
737
+ _block = block ;
738
+ return ;
739
+ }
740
+ } while ( true ) ;
735
741
}
736
742
737
743
public unsafe void CopyFromAscii ( string data )
@@ -740,64 +746,126 @@ public unsafe void CopyFromAscii(string data)
740
746
Debug . Assert ( _block . Next = = null ) ;
741
747
Debug . Assert ( _block . End = = _index ) ;
742
748
743
- var pool = _block. Pool;
744
749
var block = _block;
745
750
var blockIndex = _index ;
746
- var length = data . Length ;
751
+ var count = data . Length ;
747
752
748
- var bytesLeftInBlock = block . Data . Offset + block . Data . Count - blockIndex ;
749
- var bytesLeftInBlockMinusSpan = bytesLeftInBlock - 3 ;
753
+ var blockRemaining = block . BlockEndOffset - blockIndex ;
750
754
751
755
fixed ( char * pData = data)
752
756
{
753
- var input = pData ;
754
- var inputEnd = pData + length ;
755
- var inputEndMinusSpan = inputEnd - 3 ;
757
+ if ( blockRemaining > = count )
758
+ {
759
+ _index = blockIndex + count;
760
+
761
+ fixed ( byte * pOutput = & block. Data. Array[ blockIndex] )
762
+ {
763
+ //this line is needed to allow output be an register var
764
+ var output = pOutput;
765
+ CopyFromAscii( pData, output , count ) ;
766
+ }
756
767
757
- while ( input < inputEnd )
768
+ block . End = _index ;
769
+ return ;
770
+ }
771
+
772
+ var input = pData ;
773
+ do
758
774
{
759
- if ( bytesLeftInBlock == 0 )
775
+ if ( blockRemaining == 0 )
760
776
{
761
- var nextBlock = pool. Lease( ) ;
762
- block. End = blockIndex;
777
+ var nextBlock = block . Pool . Lease ( ) ;
778
+ blockIndex = nextBlock . Data . Offset ;
779
+ blockRemaining = nextBlock . Data . Count ;
763
780
block . Next = nextBlock ;
764
781
block = nextBlock ;
765
-
766
- blockIndex = block. Data. Offset;
767
- bytesLeftInBlock = block. Data. Count;
768
- bytesLeftInBlockMinusSpan = bytesLeftInBlock - 3 ;
769
782
}
770
783
771
- fixed ( byte * pOutput = & block . Data . Array [ block . End ] )
784
+ if ( count > blockRemaining )
772
785
{
773
- //this line is needed to allow output be an register var
774
- var output = pOutput;
786
+ count -= blockRemaining;
775
787
776
- var copied = 0 ;
777
- for ( ; input < inputEndMinusSpan && copied < bytesLeftInBlockMinusSpan ; copied += 4 )
788
+ fixed ( byte * pOutput = & block. Data. Array[ blockIndex] )
778
789
{
779
- * ( output ) = ( byte ) * ( input) ;
780
- * ( output + 1 ) = ( byte ) * ( input + 1 ) ;
781
- * ( output + 2 ) = ( byte ) * ( input + 2 ) ;
782
- * ( output + 3 ) = ( byte ) * ( input + 3 ) ;
783
- output += 4 ;
784
- input += 4 ;
790
+ //this line is needed to allow output be an register var
791
+ var output = pOutput;
792
+ CopyFromAscii( input, output , blockRemaining ) ;
785
793
}
786
- for ( ; input < inputEnd && copied < bytesLeftInBlock; copied++ )
794
+
795
+ block . End = blockIndex + blockRemaining ;
796
+ input += blockRemaining ;
797
+ blockRemaining = 0 ;
798
+ }
799
+ else
800
+ {
801
+ _index = blockIndex + count ;
802
+
803
+ fixed ( byte * pOutput = & block . Data . Array [ blockIndex ] )
787
804
{
788
- * ( output++ ) = ( byte ) * ( input++ ) ;
805
+ //this line is needed to allow output be an register var
806
+ var output = pOutput;
807
+ CopyFromAscii( input, output , count ) ;
789
808
}
790
809
791
- blockIndex += copied ;
792
- bytesLeftInBlockMinusSpan -= copied ;
793
- bytesLeftInBlock -= copied ;
810
+ block . End = _index ;
811
+ _block = block ;
812
+ return ;
794
813
}
795
- }
814
+ } while ( true ) ;
796
815
}
816
+ }
797
817
798
- block. End = blockIndex;
799
- _block = block;
800
- _index = blockIndex;
818
+ private unsafe static void CopyFromAscii ( char * input , byte * output , int count )
819
+ {
820
+ var i = 0 ;
821
+
822
+ while ( i < count - 11 )
823
+ {
824
+ i += 12 ;
825
+ * ( output ) = ( byte ) * ( input ) ;
826
+ * ( output + 1 ) = ( byte ) * ( input + 1 ) ;
827
+ * ( output + 2 ) = ( byte ) * ( input + 2 ) ;
828
+ * ( output + 3 ) = ( byte ) * ( input + 3 ) ;
829
+ * ( output + 4 ) = ( byte ) * ( input + 4 ) ;
830
+ * ( output + 5 ) = ( byte ) * ( input + 5 ) ;
831
+ * ( output + 6 ) = ( byte ) * ( input + 6 ) ;
832
+ * ( output + 7 ) = ( byte ) * ( input + 7 ) ;
833
+ * ( output + 8 ) = ( byte ) * ( input + 8 ) ;
834
+ * ( output + 9 ) = ( byte ) * ( input + 9 ) ;
835
+ * ( output + 10 ) = ( byte ) * ( input + 10 ) ;
836
+ * ( output + 11 ) = ( byte ) * ( input + 11 ) ;
837
+ output += 12 ;
838
+ input += 12 ;
839
+ }
840
+ if ( i < count - 5 )
841
+ {
842
+ i += 6 ;
843
+ * ( output ) = ( byte ) * ( input ) ;
844
+ * ( output + 1 ) = ( byte ) * ( input + 1 ) ;
845
+ * ( output + 2 ) = ( byte ) * ( input + 2 ) ;
846
+ * ( output + 3 ) = ( byte ) * ( input + 3 ) ;
847
+ * ( output + 4 ) = ( byte ) * ( input + 4 ) ;
848
+ * ( output + 5 ) = ( byte ) * ( input + 5 ) ;
849
+ output += 6 ;
850
+ input += 6 ;
851
+ }
852
+ if ( i < count - 3 )
853
+ {
854
+ i += 4 ;
855
+ * ( output ) = ( byte ) * ( input ) ;
856
+ * ( output + 1 ) = ( byte ) * ( input + 1 ) ;
857
+ * ( output + 2 ) = ( byte ) * ( input + 2 ) ;
858
+ * ( output + 3 ) = ( byte ) * ( input + 3 ) ;
859
+ output += 4 ;
860
+ input += 4 ;
861
+ }
862
+ while ( i < count )
863
+ {
864
+ i++ ;
865
+ * output = ( byte ) * input ;
866
+ output++ ;
867
+ input++ ;
868
+ }
801
869
}
802
870
}
803
871
}
0 commit comments