mq_coder/encoder.go

78 lines
1.4 KiB
Go

package mq_coder
import (
"bytes"
"fmt"
"git.hpds.cc/Component/mq_coder/encoding"
)
// Encoder will encode object to encoding
type encoder struct {
seqID byte
valBuf []byte
isNode bool
isArray bool
buf *bytes.Buffer
complete bool
}
type iEncoder interface {
Encode() []byte
}
func (enc *encoder) GetValBuf() []byte {
return enc.valBuf
}
func (enc *encoder) IsEmpty() bool {
return len(enc.valBuf) == 0
}
func (enc *encoder) AddBytes(buf []byte) {
enc.valBuf = append(enc.valBuf, buf...)
}
func (enc *encoder) addRawPacket(en iEncoder) {
enc.valBuf = append(enc.valBuf, en.Encode()...)
}
// setTag write tag as seqID
func (enc *encoder) writeTag() {
if enc.seqID > 0x3F {
panic(fmt.Errorf("sid should be in [0..0x3F]"))
}
if enc.isNode {
enc.seqID = enc.seqID | 0x80
}
if enc.isArray {
enc.seqID = enc.seqID | 0x40
}
enc.buf.WriteByte(enc.seqID)
}
func (enc *encoder) writeLengthBuf() {
valLen := len(enc.valBuf)
size := encoding.SizeOfPVarInt32(int32(valLen))
codec := encoding.VarCodec{Size: size}
tmp := make([]byte, size)
err := codec.EncodePVarInt32(tmp, int32(valLen))
if err != nil {
panic(err)
}
enc.buf.Write(tmp)
}
// Encode returns a final Y3 encoded byte slice
func (enc *encoder) Encode() []byte {
if !enc.complete {
// Tag
enc.writeTag()
// Len
enc.writeLengthBuf()
// Val
enc.buf.Write(enc.valBuf)
enc.complete = true
}
return enc.buf.Bytes()
}