func ReadDataRow(m *Message) (*DataRow, error) { if t := m.MsgType(); t != MsgDataRowD { return nil, e.BadTypeCode(t) } b := m.Payload() fieldCount, err := ReadUint16(b) if err != nil { return nil, err } values := make([][]byte, fieldCount) for i := range values { fieldLen, err := ReadInt32(b) if err != nil { return nil, err } if fieldLen >= 0 { fieldData := make([]byte, fieldLen) io.ReadFull(b, fieldData) values[i] = fieldData } else if fieldLen == -1 { values[i] = nil } else { return nil, e.WrongSize("Invalid length %v for field %v", fieldLen, i) } } return &DataRow{values}, nil }
func ReadCancelRequest(m *Message) (*CancelRequest, error) { var err error body, err := readFirst(m) if size := m.Size() - 4; size != 12 { return nil, e.WrongSize( "expected CancelRequest to be 12 bytes; got %v", size, ) } var b Reader b.InitReader(body) if code, _ := ReadUint32(&b); code != 80877102 { return nil, fmt.Errorf( "expected cancel message code 80877102; got %v", code, ) } bePid, err := ReadUint32(&b) if err != nil { return nil, err } secret, err := ReadUint32(&b) if err != nil { return nil, err } return &CancelRequest{BackendPid: bePid, SecretKey: secret}, nil }
// Read the first message from a client: either a StartupMessage or a CancelRequest func readFirst(m *Message) ([]byte, error) { if remainingSz := m.Size() - 4; remainingSz > 10000 { // Startup packets longer than this are considered // invalid. Copied from the PostgreSQL source code. err := e.TooBig( "Rejecting oversized startup packet: got %v", m.Size()) return nil, err } else if remainingSz < 4 { // We expect all initialization messages to // have at least a 4-byte header err := e.WrongSize( "Expected message of at least 4 bytes; got %v", remainingSz) return nil, err } return m.Force() }
func ReadBackendKeyData(msg *Message) (*BackendKeyData, error) { if t := msg.MsgType(); t != MsgBackendKeyDataK { return nil, e.BadTypeCode(t) } const RIGHT_SZ = 12 if msg.Size() != RIGHT_SZ { return nil, e.WrongSize("BackendKeyData is wrong size: "+ "expected %v, got %v", RIGHT_SZ, msg.Size()) } r := msg.Payload() pid, err := ReadUint32(r) if err != nil { return nil, err } key, err := ReadUint32(r) if err != nil { return nil, err } return &BackendKeyData{BackendPid: pid, SecretKey: key}, err }