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