@@ -632,113 +632,171 @@ public void CopyFrom(ArraySegment<byte> buffer)
632
632
CopyFrom( buffer . Array , buffer . Offset , buffer . Count ) ;
633
633
}
634
634
635
- public void CopyFrom( byte [ ] data , int offset , int count )
635
+ public unsafe void CopyFrom( byte [ ] data , int offset , int count )
636
636
{
637
637
Debug. Assert ( _block != null ) ;
638
638
Debug. Assert ( _block . Pool != null ) ;
639
639
Debug. Assert ( _block . Next == null ) ;
640
640
Debug. Assert ( _block . End == _index ) ;
641
-
642
- var pool = _block. Pool ;
641
+
643
642
var block = _block;
644
643
var blockIndex = _index;
644
+ var bytesLeftInBlock = block. BlockEndOffset - blockIndex ;
645
645
646
- var bufferIndex = offset ;
647
- var remaining = count ;
648
- var bytesLeftInBlock = block . Data . Offset + block . Data . Count - blockIndex ;
646
+ if ( bytesLeftInBlock >= count )
647
+ {
648
+ _index = blockIndex + count ;
649
+ Buffer. BlockCopy ( data , offset , block . Array , blockIndex , count ) ;
650
+ block. End = _index ;
651
+ return ;
652
+ }
649
653
650
- while ( remaining > 0 )
654
+ do
651
655
{
652
656
if ( bytesLeftInBlock == 0 )
653
657
{
654
- var nextBlock = pool. Lease( ) ;
655
- block . End = blockIndex ;
658
+ var nextBlock = block. Pool. Lease( ) ;
659
+ blockIndex = nextBlock . Data . Offset ;
660
+ bytesLeftInBlock = nextBlock . Data . Count ;
656
661
block . Next = nextBlock ;
657
662
block = nextBlock ;
658
-
659
- blockIndex = block . Data . Offset ;
660
- bytesLeftInBlock = block . Data . Count ;
661
663
}
662
664
663
- var bytesToCopy = remaining < bytesLeftInBlock ? remaining : bytesLeftInBlock ;
664
-
665
- Buffer . BlockCopy ( data , bufferIndex , block . Array , blockIndex , bytesToCopy ) ;
666
-
667
- blockIndex += bytesToCopy ;
668
- bufferIndex += bytesToCopy ;
669
- remaining -= bytesToCopy ;
670
- bytesLeftInBlock -= bytesToCopy ;
671
- }
672
-
673
- block . End = blockIndex ;
674
- _block = block ;
675
- _index = blockIndex ;
665
+ if ( count > bytesLeftInBlock )
666
+ {
667
+ count -= bytesLeftInBlock ;
668
+ Buffer . BlockCopy ( data , offset , block . Array , blockIndex , bytesLeftInBlock ) ;
669
+ offset += bytesLeftInBlock ;
670
+ block . End = blockIndex + bytesLeftInBlock ;
671
+ bytesLeftInBlock = 0 ;
672
+ }
673
+ else
674
+ {
675
+ _index = blockIndex + count ;
676
+ Buffer . BlockCopy ( data , offset , block . Array , blockIndex , count ) ;
677
+ block . End = _index ;
678
+ _block = block ;
679
+ return ;
680
+ }
681
+ } while ( true ) ;
676
682
}
677
683
678
684
public unsafe void CopyFromAscii ( string data )
679
685
{
680
- Debug . Assert ( _block ! = null ) ;
681
- Debug . Assert ( _block . Pool ! = null ) ;
682
- Debug . Assert ( _block . Next = = null ) ;
683
- Debug . Assert ( _block . End = = _index ) ;
684
-
685
- var pool = _block. Pool;
686
686
var block = _block ;
687
687
var blockIndex = _index ;
688
- var length = data . Length ;
688
+ var count = data . Length ;
689
689
690
- var bytesLeftInBlock = block . Data . Offset + block . Data . Count - blockIndex ;
691
- var bytesLeftInBlockMinusSpan = bytesLeftInBlock - 3 ;
690
+ var blockRemaining = block . BlockEndOffset - blockIndex ;
692
691
693
692
fixed ( char * pData = data )
694
693
{
695
- var input = pData ;
696
- var inputEnd = pData + length ;
697
- var inputEndMinusSpan = inputEnd - 3 ;
694
+ if ( blockRemaining > = count )
695
+ {
696
+ _index = blockIndex + count ;
698
697
699
- while ( input < inputEnd )
698
+ fixed ( byte * output = block . Array )
699
+ {
700
+ CopyFromAscii ( pData , output + blockIndex , count ) ;
701
+ }
702
+
703
+ block . End = _index ;
704
+ return ;
705
+ }
706
+
707
+ var input = pData ;
708
+ do
700
709
{
701
- if ( bytesLeftInBlock == 0 )
710
+ if ( blockRemaining = = 0 )
702
711
{
703
- var nextBlock = pool. Lease( ) ;
704
- block. End = blockIndex;
712
+ var nextBlock = block . Pool . Lease ( ) ;
713
+ blockIndex = nextBlock . Data . Offset ;
714
+ blockRemaining = nextBlock . Data . Count ;
705
715
block . Next = nextBlock ;
706
716
block = nextBlock ;
707
-
708
- blockIndex = block. Data. Offset;
709
- bytesLeftInBlock = block. Data. Count;
710
- bytesLeftInBlockMinusSpan = bytesLeftInBlock - 3 ;
711
717
}
712
718
713
- fixed ( byte * pOutput = block . Data . Array )
719
+ if ( count > blockRemaining )
714
720
{
715
- var output = pOutput + block . End ;
721
+ count -= blockRemaining ;
716
722
717
- var copied = 0 ;
718
- for ( ; input < inputEndMinusSpan && copied < bytesLeftInBlockMinusSpan; copied += 4 )
723
+ fixed ( byte * output = block . Array )
719
724
{
720
- * ( output) = ( byte ) * ( input) ;
721
- * ( output + 1 ) = ( byte ) * ( input + 1 ) ;
722
- * ( output + 2 ) = ( byte ) * ( input + 2 ) ;
723
- * ( output + 3 ) = ( byte ) * ( input + 3 ) ;
724
- output += 4 ;
725
- input += 4 ;
725
+ CopyFromAscii ( input , output + blockIndex , blockRemaining ) ;
726
726
}
727
- for ( ; input < inputEnd && copied < bytesLeftInBlock; copied++ )
727
+
728
+ block . End = blockIndex + blockRemaining ;
729
+ input += blockRemaining ;
730
+ blockRemaining = 0 ;
731
+ }
732
+ else
733
+ {
734
+ _index = blockIndex + count ;
735
+
736
+ fixed ( byte * output = block . Array )
728
737
{
729
- * ( output++ ) = ( byte ) * ( input ++ ) ;
738
+ CopyFromAscii ( input , output + blockIndex , count ) ;
730
739
}
731
740
732
- blockIndex += copied ;
733
- bytesLeftInBlockMinusSpan -= copied ;
734
- bytesLeftInBlock -= copied ;
741
+ block . End = _index ;
742
+ _block = block ;
743
+ return ;
735
744
}
736
- }
745
+ } while ( true ) ;
737
746
}
747
+ }
738
748
739
- block. End = blockIndex;
740
- _block = block;
741
- _index = blockIndex;
749
+ private unsafe static void CopyFromAscii ( char * input , byte * output , int count )
750
+ {
751
+ var i = 0 ;
752
+
753
+ while ( i < count - 11 )
754
+ {
755
+ i += 12 ;
756
+ * ( output) = ( byte ) * ( input ) ;
757
+ * ( output + 1 ) = ( byte ) * ( input + 1 ) ;
758
+ * ( output + 2 ) = ( byte ) * ( input + 2 ) ;
759
+ * ( output + 3 ) = ( byte ) * ( input + 3 ) ;
760
+ * ( output + 4 ) = ( byte ) * ( input + 4 ) ;
761
+ * ( output + 5 ) = ( byte ) * ( input + 5 ) ;
762
+ * ( output + 6 ) = ( byte ) * ( input + 6 ) ;
763
+ * ( output + 7 ) = ( byte ) * ( input + 7 ) ;
764
+ * ( output + 8 ) = ( byte ) * ( input + 8 ) ;
765
+ * ( output + 9 ) = ( byte ) * ( input + 9 ) ;
766
+ * ( output + 10 ) = ( byte ) * ( input + 10 ) ;
767
+ * ( output + 11 ) = ( byte ) * ( input + 11 ) ;
768
+ output += 12 ;
769
+ input += 12 ;
770
+ }
771
+ if ( i < count - 5 )
772
+ {
773
+ i += 6 ;
774
+ * ( output ) = ( byte ) * ( input ) ;
775
+ * ( output + 1 ) = ( byte ) * ( input + 1 ) ;
776
+ * ( output + 2 ) = ( byte ) * ( input + 2 ) ;
777
+ * ( output + 3 ) = ( byte ) * ( input + 3 ) ;
778
+ * ( output + 4 ) = ( byte ) * ( input + 4 ) ;
779
+ * ( output + 5 ) = ( byte ) * ( input + 5 ) ;
780
+ output += 6 ;
781
+ input += 6 ;
782
+ }
783
+ if ( i < count - 3 )
784
+ {
785
+ i += 4 ;
786
+ * ( output ) = ( byte ) * ( input ) ;
787
+ * ( output + 1 ) = ( byte ) * ( input + 1 ) ;
788
+ * ( output + 2 ) = ( byte ) * ( input + 2 ) ;
789
+ * ( output + 3 ) = ( byte ) * ( input + 3 ) ;
790
+ output += 4 ;
791
+ input += 4 ;
792
+ }
793
+ while ( i < count )
794
+ {
795
+ i++ ;
796
+ * output = ( byte ) * input ;
797
+ output++ ;
798
+ input++ ;
799
+ }
742
800
}
743
801
}
744
802
}
0 commit comments