65 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			Go
		
	
	
	
		
		
			
		
	
	
			65 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			Go
		
	
	
	
|  | package buildah | ||
|  | 
 | ||
|  | import ( | ||
|  | 	"hash" | ||
|  | 	"strings" | ||
|  | 
 | ||
|  | 	digest "github.com/opencontainers/go-digest" | ||
|  | ) | ||
|  | 
 | ||
|  | type singleDigester struct { | ||
|  | 	digester digest.Digester | ||
|  | 	prefix   string | ||
|  | } | ||
|  | 
 | ||
|  | // CompositeDigester can compute a digest over multiple items.
 | ||
|  | type CompositeDigester struct { | ||
|  | 	digesters []singleDigester | ||
|  | } | ||
|  | 
 | ||
|  | // Restart clears all state, so that the composite digester can start over.
 | ||
|  | func (c *CompositeDigester) Restart() { | ||
|  | 	c.digesters = nil | ||
|  | } | ||
|  | 
 | ||
|  | // Start starts recording the digest for a new item.  The caller should call
 | ||
|  | // Hash() immediately after to retrieve the new io.Writer.
 | ||
|  | func (c *CompositeDigester) Start(prefix string) { | ||
|  | 	prefix = strings.TrimSuffix(prefix, ":") | ||
|  | 	c.digesters = append(c.digesters, singleDigester{digester: digest.Canonical.Digester(), prefix: prefix}) | ||
|  | } | ||
|  | 
 | ||
|  | // Hash returns the hasher for the current item.
 | ||
|  | func (c *CompositeDigester) Hash() hash.Hash { | ||
|  | 	num := len(c.digesters) | ||
|  | 	if num == 0 { | ||
|  | 		return nil | ||
|  | 	} | ||
|  | 	return c.digesters[num-1].digester.Hash() | ||
|  | } | ||
|  | 
 | ||
|  | // Digest returns the prefix and a composite digest over everything that's been
 | ||
|  | // digested.
 | ||
|  | func (c *CompositeDigester) Digest() (string, digest.Digest) { | ||
|  | 	num := len(c.digesters) | ||
|  | 	switch num { | ||
|  | 	case 0: | ||
|  | 		return "", "" | ||
|  | 	case 1: | ||
|  | 		return c.digesters[0].prefix, c.digesters[0].digester.Digest() | ||
|  | 	default: | ||
|  | 		content := "" | ||
|  | 		for i, digester := range c.digesters { | ||
|  | 			if i > 0 { | ||
|  | 				content += "," | ||
|  | 			} | ||
|  | 			prefix := digester.prefix | ||
|  | 			if digester.prefix != "" { | ||
|  | 				digester.prefix += ":" | ||
|  | 			} | ||
|  | 			content += prefix + digester.digester.Digest().Encoded() | ||
|  | 		} | ||
|  | 		return "multi", digest.Canonical.FromString(content) | ||
|  | 	} | ||
|  | } |