message-size-increase #3

Merged
sashakoshka merged 227 commits from message-size-increase into main 2025-09-07 19:27:38 -06:00
2 changed files with 196 additions and 44 deletions
Showing only changes of commit a4da33536c - Show all commits

View File

@ -14,6 +14,14 @@ import "reflect"
var dummyMap map[uint16] any var dummyMap map[uint16] any
var dummyBuffer []byte var dummyBuffer []byte
type errCantAssign string
func (err errCantAssign) Error() string {
return string(err)
}
func errCantAssignf(format string, v ...any) errCantAssign {
return errCantAssign(fmt.Sprintf(format, v...))
}
// EncodeAny encodes an "any" value. Returns an error if the underlying type is // EncodeAny encodes an "any" value. Returns an error if the underlying type is
// unsupported. Supported types are: // unsupported. Supported types are:
// //
@ -83,20 +91,34 @@ type unknownSlicePlaceholder struct { }
var unknownSlicePlaceholderType = reflect.TypeOf(unknownSlicePlaceholder { }) var unknownSlicePlaceholderType = reflect.TypeOf(unknownSlicePlaceholder { })
// decodeAny is internal to [DecodeAny]. It takes in an addressable // decodeAny is internal to [DecodeAny]. It takes in an addressable
// [reflect.Value] as the destination. // [reflect.Value] as the destination. If the decoded value cannot fit in the
// destination, it skims over the payload, leaves the destination empty, and
// returns without an error.
func decodeAny(decoder *Decoder, destination reflect.Value, tag Tag) (n int, err error) { func decodeAny(decoder *Decoder, destination reflect.Value, tag Tag) (n int, err error) {
errWrongDestinationType := func(expected string) error { n, err = decodeAnyOrError(decoder, destination, tag)
panic(fmt.Errorf( if _, ok := err.(errCantAssign); ok {
// return fmt.Errorf( if n > 0 { panic(fmt.Sprintf("decodeAnyOrError decoded more than it should: %d", n)) }
"expected %s destination, not %v", nn, err := Skim(decoder, tag)
expected, destination)) n += nn; if err != nil { return n, err }
return n, nil
} }
return n, err
}
// decodeAnyOrError is internal to [decodeAny]. It takes in an addressable
// [reflect.Value] as the destination. If the decoded value cannot fit in the
// destination, it decodes nothing and returns an error of type errCantAssign,
// except for the case of a mismatched OTA element tag, wherein it will skim
// over the rest of the payload, leave the destination empty, and return without
// an error.
func decodeAnyOrError(decoder *Decoder, destination reflect.Value, tag Tag) (n int, err error) {
err = canSet(destination.Type(), tag)
if err != nil { return n, err }
switch tag.WithoutCN() { switch tag.WithoutCN() {
case SI: case SI:
// SI: (none) // SI: (none)
err = setInt(destination, uint64(tag.CN())) setInt(destination, uint64(tag.CN()))
if err != nil { return n, err }
case LI: case LI:
// LI: <value: IntN> // LI: <value: IntN>
nn, err := decodeAndSetUint(decoder, destination, tag.CN() + 1) nn, err := decodeAndSetUint(decoder, destination, tag.CN() + 1)