Microsoft.Cci.CompositeSourceDocument.CopyTo C# (CSharp) Method

CopyTo() public method

Copies no more than the specified number of characters to the destination character array, starting at the specified position in the source document. Returns the actual number of characters that were copied. This number will be greater than zero as long as position is less than this.Length. The number will be precisely the number asked for unless there are not enough characters left in the document.
public CopyTo ( int position, char destination, int destinationOffset, int length ) : int
position int The starting index to copy from. Must be greater than or equal to zero and position+length must be less than or equal to this.Length;
destination char The destination array.
destinationOffset int The starting index where the characters must be copied to in the destination array.
length int The maximum number of characters to copy. Must be greater than 0 and less than or equal to the number elements of the destination array.
return int
    public override int CopyTo(int position, char[] destination, int destinationOffset, int length)
      //^^ requires 0 <= position && 0 <= length && 0 <= position+length && position <= this.Length;
      //^^ requires 0 <= destinationOffset && 0 <= destinationOffset+length && destinationOffset+length <= destination.Length;
      //^^ ensures 0 <= result && result <= length && position+result <= this.Length;
    {
      if (this.length != null && position >= (int)this.length) return 0;
      if (!this.enumeratorIsValid || position < this.currentFragmentOffset) {
        this.fragmentEnumerator = this.GetFragments().GetEnumerator();
        this.currentFragmentOffset = 0;
        this.enumeratorIsValid = this.fragmentEnumerator.MoveNext();
      }
      Contract.Assert(this.fragmentEnumerator != null);
      while (this.enumeratorIsValid) {
        int fragmentLength = this.fragmentEnumerator.Current.Length;
        if (this.currentFragmentOffset + fragmentLength > position) break;
        this.currentFragmentOffset += fragmentLength;
        this.enumeratorIsValid = this.fragmentEnumerator.MoveNext();
      }
      int charsCopied = 0;
      Contract.Assume(0 <= position && position <= this.Length); //follows from the precondition
      while (this.enumeratorIsValid && charsCopied < length) {
        Contract.Assert(this.fragmentEnumerator != null);
        Contract.Assert(this.currentFragmentOffset+this.fragmentEnumerator.Current.Length > position);
        Contract.Assert(0 <= position && position <= this.Length);
        Contract.Assert(0 <= charsCopied && charsCopied <= length);
        Contract.Assert(position+charsCopied <= this.Length);

        int fragmentLength = this.fragmentEnumerator.Current.Length;
        int fragmentStart = 0;
        if (position > this.currentFragmentOffset) fragmentStart = position - this.currentFragmentOffset;
        Contract.Assume(fragmentStart <= this.Length); //position < this.Length as per the loop invariant
        int fragmentCharsToCopy = fragmentLength - fragmentStart;
        if (charsCopied + fragmentCharsToCopy > length) fragmentCharsToCopy = length - charsCopied;
        //Contract.Assume(fragmentStart <= this.Length);
        int fragCharsCopied = this.fragmentEnumerator.Current.CopyTo(fragmentStart, destination, destinationOffset, fragmentCharsToCopy);
        if (fragCharsCopied == 0) {
          this.enumeratorIsValid = false;
          break;
        }
        charsCopied += fragCharsCopied;
        Contract.Assume(position + charsCopied <= this.Length);
        destinationOffset += fragmentCharsToCopy;
        if (fragmentStart + fragmentCharsToCopy >= fragmentLength) {
          this.currentFragmentOffset += fragmentLength;
          this.enumeratorIsValid = this.fragmentEnumerator.MoveNext();
        }
      }
      if (!this.enumeratorIsValid) this.length = this.currentFragmentOffset;
      Contract.Assert(0 <= charsCopied && charsCopied <= length && position+charsCopied <= this.Length);
      return charsCopied;
    }