go_goutils/bitmask/bitmask.go

128 lines
2.4 KiB
Go

package bitmask
import (
"bytes"
"encoding/binary"
"errors"
"math/bits"
)
// MaskBit is a flag container.
type MaskBit uint
/*
NewMaskBit is a convenience function.
It will return a MaskBit with a (referenced) value of 0, so set your consts up accordingly.
It is highly recommended to set this default as a "None" flag (separate from your iotas!)
as shown in the example.
*/
func NewMaskBit() (m *MaskBit) {
m = new(MaskBit)
return
}
// NewMaskBitExplicit is like NewMaskBit, but allows you to specify a non-zero (0x0) value.
func NewMaskBitExplicit(value uint) (m *MaskBit) {
var v MaskBit = MaskBit(value)
m = &v
return
}
// HasFlag is true if m has MaskBit flag set/enabled.
func (m *MaskBit) HasFlag(flag MaskBit) (r bool) {
var b MaskBit = *m
if b&flag != 0 {
r = true
}
return
}
// AddFlag adds MaskBit flag to m.
func (m *MaskBit) AddFlag(flag MaskBit) {
*m |= flag
return
}
// ClearFlag removes MaskBit flag from m.
func (m *MaskBit) ClearFlag(flag MaskBit) {
*m &= flag
return
}
// ToggleFlag switches MaskBit flag in m to its inverse; if true, it is now false and vice versa.
func (m *MaskBit) ToggleFlag(flag MaskBit) {
*m ^= flag
return
}
/*
Bytes returns the current value of a MasBit as a byte slice (big-endian).
If trim is false, b will (probably) be 4 bytes long if you're on a 32-bit size system,
and b will (probably) be 8 bytes long if you're on a 64-bit size system. You can determine
the size of the resulting slice via (math/)bits.UintSize / 8.
If trim is true, it will trim leading null bytes (if any). This will lead to an unpredictable
byte slice length in b, but is most likely preferred for byte operations.
*/
func (m *MaskBit) Bytes(trim bool) (b []byte) {
var b2 []byte
var size int = bits.UintSize / 8
var err error
b2 = make([]byte, size)
switch s := bits.UintSize; s {
case 32:
binary.BigEndian.PutUint32(b2[:], uint32(*m))
case 64:
binary.BigEndian.PutUint64(b2[:], uint64(*m))
default:
err = errors.New("unsupported Uint/system bit size")
panic(err)
}
if trim {
b = bytes.TrimLeft(b2, "\x00")
return
} else {
b = b2
return
}
return
}
// Copy returns a pointer to a (new) copy of a MaskBit.
func (m *MaskBit) Copy() (newM *MaskBit) {
newM = new(MaskBit)
*newM = *m
return
}
// Value returns the current raw uint value of a MaskBit.
func (m *MaskBit) Value() (v uint) {
v = uint(*m)
return
}