func (packet *PacketHandler) sendPacket() error {
	data, err := packet.Marshal()
	if err != nil {
		packet.logger.WithField(logging.FieldKeyEventCode, logging.EventCodeErrorCodingCantSerializePostgresqlPacket).WithError(err).Errorln("Can't marshal packet")
		return err
	}
	if _, err := packet.writer.Write(data); err != nil {
		packet.logger.WithField(logging.FieldKeyEventCode, logging.EventCodeErrorNetworkWrite).WithError(err).Warningln("Can't dump marshaled packet")
		return err
	}
	if err := packet.writer.Flush(); err != nil {
		packet.logger.WithField(logging.FieldKeyEventCode, logging.EventCodeErrorNetworkFlush).WithError(err).Warningln("Can't flush writer")
		return err
	}
	return nil
}
sendPacket marshal packet and send it with writer
package postgresql
import (
	"bufio"
	"bytes"
	"encoding/binary"
	"errors"
	"github.com/cossacklabs/acra/decryptor/base"
	"github.com/cossacklabs/acra/logging"
	"github.com/cossacklabs/acra/utils"
	"github.com/sirupsen/logrus"
	"io"
)
type PacketHandler struct {
	messageType          [1]byte
	descriptionLengthBuf []byte
	descriptionBuf       *bytes.Buffer
	columnCount     int
	dataLength      int
	reader          io.Reader
	writer          *bufio.Writer
	logger          *logrus.Entry
	Columns         []*ColumnData
	terminatePacket bool
}
func NewClientSidePacketHandler(reader io.Reader, writer *bufio.Writer, logger *logrus.Entry) (*PacketHandler, error) {
	return newPacketHandlerWithLogger(reader, writer, logger.WithField("proxy", "client"))
}
func NewDbSidePacketHandler(reader io.Reader, writer *bufio.Writer, logger *logrus.Entry) (*PacketHandler, error) {
	return newPacketHandlerWithLogger(reader, writer, logger.WithField("proxy", "server"))
}
func newPacketHandlerWithLogger(reader io.Reader, writer *bufio.Writer, logger *logrus.Entry) (*PacketHandler, error) {
	return &PacketHandler{
		descriptionBuf:       bytes.NewBuffer(make([]byte, 0, OutputDefaultSize)),
		descriptionLengthBuf: make([]byte, 4),
		reader:               reader,
		writer:               writer,
		logger:               logger,
		terminatePacket:      false,
	}, nil
}
func (packet *PacketHandler) updatePacketLength(newLength int) {
	binary.BigEndian.PutUint32(packet.descriptionLengthBuf[:], uint32(newLength+DataRowLengthBufSize))
}
func (packet *PacketHandler) updateDataFromColumns() {
	columnsDataChanged := false
	for i := 0; i < packet.columnCount; i++ {
		if packet.Columns[i].changed {
			columnsDataChanged = true
			break
		}
	}
	if columnsDataChanged {
		newDataLength := packet.columnCount*4 + 2
		for i := 0; i < packet.columnCount; i++ {
			newDataLength += packet.Columns[i].Length()
		}
		packet.descriptionBuf.Reset()
		packet.descriptionBuf.Grow(newDataLength)
		columnCountBuf := make([]byte, 2)
		binary.BigEndian.PutUint16(columnCountBuf, uint16(packet.columnCount))
		packet.descriptionBuf.Write(columnCountBuf)
		for i := 0; i < packet.columnCount; i++ {
			packet.descriptionBuf.Write(packet.Columns[i].LengthBuf[:])
			if !packet.Columns[i].IsNull() {
				packet.descriptionBuf.Write(packet.Columns[i].data.Encoded())
			}
		}
		packet.updatePacketLength(newDataLength)
	}
}