12 Commits

10 changed files with 235 additions and 55 deletions

View File

@@ -6,7 +6,7 @@ PDL allows defining a protocol using HOPP and TAPE.
| Syntax | TN | CN | Description
| ---------- | ------- | -: | -----------
| I5 | SI | |
| I5 | SI | |
| I8 | LSI | 0 |
| I16 | LSI | 1 |
| I32 | LSI | 3 |
@@ -25,6 +25,7 @@ PDL allows defining a protocol using HOPP and TAPE.
| F64 | FP | 7 |
| F128[^2] | FP | 15 |
| F256[^2] | FP | 31 |
| Bool | SI | |
| String | SBA/LBA | * | UTF-8 string
| Buffer | SBA/LBA | * | Byte array
| []\<TYPE\> | OTA | * | Array of any type[^1]

View File

@@ -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.
@@ -112,13 +121,20 @@ func (this *Generator) Generate(protocol *Protocol) (n int, err error) {
return n, nil
}
func (this *Generator) generateTypedef(name string, typ Type) (n int, err error) {
func (this *Generator) generateTypedef(name string, typedef Typedef) (n int, err error) {
typ := typedef.Type
// type definition
nn, err := this.iprintf(
"\n// %s represents the protocol data type %s.\n",
name, name)
n += nn; if err != nil { return n, err }
nn, err = this.iprintf("type %s ", name)
if typedef.Doc == "" {
nn, err := this.iprintf(
"\n// %s represents the protocol data type %s.\n",
name, name)
n += nn; if err != nil { return n, err }
} else {
nn, err := this.iprintf("\n%s\n", this.formatComment(typedef.Doc))
n += nn; if err != nil { return n, err }
}
nn, err := this.iprintf("type %s ", name)
n += nn; if err != nil { return n, err }
nn, err = this.generateType(typ)
n += nn; if err != nil { return n, err }
@@ -208,10 +224,16 @@ func (this *Generator) generateTypedef(name string, typ Type) (n int, err error)
// generateMessage generates the structure, as well as encoding decoding
// functions for the given message.
func (this *Generator) generateMessage(method uint16, message Message) (n int, err error) {
nn, err := this.iprintf(
"\n// %s represents the protocol message M%04X %s.\n",
message.Name, method, message.Name)
nn, err = this.iprintf("type %s ", this.resolveMessageName(message.Name))
if message.Doc == "" {
nn, err := this.iprintf(
"\n// %s represents the protocol message M%04X %s.\n",
message.Name, method, message.Name)
n += nn; if err != nil { return n, err }
} else {
nn, err := this.iprintf("\n%s\n", this.formatComment(message.Doc))
n += nn; if err != nil { return n, err }
}
nn, err := this.iprintf("type %s ", this.resolveMessageName(message.Name))
n += nn; if err != nil { return n, err }
nn, err = this.generateType(message.Type)
n += nn; if err != nil { return n, err }
@@ -302,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>
@@ -505,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>
@@ -931,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)
@@ -984,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")
@@ -1027,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
@@ -1090,7 +1129,9 @@ func (this *Generator) generateTypeTableDefined(typ TypeTableDefined) (n int, er
for _, key := range slices.Sorted(maps.Keys(typ.Fields)) {
field := typ.Fields[key]
nn, err := this.iprintf("%s ", field.Name)
nn, err := this.iprintf("%s\n", this.formatComment(field.Doc))
n += nn; if err != nil { return n, err }
nn, err = this.iprintf("%s ", field.Name)
n += nn; if err != nil { return n, err }
nn, err = this.generateType(field.Type)
n += nn; if err != nil { return n, err }
@@ -1175,17 +1216,21 @@ func (this *Generator) iprintf(format string, args ...any) (n int, err error) {
return fmt.Fprintf(this.Output, this.indent() + format, args...)
}
func (this *Generator) formatComment(comment string) string {
return "// " + strings.ReplaceAll(comment, "\n", "\n" + this.indent() + "// ")
}
func (this *Generator) resolveMessageName(message string) string {
return "Message" + message
}
func (this *Generator) resolveTypeName(name string) (Type, error) {
if typ, ok := this.protocol.Types[name]; ok {
if typ, ok := typ.(TypeNamed); ok {
if typedef, ok := this.protocol.Types[name]; ok {
if typ, ok := typedef.Type.(TypeNamed); ok {
return this.resolveTypeName(typ.Name)
}
return typ, nil
return typedef.Type, nil
}
return nil, fmt.Errorf("no type exists called %s", name)
}

View File

@@ -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 { } },
},
},
}
@@ -83,11 +84,13 @@ func init() {
},
},
}
exampleProtocol.Types["User"] = TypeTableDefined {
Fields: map[uint16] Field {
0x0000: Field { Name: "Name", Type: TypeString { } },
0x0001: Field { Name: "Bio", Type: TypeString { } },
0x0002: Field { Name: "Followers", Type: TypeInt { Bits: 32 } },
exampleProtocol.Types["User"] = Typedef {
Type: TypeTableDefined {
Fields: map[uint16] Field {
0x0000: Field { Name: "Name", Type: TypeString { } },
0x0001: Field { Name: "Bio", Type: TypeString { } },
0x0002: Field { Name: "Followers", Type: TypeInt { Bits: 32 } },
},
},
}
}
@@ -199,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 },
@@ -216,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 {

View File

@@ -15,6 +15,7 @@ const (
TokenRBrace
TokenLBracket
TokenRBracket
TokenComment
)
var tokenNames = map[parse.TokenKind] string {
@@ -26,6 +27,7 @@ var tokenNames = map[parse.TokenKind] string {
TokenRBrace: "RBrace",
TokenLBracket: "LBracket",
TokenRBracket: "RBracket",
TokenComment: "Comment",
}
func Lex(fileName string, reader io.Reader) (parse.Lexer, error) {
@@ -81,6 +83,18 @@ func (this *lexer) nextInternal() (token parse.Token, err error) {
}
}
unexpected := func() error {
if unicode.IsPrint(this.rune) {
return parse.Errorf (
this.pos(), "unexpected rune '%c'",
this.rune)
} else {
return parse.Errorf (
this.pos(), "unexpected rune %U",
this.rune)
}
}
defer func () {
newPos := this.pos()
newPos.End -- // TODO figure out why tf we have to do this
@@ -133,14 +147,21 @@ func (this *lexer) nextInternal() (token parse.Token, err error) {
token.Kind = TokenRBracket
appendRune()
if this.eof { err = nil; return }
case unicode.IsPrint(this.rune):
err = parse.Errorf (
this.pos(), "unexpected rune '%c'",
this.rune)
// Comment
case this.rune == '/':
token.Kind = TokenComment
appendRune()
if this.eof { return }
if this.rune != '/' {
err = unexpected()
return
}
for this.rune != '\n' {
appendRune()
if this.eof { err = nil; return }
}
default:
err = parse.Errorf (
this.pos(), "unexpected rune %U",
this.rune)
err = unexpected()
}
return

View File

@@ -6,14 +6,21 @@ import "git.tebibyte.media/sashakoshka/goparse"
func TestLex(test *testing.T) {
lexer, err := Lex("test.pdl", strings.NewReader(`
// User holds profile information about a single user.
M0001 User {
0000 Name String,
// dog water comment
// Users is asdkjsagkj why
//
// wow
0001 Users []User,
0002 Followers U32,
}`))
if err != nil { test.Fatal(parse.Format(err)) }
correctTokens := []parse.Token {
tok(TokenComment, "// User holds profile information about a single user."),
tok(TokenMethod, "0001"),
tok(TokenIdent, "User"),
tok(TokenLBrace, "{"),
@@ -21,6 +28,10 @@ func TestLex(test *testing.T) {
tok(TokenIdent, "Name"),
tok(TokenIdent, "String"),
tok(TokenComma, ","),
tok(TokenComment, "// dog water comment"),
tok(TokenComment, "// Users is asdkjsagkj why"),
tok(TokenComment, "// "),
tok(TokenComment, "// wow"),
tok(TokenKey, "0001"),
tok(TokenIdent, "Users"),
tok(TokenLBracket, "["),

View File

@@ -1,6 +1,7 @@
package generate
import "io"
import "strings"
import "strconv"
import "git.tebibyte.media/sashakoshka/goparse"
@@ -21,7 +22,7 @@ func Parse(lx parse.Lexer) (*Protocol, error) {
func defaultProtocol() Protocol {
return Protocol {
Messages: make(map[uint16] Message),
Types: map[string] Type { },
Types: map[string] Typedef { },
}
}
@@ -47,18 +48,28 @@ func (this *parser) parse() error {
}
func (this *parser) parseTopLevel() error {
err := this.ExpectDesc("message or typedef", TokenMethod, TokenIdent)
if err != nil { return err }
if this.EOF() { return nil }
doc := ""
for {
err := this.ExpectDesc("message or typedef", TokenMethod, TokenIdent, TokenComment)
if err != nil { return err }
if this.EOF() { return nil }
if this.Kind() == TokenComment {
if doc != "" { doc += "\n" }
doc += this.parseComment(this.Value())
this.Next()
} else {
break
}
}
switch this.Kind() {
case TokenMethod: return this.parseMessage()
case TokenIdent: return this.parseTypedef()
case TokenMethod: return this.parseMessage(doc)
case TokenIdent: return this.parseTypedef(doc)
}
panic("bug")
}
func (this *parser) parseMessage() error {
func (this *parser) parseMessage(doc string) error {
err := this.Expect(TokenMethod)
if err != nil { return err }
method, err := this.parseHexNumber(this.Value(), 0xFFFF)
@@ -72,12 +83,13 @@ func (this *parser) parseMessage() error {
if err != nil { return err }
this.protocol.Messages[uint16(method)] = Message {
Name: name,
Doc: doc,
Type: typ,
}
return nil
}
func (this *parser) parseTypedef() error {
func (this *parser) parseTypedef(doc string) error {
err := this.Expect(TokenIdent)
if err != nil { return err }
name := this.Value()
@@ -85,7 +97,10 @@ func (this *parser) parseTypedef() error {
if err != nil { return err }
typ, err := this.parseType()
if err != nil { return err }
this.protocol.Types[name] = typ
this.protocol.Types[name] = Typedef {
Doc: doc,
Type: typ,
}
return nil
}
@@ -117,6 +132,7 @@ func (this *parser) parseType() (Type, error) {
case "Buffer": return TypeBuffer { }, this.Next()
case "Table": return TypeTable { }, this.Next()
case "Any": return TypeAny { }, this.Next()
case "Bool": return TypeBool { }, this.Next()
}
return this.parseTypeNamed()
case TokenLBracket:
@@ -157,12 +173,22 @@ func (this *parser) parseTypeTable() (TypeTableDefined, error) {
Fields: make(map[uint16] Field),
}
for {
err := this.ExpectDesc("table field", TokenKey, TokenRBrace)
if err != nil { return TypeTableDefined { }, err }
doc := ""
for {
err := this.ExpectDesc("table field", TokenKey, TokenRBrace, TokenComment)
if err != nil { return TypeTableDefined { }, err }
if this.Kind() == TokenComment {
if doc != "" { doc += "\n" }
doc += this.parseComment(this.Value())
this.Next()
} else {
break
}
}
if this.Is(TokenRBrace) {
break
}
key, field, err := this.parseField()
key, field, err := this.parseField(doc)
if err != nil { return TypeTableDefined { }, err }
typ.Fields[key] = field
err = this.Expect(TokenComma, TokenRBrace)
@@ -178,7 +204,7 @@ func (this *parser) parseTypeTable() (TypeTableDefined, error) {
return typ, nil
}
func (this *parser) parseField() (uint16, Field, error) {
func (this *parser) parseField(doc string) (uint16, Field, error) {
err := this.Expect(TokenKey)
if err != nil { return 0, Field { }, err }
key, err := this.parseHexNumber(this.Value(), 0xFFFF)
@@ -192,6 +218,7 @@ func (this *parser) parseField() (uint16, Field, error) {
if err != nil { return 0, Field { }, err }
return uint16(key), Field {
Name: name,
Doc: doc,
Type: typ,
}, nil
}
@@ -206,3 +233,7 @@ func (this *parser) parseHexNumber(input string, maxValue int64) (int64, error)
}
return number, nil
}
func (this *parser) parseComment(input string) string {
return strings.TrimPrefix(strings.TrimPrefix(input, "//"), " ")
}

View File

@@ -9,6 +9,7 @@ func TestParse(test *testing.T) {
correct := defaultProtocol()
correct.Messages[0x0000] = Message {
Name: "Connect",
Doc: "Connect is sent from the client to the server as the first message of an\nauthenticated transaction.",
Type: TypeTableDefined {
Fields: map[uint16] Field {
0x0000: Field { Name: "Name", Type: TypeString { } },
@@ -18,36 +19,50 @@ func TestParse(test *testing.T) {
}
correct.Messages[0x0001] = Message {
Name: "UserList",
Doc: "UserList is sent from the server to the client in response to a Connect\nmessage.",
Type: TypeTableDefined {
Fields: map[uint16] Field {
0x0000: Field { Name: "Users", Type: TypeArray { Element: TypeNamed { Name: "User" } } },
},
},
}
correct.Types["User"] = TypeTableDefined {
Fields: map[uint16] Field {
0x0000: Field { Name: "Name", Type: TypeString { } },
0x0001: Field { Name: "Bio", Type: TypeString { } },
0x0002: Field { Name: "Followers", Type: TypeInt { Bits: 32 } },
correct.Types["User"] = Typedef {
Doc: "User holds profile information about a single user.",
Type: TypeTableDefined {
Fields: map[uint16] Field {
0x0000: Field { Name: "Name", Type: TypeString { } },
0x0001: Field { Name: "Bio", Type: TypeString { } },
0x0002: Field { Name: "Followers", Type: TypeInt { Bits: 32 } },
0x0003: Field { Name: "Bouncy", Type: TypeBool { } },
},
},
}
correct.Types["Anything"] = TypeAny { }
correct.Types["Anything"] = Typedef {
Type: TypeAny { },
}
test.Log("CORRECT:", &correct)
got, err := ParseReader("test.pdl", strings.NewReader(`
// Connect is sent from the client to the server as the first message of an
// authenticated transaction.
M0000 Connect {
0000 Name String,
// Password is where you put your secrets, your shameful secrets
0001 Password String,
}
// UserList is sent from the server to the client in response to a Connect
// message.
M0001 UserList {
0000 Users []User,
}
// User holds profile information about a single user.
User {
0000 Name String,
0001 Bio String,
0002 Followers U32,
0003 Bouncy Bool,
}
Anything Any

View File

@@ -7,11 +7,17 @@ import "crypto/md5"
type Protocol struct {
Messages map[uint16] Message
Types map[string] Type
Types map[string] Typedef
}
type Message struct {
Name string
Doc string
Type Type
}
type Typedef struct {
Doc string
Type Type
}
@@ -43,6 +49,12 @@ func (typ TypeFloat) String() string {
return fmt.Sprintf("F%d", typ.Bits)
}
type TypeBool struct { }
func (TypeBool) String() string {
return "Bool"
}
type TypeString struct { }
func (TypeString) String() string {
@@ -84,6 +96,7 @@ func (typ TypeTableDefined) String() string {
type Field struct {
Name string
Doc string
Type Type
}

View File

@@ -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():

View File

@@ -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))