diff --git a/cmd/epik-shed/bitfield.go b/cmd/epik-shed/bitfield.go index 442cbef4846..f0824de4f2a 100644 --- a/cmd/epik-shed/bitfield.go +++ b/cmd/epik-shed/bitfield.go @@ -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 { - 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.IntersectBitField(a, b) + o, err := bitfield.MergeBitFields(a, b) if err != nil { - return xerrors.Errorf("intersect: %w", err) + return xerrors.Errorf("merge: %w", err) } - s, err := o.RunIterator() + str, err := encode(cctx, o) if err != nil { return err } + fmt.Println(str) - bytes, err := rlepluslazy.EncodeRuns(s, []byte{}) + 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 } - fmt.Println(base64.StdEncoding.EncodeToString(bytes)) + o, err := bitfield.IntersectBitField(a, b) + if err != nil { + return xerrors.Errorf("intersect: %w", err) + } + + str, err := encode(cctx, o) + if err != nil { + return err + } + 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) - } - - s, err := o.RunIterator() - if err != nil { - return err + return xerrors.Errorf("subtract: %w", err) } - bytes, err := rlepluslazy.EncodeRuns(s, []byte{}) + str, err := encode(cctx, o) 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() - if err != nil { - return err - } - - bytes, err := rlepluslazy.EncodeRuns(s, []byte{}) + str, err := encode(cctx, out) 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 }