Merge pull request #5047 from zgfzgf/feat-shed-bitfield
shed bitfield: Cleanup, add merge command
This commit is contained in:
commit
fed3e82ff8
@ -17,6 +17,7 @@ import (
|
||||
|
||||
var bitFieldCmd = &cli.Command{
|
||||
Name: "bitfield",
|
||||
Usage: "Bitfield analyze tool",
|
||||
Description: "analyze bitfields",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
@ -26,53 +27,24 @@ var bitFieldCmd = &cli.Command{
|
||||
},
|
||||
},
|
||||
Subcommands: []*cli.Command{
|
||||
bitFieldEncodeCmd,
|
||||
bitFieldDecodeCmd,
|
||||
bitFieldRunsCmd,
|
||||
bitFieldStatCmd,
|
||||
bitFieldDecodeCmd,
|
||||
bitFieldMergeCmd,
|
||||
bitFieldIntersectCmd,
|
||||
bitFieldEncodeCmd,
|
||||
bitFieldSubCmd,
|
||||
},
|
||||
}
|
||||
|
||||
var bitFieldRunsCmd = &cli.Command{
|
||||
Name: "runs",
|
||||
Usage: "Bitfield bit runs",
|
||||
Description: "print bit runs in a bitfield",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "enc",
|
||||
Value: "base64",
|
||||
Usage: "specify input encoding to parse",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
var val string
|
||||
if cctx.Args().Present() {
|
||||
val = cctx.Args().Get(0)
|
||||
} else {
|
||||
b, err := ioutil.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
val = string(b)
|
||||
}
|
||||
|
||||
var dec []byte
|
||||
switch cctx.String("enc") {
|
||||
case "base64":
|
||||
d, err := base64.StdEncoding.DecodeString(val)
|
||||
if err != nil {
|
||||
return fmt.Errorf("decoding base64 value: %w", err)
|
||||
}
|
||||
dec = d
|
||||
case "hex":
|
||||
d, err := hex.DecodeString(val)
|
||||
if err != nil {
|
||||
return fmt.Errorf("decoding hex value: %w", err)
|
||||
}
|
||||
dec = d
|
||||
default:
|
||||
return fmt.Errorf("unrecognized encoding: %s", cctx.String("enc"))
|
||||
dec, err := decodeToByte(cctx, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rle, err := rlepluslazy.FromBuf(dec)
|
||||
@ -98,7 +70,7 @@ var bitFieldRunsCmd = &cli.Command{
|
||||
s = "FALSE"
|
||||
}
|
||||
|
||||
fmt.Printf("@%d %s * %d\n", idx, s, r.Len)
|
||||
fmt.Printf("@%08d %s * %d\n", idx, s, r.Len)
|
||||
|
||||
idx += r.Len
|
||||
}
|
||||
@ -109,43 +81,14 @@ var bitFieldRunsCmd = &cli.Command{
|
||||
|
||||
var bitFieldStatCmd = &cli.Command{
|
||||
Name: "stat",
|
||||
Usage: "Bitfield stats",
|
||||
Description: "print bitfield stats",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "enc",
|
||||
Value: "base64",
|
||||
Usage: "specify input encoding to parse",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
var val string
|
||||
if cctx.Args().Present() {
|
||||
val = cctx.Args().Get(0)
|
||||
} else {
|
||||
b, err := ioutil.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
val = string(b)
|
||||
}
|
||||
|
||||
var dec []byte
|
||||
switch cctx.String("enc") {
|
||||
case "base64":
|
||||
d, err := base64.StdEncoding.DecodeString(val)
|
||||
if err != nil {
|
||||
return fmt.Errorf("decoding base64 value: %w", err)
|
||||
}
|
||||
dec = d
|
||||
case "hex":
|
||||
d, err := hex.DecodeString(val)
|
||||
if err != nil {
|
||||
return fmt.Errorf("decoding hex value: %w", err)
|
||||
}
|
||||
dec = d
|
||||
default:
|
||||
return fmt.Errorf("unrecognized encoding: %s", cctx.String("enc"))
|
||||
dec, err := decodeToByte(cctx, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("Raw length: %d bits (%d bytes)\n", len(dec)*8, len(dec))
|
||||
|
||||
rle, err := rlepluslazy.FromBuf(dec)
|
||||
if err != nil {
|
||||
@ -157,10 +100,7 @@ var bitFieldStatCmd = &cli.Command{
|
||||
return xerrors.Errorf("getting run iterator: %w", err)
|
||||
}
|
||||
|
||||
fmt.Printf("Raw length: %d bits (%d bytes)\n", len(dec)*8, len(dec))
|
||||
|
||||
var ones, zeros, oneRuns, zeroRuns, invalid uint64
|
||||
|
||||
for rit.HasNext() {
|
||||
r, err := rit.NextRun()
|
||||
if err != nil {
|
||||
@ -195,14 +135,8 @@ var bitFieldStatCmd = &cli.Command{
|
||||
|
||||
var bitFieldDecodeCmd = &cli.Command{
|
||||
Name: "decode",
|
||||
Usage: "Bitfield to decimal number",
|
||||
Description: "decode bitfield and print all numbers in it",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "enc",
|
||||
Value: "base64",
|
||||
Usage: "specify input encoding to parse",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
rle, err := decode(cctx, 0)
|
||||
if err != nil {
|
||||
@ -219,43 +153,61 @@ var bitFieldDecodeCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var bitFieldIntersectCmd = &cli.Command{
|
||||
Name: "intersect",
|
||||
Description: "intersect 2 bitfields and print the resulting bitfield as base64",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "enc",
|
||||
Value: "base64",
|
||||
Usage: "specify input encoding to parse",
|
||||
},
|
||||
},
|
||||
var bitFieldMergeCmd = &cli.Command{
|
||||
Name: "merge",
|
||||
Usage: "Merge 2 bitfields",
|
||||
Description: "Merge 2 bitfields and print the resulting bitfield",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
a, err := decode(cctx, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b, err := decode(cctx, 1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
o, err := bitfield.MergeBitFields(a, b)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("merge: %w", err)
|
||||
}
|
||||
|
||||
str, err := encode(cctx, o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println(str)
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var bitFieldIntersectCmd = &cli.Command{
|
||||
Name: "intersect",
|
||||
Usage: "Intersect 2 bitfields",
|
||||
Description: "intersect 2 bitfields and print the resulting bitfield",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
a, err := decode(cctx, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b, err := decode(cctx, 1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
o, err := bitfield.IntersectBitField(a, b)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("intersect: %w", err)
|
||||
}
|
||||
|
||||
s, err := o.RunIterator()
|
||||
str, err := encode(cctx, o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bytes, err := rlepluslazy.EncodeRuns(s, []byte{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println(base64.StdEncoding.EncodeToString(bytes))
|
||||
fmt.Println(str)
|
||||
|
||||
return nil
|
||||
},
|
||||
@ -263,41 +215,29 @@ var bitFieldIntersectCmd = &cli.Command{
|
||||
|
||||
var bitFieldSubCmd = &cli.Command{
|
||||
Name: "sub",
|
||||
Description: "subtract 2 bitfields and print the resulting bitfield as base64",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "enc",
|
||||
Value: "base64",
|
||||
Usage: "specify input encoding to parse",
|
||||
},
|
||||
},
|
||||
Usage: "Subtract 2 bitfields",
|
||||
Description: "subtract 2 bitfields and print the resulting bitfield",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
b, err := decode(cctx, 1)
|
||||
a, err := decode(cctx, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
a, err := decode(cctx, 0)
|
||||
b, err := decode(cctx, 1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
o, err := bitfield.SubtractBitField(a, b)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("intersect: %w", err)
|
||||
return xerrors.Errorf("subtract: %w", err)
|
||||
}
|
||||
|
||||
s, err := o.RunIterator()
|
||||
str, err := encode(cctx, o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bytes, err := rlepluslazy.EncodeRuns(s, []byte{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println(base64.StdEncoding.EncodeToString(bytes))
|
||||
fmt.Println(str)
|
||||
|
||||
return nil
|
||||
},
|
||||
@ -305,15 +245,9 @@ var bitFieldSubCmd = &cli.Command{
|
||||
|
||||
var bitFieldEncodeCmd = &cli.Command{
|
||||
Name: "encode",
|
||||
Usage: "Decimal number to bitfield",
|
||||
Description: "encode a series of decimal numbers into a bitfield",
|
||||
ArgsUsage: "[infile]",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "enc",
|
||||
Value: "base64",
|
||||
Usage: "specify input encoding to parse",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
f, err := os.Open(cctx.Args().First())
|
||||
if err != nil {
|
||||
@ -331,38 +265,64 @@ var bitFieldEncodeCmd = &cli.Command{
|
||||
out.Set(i)
|
||||
}
|
||||
|
||||
s, err := out.RunIterator()
|
||||
str, err := encode(cctx, out)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bytes, err := rlepluslazy.EncodeRuns(s, []byte{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println(base64.StdEncoding.EncodeToString(bytes))
|
||||
fmt.Println(str)
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
func decode(cctx *cli.Context, a int) (bitfield.BitField, error) {
|
||||
func encode(cctx *cli.Context, field bitfield.BitField) (string, error) {
|
||||
s, err := field.RunIterator()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
bytes, err := rlepluslazy.EncodeRuns(s, []byte{})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var str string
|
||||
switch cctx.String("enc") {
|
||||
case "base64":
|
||||
str = base64.StdEncoding.EncodeToString(bytes)
|
||||
case "hex":
|
||||
str = hex.EncodeToString(bytes)
|
||||
default:
|
||||
return "", fmt.Errorf("unrecognized encoding: %s", cctx.String("enc"))
|
||||
}
|
||||
|
||||
return str, nil
|
||||
|
||||
}
|
||||
func decode(cctx *cli.Context, i int) (bitfield.BitField, error) {
|
||||
b, err := decodeToByte(cctx, i)
|
||||
if err != nil {
|
||||
return bitfield.BitField{}, err
|
||||
}
|
||||
return bitfield.NewFromBytes(b)
|
||||
}
|
||||
|
||||
func decodeToByte(cctx *cli.Context, i int) ([]byte, error) {
|
||||
var val string
|
||||
if cctx.Args().Present() {
|
||||
if a >= cctx.NArg() {
|
||||
return bitfield.BitField{}, xerrors.Errorf("need more than %d args", a)
|
||||
if i >= cctx.NArg() {
|
||||
return nil, xerrors.Errorf("need more than %d args", i)
|
||||
}
|
||||
val = cctx.Args().Get(a)
|
||||
val = cctx.Args().Get(i)
|
||||
} else {
|
||||
if a > 0 {
|
||||
return bitfield.BitField{}, xerrors.Errorf("need more than %d args", a)
|
||||
if i > 0 {
|
||||
return nil, xerrors.Errorf("need more than %d args", i)
|
||||
}
|
||||
b, err := ioutil.ReadAll(os.Stdin)
|
||||
r, err := ioutil.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
return bitfield.BitField{}, err
|
||||
return nil, err
|
||||
}
|
||||
val = string(b)
|
||||
val = string(r)
|
||||
}
|
||||
|
||||
var dec []byte
|
||||
@ -370,18 +330,18 @@ func decode(cctx *cli.Context, a int) (bitfield.BitField, error) {
|
||||
case "base64":
|
||||
d, err := base64.StdEncoding.DecodeString(val)
|
||||
if err != nil {
|
||||
return bitfield.BitField{}, fmt.Errorf("decoding base64 value: %w", err)
|
||||
return nil, fmt.Errorf("decoding base64 value: %w", err)
|
||||
}
|
||||
dec = d
|
||||
case "hex":
|
||||
d, err := hex.DecodeString(val)
|
||||
if err != nil {
|
||||
return bitfield.BitField{}, fmt.Errorf("decoding hex value: %w", err)
|
||||
return nil, fmt.Errorf("decoding hex value: %w", err)
|
||||
}
|
||||
dec = d
|
||||
default:
|
||||
return bitfield.BitField{}, fmt.Errorf("unrecognized encoding: %s", cctx.String("enc"))
|
||||
return nil, fmt.Errorf("unrecognized encoding: %s", cctx.String("enc"))
|
||||
}
|
||||
|
||||
return bitfield.NewFromBytes(dec)
|
||||
return dec, nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user