Commit 6dbe3963 authored by Jeromy's avatar Jeromy

it might work, idk yet

parents
go-car (go!)
==================
[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io)
[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/)
[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs)
[![Coverage Status](https://codecov.io/gh/ipfs/go-car/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-car/branch/master)
[![Travis CI](https://travis-ci.org/ipfs/go-car.svg?branch=master)](https://travis-ci.org/ipfs/go-car)
> go-car is a simple way of packing a merkledag into a single file
## Table of Contents
- [Install](#install)
- [Contribute](#contribute)
- [License](#license)
## Contribute
PRs are welcome!
Small note: If editing the Readme, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification.
## License
MIT © Whyrusleeping
package car
import (
"archive/tar"
"context"
"fmt"
"io"
"io/ioutil"
"github.com/ipfs/go-block-format"
cid "github.com/ipfs/go-cid"
bstore "github.com/ipfs/go-ipfs-blockstore"
format "github.com/ipfs/go-ipld-format"
dag "github.com/ipfs/go-merkledag"
)
func WriteCar(ctx context.Context, ds format.DAGService, root *cid.Cid, w io.Writer) error {
tw := tar.NewWriter(w)
rh := &tar.Header{
Typeflag: tar.TypeSymlink,
Name: "root",
Linkname: root.String(),
}
if err := tw.WriteHeader(rh); err != nil {
return err
}
cw := &carWriter{ds: ds, tw: tw}
seen := cid.NewSet()
if err := dag.EnumerateChildren(ctx, cw.enumGetLinks, root, seen.Visit); err != nil {
return err
}
return tw.Flush()
}
func LoadCar(ctx context.Context, bs bstore.Blockstore, r io.Reader) (*cid.Cid, error) {
tr := tar.NewReader(r)
root, err := tr.Next()
if err != nil {
return nil, err
}
if root.Name != "root" || root.Typeflag != tar.TypeSymlink {
return nil, fmt.Errorf("expected first entry in CAR to by symlink named 'root'")
}
rootcid, err := cid.Decode(root.Linkname)
if err != nil {
return nil, err
}
for {
obj, err := tr.Next()
if err != nil {
if err == io.EOF {
break
}
return nil, err
}
c, err := cid.Decode(obj.Name)
if err != nil {
return nil, err
}
// safety 1st
limr := io.LimitReader(tr, 2<<20)
data, err := ioutil.ReadAll(limr)
if err != nil {
return nil, err
}
hashed, err := c.Prefix().Sum(data)
if err != nil {
return nil, err
}
if !hashed.Equals(c) {
return nil, fmt.Errorf("mismatch in content integrity, name: %s, data: %s", c, hashed)
}
blk, err := blocks.NewBlockWithCid(data, c)
if err != nil {
return nil, err
}
if err := bs.Put(blk); err != nil {
return nil, err
}
}
return rootcid, nil
}
type carWriter struct {
ds format.DAGService
tw *tar.Writer
}
func (cw *carWriter) enumGetLinks(ctx context.Context, c *cid.Cid) ([]*format.Link, error) {
nd, err := cw.ds.Get(ctx, c)
if err != nil {
return nil, err
}
if err := cw.writeNode(ctx, nd); err != nil {
return nil, err
}
return nd.Links(), nil
}
func (cw *carWriter) writeNode(ctx context.Context, nd format.Node) error {
hdr := &tar.Header{
Name: nd.Cid().String(),
Typeflag: tar.TypeReg,
}
if err := cw.tw.WriteHeader(hdr); err != nil {
return err
}
if _, err := cw.tw.Write(nd.RawData()); err != nil {
return err
}
return nil
}
{
"author": "why",
"bugs": {
"url": "https://github.com/ipfs/go-car"
},
"gx": {
"dvcsimport": "github.com/ipfs/go-car"
},
"gxDependencies": [
{
"author": "why",
"hash": "Qma2BR57Wqp8w9vPreK4dEzoXXk8DFFRL3LresMZg4QpzN",
"name": "go-merkledag",
"version": "1.0.2"
}
],
"gxVersion": "0.12.1",
"language": "go",
"license": "",
"name": "go-car",
"releaseCmd": "git commit -a -m \"gx publish $VERSION\"",
"version": "0.0.0"
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment