...
1 package pgproto3
2
3 import (
4 "encoding/binary"
5 "encoding/hex"
6 "encoding/json"
7
8 "github.com/jackc/pgx/v5/internal/pgio"
9 )
10
11 type FunctionCallResponse struct {
12 Result []byte
13 }
14
15
16 func (*FunctionCallResponse) Backend() {}
17
18
19
20 func (dst *FunctionCallResponse) Decode(src []byte) error {
21 if len(src) < 4 {
22 return &invalidMessageFormatErr{messageType: "FunctionCallResponse"}
23 }
24 rp := 0
25 resultSize := int(binary.BigEndian.Uint32(src[rp:]))
26 rp += 4
27
28 if resultSize == -1 {
29 dst.Result = nil
30 return nil
31 }
32
33 if len(src[rp:]) != resultSize {
34 return &invalidMessageFormatErr{messageType: "FunctionCallResponse"}
35 }
36
37 dst.Result = src[rp:]
38 return nil
39 }
40
41
42 func (src *FunctionCallResponse) Encode(dst []byte) ([]byte, error) {
43 dst, sp := beginMessage(dst, 'V')
44
45 if src.Result == nil {
46 dst = pgio.AppendInt32(dst, -1)
47 } else {
48 dst = pgio.AppendInt32(dst, int32(len(src.Result)))
49 dst = append(dst, src.Result...)
50 }
51
52 return finishMessage(dst, sp)
53 }
54
55
56 func (src FunctionCallResponse) MarshalJSON() ([]byte, error) {
57 var formattedValue map[string]string
58 var hasNonPrintable bool
59 for _, b := range src.Result {
60 if b < 32 {
61 hasNonPrintable = true
62 break
63 }
64 }
65
66 if hasNonPrintable {
67 formattedValue = map[string]string{"binary": hex.EncodeToString(src.Result)}
68 } else {
69 formattedValue = map[string]string{"text": string(src.Result)}
70 }
71
72 return json.Marshal(struct {
73 Type string
74 Result map[string]string
75 }{
76 Type: "FunctionCallResponse",
77 Result: formattedValue,
78 })
79 }
80
81
82 func (dst *FunctionCallResponse) UnmarshalJSON(data []byte) error {
83
84 if string(data) == "null" {
85 return nil
86 }
87
88 var msg struct {
89 Result map[string]string
90 }
91 err := json.Unmarshal(data, &msg)
92 if err != nil {
93 return err
94 }
95 dst.Result, err = getValueFromJSON(msg.Result)
96 return err
97 }
98
View as plain text