Beispiel #1
0
// Decode an embedded message.
func (o *Buffer) dec_struct_message(p *Properties, base uintptr, sbase uintptr) (err error) {
	raw, e := o.DecodeRawBytes(false)
	if e != nil {
		return e
	}

	ptr := (**struct{})(unsafe.Pointer(base + p.offset))
	typ := p.stype.Elem()
	structv := unsafe.New(typ)
	bas := uintptr(structv)
	*ptr = (*struct{})(structv)

	// If the object can unmarshal itself, let it.
	iv := unsafe.Unreflect(p.stype, unsafe.Pointer(ptr))
	if u, ok := iv.(Unmarshaler); ok {
		return u.Unmarshal(raw)
	}

	obuf := o.buf
	oi := o.index
	o.buf = raw
	o.index = 0

	err = o.unmarshalType(p.stype, false, bas)
	o.buf = obuf
	o.index = oi

	return err
}
Beispiel #2
0
// gobDecodeOpFor returns the op for a type that is known to implement
// GobDecoder.
func (dec *Decoder) gobDecodeOpFor(ut *userTypeInfo) (*decOp, int) {
	rcvrType := ut.user
	if ut.decIndir == -1 {
		rcvrType = reflect.PtrTo(rcvrType)
	} else if ut.decIndir > 0 {
		for i := int8(0); i < ut.decIndir; i++ {
			rcvrType = rcvrType.Elem()
		}
	}
	var op decOp
	op = func(i *decInstr, state *decoderState, p unsafe.Pointer) {
		// Caller has gotten us to within one indirection of our value.
		if i.indir > 0 {
			if *(*unsafe.Pointer)(p) == nil {
				*(*unsafe.Pointer)(p) = unsafe.New(ut.base)
			}
		}
		// Now p is a pointer to the base type.  Do we need to climb out to
		// get to the receiver type?
		var v reflect.Value
		if ut.decIndir == -1 {
			v = reflect.ValueOf(unsafe.Unreflect(rcvrType, unsafe.Pointer(&p)))
		} else {
			v = reflect.ValueOf(unsafe.Unreflect(rcvrType, p))
		}
		state.dec.decodeGobDecoder(state, v)
	}
	return &op, int(ut.indir)

}
Beispiel #3
0
// New returns a Value representing a pointer to a new zero value
// for the specified type.  That is, the returned Value's Type is PtrTo(t).
func New(typ Type) Value {
	if typ == nil {
		panic("reflect: New(nil)")
	}
	ptr := unsafe.New(typ)
	return valueFromIword(0, PtrTo(typ), iword(uintptr(ptr)))
}
Beispiel #4
0
// New returns a Value representing a pointer to a new zero value
// for the specified type.  That is, the returned Value's Type is PtrTo(t).
func New(typ Type) Value {
	if typ == nil {
		panic("reflect: New(nil)")
	}
	ptr := unsafe.New(typ)
	fl := flag(Ptr) << flagKindShift
	return Value{typ.common().ptrTo(), ptr, fl}
}
Beispiel #5
0
// Zero returns a Value representing a zero value for the specified type.
// The result is different from the zero value of the Value struct,
// which represents no value at all.
// For example, Zero(TypeOf(42)) returns a Value with Kind Int and value 0.
func Zero(typ Type) Value {
	if typ == nil {
		panic("reflect: Zero(nil)")
	}
	if typ.Kind() == Ptr || typ.Kind() == UnsafePointer {
		return valueFromIword(0, typ, 0)
	}
	return valueFromAddr(0, typ, unsafe.New(typ))
}
Beispiel #6
0
// Zero returns a Value representing a zero value for the specified type.
// The result is different from the zero value of the Value struct,
// which represents no value at all.
// For example, Zero(TypeOf(42)) returns a Value with Kind Int and value 0.
func Zero(typ Type) Value {
	if typ == nil {
		panic("reflect: Zero(nil)")
	}
	if typ.Size() <= ptrSize {
		return valueFromIword(0, typ, 0)
	}
	return valueFromAddr(0, typ, unsafe.New(typ))
}
Beispiel #7
0
// Zero returns a Value representing a zero value for the specified type.
// The result is different from the zero value of the Value struct,
// which represents no value at all.
// For example, Zero(TypeOf(42)) returns a Value with Kind Int and value 0.
func Zero(typ Type) Value {
	if typ == nil {
		panic("reflect: Zero(nil)")
	}
	t := typ.common()
	fl := flag(t.Kind()) << flagKindShift
	if t.size <= ptrSize {
		return Value{t, nil, fl}
	}
	return Value{t, unsafe.New(typ), fl | flagIndir}
}
Beispiel #8
0
// Decode a group.
func (o *Buffer) dec_struct_group(p *Properties, base uintptr, sbase uintptr) error {
	ptr := (**struct{})(unsafe.Pointer(base + p.offset))
	typ := p.stype.Elem()
	structv := unsafe.New(typ)
	bas := uintptr(structv)
	*ptr = (*struct{})(structv)

	err := o.unmarshalType(p.stype, true, bas)

	return err
}
Beispiel #9
0
// decodeExtension decodes an extension encoded in b.
func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) {
	// Discard wire type and field number varint. It isn't needed.
	_, n := DecodeVarint(b)
	o := NewBuffer(b[n:])

	t := reflect.TypeOf(extension.ExtensionType)
	props := &Properties{}
	props.Init(t, "irrelevant_name", extension.Tag, 0)

	base := unsafe.New(t)
	var sbase uintptr
	if t.Elem().Kind() == reflect.Struct {
		// props.dec will be dec_struct_message, which does not refer to sbase.
		*(*unsafe.Pointer)(base) = unsafe.New(t.Elem())
	} else {
		sbase = uintptr(unsafe.New(t.Elem()))
	}
	if err := props.dec(o, props, uintptr(base), sbase); err != nil {
		return nil, err
	}
	return unsafe.Unreflect(t, base), nil
}
Beispiel #10
0
// allocate makes sure storage is available for an object of underlying type rtyp
// that is indir levels of indirection through p.
func allocate(rtyp reflect.Type, p uintptr, indir int) uintptr {
	if indir == 0 {
		return p
	}
	up := unsafe.Pointer(p)
	if indir > 1 {
		up = decIndirect(up, indir)
	}
	if *(*unsafe.Pointer)(up) == nil {
		// Allocate object.
		*(*unsafe.Pointer)(up) = unsafe.New(rtyp)
	}
	return *(*uintptr)(up)
}
Beispiel #11
0
func decodeArray(atyp *reflect.ArrayType, state *decodeState, p uintptr, elemOp decOp, elemWid uintptr, length, indir, elemIndir int, ovfl os.ErrorString) os.Error {
	if indir > 0 {
		up := unsafe.Pointer(p)
		if *(*unsafe.Pointer)(up) == nil {
			// Allocate object.
			*(*unsafe.Pointer)(up) = unsafe.New(atyp)
		}
		p = *(*uintptr)(up)
	}
	if n := decodeUint(state); n != uint64(length) {
		return os.ErrorString("gob: length mismatch in decodeArray")
	}
	return decodeArrayHelper(state, p, elemOp, elemWid, length, elemIndir, ovfl)
}
Beispiel #12
0
// Decode a slice of structs ([]*struct).
func (o *Buffer) dec_slice_struct(p *Properties, is_group bool, base uintptr, sbase uintptr) error {

	x := (*[]*struct{})(unsafe.Pointer(base + p.offset))
	y := *x
	if cap(y) == 0 {
		initSlice(unsafe.Pointer(x), sbase+p.scratch)
		y = *x
	}

	typ := p.stype.Elem()
	structv := unsafe.New(typ)
	bas := uintptr(structv)
	y = append(y, (*struct{})(structv))
	*x = y

	if is_group {
		err := o.unmarshalType(p.stype, is_group, bas)
		return err
	}

	raw, err := o.DecodeRawBytes(true)
	if err != nil {
		return err
	}

	// If the object can unmarshal itself, let it.
	iv := unsafe.Unreflect(p.stype, unsafe.Pointer(&y[len(y)-1]))
	if u, ok := iv.(Unmarshaler); ok {
		return u.Unmarshal(raw)
	}

	obuf := o.buf
	oi := o.index
	o.buf = raw
	o.index = 0

	err = o.unmarshalType(p.stype, is_group, bas)

	o.buf = obuf
	o.index = oi

	return err
}
Beispiel #13
0
func decodeStruct(engine *decEngine, rtyp *reflect.StructType, b *bytes.Buffer, p uintptr, indir int) os.Error {
	if indir > 0 {
		up := unsafe.Pointer(p)
		if indir > 1 {
			up = decIndirect(up, indir)
		}
		if *(*unsafe.Pointer)(up) == nil {
			// Allocate object.
			*(*unsafe.Pointer)(up) = unsafe.New((*runtime.StructType)(unsafe.Pointer(rtyp)))
		}
		p = *(*uintptr)(up)
	}
	state := newDecodeState(b)
	state.fieldnum = -1
	basep := p
	for state.err == nil {
		delta := int(decodeUint(state))
		if delta < 0 {
			state.err = os.ErrorString("gob decode: corrupted data: negative delta")
			break
		}
		if state.err != nil || delta == 0 { // struct terminator is zero delta fieldnum
			break
		}
		fieldnum := state.fieldnum + delta
		if fieldnum >= len(engine.instr) {
			state.err = errRange
			break
		}
		instr := &engine.instr[fieldnum]
		p := unsafe.Pointer(basep + instr.offset)
		if instr.indir > 1 {
			p = decIndirect(p, instr.indir)
		}
		instr.op(instr, state, p)
		state.fieldnum = fieldnum
	}
	return state.err
}
Beispiel #14
0
// MakeZero returns a zero Value for the specified Type.
func MakeZero(typ Type) Value {
	if typ == nil {
		return nil
	}
	return newValue(typ, addr(unsafe.New(typ)), true)
}
Beispiel #15
0
// MakeZero returns a zero Value for the specified Type.
func MakeZero(typ Type) Value {
	if typ == nil {
		return nil
	}
	return newValue(typ, addr(unsafe.New(typ)), canSet|canAddr|canStore)
}