github.com/matrixorigin/matrixone@v1.2.0/pkg/frontend/codec.go (about)

     1  // Copyright 2021 Matrix Origin
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package frontend
    16  
    17  import (
    18  	"context"
    19  	"io"
    20  
    21  	"github.com/fagongzi/goetty/v2/buf"
    22  	"github.com/fagongzi/goetty/v2/codec"
    23  
    24  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    25  )
    26  
    27  var (
    28  	errorInvalidLength0             = moerr.NewInvalidInput(context.Background(), "invalid length: 0")
    29  	errorLenOfWrittenNotEqLenOfData = moerr.NewInternalError(context.Background(), "len of written != len of the data")
    30  )
    31  
    32  const PacketHeaderLength = 4
    33  
    34  func NewSqlCodec() codec.Codec {
    35  	return &sqlCodec{}
    36  }
    37  
    38  type sqlCodec struct {
    39  }
    40  
    41  type Packet struct {
    42  	Length     int32
    43  	SequenceID int8
    44  	Payload    []byte
    45  }
    46  
    47  func (c *sqlCodec) Decode(in *buf.ByteBuf) (interface{}, bool, error) {
    48  	readable := in.Readable()
    49  	if readable < PacketHeaderLength {
    50  		return nil, false, nil
    51  	}
    52  
    53  	header := in.PeekN(0, PacketHeaderLength)
    54  	length := int32(uint32(header[0]) | uint32(header[1])<<8 | uint32(header[2])<<16)
    55  	if length == 0 {
    56  		return nil, false, errorInvalidLength0
    57  	}
    58  
    59  	sequenceID := int8(header[3])
    60  
    61  	if readable < int(length)+PacketHeaderLength {
    62  		return nil, false, nil
    63  	}
    64  
    65  	in.Skip(PacketHeaderLength)
    66  	in.SetMarkIndex(in.GetReadIndex() + int(length))
    67  	payload := in.ReadMarkedData()
    68  
    69  	packet := &Packet{
    70  		Length:     length,
    71  		SequenceID: sequenceID,
    72  		Payload:    payload,
    73  	}
    74  
    75  	return packet, true, nil
    76  }
    77  
    78  func (c *sqlCodec) Encode(data interface{}, out *buf.ByteBuf, writer io.Writer) error {
    79  	x := data.([]byte)
    80  	xlen := len(x)
    81  	tlen, err := out.Write(data.([]byte))
    82  	if err != nil {
    83  		return err
    84  	}
    85  	if tlen != xlen {
    86  		return errorLenOfWrittenNotEqLenOfData
    87  	}
    88  	return nil
    89  }