Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
c4b3c6441a
|
|||
|
1c5abd4083
|
118
bitmask/bitmask.go
Normal file
118
bitmask/bitmask.go
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
package bitmask
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"encoding/binary"
|
||||||
|
"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
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value returns the current raw uint value of a MaskBit.
|
||||||
|
func (m *MaskBit) Value() (v uint) {
|
||||||
|
|
||||||
|
v = uint(*m)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package bitmask
|
|
||||||
|
|
||||||
// MaskBit is a flag container.
|
|
||||||
type MaskBit uint8
|
|
||||||
|
|
||||||
/*
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
@@ -11,18 +11,18 @@ To use this, set constants like thus:
|
|||||||
"r00t2.io/goutils/bitmask"
|
"r00t2.io/goutils/bitmask"
|
||||||
)
|
)
|
||||||
|
|
||||||
const OPTNONE types.MaskBit = 0
|
const OPTNONE bitmask.MaskBit = 0
|
||||||
const (
|
const (
|
||||||
OPT1 types.MaskBit = 1 << iota
|
OPT1 bitmask.MaskBit = 1 << iota
|
||||||
OPT2
|
OPT2
|
||||||
OPT3
|
OPT3
|
||||||
// ...
|
// ...
|
||||||
)
|
)
|
||||||
|
|
||||||
var MyMask *MaskBit
|
var MyMask *bitmask.MaskBit
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
MyMask = types.NewMaskBit
|
MyMask = bitmask.NewMaskBit()
|
||||||
|
|
||||||
MyMask.AddFlag(OPT1)
|
MyMask.AddFlag(OPT1)
|
||||||
MyMask.AddFlag(OPT3)
|
MyMask.AddFlag(OPT3)
|
||||||
@@ -41,5 +41,13 @@ As would this:
|
|||||||
But this would return false:
|
But this would return false:
|
||||||
|
|
||||||
MyMask.HasFlag(OPT2)
|
MyMask.HasFlag(OPT2)
|
||||||
|
|
||||||
|
If you need something with more flexibility (as always, at the cost of complexity),
|
||||||
|
you may be interested in one of the following libraries:
|
||||||
|
|
||||||
|
. github.com/alvaroloes/enumer
|
||||||
|
. github.com/abice/go-enum
|
||||||
|
. github.com/jeffreyrichter/enum/enum
|
||||||
|
|
||||||
*/
|
*/
|
||||||
package bitmask
|
package bitmask
|
||||||
|
|||||||
Reference in New Issue
Block a user