Beispiel #1
0
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
}
Beispiel #2
0
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
}
Beispiel #3
0
// 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()
}
Beispiel #4
0
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
}