...
1 package pgproto3
2
3 import (
4 "encoding/hex"
5 "errors"
6 "fmt"
7
8 "github.com/jackc/pgio"
9 )
10
11
12
13 const maxMessageBodyLen = (0x3fffffff - 1)
14
15
16
17 type Message interface {
18
19
20 Decode(data []byte) error
21
22
23 Encode(dst []byte) ([]byte, error)
24 }
25
26 type FrontendMessage interface {
27 Message
28 Frontend()
29 }
30
31 type BackendMessage interface {
32 Message
33 Backend()
34 }
35
36 type AuthenticationResponseMessage interface {
37 BackendMessage
38 AuthenticationResponse()
39 }
40
41 type invalidMessageLenErr struct {
42 messageType string
43 expectedLen int
44 actualLen int
45 }
46
47 func (e *invalidMessageLenErr) Error() string {
48 return fmt.Sprintf("%s body must have length of %d, but it is %d", e.messageType, e.expectedLen, e.actualLen)
49 }
50
51 type invalidMessageFormatErr struct {
52 messageType string
53 }
54
55 func (e *invalidMessageFormatErr) Error() string {
56 return fmt.Sprintf("%s body is invalid", e.messageType)
57 }
58
59
60 func getValueFromJSON(v map[string]string) ([]byte, error) {
61 if v == nil {
62 return nil, nil
63 }
64 if text, ok := v["text"]; ok {
65 return []byte(text), nil
66 }
67 if binary, ok := v["binary"]; ok {
68 return hex.DecodeString(binary)
69 }
70 return nil, errors.New("unknown protocol representation")
71 }
72
73
74
75 func beginMessage(dst []byte, t byte) ([]byte, int) {
76 dst = append(dst, t)
77 sp := len(dst)
78 dst = pgio.AppendInt32(dst, -1)
79 return dst, sp
80 }
81
82
83
84 func finishMessage(dst []byte, sp int) ([]byte, error) {
85 messageBodyLen := len(dst[sp:])
86 if messageBodyLen > maxMessageBodyLen {
87 return nil, errors.New("message body too large")
88 }
89 pgio.SetInt32(dst[sp:], int32(messageBodyLen))
90 return dst, nil
91 }
92
View as plain text