blob: 1f144431a8bf5d6c3eab0d9f7895222bb7a5874c [file] [log] [blame]
khenaidooac637102019-01-14 15:44:34 -05001package sarama
2
3import (
4 "encoding/binary"
5 "fmt"
6 "hash/crc32"
7)
8
9type crcPolynomial int8
10
11const (
12 crcIEEE crcPolynomial = iota
13 crcCastagnoli
14)
15
16var castagnoliTable = crc32.MakeTable(crc32.Castagnoli)
17
18// crc32Field implements the pushEncoder and pushDecoder interfaces for calculating CRC32s.
19type crc32Field struct {
20 startOffset int
21 polynomial crcPolynomial
22}
23
24func (c *crc32Field) saveOffset(in int) {
25 c.startOffset = in
26}
27
28func (c *crc32Field) reserveLength() int {
29 return 4
30}
31
32func newCRC32Field(polynomial crcPolynomial) *crc32Field {
33 return &crc32Field{polynomial: polynomial}
34}
35
36func (c *crc32Field) run(curOffset int, buf []byte) error {
37 crc, err := c.crc(curOffset, buf)
38 if err != nil {
39 return err
40 }
41 binary.BigEndian.PutUint32(buf[c.startOffset:], crc)
42 return nil
43}
44
45func (c *crc32Field) check(curOffset int, buf []byte) error {
46 crc, err := c.crc(curOffset, buf)
47 if err != nil {
48 return err
49 }
50
51 expected := binary.BigEndian.Uint32(buf[c.startOffset:])
52 if crc != expected {
53 return PacketDecodingError{fmt.Sprintf("CRC didn't match expected %#x got %#x", expected, crc)}
54 }
55
56 return nil
57}
58func (c *crc32Field) crc(curOffset int, buf []byte) (uint32, error) {
59 var tab *crc32.Table
60 switch c.polynomial {
61 case crcIEEE:
62 tab = crc32.IEEETable
63 case crcCastagnoli:
64 tab = castagnoliTable
65 default:
66 return 0, PacketDecodingError{"invalid CRC type"}
67 }
68 return crc32.Checksum(buf[c.startOffset+4:curOffset], tab), nil
69}