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 }