cmd/rlpdump: add -pos flag, displaying byte positions (#28785)
This commit is contained in:
parent
29b73555ae
commit
1485814f89
@ -25,7 +25,9 @@ import (
|
|||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"math"
|
||||||
"os"
|
"os"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
@ -37,6 +39,7 @@ var (
|
|||||||
reverseMode = flag.Bool("reverse", false, "convert ASCII to rlp")
|
reverseMode = flag.Bool("reverse", false, "convert ASCII to rlp")
|
||||||
noASCII = flag.Bool("noascii", false, "don't print ASCII strings readably")
|
noASCII = flag.Bool("noascii", false, "don't print ASCII strings readably")
|
||||||
single = flag.Bool("single", false, "print only the first element, discard the rest")
|
single = flag.Bool("single", false, "print only the first element, discard the rest")
|
||||||
|
showpos = flag.Bool("pos", false, "display element byte posititions")
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -52,17 +55,17 @@ If the filename is omitted, data is read from stdin.`)
|
|||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
var r io.Reader
|
var r *inStream
|
||||||
switch {
|
switch {
|
||||||
case *hexMode != "":
|
case *hexMode != "":
|
||||||
data, err := hex.DecodeString(strings.TrimPrefix(*hexMode, "0x"))
|
data, err := hex.DecodeString(strings.TrimPrefix(*hexMode, "0x"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
die(err)
|
die(err)
|
||||||
}
|
}
|
||||||
r = bytes.NewReader(data)
|
r = newInStream(bytes.NewReader(data), int64(len(data)))
|
||||||
|
|
||||||
case flag.NArg() == 0:
|
case flag.NArg() == 0:
|
||||||
r = os.Stdin
|
r = newInStream(bufio.NewReader(os.Stdin), 0)
|
||||||
|
|
||||||
case flag.NArg() == 1:
|
case flag.NArg() == 1:
|
||||||
fd, err := os.Open(flag.Arg(0))
|
fd, err := os.Open(flag.Arg(0))
|
||||||
@ -70,13 +73,19 @@ func main() {
|
|||||||
die(err)
|
die(err)
|
||||||
}
|
}
|
||||||
defer fd.Close()
|
defer fd.Close()
|
||||||
r = fd
|
var size int64
|
||||||
|
finfo, err := fd.Stat()
|
||||||
|
if err == nil {
|
||||||
|
size = finfo.Size()
|
||||||
|
}
|
||||||
|
r = newInStream(bufio.NewReader(fd), size)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fmt.Fprintln(os.Stderr, "Error: too many arguments")
|
fmt.Fprintln(os.Stderr, "Error: too many arguments")
|
||||||
flag.Usage()
|
flag.Usage()
|
||||||
os.Exit(2)
|
os.Exit(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
out := os.Stdout
|
out := os.Stdout
|
||||||
if *reverseMode {
|
if *reverseMode {
|
||||||
data, err := textToRlp(r)
|
data, err := textToRlp(r)
|
||||||
@ -93,10 +102,10 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func rlpToText(r io.Reader, out io.Writer) error {
|
func rlpToText(in *inStream, out io.Writer) error {
|
||||||
s := rlp.NewStream(r, 0)
|
stream := rlp.NewStream(in, 0)
|
||||||
for {
|
for {
|
||||||
if err := dump(s, 0, out); err != nil {
|
if err := dump(in, stream, 0, out); err != nil {
|
||||||
if err != io.EOF {
|
if err != io.EOF {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -110,7 +119,10 @@ func rlpToText(r io.Reader, out io.Writer) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func dump(s *rlp.Stream, depth int, out io.Writer) error {
|
func dump(in *inStream, s *rlp.Stream, depth int, out io.Writer) error {
|
||||||
|
if *showpos {
|
||||||
|
fmt.Fprintf(out, "%s: ", in.posLabel())
|
||||||
|
}
|
||||||
kind, size, err := s.Kind()
|
kind, size, err := s.Kind()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -137,7 +149,7 @@ func dump(s *rlp.Stream, depth int, out io.Writer) error {
|
|||||||
if i > 0 {
|
if i > 0 {
|
||||||
fmt.Fprint(out, ",\n")
|
fmt.Fprint(out, ",\n")
|
||||||
}
|
}
|
||||||
if err := dump(s, depth+1, out); err == rlp.EOL {
|
if err := dump(in, s, depth+1, out); err == rlp.EOL {
|
||||||
break
|
break
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -208,3 +220,36 @@ func textToRlp(r io.Reader) ([]byte, error) {
|
|||||||
data, err := rlp.EncodeToBytes(obj[0])
|
data, err := rlp.EncodeToBytes(obj[0])
|
||||||
return data, err
|
return data, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type inStream struct {
|
||||||
|
br rlp.ByteReader
|
||||||
|
pos int
|
||||||
|
columns int
|
||||||
|
}
|
||||||
|
|
||||||
|
func newInStream(br rlp.ByteReader, totalSize int64) *inStream {
|
||||||
|
col := int(math.Ceil(math.Log10(float64(totalSize))))
|
||||||
|
return &inStream{br: br, columns: col}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rc *inStream) Read(b []byte) (n int, err error) {
|
||||||
|
n, err = rc.br.Read(b)
|
||||||
|
rc.pos += n
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rc *inStream) ReadByte() (byte, error) {
|
||||||
|
b, err := rc.br.ReadByte()
|
||||||
|
if err == nil {
|
||||||
|
rc.pos++
|
||||||
|
}
|
||||||
|
return b, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rc *inStream) posLabel() string {
|
||||||
|
l := strconv.FormatInt(int64(rc.pos), 10)
|
||||||
|
if len(l) < rc.columns {
|
||||||
|
l = strings.Repeat(" ", rc.columns-len(l)) + l
|
||||||
|
}
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
@ -34,7 +34,8 @@ func TestRoundtrip(t *testing.T) {
|
|||||||
"0xc780c0c1c0825208",
|
"0xc780c0c1c0825208",
|
||||||
} {
|
} {
|
||||||
var out strings.Builder
|
var out strings.Builder
|
||||||
err := rlpToText(bytes.NewReader(common.FromHex(want)), &out)
|
in := newInStream(bytes.NewReader(common.FromHex(want)), 0)
|
||||||
|
err := rlpToText(in, &out)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user