github.com/jackc/pgx/v5@v5.5.5/pgproto3/function_call_response.go (about) 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 // Backend identifies this message as sendable by the PostgreSQL backend. 16 func (*FunctionCallResponse) Backend() {} 17 18 // Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message 19 // type identifier and 4 byte message length. 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 // Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. 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 // MarshalJSON implements encoding/json.Marshaler. 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 // UnmarshalJSON implements encoding/json.Unmarshaler. 82 func (dst *FunctionCallResponse) UnmarshalJSON(data []byte) error { 83 // Ignore null, like in the main JSON package. 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 }