Cat any files to the io.Writer if offset == 0 it will be ignored if offset > 0 then the file will be seeked to that offset if offset < 0 then the file will be seeked that far from the end if count < 0 then it will be ignored if count >= 0 then only that many characters will be output
(ctx context.Context, f fs.Fs, w io.Writer, offset, count int64, sep []byte)
| 1296 | // if count < 0 then it will be ignored |
| 1297 | // if count >= 0 then only that many characters will be output |
| 1298 | func Cat(ctx context.Context, f fs.Fs, w io.Writer, offset, count int64, sep []byte) error { |
| 1299 | var mu sync.Mutex |
| 1300 | ci := fs.GetConfig(ctx) |
| 1301 | return ListFn(ctx, f, func(o fs.Object) { |
| 1302 | var err error |
| 1303 | tr := accounting.Stats(ctx).NewTransfer(o, nil) |
| 1304 | defer func() { |
| 1305 | tr.Done(ctx, err) |
| 1306 | }() |
| 1307 | opt := fs.RangeOption{Start: offset, End: -1} |
| 1308 | size := o.Size() |
| 1309 | if opt.Start < 0 { |
| 1310 | opt.Start += size |
| 1311 | } |
| 1312 | if count >= 0 { |
| 1313 | opt.End = opt.Start + count - 1 |
| 1314 | } |
| 1315 | var options []fs.OpenOption |
| 1316 | if opt.Start > 0 || opt.End >= 0 { |
| 1317 | options = append(options, &opt) |
| 1318 | } |
| 1319 | for _, option := range ci.DownloadHeaders { |
| 1320 | options = append(options, option) |
| 1321 | } |
| 1322 | var in io.ReadCloser |
| 1323 | in, err = Open(ctx, o, options...) |
| 1324 | if err != nil { |
| 1325 | err = fs.CountError(ctx, err) |
| 1326 | fs.Errorf(o, "Failed to open: %v", err) |
| 1327 | return |
| 1328 | } |
| 1329 | if count >= 0 { |
| 1330 | in = &readCloser{Reader: &io.LimitedReader{R: in, N: count}, Closer: in} |
| 1331 | } |
| 1332 | in = tr.Account(ctx, in).WithBuffer() // account and buffer the transfer |
| 1333 | // take the lock just before we output stuff, so at the last possible moment |
| 1334 | mu.Lock() |
| 1335 | defer mu.Unlock() |
| 1336 | _, err = io.Copy(w, in) |
| 1337 | if err != nil { |
| 1338 | err = fs.CountError(ctx, err) |
| 1339 | fs.Errorf(o, "Failed to send to output: %v", err) |
| 1340 | } |
| 1341 | if len(sep) > 0 { |
| 1342 | _, err = w.Write(sep) |
| 1343 | if err != nil { |
| 1344 | err = fs.CountError(ctx, err) |
| 1345 | fs.Errorf(o, "Failed to send separator to output: %v", err) |
| 1346 | } |
| 1347 | } |
| 1348 | }) |
| 1349 | } |
| 1350 | |
| 1351 | // Rcat reads data from the Reader until EOF and uploads it to a file on remote |
| 1352 | // |