From b907a5d76542789e8258c7957981a0ef65fe48d6 Mon Sep 17 00:00:00 2001
From: Felix Lange <fjl@twurst.com>
Date: Mon, 5 Jan 2015 13:30:58 +0100
Subject: cmd/rlpdump: new helper command

---
 cmd/rlpdump/main.go | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 128 insertions(+)
 create mode 100644 cmd/rlpdump/main.go

(limited to 'cmd')

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)
+}
-- 
cgit v1.2.3