Commit 5aa17455 authored by Rob Pike's avatar Rob Pike

clean up for public use: make some stuff private, add doc comments.

R=rsc
DELTA=298  (202 added, 0 deleted, 96 changed)
OCL=32006
CL=32224
parent 3ff5e727
...@@ -36,6 +36,7 @@ var encodeT = []EncodeT { ...@@ -36,6 +36,7 @@ var encodeT = []EncodeT {
EncodeT{ 1<<63, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81} }, EncodeT{ 1<<63, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81} },
} }
// Test basic encode/decode routines for unsigned integers // Test basic encode/decode routines for unsigned integers
func TestUintCodec(t *testing.T) { func TestUintCodec(t *testing.T) {
b := new(bytes.Buffer); b := new(bytes.Buffer);
...@@ -552,7 +553,7 @@ func TestEndToEnd(t *testing.T) { ...@@ -552,7 +553,7 @@ func TestEndToEnd(t *testing.T) {
b := new(bytes.Buffer); b := new(bytes.Buffer);
encode(b, t1); encode(b, t1);
var _t1 T1; var _t1 T1;
decode(b, getTypeInfo(reflect.Typeof(_t1)).typeId, &_t1); decode(b, getTypeInfo(reflect.Typeof(_t1)).id, &_t1);
if !reflect.DeepEqual(t1, &_t1) { if !reflect.DeepEqual(t1, &_t1) {
t.Errorf("encode expected %v got %v", *t1, _t1); t.Errorf("encode expected %v got %v", *t1, _t1);
} }
...@@ -570,7 +571,7 @@ func TestNesting(t *testing.T) { ...@@ -570,7 +571,7 @@ func TestNesting(t *testing.T) {
b := new(bytes.Buffer); b := new(bytes.Buffer);
encode(b, rt); encode(b, rt);
var drt RT; var drt RT;
decode(b, getTypeInfo(reflect.Typeof(drt)).typeId, &drt); decode(b, getTypeInfo(reflect.Typeof(drt)).id, &drt);
if drt.a != rt.a { if drt.a != rt.a {
t.Errorf("nesting: encode expected %v got %v", *rt, drt); t.Errorf("nesting: encode expected %v got %v", *rt, drt);
} }
...@@ -612,7 +613,7 @@ func TestAutoIndirection(t *testing.T) { ...@@ -612,7 +613,7 @@ func TestAutoIndirection(t *testing.T) {
b := new(bytes.Buffer); b := new(bytes.Buffer);
encode(b, t1); encode(b, t1);
var t0 T0; var t0 T0;
t0Id := getTypeInfo(reflect.Typeof(t0)).typeId; t0Id := getTypeInfo(reflect.Typeof(t0)).id;
decode(b, t0Id, &t0); decode(b, t0Id, &t0);
if t0.a != 17 || t0.b != 177 || t0.c != 1777 || t0.d != 17777 { if t0.a != 17 || t0.b != 177 || t0.c != 1777 || t0.d != 17777 {
t.Errorf("t1->t0: expected {17 177 1777 17777}; got %v", t0); t.Errorf("t1->t0: expected {17 177 1777 17777}; got %v", t0);
...@@ -637,7 +638,7 @@ func TestAutoIndirection(t *testing.T) { ...@@ -637,7 +638,7 @@ func TestAutoIndirection(t *testing.T) {
b.Reset(); b.Reset();
encode(b, t0); encode(b, t0);
t1 = T1{}; t1 = T1{};
t1Id := getTypeInfo(reflect.Typeof(t1)).typeId; t1Id := getTypeInfo(reflect.Typeof(t1)).id;
decode(b, t1Id, &t1); decode(b, t1Id, &t1);
if t1.a != 17 || *t1.b != 177 || **t1.c != 1777 || ***t1.d != 17777 { if t1.a != 17 || *t1.b != 177 || **t1.c != 1777 || ***t1.d != 17777 {
t.Errorf("t0->t1 expected {17 177 1777 17777}; got {%d %d %d %d}", t1.a, *t1.b, **t1.c, ***t1.d); t.Errorf("t0->t1 expected {17 177 1777 17777}; got {%d %d %d %d}", t1.a, *t1.b, **t1.c, ***t1.d);
...@@ -647,7 +648,7 @@ func TestAutoIndirection(t *testing.T) { ...@@ -647,7 +648,7 @@ func TestAutoIndirection(t *testing.T) {
b.Reset(); b.Reset();
encode(b, t0); encode(b, t0);
t2 = T2{}; t2 = T2{};
t2Id := getTypeInfo(reflect.Typeof(t2)).typeId; t2Id := getTypeInfo(reflect.Typeof(t2)).id;
decode(b, t2Id, &t2); decode(b, t2Id, &t2);
if ***t2.a != 17 || **t2.b != 177 || *t2.c != 1777 || t2.d != 17777 { if ***t2.a != 17 || **t2.b != 177 || *t2.c != 1777 || t2.d != 17777 {
t.Errorf("t0->t2 expected {17 177 1777 17777}; got {%d %d %d %d}", ***t2.a, **t2.b, *t2.c, t2.d); t.Errorf("t0->t2 expected {17 177 1777 17777}; got {%d %d %d %d}", ***t2.a, **t2.b, *t2.c, t2.d);
...@@ -685,7 +686,7 @@ func TestReorderedFields(t *testing.T) { ...@@ -685,7 +686,7 @@ func TestReorderedFields(t *testing.T) {
rt0.c = 3.14159; rt0.c = 3.14159;
b := new(bytes.Buffer); b := new(bytes.Buffer);
encode(b, rt0); encode(b, rt0);
rt0Id := getTypeInfo(reflect.Typeof(rt0)).typeId; rt0Id := getTypeInfo(reflect.Typeof(rt0)).id;
var rt1 RT1; var rt1 RT1;
// Wire type is RT0, local type is RT1. // Wire type is RT0, local type is RT1.
decode(b, rt0Id, &rt1); decode(b, rt0Id, &rt1);
...@@ -723,7 +724,7 @@ func TestIgnoredFields(t *testing.T) { ...@@ -723,7 +724,7 @@ func TestIgnoredFields(t *testing.T) {
b := new(bytes.Buffer); b := new(bytes.Buffer);
encode(b, it0); encode(b, it0);
rt0Id := getTypeInfo(reflect.Typeof(it0)).typeId; rt0Id := getTypeInfo(reflect.Typeof(it0)).id;
var rt1 RT1; var rt1 RT1;
// Wire type is IT0, local type is RT1. // Wire type is IT0, local type is RT1.
err := decode(b, rt0Id, &rt1); err := decode(b, rt0Id, &rt1);
......
...@@ -18,8 +18,8 @@ import ( ...@@ -18,8 +18,8 @@ import (
) )
var ( var (
ErrRange = os.ErrorString("gob: internal error: field numbers out of bounds"); errRange = os.ErrorString("gob: internal error: field numbers out of bounds");
ErrNotStruct = os.ErrorString("gob: TODO: can only handle structs") errNotStruct = os.ErrorString("gob: TODO: can only handle structs")
) )
// The global execution state of an instance of the decoder. // The global execution state of an instance of the decoder.
...@@ -347,7 +347,7 @@ func decodeStruct(engine *decEngine, rtyp *reflect.StructType, b *bytes.Buffer, ...@@ -347,7 +347,7 @@ func decodeStruct(engine *decEngine, rtyp *reflect.StructType, b *bytes.Buffer,
} }
fieldnum := state.fieldnum + delta; fieldnum := state.fieldnum + delta;
if fieldnum >= len(engine.instr) { if fieldnum >= len(engine.instr) {
state.err = ErrRange; state.err = errRange;
break; break;
} }
instr := &engine.instr[fieldnum]; instr := &engine.instr[fieldnum];
...@@ -376,7 +376,7 @@ func ignoreStruct(engine *decEngine, b *bytes.Buffer) os.Error { ...@@ -376,7 +376,7 @@ func ignoreStruct(engine *decEngine, b *bytes.Buffer) os.Error {
} }
fieldnum := state.fieldnum + delta; fieldnum := state.fieldnum + delta;
if fieldnum >= len(engine.instr) { if fieldnum >= len(engine.instr) {
state.err = ErrRange; state.err = errRange;
break; break;
} }
instr := &engine.instr[fieldnum]; instr := &engine.instr[fieldnum];
...@@ -474,7 +474,7 @@ var decOpMap = map[reflect.Type] decOp { ...@@ -474,7 +474,7 @@ var decOpMap = map[reflect.Type] decOp {
reflect.Typeof((*reflect.StringType)(nil)): decString, reflect.Typeof((*reflect.StringType)(nil)): decString,
} }
var decIgnoreOpMap = map[TypeId] decOp { var decIgnoreOpMap = map[typeId] decOp {
tBool: ignoreUint, tBool: ignoreUint,
tInt: ignoreUint, tInt: ignoreUint,
tUint: ignoreUint, tUint: ignoreUint,
...@@ -483,12 +483,12 @@ var decIgnoreOpMap = map[TypeId] decOp { ...@@ -483,12 +483,12 @@ var decIgnoreOpMap = map[TypeId] decOp {
tString: ignoreUint8Array, tString: ignoreUint8Array,
} }
func getDecEnginePtr(wireId TypeId, rt reflect.Type) (enginePtr **decEngine, err os.Error) func getDecEnginePtr(wireId typeId, rt reflect.Type) (enginePtr **decEngine, err os.Error)
func getIgnoreEnginePtr(wireId TypeId) (enginePtr **decEngine, err os.Error) func getIgnoreEnginePtr(wireId typeId) (enginePtr **decEngine, err os.Error)
// Return the decoding op for the base type under rt and // Return the decoding op for the base type under rt and
// the indirection count to reach it. // the indirection count to reach it.
func decOpFor(wireId TypeId, rt reflect.Type) (decOp, int, os.Error) { func decOpFor(wireId typeId, rt reflect.Type) (decOp, int, os.Error) {
typ, indir := indirect(rt); typ, indir := indirect(rt);
op, ok := decOpMap[reflect.Typeof(typ)]; op, ok := decOpMap[reflect.Typeof(typ)];
if !ok { if !ok {
...@@ -537,7 +537,7 @@ func decOpFor(wireId TypeId, rt reflect.Type) (decOp, int, os.Error) { ...@@ -537,7 +537,7 @@ func decOpFor(wireId TypeId, rt reflect.Type) (decOp, int, os.Error) {
} }
// Return the decoding op for a field that has no destination. // Return the decoding op for a field that has no destination.
func decIgnoreOpFor(wireId TypeId) (decOp, os.Error) { func decIgnoreOpFor(wireId typeId) (decOp, os.Error) {
op, ok := decIgnoreOpMap[wireId]; op, ok := decIgnoreOpMap[wireId];
if !ok { if !ok {
// Special cases // Special cases
...@@ -583,7 +583,7 @@ func decIgnoreOpFor(wireId TypeId) (decOp, os.Error) { ...@@ -583,7 +583,7 @@ func decIgnoreOpFor(wireId TypeId) (decOp, os.Error) {
// Are these two gob Types compatible? // Are these two gob Types compatible?
// Answers the question for basic types, arrays, and slices. // Answers the question for basic types, arrays, and slices.
// Structs are considered ok; fields will be checked later. // Structs are considered ok; fields will be checked later.
func compatibleType(fr reflect.Type, fw TypeId) bool { func compatibleType(fr reflect.Type, fw typeId) bool {
for { for {
if pt, ok := fr.(*reflect.PtrType); ok { if pt, ok := fr.(*reflect.PtrType); ok {
fr = pt.Elem(); fr = pt.Elem();
...@@ -645,11 +645,11 @@ func compatibleType(fr reflect.Type, fw TypeId) bool { ...@@ -645,11 +645,11 @@ func compatibleType(fr reflect.Type, fw TypeId) bool {
return true; return true;
} }
func compileDec(wireId TypeId, rt reflect.Type) (engine *decEngine, err os.Error) { func compileDec(wireId typeId, rt reflect.Type) (engine *decEngine, err os.Error) {
srt, ok1 := rt.(*reflect.StructType); srt, ok1 := rt.(*reflect.StructType);
wireStruct, ok2 := wireId.gobType().(*structType); wireStruct, ok2 := wireId.gobType().(*structType);
if !ok1 || !ok2 { if !ok1 || !ok2 {
return nil, ErrNotStruct return nil, errNotStruct
} }
engine = new(decEngine); engine = new(decEngine);
engine.instr = make([]decInstr, len(wireStruct.field)); engine.instr = make([]decInstr, len(wireStruct.field));
...@@ -660,17 +660,17 @@ func compileDec(wireId TypeId, rt reflect.Type) (engine *decEngine, err os.Error ...@@ -660,17 +660,17 @@ func compileDec(wireId TypeId, rt reflect.Type) (engine *decEngine, err os.Error
localField, present := srt.FieldByName(wireField.name); localField, present := srt.FieldByName(wireField.name);
// TODO(r): anonymous names // TODO(r): anonymous names
if !present || localField.Anonymous { if !present || localField.Anonymous {
op, err := decIgnoreOpFor(wireField.typeId); op, err := decIgnoreOpFor(wireField.id);
if err != nil { if err != nil {
return nil, err return nil, err
} }
engine.instr[fieldnum] = decInstr{op, fieldnum, 0, 0}; engine.instr[fieldnum] = decInstr{op, fieldnum, 0, 0};
continue; continue;
} }
if !compatibleType(localField.Type, wireField.typeId) { if !compatibleType(localField.Type, wireField.id) {
return nil, os.ErrorString("gob: wrong type for field " + wireField.name + " in type " + wireId.Name()); return nil, os.ErrorString("gob: wrong type for field " + wireField.name + " in type " + wireId.Name());
} }
op, indir, err := decOpFor(wireField.typeId, localField.Type); op, indir, err := decOpFor(wireField.id, localField.Type);
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -680,14 +680,14 @@ func compileDec(wireId TypeId, rt reflect.Type) (engine *decEngine, err os.Error ...@@ -680,14 +680,14 @@ func compileDec(wireId TypeId, rt reflect.Type) (engine *decEngine, err os.Error
return; return;
} }
var decoderCache = make(map[reflect.Type] map[TypeId] **decEngine) var decoderCache = make(map[reflect.Type] map[typeId] **decEngine)
var ignorerCache = make(map[TypeId] **decEngine) var ignorerCache = make(map[typeId] **decEngine)
// typeLock must be held. // typeLock must be held.
func getDecEnginePtr(wireId TypeId, rt reflect.Type) (enginePtr **decEngine, err os.Error) { func getDecEnginePtr(wireId typeId, rt reflect.Type) (enginePtr **decEngine, err os.Error) {
decoderMap, ok := decoderCache[rt]; decoderMap, ok := decoderCache[rt];
if !ok { if !ok {
decoderMap = make(map[TypeId] **decEngine); decoderMap = make(map[typeId] **decEngine);
decoderCache[rt] = decoderMap; decoderCache[rt] = decoderMap;
} }
if enginePtr, ok = decoderMap[wireId]; !ok { if enginePtr, ok = decoderMap[wireId]; !ok {
...@@ -707,7 +707,7 @@ type emptyStruct struct {} ...@@ -707,7 +707,7 @@ type emptyStruct struct {}
var emptyStructType = reflect.Typeof(emptyStruct{}) var emptyStructType = reflect.Typeof(emptyStruct{})
// typeLock must be held. // typeLock must be held.
func getIgnoreEnginePtr(wireId TypeId) (enginePtr **decEngine, err os.Error) { func getIgnoreEnginePtr(wireId typeId) (enginePtr **decEngine, err os.Error) {
var ok bool; var ok bool;
if enginePtr, ok = ignorerCache[wireId]; !ok { if enginePtr, ok = ignorerCache[wireId]; !ok {
// To handle recursive types, mark this engine as underway before compiling. // To handle recursive types, mark this engine as underway before compiling.
...@@ -721,7 +721,7 @@ func getIgnoreEnginePtr(wireId TypeId) (enginePtr **decEngine, err os.Error) { ...@@ -721,7 +721,7 @@ func getIgnoreEnginePtr(wireId TypeId) (enginePtr **decEngine, err os.Error) {
return return
} }
func decode(b *bytes.Buffer, wireId TypeId, e interface{}) os.Error { func decode(b *bytes.Buffer, wireId typeId, e interface{}) os.Error {
// Dereference down to the underlying object. // Dereference down to the underlying object.
rt, indir := indirect(reflect.Typeof(e)); rt, indir := indirect(reflect.Typeof(e));
v := reflect.NewValue(e); v := reflect.NewValue(e);
......
...@@ -13,27 +13,30 @@ import ( ...@@ -13,27 +13,30 @@ import (
"sync"; "sync";
) )
// A Decoder manages the receipt of type and data information read from the
// remote side of a connection.
type Decoder struct { type Decoder struct {
sync.Mutex; // each item must be received atomically mutex sync.Mutex; // each item must be received atomically
r io.Reader; // source of the data r io.Reader; // source of the data
seen map[TypeId] *wireType; // which types we've already seen described seen map[typeId] *wireType; // which types we've already seen described
state *decodeState; // reads data from in-memory buffer state *decodeState; // reads data from in-memory buffer
countState *decodeState; // reads counts from wire countState *decodeState; // reads counts from wire
buf []byte; buf []byte;
oneByte []byte; oneByte []byte;
} }
// NewDecoder returns a new decoder that reads from the io.Reader.
func NewDecoder(r io.Reader) *Decoder { func NewDecoder(r io.Reader) *Decoder {
dec := new(Decoder); dec := new(Decoder);
dec.r = r; dec.r = r;
dec.seen = make(map[TypeId] *wireType); dec.seen = make(map[typeId] *wireType);
dec.state = new(decodeState); // buffer set in Decode(); rest is unimportant dec.state = new(decodeState); // buffer set in Decode(); rest is unimportant
dec.oneByte = make([]byte, 1); dec.oneByte = make([]byte, 1);
return dec; return dec;
} }
func (dec *Decoder) recvType(id TypeId) { func (dec *Decoder) recvType(id typeId) {
// Have we already seen this type? That's an error // Have we already seen this type? That's an error
if wt_, alreadySeen := dec.seen[id]; alreadySeen { if wt_, alreadySeen := dec.seen[id]; alreadySeen {
dec.state.err = os.ErrorString("gob: duplicate type received"); dec.state.err = os.ErrorString("gob: duplicate type received");
...@@ -47,14 +50,16 @@ func (dec *Decoder) recvType(id TypeId) { ...@@ -47,14 +50,16 @@ func (dec *Decoder) recvType(id TypeId) {
dec.seen[id] = wire; dec.seen[id] = wire;
} }
// Decode reads the next value from the connection and stores
// it in the data represented by the empty interface value.
// The value underlying e must be the correct type for the next // The value underlying e must be the correct type for the next
// value to be received for this decoder. // data item received.
func (dec *Decoder) Decode(e interface{}) os.Error { func (dec *Decoder) Decode(e interface{}) os.Error {
rt, indir := indirect(reflect.Typeof(e)); rt, indir := indirect(reflect.Typeof(e));
// Make sure we're single-threaded through here. // Make sure we're single-threaded through here.
dec.Lock(); dec.mutex.Lock();
defer dec.Unlock(); defer dec.mutex.Unlock();
dec.state.err = nil; dec.state.err = nil;
for { for {
...@@ -81,7 +86,7 @@ func (dec *Decoder) Decode(e interface{}) os.Error { ...@@ -81,7 +86,7 @@ func (dec *Decoder) Decode(e interface{}) os.Error {
} }
// Receive a type id. // Receive a type id.
id := TypeId(decodeInt(dec.state)); id := typeId(decodeInt(dec.state));
if dec.state.err != nil { if dec.state.err != nil {
break; break;
} }
......
This diff is collapsed.
...@@ -70,7 +70,7 @@ func TestBasicEncoder(t *testing.T) { ...@@ -70,7 +70,7 @@ func TestBasicEncoder(t *testing.T) {
t.Fatal("error decoding ET1 type:", err); t.Fatal("error decoding ET1 type:", err);
} }
info := getTypeInfo(reflect.Typeof(ET1{})); info := getTypeInfo(reflect.Typeof(ET1{}));
trueWire1 := &wireType{s: info.typeId.gobType().(*structType)}; trueWire1 := &wireType{s: info.id.gobType().(*structType)};
if !reflect.DeepEqual(wire1, trueWire1) { if !reflect.DeepEqual(wire1, trueWire1) {
t.Fatalf("invalid wireType for ET1: expected %+v; got %+v\n", *trueWire1, *wire1); t.Fatalf("invalid wireType for ET1: expected %+v; got %+v\n", *trueWire1, *wire1);
} }
...@@ -91,7 +91,7 @@ func TestBasicEncoder(t *testing.T) { ...@@ -91,7 +91,7 @@ func TestBasicEncoder(t *testing.T) {
t.Fatal("error decoding ET2 type:", err); t.Fatal("error decoding ET2 type:", err);
} }
info = getTypeInfo(reflect.Typeof(ET2{})); info = getTypeInfo(reflect.Typeof(ET2{}));
trueWire2 := &wireType{s: info.typeId.gobType().(*structType)}; trueWire2 := &wireType{s: info.id.gobType().(*structType)};
if !reflect.DeepEqual(wire2, trueWire2) { if !reflect.DeepEqual(wire2, trueWire2) {
t.Fatalf("invalid wireType for ET2: expected %+v; got %+v\n", *trueWire2, *wire2); t.Fatalf("invalid wireType for ET2: expected %+v; got %+v\n", *trueWire2, *wire2);
} }
...@@ -107,7 +107,7 @@ func TestBasicEncoder(t *testing.T) { ...@@ -107,7 +107,7 @@ func TestBasicEncoder(t *testing.T) {
} }
// 8) The value of et1 // 8) The value of et1
newEt1 := new(ET1); newEt1 := new(ET1);
et1Id := getTypeInfo(reflect.Typeof(*newEt1)).typeId; et1Id := getTypeInfo(reflect.Typeof(*newEt1)).id;
err = decode(b, et1Id, newEt1); err = decode(b, et1Id, newEt1);
if err != nil { if err != nil {
t.Fatal("error decoding ET1 value:", err); t.Fatal("error decoding ET1 value:", err);
......
...@@ -13,23 +13,23 @@ import ( ...@@ -13,23 +13,23 @@ import (
"unicode"; "unicode";
) )
// Types are identified by an integer TypeId. These can be passed on the wire. // A typeId represents a gob Type as an integer that can be passed on the wire.
// Internally, they are used as keys to a map to recover the underlying type info. // Internally, typeIds are used as keys to a map to recover the underlying type info.
type TypeId int32 type typeId int32
var nextId TypeId // incremented for each new type we build var nextId typeId // incremented for each new type we build
var typeLock sync.Mutex // set while building a type var typeLock sync.Mutex // set while building a type
type gobType interface { type gobType interface {
id() TypeId; id() typeId;
setId(id TypeId); setId(id typeId);
Name() string; Name() string;
String() string; String() string;
safeString(seen map[TypeId] bool) string; safeString(seen map[typeId] bool) string;
} }
var types = make(map[reflect.Type] gobType) var types = make(map[reflect.Type] gobType)
var idToType = make(map[TypeId] gobType) var idToType = make(map[typeId] gobType)
func setTypeId(typ gobType) { func setTypeId(typ gobType) {
nextId++; nextId++;
...@@ -37,32 +37,34 @@ func setTypeId(typ gobType) { ...@@ -37,32 +37,34 @@ func setTypeId(typ gobType) {
idToType[nextId] = typ; idToType[nextId] = typ;
} }
func (t TypeId) gobType() gobType { func (t typeId) gobType() gobType {
if t == 0 { if t == 0 {
return nil return nil
} }
return idToType[t] return idToType[t]
} }
func (t TypeId) String() string { // String returns the string representation of the type associated with the typeId.
func (t typeId) String() string {
return t.gobType().String() return t.gobType().String()
} }
func (t TypeId) Name() string { // Name returns the name of the type associated with the typeId.
func (t typeId) Name() string {
return t.gobType().Name() return t.gobType().Name()
} }
// Common elements of all types. // Common elements of all types.
type commonType struct { type commonType struct {
name string; name string;
_id TypeId; _id typeId;
} }
func (t *commonType) id() TypeId { func (t *commonType) id() typeId {
return t._id return t._id
} }
func (t *commonType) setId(id TypeId) { func (t *commonType) setId(id typeId) {
t._id = id t._id = id
} }
...@@ -79,20 +81,20 @@ func (t *commonType) Name() string { ...@@ -79,20 +81,20 @@ func (t *commonType) Name() string {
} }
// Basic type identifiers, predefined. // Basic type identifiers, predefined.
var tBool TypeId var tBool typeId
var tInt TypeId var tInt typeId
var tUint TypeId var tUint typeId
var tFloat TypeId var tFloat typeId
var tString TypeId var tString typeId
var tBytes TypeId var tBytes typeId
// Predefined because it's needed by the Decoder // Predefined because it's needed by the Decoder
var tWireType TypeId var tWireType typeId
// Array type // Array type
type arrayType struct { type arrayType struct {
commonType; commonType;
Elem TypeId; Elem typeId;
Len int; Len int;
} }
...@@ -102,7 +104,7 @@ func newArrayType(name string, elem gobType, length int) *arrayType { ...@@ -102,7 +104,7 @@ func newArrayType(name string, elem gobType, length int) *arrayType {
return a; return a;
} }
func (a *arrayType) safeString(seen map[TypeId] bool) string { func (a *arrayType) safeString(seen map[typeId] bool) string {
if _, ok := seen[a._id]; ok { if _, ok := seen[a._id]; ok {
return a.name return a.name
} }
...@@ -117,7 +119,7 @@ func (a *arrayType) String() string { ...@@ -117,7 +119,7 @@ func (a *arrayType) String() string {
// Slice type // Slice type
type sliceType struct { type sliceType struct {
commonType; commonType;
Elem TypeId; Elem typeId;
} }
func newSliceType(name string, elem gobType) *sliceType { func newSliceType(name string, elem gobType) *sliceType {
...@@ -126,7 +128,7 @@ func newSliceType(name string, elem gobType) *sliceType { ...@@ -126,7 +128,7 @@ func newSliceType(name string, elem gobType) *sliceType {
return s; return s;
} }
func (s *sliceType) safeString(seen map[TypeId] bool) string { func (s *sliceType) safeString(seen map[typeId] bool) string {
if _, ok := seen[s._id]; ok { if _, ok := seen[s._id]; ok {
return s.name return s.name
} }
...@@ -135,13 +137,13 @@ func (s *sliceType) safeString(seen map[TypeId] bool) string { ...@@ -135,13 +137,13 @@ func (s *sliceType) safeString(seen map[TypeId] bool) string {
} }
func (s *sliceType) String() string { func (s *sliceType) String() string {
return s.safeString(make(map[TypeId] bool)) return s.safeString(make(map[typeId] bool))
} }
// Struct type // Struct type
type fieldType struct { type fieldType struct {
name string; name string;
typeId TypeId; id typeId;
} }
type structType struct { type structType struct {
...@@ -149,7 +151,7 @@ type structType struct { ...@@ -149,7 +151,7 @@ type structType struct {
field []*fieldType; field []*fieldType;
} }
func (s *structType) safeString(seen map[TypeId] bool) string { func (s *structType) safeString(seen map[typeId] bool) string {
if s == nil { if s == nil {
return "<nil>" return "<nil>"
} }
...@@ -159,14 +161,14 @@ func (s *structType) safeString(seen map[TypeId] bool) string { ...@@ -159,14 +161,14 @@ func (s *structType) safeString(seen map[TypeId] bool) string {
seen[s._id] = true; seen[s._id] = true;
str := s.name + " = struct { "; str := s.name + " = struct { ";
for _, f := range s.field { for _, f := range s.field {
str += fmt.Sprintf("%s %s; ", f.name, f.typeId.gobType().safeString(seen)); str += fmt.Sprintf("%s %s; ", f.name, f.id.gobType().safeString(seen));
} }
str += "}"; str += "}";
return str; return str;
} }
func (s *structType) String() string { func (s *structType) String() string {
return s.safeString(make(map[TypeId] bool)) return s.safeString(make(map[typeId] bool))
} }
func newStructType(name string) *structType { func newStructType(name string) *structType {
...@@ -294,8 +296,14 @@ func getType(name string, rt reflect.Type) gobType { ...@@ -294,8 +296,14 @@ func getType(name string, rt reflect.Type) gobType {
return t; return t;
} }
func checkId(want, got typeId) {
if want != got {
panicln("bootstrap type wrong id:", got.Name(), got, "not", want);
}
}
// used for building the basic types; called only from init() // used for building the basic types; called only from init()
func bootstrapType(name string, e interface{}) TypeId { func bootstrapType(name string, e interface{}, expect typeId) typeId {
rt := reflect.Typeof(e); rt := reflect.Typeof(e);
_, present := types[rt]; _, present := types[rt];
if present { if present {
...@@ -304,6 +312,7 @@ func bootstrapType(name string, e interface{}) TypeId { ...@@ -304,6 +312,7 @@ func bootstrapType(name string, e interface{}) TypeId {
typ := &commonType{ name: name }; typ := &commonType{ name: name };
types[rt] = typ; types[rt] = typ;
setTypeId(typ); setTypeId(typ);
checkId(expect, nextId);
return nextId return nextId
} }
...@@ -329,7 +338,7 @@ func (w *wireType) name() string { ...@@ -329,7 +338,7 @@ func (w *wireType) name() string {
type decEngine struct // defined in decode.go type decEngine struct // defined in decode.go
type encEngine struct // defined in encode.go type encEngine struct // defined in encode.go
type typeInfo struct { type typeInfo struct {
typeId TypeId; id typeId;
encoder *encEngine; encoder *encEngine;
wire *wireType; wire *wireType;
} }
...@@ -346,21 +355,26 @@ func getTypeInfo(rt reflect.Type) *typeInfo { ...@@ -346,21 +355,26 @@ func getTypeInfo(rt reflect.Type) *typeInfo {
if !ok { if !ok {
info = new(typeInfo); info = new(typeInfo);
name := rt.Name(); name := rt.Name();
info.typeId = getType(name, rt).id(); info.id = getType(name, rt).id();
// assume it's a struct type // assume it's a struct type
info.wire = &wireType{info.typeId.gobType().(*structType)}; info.wire = &wireType{info.id.gobType().(*structType)};
typeInfoMap[rt] = info; typeInfoMap[rt] = info;
} }
return info; return info;
} }
func init() { func init() {
tBool = bootstrapType("bool", false); // Create and check predefined types
tInt = bootstrapType("int", int(0)); tBool = bootstrapType("bool", false, 1);
tUint = bootstrapType("uint", uint(0)); tInt = bootstrapType("int", int(0), 2);
tFloat = bootstrapType("float", float64(0)); tUint = bootstrapType("uint", uint(0), 3);
tFloat = bootstrapType("float", float64(0), 4);
// The string for tBytes is "bytes" not "[]byte" to signify its specialness. // The string for tBytes is "bytes" not "[]byte" to signify its specialness.
tBytes = bootstrapType("bytes", make([]byte, 0)); tBytes = bootstrapType("bytes", make([]byte, 0), 5);
tString= bootstrapType("string", ""); tString= bootstrapType("string", "", 6);
tWireType = getTypeInfo(reflect.Typeof(wireType{})).typeId; tWireType = getTypeInfo(reflect.Typeof(wireType{})).id;
checkId(7, tWireType);
checkId(8, getTypeInfo(reflect.Typeof(structType{})).id);
checkId(9, getTypeInfo(reflect.Typeof(commonType{})).id);
checkId(10, getTypeInfo(reflect.Typeof(fieldType{})).id);
} }
...@@ -12,7 +12,7 @@ import ( ...@@ -12,7 +12,7 @@ import (
) )
type typeT struct { type typeT struct {
typeId TypeId; id typeId;
str string; str string;
} }
var basicTypes = []typeT { var basicTypes = []typeT {
...@@ -33,10 +33,10 @@ func getTypeUnlocked(name string, rt reflect.Type) gobType { ...@@ -33,10 +33,10 @@ func getTypeUnlocked(name string, rt reflect.Type) gobType {
// Sanity checks // Sanity checks
func TestBasic(t *testing.T) { func TestBasic(t *testing.T) {
for _, tt := range basicTypes { for _, tt := range basicTypes {
if tt.typeId.String() != tt.str { if tt.id.String() != tt.str {
t.Errorf("checkType: expected %q got %s", tt.str, tt.typeId.String()) t.Errorf("checkType: expected %q got %s", tt.str, tt.id.String())
} }
if tt.typeId == 0 { if tt.id == 0 {
t.Errorf("id for %q is zero", tt.str) t.Errorf("id for %q is zero", tt.str)
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment