@cryptotaxi247 / kubo / commits / 153bb6813

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 }