@@ -513,21 +513,24 @@ public int GetLength(MemoryPoolIterator2 end)
513
513
var block = _block;
514
514
var index = _index ;
515
515
var length = 0 ;
516
- while ( true )
516
+ checked
517
517
{
518
- if ( block == end . _block )
519
- {
520
- return length + end . _index - index ;
521
- }
522
- else if ( block . Next = = null )
518
+ while ( true )
523
519
{
524
- throw new InvalidOperationException ( "end did not follow iterator" ) ;
525
- }
526
- else
527
- {
528
- length += block . End - index ;
529
- block = block . Next ;
530
- index = block . Start ;
520
+ if ( block == end . _block )
521
+ {
522
+ return length + end . _index - index ;
523
+ }
524
+ else if ( block . Next = = null )
525
+ {
526
+ throw new InvalidOperationException ( "end did not follow iterator" ) ;
527
+ }
528
+ else
529
+ {
530
+ length += block . End - index ;
531
+ block = block . Next ;
532
+ index = block . Start ;
533
+ }
531
534
}
532
535
}
533
536
}
@@ -588,113 +591,168 @@ public void CopyFrom(ArraySegment<byte> buffer)
588
591
CopyFrom( buffer . Array , buffer . Offset , buffer . Count ) ;
589
592
}
590
593
591
- public void CopyFrom( byte [ ] data , int offset , int count )
594
+ public unsafe void CopyFrom( byte [ ] data , int offset , int count )
592
595
{
593
- Debug. Assert ( _block != null ) ;
594
- Debug. Assert ( _block . Pool != null ) ;
595
- Debug. Assert ( _block . Next == null ) ;
596
- Debug. Assert ( _block . End == _index ) ;
597
-
598
- var pool = _block. Pool ;
599
596
var block = _block;
600
597
var blockIndex = _index;
598
+ var bytesLeftInBlock = block. BlockEndOffset - blockIndex ;
601
599
602
- var bufferIndex = offset ;
603
- var remaining = count ;
604
- var bytesLeftInBlock = block . Data . Offset + block . Data . Count - blockIndex ;
600
+ if ( bytesLeftInBlock >= count )
601
+ {
602
+ _index = blockIndex + count ;
603
+ Buffer. BlockCopy ( data , offset , block . Array , blockIndex , count ) ;
604
+ block. End = _index ;
605
+ return ;
606
+ }
605
607
606
- while ( remaining > 0 )
608
+ do
607
609
{
608
610
if ( bytesLeftInBlock == 0 )
609
611
{
610
- var nextBlock = pool. Lease( ) ;
611
- block . End = blockIndex ;
612
+ var nextBlock = block. Pool. Lease( ) ;
613
+ blockIndex = nextBlock . Data . Offset ;
614
+ bytesLeftInBlock = nextBlock . Data . Count ;
612
615
block . Next = nextBlock ;
613
616
block = nextBlock ;
614
-
615
- blockIndex = block . Data . Offset ;
616
- bytesLeftInBlock = block . Data . Count ;
617
617
}
618
618
619
- var bytesToCopy = remaining < bytesLeftInBlock ? remaining : bytesLeftInBlock ;
620
-
621
- Buffer . BlockCopy ( data , bufferIndex , block . Array , blockIndex , bytesToCopy ) ;
622
-
623
- blockIndex += bytesToCopy ;
624
- bufferIndex += bytesToCopy ;
625
- remaining -= bytesToCopy ;
626
- bytesLeftInBlock -= bytesToCopy ;
627
- }
628
-
629
- block . End = blockIndex ;
630
- _block = block ;
631
- _index = blockIndex ;
619
+ if ( count > bytesLeftInBlock )
620
+ {
621
+ count -= bytesLeftInBlock ;
622
+ Buffer . BlockCopy ( data , offset , block . Array , blockIndex , bytesLeftInBlock ) ;
623
+ offset += bytesLeftInBlock ;
624
+ block . End = blockIndex + bytesLeftInBlock ;
625
+ bytesLeftInBlock = 0 ;
626
+ continue ;
627
+ }
628
+ else
629
+ {
630
+ _index = blockIndex + count ;
631
+ Buffer . BlockCopy ( data , offset , block . Array , blockIndex , count ) ;
632
+ block . End = _index ;
633
+ _block = block ;
634
+ return ;
635
+ }
636
+ } while ( true ) ;
632
637
}
633
638
634
639
public unsafe void CopyFromAscii ( string data )
635
640
{
636
- Debug . Assert ( _block ! = null ) ;
637
- Debug . Assert ( _block . Pool ! = null ) ;
638
- Debug . Assert ( _block . Next = = null ) ;
639
- Debug . Assert ( _block . End = = _index ) ;
640
-
641
- var pool = _block. Pool;
642
641
var block = _block ;
643
642
var blockIndex = _index ;
644
- var length = data . Length ;
643
+ var count = data . Length ;
645
644
646
- var bytesLeftInBlock = block . Data . Offset + block . Data . Count - blockIndex ;
647
- var bytesLeftInBlockMinusSpan = bytesLeftInBlock - 3 ;
645
+ var blockRemaining = block . BlockEndOffset - blockIndex ;
648
646
649
647
fixed ( char * pData = data )
650
648
{
651
- var input = pData ;
652
- var inputEnd = pData + length ;
653
- var inputEndMinusSpan = inputEnd - 3 ;
649
+ if ( blockRemaining > = count )
650
+ {
651
+ _index = blockIndex + count ;
652
+
653
+ fixed ( byte * output = block . Array )
654
+ {
655
+ CopyFromAscii ( pData , output + blockIndex , count ) ;
656
+ }
657
+
658
+ block . End = _index ;
659
+ return ;
660
+ }
654
661
655
- while ( input < inputEnd )
662
+ var input = pData ;
663
+ do
656
664
{
657
- if ( bytesLeftInBlock == 0 )
665
+ if ( blockRemaining = = 0 )
658
666
{
659
- var nextBlock = pool. Lease( ) ;
660
- block. End = blockIndex;
667
+ var nextBlock = block . Pool . Lease ( ) ;
668
+ blockIndex = nextBlock . Data . Offset ;
669
+ blockRemaining = nextBlock . Data . Count ;
661
670
block . Next = nextBlock ;
662
671
block = nextBlock ;
663
-
664
- blockIndex = block. Data. Offset;
665
- bytesLeftInBlock = block. Data. Count;
666
- bytesLeftInBlockMinusSpan = bytesLeftInBlock - 3 ;
667
672
}
668
673
669
- fixed ( byte * pOutput = block . Data . Array )
674
+ if ( count > blockRemaining )
670
675
{
671
- var output = pOutput + block . End ;
676
+ count -= blockRemaining ;
672
677
673
- var copied = 0 ;
674
- for ( ; input < inputEndMinusSpan && copied < bytesLeftInBlockMinusSpan; copied += 4 )
678
+ fixed ( byte * output = block . Array )
675
679
{
676
- * ( output) = ( byte ) * ( input) ;
677
- * ( output + 1 ) = ( byte ) * ( input + 1 ) ;
678
- * ( output + 2 ) = ( byte ) * ( input + 2 ) ;
679
- * ( output + 3 ) = ( byte ) * ( input + 3 ) ;
680
- output += 4 ;
681
- input += 4 ;
680
+ CopyFromAscii ( input , output + blockIndex , blockRemaining ) ;
682
681
}
683
- for ( ; input < inputEnd && copied < bytesLeftInBlock; copied++ )
682
+
683
+ block . End = blockIndex + blockRemaining ;
684
+ input += blockRemaining ;
685
+ blockRemaining = 0 ;
686
+ continue ;
687
+ }
688
+ else
689
+ {
690
+ _index = blockIndex + count ;
691
+
692
+ fixed ( byte * output = block . Array )
684
693
{
685
- * ( output++ ) = ( byte ) * ( input ++ ) ;
694
+ CopyFromAscii ( input , output + blockIndex , count ) ;
686
695
}
687
696
688
- blockIndex += copied ;
689
- bytesLeftInBlockMinusSpan -= copied ;
690
- bytesLeftInBlock -= copied ;
697
+ block . End = _index ;
698
+ _block = block ;
699
+ return ;
691
700
}
692
- }
701
+ } while ( true ) ;
693
702
}
703
+ }
694
704
695
- block. End = blockIndex;
696
- _block = block;
697
- _index = blockIndex;
705
+ private unsafe static void CopyFromAscii ( char * input , byte * output , int count )
706
+ {
707
+ var i = 0 ;
708
+
709
+ while ( i < count - 11 )
710
+ {
711
+ i += 12 ;
712
+ * ( output) = ( byte ) * ( input ) ;
713
+ * ( output + 1 ) = ( byte ) * ( input + 1 ) ;
714
+ * ( output + 2 ) = ( byte ) * ( input + 2 ) ;
715
+ * ( output + 3 ) = ( byte ) * ( input + 3 ) ;
716
+ * ( output + 4 ) = ( byte ) * ( input + 4 ) ;
717
+ * ( output + 5 ) = ( byte ) * ( input + 5 ) ;
718
+ * ( output + 6 ) = ( byte ) * ( input + 6 ) ;
719
+ * ( output + 7 ) = ( byte ) * ( input + 7 ) ;
720
+ * ( output + 8 ) = ( byte ) * ( input + 8 ) ;
721
+ * ( output + 9 ) = ( byte ) * ( input + 9 ) ;
722
+ * ( output + 10 ) = ( byte ) * ( input + 10 ) ;
723
+ * ( output + 11 ) = ( byte ) * ( input + 11 ) ;
724
+ output += 12 ;
725
+ input += 12 ;
726
+ }
727
+ if ( i < count - 5 )
728
+ {
729
+ i += 6 ;
730
+ * ( output ) = ( byte ) * ( input ) ;
731
+ * ( output + 1 ) = ( byte ) * ( input + 1 ) ;
732
+ * ( output + 2 ) = ( byte ) * ( input + 2 ) ;
733
+ * ( output + 3 ) = ( byte ) * ( input + 3 ) ;
734
+ * ( output + 4 ) = ( byte ) * ( input + 4 ) ;
735
+ * ( output + 5 ) = ( byte ) * ( input + 5 ) ;
736
+ output += 6 ;
737
+ input += 6 ;
738
+ }
739
+ if ( i < count - 3 )
740
+ {
741
+ i += 4 ;
742
+ * ( output ) = ( byte ) * ( input ) ;
743
+ * ( output + 1 ) = ( byte ) * ( input + 1 ) ;
744
+ * ( output + 2 ) = ( byte ) * ( input + 2 ) ;
745
+ * ( output + 3 ) = ( byte ) * ( input + 3 ) ;
746
+ output += 4 ;
747
+ input += 4 ;
748
+ }
749
+ while ( i < count )
750
+ {
751
+ i++ ;
752
+ * output = ( byte ) * input ;
753
+ output++ ;
754
+ input++ ;
755
+ }
698
756
}
699
757
}
700
758
}
0 commit comments