Microsoft.Cci.PrimarySourceDocument.ToLineColumn C# (CSharp) Method

ToLineColumn() public method

Maps the given (zero based) source position to a (one based) line and column, by scanning the source character by character, counting new lines until the given source position is reached. The source position and corresponding line+column are remembered and scanning carries on where it left off when this routine is called next. If the given position precedes the last given position, we use backward scanning. Optimal use of this method requires the client to sort calls in order of position.
This method behaves badly when applied to a really large file since it loads the entire file in memory as a UTF16 unicode string. In such cases, a slower implementation based on streaming would be more appropriate. However, it is assumed that getting source context information from such really large files is an extremely rare event and that bad performance in such cases is better than degraded performance in the common case.
public ToLineColumn ( int position, int &line, int &column ) : void
position int
line int
column int
return void
    public virtual void ToLineColumn(int position, out int line, out int column)
      //^^ requires position >= 0 && position <= Length;
      //^^ ensures line >= 1 && column >= 1;
    {
      int n = this.Length;
      if (position == n) position--;
      int best = FindBestStartPointForPosition(position);
      line = this.lineCounters[best];
      column = this.columnCounters[best];
      int i = this.lastPositions[best];
      string text = this.GetText();
      if (position < i) {
        if (position < (i - position)) {
          // we need to scan more characters when going backwards from here than starting from the beginning, so do that
          line = 1;
          column = 1;
          i = 0;
          goto forwardSearch;
        }
        column = 1;
        while (i > 0) {
          switch (text[--i]) {
            case '\n':
              if (i > 0 && text[i-1] == '\r')
                i--;
              goto case '\r';
            case '\r':
            case (char)0x2028:
            case (char)0x2029:
              line--;
              if (i <= position) goto forwardSearch;
              break;
          }
        }
      }
    forwardSearch:
      while (i < position) {
        switch (text[i++]) {
          case '\r':
            if (i < n && text[i] == '\n')
              i++;
            goto case '\n';
          case '\n':
          case (char)0x2028:
          case (char)0x2029:
            line++; //TODO: Boogie crashes here, presumably because it does not like ++ on an out parameter
            column = 1;
            //this.positionJumpList[i] = line;
            break;
          default:
            column++;
            break;
        }
      }
      this.lineCounters[best] = line;
      this.columnCounters[best] = column;
      this.lastPositions[best] = position;
    }