private _readOrSeekTo()

in packages/selector/src/text/seeker.ts [318:390]


  private _readOrSeekTo(
    read: false,
    target: number,
    roundUp?: boolean,
    lessIsFine?: boolean,
  ): void;
  private _readOrSeekTo(
    read: boolean,
    target: number,
    roundUp = false,
    lessIsFine = false,
  ): string | void {
    let result = '';

    if (this.position <= target) {
      while (true) {
        const endOfChunk =
          this.currentChunkPosition + this.currentChunk.data.length;
        if (endOfChunk <= target) {
          // The target is beyond the current chunk.
          // (we use ≤ not <: if the target is *at* the end of the chunk, possibly
          // because the current chunk is empty, we prefer to take the next chunk)

          const [data, nextChunk] = this._readToNextChunk();
          if (read) result += data;
          if (nextChunk === null) {
            if (this.position === target || lessIsFine) break;
            else throw new RangeError(E_END);
          }
        } else {
          // The target is within the current chunk.
          const newOffset = roundUp
            ? this.currentChunk.data.length
            : target - this.currentChunkPosition;
          if (read)
            result += this.currentChunk.data.substring(
              this.offsetInChunk,
              newOffset,
            );
          this.offsetInChunk = newOffset;

          // If we finish end at the end of the chunk, seek to the start of the next non-empty node.
          // (TODO decide: should we keep this guarantee of not finishing at the end of a chunk?)
          if (roundUp) this.seekBy(0);

          break;
        }
      }
    } else {
      // Similar to the if-block, but moving backward in the text.
      while (this.position > target) {
        if (this.currentChunkPosition <= target) {
          // The target is within the current chunk.
          const newOffset = roundUp ? 0 : target - this.currentChunkPosition;
          if (read)
            result =
              this.currentChunk.data.substring(newOffset, this.offsetInChunk) +
              result;
          this.offsetInChunk = newOffset;
          break;
        } else {
          const [data, previousChunk] = this._readToPreviousChunk();
          if (read) result = data + result;
          if (previousChunk === null) {
            if (lessIsFine) break;
            else throw new RangeError(E_END);
          }
        }
      }
    }

    if (read) return result;
  }