Simplify binary protocol processing in Go with nibble. By using declarative struct tags, this library automatically manages all aspects of parsing, including masking, shifting, sign-extension, and endianness. Focus on your data structure while nibble handles the complexities of binary encoding seamlessly.
Nibble is a powerful library for declarative bit-level binary encoding in Go, designed to simplify the process of working with binary protocols. Traditional methods often involve tedious bit-shifting arithmetic scattered throughout the code base. nibble streamlines this with the use of struct tags, allowing developers to define their packed formats succinctly using bits:"N" annotations. The library then automatically manages bit manipulation tasks such as masking, shifting, sign-extension, endianness, and validation.
Key Features
- Declarative Structure: Utilize struct tags to represent packed data formats accurately without manual manipulation.
- Support for Various Data Types: Handle multiple Go types, including
bool,uint8,uint16,int8, and more, with automatic handling of signed integers using two's complement. - Performance Optimized: Leverages reflection with schema caching to minimize overhead during data operations, achieving fast unmarshalling and marshalling with zero allocations in many cases.
Example Usage
A common application of nibble involves encoding TCP flags:
type TCPFlags struct {
CWR bool `bits:"1"`
ECE bool `bits:"1"`
URG bool `bits:"1"`
ACK bool `bits:"1"`
PSH bool `bits:"1"`
RST bool `bits:"1"`
SYN bool `bits:"1"`
FIN bool `bits:"1"`
}
var flags TCPFlags
nibble.UnmarshalBE([]byte{0x12}, &flags)
// flags → {ACK:true SYN:true}
Additionally, nibble offers a detailed breakdown of the raw byte data, aiding debugging and validation tasks.
Supported Field Types
| Go Type | Max Bits | Notes |
|---|---|---|
bool | 1 | |
uint8 | 8 | |
uint16 | 16 | |
uint32 | 32 | |
uint64 | 64 | |
int8 | 8 | Two's complement |
int16 | 16 | Two's complement |
int32 | 32 | Two's complement |
int64 | 64 | Two's complement |
Efficient Memory Management
Utilizing methods such as MarshalInto, developers can reduce memory allocations significantly, making nibble suitable for high-performance applications, especially in scenarios involving high-frequency packet processing.
var bufPool = sync.Pool{New: func() any { return make([]byte, 64) }}
func encode(pkt *GamePacket) ([]byte, error) {
buf := bufPool.Get().([]byte)
defer bufPool.Put(buf)
n, err := nibble.MarshalInto(buf, pkt, false) // 0 allocs
if err != nil {
return nil, err
}
return buf[:n], nil
}
Comprehensive API Reference
The nibble library provides clear API definitions for marshalling and unmarshalling binary data, including options for endianness, and includes mechanisms for validating field sizes and comparing data structures.
Conclusion
Overall, nibble stands out as a robust solution for Go developers looking to simplify binary data handling while maintaining high performance and clarity in code. The convenience of using struct tags enhances developer productivity, enabling more efficient and error-free interactions with binary protocols.
No comments yet.
Sign in to be the first to comment.