gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

parse.go (2017B)


      1 package pgproto3
      2 
      3 import (
      4 	"bytes"
      5 	"encoding/binary"
      6 	"encoding/json"
      7 
      8 	"github.com/jackc/pgio"
      9 )
     10 
     11 type Parse struct {
     12 	Name          string
     13 	Query         string
     14 	ParameterOIDs []uint32
     15 }
     16 
     17 // Frontend identifies this message as sendable by a PostgreSQL frontend.
     18 func (*Parse) Frontend() {}
     19 
     20 // Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message
     21 // type identifier and 4 byte message length.
     22 func (dst *Parse) Decode(src []byte) error {
     23 	*dst = Parse{}
     24 
     25 	buf := bytes.NewBuffer(src)
     26 
     27 	b, err := buf.ReadBytes(0)
     28 	if err != nil {
     29 		return err
     30 	}
     31 	dst.Name = string(b[:len(b)-1])
     32 
     33 	b, err = buf.ReadBytes(0)
     34 	if err != nil {
     35 		return err
     36 	}
     37 	dst.Query = string(b[:len(b)-1])
     38 
     39 	if buf.Len() < 2 {
     40 		return &invalidMessageFormatErr{messageType: "Parse"}
     41 	}
     42 	parameterOIDCount := int(binary.BigEndian.Uint16(buf.Next(2)))
     43 
     44 	for i := 0; i < parameterOIDCount; i++ {
     45 		if buf.Len() < 4 {
     46 			return &invalidMessageFormatErr{messageType: "Parse"}
     47 		}
     48 		dst.ParameterOIDs = append(dst.ParameterOIDs, binary.BigEndian.Uint32(buf.Next(4)))
     49 	}
     50 
     51 	return nil
     52 }
     53 
     54 // Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.
     55 func (src *Parse) Encode(dst []byte) []byte {
     56 	dst = append(dst, 'P')
     57 	sp := len(dst)
     58 	dst = pgio.AppendInt32(dst, -1)
     59 
     60 	dst = append(dst, src.Name...)
     61 	dst = append(dst, 0)
     62 	dst = append(dst, src.Query...)
     63 	dst = append(dst, 0)
     64 
     65 	dst = pgio.AppendUint16(dst, uint16(len(src.ParameterOIDs)))
     66 	for _, oid := range src.ParameterOIDs {
     67 		dst = pgio.AppendUint32(dst, oid)
     68 	}
     69 
     70 	pgio.SetInt32(dst[sp:], int32(len(dst[sp:])))
     71 
     72 	return dst
     73 }
     74 
     75 // MarshalJSON implements encoding/json.Marshaler.
     76 func (src Parse) MarshalJSON() ([]byte, error) {
     77 	return json.Marshal(struct {
     78 		Type          string
     79 		Name          string
     80 		Query         string
     81 		ParameterOIDs []uint32
     82 	}{
     83 		Type:          "Parse",
     84 		Name:          src.Name,
     85 		Query:         src.Query,
     86 		ParameterOIDs: src.ParameterOIDs,
     87 	})
     88 }