File: fileinfosums.go

package info (click to toggle)
docker.io 20.10.24%2Bdfsg1-1%2Bdeb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 60,824 kB
  • sloc: sh: 5,621; makefile: 593; ansic: 179; python: 162; asm: 7
file content (133 lines) | stat: -rw-r--r-- 3,602 bytes parent folder | download | duplicates (6)
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package tarsum // import "github.com/docker/docker/pkg/tarsum"

import (
	"runtime"
	"sort"
	"strings"
)

// FileInfoSumInterface provides an interface for accessing file checksum
// information within a tar file. This info is accessed through interface
// so the actual name and sum cannot be melded with.
type FileInfoSumInterface interface {
	// File name
	Name() string
	// Checksum of this particular file and its headers
	Sum() string
	// Position of file in the tar
	Pos() int64
}

type fileInfoSum struct {
	name string
	sum  string
	pos  int64
}

func (fis fileInfoSum) Name() string {
	return fis.name
}
func (fis fileInfoSum) Sum() string {
	return fis.sum
}
func (fis fileInfoSum) Pos() int64 {
	return fis.pos
}

// FileInfoSums provides a list of FileInfoSumInterfaces.
type FileInfoSums []FileInfoSumInterface

// GetFile returns the first FileInfoSumInterface with a matching name.
func (fis FileInfoSums) GetFile(name string) FileInfoSumInterface {
	// We do case insensitive matching on Windows as c:\APP and c:\app are
	// the same. See issue #33107.
	for i := range fis {
		if (runtime.GOOS == "windows" && strings.EqualFold(fis[i].Name(), name)) ||
			(runtime.GOOS != "windows" && fis[i].Name() == name) {
			return fis[i]
		}
	}
	return nil
}

// GetAllFile returns a FileInfoSums with all matching names.
func (fis FileInfoSums) GetAllFile(name string) FileInfoSums {
	f := FileInfoSums{}
	for i := range fis {
		if fis[i].Name() == name {
			f = append(f, fis[i])
		}
	}
	return f
}

// GetDuplicatePaths returns a FileInfoSums with all duplicated paths.
func (fis FileInfoSums) GetDuplicatePaths() (dups FileInfoSums) {
	seen := make(map[string]int, len(fis)) // allocate earl. no need to grow this map.
	for i := range fis {
		f := fis[i]
		if _, ok := seen[f.Name()]; ok {
			dups = append(dups, f)
		} else {
			seen[f.Name()] = 0
		}
	}
	return dups
}

// Len returns the size of the FileInfoSums.
func (fis FileInfoSums) Len() int { return len(fis) }

// Swap swaps two FileInfoSum values if a FileInfoSums list.
func (fis FileInfoSums) Swap(i, j int) { fis[i], fis[j] = fis[j], fis[i] }

// SortByPos sorts FileInfoSums content by position.
func (fis FileInfoSums) SortByPos() {
	sort.Sort(byPos{fis})
}

// SortByNames sorts FileInfoSums content by name.
func (fis FileInfoSums) SortByNames() {
	sort.Sort(byName{fis})
}

// SortBySums sorts FileInfoSums content by sums.
func (fis FileInfoSums) SortBySums() {
	dups := fis.GetDuplicatePaths()
	if len(dups) > 0 {
		sort.Sort(bySum{fis, dups})
	} else {
		sort.Sort(bySum{fis, nil})
	}
}

// byName is a sort.Sort helper for sorting by file names.
// If names are the same, order them by their appearance in the tar archive
type byName struct{ FileInfoSums }

func (bn byName) Less(i, j int) bool {
	if bn.FileInfoSums[i].Name() == bn.FileInfoSums[j].Name() {
		return bn.FileInfoSums[i].Pos() < bn.FileInfoSums[j].Pos()
	}
	return bn.FileInfoSums[i].Name() < bn.FileInfoSums[j].Name()
}

// bySum is a sort.Sort helper for sorting by the sums of all the fileinfos in the tar archive
type bySum struct {
	FileInfoSums
	dups FileInfoSums
}

func (bs bySum) Less(i, j int) bool {
	if bs.dups != nil && bs.FileInfoSums[i].Name() == bs.FileInfoSums[j].Name() {
		return bs.FileInfoSums[i].Pos() < bs.FileInfoSums[j].Pos()
	}
	return bs.FileInfoSums[i].Sum() < bs.FileInfoSums[j].Sum()
}

// byPos is a sort.Sort helper for sorting by the sums of all the fileinfos by their original order
type byPos struct{ FileInfoSums }

func (bp byPos) Less(i, j int) bool {
	return bp.FileInfoSums[i].Pos() < bp.FileInfoSums[j].Pos()
}