// checkDecodeFromJSON decodes from s guided by exp. exp drives the // Stream by invoking decoding operations (Uint, Big, List, ...) based // on the type of each value. The value decoded from the RLP stream // must match the JSON value. func checkDecodeFromJSON(s *rlp.Stream, exp interface{}) error { switch exp := exp.(type) { case uint64: i, err := s.Uint() if err != nil { return addStack("Uint", exp, err) } if i != exp { return addStack("Uint", exp, fmt.Errorf("result mismatch: got %d", i)) } case *big.Int: big := new(big.Int) if err := s.Decode(&big); err != nil { return addStack("Big", exp, err) } if big.Cmp(exp) != 0 { return addStack("Big", exp, fmt.Errorf("result mismatch: got %d", big)) } case []byte: b, err := s.Bytes() if err != nil { return addStack("Bytes", exp, err) } if !bytes.Equal(b, exp) { return addStack("Bytes", exp, fmt.Errorf("result mismatch: got %x", b)) } case []interface{}: if _, err := s.List(); err != nil { return addStack("List", exp, err) } for i, v := range exp { if err := checkDecodeFromJSON(s, v); err != nil { return addStack(fmt.Sprintf("[%d]", i), exp, err) } } if err := s.ListEnd(); err != nil { return addStack("ListEnd", exp, err) } default: panic(fmt.Errorf("unhandled type: %T", exp)) } return nil }
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.Print(ws(depth) + "[]") } 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 }