Compare commits
5 Commits
770f6b05b4
...
0ac26711ac
| Author | SHA1 | Date | |
|---|---|---|---|
| 0ac26711ac | |||
| 8446ae6186 | |||
| c511ebcb15 | |||
| 00b0f13d3e | |||
| 13d35e54f5 |
@ -47,6 +47,15 @@ func canAssign(destination, source tape.Tag) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// boolInt converts a bool to an integer.
|
||||
func boolInt(input bool) int {
|
||||
if input {
|
||||
return 1
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
// Generator converts protocols into Go code.
|
||||
@ -315,6 +324,9 @@ func (this *Generator) generateMessage(method uint16, message Message) (n int, e
|
||||
// - nn int
|
||||
func (this *Generator) generateEncodeValue(typ Type, valueSource, tagSource string) (n int, err error) {
|
||||
switch typ := typ.(type) {
|
||||
case TypeBool:
|
||||
// SI: (none)
|
||||
// SI stores the value in the tag, so we write nothing here
|
||||
case TypeInt:
|
||||
// SI: (none)
|
||||
// LI/LSI: <value: IntN>
|
||||
@ -518,6 +530,11 @@ func (this *Generator) generateEncodeValue(typ Type, valueSource, tagSource stri
|
||||
// for [Generator.generateDecodeBranch].
|
||||
func (this *Generator) generateDecodeValue(typ Type, typeName, valueSource, tagSource string) (n int, err error) {
|
||||
switch typ := typ.(type) {
|
||||
case TypeBool:
|
||||
// SI: (none)
|
||||
// SI stores the value in the tag
|
||||
nn, err := this.iprintf("*%s = %s.CN() > 0\n", valueSource, tagSource)
|
||||
n += nn; if err != nil { return n, err }
|
||||
case TypeInt:
|
||||
// SI: (none)
|
||||
// LI/LSI: <value: IntN>
|
||||
@ -944,6 +961,9 @@ func (this *Generator) generateBareErrorCheck() (n int, err error) {
|
||||
func (this *Generator) generateTag(typ Type, source string) (tagVar string, n int, err error) {
|
||||
tagVar = this.newTemporaryVar("tag")
|
||||
switch typ := typ.(type) {
|
||||
case TypeBool:
|
||||
nn, err := this.iprintf("%s := tape.SI.WithCN(boolInt(bool(%s)))\n", tagVar, source)
|
||||
n += nn; if err != nil { return tagVar, n, err }
|
||||
case TypeInt:
|
||||
if typ.Bits <= 5 {
|
||||
nn, err := this.iprintf("%s := tape.SI.WithCN(int(%s))\n", tagVar, source)
|
||||
@ -997,6 +1017,9 @@ func (this *Generator) generateTag(typ Type, source string) (tagVar string, n in
|
||||
// information is chosen.
|
||||
func (this *Generator) generateTN(typ Type) (n int, err error) {
|
||||
switch typ := typ.(type) {
|
||||
case TypeBool:
|
||||
nn, err := this.printf("tape.SI")
|
||||
n += nn; if err != nil { return n, err }
|
||||
case TypeInt:
|
||||
if typ.Bits <= 5 {
|
||||
nn, err := this.printf("tape.SI")
|
||||
@ -1040,6 +1063,9 @@ func (this *Generator) generateTN(typ Type) (n int, err error) {
|
||||
|
||||
func (this *Generator) generateType(typ Type) (n int, err error) {
|
||||
switch typ := typ.(type) {
|
||||
case TypeBool:
|
||||
nn, err := this.printf("bool")
|
||||
n += nn; if err != nil { return n, err }
|
||||
case TypeInt:
|
||||
if err := this.validateIntBitSize(typ.Bits); err != nil {
|
||||
return n, err
|
||||
|
||||
@ -59,6 +59,7 @@ func init() {
|
||||
0x000C: Field { Name: "NI16",Type: TypeInt { Bits: 16, Signed: true } },
|
||||
0x000D: Field { Name: "NI32",Type: TypeInt { Bits: 32, Signed: true } },
|
||||
0x000E: Field { Name: "NI64",Type: TypeInt { Bits: 64, Signed: true } },
|
||||
0x000F: Field { Name: "Bool",Type: TypeBool { } },
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -201,10 +202,11 @@ func TestGenerateRunEncodeDecode(test *testing.T) {
|
||||
NI16: -0x34C9,
|
||||
NI32: -0x10E134C9,
|
||||
NI64: -0x639109BC10E134C9,
|
||||
Bool: true,
|
||||
}
|
||||
testEncodeDecode(
|
||||
&messageIntegers,
|
||||
tu.S(0xE0, 13).AddVar(
|
||||
tu.S(0xE0, 14).AddVar(
|
||||
[]byte { 0x00, 0x00, 0x13 },
|
||||
[]byte { 0x00, 0x01, 0x20, 0xC9 },
|
||||
[]byte { 0x00, 0x02, 0x21, 0x34, 0xC9 },
|
||||
@ -218,6 +220,7 @@ func TestGenerateRunEncodeDecode(test *testing.T) {
|
||||
[]byte { 0x00, 0x0C, 0x41, 0xCB, 0x37 },
|
||||
[]byte { 0x00, 0x0D, 0x43, 0xEF, 0x1E, 0xCB, 0x37 },
|
||||
[]byte { 0x00, 0x0E, 0x47, 0x9C, 0x6E, 0xF6, 0x43, 0xEF, 0x1E, 0xCB, 0x37 },
|
||||
[]byte { 0x00, 0x0F, 0x01 },
|
||||
))
|
||||
log.Println("MessageDynamic")
|
||||
messageDynamic := MessageDynamic {
|
||||
|
||||
@ -59,6 +59,7 @@ func EncodeAny(encoder *Encoder, value any, tag Tag) (n int, err error) {
|
||||
case reflect.Uint64: return encoder.WriteUint64(uint64(reflectValue.Uint()))
|
||||
case reflect.Float32: return encoder.WriteFloat32(float32(reflectValue.Float()))
|
||||
case reflect.Float64: return encoder.WriteFloat64(float64(reflectValue.Float()))
|
||||
case reflect.Bool: return // SI has no payload
|
||||
case reflect.String:
|
||||
if reflectValue.Len() > MaxStructureLength {
|
||||
return 0, ErrTooLong
|
||||
@ -298,6 +299,12 @@ func tagAny(reflectValue reflect.Value) (Tag, error) {
|
||||
case reflect.Uint64: return LI.WithCN(7), nil
|
||||
case reflect.Float32: return FP.WithCN(3), nil
|
||||
case reflect.Float64: return FP.WithCN(7), nil
|
||||
case reflect.Bool:
|
||||
if reflectValue.Bool() {
|
||||
return SI.WithCN(1), nil
|
||||
} else {
|
||||
return SI.WithCN(0), nil
|
||||
}
|
||||
case reflect.String: return bufferLenTag(reflectValue.Len()), nil
|
||||
}
|
||||
if reflectValue.CanConvert(reflect.TypeOf(dummyBuffer)) {
|
||||
@ -374,7 +381,8 @@ func canSet(destination reflect.Type, tag Tag) error {
|
||||
switch destination.Kind() {
|
||||
case
|
||||
reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
|
||||
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
|
||||
reflect.Bool:
|
||||
default:
|
||||
return errCantAssignf("cannot assign integer to %v", destination)
|
||||
}
|
||||
@ -432,6 +440,8 @@ func setInt(destination reflect.Value, value int64, bytes int) {
|
||||
// setUint expects a settable destination.
|
||||
func setUint(destination reflect.Value, value uint64, bytes int) {
|
||||
switch {
|
||||
case destination.Kind() == reflect.Bool:
|
||||
destination.Set(reflect.ValueOf(value > 0))
|
||||
case destination.CanInt():
|
||||
destination.Set(reflect.ValueOf(int64(value)).Convert(destination.Type()))
|
||||
case destination.CanUint():
|
||||
|
||||
@ -15,6 +15,8 @@ var samplePayloads = [][]byte {
|
||||
/* uint16 */ []byte { byte(LI.WithCN(1)), 0x45, 0x67 },
|
||||
/* uint32 */ []byte { byte(LI.WithCN(3)), 0x45, 0x67, 0x89, 0xAB },
|
||||
/* uint64 */ []byte { byte(LI.WithCN(7)), 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23 },
|
||||
/* bool */ []byte { byte(SI.WithCN(0)) },
|
||||
/* bool */ []byte { byte(SI.WithCN(1)) },
|
||||
/* string */ []byte { byte(SBA.WithCN(7)), 'p', 'u', 'p', 'e', 'v', 'e', 'r' },
|
||||
/* []byte */ []byte { byte(SBA.WithCN(5)), 'b', 'l', 'a', 'r', 'g' },
|
||||
/* []string */ []byte {
|
||||
@ -45,6 +47,8 @@ var sampleValues = []any {
|
||||
/* uint16 */ uint16(0x4567),
|
||||
/* uint32 */ uint32(0x456789AB),
|
||||
/* uint64 */ uint64(0x456789ABCDEF0123),
|
||||
/* bool */ false,
|
||||
/* bool */ true,
|
||||
/* string */ "pupever",
|
||||
/* []byte */ "blarg",
|
||||
/* []string */ []string {
|
||||
@ -84,7 +88,9 @@ func TestEncodeAnyTable(test *testing.T) {
|
||||
0x3456: userDefinedInteger(0x3921),
|
||||
0x1F1F: float32(67.26),
|
||||
0x0F0F: float64(5.3),
|
||||
}, KTV.WithCN(0), tu.S(9).AddVar(
|
||||
0xAAAA: false,
|
||||
0xBBBB: true,
|
||||
}, KTV.WithCN(0), tu.S(11).AddVar(
|
||||
[]byte {
|
||||
0xF3, 0xB9,
|
||||
byte(LSI.WithCN(3)),
|
||||
@ -138,6 +144,14 @@ func TestEncodeAnyTable(test *testing.T) {
|
||||
byte(FP.WithCN(7)),
|
||||
0x40, 0x15, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
|
||||
},
|
||||
[]byte {
|
||||
0xAA, 0xAA,
|
||||
byte(SI.WithCN(0)),
|
||||
},
|
||||
[]byte {
|
||||
0xBB, 0xBB,
|
||||
byte(SI.WithCN(1)),
|
||||
},
|
||||
))
|
||||
if err != nil { test.Fatal(err) }
|
||||
}
|
||||
@ -146,7 +160,7 @@ func TestDecodeWrongType(test *testing.T) {
|
||||
for index, data := range samplePayloads {
|
||||
test.Logf("data %2d %v [%s]", index, Tag(data[0]), tu.HexBytes(data[1:]))
|
||||
// integers should only assign to other integers
|
||||
if index > 8 {
|
||||
if index > 10 {
|
||||
cas := func(destination any) {
|
||||
n, err := DecodeAnyInto(NewDecoder(bytes.NewBuffer(data[1:])), destination, Tag(data[0]))
|
||||
if err != nil { test.Fatalf("error: %v | n: %d", err, n) }
|
||||
@ -155,7 +169,7 @@ func TestDecodeWrongType(test *testing.T) {
|
||||
if reflectValue.Int() != 0 {
|
||||
test.Fatalf("destination not zero: %v", reflectValue.Elem().Interface())
|
||||
}
|
||||
} else {
|
||||
} else if reflectValue.Kind() != reflect.Bool {
|
||||
if reflectValue.Uint() != 0 {
|
||||
test.Fatalf("destination not zero: %v", reflectValue.Elem().Interface())
|
||||
}
|
||||
@ -180,6 +194,8 @@ func TestDecodeWrongType(test *testing.T) {
|
||||
{ var dest uint32; cas(&dest) }
|
||||
test.Log("- uint64")
|
||||
{ var dest uint64; cas(&dest) }
|
||||
test.Log("- bool")
|
||||
{ var dest bool; cas(&dest) }
|
||||
}
|
||||
arrayCase := func(destination any) {
|
||||
n, err := DecodeAnyInto(NewDecoder(bytes.NewBuffer(data[1:])), destination, Tag(data[0]))
|
||||
@ -194,19 +210,19 @@ func TestDecodeWrongType(test *testing.T) {
|
||||
}
|
||||
}
|
||||
// SBA/LBA types should only assign to other SBA/LBA types
|
||||
if index != 9 && index != 10 {
|
||||
if index != 11 && index != 12 {
|
||||
test.Log("- string")
|
||||
{ var dest string; arrayCase(&dest) }
|
||||
test.Log("- []byte")
|
||||
{ var dest []byte; arrayCase(&dest) }
|
||||
}
|
||||
// arrays should only assign to other arrays
|
||||
if index != 11 {
|
||||
if index != 13 {
|
||||
test.Log("- []string")
|
||||
{ var dest []string; arrayCase(&dest) }
|
||||
}
|
||||
// tables should only assign to other tables
|
||||
if index != 12 && index != 13 {
|
||||
if index != 14 && index != 15 {
|
||||
test.Log("- map[uint16] any")
|
||||
{ var dest = map[uint16] any { }; arrayCase(&dest) }
|
||||
}
|
||||
@ -231,6 +247,12 @@ func TestEncodeDecodeAnyTable(test *testing.T) {
|
||||
func TestEncodeDecodeAnyDestination(test *testing.T) {
|
||||
var destination any
|
||||
for index, data := range samplePayloads {
|
||||
if _, isBool := sampleValues[index].(bool); isBool {
|
||||
// test is invalid for bools because they are never
|
||||
// created as a skeleton value
|
||||
continue
|
||||
}
|
||||
|
||||
tag := Tag(data[0])
|
||||
payload := data[1:]
|
||||
test.Logf("data %2d %v [%s]", index, tag, tu.HexBytes(payload))
|
||||
@ -349,6 +371,12 @@ func TestTagAny(test *testing.T) {
|
||||
|
||||
func TestDecodeAny(test *testing.T) {
|
||||
for index, payload := range samplePayloads {
|
||||
if _, isBool := sampleValues[index].(bool); isBool {
|
||||
// test is invalid for bools because they are never
|
||||
// created as a skeleton value
|
||||
continue
|
||||
}
|
||||
|
||||
correctValue := sampleValues[index]
|
||||
data := payload[1:]
|
||||
decoder := NewDecoder(bytes.NewBuffer(data))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user