-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
coreapi: get going, add Cat() and Ls()
License: MIT Signed-off-by: Lars Gierth <larsg@systemli.org>
- Loading branch information
Lars Gierth
committed
Sep 11, 2016
1 parent
0e2b4eb
commit 88187f4
Showing
3 changed files
with
232 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package coreapi | ||
|
||
import ( | ||
"context" | ||
|
||
core "github.com/ipfs/go-ipfs/core" | ||
coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" | ||
dag "github.com/ipfs/go-ipfs/merkledag" | ||
path "github.com/ipfs/go-ipfs/path" | ||
uio "github.com/ipfs/go-ipfs/unixfs/io" | ||
cid "gx/ipfs/QmfSc2xehWmWLnwwYR91Y8QF4xdASypTFVknutoKQS3GHp/go-cid" | ||
) | ||
|
||
type UnixfsAPI struct { | ||
Context context.Context | ||
Node *core.IpfsNode | ||
} | ||
|
||
func (api *UnixfsAPI) resolve(p string) (*dag.Node, error) { | ||
pp, err := path.ParsePath(p) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
dagnode, err := core.Resolve(api.Context, api.Node, pp) | ||
if err == core.ErrNoNamesys { | ||
return nil, coreiface.ErrOffline | ||
} else if err != nil { | ||
return nil, err | ||
} | ||
return dagnode, nil | ||
} | ||
|
||
func (api *UnixfsAPI) Cat(p string) (coreiface.Reader, error) { | ||
dagnode, err := api.resolve(p) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
r, err := uio.NewDagReader(api.Context, dagnode, api.Node.DAG) | ||
if err == uio.ErrIsDir { | ||
return nil, coreiface.ErrIsDir | ||
} else if err != nil { | ||
return nil, err | ||
} | ||
return r, nil | ||
} | ||
|
||
func (api *UnixfsAPI) Ls(p string) ([]*coreiface.Link, error) { | ||
dagnode, err := api.resolve(p) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
links := make([]*coreiface.Link, len(dagnode.Links)) | ||
for i, l := range dagnode.Links { | ||
links[i] = &coreiface.Link{l.Name, l.Size, cid.NewCidV0(l.Hash)} | ||
} | ||
return links, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
package coreapi_test | ||
|
||
import ( | ||
"bytes" | ||
"context" | ||
"io" | ||
"strings" | ||
"testing" | ||
|
||
core "github.com/ipfs/go-ipfs/core" | ||
coreapi "github.com/ipfs/go-ipfs/core/coreapi" | ||
// coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" | ||
coreunix "github.com/ipfs/go-ipfs/core/coreunix" | ||
repo "github.com/ipfs/go-ipfs/repo" | ||
config "github.com/ipfs/go-ipfs/repo/config" | ||
testutil "github.com/ipfs/go-ipfs/thirdparty/testutil" | ||
) | ||
|
||
// `ipfs object new unixfs-dir` | ||
var emptyUnixfsDir = "QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn" | ||
|
||
// `echo -n | ipfs add` | ||
var emptyUnixfsFile = "QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwQH" | ||
|
||
func makeAPI(ctx context.Context) (*core.IpfsNode, *coreapi.UnixfsAPI, error) { | ||
r := &repo.Mock{ | ||
C: config.Config{ | ||
Identity: config.Identity{ | ||
PeerID: "Qmfoo", // required by offline node | ||
}, | ||
}, | ||
D: testutil.ThreadSafeCloserMapDatastore(), | ||
} | ||
node, err := core.NewNode(ctx, &core.BuildCfg{Repo: r}) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
api := &coreapi.UnixfsAPI{Node: node, Context: ctx} | ||
return node, api, nil | ||
} | ||
|
||
func TestCatBasic(t *testing.T) { | ||
node, api, err := makeAPI(context.Background()) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
hello := "hello, world!" | ||
hr := strings.NewReader(hello) | ||
k, err := coreunix.Add(node, hr) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
r, err := api.Cat(k) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
buf := make([]byte, len(hello)) | ||
n, err := io.ReadFull(r, buf) | ||
if err != nil && err != io.EOF { | ||
t.Error(err) | ||
} | ||
if string(buf) != hello { | ||
t.Fatalf("expected [hello, world!], got [%s] [err=%s]", string(buf), n, err) | ||
} | ||
} | ||
|
||
func TestCatEmptyFile(t *testing.T) { | ||
node, api, err := makeAPI(context.Background()) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
_, err = coreunix.Add(node, strings.NewReader("")) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
r, err := api.Cat(emptyUnixfsFile) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
buf := make([]byte, 1) // non-zero so that Read() actually tries to read | ||
n, err := io.ReadFull(r, buf) | ||
if err != nil && err != io.EOF { | ||
t.Error(err) | ||
} | ||
if !bytes.HasPrefix(buf, []byte{0x00}) { | ||
t.Fatalf("expected empty data, got [%s] [read=%d]", buf, n) | ||
} | ||
} | ||
|
||
func TestCatDir(t *testing.T) { | ||
t.Skip("TODO: implement me") | ||
} | ||
|
||
func TestCatNonUnixfs(t *testing.T) { | ||
t.Skip("TODO: implement me") | ||
} | ||
|
||
func TestCatOffline(t *testing.T) { | ||
t.Skip("TODO: implement me") | ||
} | ||
|
||
func TestLs(t *testing.T) { | ||
t.Skip("TODO: implement me") | ||
} | ||
|
||
func TestLsEmpty(t *testing.T) { | ||
t.Skip("TODO: implement me") | ||
} | ||
|
||
func TestLsNonUnixfs(t *testing.T) { | ||
t.Skip("TODO: implement me") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package iface | ||
|
||
import ( | ||
"errors" | ||
"io" | ||
|
||
cid "gx/ipfs/QmfSc2xehWmWLnwwYR91Y8QF4xdASypTFVknutoKQS3GHp/go-cid" | ||
) | ||
|
||
// type CoreAPI interface { | ||
// ID() CoreID | ||
// Version() CoreVersion | ||
// } | ||
|
||
type Link struct { | ||
Name string | ||
Size uint64 | ||
Cid *cid.Cid | ||
} | ||
|
||
type Reader interface { | ||
io.ReadSeeker | ||
io.Closer | ||
} | ||
|
||
type UnixfsAPI interface { | ||
Cat(string) (Reader, error) | ||
Ls(string) ([]*Link, error) | ||
} | ||
|
||
// type ObjectAPI interface { | ||
// New() (cid.Cid, Object) | ||
// Get(string) (Object, error) | ||
// Links(string) ([]*Link, error) | ||
// Data(string) (Reader, error) | ||
// Stat(string) (ObjectStat, error) | ||
// Put(Object) (cid.Cid, error) | ||
// SetData(string, Reader) (cid.Cid, error) | ||
// AppendData(string, Data) (cid.Cid, error) | ||
// AddLink(string, string, string) (cid.Cid, error) | ||
// RmLink(string, string) (cid.Cid, error) | ||
// } | ||
|
||
// type ObjectStat struct { | ||
// Cid cid.Cid | ||
// NumLinks int | ||
// BlockSize int | ||
// LinksSize int | ||
// DataSize int | ||
// CumulativeSize int | ||
// } | ||
|
||
var ErrIsDir = errors.New("object is a directory") | ||
var ErrOffline = errors.New("can't resolve, ipfs node is offline") |