diff options
author | Felix Lange <fjl@twurst.com> | 2015-01-05 20:30:58 +0800 |
---|---|---|
committer | Felix Lange <fjl@twurst.com> | 2015-01-05 20:45:38 +0800 |
commit | b907a5d76542789e8258c7957981a0ef65fe48d6 (patch) | |
tree | 0ea14f3be0b20b91a820343f0c07a8c3467934f7 | |
parent | b0854fbff5c3d588134f577918a39d08002235dc (diff) | |
download | dexon-b907a5d76542789e8258c7957981a0ef65fe48d6.tar dexon-b907a5d76542789e8258c7957981a0ef65fe48d6.tar.gz dexon-b907a5d76542789e8258c7957981a0ef65fe48d6.tar.bz2 dexon-b907a5d76542789e8258c7957981a0ef65fe48d6.tar.lz dexon-b907a5d76542789e8258c7957981a0ef65fe48d6.tar.xz dexon-b907a5d76542789e8258c7957981a0ef65fe48d6.tar.zst dexon-b907a5d76542789e8258c7957981a0ef65fe48d6.zip |
cmd/rlpdump: new helper command
-rw-r--r-- | cmd/rlpdump/main.go | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/cmd/rlpdump/main.go b/cmd/rlpdump/main.go new file mode 100644 index 000000000..4fb53369a --- /dev/null +++ b/cmd/rlpdump/main.go @@ -0,0 +1,128 @@ +package main + +import ( + "bufio" + "bytes" + "encoding/hex" + "flag" + "fmt" + "io" + "os" + "strings" + + "github.com/ethereum/go-ethereum/rlp" +) + +var ( + hexMode = flag.String("hex", "", "dump given hex data") + noASCII = flag.Bool("noascii", false, "don't print ASCII strings readably") +) + +func init() { + flag.Usage = func() { + fmt.Fprintln(os.Stderr, "Usage:", os.Args[0], "[-noascii] [-hex <data>] [filename]") + flag.PrintDefaults() + fmt.Fprintln(os.Stderr, ` +Dumps RLP data from the given file in readable form. +If the filename is omitted, data is read from stdin.`) + } +} + +func main() { + flag.Parse() + + var r io.Reader + switch { + case *hexMode != "": + data, err := hex.DecodeString(*hexMode) + if err != nil { + die(err) + } + r = bytes.NewReader(data) + + case flag.NArg() == 0: + r = os.Stdin + + case flag.NArg() == 1: + fd, err := os.Open(flag.Arg(0)) + if err != nil { + die(err) + } + defer fd.Close() + r = bufio.NewReader(fd) + + default: + fmt.Fprintln(os.Stderr, "Error: too many arguments") + flag.Usage() + os.Exit(2) + } + + s := rlp.NewStream(r) + for { + if err := dump(s, 0); err != nil { + if err != io.EOF { + die(err) + } + break + } + fmt.Println() + } +} + +func dump(s *rlp.Stream, depth int) error { + kind, size, err := s.Kind() + if err != nil { + return err + } + switch kind { + case rlp.Byte, rlp.String: + str, err := s.Bytes() + if err != nil { + return err + } + if len(str) == 0 || !*noASCII && isASCII(str) { + fmt.Printf("%s%q", ws(depth), str) + } else { + fmt.Printf("%s%x", ws(depth), str) + } + case rlp.List: + s.List() + defer s.ListEnd() + if size == 0 { + fmt.Printf(ws(depth) + "[]") + return nil + } else { + fmt.Println(ws(depth) + "[") + for i := 0; ; i++ { + if i > 0 { + fmt.Print(",\n") + } + if err := dump(s, depth+1); err == rlp.EOL { + break + } else if err != nil { + return err + } + } + fmt.Print(ws(depth) + "]") + } + } + return nil +} + +func isASCII(b []byte) bool { + for _, c := range b { + if c < 32 || c > 126 { + return false + } + } + return true +} + +func ws(n int) string { + return strings.Repeat(" ", n) +} + +func die(args ...interface{}) { + fmt.Fprintln(os.Stderr, args...) + os.Exit(1) +} |