X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/2d2f3bed79f9504d15503277056feb394c12dd7c..093ec98e4a065acfc537ea22c08c337c115fe273:/sdk/go/blockdigest/blockdigest.go diff --git a/sdk/go/blockdigest/blockdigest.go b/sdk/go/blockdigest/blockdigest.go index 0742839720..ecb09964ec 100644 --- a/sdk/go/blockdigest/blockdigest.go +++ b/sdk/go/blockdigest/blockdigest.go @@ -1,25 +1,47 @@ -/* Stores a Block Locator Digest compactly. Can be used as a map key. */ +// Copyright (C) The Arvados Authors. All rights reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// Package blockdigest stores a Block Locator Digest compactly. Can be used as a map key. package blockdigest import ( "fmt" - "log" + "regexp" "strconv" + "strings" ) -// Stores a Block Locator Digest compactly, up to 128 bits. -// Can be used as a map key. +var LocatorPattern = regexp.MustCompile( + "^[0-9a-fA-F]{32}\\+[0-9]+(\\+[A-Z][A-Za-z0-9@_-]*)*$") + +// BlockDigest stores a Block Locator Digest compactly, up to 128 bits. Can be +// used as a map key. type BlockDigest struct { - h uint64 - l uint64 + H uint64 + L uint64 +} + +type DigestWithSize struct { + Digest BlockDigest + Size uint32 } -func (d *BlockDigest) ToString() (s string) { - return fmt.Sprintf("%016x%016x", d.h, d.l) +type BlockLocator struct { + Digest BlockDigest + Size int + Hints []string } -// Will create a new BlockDigest unless an error is encountered. +func (d BlockDigest) String() string { + return fmt.Sprintf("%016x%016x", d.H, d.L) +} + +func (w DigestWithSize) String() string { + return fmt.Sprintf("%s+%d", w.Digest.String(), w.Size) +} + +// FromString creates a new BlockDigest unless an error is encountered. func FromString(s string) (dig BlockDigest, err error) { if len(s) != 32 { err = fmt.Errorf("Block digest should be exactly 32 characters but this one is %d: %s", len(s), s) @@ -27,11 +49,11 @@ func FromString(s string) (dig BlockDigest, err error) { } var d BlockDigest - d.h, err = strconv.ParseUint(s[:16], 16, 64) + d.H, err = strconv.ParseUint(s[:16], 16, 64) if err != nil { return } - d.l, err = strconv.ParseUint(s[16:], 16, 64) + d.L, err = strconv.ParseUint(s[16:], 16, 64) if err != nil { return } @@ -39,11 +61,33 @@ func FromString(s string) (dig BlockDigest, err error) { return } -// Will fatal with the error if an error is encountered -func AssertFromString(s string) BlockDigest { - d, err := FromString(s) - if err != nil { - log.Fatalf("Error creating BlockDigest from %s: %v", s, err) +func IsBlockLocator(s string) bool { + return LocatorPattern.MatchString(s) +} + +func ParseBlockLocator(s string) (b BlockLocator, err error) { + if !LocatorPattern.MatchString(s) { + err = fmt.Errorf("String \"%s\" does not match BlockLocator pattern "+ + "\"%s\".", + s, + LocatorPattern.String()) + } else { + tokens := strings.Split(s, "+") + var blockSize int64 + var blockDigest BlockDigest + // We expect both of the following to succeed since LocatorPattern + // restricts the strings appropriately. + blockDigest, err = FromString(tokens[0]) + if err != nil { + return + } + blockSize, err = strconv.ParseInt(tokens[1], 10, 0) + if err != nil { + return + } + b.Digest = blockDigest + b.Size = int(blockSize) + b.Hints = tokens[2:] } - return d + return }