any-type #20
@ -114,7 +114,7 @@ func DecodeAnyInto(decoder *Decoder, destination any, tag Tag) (n int, err error
|
|||||||
// destination from the tag and data. The head of the decoder must be at the
|
// destination from the tag and data. The head of the decoder must be at the
|
||||||
// start of the payload.
|
// start of the payload.
|
||||||
func DecodeAny(decoder *Decoder, tag Tag) (value any, n int, err error) {
|
func DecodeAny(decoder *Decoder, tag Tag) (value any, n int, err error) {
|
||||||
destination, err := skeletonValue(decoder, tag)
|
destination, err := skeletonPointer(decoder, tag)
|
||||||
if err != nil { return nil, n, err }
|
if err != nil { return nil, n, err }
|
||||||
nn, err := DecodeAnyInto(decoder, destination, tag)
|
nn, err := DecodeAnyInto(decoder, destination, tag)
|
||||||
n += nn; if err != nil { return nil, n, err }
|
n += nn; if err != nil { return nil, n, err }
|
||||||
@ -192,12 +192,12 @@ func decodeAnyOrError(decoder *Decoder, destination reflect.Value, tag Tag) (n i
|
|||||||
setString(destination, string(buffer))
|
setString(destination, string(buffer))
|
||||||
case OTA:
|
case OTA:
|
||||||
// OTA: <length: UN> <elementTag: tape.Tag> <values>*
|
// OTA: <length: UN> <elementTag: tape.Tag> <values>*
|
||||||
|
oldDestination := destination
|
||||||
if isTypeAny(destination.Type()) {
|
if isTypeAny(destination.Type()) {
|
||||||
// need a skeleton value if we are assigning to any.
|
// need a skeleton value if we are assigning to any.
|
||||||
value, err := skeletonValue(decoder, tag)
|
value, err := skeletonValue(decoder, tag)
|
||||||
if err != nil { return n, err }
|
if err != nil { return n, err }
|
||||||
destination.Set(value)
|
destination = value
|
||||||
destination = value.Elem()
|
|
||||||
}
|
}
|
||||||
length, nn, err := decoder.ReadUintN(tag.CN() + 1)
|
length, nn, err := decoder.ReadUintN(tag.CN() + 1)
|
||||||
n += nn; if err != nil { return n, err }
|
n += nn; if err != nil { return n, err }
|
||||||
@ -232,6 +232,7 @@ func decodeAnyOrError(decoder *Decoder, destination reflect.Value, tag Tag) (n i
|
|||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
oldDestination.Set(destination)
|
||||||
case KTV:
|
case KTV:
|
||||||
// KTV: <length: UN> (<key: U16> <tag: Tag> <value>)*
|
// KTV: <length: UN> (<key: U16> <tag: Tag> <value>)*
|
||||||
length, nn, err := decoder.ReadUintN(tag.CN() + 1)
|
length, nn, err := decoder.ReadUintN(tag.CN() + 1)
|
||||||
@ -245,7 +246,7 @@ func decodeAnyOrError(decoder *Decoder, destination reflect.Value, tag Tag) (n i
|
|||||||
n += nn; if err != nil { return n, err }
|
n += nn; if err != nil { return n, err }
|
||||||
itemTag, nn, err := decoder.ReadTag()
|
itemTag, nn, err := decoder.ReadTag()
|
||||||
n += nn; if err != nil { return n, err }
|
n += nn; if err != nil { return n, err }
|
||||||
value, err := skeletonValue(decoder, itemTag)
|
value, err := skeletonPointer(decoder, itemTag)
|
||||||
if err != nil { return n, err }
|
if err != nil { return n, err }
|
||||||
nn, err = decodeAny(decoder, value.Elem(), itemTag)
|
nn, err = decodeAny(decoder, value.Elem(), itemTag)
|
||||||
n += nn; if err != nil { return n, err }
|
n += nn; if err != nil { return n, err }
|
||||||
@ -473,10 +474,18 @@ func decodeAndSetFloat(decoder *Decoder, destination reflect.Value, bytes int) (
|
|||||||
return n, errCantAssignf("unsupported bit width float%d", bytes * 8)
|
return n, errCantAssignf("unsupported bit width float%d", bytes * 8)
|
||||||
}
|
}
|
||||||
|
|
||||||
// skeletonValue returns a pointer value. In order for it to be set, it must be
|
// skeletonValue returns an addressable value. It can be set directly. The head
|
||||||
// dereferenced using Elem(). The head of the decoder must be at the start of
|
// of the decoder must be at the start of the payload when calling.
|
||||||
// the payload.
|
|
||||||
func skeletonValue(decoder *Decoder, tag Tag) (reflect.Value, error) {
|
func skeletonValue(decoder *Decoder, tag Tag) (reflect.Value, error) {
|
||||||
|
ptr, err := skeletonPointer(decoder, tag)
|
||||||
|
if err != nil { return reflect.Value { }, err }
|
||||||
|
return ptr.Elem(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// skeletonPointer returns a pointer value. In order for it to be set, it must
|
||||||
|
// be dereferenced using Elem(). The head of the decoder must be at the start of
|
||||||
|
// the payload when calling.
|
||||||
|
func skeletonPointer(decoder *Decoder, tag Tag) (reflect.Value, error) {
|
||||||
typ, err := typeOf(decoder, tag)
|
typ, err := typeOf(decoder, tag)
|
||||||
if err != nil { return reflect.Value { }, err }
|
if err != nil { return reflect.Value { }, err }
|
||||||
return reflect.New(typ), nil
|
return reflect.New(typ), nil
|
||||||
@ -484,7 +493,7 @@ func skeletonValue(decoder *Decoder, tag Tag) (reflect.Value, error) {
|
|||||||
|
|
||||||
// typeOf returns the type of the current tag being decoded. It does not use up
|
// typeOf returns the type of the current tag being decoded. It does not use up
|
||||||
// the decoder, it only peeks. The head of the decoder must be at the start of
|
// the decoder, it only peeks. The head of the decoder must be at the start of
|
||||||
// the payload.
|
// the payload when calling.
|
||||||
func typeOf(decoder *Decoder, tag Tag) (reflect.Type, error) {
|
func typeOf(decoder *Decoder, tag Tag) (reflect.Type, error) {
|
||||||
switch tag.WithoutCN() {
|
switch tag.WithoutCN() {
|
||||||
case SI:
|
case SI:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user