diff options
| author | 2026-03-25 16:22:03 +0000 | |
|---|---|---|
| committer | 2026-03-25 16:22:03 +0000 | |
| commit | 311edcd50f3a84f4b860bde3cb887451d74eaa11 (patch) | |
| tree | be7aa5e9a51e636358f33b1c90637b5024b70dc3 /network/protocol/pktline/header.go | |
| parent | README: Split off contrib, benchmarks, remove history for now I guess, etc. (diff) | |
| signature | No signature | |
network/protocol: Rename from protocol v0.1.110
Diffstat (limited to 'network/protocol/pktline/header.go')
| -rw-r--r-- | network/protocol/pktline/header.go | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/network/protocol/pktline/header.go b/network/protocol/pktline/header.go new file mode 100644 index 00000000..41e50e04 --- /dev/null +++ b/network/protocol/pktline/header.go @@ -0,0 +1,57 @@ +package pktline + +import "fmt" + +func hexval(b byte) int { + switch { + case b >= '0' && b <= '9': + return int(b - '0') + case b >= 'a' && b <= 'f': + return int(b-'a') + 10 + case b >= 'A' && b <= 'F': + return int(b-'A') + 10 + default: + return -1 + } +} + +// ParseLengthHeader parses a 4-byte hexadecimal pkt-line length header. +// +// The returned value is the full on-wire packet size, including the 4-byte +// header. Semantic interpretation (data/control/error) is done by Decoder. +// +// The 4-byte header is only an actual length when above or equal to 4. +// Otherwise, it indicates some control packet. +func ParseLengthHeader(h [4]byte) (int, error) { + a := hexval(h[0]) + b := hexval(h[1]) + c := hexval(h[2]) + d := hexval(h[3]) + + if a < 0 || b < 0 || c < 0 || d < 0 { + return 0, fmt.Errorf("%w: %q", ErrInvalidLength, string(h[:])) + } + + return (a << 12) | (b << 8) | (c << 4) | d, nil +} + +// EncodeLengthHeader encodes n as a 4-byte hexadecimal pkt-line header. +// +// n is the full on-wire packet size including the 4-byte header. +// +// The 4-byte header is only an actual length when above or equal to 4. +// Otherwise, it indicates some control packet. +func EncodeLengthHeader(dst *[4]byte, n int) error { + if n < 0 || n > LargePacketMax { + return fmt.Errorf("%w: %d", ErrInvalidLength, n) + } + + const hex = "0123456789abcdef" + + dst[0] = hex[(n>>12)&0xf] + dst[1] = hex[(n>>8)&0xf] + dst[2] = hex[(n>>4)&0xf] + dst[3] = hex[n&0xf] + + return nil +} |
