cmd/rlpdump: new helper command
This commit is contained in:
		
							parent
							
								
									b0854fbff5
								
							
						
					
					
						commit
						b907a5d765
					
				
							
								
								
									
										128
									
								
								cmd/rlpdump/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								cmd/rlpdump/main.go
									
									
									
									
									
										Normal file
									
								
							| @ -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) | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user