Split ReadBinary into ReadBinary/ReadBinaryPtr.

This commit is contained in:
Jae Kwon
2015-06-26 16:43:41 -07:00
parent 9965dd5de6
commit 6781b21d32
5 changed files with 26 additions and 15 deletions

View File

@ -9,7 +9,7 @@ import (
func ReadBinary(o interface{}, r io.Reader, n *int64, err *error) interface{} { func ReadBinary(o interface{}, r io.Reader, n *int64, err *error) interface{} {
rv, rt := reflect.ValueOf(o), reflect.TypeOf(o) rv, rt := reflect.ValueOf(o), reflect.TypeOf(o)
if rv.Kind() == reflect.Ptr { if rv.Kind() == reflect.Ptr {
readReflectBinary(rv.Elem(), rt.Elem(), Options{}, r, n, err) readReflectBinary(rv, rt, Options{}, r, n, err)
return o return o
} else { } else {
ptrRv := reflect.New(rt) ptrRv := reflect.New(rt)
@ -18,12 +18,19 @@ func ReadBinary(o interface{}, r io.Reader, n *int64, err *error) interface{} {
} }
} }
func ReadBinaryPtr(o interface{}, r io.Reader, n *int64, err *error) interface{} {
rv, rt := reflect.ValueOf(o), reflect.TypeOf(o)
if rv.Kind() == reflect.Ptr {
readReflectBinary(rv.Elem(), rt.Elem(), Options{}, r, n, err)
return o
} else {
panic("ReadBinaryPtr expects o to be a pointer")
}
}
func WriteBinary(o interface{}, w io.Writer, n *int64, err *error) { func WriteBinary(o interface{}, w io.Writer, n *int64, err *error) {
rv := reflect.ValueOf(o) rv := reflect.ValueOf(o)
rt := reflect.TypeOf(o) rt := reflect.TypeOf(o)
if rv.Kind() == reflect.Ptr {
rv, rt = rv.Elem(), rt.Elem()
}
writeReflectBinary(rv, rt, Options{}, w, n, err) writeReflectBinary(rv, rt, Options{}, w, n, err)
} }

View File

@ -226,6 +226,9 @@ func readReflectBinary(rv reflect.Value, rt reflect.Type, opts Options, r io.Rea
typeInfo = GetTypeInfo(rt) typeInfo = GetTypeInfo(rt)
if typeInfo.Byte != 0x00 { if typeInfo.Byte != 0x00 {
r = NewPrefixedReader([]byte{typeByte}, r) r = NewPrefixedReader([]byte{typeByte}, r)
} else if typeByte != 0x01 {
*err = errors.New(Fmt("Unexpected type byte %X for ptr of untyped thing", typeByte))
return
} }
// continue... // continue...
} }
@ -250,7 +253,7 @@ func readReflectBinary(rv reflect.Value, rt reflect.Type, opts Options, r io.Rea
} else { } else {
var sliceRv reflect.Value var sliceRv reflect.Value
// Read length // Read length
length := int(ReadUvarint(r, n, err)) length := ReadVarint(r, n, err)
log.Debug(Fmt("Read length: %v", length)) log.Debug(Fmt("Read length: %v", length))
sliceRv = reflect.MakeSlice(rt, 0, 0) sliceRv = reflect.MakeSlice(rt, 0, 0)
// read one ReflectSliceChunk at a time and append // read one ReflectSliceChunk at a time and append
@ -322,7 +325,7 @@ func readReflectBinary(rv reflect.Value, rt reflect.Type, opts Options, r io.Rea
case reflect.Uint64: case reflect.Uint64:
if opts.Varint { if opts.Varint {
num := ReadUvarint(r, n, err) num := ReadVarint(r, n, err)
log.Debug(Fmt("Read num: %v", num)) log.Debug(Fmt("Read num: %v", num))
rv.SetUint(uint64(num)) rv.SetUint(uint64(num))
} else { } else {
@ -347,7 +350,7 @@ func readReflectBinary(rv reflect.Value, rt reflect.Type, opts Options, r io.Rea
rv.SetUint(uint64(num)) rv.SetUint(uint64(num))
case reflect.Uint: case reflect.Uint:
num := ReadUvarint(r, n, err) num := ReadVarint(r, n, err)
log.Debug(Fmt("Read num: %v", num)) log.Debug(Fmt("Read num: %v", num))
rv.SetUint(uint64(num)) rv.SetUint(uint64(num))

View File

@ -72,13 +72,14 @@ func TestAnimalInterface(t *testing.T) {
ptr := reflect.New(rte).Interface() ptr := reflect.New(rte).Interface()
fmt.Printf("ptr: %v", ptr) fmt.Printf("ptr: %v", ptr)
// Make a binary byteslice that represents a snake. // Make a binary byteslice that represents a *snake.
snakeBytes := BinaryBytes(Snake([]byte("snake"))) foo = Snake([]byte("snake"))
snakeBytes := BinaryBytes(foo)
snakeReader := bytes.NewReader(snakeBytes) snakeReader := bytes.NewReader(snakeBytes)
// Now you can read it. // Now you can read it.
n, err := new(int64), new(error) n, err := new(int64), new(error)
it := *ReadBinary(ptr, snakeReader, n, err).(*Animal) it := ReadBinary(foo, snakeReader, n, err).(Animal)
fmt.Println(it, reflect.TypeOf(it)) fmt.Println(it, reflect.TypeOf(it))
} }
@ -374,7 +375,7 @@ func TestBinary(t *testing.T) {
// Read onto a pointer // Read onto a pointer
n, err = new(int64), new(error) n, err = new(int64), new(error)
res = ReadBinary(instancePtr, bytes.NewReader(data), n, err) res = ReadBinaryPtr(instancePtr, bytes.NewReader(data), n, err)
if *err != nil { if *err != nil {
t.Fatalf("Failed to read into instance: %v", *err) t.Fatalf("Failed to read into instance: %v", *err)
} }

View File

@ -5,16 +5,16 @@ import "io"
// String // String
func WriteString(s string, w io.Writer, n *int64, err *error) { func WriteString(s string, w io.Writer, n *int64, err *error) {
WriteUvarint(uint(len(s)), w, n, err) WriteVarint(len(s), w, n, err)
WriteTo([]byte(s), w, n, err) WriteTo([]byte(s), w, n, err)
} }
func ReadString(r io.Reader, n *int64, err *error) string { func ReadString(r io.Reader, n *int64, err *error) string {
length := ReadUvarint(r, n, err) length := ReadVarint(r, n, err)
if *err != nil { if *err != nil {
return "" return ""
} }
buf := make([]byte, int(length)) buf := make([]byte, length)
ReadFull(buf, r, n, err) ReadFull(buf, r, n, err)
return string(buf) return string(buf)
} }

View File

@ -403,7 +403,7 @@ FOR_LOOP:
log.Debug("Receive Pong") log.Debug("Receive Pong")
case packetTypeMsg: case packetTypeMsg:
pkt, n, err := msgPacket{}, new(int64), new(error) pkt, n, err := msgPacket{}, new(int64), new(error)
binary.ReadBinary(&pkt, c.bufReader, n, err) binary.ReadBinaryPtr(&pkt, c.bufReader, n, err)
c.recvMonitor.Update(int(*n)) c.recvMonitor.Update(int(*n))
if *err != nil { if *err != nil {
if atomic.LoadUint32(&c.stopped) != 1 { if atomic.LoadUint32(&c.stopped) != 1 {