From 226142ae1b0adeeaa7edab858ce768063a1f6e22 Mon Sep 17 00:00:00 2001 From: Jack Christensen <jack@jackchristensen.com> Date: Sat, 30 Mar 2013 19:57:37 -0500 Subject: [PATCH] Added rxMsg* --- conn.go | 76 +++++++++++++++++++++++++++++++++++++++++++++++------ messages.go | 4 +++ 2 files changed, 72 insertions(+), 8 deletions(-) diff --git a/conn.go b/conn.go index 0a582541..f3716451 100644 --- a/conn.go +++ b/conn.go @@ -2,11 +2,15 @@ package pqx import ( "encoding/binary" + "errors" + "fmt" + "io" "net" ) type conn struct { - conn net.Conn + conn net.Conn // the underlying TCP or unix domain socket connection + buf []byte // work buffer to avoid constant alloc and dealloc } func Connect(options map[string]string) (c *conn, err error) { @@ -22,19 +26,75 @@ func Connect(options map[string]string) (c *conn, err error) { } } + c.buf = make([]byte, 1024) + // conn, err := net.Dial("tcp", "localhost:5432") msg := newStartupMessage() msg.options["user"] = "jack" c.conn.Write(msg.Bytes()) - buf := make([]byte, 512) - - num, _ := c.conn.Read(buf) - println(string(buf[0:1])) - println(binary.BigEndian.Uint32(buf[1:5])) - println(binary.BigEndian.Uint32(buf[5:9])) - println(num) + var response interface{} + response, err = c.rxMsg() + fmt.Println(err) + fmt.Println(response) return c, nil } + +func (c *conn) rxMsg() (msg interface{}, err error) { + var t byte + var bodySize int32 + t, bodySize, err = c.rxMsgHeader() + if err != nil { + return nil, err + } + + var buf []byte + if buf, err = c.rxMsgBody(bodySize); err != nil { + return nil, err + } + + switch t { + case 'R': + return c.rxAuthenticationX(buf) + default: + return nil, errors.New("Received unknown message type") + } + + panic("Unreachable") +} + +func (c *conn) rxMsgHeader() (t byte, bodySize int32, err error) { + buf := c.buf[:5] + if _, err = io.ReadFull(c.conn, buf); err != nil { + return 0, 0, err + } + + t = buf[0] + bodySize = int32(binary.BigEndian.Uint32(buf[1:5])) - 4 + return t, bodySize, nil +} + +func (c *conn) rxMsgBody(bodySize int32) (buf []byte, err error) { + if int(bodySize) <= cap(c.buf) { + buf = c.buf[:bodySize] + } else { + buf = make([]byte, bodySize) + } + + _, err = io.ReadFull(c.conn, buf) + return +} + +func (c *conn) rxAuthenticationX(buf []byte) (msg interface{}, err error) { + code := binary.BigEndian.Uint32(buf[:4]) + switch code { + case 0: + return &authenticationOk{}, nil + default: + return nil, errors.New("Received unknown authentication message") + } + + panic("Unreachable") +} diff --git a/messages.go b/messages.go index b6e6f907..0ecb9bed 100644 --- a/messages.go +++ b/messages.go @@ -32,3 +32,7 @@ func (self *startupMessage) Bytes() (buf []byte) { type authenticationOk struct { } + +func (self *authenticationOk) String() string { + return "AuthenticationOk" +}