| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- package main
- import (
- "bytes"
- "compress/zlib"
- "encoding/binary"
- "fmt"
- "github.com/pkg/errors"
- //"github.com/google/brotli/go/cbrotli"
- "io"
- )
- type IDecode interface {
- Decode([]byte) ([][]byte, error)
- }
- type DecodeV0 struct {
- IDecode
- }
- // Decode v0没有压缩
- func (d *DecodeV0) Decode(input []byte) (result [][]byte, err error) {
- return [][]byte{input}, nil
- }
- type DecodeV2 struct {
- IDecode
- }
- // Decode v2zip压缩
- func (d *DecodeV2) Decode(input []byte) (result [][]byte, err error) {
- result = [][]byte{}
- b := bytes.NewReader(input)
- r, err := zlib.NewReader(b)
- if err != nil {
- err = errors.Wrapf(err, "[DecodeV2 | Decode] unzip err")
- return
- }
- var bodyBuf bytes.Buffer
- _, err = io.Copy(&bodyBuf, r)
- if err != nil {
- err = errors.Wrapf(err, "[DecodeV2 | Decode] io.Copy err")
- return
- }
- bodyLen := int32(bodyBuf.Len())
- var offset int32
- // |int32(一个cmd的长度+4位)|cmd内容|int32(一个cmd的长度+4位)|cmd内容|int32(一个cmd的长度+4位)|cmd内容|....
- for offset < bodyLen {
- cmdSize := int32(binary.BigEndian.Uint32(bodyBuf.Bytes()[offset : offset+CmdSize]))
- // 协议长度大于body长度
- if offset+cmdSize > bodyLen {
- err = fmt.Errorf("[DecodeV2 | Decode] offset:%d + cmdSize:%d > bodyLen:%d", offset, cmdSize, bodyLen)
- return
- }
- cmd := bodyBuf.Bytes()[offset+CmdSize : offset+cmdSize]
- result = append(result, cmd)
- offset += cmdSize
- }
- return
- }
- type DecodeManager struct {
- m map[int64]IDecode
- }
- func NewDecodeManager() (manager *DecodeManager) {
- return &DecodeManager{
- m: map[int64]IDecode{
- ProtoVersion0: &DecodeV0{},
- ProtoVersion2: &DecodeV2{},
- },
- }
- }
- func (m *DecodeManager) Decode(version int64, input []byte) (result [][]byte, err error) {
- d, exist := m.m[version]
- if !exist {
- err = errors.Wrapf(err, "[DecodeManager | Decode] version not found")
- return
- }
- result, err = d.Decode(input)
- if err != nil {
- err = errors.Wrapf(err, "[DecodeManager | Decode] Decode err")
- return
- }
- return
- }
|