1 // Stores a Block Locator Digest compactly. Can be used as a map key.
12 var LocatorPattern = regexp.MustCompile(
13 "^[0-9a-fA-F]{32}\\+[0-9]+(\\+[A-Z][A-Za-z0-9@_-]+)*$")
15 // Stores a Block Locator Digest compactly, up to 128 bits.
16 // Can be used as a map key.
17 type BlockDigest struct {
22 type DigestWithSize struct {
27 type BlockLocator struct {
33 func (d BlockDigest) String() string {
34 return fmt.Sprintf("%016x%016x", d.H, d.L)
37 func (w DigestWithSize) String() string {
38 return fmt.Sprintf("%s+%d", w.Digest.String(), w.Size)
41 // Will create a new BlockDigest unless an error is encountered.
42 func FromString(s string) (dig BlockDigest, err error) {
44 err = fmt.Errorf("Block digest should be exactly 32 characters but this one is %d: %s", len(s), s)
49 d.H, err = strconv.ParseUint(s[:16], 16, 64)
53 d.L, err = strconv.ParseUint(s[16:], 16, 64)
61 // Will fatal with the error if an error is encountered
62 func AssertFromString(s string) BlockDigest {
63 d, err := FromString(s)
65 log.Fatalf("Error creating BlockDigest from %s: %v", s, err)
70 func IsBlockLocator(s string) bool {
71 return LocatorPattern.MatchString(s)
74 func ParseBlockLocator(s string) (b BlockLocator, err error) {
75 if !LocatorPattern.MatchString(s) {
76 err = fmt.Errorf("String \"%s\" does not match BlockLocator pattern "+
79 LocatorPattern.String())
81 tokens := strings.Split(s, "+")
83 var blockDigest BlockDigest
84 // We expect both of the following to succeed since LocatorPattern
85 // restricts the strings appropriately.
86 blockDigest, err = FromString(tokens[0])
90 blockSize, err = strconv.ParseInt(tokens[1], 10, 0)
94 b.Digest = blockDigest
95 b.Size = int(blockSize)