github.com/decomp/exp@v0.0.0-20210624183419-6d058f5e1da6/bin/uint64.go (about)

     1  package bin
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  	"strings"
     7  
     8  	"github.com/pkg/errors"
     9  )
    10  
    11  // Uint64 represents a 64-bit unsigned integer, which may be specified in
    12  // hexadecimal notation. It implements the flag.Value and
    13  // encoding.TextUnmarshaler interfaces.
    14  type Uint64 uint64
    15  
    16  // String returns the hexadecimal string representation of v.
    17  func (v Uint64) String() string {
    18  	return fmt.Sprintf("0x%X", uint64(v))
    19  }
    20  
    21  // Set sets v to the numberic value represented by s.
    22  func (v *Uint64) Set(s string) error {
    23  	x, err := ParseUint64(s)
    24  	if err != nil {
    25  		return errors.WithStack(err)
    26  	}
    27  	*v = x
    28  	return nil
    29  }
    30  
    31  // UnmarshalText unmarshals the text into v.
    32  func (v *Uint64) UnmarshalText(text []byte) error {
    33  	return v.Set(string(text))
    34  }
    35  
    36  // MarshalText returns the textual representation of v.
    37  func (v Uint64) MarshalText() ([]byte, error) {
    38  	return []byte(v.String()), nil
    39  }
    40  
    41  // ParseUint64 interprets the given string in base 10 or base 16 (if prefixed
    42  // with `0x` or `0X`) and returns the corresponding value.
    43  func ParseUint64(s string) (Uint64, error) {
    44  	base := 10
    45  	if strings.HasPrefix(s, "0x") || strings.HasPrefix(s, "0X") {
    46  		s = s[2:]
    47  		base = 16
    48  	}
    49  	x, err := strconv.ParseUint(s, base, 64)
    50  	if err != nil {
    51  		// Parse signed integer as fallback.
    52  		y, err := strconv.ParseInt(s, base, 64)
    53  		if err != nil {
    54  			return 0, errors.WithStack(err)
    55  		}
    56  		return Uint64(y), nil
    57  	}
    58  	return Uint64(x), nil
    59  }