123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- package sarama
- import (
- "encoding/binary"
- "fmt"
- "hash/crc32"
- "sync"
- )
- type crcPolynomial int8
- const (
- crcIEEE crcPolynomial = iota
- crcCastagnoli
- )
- var crc32FieldPool = sync.Pool{}
- func acquireCrc32Field(polynomial crcPolynomial) *crc32Field {
- val := crc32FieldPool.Get()
- if val != nil {
- c := val.(*crc32Field)
- c.polynomial = polynomial
- return c
- }
- return newCRC32Field(polynomial)
- }
- func releaseCrc32Field(c *crc32Field) {
- crc32FieldPool.Put(c)
- }
- var castagnoliTable = crc32.MakeTable(crc32.Castagnoli)
- // crc32Field implements the pushEncoder and pushDecoder interfaces for calculating CRC32s.
- type crc32Field struct {
- startOffset int
- polynomial crcPolynomial
- }
- func (c *crc32Field) saveOffset(in int) {
- c.startOffset = in
- }
- func (c *crc32Field) reserveLength() int {
- return 4
- }
- func newCRC32Field(polynomial crcPolynomial) *crc32Field {
- return &crc32Field{polynomial: polynomial}
- }
- func (c *crc32Field) run(curOffset int, buf []byte) error {
- crc, err := c.crc(curOffset, buf)
- if err != nil {
- return err
- }
- binary.BigEndian.PutUint32(buf[c.startOffset:], crc)
- return nil
- }
- func (c *crc32Field) check(curOffset int, buf []byte) error {
- crc, err := c.crc(curOffset, buf)
- if err != nil {
- return err
- }
- expected := binary.BigEndian.Uint32(buf[c.startOffset:])
- if crc != expected {
- return PacketDecodingError{fmt.Sprintf("CRC didn't match expected %#x got %#x", expected, crc)}
- }
- return nil
- }
- func (c *crc32Field) crc(curOffset int, buf []byte) (uint32, error) {
- var tab *crc32.Table
- switch c.polynomial {
- case crcIEEE:
- tab = crc32.IEEETable
- case crcCastagnoli:
- tab = castagnoliTable
- default:
- return 0, PacketDecodingError{"invalid CRC type"}
- }
- return crc32.Checksum(buf[c.startOffset+4:curOffset], tab), nil
- }
|