github.com/jmigpin/editor@v1.6.0/util/iout/iorw/bytesreadwriter.go (about)

     1  package iorw
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  )
     7  
     8  type BytesReadWriterAt struct {
     9  	buf []byte
    10  }
    11  
    12  func NewBytesReadWriterAt(b []byte) *BytesReadWriterAt {
    13  	return &BytesReadWriterAt{b}
    14  }
    15  
    16  //----------
    17  
    18  // Implement ReaderAt
    19  func (rw *BytesReadWriterAt) ReadFastAt(i, n int) ([]byte, error) {
    20  	if i < 0 {
    21  		return nil, fmt.Errorf("bad index: %v<0", i)
    22  	}
    23  	if i > len(rw.buf) {
    24  		return nil, fmt.Errorf("bad index: %v>%v", i, len(rw.buf))
    25  	}
    26  
    27  	// before "i==len" to allow reading an empty buffer (ex: readfull("") without err)
    28  	if n == 0 {
    29  		return nil, nil
    30  	}
    31  	if n < 0 {
    32  		return nil, fmt.Errorf("bad arg: %v<0", n)
    33  	}
    34  
    35  	if i == len(rw.buf) {
    36  		return nil, io.EOF
    37  	}
    38  
    39  	// i>=0 && i<len && n>=0 -> n>=1
    40  	if i+n > len(rw.buf) {
    41  		n = len(rw.buf) - i
    42  	}
    43  
    44  	return rw.buf[i : i+n], nil
    45  }
    46  
    47  // Implement ReaderAt
    48  func (rw *BytesReadWriterAt) Min() int { return 0 }
    49  
    50  // Implement ReaderAt
    51  func (rw *BytesReadWriterAt) Max() int { return len(rw.buf) }
    52  
    53  //----------
    54  
    55  // Implement WriterAt
    56  func (rw *BytesReadWriterAt) OverwriteAt(i, del int, p []byte) error {
    57  	// delete
    58  	if i+del > len(rw.buf) {
    59  		return fmt.Errorf("iorw.OverwriteAt: del %v>%v", i+del, len(rw.buf))
    60  	}
    61  	copy(rw.buf[i:], rw.buf[i+del:])
    62  	rw.buf = rw.buf[:len(rw.buf)-del]
    63  	// insert
    64  	l := len(rw.buf)
    65  	if l+len(p) <= cap(rw.buf) {
    66  		rw.buf = rw.buf[:l+len(p)] // increase length
    67  	} else {
    68  		rw.buf = append(rw.buf, p...) // increase capacity
    69  	}
    70  	copy(rw.buf[i+len(p):], rw.buf[i:l]) // shift data to the right
    71  	n := copy(rw.buf[i:], p)
    72  	if n != len(p) {
    73  		return fmt.Errorf("iorw.OverwriteAt: failed full write: %v!=%v", n, len(p))
    74  	}
    75  
    76  	rw.buf = autoReduceCap(rw.buf)
    77  	return nil
    78  }
    79  
    80  //----------
    81  
    82  func autoReduceCap(p []byte) []byte {
    83  	if len(p) > 1024 && len(p) < 3*cap(p) {
    84  		return append([]byte{}, p...)
    85  	}
    86  	return p
    87  }