1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: Apache-2.0
5 // Package blockdigest stores a Block Locator Digest compactly. Can be used as a map key.
15 var LocatorPattern = regexp.MustCompile(
16 "^[0-9a-fA-F]{32}\\+[0-9]+(\\+[A-Z][A-Za-z0-9@_-]*)*$")
18 // BlockDigest stores a Block Locator Digest compactly, up to 128 bits. Can be
20 type BlockDigest struct {
25 type DigestWithSize struct {
30 type BlockLocator struct {
36 func (d BlockDigest) String() string {
37 return fmt.Sprintf("%016x%016x", d.H, d.L)
40 func (w DigestWithSize) String() string {
41 return fmt.Sprintf("%s+%d", w.Digest.String(), w.Size)
44 // FromString creates a new BlockDigest unless an error is encountered.
45 func FromString(s string) (dig BlockDigest, err error) {
47 err = fmt.Errorf("Block digest should be exactly 32 characters but this one is %d: %s", len(s), s)
52 d.H, err = strconv.ParseUint(s[:16], 16, 64)
56 d.L, err = strconv.ParseUint(s[16:], 16, 64)
64 func IsBlockLocator(s string) bool {
65 return LocatorPattern.MatchString(s)
68 func ParseBlockLocator(s string) (b BlockLocator, err error) {
69 if !LocatorPattern.MatchString(s) {
70 err = fmt.Errorf("String \"%s\" does not match BlockLocator pattern "+
73 LocatorPattern.String())
75 tokens := strings.Split(s, "+")
77 var blockDigest BlockDigest
78 // We expect both of the following to succeed since LocatorPattern
79 // restricts the strings appropriately.
80 blockDigest, err = FromString(tokens[0])
84 blockSize, err = strconv.ParseInt(tokens[1], 10, 0)
88 b.Digest = blockDigest
89 b.Size = int(blockSize)