@@ -632,47 +632,53 @@ 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 )
@@ -682,63 +688,120 @@ public unsafe void CopyFromAscii(string data)
682
688
Debug . Assert ( _block . Next = = null ) ;
683
689
Debug . Assert ( _block . End = = _index ) ;
684
690
685
- var pool = _block. Pool;
686
691
var block = _block;
687
692
var blockIndex = _index ;
688
- var length = data . Length ;
693
+ var count = data . Length ;
689
694
690
- var bytesLeftInBlock = block . Data . Offset + block . Data . Count - blockIndex ;
691
- var bytesLeftInBlockMinusSpan = bytesLeftInBlock - 3 ;
695
+ var blockRemaining = block . BlockEndOffset - blockIndex ;
692
696
693
697
fixed ( char * pData = data)
694
698
{
695
- var input = pData ;
696
- var inputEnd = pData + length ;
697
- var inputEndMinusSpan = inputEnd - 3 ;
699
+ if ( blockRemaining > = count )
700
+ {
701
+ _index = blockIndex + count;
702
+
703
+ fixed ( byte * output = block. Array)
704
+ {
705
+ CopyFromAscii( pData , output + blockIndex , count ) ;
706
+ }
698
707
699
- while ( input < inputEnd )
708
+ block . End = _index ;
709
+ return ;
710
+ }
711
+
712
+ var input = pData ;
713
+ do
700
714
{
701
- if ( bytesLeftInBlock == 0 )
715
+ if ( blockRemaining = = 0 )
702
716
{
703
- var nextBlock = pool. Lease( ) ;
704
- block. End = blockIndex;
717
+ var nextBlock = block . Pool . Lease ( ) ;
718
+ blockIndex = nextBlock . Data . Offset ;
719
+ blockRemaining = nextBlock . Data . Count ;
705
720
block . Next = nextBlock ;
706
721
block = nextBlock ;
707
-
708
- blockIndex = block. Data. Offset;
709
- bytesLeftInBlock = block. Data. Count;
710
- bytesLeftInBlockMinusSpan = bytesLeftInBlock - 3 ;
711
722
}
712
723
713
- fixed ( byte * pOutput = block . Data . Array )
724
+ if ( count > blockRemaining )
714
725
{
715
- var output = pOutput + block . End ;
726
+ count -= blockRemaining ;
716
727
717
- var copied = 0 ;
718
- for ( ; input < inputEndMinusSpan && copied < bytesLeftInBlockMinusSpan; copied += 4 )
728
+ fixed ( byte * output = block. Array)
719
729
{
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 ;
730
+ CopyFromAscii( input, output + blockIndex , blockRemaining ) ;
726
731
}
727
- for ( ; input < inputEnd && copied < bytesLeftInBlock; copied++ )
732
+
733
+ block . End = blockIndex + blockRemaining ;
734
+ input += blockRemaining ;
735
+ blockRemaining = 0 ;
736
+ }
737
+ else
738
+ {
739
+ _index = blockIndex + count ;
740
+
741
+ fixed ( byte * output = block . Array )
728
742
{
729
- * ( output++ ) = ( byte ) * ( input ++ ) ;
743
+ CopyFromAscii ( input , output + blockIndex , count ) ;
730
744
}
731
745
732
- blockIndex += copied ;
733
- bytesLeftInBlockMinusSpan -= copied ;
734
- bytesLeftInBlock -= copied ;
746
+ block . End = _index ;
747
+ _block = block ;
748
+ return ;
735
749
}
736
- }
750
+ } while ( true ) ;
737
751
}
752
+ }
738
753
739
- block. End = blockIndex;
740
- _block = block;
741
- _index = blockIndex;
754
+ private unsafe static void CopyFromAscii ( char * input , byte * output , int count )
755
+ {
756
+ var i = 0 ;
757
+
758
+ while ( i < count - 11 )
759
+ {
760
+ i += 12 ;
761
+ * ( output ) = ( byte ) * ( input) ;
762
+ * ( output + 1 ) = ( byte ) * ( input + 1 ) ;
763
+ * ( output + 2 ) = ( byte ) * ( input + 2 ) ;
764
+ * ( output + 3 ) = ( byte ) * ( input + 3 ) ;
765
+ * ( output + 4 ) = ( byte ) * ( input + 4 ) ;
766
+ * ( output + 5 ) = ( byte ) * ( input + 5 ) ;
767
+ * ( output + 6 ) = ( byte ) * ( input + 6 ) ;
768
+ * ( output + 7 ) = ( byte ) * ( input + 7 ) ;
769
+ * ( output + 8 ) = ( byte ) * ( input + 8 ) ;
770
+ * ( output + 9 ) = ( byte ) * ( input + 9 ) ;
771
+ * ( output + 10 ) = ( byte ) * ( input + 10 ) ;
772
+ * ( output + 11 ) = ( byte ) * ( input + 11 ) ;
773
+ output += 12 ;
774
+ input += 12 ;
775
+ }
776
+ if ( i < count - 5 )
777
+ {
778
+ i += 6 ;
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 ) = ( byte ) * ( input + 4 ) ;
784
+ * ( output + 5 ) = ( byte ) * ( input + 5 ) ;
785
+ output += 6 ;
786
+ input += 6 ;
787
+ }
788
+ if ( i < count - 3 )
789
+ {
790
+ i += 4 ;
791
+ * ( output) = ( byte ) * ( input) ;
792
+ * ( output + 1 ) = ( byte ) * ( input + 1 ) ;
793
+ * ( output + 2 ) = ( byte ) * ( input + 2 ) ;
794
+ * ( output + 3 ) = ( byte ) * ( input + 3 ) ;
795
+ output += 4 ;
796
+ input += 4 ;
797
+ }
798
+ while ( i < count)
799
+ {
800
+ i++ ;
801
+ * output = ( byte ) * input;
802
+ output++ ;
803
+ input++ ;
804
+ }
742
805
}
743
806
}
744
807
}
0 commit comments