github.com/anonymouse64/snapd@v0.0.0-20210824153203-04c4c42d842d/gadget/quantity/offset.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2020 Canonical Ltd
     5   *
     6   * This program is free software: you can redistribute it and/or modify
     7   * it under the terms of the GNU General Public License version 3 as
     8   * published by the Free Software Foundation.
     9   *
    10   * This program is distributed in the hope that it will be useful,
    11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13   * GNU General Public License for more details.
    14   *
    15   * You should have received a copy of the GNU General Public License
    16   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17   *
    18   */
    19  
    20  package quantity
    21  
    22  import (
    23  	"errors"
    24  	"fmt"
    25  )
    26  
    27  // Offset describes the offset in bytes and is a thin wrapper around Size.
    28  type Offset Size
    29  
    30  const (
    31  	// OffsetKiB is the byte size of one kibibyte (2^10 = 1024 bytes)
    32  	OffsetKiB = Offset(1 << 10)
    33  	// OffsetMiB is the offset of one mebibyte (2^20)
    34  	OffsetMiB = Offset(1 << 20)
    35  )
    36  
    37  func (o *Offset) String() string {
    38  	return (*Size)(o).String()
    39  }
    40  
    41  // IECString formats the offset using multiples from IEC units (i.e. kibibytes,
    42  // mebibytes), that is as multiples of 1024. Printed values are truncated to 2
    43  // decimal points.
    44  func (o *Offset) IECString() string {
    45  	return iecSizeString(int64(*o))
    46  }
    47  
    48  func (o *Offset) UnmarshalYAML(unmarshal func(interface{}) error) error {
    49  	var gs string
    50  	if err := unmarshal(&gs); err != nil {
    51  		return errors.New(`cannot unmarshal gadget offset`)
    52  	}
    53  
    54  	var err error
    55  	*o, err = ParseOffset(gs)
    56  	if err != nil {
    57  		return fmt.Errorf("cannot parse offset %q: %v", gs, err)
    58  	}
    59  	return err
    60  }
    61  
    62  // ParseOffset parses a string expressing offset in a gadget specific format. The
    63  // accepted format is one of: <bytes> | <bytes/2^20>M | <bytes/2^30>G.
    64  func ParseOffset(gs string) (Offset, error) {
    65  	offs, err := parseSizeOrOffset(gs)
    66  	if offs < 0 {
    67  		// XXX: in theory offsets can be negative, but not in gadget
    68  		// YAML
    69  		return 0, errors.New("offset cannot be negative")
    70  	}
    71  	return Offset(offs), err
    72  }