Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
688abd0874
|
||
|
|
a1f87d6b51
|
19
.encoding.TODO/bit/docs.go
Normal file
19
.encoding.TODO/bit/docs.go
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
Package bit aims to provide feature parity with stdlib's [encoding/hex].
|
||||||
|
|
||||||
|
It's a ludicrous tragedy that hex/base16, base32, base64 all have libraries for converting
|
||||||
|
to/from string representations... but there's nothing for binary ('01010001' etc.) whatsoever.
|
||||||
|
|
||||||
|
This package also provides some extra convenience functions and types in an attempt to provide
|
||||||
|
an abstracted bit-level fidelity in Go. A [Bit] is a bool type, in which that underlying bool
|
||||||
|
being false represents a 0 and that underlying bool being true represents a 1.
|
||||||
|
|
||||||
|
Note that a [Bit] or arbitrary-length or non-octal-aligned [][Bit] may take up more bytes in memory
|
||||||
|
than expected; a [Bit] will actually always occupy a single byte -- thus representing
|
||||||
|
`00000000 00000000` as a [][Bit] or [16][Bit] will actually occupy *sixteen bytes* in memory,
|
||||||
|
NOT 2 bytes (nor, obviously, [2][Byte])!
|
||||||
|
It is recommended instead to use a [Bits] instead of a [Bit] slice or array, as it will try to properly align to the
|
||||||
|
smallest memory allocation possible (at the cost of a few extra CPU cycles on adding/removing one or more [Bit]).
|
||||||
|
It will properly retain any appended, prepended, leading, or trailing bits that do not currently align to a byte.
|
||||||
|
*/
|
||||||
|
package bit
|
||||||
14
.encoding.TODO/bit/funcs.go
Normal file
14
.encoding.TODO/bit/funcs.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package bit
|
||||||
|
|
||||||
|
// TODO: Provide analogues of encoding/hex, encoding/base64, etc. functions etc.
|
||||||
|
|
||||||
|
/*
|
||||||
|
TODO: Also provide interfaces for the following:
|
||||||
|
|
||||||
|
* https://pkg.go.dev/encoding#BinaryAppender
|
||||||
|
* https://pkg.go.dev/encoding#BinaryMarshaler
|
||||||
|
* https://pkg.go.dev/encoding#BinaryUnmarshaler
|
||||||
|
* https://pkg.go.dev/encoding#TextAppender
|
||||||
|
* https://pkg.go.dev/encoding#TextMarshaler
|
||||||
|
* https://pkg.go.dev/encoding#TextUnmarshaler
|
||||||
|
*/
|
||||||
34
.encoding.TODO/bit/types.go
Normal file
34
.encoding.TODO/bit/types.go
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package bit
|
||||||
|
|
||||||
|
type (
|
||||||
|
// Bit aims to provide a native-like type for a single bit (Golang operates on the smallest fidelity level of *byte*/uint8).
|
||||||
|
Bit bool
|
||||||
|
|
||||||
|
// Bits is an arbitrary length of bits.
|
||||||
|
Bits struct {
|
||||||
|
/*
|
||||||
|
leading is a series of Bit that do not cleanly align to the beginning of Bits.b.
|
||||||
|
They will always be the bits at the *beginning* of the sequence.
|
||||||
|
len(Bits.leading) will *never* be more than 7;
|
||||||
|
it's converted into a byte, prepended to Bits.b, and cleared if it reaches that point.
|
||||||
|
*/
|
||||||
|
leading []Bit
|
||||||
|
// b is the condensed/memory-aligned alternative to an [][8]Bit (or []Bit, or [][]Bit, etc.).
|
||||||
|
b []byte
|
||||||
|
/*
|
||||||
|
remaining is a series of Bit that do not cleanly align to the end of Bits.b.
|
||||||
|
They will always be the bits at the *end* of the sequence.
|
||||||
|
len(Bits.remaining) will *never* be more than 7;
|
||||||
|
it's converted into a byte, appended to Bits.b, and cleared if it reaches that point.
|
||||||
|
*/
|
||||||
|
remaining []Bit
|
||||||
|
// fixedLen, if 0, represents a "slice". If >= 1, it represents an "array".
|
||||||
|
fixedLen uint
|
||||||
|
}
|
||||||
|
|
||||||
|
// Byte is this package's representation of a byte. It's primarily for convenience.
|
||||||
|
Byte byte
|
||||||
|
|
||||||
|
// Bytes is defined as a type for convenience single-call functions.
|
||||||
|
Bytes []Byte
|
||||||
|
)
|
||||||
@@ -34,11 +34,47 @@ func NewMaskBitExplicit(value uint) (m *MaskBit) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasFlag is true if m has MaskBit flag set/enabled.
|
/*
|
||||||
|
HasFlag is true if m has MaskBit flag set/enabled.
|
||||||
|
THIS WILL RETURN FALSE FOR OR'd FLAGS.
|
||||||
|
For example:
|
||||||
|
|
||||||
|
flagA MaskBit = 0x01
|
||||||
|
flagB MaskBit = 0x02
|
||||||
|
flagComposite = flagA | flagB
|
||||||
|
|
||||||
|
m *MaskBit = NewMaskBitExplicit(uint(flagA))
|
||||||
|
|
||||||
|
m.HasFlag(flagComposite) will return false even though flagComposite is an OR
|
||||||
|
that contains flagA.
|
||||||
|
Use [MaskBit.IsOneOf] instead if you do not desire this behavior,
|
||||||
|
and instead want to test composite flag *membership*.
|
||||||
|
(MaskBit.IsOneOf will also return true for non-composite equality.)
|
||||||
|
*/
|
||||||
func (m *MaskBit) HasFlag(flag MaskBit) (r bool) {
|
func (m *MaskBit) HasFlag(flag MaskBit) (r bool) {
|
||||||
|
|
||||||
var b MaskBit = *m
|
var b MaskBit = *m
|
||||||
|
|
||||||
|
if b&flag == flag {
|
||||||
|
r = true
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
IsOneOf is like a "looser" form of [MaskBit.HasFlag]
|
||||||
|
in that it allows for testing composite membership.
|
||||||
|
|
||||||
|
See [MaskBit.HasFlag] for more information.
|
||||||
|
|
||||||
|
If composite is *not* an OR'd MaskBit (i.e.
|
||||||
|
it falls directly on a boundary -- 0, 1, 2, 4, 8, 16, etc.),
|
||||||
|
then IsOneOf will behave exactly like HasFlag.
|
||||||
|
*/
|
||||||
|
func (m *MaskBit) IsOneOf(composite MaskBit) (r bool) {
|
||||||
|
|
||||||
|
var b MaskBit = *m
|
||||||
|
|
||||||
if b&flag != 0 {
|
if b&flag != 0 {
|
||||||
r = true
|
r = true
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user