119 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			119 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 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
 | |
| }
 |