1
1
mirror of https://github.com/wader/fq.git synced 2024-12-23 05:13:30 +03:00

decode,scalar: Add scalar.Str{Uint/Int/F}ToSym to parse numbers

This commit is contained in:
Mattias Wadman 2022-01-28 17:18:30 +01:00
parent b2e5a83860
commit 6cd1c38fbf
3 changed files with 41 additions and 45 deletions

View File

@ -1,9 +1,6 @@
package ar
import (
"strconv"
"strings"
"github.com/wader/fq/format"
"github.com/wader/fq/format/registry"
"github.com/wader/fq/pkg/decode"
@ -27,29 +24,14 @@ func init() {
func decodeAr(d *decode.D, in interface{}) interface{} {
d.FieldUTF8("signature", 8, d.AssertStr("!<arch>\n"))
d.FieldArray("files", func(d *decode.D) {
// TODO: extract? share with tar?
mapStrToSymU := func(base int) scalar.Mapper {
return scalar.Fn(func(s scalar.S) (scalar.S, error) {
ts := strings.Trim(s.ActualStr(), " ")
if ts != "" {
n, err := strconv.ParseUint(ts, base, 64)
if err != nil {
return s, err
}
s.Sym = n
}
return s, nil
})
}
for !d.End() {
d.FieldStruct("file", func(d *decode.D) {
d.FieldUTF8("identifier", 16, scalar.TrimSpace)
d.FieldUTF8("modification_timestamp", 12, scalar.TrimSpace, mapStrToSymU(10))
d.FieldUTF8("owner_id", 6, scalar.TrimSpace, mapStrToSymU(10))
d.FieldUTF8("group_id", 6, scalar.TrimSpace, mapStrToSymU(10))
d.FieldUTF8("file_mode", 8, scalar.TrimSpace, mapStrToSymU(8)) // Octal
sizeS := d.FieldScalarUTF8("file_size", 10, scalar.TrimSpace, mapStrToSymU(10))
d.FieldUTF8("modification_timestamp", 12, scalar.TrimSpace, scalar.StrUintToSym(10))
d.FieldUTF8("owner_id", 6, scalar.TrimSpace, scalar.StrUintToSym(10))
d.FieldUTF8("group_id", 6, scalar.TrimSpace, scalar.StrUintToSym(10))
d.FieldUTF8("file_mode", 8, scalar.TrimSpace, scalar.StrUintToSym(8)) // Octal
sizeS := d.FieldScalarUTF8("file_size", 10, scalar.TrimSpace, scalar.StrUintToSym(10))
if sizeS.Sym == nil {
d.Fatalf("could not decode file_size")
}

View File

@ -5,8 +5,6 @@ package tar
import (
"bytes"
"strconv"
"strings"
"github.com/wader/fq/format"
"github.com/wader/fq/format/registry"
@ -33,17 +31,6 @@ func tarDecode(d *decode.D, in interface{}) interface{} {
const blockBits = blockBytes * 8
mapTrimSpaceNull := scalar.Trim(" \x00")
mapOctStrToSymU := scalar.Fn(func(s scalar.S) (scalar.S, error) {
ts := strings.Trim(s.ActualStr(), " ")
if ts != "" {
n, err := strconv.ParseUint(ts, 8, 64)
if err != nil {
return s, err
}
s.Sym = n
}
return s, nil
})
blockPadding := func(d *decode.D) int64 {
return (blockBits - (d.Pos() % blockBits)) % blockBits
}
@ -58,24 +45,24 @@ func tarDecode(d *decode.D, in interface{}) interface{} {
for !d.End() {
d.FieldStruct("file", func(d *decode.D) {
d.FieldUTF8("name", 100, mapTrimSpaceNull)
d.FieldUTF8NullFixedLen("mode", 8, mapOctStrToSymU)
d.FieldUTF8NullFixedLen("uid", 8, mapOctStrToSymU)
d.FieldUTF8NullFixedLen("gid", 8, mapOctStrToSymU)
sizeS := d.FieldScalarUTF8NullFixedLen("size", 12, mapOctStrToSymU)
d.FieldUTF8NullFixedLen("mode", 8, scalar.StrUintToSym(8))
d.FieldUTF8NullFixedLen("uid", 8, scalar.StrUintToSym(8))
d.FieldUTF8NullFixedLen("gid", 8, scalar.StrUintToSym(8))
sizeS := d.FieldScalarUTF8NullFixedLen("size", 12, scalar.StrUintToSym(8))
if sizeS.Sym == nil {
d.Fatalf("could not decode size")
}
size := int64(sizeS.SymU()) * 8
d.FieldUTF8NullFixedLen("mtime", 12, mapOctStrToSymU)
d.FieldUTF8NullFixedLen("chksum", 8, mapOctStrToSymU)
d.FieldUTF8NullFixedLen("mtime", 12, scalar.StrUintToSym(8))
d.FieldUTF8NullFixedLen("chksum", 8, scalar.StrUintToSym(8))
d.FieldUTF8("typeflag", 1, mapTrimSpaceNull)
d.FieldUTF8("linkname", 100, mapTrimSpaceNull)
d.FieldUTF8("magic", 6, mapTrimSpaceNull, d.AssertStr("ustar"))
d.FieldUTF8NullFixedLen("version", 2, mapOctStrToSymU)
d.FieldUTF8NullFixedLen("version", 2, scalar.StrUintToSym(8))
d.FieldUTF8("uname", 32, mapTrimSpaceNull)
d.FieldUTF8("gname", 32, mapTrimSpaceNull)
d.FieldUTF8NullFixedLen("devmajor", 8, mapOctStrToSymU)
d.FieldUTF8NullFixedLen("devminor", 8, mapOctStrToSymU)
d.FieldUTF8NullFixedLen("devmajor", 8, scalar.StrUintToSym(8))
d.FieldUTF8NullFixedLen("devminor", 8, scalar.StrUintToSym(8))
d.FieldUTF8("prefix", 155, mapTrimSpaceNull)
d.FieldRawLen("header_block_padding", blockPadding(d), d.BitBufIsZero())

View File

@ -8,6 +8,7 @@ package scalar
import (
"bytes"
"fmt"
"strconv"
"strings"
"github.com/wader/fq/pkg/bitio"
@ -113,6 +114,32 @@ var TrimSpace = Fn(func(s S) (S, error) {
return s, nil
})
func strMapToSym(fn func(s string) (interface{}, error)) Mapper {
return Fn(func(s S) (S, error) {
ts := strings.TrimSpace(s.ActualStr())
if ts != "" {
n, err := fn(ts)
if err != nil {
return s, err
}
s.Sym = n
}
return s, nil
})
}
func StrUintToSym(base int) Mapper {
return strMapToSym(func(s string) (interface{}, error) { return strconv.ParseUint(s, base, 64) })
}
func StrIntToSym(base int) Mapper {
return strMapToSym(func(s string) (interface{}, error) { return strconv.ParseInt(s, base, 64) })
}
func StrFToSym(base int) Mapper {
return strMapToSym(func(s string) (interface{}, error) { return strconv.ParseFloat(s, base) })
}
//nolint:unparam
func rawSym(s S, nBytes int, fn func(b []byte) string) (S, error) {
bb, ok := s.Actual.(*bitio.Buffer)