mirror of
https://github.com/wavetermdev/waveterm.git
synced 2024-12-31 18:18:02 +01:00
update to allow a WriteAt call for cirfiles
This commit is contained in:
parent
e1eecae6d3
commit
26bd499fac
@ -307,18 +307,24 @@ func (f *File) getFreeChunks() []fileChunk {
|
||||
return rtn
|
||||
}
|
||||
|
||||
// returns (realOffset, data, error)
|
||||
// will only return io.EOF when len(data) == 0, otherwise will just do a short read
|
||||
func (f *File) ReadNext(ctx context.Context, buf []byte, offset int64) (int64, int, error) {
|
||||
func (f *File) ReadAll(ctx context.Context) (int64, []byte, error) {
|
||||
err := f.flock(ctx, syscall.LOCK_SH)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
return 0, nil, err
|
||||
}
|
||||
defer f.unflock()
|
||||
err = f.readMeta()
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
return 0, nil, err
|
||||
}
|
||||
chunks := f.getFileChunks()
|
||||
curSize := totalChunksSize(chunks)
|
||||
buf := make([]byte, curSize)
|
||||
realOffset, nr, err := f.internalReadNext(buf, 0)
|
||||
return realOffset, buf[0:nr], err
|
||||
}
|
||||
|
||||
func (f *File) internalReadNext(buf []byte, offset int64) (int64, int, error) {
|
||||
if offset < f.FileOffset {
|
||||
offset = f.FileOffset
|
||||
}
|
||||
@ -347,6 +353,21 @@ func (f *File) ReadNext(ctx context.Context, buf []byte, offset int64) (int64, i
|
||||
return offset, numRead, nil
|
||||
}
|
||||
|
||||
// returns (realOffset, numread, error)
|
||||
// will only return io.EOF when len(data) == 0, otherwise will just do a short read
|
||||
func (f *File) ReadNext(ctx context.Context, buf []byte, offset int64) (int64, int, error) {
|
||||
err := f.flock(ctx, syscall.LOCK_SH)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
defer f.unflock()
|
||||
err = f.readMeta()
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
return f.internalReadNext(buf, offset)
|
||||
}
|
||||
|
||||
func (f *File) ensureFreeSpace(requiredSpace int64) error {
|
||||
chunks := f.getFileChunks()
|
||||
curSpace := f.MaxSize - totalChunksSize(chunks)
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"syscall"
|
||||
"testing"
|
||||
"time"
|
||||
@ -28,7 +29,9 @@ func validateMeta(t *testing.T, desc string, f *File, startPos int64, endPos int
|
||||
|
||||
func dumpFile(name string) {
|
||||
barr, _ := os.ReadFile(name)
|
||||
fmt.Printf("<<<\n%s\n>>>", string(barr))
|
||||
str := string(barr)
|
||||
str = strings.ReplaceAll(str, "\x00", ".")
|
||||
fmt.Printf("%s<<<\n%s\n>>>\n", name, str)
|
||||
}
|
||||
|
||||
func makeData(size int) string {
|
||||
@ -216,3 +219,64 @@ func TestFlock(t *testing.T) {
|
||||
t.Fatalf("append error (should work fd2 was closed): %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteAt(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
f1Name := path.Join(tempDir, "f1.cf")
|
||||
f, err := CreateCirFile(f1Name, 100)
|
||||
if err != nil {
|
||||
t.Fatalf("cannot create cirfile: %v", err)
|
||||
}
|
||||
err = f.WriteAt(nil, []byte("hello\nmike"), 4)
|
||||
if err != nil {
|
||||
t.Fatalf("writeat error: %v", err)
|
||||
}
|
||||
err = f.WriteAt(nil, []byte("t"), 2)
|
||||
if err != nil {
|
||||
t.Fatalf("writeat error: %v", err)
|
||||
}
|
||||
err = f.WriteAt(nil, []byte("more"), 30)
|
||||
if err != nil {
|
||||
t.Fatalf("writeat error: %v", err)
|
||||
}
|
||||
err = f.WriteAt(nil, []byte("\n"), 19)
|
||||
if err != nil {
|
||||
t.Fatalf("writeat error: %v", err)
|
||||
}
|
||||
dumpFile(f1Name)
|
||||
err = f.WriteAt(nil, []byte("hello"), 200)
|
||||
if err != nil {
|
||||
t.Fatalf("writeat error: %v", err)
|
||||
}
|
||||
buf := make([]byte, 10)
|
||||
realOffset, nr, err := f.ReadNext(context.Background(), buf, 200)
|
||||
if err != nil || realOffset != 200 || nr != 5 || string(buf[0:nr]) != "hello" {
|
||||
t.Fatalf("invalid readnext: err[%v] realoffset[%d] nr[%d] buf[%s]", err, realOffset, nr, string(buf[0:nr]))
|
||||
}
|
||||
err = f.WriteAt(nil, []byte("0123456789\n"), 100)
|
||||
if err != nil {
|
||||
t.Fatalf("writeat error: %v", err)
|
||||
}
|
||||
dumpFile(f1Name)
|
||||
dataStr := makeData(200)
|
||||
err = f.WriteAt(nil, []byte(dataStr), 50)
|
||||
if err != nil {
|
||||
t.Fatalf("writeat error: %v", err)
|
||||
}
|
||||
dumpFile(f1Name)
|
||||
|
||||
dataStr = makeData(1000)
|
||||
err = f.WriteAt(nil, []byte(dataStr), 1002)
|
||||
if err != nil {
|
||||
t.Fatalf("writeat error: %v", err)
|
||||
}
|
||||
err = f.WriteAt(nil, []byte("hello\n"), 2010)
|
||||
if err != nil {
|
||||
t.Fatalf("writeat error: %v", err)
|
||||
}
|
||||
err = f.AppendData(nil, []byte("foo\n"))
|
||||
if err != nil {
|
||||
t.Fatalf("appenddata error: %v", err)
|
||||
}
|
||||
dumpFile(f1Name)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user