ParseSumFile parses a hash SUM file and returns hashes as a map
(ctx context.Context, sumFile fs.Object)
| 570 | |
| 571 | // ParseSumFile parses a hash SUM file and returns hashes as a map |
| 572 | func ParseSumFile(ctx context.Context, sumFile fs.Object) (HashSums, error) { |
| 573 | rd, err := Open(ctx, sumFile) |
| 574 | if err != nil { |
| 575 | return nil, err |
| 576 | } |
| 577 | parser := bufio.NewReader(rd) |
| 578 | |
| 579 | const maxWarn = 3 |
| 580 | numWarn := 0 |
| 581 | |
| 582 | re := regexp.MustCompile(`^([^ ]+) [ *](.+)$`) |
| 583 | hashes := HashSums{} |
| 584 | for lineNo := 0; true; lineNo++ { |
| 585 | lineBytes, _, err := parser.ReadLine() |
| 586 | if err == io.EOF { |
| 587 | break |
| 588 | } |
| 589 | if err != nil { |
| 590 | return nil, err |
| 591 | } |
| 592 | line := string(lineBytes) |
| 593 | if line == "" { |
| 594 | continue |
| 595 | } |
| 596 | |
| 597 | fields := re.FindStringSubmatch(ApplyTransforms(ctx, line)) |
| 598 | if fields == nil { |
| 599 | numWarn++ |
| 600 | if numWarn <= maxWarn { |
| 601 | fs.Logf(sumFile, "improperly formatted checksum line %d", lineNo) |
| 602 | } |
| 603 | continue |
| 604 | } |
| 605 | |
| 606 | sum, file := fields[1], fields[2] |
| 607 | if hashes[file] != "" { |
| 608 | numWarn++ |
| 609 | if numWarn <= maxWarn { |
| 610 | fs.Logf(sumFile, "duplicate file on checksum line %d", lineNo) |
| 611 | } |
| 612 | continue |
| 613 | } |
| 614 | |
| 615 | // We've standardised on lower case checksums in rclone internals. |
| 616 | hashes[file] = strings.ToLower(sum) |
| 617 | } |
| 618 | |
| 619 | if numWarn > maxWarn { |
| 620 | fs.Logf(sumFile, "%d warning(s) suppressed...", numWarn-maxWarn) |
| 621 | } |
| 622 | if err = rd.Close(); err != nil { |
| 623 | return nil, err |
| 624 | } |
| 625 | return hashes, nil |
| 626 | } |
searching dependent graphs…