/** * Moves a position forward. On entry, <code>pos</code> gives * the position of the byte at index <code>off</code> in * <code>buf</code>. On exit, it <code>pos</code> will give * the position of the byte at index <code>end</code>, which * must be greater than or equal to <code>off</code>. The * bytes between <code>off</code> and <code>end</code> must * encode one or more complete characters. A carriage return * followed by a line feed will be treated as a single line * delimiter provided that they are given to * <code>movePosition</code> together. */ protected abstract void movePosition(byte[] buf, int off, int end, Position pos);
/// <summary> /// /// </summary> /// <param name="buf"></param> /// <param name="off"></param> /// <param name="end"></param> /// <param name="pos"></param> protected override void movePosition(byte[] buf, int off, int end, Position pos) { /* Maintain the invariant: off - colDiff == colNumber. */ int colDiff = off - pos.ColumnNumber; int lineNumber = pos.LineNumber; while (off != end) { byte b = buf[off]; if (b >= 0) { ++off; switch (b) { case (byte)'\n': lineNumber += 1; colDiff = off; break; case (byte)'\r': lineNumber += 1; if (off != end && buf[off] == '\n') off++; colDiff = off; break; } } else { switch (utf8TypeTable[b & 0xFF]) { default: off += 1; break; case BT_LEAD2: off += 2; colDiff++; break; case BT_LEAD3: off += 3; colDiff += 2; break; case BT_LEAD4: off += 4; colDiff += 3; break; } } } pos.ColumnNumber = off - colDiff; pos.LineNumber = lineNumber; }