11
ftpb "github.com/ipfs/go-ipfs/unixfs/pb"
12
13
ipld "gx/ipfs/QmWi2BYBL5gJ3CiAiQchg6rn1A8iBsrWy51EYxvHVjFvLb/go-ipld-format"
14
- proto "gx/ipfs/QmZ4Qi3GaRbjcx28Sme5eMH7RQjGkt8wHxt2a65oLaeFEV/gogo-protobuf/proto"
14
cid "gx/ipfs/QmapdYm1b22Frv3k17fqrBYTFRxwiaVJkB299Mfn33edeB/go-cid"
15
)
16
18
type PBDagReader struct {
19
serv ipld.NodeGetter
20
22
- // the node being read
23
- node *mdag.ProtoNode
24
-
25
- // cached protobuf structure from node.Data
26
- pbdata *ftpb.Data
21
+ // UnixFS file (it should be of type `Data_File` or `Data_Raw` only).
22
+ file *ft.FSNode
23
24
// the current data buffer to be read from
25
// will either be a bytes.Reader or a child DagReader
47
var _ DagReader = (*PBDagReader)(nil)
48
49
// NewPBFileReader constructs a new PBFileReader.
54
-func NewPBFileReader(ctx context.Context, n *mdag.ProtoNode, pb *ftpb.Data, serv ipld.NodeGetter) *PBDagReader {
50
+func NewPBFileReader(ctx context.Context, n *mdag.ProtoNode, file *ft.FSNode, serv ipld.NodeGetter) *PBDagReader {
51
fctx, cancel := context.WithCancel(ctx)
52
curLinks := getLinkCids(n)
53
return &PBDagReader{
58
- node: n,
54
serv: serv,
60
- buf: NewBufDagReader(pb.GetData()),
55
+ buf: NewBufDagReader(file.GetData()),
56
promises: make([]*ipld.NodePromise, len(curLinks)),
57
links: curLinks,
58
ctx: fctx,
59
cancel: cancel,
65
- pbdata: pb,
60
+ file: file,
61
}
62
}
63
100
101
switch nxt := nxt.(type) {
102
case *mdag.ProtoNode:
108
- pb := new(ftpb.Data)
109
- err = proto.Unmarshal(nxt.Data(), pb)
103
+ fsNode, err := ft.FSNodeFromBytes(nxt.Data())
104
if err != nil {
105
return fmt.Errorf("incorrectly formatted protobuf: %s", err)
106
}
107
114
- switch pb.GetType() {
108
+ switch fsNode.GetType() {
109
case ftpb.Data_Directory, ftpb.Data_HAMTShard:
110
// A directory should not exist within a file
111
return ft.ErrInvalidDirLocation
112
case ftpb.Data_File:
119
- dr.buf = NewPBFileReader(dr.ctx, nxt, pb, dr.serv)
113
+ dr.buf = NewPBFileReader(dr.ctx, nxt, fsNode, dr.serv)
114
return nil
115
case ftpb.Data_Raw:
122
- dr.buf = NewBufDagReader(pb.GetData())
116
+ dr.buf = NewBufDagReader(fsNode.GetData())
117
return nil
118
case ftpb.Data_Metadata:
119
return errors.New("shouldnt have had metadata object inside file")
140
141
// Size return the total length of the data from the DAG structured file.
142
func (dr *PBDagReader) Size() uint64 {
149
- return dr.pbdata.GetFilesize()
143
+ return dr.file.FileSize()
144
}
145
146
// Read reads data from the DAG structured file
238
return offset, nil
239
}
240
247
- // Grab cached protobuf object (solely to make code look cleaner)
248
- pb := dr.pbdata
249
-
241
// left represents the number of bytes remaining to seek to (from beginning)
242
left := offset
252
- if int64(len(pb.Data)) >= offset {
243
+ if int64(len(dr.file.GetData())) >= offset {
244
// Close current buf to close potential child dagreader
245
if dr.buf != nil {
246
dr.buf.Close()
247
}
257
- dr.buf = NewBufDagReader(pb.GetData()[offset:])
248
+ dr.buf = NewBufDagReader(dr.file.GetData()[offset:])
249
250
// start reading links from the beginning
251
dr.linkPosition = 0
254
}
255
256
// skip past root block data
266
- left -= int64(len(pb.Data))
257
+ left -= int64(len(dr.file.GetData()))
258
259
// iterate through links and find where we need to be
269
- for i := 0; i < len(pb.Blocksizes); i++ {
270
- if pb.Blocksizes[i] > uint64(left) {
260
+ for i := 0; i < dr.file.NumChildren(); i++ {
261
+ if dr.file.BlockSize(i) > uint64(left) {
262
dr.linkPosition = i
263
break
264
} else {
274
- left -= int64(pb.Blocksizes[i])
265
+ left -= int64(dr.file.BlockSize(i))
266
}
267
}
268
294
noffset := dr.offset + offset
295
return dr.Seek(noffset, io.SeekStart)
296
case io.SeekEnd:
306
- noffset := int64(dr.pbdata.GetFilesize()) - offset
297
+ noffset := int64(dr.file.FileSize()) - offset
298
n, err := dr.Seek(noffset, io.SeekStart)
299
300
// Return negative number if we can't figure out the file size. Using io.EOF
301
// for this seems to be good(-enough) solution as it's only returned by
302
// precalcNextBuf when we step out of file range.
303
// This is needed for gateway to function properly
313
- if err == io.EOF && *dr.pbdata.Type == ftpb.Data_File {
304
+ if err == io.EOF && dr.file.GetType() == ftpb.Data_File {
305
return -1, nil
306
}
307
return n, err