package pgproto3
import (
"encoding/binary"
"encoding/hex"
"encoding/json"
"github.com/jackc/pgx/v5/internal/pgio"
)
type DataRow struct {
Values [][]byte
}
func (*DataRow ) Backend () {}
func (dst *DataRow ) Decode (src []byte ) error {
if len (src ) < 2 {
return &invalidMessageFormatErr {messageType : "DataRow" }
}
rp := 0
fieldCount := int (binary .BigEndian .Uint16 (src [rp :]))
rp += 2
if cap (dst .Values ) < fieldCount || cap (dst .Values )-fieldCount > 32 {
newCap := 32
if newCap < fieldCount {
newCap = fieldCount
}
dst .Values = make ([][]byte , fieldCount , newCap )
} else {
dst .Values = dst .Values [:fieldCount ]
}
for i := 0 ; i < fieldCount ; i ++ {
if len (src [rp :]) < 4 {
return &invalidMessageFormatErr {messageType : "DataRow" }
}
valueLen := int (int32 (binary .BigEndian .Uint32 (src [rp :])))
rp += 4
if valueLen == -1 {
dst .Values [i ] = nil
} else {
if len (src [rp :]) < valueLen || valueLen < 0 {
return &invalidMessageFormatErr {messageType : "DataRow" }
}
dst .Values [i ] = src [rp : rp +valueLen : rp +valueLen ]
rp += valueLen
}
}
return nil
}
func (src *DataRow ) Encode (dst []byte ) []byte {
dst = append (dst , 'D' )
sp := len (dst )
dst = pgio .AppendInt32 (dst , -1 )
dst = pgio .AppendUint16 (dst , uint16 (len (src .Values )))
for _ , v := range src .Values {
if v == nil {
dst = pgio .AppendInt32 (dst , -1 )
continue
}
dst = pgio .AppendInt32 (dst , int32 (len (v )))
dst = append (dst , v ...)
}
pgio .SetInt32 (dst [sp :], int32 (len (dst [sp :])))
return dst
}
func (src DataRow ) MarshalJSON () ([]byte , error ) {
formattedValues := make ([]map [string ]string , len (src .Values ))
for i , v := range src .Values {
if v == nil {
continue
}
var hasNonPrintable bool
for _ , b := range v {
if b < 32 {
hasNonPrintable = true
break
}
}
if hasNonPrintable {
formattedValues [i ] = map [string ]string {"binary" : hex .EncodeToString (v )}
} else {
formattedValues [i ] = map [string ]string {"text" : string (v )}
}
}
return json .Marshal (struct {
Type string
Values []map [string ]string
}{
Type : "DataRow" ,
Values : formattedValues ,
})
}
func (dst *DataRow ) UnmarshalJSON (data []byte ) error {
if string (data ) == "null" {
return nil
}
var msg struct {
Values []map [string ]string
}
if err := json .Unmarshal (data , &msg ); err != nil {
return err
}
dst .Values = make ([][]byte , len (msg .Values ))
for n , parameter := range msg .Values {
var err error
dst .Values [n ], err = getValueFromJSON (parameter )
if err != nil {
return err
}
}
return nil
}
The pages are generated with Golds v0.6.7 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds .