提交 411f9d67 作者: Jeromy Johnson 提交者: GitHub

Merge pull request #3095 from ipfs/fix/unixfs-relative-seek-expand

unixfs: fix relative seek not expanding file properly 
......@@ -210,6 +210,10 @@ func (dr *DagReader) Close() error {
return nil
}
func (dr *DagReader) Offset() int64 {
return dr.offset
}
// Seek implements io.Seeker, and will seek to a given offset in the file
// interface matches standard unix seek
// TODO: check if we can do relative seeks, to reduce the amount of dagreader
......
......@@ -6,10 +6,6 @@ import (
"io"
"os"
mh "gx/ipfs/QmYf7ng2hG5XBtJA3tN34DQ2GUN5HNksEw1rLDkmr6vGku/go-multihash"
proto "gx/ipfs/QmZ4Qi3GaRbjcx28Sme5eMH7RQjGkt8wHxt2a65oLaeFEV/gogo-protobuf/proto"
context "gx/ipfs/QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt/go-net/context"
key "github.com/ipfs/go-ipfs/blocks/key"
chunk "github.com/ipfs/go-ipfs/importer/chunk"
help "github.com/ipfs/go-ipfs/importer/helpers"
......@@ -17,11 +13,14 @@ import (
mdag "github.com/ipfs/go-ipfs/merkledag"
ft "github.com/ipfs/go-ipfs/unixfs"
uio "github.com/ipfs/go-ipfs/unixfs/io"
logging "gx/ipfs/QmNQynaz7qfriSUJkiEZUrm2Wen1u3Kj9goZzWtrPyu7XR/go-log"
mh "gx/ipfs/QmYf7ng2hG5XBtJA3tN34DQ2GUN5HNksEw1rLDkmr6vGku/go-multihash"
proto "gx/ipfs/QmZ4Qi3GaRbjcx28Sme5eMH7RQjGkt8wHxt2a65oLaeFEV/gogo-protobuf/proto"
context "gx/ipfs/QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt/go-net/context"
)
var ErrSeekFail = errors.New("failed to seek properly")
var ErrSeekEndNotImpl = errors.New("SEEK_END currently not implemented")
var ErrUnrecognizedWhence = errors.New("unrecognized whence")
// 2MB
......@@ -378,8 +377,8 @@ func (dm *DagModifier) Seek(offset int64, whence int) (int64, error) {
return 0, ErrUnrecognizedWhence
}
if offset > fisize {
if err := dm.expandSparse(offset - fisize); err != nil {
if int64(newoffset) > fisize {
if err := dm.expandSparse(int64(newoffset) - fisize); err != nil {
return 0, err
}
}
......
......@@ -17,10 +17,10 @@ import (
mdag "github.com/ipfs/go-ipfs/merkledag"
ft "github.com/ipfs/go-ipfs/unixfs"
uio "github.com/ipfs/go-ipfs/unixfs/io"
"gx/ipfs/QmTxLSvdhwg68WJimdS6icLPhZi28aTp6b7uihC2Yb47Xk/go-datastore/sync"
u "gx/ipfs/QmZNVWh8LLjAavuQ2JXuFmuYH3C11xo988vSgp7UQrTRj1/go-ipfs-util"
ds "gx/ipfs/QmTxLSvdhwg68WJimdS6icLPhZi28aTp6b7uihC2Yb47Xk/go-datastore"
"gx/ipfs/QmTxLSvdhwg68WJimdS6icLPhZi28aTp6b7uihC2Yb47Xk/go-datastore/sync"
u "gx/ipfs/QmZNVWh8LLjAavuQ2JXuFmuYH3C11xo988vSgp7UQrTRj1/go-ipfs-util"
context "gx/ipfs/QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt/go-net/context"
)
......@@ -548,6 +548,151 @@ func TestSeekPastEndWrite(t *testing.T) {
}
}
func TestRelativeSeek(t *testing.T) {
dserv := getMockDagServ(t)
_, n := getNode(t, dserv, 0)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
dagmod, err := NewDagModifier(ctx, n, dserv, sizeSplitterGen(512))
if err != nil {
t.Fatal(err)
}
for i := 0; i < 64; i++ {
dagmod.Write([]byte{byte(i)})
if _, err := dagmod.Seek(1, os.SEEK_CUR); err != nil {
t.Fatal(err)
}
}
out, err := ioutil.ReadAll(dagmod)
if err != nil {
t.Fatal(err)
}
for i, v := range out {
if v != 0 && i/2 != int(v) {
t.Errorf("expected %d, at index %d, got %d", i/2, i, v)
}
}
}
func TestInvalidSeek(t *testing.T) {
dserv := getMockDagServ(t)
_, n := getNode(t, dserv, 0)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
dagmod, err := NewDagModifier(ctx, n, dserv, sizeSplitterGen(512))
if err != nil {
t.Fatal(err)
}
_, err = dagmod.Seek(10, -10)
if err != ErrUnrecognizedWhence {
t.Fatal(err)
}
}
func TestEndSeek(t *testing.T) {
dserv := getMockDagServ(t)
_, n := getNode(t, dserv, 0)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
dagmod, err := NewDagModifier(ctx, n, dserv, sizeSplitterGen(512))
if err != nil {
t.Fatal(err)
}
_, err = dagmod.Write(make([]byte, 100))
if err != nil {
t.Fatal(err)
}
offset, err := dagmod.Seek(0, os.SEEK_CUR)
if offset != 100 {
t.Fatal("expected the relative seek 0 to return current location")
}
offset, err = dagmod.Seek(0, os.SEEK_SET)
if offset != 0 {
t.Fatal("expected the absolute seek to set offset at 0")
}
offset, err = dagmod.Seek(0, os.SEEK_END)
if offset != 100 {
t.Fatal("expected the end seek to set offset at end")
}
}
func TestReadAndSeek(t *testing.T) {
dserv := getMockDagServ(t)
_, n := getNode(t, dserv, 0)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
dagmod, err := NewDagModifier(ctx, n, dserv, sizeSplitterGen(512))
if err != nil {
t.Fatal(err)
}
writeBuf := []byte{0, 1, 2, 3, 4, 5, 6, 7}
dagmod.Write(writeBuf)
readBuf := make([]byte, 4)
offset, err := dagmod.Seek(0, os.SEEK_SET)
if offset != 0 {
t.Fatal("expected offset to be 0")
}
if err != nil {
t.Fatal(err)
}
// read 0,1,2,3
c, err := dagmod.Read(readBuf)
if err != nil {
t.Fatal(err)
}
if c != 4 {
t.Fatalf("expected length of 4 got %d", c)
}
for i := byte(0); i < 4; i++ {
if readBuf[i] != i {
t.Fatalf("wrong value %d [at index %d]", readBuf[i], i)
}
}
// skip 4
_, err = dagmod.Seek(1, os.SEEK_CUR)
if err != nil {
t.Fatalf("error: %s, offset %d, reader offset %d", err, dagmod.curWrOff, dagmod.read.Offset())
}
//read 5,6,7
readBuf = make([]byte, 3)
c, err = dagmod.Read(readBuf)
if err != nil {
t.Fatal(err)
}
if c != 3 {
t.Fatalf("expected length of 3 got %d", c)
}
for i := byte(0); i < 3; i++ {
if readBuf[i] != i+5 {
t.Fatalf("wrong value %d [at index %d]", readBuf[i], i)
}
}
}
func BenchmarkDagmodWrite(b *testing.B) {
b.StopTimer()
dserv := getMockDagServ(b)
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论