diff options
author | Felix Lange <fjl@twurst.com> | 2015-02-12 02:28:56 +0800 |
---|---|---|
committer | Felix Lange <fjl@twurst.com> | 2015-02-12 02:28:56 +0800 |
commit | b94f85de22cd53b87872543c959064cd2043c40d (patch) | |
tree | ac432bed0900180e7952e4c84706801c6dbeb4e6 /rlp/encode.go | |
parent | ddccea75e8f4931689fdf6b57ec7159b65c0d3c5 (diff) | |
download | dexon-b94f85de22cd53b87872543c959064cd2043c40d.tar.gz dexon-b94f85de22cd53b87872543c959064cd2043c40d.tar.zst dexon-b94f85de22cd53b87872543c959064cd2043c40d.zip |
rlp: add Flat
Diffstat (limited to 'rlp/encode.go')
-rw-r--r-- | rlp/encode.go | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/rlp/encode.go b/rlp/encode.go index d80b66315..6ae4a123a 100644 --- a/rlp/encode.go +++ b/rlp/encode.go @@ -32,6 +32,48 @@ type Encoder interface { EncodeRLP(io.Writer) error } +// Flat wraps a value (which must encode as a list) so +// it encodes as the list's elements. +// +// Example: suppose you have defined a type +// +// type foo struct { A, B uint } +// +// Under normal encoding rules, +// +// rlp.Encode(foo{1, 2}) --> 0xC20102 +// +// This function can help you achieve the following encoding: +// +// rlp.Encode(rlp.Flat(foo{1, 2})) --> 0x0102 +func Flat(val interface{}) Encoder { + return flatenc{val} +} + +type flatenc struct{ val interface{} } + +func (e flatenc) EncodeRLP(out io.Writer) error { + // record current output position + var ( + eb = out.(*encbuf) + prevstrsize = len(eb.str) + prevnheads = len(eb.lheads) + ) + if err := eb.encode(e.val); err != nil { + return err + } + // check that a new list header has appeared + if len(eb.lheads) == prevnheads || eb.lheads[prevnheads].offset == prevstrsize-1 { + return fmt.Errorf("rlp.Flat: %T did not encode as list", e.val) + } + // remove the new list header + newhead := eb.lheads[prevnheads] + copy(eb.lheads[prevnheads:], eb.lheads[prevnheads+1:]) + eb.lheads = eb.lheads[:len(eb.lheads)-1] + eb.lhsize -= newhead.tagsize() + return nil +} + // Encode writes the RLP encoding of val to w. Note that Encode may // perform many small writes in some cases. Consider making w // buffered. @@ -123,6 +165,13 @@ func (head *listhead) encode(buf []byte) []byte { } } +func (head *listhead) tagsize() int { + if head.size < 56 { + return 1 + } + return 1 + intsize(uint64(head.size)) +} + func newencbuf() *encbuf { return &encbuf{sizebuf: make([]byte, 9)} } |