github.com/Microsoft/azure-vhd-utils@v0.0.0-20230613175315-7c30a3748a1b/vhdcore/block/bitmap/bitmap.go (about)

     1  package bitmap
     2  
     3  import "fmt"
     4  
     5  // BitMap type represents 'bitmap section' of a block.
     6  //
     7  type BitMap struct {
     8  	data   []byte
     9  	Length int32
    10  }
    11  
    12  // NewBitMapFromByteSlice creates a new BitMap, b is the byte slice that needs to be used as bitmap
    13  // source. The caller should not reuse this byte slice anymore.
    14  //
    15  func NewBitMapFromByteSlice(b []byte) *BitMap {
    16  	return &BitMap{data: b, Length: int32(len(b)) * 8}
    17  }
    18  
    19  // NewBitMapFromByteSliceCopy creates a new BitMap, b is the byte slice that needs to be used as bitmap
    20  // source. The caller can reuse the byte slice as this method creates a copy of it.
    21  //
    22  func NewBitMapFromByteSliceCopy(b []byte) *BitMap {
    23  	data := make([]byte, len(b))
    24  	copy(data, b)
    25  	return &BitMap{data: data, Length: int32(len(b)) * 8}
    26  }
    27  
    28  // Set sets the bit at the given index. It returns error if idx < 0 or idx >= bitsCount.
    29  //
    30  func (b *BitMap) Set(idx int32, value bool) error {
    31  	if idx < 0 || idx >= b.Length {
    32  		return fmt.Errorf("The index %d is out of boundary", idx)
    33  	}
    34  
    35  	i := idx >> 3
    36  	m := 1 << (uint32(idx) & 7)
    37  
    38  	if value {
    39  		b.data[i] = b.data[i] | byte(m)
    40  	} else {
    41  		b.data[i] = b.data[i] & byte(^m)
    42  	}
    43  
    44  	return nil
    45  }
    46  
    47  // Get returns the value of the bit at the given index. It returns error if idx < 0 or idx >= bitsCount.
    48  //
    49  func (b *BitMap) Get(idx int32) (bool, error) {
    50  	if idx < 0 || idx >= b.Length {
    51  		return false, fmt.Errorf("The index %d is out of boundary", idx)
    52  	}
    53  
    54  	i := idx >> 3
    55  	m := 1 << (uint32(idx) & 7)
    56  
    57  	return (b.data[i] & byte(m)) != 0, nil
    58  }