perkeep/blobserver/go/blobref.go

77 lines
1.6 KiB
Go

package main
import (
"crypto/sha1"
"fmt"
"hash"
"regexp"
)
var kGetPutPattern *regexp.Regexp = regexp.MustCompile(`^/camli/([a-z0-9]+)-([a-f0-9]+)$`)
var kBlobRefPattern *regexp.Regexp = regexp.MustCompile(`^([a-z0-9]+)-([a-f0-9]+)$`)
type BlobRef struct {
HashName string
Digest string
}
var kExpectedDigestSize = map[string]int{
"md5": 32,
"sha1": 40,
}
func blobIfValid(hashname, digest string) *BlobRef {
expectedSize := kExpectedDigestSize[hashname]
if expectedSize != 0 && len(digest) != expectedSize {
return nil
}
return &BlobRef{hashname, digest}
}
func blobFromPattern(r *regexp.Regexp, s string) *BlobRef {
matches := r.FindStringSubmatch(s)
if len(matches) != 3 {
return nil
}
return blobIfValid(matches[1], matches[2])
}
func ParseBlobRef(ref string) *BlobRef {
return blobFromPattern(kBlobRefPattern, ref)
}
func ParsePath(path string) *BlobRef {
return blobFromPattern(kGetPutPattern, path)
}
func (o *BlobRef) IsSupported() bool {
if o.HashName == "sha1" {
return true
}
return false
}
func (o *BlobRef) String() string {
return fmt.Sprintf("%s-%s", o.HashName, o.Digest)
}
func (o *BlobRef) Hash() hash.Hash {
if o.HashName == "sha1" {
return sha1.New()
}
return nil
}
func (o *BlobRef) FileBaseName() string {
return fmt.Sprintf("%s-%s.dat", o.HashName, o.Digest)
}
func (o *BlobRef) DirectoryName() string {
return fmt.Sprintf("%s/%s/%s/%s",
*flagStorageRoot, o.HashName, o.Digest[0:3], o.Digest[3:6])
}
func (o *BlobRef) FileName() string {
return fmt.Sprintf("%s/%s-%s.dat", o.DirectoryName(), o.HashName, o.Digest)
}