6 Commits

5 changed files with 43 additions and 17 deletions

View File

@@ -24,7 +24,7 @@ const preamble = `
const static = `
// Table is a KTV table with an undefined schema.
type Table map[uint16] any
type Table = map[uint16] any
// Message is any message that can be sent along this protocol.
type Message interface {

View File

@@ -100,12 +100,12 @@ func testGenerateRun(test *testing.T, protocol *Protocol, title, imports, testCa
log.Println("decoding:")
destination := reflect.New(reflect.ValueOf(message).Elem().Type()).Interface().(Message)
flat := data.Flatten()
log.Println("before: ", destination)
log.Println("before: ", tu.Describe(destination))
decoder := tape.NewDecoder(bytes.NewBuffer(flat))
n, err = destination.Decode(decoder)
if err != nil { log.Fatalf("at %d: %v\n", n, err) }
log.Println("got: ", destination)
log.Println("correct:", message)
log.Println("got: ", tu.Describe(destination))
log.Println("correct:", tu.Describe(message))
if n != len(flat) {
log.Fatalf("n incorrect: %d != %d\n", n, len(flat))
}

View File

@@ -125,6 +125,10 @@ func (this *describer) describe(value reflect.Value) {
return
}
value = reflect.ValueOf(value.Interface())
if !value.IsValid() {
this.printf("<invalid>")
return
}
switch value.Kind() {
case reflect.Array, reflect.Slice:
this.printf("[\n")
@@ -155,7 +159,7 @@ func (this *describer) describe(value reflect.Value) {
this.iprintf("\n")
}
this.indent -= 1
this.iprintf("}\n")
this.iprintf("}")
case reflect.Map:
this.printf("map {\n")
this.indent += 1
@@ -168,7 +172,7 @@ func (this *describer) describe(value reflect.Value) {
this.iprintf("\n")
}
this.indent -= 1
this.iprintf("}\n")
this.iprintf("}")
case reflect.Pointer:
this.printf("& ")
this.describe(value.Elem())

View File

@@ -242,12 +242,22 @@ func decodeAnyOrError(decoder *Decoder, destination reflect.Value, tag Tag) (n i
}
lengthCast, err := Uint64ToIntSafe(length)
if err != nil { return n, err }
if isTypeAny(destination.Type()) {
// need a skeleton value if we are assigning to any.
value := reflect.MakeMapWithSize(reflect.TypeOf(dummyMap), lengthCast)
destination.Set(value)
destination = value
}
// im fucking so done dude. im so fucking done. this was
// supposed to only run when we need it but i guess it runs all
// the time, because when we get a map destination (a valid,
// allocated one) we break apart on SetMapIndex because of a nil
// map. yeah thats right. a fucking nil map panic. on the map we
// just allocated. but running this unconditionally (whether or
// not we receive an empty any value) actually makes it fucking
// work. go figure().
//
// (the map allocation functionality in skeletonPointer has been
// removed)
value := reflect.MakeMapWithSize(reflect.TypeOf(dummyMap), lengthCast)
destination.Set(value)
destination = value
destination.Clear()
for _ = range lengthCast {
key, nn, err := decoder.ReadUint16()
@@ -387,7 +397,11 @@ func canSet(destination reflect.Type, tag Tag) error {
return errCantAssignf("cannot assign array to %v", destination)
}
case KTV:
if destination != reflect.TypeOf(dummyMap) {
cantAssign :=
destination.Kind() != reflect.Map ||
destination.Key().Kind() != reflect.Uint16 ||
!isTypeAny(destination.Elem())
if cantAssign {
return errCantAssignf("cannot assign table to %v", destination)
}
default:
@@ -497,9 +511,6 @@ func skeletonPointer(decoder *Decoder, tag Tag) (reflect.Value, error) {
typ, err := typeOf(decoder, tag)
if err != nil { return reflect.Value { }, err }
value := reflect.New(typ)
if tag.Is(KTV) {
value.Elem().Set(reflect.MakeMap(typ))
}
return value, nil
}

View File

@@ -27,6 +27,12 @@ var samplePayloads = [][]byte {
0x02, 0x23, byte(LSI.WithCN(1)), 0x45, 0x67,
0x02, 0x24, byte(LI.WithCN(3)), 0x45, 0x67, 0x89, 0xAB,
},
/* map[uint16] any */ []byte {
byte(KTV.WithCN(0)), 3,
0x00, 0x01, 0x63, 0x43, 0xF4, 0xC0, 0x00,
0x00, 0x02, 0x82, 'h', 'i',
0x00, 0x03, 0x21, 0x39, 0x92,
},
}
var sampleValues = []any {
@@ -49,6 +55,11 @@ var sampleValues = []any {
0x0223: int16(0x4567),
0x0224: uint32(0x456789AB),
},
/* map[uint16] any */ map[uint16] any {
0x0001: float32(489.5),
0x0002: "hi",
0x0003: uint16(0x3992),
},
}
type userDefinedInteger int16
@@ -195,7 +206,7 @@ func TestDecodeWrongType(test *testing.T) {
{ var dest []string; arrayCase(&dest) }
}
// tables should only assign to other tables
if index != 12 {
if index != 12 && index != 13 {
test.Log("- map[uint16] any")
{ var dest = map[uint16] any { }; arrayCase(&dest) }
}