...
1 package pgproto3
2
3 import (
4 "bytes"
5 "encoding/binary"
6 "encoding/json"
7 "errors"
8 "math"
9
10 "github.com/jackc/pgio"
11 )
12
13 type Parse struct {
14 Name string
15 Query string
16 ParameterOIDs []uint32
17 }
18
19
20 func (*Parse) Frontend() {}
21
22
23
24 func (dst *Parse) Decode(src []byte) error {
25 *dst = Parse{}
26
27 buf := bytes.NewBuffer(src)
28
29 b, err := buf.ReadBytes(0)
30 if err != nil {
31 return err
32 }
33 dst.Name = string(b[:len(b)-1])
34
35 b, err = buf.ReadBytes(0)
36 if err != nil {
37 return err
38 }
39 dst.Query = string(b[:len(b)-1])
40
41 if buf.Len() < 2 {
42 return &invalidMessageFormatErr{messageType: "Parse"}
43 }
44 parameterOIDCount := int(binary.BigEndian.Uint16(buf.Next(2)))
45
46 for i := 0; i < parameterOIDCount; i++ {
47 if buf.Len() < 4 {
48 return &invalidMessageFormatErr{messageType: "Parse"}
49 }
50 dst.ParameterOIDs = append(dst.ParameterOIDs, binary.BigEndian.Uint32(buf.Next(4)))
51 }
52
53 return nil
54 }
55
56
57 func (src *Parse) Encode(dst []byte) ([]byte, error) {
58 dst, sp := beginMessage(dst, 'P')
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 if len(src.ParameterOIDs) > math.MaxUint16 {
66 return nil, errors.New("too many parameter oids")
67 }
68 dst = pgio.AppendUint16(dst, uint16(len(src.ParameterOIDs)))
69 for _, oid := range src.ParameterOIDs {
70 dst = pgio.AppendUint32(dst, oid)
71 }
72
73 return finishMessage(dst, sp)
74 }
75
76
77 func (src Parse) MarshalJSON() ([]byte, error) {
78 return json.Marshal(struct {
79 Type string
80 Name string
81 Query string
82 ParameterOIDs []uint32
83 }{
84 Type: "Parse",
85 Name: src.Name,
86 Query: src.Query,
87 ParameterOIDs: src.ParameterOIDs,
88 })
89 }
90
View as plain text