Make MessageReader a type of bytes.Buffer

scan-io
Jack Christensen 2014-06-26 18:12:30 -05:00
parent 3706b9519f
commit 84dd626bcc
2 changed files with 10 additions and 78 deletions

View File

@ -497,7 +497,7 @@ func (c *Conn) SelectValueTo(w io.Writer, sql string, arguments ...interface{})
return err return err
} }
r := newMessageReader(body) r := (*MessageReader)(body)
switch t { switch t {
case readyForQuery: case readyForQuery:
c.rxReadyForQuery(r) c.rxReadyForQuery(r)
@ -950,7 +950,7 @@ func (c *Conn) rxMsg() (t byte, r *MessageReader, err error) {
return return
} }
r = newMessageReader(body) r = (*MessageReader)(body)
return return
} }

View File

@ -3,113 +3,45 @@ package pgx
import ( import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"fmt"
) )
// MessageReader is a helper that reads values from a PostgreSQL message. // MessageReader is a helper that reads values from a PostgreSQL message.
// To avoid verbose error handling it internally records errors and no-ops type MessageReader bytes.Buffer
// any calls that occur after an error. At the end of a sequence of reads
// the Err field should be checked to see if any errors occurred.
type MessageReader struct {
buf *bytes.Buffer
Err error
}
func newMessageReader(buf *bytes.Buffer) *MessageReader {
return &MessageReader{buf: buf}
}
func (r *MessageReader) ReadByte() (b byte) { func (r *MessageReader) ReadByte() (b byte) {
if r.Err != nil { b, _ = (*bytes.Buffer)(r).ReadByte()
return
}
b, r.Err = r.buf.ReadByte()
return return
} }
func (r *MessageReader) ReadInt16() (n int16) { func (r *MessageReader) ReadInt16() (n int16) {
if r.Err != nil { b := (*bytes.Buffer)(r).Next(2)
return
}
size := 2
b := r.buf.Next(size)
if len(b) != size {
r.Err = fmt.Errorf("Unable to read %d bytes, only read %d", size, len(b))
}
return int16(binary.BigEndian.Uint16(b)) return int16(binary.BigEndian.Uint16(b))
} }
func (r *MessageReader) ReadInt32() (n int32) { func (r *MessageReader) ReadInt32() (n int32) {
if r.Err != nil { b := (*bytes.Buffer)(r).Next(4)
return
}
size := 4
b := r.buf.Next(size)
if len(b) != size {
r.Err = fmt.Errorf("Unable to read %d bytes, only read %d", size, len(b))
}
return int32(binary.BigEndian.Uint32(b)) return int32(binary.BigEndian.Uint32(b))
} }
func (r *MessageReader) ReadInt64() (n int64) { func (r *MessageReader) ReadInt64() (n int64) {
if r.Err != nil { b := (*bytes.Buffer)(r).Next(8)
return
}
size := 8
b := r.buf.Next(size)
if len(b) != size {
r.Err = fmt.Errorf("Unable to read %d bytes, only read %d", size, len(b))
}
return int64(binary.BigEndian.Uint64(b)) return int64(binary.BigEndian.Uint64(b))
} }
func (r *MessageReader) ReadOid() (oid Oid) { func (r *MessageReader) ReadOid() (oid Oid) {
if r.Err != nil { b := (*bytes.Buffer)(r).Next(4)
return
}
size := 4
b := r.buf.Next(size)
if len(b) != size {
r.Err = fmt.Errorf("Unable to read %d bytes, only read %d", size, len(b))
}
return Oid(binary.BigEndian.Uint32(b)) return Oid(binary.BigEndian.Uint32(b))
} }
// ReadString reads a null terminated string // ReadString reads a null terminated string
func (r *MessageReader) ReadCString() (s string) { func (r *MessageReader) ReadCString() (s string) {
if r.Err != nil { b, _ := (*bytes.Buffer)(r).ReadBytes(0)
return
}
var b []byte
b, r.Err = r.buf.ReadBytes(0)
if r.Err != nil {
return
}
return string(b[:len(b)-1]) return string(b[:len(b)-1])
} }
// ReadString reads count bytes and returns as string // ReadString reads count bytes and returns as string
func (r *MessageReader) ReadString(count int32) (s string) { func (r *MessageReader) ReadString(count int32) (s string) {
if r.Err != nil {
return
}
size := int(count) size := int(count)
b := r.buf.Next(size) b := (*bytes.Buffer)(r).Next(size)
if len(b) != size {
r.Err = fmt.Errorf("Unable to read %d bytes, only read %d", size, len(b))
}
return string(b) return string(b)
} }