示例#1
0
func isTypeMatch(r reflect.Type, s schema.Type) bool {
	switch s.Which() {
	case schema.Type_Which_text:
		return r.Kind() == reflect.String || r.Kind() == reflect.Slice && r.Elem().Kind() == reflect.Uint8
	case schema.Type_Which_data:
		return r.Kind() == reflect.Slice && r.Elem().Kind() == reflect.Uint8
	case schema.Type_Which_structType:
		return isStructOrStructPtr(r)
	case schema.Type_Which_list:
		e, _ := s.List().ElementType()
		return r.Kind() == reflect.Slice && isTypeMatch(r.Elem(), e)
	}
	k, ok := typeMap[s.Which()]
	return ok && k == r.Kind()
}
示例#2
0
func makeTypeRef(t schema.Type, rel *node, nodes nodeMap) (typeRef, error) {
	nodeRef := func(id uint64) (typeRef, error) {
		ni, err := nodes.mustFind(id)
		if err != nil {
			return typeRef{}, err
		}
		return makeNodeTypeRef(ni, rel)
	}
	if ref, ok := staticTypeRefs[t.Which()]; ok {
		return ref, nil
	}
	switch t.Which() {
	case schema.Type_Which_enum:
		return nodeRef(t.Enum().TypeId())
	case schema.Type_Which_structType:
		return nodeRef(t.StructType().TypeId())
	case schema.Type_Which_interface:
		return nodeRef(t.Interface().TypeId())
	case schema.Type_Which_list:
		lt, _ := t.List().ElementType()
		if ref, ok := staticListTypeRefs[lt.Which()]; ok {
			return ref, nil
		}
		switch lt.Which() {
		case schema.Type_Which_enum:
			ref, err := nodeRef(lt.Enum().TypeId())
			if err != nil {
				return ref, err
			}
			ref.name = ref.name + "_List"
			ref.newfunc = "New" + ref.name
			return ref, nil
		case schema.Type_Which_structType:
			ref, err := nodeRef(lt.StructType().TypeId())
			if err != nil {
				return ref, err
			}
			ref.name = ref.name + "_List"
			ref.newfunc = "New" + ref.name
			return ref, nil
		case schema.Type_Which_anyPointer, schema.Type_Which_list, schema.Type_Which_interface:
			return typeRef{name: "PointerList", newfunc: "NewPointerList", imp: capnpImportSpec}, nil
		}
	}
	return typeRef{}, fmt.Errorf("unable to reference type %v", t.Which())
}
示例#3
0
func (e *extracter) extractList(val reflect.Value, typ schema.Type, l capnp.List) error {
	vt := val.Type()
	elem, err := typ.List().ElementType()
	if err != nil {
		return err
	}
	if !isTypeMatch(vt, typ) {
		// TODO(light): the error won't be that useful for nested lists.
		return fmt.Errorf("can't extract %v list into a Go %v", elem.Which(), vt)
	}
	if !l.IsValid() {
		val.Set(reflect.Zero(vt))
		return nil
	}
	n := l.Len()
	val.Set(reflect.MakeSlice(vt, n, n))
	switch elem.Which() {
	case schema.Type_Which_bool:
		for i := 0; i < n; i++ {
			val.Index(i).SetBool(capnp.BitList{List: l}.At(i))
		}
	case schema.Type_Which_int8:
		for i := 0; i < n; i++ {
			val.Index(i).SetInt(int64(capnp.Int8List{List: l}.At(i)))
		}
	case schema.Type_Which_int16:
		for i := 0; i < n; i++ {
			val.Index(i).SetInt(int64(capnp.Int16List{List: l}.At(i)))
		}
	case schema.Type_Which_int32:
		for i := 0; i < n; i++ {
			val.Index(i).SetInt(int64(capnp.Int32List{List: l}.At(i)))
		}
	case schema.Type_Which_int64:
		for i := 0; i < n; i++ {
			val.Index(i).SetInt(capnp.Int64List{List: l}.At(i))
		}
	case schema.Type_Which_uint8:
		for i := 0; i < n; i++ {
			val.Index(i).SetUint(uint64(capnp.UInt8List{List: l}.At(i)))
		}
	case schema.Type_Which_uint16, schema.Type_Which_enum:
		for i := 0; i < n; i++ {
			val.Index(i).SetUint(uint64(capnp.UInt16List{List: l}.At(i)))
		}
	case schema.Type_Which_uint32:
		for i := 0; i < n; i++ {
			val.Index(i).SetUint(uint64(capnp.UInt32List{List: l}.At(i)))
		}
	case schema.Type_Which_uint64:
		for i := 0; i < n; i++ {
			val.Index(i).SetUint(capnp.UInt64List{List: l}.At(i))
		}
	case schema.Type_Which_float32:
		for i := 0; i < n; i++ {
			val.Index(i).SetFloat(float64(capnp.Float32List{List: l}.At(i)))
		}
	case schema.Type_Which_float64:
		for i := 0; i < n; i++ {
			val.Index(i).SetFloat(capnp.Float64List{List: l}.At(i))
		}
	case schema.Type_Which_text:
		if val.Type().Elem().Kind() == reflect.String {
			for i := 0; i < n; i++ {
				s, err := capnp.TextList{List: l}.At(i)
				if err != nil {
					// TODO(light): collect errors and finish
					return err
				}
				val.Index(i).SetString(s)
			}
		} else {
			for i := 0; i < n; i++ {
				b, err := capnp.TextList{List: l}.BytesAt(i)
				if err != nil {
					// TODO(light): collect errors and finish
					return err
				}
				val.Index(i).SetBytes(b)
			}
		}
	case schema.Type_Which_data:
		for i := 0; i < n; i++ {
			b, err := capnp.DataList{List: l}.At(i)
			if err != nil {
				// TODO(light): collect errors and finish
				return err
			}
			val.Index(i).SetBytes(b)
		}
	case schema.Type_Which_list:
		for i := 0; i < n; i++ {
			p, err := capnp.PointerList{List: l}.PtrAt(i)
			// TODO(light): collect errors and finish
			if err != nil {
				return err
			}
			if err := e.extractList(val.Index(i), elem, p.List()); err != nil {
				return err
			}
		}
	case schema.Type_Which_structType:
		if val.Type().Elem().Kind() == reflect.Struct {
			for i := 0; i < n; i++ {
				err := e.extractStruct(val.Index(i), elem.StructType().TypeId(), l.Struct(i))
				if err != nil {
					return err
				}
			}
		} else {
			for i := 0; i < n; i++ {
				newval := reflect.New(val.Type().Elem().Elem())
				val.Index(i).Set(newval)
				err := e.extractStruct(newval, elem.StructType().TypeId(), l.Struct(i))
				if err != nil {
					return err
				}
			}
		}
	default:
		return fmt.Errorf("unknown list type %v", elem.Which())
	}
	return nil
}
示例#4
0
func (ins *inserter) insertList(l capnp.List, typ schema.Type, val reflect.Value) error {
	elem, err := typ.List().ElementType()
	if err != nil {
		return err
	}
	if !isTypeMatch(val.Type(), typ) {
		// TODO(light): the error won't be that useful for nested lists.
		return fmt.Errorf("can't insert Go %v into a %v list", val.Type(), elem.Which())
	}
	n := val.Len()
	switch elem.Which() {
	case schema.Type_Which_void:
	case schema.Type_Which_bool:
		for i := 0; i < n; i++ {
			capnp.BitList{List: l}.Set(i, val.Index(i).Bool())
		}
	case schema.Type_Which_int8:
		for i := 0; i < n; i++ {
			capnp.Int8List{List: l}.Set(i, int8(val.Index(i).Int()))
		}
	case schema.Type_Which_int16:
		for i := 0; i < n; i++ {
			capnp.Int16List{List: l}.Set(i, int16(val.Index(i).Int()))
		}
	case schema.Type_Which_int32:
		for i := 0; i < n; i++ {
			capnp.Int32List{List: l}.Set(i, int32(val.Index(i).Int()))
		}
	case schema.Type_Which_int64:
		for i := 0; i < n; i++ {
			capnp.Int64List{List: l}.Set(i, val.Index(i).Int())
		}
	case schema.Type_Which_uint8:
		for i := 0; i < n; i++ {
			capnp.UInt8List{List: l}.Set(i, uint8(val.Index(i).Uint()))
		}
	case schema.Type_Which_uint16, schema.Type_Which_enum:
		for i := 0; i < n; i++ {
			capnp.UInt16List{List: l}.Set(i, uint16(val.Index(i).Uint()))
		}
	case schema.Type_Which_uint32:
		for i := 0; i < n; i++ {
			capnp.UInt32List{List: l}.Set(i, uint32(val.Index(i).Uint()))
		}
	case schema.Type_Which_uint64:
		for i := 0; i < n; i++ {
			capnp.UInt64List{List: l}.Set(i, val.Index(i).Uint())
		}
	case schema.Type_Which_float32:
		for i := 0; i < n; i++ {
			capnp.Float32List{List: l}.Set(i, float32(val.Index(i).Float()))
		}
	case schema.Type_Which_float64:
		for i := 0; i < n; i++ {
			capnp.Float64List{List: l}.Set(i, val.Index(i).Float())
		}
	case schema.Type_Which_text:
		if val.Type().Elem().Kind() == reflect.String {
			for i := 0; i < n; i++ {
				err := capnp.TextList{List: l}.Set(i, val.Index(i).String())
				if err != nil {
					// TODO(light): collect errors and finish
					return err
				}
			}
		} else {
			for i := 0; i < n; i++ {
				b := val.Index(i).Bytes()
				if len(b) == 0 {
					err := capnp.PointerList{List: l}.SetPtr(i, capnp.Ptr{})
					if err != nil {
						// TODO(light): collect errors and finish
						return err
					}
				}
				t, err := capnp.NewTextFromBytes(l.Segment(), b)
				if err != nil {
					// TODO(light): collect errors and finish
					return err
				}
				err = capnp.PointerList{List: l}.SetPtr(i, t.ToPtr())
				if err != nil {
					// TODO(light): collect errors and finish
					return err
				}
			}
		}
	case schema.Type_Which_data:
		for i := 0; i < n; i++ {
			b := val.Index(i).Bytes()
			if len(b) == 0 {
				err := capnp.PointerList{List: l}.SetPtr(i, capnp.Ptr{})
				if err != nil {
					// TODO(light): collect errors and finish
					return err
				}
			}
			err := capnp.DataList{List: l}.Set(i, b)
			if err != nil {
				// TODO(light): collect errors and finish
				return err
			}
		}
	case schema.Type_Which_list:
		pl := capnp.PointerList{List: l}
		for i := 0; i < n; i++ {
			vi := val.Index(i)
			if vi.IsNil() {
				if err := pl.SetPtr(i, capnp.Ptr{}); err != nil {
					return err
				}
				continue
			}
			ee, err := elem.List().ElementType()
			if err != nil {
				return err
			}
			li, err := ins.newList(l.Segment(), ee, int32(vi.Len()))
			if err != nil {
				return err
			}
			if err := pl.SetPtr(i, li.ToPtr()); err != nil {
				return err
			}
			if err := ins.insertList(li, elem, vi); err != nil {
				return err
			}
		}
	case schema.Type_Which_structType:
		id := elem.StructType().TypeId()
		for i := 0; i < n; i++ {
			err := ins.insertStruct(id, l.Struct(i), val.Index(i))
			if err != nil {
				// TODO(light): collect errors and finish
				return err
			}
		}
	default:
		return fmt.Errorf("unknown list type %v", elem.Which())
	}
	return nil
}
示例#5
0
func (enc *Encoder) marshalList(elem schema.Type, l capnp.List) error {
	enc.w.WriteByte('[')
	switch elem.Which() {
	case schema.Type_Which_void:
		for i := 0; i < l.Len(); i++ {
			if i > 0 {
				enc.w.WriteString(", ")
			}
			enc.w.WriteString(voidMarker)
		}
	case schema.Type_Which_bool:
		bl := capnp.BitList{List: l}
		for i := 0; i < bl.Len(); i++ {
			if i > 0 {
				enc.w.WriteString(", ")
			}
			enc.marshalBool(bl.At(i))
		}
	case schema.Type_Which_int8:
		il := capnp.Int8List{List: l}
		for i := 0; i < il.Len(); i++ {
			if i > 0 {
				enc.w.WriteString(", ")
			}
			enc.marshalInt(int64(il.At(i)))
		}
	case schema.Type_Which_int16:
		il := capnp.Int16List{List: l}
		for i := 0; i < il.Len(); i++ {
			if i > 0 {
				enc.w.WriteString(", ")
			}
			enc.marshalInt(int64(il.At(i)))
		}
	case schema.Type_Which_int32:
		il := capnp.Int32List{List: l}
		for i := 0; i < il.Len(); i++ {
			if i > 0 {
				enc.w.WriteString(", ")
			}
			enc.marshalInt(int64(il.At(i)))
		}
	case schema.Type_Which_int64:
		il := capnp.Int64List{List: l}
		for i := 0; i < il.Len(); i++ {
			if i > 0 {
				enc.w.WriteString(", ")
			}
			enc.marshalInt(il.At(i))
		}
	case schema.Type_Which_uint8:
		il := capnp.UInt8List{List: l}
		for i := 0; i < il.Len(); i++ {
			if i > 0 {
				enc.w.WriteString(", ")
			}
			enc.marshalUint(uint64(il.At(i)))
		}
	case schema.Type_Which_uint16:
		il := capnp.UInt16List{List: l}
		for i := 0; i < il.Len(); i++ {
			if i > 0 {
				enc.w.WriteString(", ")
			}
			enc.marshalUint(uint64(il.At(i)))
		}
	case schema.Type_Which_uint32:
		il := capnp.UInt32List{List: l}
		for i := 0; i < il.Len(); i++ {
			if i > 0 {
				enc.w.WriteString(", ")
			}
			enc.marshalUint(uint64(il.At(i)))
		}
	case schema.Type_Which_uint64:
		il := capnp.UInt64List{List: l}
		for i := 0; i < il.Len(); i++ {
			if i > 0 {
				enc.w.WriteString(", ")
			}
			enc.marshalUint(il.At(i))
		}
	case schema.Type_Which_float32:
		fl := capnp.Float32List{List: l}
		for i := 0; i < fl.Len(); i++ {
			if i > 0 {
				enc.w.WriteString(", ")
			}
			enc.marshalFloat32(fl.At(i))
		}
	case schema.Type_Which_float64:
		fl := capnp.Float64List{List: l}
		for i := 0; i < fl.Len(); i++ {
			if i > 0 {
				enc.w.WriteString(", ")
			}
			enc.marshalFloat64(fl.At(i))
		}
	case schema.Type_Which_data:
		dl := capnp.DataList{List: l}
		for i := 0; i < dl.Len(); i++ {
			if i > 0 {
				enc.w.WriteString(", ")
			}
			d, err := dl.At(i)
			if err != nil {
				return err
			}
			enc.marshalText(d)
		}
	case schema.Type_Which_text:
		tl := capnp.TextList{List: l}
		for i := 0; i < tl.Len(); i++ {
			if i > 0 {
				enc.w.WriteString(", ")
			}
			t, err := tl.BytesAt(i)
			if err != nil {
				return err
			}
			enc.marshalText(t)
		}
	case schema.Type_Which_structType:
		for i := 0; i < l.Len(); i++ {
			if i > 0 {
				enc.w.WriteString(", ")
			}
			err := enc.marshalStruct(elem.StructType().TypeId(), l.Struct(i))
			if err != nil {
				return err
			}
		}
	case schema.Type_Which_list:
		ee, err := elem.List().ElementType()
		if err != nil {
			return err
		}
		for i := 0; i < l.Len(); i++ {
			if i > 0 {
				enc.w.WriteString(", ")
			}
			p, err := capnp.PointerList{List: l}.PtrAt(i)
			if err != nil {
				return err
			}
			err = enc.marshalList(ee, p.List())
			if err != nil {
				return err
			}
		}
	case schema.Type_Which_enum:
		il := capnp.UInt16List{List: l}
		typ := elem.Enum().TypeId()
		// TODO(light): only search for node once
		for i := 0; i < il.Len(); i++ {
			if i > 0 {
				enc.w.WriteString(", ")
			}
			enc.marshalEnum(typ, il.At(i))
		}
	case schema.Type_Which_interface:
		for i := 0; i < l.Len(); i++ {
			if i > 0 {
				enc.w.WriteString(", ")
			}
			enc.w.WriteString(interfaceMarker)
		}
	case schema.Type_Which_anyPointer:
		for i := 0; i < l.Len(); i++ {
			if i > 0 {
				enc.w.WriteString(", ")
			}
			enc.w.WriteString(anyPointerMarker)
		}
	default:
		return fmt.Errorf("unknown list type %v", elem.Which())
	}
	enc.w.WriteByte(']')
	return nil
}