提交 a1510413 作者: Łukasz Magiera

coreapi: extract unixfile to go-unixfs

License: MIT
Signed-off-by: 's avatarŁukasz Magiera <magik6k@gmail.com>
上级 aa3e087e
package coreapi
import (
"context"
"errors"
ipld "gx/ipfs/QmRL22E4paat7ky7vx9MLpR97JHHbFPrg3ytFQw6qp1y1s/go-ipld-format"
ft "gx/ipfs/QmSMJ4rZbCJaih3y82Ebq7BZqK6vU2FHsKcWKQiE1DPTpS/go-unixfs"
uio "gx/ipfs/QmSMJ4rZbCJaih3y82Ebq7BZqK6vU2FHsKcWKQiE1DPTpS/go-unixfs/io"
files "gx/ipfs/QmXWZCd8jfaHmt4UDSnjKmGcrQMw95bDGWqEeVLVJjoANX/go-ipfs-files"
dag "gx/ipfs/Qmb2UEG2TAeVrEJSjqsZF7Y2he7wRDkrdt6c3bECxwZf4k/go-merkledag"
)
// Number to file to prefetch in directories
// TODO: should we allow setting this via context hint?
const prefetchFiles = 4
// TODO: this probably belongs in go-unixfs (and could probably replace a chunk of it's interface in the long run)
type ufsDirectory struct {
ctx context.Context
dserv ipld.DAGService
dir uio.Directory
}
type ufsIterator struct {
ctx context.Context
files chan *ipld.Link
dserv ipld.DAGService
curName string
curFile files.Node
err error
errCh chan error
}
func (it *ufsIterator) Name() string {
return it.curName
}
func (it *ufsIterator) Node() files.Node {
return it.curFile
}
func (it *ufsIterator) Next() bool {
if it.err != nil {
return false
}
var l *ipld.Link
var ok bool
for !ok {
if it.files == nil && it.errCh == nil {
return false
}
select {
case l, ok = <-it.files:
if !ok {
it.files = nil
}
case err := <-it.errCh:
it.errCh = nil
it.err = err
if err != nil {
return false
}
}
}
it.curFile = nil
nd, err := l.GetNode(it.ctx, it.dserv)
if err != nil {
it.err = err
return false
}
it.curName = l.Name
it.curFile, it.err = newUnixfsFile(it.ctx, it.dserv, nd)
return it.err == nil
}
func (it *ufsIterator) Err() error {
return it.err
}
func (d *ufsDirectory) Close() error {
return nil
}
func (d *ufsDirectory) Entries() files.DirIterator {
fileCh := make(chan *ipld.Link, prefetchFiles)
errCh := make(chan error, 1)
go func() {
errCh <- d.dir.ForEachLink(d.ctx, func(link *ipld.Link) error {
if d.ctx.Err() != nil {
return d.ctx.Err()
}
select {
case fileCh <- link:
case <-d.ctx.Done():
return d.ctx.Err()
}
return nil
})
close(errCh)
close(fileCh)
}()
return &ufsIterator{
ctx: d.ctx,
files: fileCh,
errCh: errCh,
dserv: d.dserv,
}
}
func (d *ufsDirectory) Size() (int64, error) {
n, err := d.dir.GetNode()
if err != nil {
return 0, err
}
s, err := n.Size()
return int64(s), err
}
type ufsFile struct {
uio.DagReader
}
func (f *ufsFile) Size() (int64, error) {
return int64(f.DagReader.Size()), nil
}
func newUnixfsDir(ctx context.Context, dserv ipld.DAGService, nd ipld.Node) (files.Directory, error) {
dir, err := uio.NewDirectoryFromNode(dserv, nd)
if err != nil {
return nil, err
}
return &ufsDirectory{
ctx: ctx,
dserv: dserv,
dir: dir,
}, nil
}
func newUnixfsFile(ctx context.Context, dserv ipld.DAGService, nd ipld.Node) (files.Node, error) {
switch dn := nd.(type) {
case *dag.ProtoNode:
fsn, err := ft.FSNodeFromBytes(dn.Data())
if err != nil {
return nil, err
}
if fsn.IsDir() {
return newUnixfsDir(ctx, dserv, nd)
}
if fsn.Type() == ft.TSymlink {
return files.NewLinkFile(string(fsn.Data()), nil), nil
}
case *dag.RawNode:
default:
return nil, errors.New("unknown node type")
}
dr, err := uio.NewDagReader(ctx, nd, dserv)
if err != nil {
return nil, err
}
return &ufsFile{
DagReader: dr,
}, nil
}
var _ files.Directory = &ufsDirectory{}
var _ files.File = &ufsFile{}
......@@ -15,6 +15,7 @@ import (
mfs "gx/ipfs/QmRg4joNWApLL7yuvLjmKwZaqZX2d7AY7TU35kPmviRoMY/go-mfs"
bstore "gx/ipfs/QmS2aqUZLJp8kF1ihE5rvDGE5LvmKDPnx32w9Z1BW9xLV5/go-ipfs-blockstore"
ft "gx/ipfs/QmSMJ4rZbCJaih3y82Ebq7BZqK6vU2FHsKcWKQiE1DPTpS/go-unixfs"
unixfile "gx/ipfs/QmSMJ4rZbCJaih3y82Ebq7BZqK6vU2FHsKcWKQiE1DPTpS/go-unixfs/file"
uio "gx/ipfs/QmSMJ4rZbCJaih3y82Ebq7BZqK6vU2FHsKcWKQiE1DPTpS/go-unixfs/io"
blockservice "gx/ipfs/QmVKQHuzni68SWByzJgBUCwHvvr4TWiXfutNWWwpZpp4rE/go-blockservice"
files "gx/ipfs/QmXWZCd8jfaHmt4UDSnjKmGcrQMw95bDGWqEeVLVJjoANX/go-ipfs-files"
......@@ -137,7 +138,7 @@ func (api *UnixfsAPI) Get(ctx context.Context, p coreiface.Path) (files.Node, er
return nil, err
}
return newUnixfsFile(ctx, ses.dag, nd)
return unixfile.NewUnixfsFile(ctx, ses.dag, nd)
}
// Ls returns the contents of an IPFS or IPNS object(s) at path p, with the format:
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论