implement an ipfs cat --length flag
fixes #4085 License: MIT Signed-off-by: Steven Allen <steven@stebalien.com>
Steven Allen committed
Jan 5, 2018 at 18:20 UTC
153bb681300cc98e4646179d8d7ac9b1c34197cc
1 file changed
+30
-3
core/commands/cat.go
+30
-3
@@ -26,6 +26,7 @@ var CatCmd = &cmds.Command{
26
},
27
Options: []cmdkit.Option{
28
cmdkit.IntOption("offset", "o", "Byte offset to begin reading from."),
29
+ cmdkit.IntOption("length", "l", "Maximum number of bytes to read."),
30
},
31
Run: func(req cmds.Request, res cmds.ResponseEmitter) {
32
node, err := req.InvocContext().GetNode()
@@ -50,7 +51,20 @@ var CatCmd = &cmds.Command{
51
return
52
}
53
53
- readers, length, err := cat(req.Context(), node, req.Arguments(), int64(offset))
54
+ max, found, err := req.Option("length").Int()
55
+ if err != nil {
56
+ res.SetError(err, cmdkit.ErrNormal)
57
+ return
58
+ }
59
+ if max < 0 {
60
+ res.SetError(fmt.Errorf("Cannot specify negative length."), cmdkit.ErrNormal)
61
+ return
62
+ }
63
+ if !found {
64
+ max = -1
65
+ }
66
+
67
+ readers, length, err := cat(req.Context(), node, req.Arguments(), int64(offset), int64(max))
68
if err != nil {
69
res.SetError(err, cmdkit.ErrNormal)
70
return
@@ -116,9 +130,12 @@ var CatCmd = &cmds.Command{
130
},
131
}
132
119
-func cat(ctx context.Context, node *core.IpfsNode, paths []string, offset int64) ([]io.Reader, uint64, error) {
133
+func cat(ctx context.Context, node *core.IpfsNode, paths []string, offset int64, max int64) ([]io.Reader, uint64, error) {
134
readers := make([]io.Reader, 0, len(paths))
135
length := uint64(0)
136
+ if max == 0 {
137
+ return nil, 0, nil
138
+ }
139
for _, fpath := range paths {
140
read, err := coreunix.Cat(ctx, node, fpath)
141
if err != nil {
@@ -134,8 +151,18 @@ func cat(ctx context.Context, node *core.IpfsNode, paths []string, offset int64)
151
}
152
offset = 0
153
154
+ size := uint64(read.Size() - uint64(count))
155
+ length += size
156
+ if max > 0 && length >= uint64(max) {
157
+ var r io.Reader = read
158
+ if overshoot := int64(length - uint64(max)); overshoot != 0 {
159
+ r = io.LimitReader(read, int64(size)-overshoot)
160
+ length = uint64(max)
161
+ }
162
+ readers = append(readers, r)
163
+ break
164
+ }
165
readers = append(readers, read)
138
- length += uint64(read.Size() - uint64(count))
166
}
167
return readers, length, nil
168
}