101 lines
1.7 KiB
Go
101 lines
1.7 KiB
Go
|
|
package docbuf
|
||
|
|
|
||
|
|
import (
|
||
|
|
"errors"
|
||
|
|
"io"
|
||
|
|
"fmt"
|
||
|
|
)
|
||
|
|
|
||
|
|
/* WARNING:
|
||
|
|
* This code is meant to assist with testing and mock ups
|
||
|
|
* It is not only not designed to any rigorous standards,
|
||
|
|
* but additionally does not offer any benefit over a static
|
||
|
|
* in memory single layer cache.
|
||
|
|
*/
|
||
|
|
|
||
|
|
type ReadWriteSeekString struct {
|
||
|
|
inner string
|
||
|
|
cursor int
|
||
|
|
}
|
||
|
|
|
||
|
|
func NewReadWriteSeekString() ReadWriteSeekString{
|
||
|
|
return ReadWriteSeekString{
|
||
|
|
inner: "",
|
||
|
|
cursor: 0,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func (s *ReadWriteSeekString) Read(
|
||
|
|
buf []byte,
|
||
|
|
) (int, error) {
|
||
|
|
i := 0
|
||
|
|
for ; i < len(buf); i++ {
|
||
|
|
if len(s.inner) <= s.cursor {
|
||
|
|
return i, nil
|
||
|
|
}
|
||
|
|
buf[i] = s.inner[s.cursor]
|
||
|
|
s.cursor += 1
|
||
|
|
}
|
||
|
|
return i, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (s *ReadWriteSeekString) Write(
|
||
|
|
buf []byte,
|
||
|
|
) (int, error) {
|
||
|
|
backfillDelta := s.cursor - (len(s.inner) - 1)
|
||
|
|
if backfillDelta > 0 {
|
||
|
|
for range backfillDelta {
|
||
|
|
s.inner += "\x00"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
tmpBuf := ""
|
||
|
|
if s.cursor > 0 {
|
||
|
|
tmpBuf += s.inner[:s.cursor]
|
||
|
|
}
|
||
|
|
tmpBuf += string(buf)
|
||
|
|
if s.cursor + len(buf) < (len(s.inner) - 1) {
|
||
|
|
tmpBuf += s.inner[s.cursor + len(buf):]
|
||
|
|
}
|
||
|
|
|
||
|
|
s.inner = tmpBuf
|
||
|
|
s.cursor += len(buf)
|
||
|
|
return len(buf), nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (s *ReadWriteSeekString) Seek(
|
||
|
|
offset int64,
|
||
|
|
whence int,
|
||
|
|
) (int64, error) {
|
||
|
|
var tmpCur int64
|
||
|
|
tmpCur = 0
|
||
|
|
|
||
|
|
switch whence {
|
||
|
|
case io.SeekCurrent:
|
||
|
|
tmpCur = int64(s.cursor)
|
||
|
|
case io.SeekEnd:
|
||
|
|
tmpCur = int64(len(s.inner))
|
||
|
|
case io.SeekStart:
|
||
|
|
tmpCur = int64(0)
|
||
|
|
default:
|
||
|
|
return int64(s.cursor),
|
||
|
|
errors.New("invalid whence value")
|
||
|
|
}
|
||
|
|
|
||
|
|
tmpCur += offset
|
||
|
|
if tmpCur < 0 {
|
||
|
|
msg := fmt.Sprintf("seek index (%d) is negative", tmpCur)
|
||
|
|
return int64(s.cursor), errors.New(msg)
|
||
|
|
}
|
||
|
|
s.cursor = int(tmpCur)
|
||
|
|
return tmpCur, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (s *ReadWriteSeekString) Contents() string {
|
||
|
|
return s.inner
|
||
|
|
}
|
||
|
|
|
||
|
|
func (s *ReadWriteSeekString) Cursor() int {
|
||
|
|
return s.cursor
|
||
|
|
}
|