mirror of
https://github.com/jackc/pgx.git
synced 2025-05-31 11:42:24 +00:00
79 lines
1.8 KiB
Go
79 lines
1.8 KiB
Go
package binary
|
|
|
|
import (
|
|
"encoding/binary"
|
|
|
|
"github.com/jackc/pgio"
|
|
errors "golang.org/x/xerrors"
|
|
)
|
|
|
|
type RecordFieldIter struct {
|
|
rp int
|
|
src []byte
|
|
}
|
|
|
|
// NewRecordFieldIterator creates iterator over binary representation
|
|
// of record, aka ROW(), aka Composite
|
|
func NewRecordFieldIterator(src []byte) (RecordFieldIter, int, error) {
|
|
rp := 0
|
|
if len(src[rp:]) < 4 {
|
|
return RecordFieldIter{}, 0, errors.Errorf("Record incomplete %v", src)
|
|
}
|
|
|
|
fieldCount := int(int32(binary.BigEndian.Uint32(src[rp:])))
|
|
rp += 4
|
|
|
|
return RecordFieldIter{
|
|
rp: rp,
|
|
src: src,
|
|
}, fieldCount, nil
|
|
}
|
|
|
|
// Next returns next field decoded from record. eof is returned if no
|
|
// more fields left to decode.
|
|
func (fi *RecordFieldIter) Next() (fieldOID uint32, buf []byte, eof bool, err error) {
|
|
if fi.rp == len(fi.src) {
|
|
eof = true
|
|
return
|
|
}
|
|
|
|
if len(fi.src[fi.rp:]) < 8 {
|
|
err = errors.Errorf("Record incomplete %v", fi.src)
|
|
return
|
|
}
|
|
fieldOID = binary.BigEndian.Uint32(fi.src[fi.rp:])
|
|
fi.rp += 4
|
|
|
|
fieldLen := int(int32(binary.BigEndian.Uint32(fi.src[fi.rp:])))
|
|
fi.rp += 4
|
|
|
|
if fieldLen >= 0 {
|
|
if len(fi.src[fi.rp:]) < fieldLen {
|
|
err = errors.Errorf("Record incomplete rp=%d src=%v", fi.rp, fi.src)
|
|
return
|
|
}
|
|
buf = fi.src[fi.rp : fi.rp+fieldLen]
|
|
fi.rp += fieldLen
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// RecordStart adds record header to the buf
|
|
func RecordStart(buf []byte, fieldCount int) []byte {
|
|
return pgio.AppendUint32(buf, uint32(fieldCount))
|
|
}
|
|
|
|
// RecordAdd adds record field to the buf
|
|
func RecordAdd(buf []byte, oid uint32, fieldBytes []byte) []byte {
|
|
buf = pgio.AppendUint32(buf, oid)
|
|
buf = pgio.AppendUint32(buf, uint32(len(fieldBytes)))
|
|
buf = append(buf, fieldBytes...)
|
|
return buf
|
|
}
|
|
|
|
// RecordAddNull adds null value as a field to the buf
|
|
func RecordAddNull(buf []byte, oid uint32) []byte {
|
|
return pgio.AppendInt32(buf, int32(-1))
|
|
}
|