1
1
mirror of https://github.com/wader/fq.git synced 2024-12-22 12:51:38 +03:00

decode: Remove D.Scalar* and add d.(Try)FieldScala*Fn instead

Idea is scalar fn should not read
This commit is contained in:
Mattias Wadman 2021-11-21 13:08:18 +01:00
parent 046f2fd965
commit f40320b04c
9 changed files with 308 additions and 3252 deletions

View File

@ -39,6 +39,12 @@ var classBits = decode.UToU{
2: 64,
}
//nolint:revive
const (
CLASS_32 = 1
CLASS_64 = 2
)
var osABINames = decode.UToStr{
0: "Sysv",
1: "HPUX",
@ -127,12 +133,13 @@ func mapStrTable(table string) func(decode.Scalar) (decode.Scalar, error) {
func elfDecode(d *decode.D, in interface{}) interface{} {
d.AssertAtLeastBitsLeft(128 * 8)
var class uint64
var archBits int
var endian uint64
d.FieldStruct("ident", func(d *decode.D) {
d.FieldRawLen("magic", 4*8, d.AssertBitBuf([]byte("\x7fELF")))
archBits = int(d.FieldU8("class", d.MapUToUSym(classBits)))
class = d.FieldU8("class", d.MapUToUSym(classBits))
endian = d.FieldU8("data", d.MapUToStrSym(endianNames))
d.FieldU8("version")
d.FieldU8("os_abi", d.MapUToStrSym(osABINames))
@ -140,13 +147,22 @@ func elfDecode(d *decode.D, in interface{}) interface{} {
d.FieldRawLen("pad", 7*8, d.BitBufIsZero)
})
switch class {
case CLASS_32:
archBits = 32
case CLASS_64:
archBits = 64
default:
d.Fatalf("unknown class %d", class)
}
switch endian {
case LITTLE_ENDIAN:
d.Endian = decode.LittleEndian
case BIG_ENDIAN:
d.Endian = decode.BigEndian
default:
d.Fatalf("unknown endian")
d.Fatalf("unknown endian %d", endian)
}
// TODO: hex functions?
@ -235,6 +251,8 @@ func elfDecode(d *decode.D, in interface{}) interface{} {
if shstrndx != 0 {
var strTableOffset uint64
var strTableSize uint64
// log.Printf("int64((shoff+shstrndx*shentsize)*8): %#+v\n", int64((shoff+shstrndx*shentsize)*8))
// log.Printf("int64(shentsize*8),: %#+v\n", int64(shentsize*8))
d.RangeFn(int64((shoff+shstrndx*shentsize)*8), int64(shentsize*8), func(d *decode.D) {
d.SeekRel(32)
d.SeekRel(32)
@ -446,7 +464,7 @@ func elfDecode(d *decode.D, in interface{}) interface{} {
switch archBits {
case 32:
shname = d.FieldScalar("sh_name", d.ScalarU32(), mapStrTable(strIndexTable)).SymStr()
shname = d.FieldScalarUFn("sh_name", (*decode.D).U32, mapStrTable(strIndexTable)).SymStr()
typ = d.FieldU32("sh_type", d.MapUToStrSym(shTypeNames), d.Hex)
shFlags(d, archBits)
d.FieldU("sh_addr", archBits)
@ -457,7 +475,7 @@ func elfDecode(d *decode.D, in interface{}) interface{} {
d.FieldU32("sh_addralign")
d.FieldU32("sh_entsize")
case 64:
shname = d.FieldScalar("sh_name", d.ScalarU32(), mapStrTable(strIndexTable)).SymStr()
shname = d.FieldScalarUFn("sh_name", (*decode.D).U32, mapStrTable(strIndexTable)).SymStr()
typ = d.FieldU32("sh_type", d.MapUToStrSym(shTypeNames), d.Hex)
shFlags(d, archBits)
d.FieldU("sh_addr", archBits)

View File

@ -392,7 +392,7 @@ func frameDecode(d *decode.D, in interface{}) interface{} {
d.MustCopy(crcHash, d.BitBufRange(6*8, sideInfoBytes*8))
if crcValue != nil {
_ = crcValue.ScalarFn(d.ValidateBitBuf(crcHash.Sum(nil)))
_ = crcValue.TryScalarFn(d.ValidateBitBuf(crcHash.Sum(nil)))
}
d.FieldValueRaw("crc_calculated", crcHash.Sum(nil), d.RawHex)

View File

@ -45,7 +45,7 @@ func pesDecode(d *decode.D, in interface{}) interface{} {
i := 0
spuD := d.FieldArray("spus")
spuD := d.FieldArrayValue("spus")
for d.NotEnd() {
dv, v, err := d.FieldTryFormat("packet", pesPacketFormat, nil)

View File

@ -60,7 +60,7 @@ type stream struct {
func decodeOgg(d *decode.D, in interface{}) interface{} {
validPages := 0
streams := map[uint32]*stream{}
streamsD := d.FieldArray("streams")
streamsD := d.FieldArrayValue("streams")
d.FieldArray("pages", func(d *decode.D) {
for !d.End() {
@ -78,7 +78,7 @@ func decodeOgg(d *decode.D, in interface{}) interface{} {
var packetsD *decode.D
streamsD.FieldStruct("stream", func(d *decode.D) {
d.FieldValueU("serial_number", uint64(oggPageOut.StreamSerialNumber))
packetsD = d.FieldArray("packets")
packetsD = d.FieldArrayValue("packets")
})
s = &stream{
sequenceNo: oggPageOut.SequenceNo,

View File

@ -51,7 +51,7 @@ func pageDecode(d *decode.D, in interface{}) interface{} {
d.MustCopy(pageCRC, d.BitBufRange(startPos, pageChecksumValue.Range.Start-startPos)) // header before checksum
d.MustCopy(pageCRC, bytes.NewReader([]byte{0, 0, 0, 0})) // zero checksum bits
d.MustCopy(pageCRC, d.BitBufRange(pageChecksumValue.Range.Stop(), endPos-pageChecksumValue.Range.Stop())) // rest of page
_ = pageChecksumValue.ScalarFn(d.ValidateBitBuf(bitio.ReverseBytes(pageCRC.Sum(nil))))
_ = pageChecksumValue.TryScalarFn(d.ValidateBitBuf(bitio.ReverseBytes(pageCRC.Sum(nil))))
return p
}

View File

@ -550,24 +550,28 @@ func (d *D) FieldMustGet(name string) *Value {
panic(fmt.Sprintf("%s not found in struct %s", name, d.Value.Name))
}
func (d *D) FieldArray(name string, fns ...func(d *D)) *D {
func (d *D) FieldArray(name string, fn func(d *D), sfns ...ScalarFn) *D {
cd := d.FieldDecoder(name, d.bitBuf, Compound{IsArray: true, Children: new([]*Value)})
d.AddChild(cd.Value)
for _, fn := range fns {
fn(cd)
}
return cd
}
func (d *D) FieldStruct(name string, fns ...func(d *D)) *D {
func (d *D) FieldArrayValue(name string) *D {
return d.FieldArray(name, func(d *D) {})
}
func (d *D) FieldStruct(name string, fn func(d *D)) *D {
cd := d.FieldDecoder(name, d.bitBuf, Compound{Children: new([]*Value)})
d.AddChild(cd.Value)
for _, fn := range fns {
fn(cd)
}
return cd
}
func (d *D) FieldStructValue(name string) *D {
return d.FieldStruct(name, func(d *D) {})
}
func (d *D) FieldStructArrayLoop(name string, structName string, condFn func() bool, fn func(d *D)) *D {
return d.FieldArray(name, func(d *D) {
for condFn() {
@ -817,8 +821,6 @@ func (d *D) TryFieldFormatBitBuf(name string, bb *bitio.Buffer, group Group, inA
dv.Range.Start = d.Pos()
// log.Printf("FieldTryFormatBitBuf dv.Range: %#+v\n", dv.Range)
d.AddChild(dv)
return dv, v, err
@ -897,6 +899,7 @@ func (d *D) TryFieldReaderRangeFormat(name string, startBit int64, nBits int64,
return 0, nil, nil, nil, err
}
dv, v, err := d.TryFieldFormatBitBuf(name, rbb, group, inArg)
return cz, rbb, dv, v, err
}

File diff suppressed because it is too large Load Diff

View File

@ -29,6 +29,15 @@ import (
return v
}
// TryField{{$name}}ScalarFn tries to add a field, calls scalar functions and returns actual value as a {{$name}}
func (d *D) TryField{{$name}}ScalarFn(name string, fn func(d *D) (Scalar, error), sfns ...ScalarFn) ({{$t.go_type}}, error) {
v, err := d.TryFieldScalar(name, func(_ Scalar) (Scalar, error) { return fn(d) }, sfns...)
if err != nil {
return {{$t.zero}}, err
}
return v.Actual{{$name}}(), err
}
// Field{{$name}}ScalarFn adds a field, calls scalar functions and returns actual value as a {{$name}}
func (d *D) Field{{$name}}ScalarFn(name string, fn func(d *D) Scalar, sfns ...ScalarFn) {{$t.go_type}} {
v, err := d.TryFieldScalar(name, func(_ Scalar) (Scalar, error) { return fn(d), nil }, sfns...)
@ -43,15 +52,6 @@ import (
return d.Field{{$name}}ScalarFn(name, func(d *D) Scalar { return Scalar{Actual: fn(d) } }, sfns...)
}
// TryField{{$name}}ScalarFn tries to add a field, calls scalar functions and returns actual value as a {{$name}}
func (d *D) TryField{{$name}}ScalarFn(name string, fn func(d *D) (Scalar, error), sfns ...ScalarFn) ({{$t.go_type}}, error) {
v, err := d.TryFieldScalar(name, func(_ Scalar) (Scalar, error) { return fn(d) }, sfns...)
if err != nil {
return {{$t.zero}}, err
}
return v.Actual{{$name}}(), err
}
// TryField{{$name}}Fn tries to add a field, calls {{$t.go_type}} decode function and returns actual value as a {{$name}}
func (d *D) TryField{{$name}}Fn(name string, fn func(d *D) ({{$t.go_type}}, error), sfns ...ScalarFn) ({{$t.go_type}}, error) {
return d.TryField{{$name}}ScalarFn(name, func(d *D) (Scalar, error) {
@ -59,6 +59,23 @@ import (
return Scalar{Actual: v}, err
}, sfns...)
}
// TryFieldScalar{{$name}}Fn tries to add a field, calls {{$t.go_type}} decode function and returns scalar
func (d *D) TryFieldScalar{{$name}}Fn(name string, fn func(d *D) ({{$t.go_type}}, error), sfns ...ScalarFn) (Scalar, error) {
return d.TryFieldScalar(name, func(_ Scalar) (Scalar, error) {
v, err := fn(d)
return Scalar{Actual: v}, err
}, sfns...)
}
// FieldScalar{{$name}}Fn tries to add a field, calls {{$t.go_type}} decode function and returns scalar
func (d *D) FieldScalar{{$name}}Fn(name string, fn func(d *D) {{$t.go_type}}, sfns ...ScalarFn) Scalar {
v, err := d.TryFieldScalar{{$name}}Fn(name, func(d *D) ({{$t.go_type}}, error) { return fn(d), nil }, sfns...)
if err != nil {
panic(IOError{Err: err, Name: name, Op: "{{$name}}", Pos: d.Pos()})
}
return v
}
{{end}}
{{- range $name, $t := $.types }}
@ -149,14 +166,6 @@ import (
// Try{{$r.name}}{{replace $v.name "$n" $n}} tries to read {{replace $v.doc "$n" $n}}
func (d *D) Try{{$r.name}}{{replace $v.name "$n" $n}}({{$v.params}}) ({{$t.go_type}}, error) { return {{replace $v.call "$n" $n}} }
func (d *D) Scalar{{$r.name}}{{replace $v.name "$n" $n}}({{$v.params}}) func(Scalar) (Scalar, error) {
return func(s Scalar) (Scalar, error) {
v, err := {{replace $v.call "$n" $n}}
s.Actual = v
return s, err
}
}
// {{$r.name}}{{replace $v.name "$n" $n}} reads {{replace $v.doc "$n" $n}}
func (d *D) {{$r.name}}{{replace $v.name "$n" $n}}({{$v.params}}) {{$t.go_type}} {
v, err := {{replace $v.call "$n" $n}}
@ -169,7 +178,11 @@ import (
// TryField{{$r.name}}{{replace $v.name "$n" $n}} tries to add a field and read {{replace $v.doc "$n" $n}}
func (d *D) TryField{{$r.name}}{{replace $v.name "$n" $n}}(name string{{if $v.params}}, {{$v.params}}{{end}}, sfns ...ScalarFn) ({{$t.go_type}}, error) {
{{- if $v.params}}
v, err := d.TryFieldScalar(name, d.Scalar{{$r.name}}{{replace $v.name "$n" $n}}({{$v.args}}), sfns...)
v, err := d.TryFieldScalar(name, func(s Scalar) (Scalar, error) {
v, err := {{replace $v.call "$n" $n}}
s.Actual = v
return s, err
}, sfns...)
if err != nil {
return {{$t.zero}}, err
}

View File

@ -255,7 +255,7 @@ func (v *Value) postProcess() {
}
}
func (v *Value) ScalarFn(sfns ...ScalarFn) error {
func (v *Value) TryScalarFn(sfns ...ScalarFn) error {
var err error
s, ok := v.V.(Scalar)
if !ok {