-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathblock_slicer.go
70 lines (48 loc) · 1.32 KB
/
block_slicer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package crabfs
import (
"io"
"crypto/cipher"
blocks "github.com/ipfs/go-block-format"
"github.com/runletapp/crabfs/interfaces"
pb "github.com/runletapp/crabfs/protos"
)
var _ interfaces.Slicer = &BlockSlicer{}
// BlockSlicer a simple block slicer
type BlockSlicer struct {
reader io.Reader
blockSize int64
offset int64
cipher cipher.Block
}
// BlockSlicerNew creates a new BlockSlicer with 'blockSize'
func BlockSlicerNew(reader io.Reader, blockSize int64, cipher cipher.Block) (interfaces.Slicer, error) {
slicer := &BlockSlicer{
reader: reader,
blockSize: blockSize,
offset: 0,
cipher: cipher,
}
return slicer, nil
}
func (slicer *BlockSlicer) Next() (*pb.BlockMetadata, blocks.Block, int64, error) {
data := make([]byte, slicer.blockSize)
n, err := slicer.reader.Read(data)
if err != nil {
return nil, nil, 0, err
}
dataBlock := append([]byte{}, data[:n]...)
paddingStart := int64(n)
for i := 0; i < slicer.cipher.BlockSize()-n; i++ {
dataBlock = append(dataBlock, 0)
}
slicer.cipher.Encrypt(dataBlock, dataBlock)
block := blocks.NewBlock(dataBlock)
metadata := &pb.BlockMetadata{
Start: slicer.offset,
Size: int64(len(dataBlock)),
Cid: block.Cid().Bytes(),
PaddingStart: paddingStart,
}
slicer.offset += int64(n)
return metadata, block, int64(n), nil
}