Commit 24257b36 authored by Jeromy's avatar Jeromy

implement a basic data format for data inside dag nodes

parent 939ac997
all: node.pb.go
all: node.pb.go data.pb.go
node.pb.go: node.proto
protoc --gogo_out=. --proto_path=../../../../:/usr/local/opt/protobuf/include:. $<
data.pb.go: data.proto
protoc --go_out=. data.proto
clean:
rm node.pb.go
package merkledag
import (
"bytes"
"errors"
"io"
"code.google.com/p/goprotobuf/proto"
)
var ErrIsDir = errors.New("this dag node is a directory.")
// DagReader provides a way to easily read the data contained in a dag.
type DagReader struct {
node *Node
position int
buf *bytes.Buffer
thisData []byte
}
func NewDagReader(n *Node) (io.Reader, error) {
pb := new(PBData)
err := proto.Unmarshal(n.Data, pb)
if err != nil {
return nil, err
}
switch pb.GetType() {
case PBData_Directory:
return nil, ErrIsDir
case PBData_File:
return &DagReader{
node: n,
thisData: pb.GetData(),
}, nil
case PBData_Raw:
return bytes.NewBuffer(pb.GetData()), nil
default:
panic("Unrecognized node type!")
}
}
func (dr *DagReader) precalcNextBuf() error {
if dr.position >= len(dr.node.Links) {
return io.EOF
}
nxtLink := dr.node.Links[dr.position]
nxt := nxtLink.Node
if nxt == nil {
//TODO: should use dagservice or something to get needed block
return errors.New("Link to nil node! Tree not fully expanded!")
}
pb := new(PBData)
err := proto.Unmarshal(nxt.Data, pb)
if err != nil {
return err
}
dr.position++
// TODO: dont assume a single layer of indirection
switch pb.GetType() {
case PBData_Directory:
panic("Why is there a directory under a file?")
case PBData_File:
//TODO: maybe have a PBData_Block type for indirect blocks?
panic("Not yet handling different layers of indirection!")
case PBData_Raw:
dr.buf = bytes.NewBuffer(pb.GetData())
return nil
default:
panic("Unrecognized node type!")
}
}
func (dr *DagReader) Read(b []byte) (int, error) {
if dr.buf == nil {
err := dr.precalcNextBuf()
if err != nil {
return 0, err
}
}
total := 0
for {
n, err := dr.buf.Read(b[total:])
total += n
if err != nil {
if err != io.EOF {
return total, err
}
}
if total == len(b) {
return total, nil
}
err = dr.precalcNextBuf()
if err != nil {
return total, err
}
}
}
// Code generated by protoc-gen-go.
// source: data.proto
// DO NOT EDIT!
/*
Package merkledag is a generated protocol buffer package.
It is generated from these files:
data.proto
It has these top-level messages:
PBData
*/
package merkledag
import proto "code.google.com/p/goprotobuf/proto"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = math.Inf
type PBData_DataType int32
const (
PBData_Raw PBData_DataType = 0
PBData_Directory PBData_DataType = 1
PBData_File PBData_DataType = 2
)
var PBData_DataType_name = map[int32]string{
0: "Raw",
1: "Directory",
2: "File",
}
var PBData_DataType_value = map[string]int32{
"Raw": 0,
"Directory": 1,
"File": 2,
}
func (x PBData_DataType) Enum() *PBData_DataType {
p := new(PBData_DataType)
*p = x
return p
}
func (x PBData_DataType) String() string {
return proto.EnumName(PBData_DataType_name, int32(x))
}
func (x *PBData_DataType) UnmarshalJSON(data []byte) error {
value, err := proto.UnmarshalJSONEnum(PBData_DataType_value, data, "PBData_DataType")
if err != nil {
return err
}
*x = PBData_DataType(value)
return nil
}
type PBData struct {
Type *PBData_DataType `protobuf:"varint,1,req,enum=merkledag.PBData_DataType" json:"Type,omitempty"`
Data []byte `protobuf:"bytes,2,opt" json:"Data,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *PBData) Reset() { *m = PBData{} }
func (m *PBData) String() string { return proto.CompactTextString(m) }
func (*PBData) ProtoMessage() {}
func (m *PBData) GetType() PBData_DataType {
if m != nil && m.Type != nil {
return *m.Type
}
return PBData_Raw
}
func (m *PBData) GetData() []byte {
if m != nil {
return m.Data
}
return nil
}
func init() {
proto.RegisterEnum("merkledag.PBData_DataType", PBData_DataType_name, PBData_DataType_value)
}
package merkledag;
message PBData {
enum DataType {
Raw = 0;
Directory = 1;
File = 2;
}
required DataType Type = 1;
optional bytes Data = 2;
}
......@@ -3,6 +3,8 @@ package merkledag
import (
"fmt"
"code.google.com/p/goprotobuf/proto"
blocks "github.com/jbenet/go-ipfs/blocks"
bserv "github.com/jbenet/go-ipfs/blockservice"
u "github.com/jbenet/go-ipfs/util"
......@@ -152,3 +154,44 @@ func (n *DAGService) Get(k u.Key) (*Node, error) {
return Decoded(b.Data)
}
func FilePBData() []byte {
pbfile := new(PBData)
typ := PBData_File
pbfile.Type = &typ
data, err := proto.Marshal(pbfile)
if err != nil {
//this really shouldnt happen, i promise
panic(err)
}
return data
}
func FolderPBData() []byte {
pbfile := new(PBData)
typ := PBData_Directory
pbfile.Type = &typ
data, err := proto.Marshal(pbfile)
if err != nil {
//this really shouldnt happen, i promise
panic(err)
}
return data
}
func WrapData(b []byte) []byte {
pbdata := new(PBData)
typ := PBData_Raw
pbdata.Data = b
pbdata.Type = &typ
out, err := proto.Marshal(pbdata)
if err != nil {
// This shouldnt happen. seriously.
panic(err)
}
return out
}
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