ref: ba8c85ed2456c59269214f6e4f1203537fb3f6d4
dir: /protocol/pktline/header.go/
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
}