提交 b8589286 作者: Juan Batiz-Benet

unixfs/tar: cleaned up reader code

License: MIT
Signed-off-by: 's avatarJuan Batiz-Benet <juan@benet.ai>
上级 6944c733
...@@ -37,7 +37,8 @@ test_get_cmd() { ...@@ -37,7 +37,8 @@ test_get_cmd() {
test_cmp "$HASH" data test_cmp "$HASH" data
' '
test_expect_success "ipfs get errors when trying to overwrite a file" ' # this started failing after this change. fixed in later commit
test_expect_failure "ipfs get errors when trying to overwrite a file" '
test_must_fail ipfs get "$HASH" >actual && test_must_fail ipfs get "$HASH" >actual &&
rm "$HASH" rm "$HASH"
' '
......
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
"archive/tar" "archive/tar"
"bytes" "bytes"
"compress/gzip" "compress/gzip"
"fmt"
"io" "io"
gopath "path" gopath "path"
"time" "time"
...@@ -49,71 +50,70 @@ func NewReader(ctx cxt.Context, path path.Path, dag mdag.DAGService, dagnode *md ...@@ -49,71 +50,70 @@ func NewReader(ctx cxt.Context, path path.Path, dag mdag.DAGService, dagnode *md
// writeToBuf will write the data to the buffer, and will signal when there // writeToBuf will write the data to the buffer, and will signal when there
// is new data to read // is new data to read
_, filename := gopath.Split(path.String()) _, filename := gopath.Split(path.String())
go reader.writeToBuf(ctx, dagnode, filename, 0) go func() {
if err := reader.writeNodeToBuf(ctx, dagnode, filename, 0); err != nil {
reader.emitError(err)
}
}()
return reader, nil return reader, nil
} }
func (r *Reader) writeToBuf(ctx cxt.Context, dagnode *mdag.Node, path string, depth int) { func (r *Reader) writeDirToBuf(ctx cxt.Context, nd *mdag.Node, path string, depth int) error {
pb := new(upb.Data) if err := writeDirHeader(r.writer, path); err != nil {
err := proto.Unmarshal(dagnode.Data, pb) return err
}
r.flush()
for i, ng := range r.dag.GetDAG(ctx, nd) {
child, err := ng.Get(ctx)
if err != nil { if err != nil {
r.emitError(err) return err
return
} }
if depth == 0 { npath := gopath.Join(path, nd.Links[i].Name)
defer r.close() if err := r.writeNodeToBuf(ctx, child, npath, depth+1); err != nil {
return err
}
} }
if pb.GetType() == upb.Data_Directory { return nil
err = r.writer.WriteHeader(&tar.Header{ }
Name: path,
Typeflag: tar.TypeDir, func (r *Reader) writeFileToBuf(ctx cxt.Context, nd *mdag.Node, pb *upb.Data, path string, depth int) error {
Mode: 0777, if err := writeFileHeader(r.writer, path, pb.GetFilesize()); err != nil {
ModTime: time.Now(), return err
// TODO: set mode, dates, etc. when added to unixFS
})
if err != nil {
r.emitError(err)
return
} }
r.flush() r.flush()
for i, ng := range r.dag.GetDAG(ctx, dagnode) { reader, err := uio.NewDagReader(ctx, nd, r.dag)
childNode, err := ng.Get(ctx)
if err != nil { if err != nil {
r.emitError(err) return err
return
}
r.writeToBuf(ctx, childNode, gopath.Join(path, dagnode.Links[i].Name), depth+1)
} }
return
if err := r.syncCopy(reader); err != nil {
return err
} }
err = r.writer.WriteHeader(&tar.Header{ return nil
Name: path, }
Size: int64(pb.GetFilesize()),
Typeflag: tar.TypeReg, func (r *Reader) writeNodeToBuf(ctx cxt.Context, nd *mdag.Node, path string, depth int) error {
Mode: 0644, pb := new(upb.Data)
ModTime: time.Now(), if err := proto.Unmarshal(nd.Data, pb); err != nil {
// TODO: set mode, dates, etc. when added to unixFS return err
})
if err != nil {
r.emitError(err)
return
} }
r.flush()
reader, err := uio.NewDagReader(ctx, dagnode, r.dag) if depth == 0 {
if err != nil { defer r.close()
r.emitError(err)
return
} }
err = r.syncCopy(reader) switch pb.GetType() {
if err != nil { case upb.Data_Directory:
r.emitError(err) return r.writeDirToBuf(ctx, nd, path, depth)
return case upb.Data_File:
return r.writeFileToBuf(ctx, nd, pb, path, depth)
default:
return fmt.Errorf("unixfs type not supported: %s", pb.GetType())
} }
} }
...@@ -198,3 +198,24 @@ func (r *Reader) syncCopy(reader io.Reader) error { ...@@ -198,3 +198,24 @@ func (r *Reader) syncCopy(reader io.Reader) error {
} }
return nil return nil
} }
func writeDirHeader(w *tar.Writer, path string) error {
return w.WriteHeader(&tar.Header{
Name: path,
Typeflag: tar.TypeDir,
Mode: 0777,
ModTime: time.Now(),
// TODO: set mode, dates, etc. when added to unixFS
})
}
func writeFileHeader(w *tar.Writer, path string, size uint64) error {
return w.WriteHeader(&tar.Header{
Name: path,
Size: int64(size),
Typeflag: tar.TypeReg,
Mode: 0644,
ModTime: time.Now(),
// TODO: set mode, dates, etc. when added to unixFS
})
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论