Skip to content

Commit

Permalink
decode,scalar: Add scalar.Str{Uint/Int/F}ToSym to parse numbers
Browse files Browse the repository at this point in the history
  • Loading branch information
wader committed Jan 28, 2022
1 parent b2e5a83 commit 6cd1c38
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 45 deletions.
28 changes: 5 additions & 23 deletions format/ar/ar.go
@@ -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"
Expand All @@ -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")
}
Expand Down
31 changes: 9 additions & 22 deletions format/tar/tar.go
Expand Up @@ -5,8 +5,6 @@ package tar

import (
"bytes"
"strconv"
"strings"

"github.com/wader/fq/format"
"github.com/wader/fq/format/registry"
Expand All @@ -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
}
Expand All @@ -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())

Expand Down
27 changes: 27 additions & 0 deletions pkg/scalar/scalar.go
Expand Up @@ -8,6 +8,7 @@ package scalar
import (
"bytes"
"fmt"
"strconv"
"strings"

"github.com/wader/fq/pkg/bitio"
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 6cd1c38

Please sign in to comment.