summaryrefslogtreecommitdiff
path: root/internal/gitdiff/io.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/gitdiff/io.go')
-rw-r--r--internal/gitdiff/io.go220
1 files changed, 0 insertions, 220 deletions
diff --git a/internal/gitdiff/io.go b/internal/gitdiff/io.go
deleted file mode 100644
index 8143238..0000000
--- a/internal/gitdiff/io.go
+++ /dev/null
@@ -1,220 +0,0 @@
-package gitdiff
-
-import (
- "errors"
- "io"
-)
-
-const (
- byteBufferSize = 32 * 1024 // from io.Copy
- lineBufferSize = 32
- indexBufferSize = 1024
-)
-
-// LineReaderAt is the interface that wraps the ReadLinesAt method.
-//
-// ReadLinesAt reads len(lines) into lines starting at line offset. It returns
-// the number of lines read (0 <= n <= len(lines)) and any error encountered.
-// Line numbers are zero-indexed.
-//
-// If n < len(lines), ReadLinesAt returns a non-nil error explaining why more
-// lines were not returned.
-//
-// Lines read by ReadLinesAt include the newline character. The last line does
-// not have a final newline character if the input ends without one.
-type LineReaderAt interface {
- ReadLinesAt(lines [][]byte, offset int64) (n int, err error)
-}
-
-type lineReaderAt struct {
- r io.ReaderAt
- index []int64
- eof bool
-}
-
-func (r *lineReaderAt) ReadLinesAt(lines [][]byte, offset int64) (n int, err error) {
- if offset < 0 {
- return 0, errors.New("ReadLinesAt: negative offset")
- }
- if len(lines) == 0 {
- return 0, nil
- }
-
- count := len(lines)
- startLine := offset
- endLine := startLine + int64(count)
-
- if endLine > int64(len(r.index)) && !r.eof {
- if err := r.indexTo(endLine); err != nil {
- return 0, err
- }
- }
- if startLine >= int64(len(r.index)) {
- return 0, io.EOF
- }
-
- buf, byteOffset, err := r.readBytes(startLine, int64(count))
- if err != nil {
- return 0, err
- }
-
- for n = 0; n < count && startLine+int64(n) < int64(len(r.index)); n++ {
- lineno := startLine + int64(n)
- start, end := int64(0), r.index[lineno]-byteOffset
- if lineno > 0 {
- start = r.index[lineno-1] - byteOffset
- }
- lines[n] = buf[start:end]
- }
-
- if n < count {
- return n, io.EOF
- }
- return n, nil
-}
-
-// indexTo reads data and computes the line index until there is information
-// for line or a read returns io.EOF. It returns an error if and only if there
-// is an error reading data.
-func (r *lineReaderAt) indexTo(line int64) error {
- var buf [indexBufferSize]byte
-
- offset := r.lastOffset()
- for int64(len(r.index)) < line {
- n, err := r.r.ReadAt(buf[:], offset)
- if err != nil && err != io.EOF {
- return err
- }
- for _, b := range buf[:n] {
- offset++
- if b == '\n' {
- r.index = append(r.index, offset)
- }
- }
- if err == io.EOF {
- if offset > r.lastOffset() {
- r.index = append(r.index, offset)
- }
- r.eof = true
- break
- }
- }
- return nil
-}
-
-func (r *lineReaderAt) lastOffset() int64 {
- if n := len(r.index); n > 0 {
- return r.index[n-1]
- }
- return 0
-}
-
-// readBytes reads the bytes of the n lines starting at line and returns the
-// bytes and the offset of the first byte in the underlying source.
-func (r *lineReaderAt) readBytes(line, n int64) (b []byte, offset int64, err error) {
- indexLen := int64(len(r.index))
-
- var size int64
- if line > indexLen {
- offset = r.index[indexLen-1]
- } else if line > 0 {
- offset = r.index[line-1]
- }
- if n > 0 {
- if line+n > indexLen {
- size = r.index[indexLen-1] - offset
- } else {
- size = r.index[line+n-1] - offset
- }
- }
-
- b = make([]byte, size)
- if _, err := r.r.ReadAt(b, offset); err != nil {
- if err == io.EOF {
- err = errors.New("ReadLinesAt: corrupt line index or changed source data")
- }
- return nil, 0, err
- }
- return b, offset, nil
-}
-
-func isLen(r io.ReaderAt, n int64) (bool, error) {
- off := n - 1
- if off < 0 {
- off = 0
- }
-
- var b [2]byte
- nr, err := r.ReadAt(b[:], off)
- if err == io.EOF {
- return (n == 0 && nr == 0) || (n > 0 && nr == 1), nil
- }
- return false, err
-}
-
-// copyFrom writes bytes starting from offset off in src to dst stopping at the
-// end of src or at the first error. copyFrom returns the number of bytes
-// written and any error.
-func copyFrom(dst io.Writer, src io.ReaderAt, off int64) (written int64, err error) {
- buf := make([]byte, byteBufferSize)
- for {
- nr, rerr := src.ReadAt(buf, off)
- if nr > 0 {
- nw, werr := dst.Write(buf[0:nr])
- if nw > 0 {
- written += int64(nw)
- }
- if werr != nil {
- err = werr
- break
- }
- if nr != nw {
- err = io.ErrShortWrite
- break
- }
- off += int64(nr)
- }
- if rerr != nil {
- if rerr != io.EOF {
- err = rerr
- }
- break
- }
- }
- return written, err
-}
-
-// copyLinesFrom writes lines starting from line off in src to dst stopping at
-// the end of src or at the first error. copyLinesFrom returns the number of
-// lines written and any error.
-func copyLinesFrom(dst io.Writer, src LineReaderAt, off int64) (written int64, err error) {
- buf := make([][]byte, lineBufferSize)
-ReadLoop:
- for {
- nr, rerr := src.ReadLinesAt(buf, off)
- if nr > 0 {
- for _, line := range buf[0:nr] {
- nw, werr := dst.Write(line)
- if nw > 0 {
- written++
- }
- if werr != nil {
- err = werr
- break ReadLoop
- }
- if len(line) != nw {
- err = io.ErrShortWrite
- break ReadLoop
- }
- }
- off += int64(nr)
- }
- if rerr != nil {
- if rerr != io.EOF {
- err = rerr
- }
- break
- }
- }
- return written, err
-}