tape: Implement Skim function

This commit is contained in:
Sasha Koshka 2025-08-12 12:29:50 -04:00
parent 2209763666
commit 2180d29615

54
tape/skim.go Normal file
View File

@ -0,0 +1,54 @@
package tape
import "fmt"
// Skim uses up data from a decoder to "skim" over one value (and all else
// contained within it) without actually putting the data anywhere.
func Skim(decoder *Decoder, tag Tag) (n int, err error) {
switch tag.WithoutCN() {
case SI:
// SI: (none)
return n, nil
case LI, LSI, FP:
// LI: <value: IntN>
// LSI: <value: IntN>
// FP: <value: FloatN>
nn, err := decoder.Discard(tag.CN() + 1)
n += nn; if err != nil { return n, err }
case SBA:
// SBA: <data: U8>*
nn, err := decoder.Discard(tag.CN())
n += nn; if err != nil { return n, err }
case LBA:
// LBA: <length: UN> <data: U8>*
length, nn, err := decoder.ReadUintN(tag.CN() + 1)
n += nn; if err != nil { return n, err }
nn, err = decoder.Discard(int(length))
n += nn; if err != nil { return n, err }
case OTA:
// OTA: <length: UN> <elementTag: tape.Tag> <values>*
length, nn, err := decoder.ReadUintN(tag.CN() + 1)
n += nn; if err != nil { return n, err }
oneTag, nn, err := decoder.ReadTag()
n += nn; if err != nil { return n, err }
for _ = range length {
nn, err := Skim(decoder, oneTag)
n += nn; if err != nil { return n, err }
}
case KTV:
// KTV: <length: UN> (<key: U16> <tag: Tag> <value>)*
length, nn, err := decoder.ReadUintN(tag.CN() + 1)
n += nn; if err != nil { return n, err }
for _ = range length {
nn, err := decoder.Discard(2)
n += nn; if err != nil { return n, err }
itemTag, nn, err := decoder.ReadTag()
n += nn; if err != nil { return n, err }
nn, err = Skim(decoder, itemTag)
n += nn; if err != nil { return n, err }
}
default:
return n, fmt.Errorf("unknown TN %d", tag.TN())
}
return n, nil
}