func (enc *Encoder) marshalFieldValue(s capnp.Struct, f schema.Field) error { typ, err := f.Slot().Type() if err != nil { return err } dv, err := f.Slot().DefaultValue() if err != nil { return err } if dv.IsValid() && int(typ.Which()) != int(dv.Which()) { name, _ := f.Name() return fmt.Errorf("marshal field %s: default value is a %v, want %v", name, dv.Which(), typ.Which()) } switch typ.Which() { case schema.Type_Which_void: enc.w.WriteString(voidMarker) case schema.Type_Which_bool: v := s.Bit(capnp.BitOffset(f.Slot().Offset())) d := dv.Bool() enc.marshalBool(!d && v || d && !v) case schema.Type_Which_int8: v := s.Uint8(capnp.DataOffset(f.Slot().Offset())) d := uint8(dv.Int8()) enc.marshalInt(int64(int8(v ^ d))) case schema.Type_Which_int16: v := s.Uint16(capnp.DataOffset(f.Slot().Offset() * 2)) d := uint16(dv.Int16()) enc.marshalInt(int64(int16(v ^ d))) case schema.Type_Which_int32: v := s.Uint32(capnp.DataOffset(f.Slot().Offset() * 4)) d := uint32(dv.Int32()) enc.marshalInt(int64(int32(v ^ d))) case schema.Type_Which_int64: v := s.Uint64(capnp.DataOffset(f.Slot().Offset() * 8)) d := uint64(dv.Int64()) enc.marshalInt(int64(v ^ d)) case schema.Type_Which_uint8: v := s.Uint8(capnp.DataOffset(f.Slot().Offset())) d := dv.Uint8() enc.marshalUint(uint64(v ^ d)) case schema.Type_Which_uint16: v := s.Uint16(capnp.DataOffset(f.Slot().Offset() * 2)) d := dv.Uint16() enc.marshalUint(uint64(v ^ d)) case schema.Type_Which_uint32: v := s.Uint32(capnp.DataOffset(f.Slot().Offset() * 4)) d := dv.Uint32() enc.marshalUint(uint64(v ^ d)) case schema.Type_Which_uint64: v := s.Uint64(capnp.DataOffset(f.Slot().Offset() * 8)) d := dv.Uint64() enc.marshalUint(v ^ d) case schema.Type_Which_float32: v := s.Uint32(capnp.DataOffset(f.Slot().Offset() * 4)) d := math.Float32bits(dv.Float32()) enc.marshalFloat32(math.Float32frombits(v ^ d)) case schema.Type_Which_float64: v := s.Uint64(capnp.DataOffset(f.Slot().Offset() * 8)) d := math.Float64bits(dv.Float64()) enc.marshalFloat64(math.Float64frombits(v ^ d)) case schema.Type_Which_structType: p, err := s.Ptr(uint16(f.Slot().Offset())) if err != nil { return err } if !p.IsValid() { p, _ = dv.StructValuePtr() } return enc.marshalStruct(typ.StructType().TypeId(), p.Struct()) case schema.Type_Which_data: p, err := s.Ptr(uint16(f.Slot().Offset())) if err != nil { return err } if !p.IsValid() { b, _ := dv.Data() enc.marshalText(b) return nil } enc.marshalText(p.Data()) case schema.Type_Which_text: p, err := s.Ptr(uint16(f.Slot().Offset())) if err != nil { return err } if !p.IsValid() { b, _ := dv.TextBytes() enc.marshalText(b) return nil } enc.marshalText(p.TextBytes()) case schema.Type_Which_list: elem, err := typ.List().ElementType() if err != nil { return err } p, err := s.Ptr(uint16(f.Slot().Offset())) if err != nil { return err } if !p.IsValid() { p, _ = dv.ListPtr() } return enc.marshalList(elem, p.List()) case schema.Type_Which_enum: v := s.Uint16(capnp.DataOffset(f.Slot().Offset() * 2)) d := dv.Uint16() return enc.marshalEnum(typ.Enum().TypeId(), v^d) case schema.Type_Which_interface: enc.w.WriteString(interfaceMarker) case schema.Type_Which_anyPointer: enc.w.WriteString(anyPointerMarker) default: return fmt.Errorf("unknown field type %v", typ.Which()) } return nil }