// Injects the second reader into the first at an offset
338506
func InjectedReader(
	offsetFromStart int64,
	base io.Reader,
	inject io.Reader,
) io.Reader {
	return io.MultiReader(
		io.LimitReader(base, offsetFromStart),
		inject,
		base,
	)
}
177737
func (t *Torrent) forReaderOffsetPieces(f func(begin, end pieceIndex) (more bool)) (all bool) {
	for r := range t.readers {
		p := r.pieces
		if p.begin >= p.end {
			continue
		}
		if !f(p.begin, p.end) {
			return false
		}
	}
	return true
}
1252796
func (l *ReaderLexer) Next() (r rune) {
	/* Illustrated guide to how the cursors move:

	              pos
	              |
	              v
	buf | a | b | c |
	              ^
	              |
	              peekLoc

	-> l.Nex() -> returns d

	                  pos
	                  |
	                  v
	buf | a | b | c | d |
	                  ^
	                  |
	                  peekLoc


	-> l.Peek() -> returns e

	                  pos
	                  |
	                  v
	buf | a | b | c | d | e |
	                      ^
	                      |
	                      peekLoc

	-> l.Backup()
	-> l.Backup()

	              pos
	              |
	              v
	buf | a | b | c | d | e |
	              ^
	              |
	              peekLoc

	-> l.Next() -> returns c

	                  pos
	                  |
	                  v
	buf | a | b | c | d | e |
	                  ^
	                  |
	                  peekLoc

	-> l.Next() -> returns d

	                      pos
	                      |
	                      v
	buf | a | b | c | d | e |
	                      ^
	                      |
	                      peekLoc
	*/
	guard := Mark("Next")
	defer func() {
		Trace("return = %q", r)
		guard()
	}()

	if l.pos == -1 || len(l.buf) == l.peekLoc+1 {
		r, _, err := l.source.ReadRune()
		switch err {
		case nil:
			l.peekLoc++
			l.pos++
			l.buf = append(l.buf, r)
		case io.EOF:
			l.peekLoc++
			l.pos++
			r = -1
			if l.buf[len(l.buf)-1] != r {
				l.buf = append(l.buf, r)
			}
		}
	} else {
		l.peekLoc++
		l.pos++
	}

	loc := l.peekLoc

	if loc < 0 || len(l.buf) <= loc {
		return EOF
		//    panic(fmt.Sprintf("FATAL: loc = %d, l.buf = %q (len = %d)", loc, l.buf, len(l.buf)))
	}

	Trace("l.buf = %q, loc = %d", l.buf, loc)
	return l.buf[loc]
}
360620
func (pool *ReaderPool) AcquireReader(buf []byte, simple bool) (reader *Reader) {
	reader = pool.Get().(*Reader)
	reader.Init(buf)
	reader.Simple = simple
	return
}
740441
func (c *CommitLog) NewReader(offset int64) (io.Reader, error) {
	c.mu.RLock()
	defer c.mu.RUnlock()
	log.With("num_segments", len(c.segments)).
		With("offset", offset).
		Infoln("searching segments")

	// in the event there has been data committed to the segment but no offset for a path,
	// then we need to create a reader that starts from the very beginning
	if offset < 0 && len(c.segments) > 0 {
		// if err := c.segments[0].Open(); err != nil {
		// 	log.Errorf("unable to open segment, %s", err)
		// }
		return &Reader{commitlog: c, idx: 0, position: 0}, nil
	}

	var idx int
	for i := 0; i < len(c.segments); i++ {
		idx = i
		if (i + 1) != len(c.segments) {
			lowerOffset := c.segments[i].BaseOffset
			upperOffset := c.segments[i+1].BaseOffset
			log.With("lower_offset", lowerOffset).
				With("upper_offset", upperOffset).
				With("offset", offset).
				With("segment", idx).
				Debugln("checking if offset in segment")
			if offset >= lowerOffset && offset < upperOffset {
				break
			}
		}
	}

	log.With("offset", offset).With("segment_index", idx).Debugln("finding offset in segment")
	// if err := c.segments[idx].Open(); err != nil {
	// 	log.Errorf("unable to open segment, %s", err)
	// }
	position, err := c.segments[idx].FindOffsetPosition(uint64(offset))
	if err != nil {
		return nil, err
	}

	return &Reader{
		commitlog: c,
		idx:       idx,
		position:  position,
	}, nil
}
269552
func seekReader(r io.Reader, offset, size int64) (io.Reader, error) {
	// attempt to resolve r as a seeker and setup the offset.
	seeker, ok := r.(io.Seeker)
	if ok {
		nn, err := seeker.Seek(offset, io.SeekStart)
		if nn != offset {
			return nil, errors.Wrapf(err, "failed to seek to offset %v", offset)
		}

		if err != nil {
			return nil, err
		}

		return r, nil
	}

	// ok, let's try io.ReaderAt!
	readerAt, ok := r.(io.ReaderAt)
	if ok && size > offset {
		sr := io.NewSectionReader(readerAt, offset, size)
		return sr, nil
	}

	// well then, let's just discard up to the offset
	n, err := copyWithBuffer(ioutil.Discard, io.LimitReader(r, offset))
	if err != nil {
		return nil, errors.Wrap(err, "failed to discard to offset")
	}
	if n != offset {
		return nil, errors.Errorf("unable to discard to offset")
	}

	return r, nil
}
15404
func (base *Base) Reader(ctx context.Context, path string, offset int64) (io.ReadCloser, error) {
	ctx, done := dcontext.WithTrace(ctx)
	defer done("%s.Reader(%q, %d)", base.Name(), path, offset)

	if offset < 0 {
		return nil, storagedriver.InvalidOffsetError{Path: path, Offset: offset, DriverName: base.StorageDriver.Name()}
	}

	if !storagedriver.PathRegexp.MatchString(path) {
		return nil, storagedriver.InvalidPathError{Path: path, DriverName: base.StorageDriver.Name()}
	}

	rc, e := base.StorageDriver.Reader(ctx, path, offset)
	return rc, base.setDriverName(e)
}
781518
func (br *Reader) Seek(off bgzf.Offset) error {
	return br.r.Seek(off)
}
353639
func NewReaderLexer(in io.Reader, fn LexFn) *ReaderLexer {
	return &ReaderLexer{
		bufio.NewReader(in),
		0,
		-1,
		-1,
		1,
		[]rune{},
		make(chan LexItem, 1),
		fn,
	}
}
856940
func NewReader(input io.Reader) *Reader {
	return &Reader{
		input: bufio.NewReader(input),
	}
}
1015646
func NewReader(ctx context.Context, r io.Reader) *Reader {
	return &Reader{
		ctx:    ctx,
		reader: r,
	}
}
388646
func (r *walReader) next() bool {
	if r.cur >= len(r.files) {
		return false
	}
	cf := r.files[r.cur]

	// Remember the offset after the last correctly read entry. If the next one
	// is corrupted, this is where we can safely truncate.
	r.lastOffset, r.err = cf.Seek(0, io.SeekCurrent)
	if r.err != nil {
		return false
	}

	et, flag, b, err := r.entry(cf)
	// If we reached the end of the reader, advance to the next one
	// and close.
	// Do not close on the last one as it will still be appended to.
	if err == io.EOF {
		if r.cur == len(r.files)-1 {
			return false
		}
		// Current reader completed, close and move to the next one.
		if err := cf.Close(); err != nil {
			r.err = err
			return false
		}
		r.cur++
		return r.next()
	}
	if err != nil {
		r.err = err
		return false
	}

	r.curType = et
	r.curFlag = flag
	r.curBuf = b
	return r.err == nil
}
887585
func (f *FileReader) Seek(offset int64, whence int) (int64, error) {
	if f.closed {
		return 0, io.ErrClosedPipe
	}

	var off int64
	if whence == 0 {
		off = offset
	} else if whence == 1 {
		off = f.offset + offset
	} else if whence == 2 {
		off = f.info.Size() + offset
	} else {
		return f.offset, fmt.Errorf("invalid whence: %d", whence)
	}

	if off < 0 || off > f.info.Size() {
		return f.offset, fmt.Errorf("invalid resulting offset: %d", off)
	}

	if f.offset != off {
		f.offset = off
		if f.blockReader != nil {
			f.blockReader.Close()
			f.blockReader = nil
		}
	}
	return f.offset, nil
}
590155
func (br *bitReader) FlushOffset() int64 {
	if br.bufRd == nil {
		return br.offset
	}

	// Update the number of total bits to discard.
	br.discardBits += int(br.fedBits - br.numBits)
	br.fedBits = br.numBits

	// Discard some bytes to update read offset.
	nd := (br.discardBits + 7) / 8 // Round up to nearest byte
	nd, _ = br.bufRd.Discard(nd)
	br.discardBits -= nd * 8 // -7..0
	br.offset += int64(nd)

	// These are invalid after Discard.
	br.bufPeek = nil
	return br.offset
}
626387
func NewReader(r io.Reader) io.Reader {
	buf := bufio.NewReader(r)
	b, err := buf.Peek(3)
	if err != nil {
		// not enough bytes
		return buf
	}
	if b[0] == bom0 && b[1] == bom1 && b[2] == bom2 {
		discardBytes(buf, 3)
	}
	return buf
}
939108
func NewBreakReader(r io.Reader, n int64) io.Reader {
	return &breakReader{r: r, n: n}
}
1199351
func (h *TermsHashPerFieldImpl) initReader(reader *ByteSliceReader, termId, stream int) {
	assert(stream < h.streamCount)
	intStart := h.postingsArray.intStarts[termId]
	ints := h.intPool.Buffers[intStart>>util.INT_BLOCK_SHIFT]
	upto := intStart & util.INT_BLOCK_MASK
	reader.init(h.bytePool,
		h.postingsArray.byteStarts[termId]+stream*util.FIRST_LEVEL_SIZE,
		ints[upto+stream])
}