return v
case reflect.Struct:
- v := reflect.Zero(p.Type())
+ v := reflect.New(p.Type()).Elem()
for i := 0; i < p.NumField(); i++ {
v.Field(i).Set(subst(m, p.Field(i), pos))
}
return v
case reflect.Ptr:
- v := reflect.Zero(p.Type())
+ v := reflect.New(p.Type()).Elem()
if elem := p.Elem(); elem.IsValid() {
v.Set(subst(m, elem, pos).Addr())
}
return v
case reflect.Interface:
- v := reflect.Zero(p.Type())
+ v := reflect.New(p.Type()).Elem()
if elem := p.Elem(); elem.IsValid() {
v.Set(subst(m, elem, pos))
}
}
}
-type unmarshalTest struct {
- in []byte
- out interface{}
-}
-
type TestObjectIdentifierStruct struct {
OID ObjectIdentifier
}
A, B int
}
-var unmarshalTestData []unmarshalTest = []unmarshalTest{
+var unmarshalTestData = []struct {
+ in []byte
+ out interface{}
+}{
{[]byte{0x02, 0x01, 0x42}, newInt(0x42)},
{[]byte{0x30, 0x08, 0x06, 0x06, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d}, &TestObjectIdentifierStruct{[]int{1, 2, 840, 113549}}},
{[]byte{0x03, 0x04, 0x06, 0x6e, 0x5d, 0xc0}, &BitString{[]byte{110, 93, 192}, 18}},
func TestUnmarshal(t *testing.T) {
for i, test := range unmarshalTestData {
- pv := reflect.Zero(reflect.NewValue(test.out).Type())
- zv := reflect.Zero(pv.Type().Elem())
- pv.Set(zv.Addr())
+ pv := reflect.New(reflect.Typeof(test.out).Elem())
val := pv.Interface()
_, err := Unmarshal(test.in, val)
if err != nil {
C float64
}
-
func TestInvalidField(t *testing.T) {
var bad0 Bad0
bad0.CH = make(chan int)
// unlike the other items we can't use a pointer directly.
func decodeIntoValue(state *decoderState, op decOp, indir int, v reflect.Value, ovfl os.ErrorString) reflect.Value {
instr := &decInstr{op, 0, indir, 0, ovfl}
- up := unsafe.Pointer(v.UnsafeAddr())
+ up := unsafe.Pointer(unsafeAddr(v))
if indir > 1 {
up = decIndirect(up, indir)
}
v := reflect.NewValue(unsafe.Unreflect(mtyp, unsafe.Pointer(p)))
n := int(state.decodeUint())
for i := 0; i < n; i++ {
- key := decodeIntoValue(state, keyOp, keyIndir, reflect.Zero(mtyp.Key()), ovfl)
- elem := decodeIntoValue(state, elemOp, elemIndir, reflect.Zero(mtyp.Elem()), ovfl)
+ key := decodeIntoValue(state, keyOp, keyIndir, allocValue(mtyp.Key()), ovfl)
+ elem := decodeIntoValue(state, elemOp, elemIndir, allocValue(mtyp.Elem()), ovfl)
v.SetMapIndex(key, elem)
}
}
// Interfaces are encoded as the name of a concrete type followed by a value.
// If the name is empty, the value is nil and no value is sent.
func (dec *Decoder) decodeInterface(ityp reflect.Type, state *decoderState, p uintptr, indir int) {
- // Create an interface reflect.Value. We need one even for the nil case.
- ivalue := reflect.Zero(ityp)
+ // Create a writable interface reflect.Value. We need one even for the nil case.
+ ivalue := allocValue(ityp)
// Read the name of the concrete type.
b := make([]byte, state.decodeUint())
state.b.Read(b)
// in case we want to ignore the value by skipping it completely).
state.decodeUint()
// Read the concrete value.
- value := reflect.Zero(typ)
+ value := allocValue(typ)
dec.decodeValue(concreteId, value)
if dec.err != nil {
error(dec.err)
name := base.Name()
errorf("gob: type mismatch: no fields matched compiling decoder for %s", name)
}
- dec.decodeStruct(engine, ut, uintptr(val.UnsafeAddr()), ut.indir)
+ dec.decodeStruct(engine, ut, uintptr(unsafeAddr(val)), ut.indir)
} else {
- dec.decodeSingle(engine, ut, uintptr(val.UnsafeAddr()))
+ dec.decodeSingle(engine, ut, uintptr(unsafeAddr(val)))
}
}
}
decOpTable[reflect.Uintptr] = uop
}
+
+// Gob assumes it can call UnsafeAddr on any Value
+// in order to get a pointer it can copy data from.
+// Values that have just been created and do not point
+// into existing structs or slices cannot be addressed,
+// so simulate it by returning a pointer to a copy.
+// Each call allocates once.
+func unsafeAddr(v reflect.Value) uintptr {
+ if v.CanAddr() {
+ return v.UnsafeAddr()
+ }
+ x := reflect.New(v.Type()).Elem()
+ x.Set(v)
+ return x.UnsafeAddr()
+}
+
+// Gob depends on being able to take the address
+// of zeroed Values it creates, so use this wrapper instead
+// of the standard reflect.Zero.
+// Each call allocates once.
+func allocValue(t reflect.Type) reflect.Value {
+ return reflect.New(t).Elem()
+}
return dec.DecodeValue(value)
}
-// DecodeValue reads the next value from the connection and stores
-// it in the data represented by the reflection value.
-// The value must be the correct type for the next
-// data item received, or it may be nil, which means the
-// value will be discarded.
-func (dec *Decoder) DecodeValue(value reflect.Value) os.Error {
+// DecodeValue reads the next value from the connection.
+// If v is the zero reflect.Value (v.Kind() == Invalid), DecodeValue discards the value.
+// Otherwise, it stores the value into v. In that case, v must represent
+// a non-nil pointer to data or be an assignable reflect.Value (v.CanSet())
+func (dec *Decoder) DecodeValue(v reflect.Value) os.Error {
+ if v.IsValid() {
+ if v.Kind() == reflect.Ptr && !v.IsNil() {
+ // That's okay, we'll store through the pointer.
+ } else if !v.CanSet() {
+ return os.ErrorString("gob: DecodeValue of unassignable value")
+ }
+ }
// Make sure we're single-threaded through here.
dec.mutex.Lock()
defer dec.mutex.Unlock()
dec.err = nil
id := dec.decodeTypeSequence(false)
if dec.err == nil {
- dec.decodeValue(id, value)
+ dec.decodeValue(id, v)
}
return dec.err
}
if !v.IsValid() {
errorf("gob: encodeReflectValue: nil element")
}
- op(nil, state, unsafe.Pointer(v.UnsafeAddr()))
+ op(nil, state, unsafe.Pointer(unsafeAddr(v)))
}
// encodeMap encodes a map as unsigned count followed by key:value pairs.
value = reflect.Indirect(value)
}
if !ut.isGobEncoder && value.Type().Kind() == reflect.Struct {
- enc.encodeStruct(b, engine, value.UnsafeAddr())
+ enc.encodeStruct(b, engine, unsafeAddr(value))
} else {
- enc.encodeSingle(b, engine, value.UnsafeAddr())
+ enc.encodeSingle(b, engine, unsafeAddr(value))
}
}
A int
}
t0 := Type0{7}
- t0p := (*Type0)(nil)
+ t0p := new(Type0)
if err := encAndDec(t0, t0p); err != nil {
t.Error(err)
}
rv := reflect.NewValue(v)
pv := rv
- if pv.Kind() != reflect.Ptr ||
- pv.IsNil() {
+ if pv.Kind() != reflect.Ptr || pv.IsNil() {
return &InvalidUnmarshalError{reflect.Typeof(v)}
}
v = iv.Elem()
continue
}
+
pv := v
if pv.Kind() != reflect.Ptr {
break
}
- if pv.Elem().Kind() != reflect.Ptr &&
- wantptr && !isUnmarshaler {
+ if pv.Elem().Kind() != reflect.Ptr && wantptr && pv.CanSet() && !isUnmarshaler {
return nil, pv
}
if pv.IsNil() {
- pv.Set(reflect.Zero(pv.Type().Elem()).Addr())
+ pv.Set(reflect.New(pv.Type().Elem()))
}
if isUnmarshaler {
// Using v.Interface().(Unmarshaler)
return
}
+ var mapElem reflect.Value
+
for {
// Read opening " of string key or closing }.
op := d.scanWhile(scanSkipSpace)
// Figure out field corresponding to key.
var subv reflect.Value
if mv.IsValid() {
- subv = reflect.Zero(mv.Type().Elem())
+ elemType := mv.Type().Elem()
+ if !mapElem.IsValid() {
+ mapElem = reflect.New(elemType).Elem()
+ } else {
+ mapElem.Set(reflect.Zero(elemType))
+ }
+ subv = mapElem
} else {
var f reflect.StructField
var ok bool
continue
}
// v = new(right-type)
- v := reflect.NewValue(tt.ptr)
- v.Set(reflect.Zero(v.Type().Elem()).Addr())
+ v := reflect.New(reflect.Typeof(tt.ptr).Elem())
if err := Unmarshal([]byte(in), v.Interface()); !reflect.DeepEqual(err, tt.err) {
t.Errorf("#%d: %v want %v", i, err, tt.err)
continue
return
}
// Create a new value for each received item.
- val := reflect.Zero(nch.ch.Type().Elem())
+ val := reflect.New(nch.ch.Type().Elem()).Elem()
if err := client.decode(val); err != nil {
expLog("value decode:", err, "; type ", nch.ch.Type())
return
ackHdr.SeqNum = hdr.SeqNum
imp.encode(ackHdr, payAck, nil)
// Create a new value for each received item.
- value := reflect.Zero(nch.ch.Type().Elem())
+ value := reflect.New(nch.ch.Type().Elem()).Elem()
if e := imp.decode(value); e != nil {
impLog("importer value decode:", e)
return
var invalidRequest = InvalidRequest{}
-func _new(t reflect.Type) reflect.Value {
- v := reflect.Zero(t)
- v.Set(reflect.Zero(t.Elem()).Addr())
- return v
-}
-
func (server *Server) sendResponse(sending *sync.Mutex, req *Request, reply interface{}, codec ServerCodec, errmsg string) {
resp := server.getResponse()
// Encode the response header
}
// Decode the argument value.
- argv := _new(mtype.ArgType)
- replyv := _new(mtype.ReplyType)
+ argv := reflect.New(mtype.ArgType.Elem())
+ replyv := reflect.New(mtype.ReplyType.Elem())
err = codec.ReadRequestBody(argv.Interface())
if err != nil {
if err == os.EOF || err == io.ErrUnexpectedEOF {
if !ok {
return reflect.Value{}, false
}
- p := reflect.Zero(concrete)
- p.Set(v.Addr())
+ p := reflect.New(concrete.Elem())
+ p.Elem().Set(v)
return p, true
case reflect.Slice:
numElems := rand.Intn(complexSize)
}
return reflect.NewValue(string(codePoints)), true
case reflect.Struct:
- s := reflect.Zero(t)
+ s := reflect.New(t).Elem()
for i := 0; i < s.NumField(); i++ {
v, ok := Value(concrete.Field(i).Type, rand)
if !ok {
func TestUnmarshalPaths(t *testing.T) {
for _, pt := range pathTests {
- p := reflect.Zero(reflect.NewValue(pt).Type())
- p.Set(reflect.Zero(p.Type().Elem()).Addr())
- v := p.Interface()
+ v := reflect.New(reflect.Typeof(pt).Elem()).Interface()
if err := Unmarshal(StringReader(pathTestString), v); err != nil {
t.Fatalf("Unmarshal: %s", err)
}