diff options
author | Jeffrey Wilcke <jeffrey@ethereum.org> | 2015-02-12 03:22:04 +0800 |
---|---|---|
committer | Jeffrey Wilcke <jeffrey@ethereum.org> | 2015-02-12 03:22:04 +0800 |
commit | d73dff4d5b7ec88325cb605d9e3a56e7da979f8d (patch) | |
tree | 7c67f388a5b6913e6b35b9219edb372587842008 /rlp/encode.go | |
parent | ebc506dae8a15e5dcce4e4369e21d04e3b8f9aa4 (diff) | |
parent | b94f85de22cd53b87872543c959064cd2043c40d (diff) | |
download | dexon-d73dff4d5b7ec88325cb605d9e3a56e7da979f8d.tar dexon-d73dff4d5b7ec88325cb605d9e3a56e7da979f8d.tar.gz dexon-d73dff4d5b7ec88325cb605d9e3a56e7da979f8d.tar.bz2 dexon-d73dff4d5b7ec88325cb605d9e3a56e7da979f8d.tar.lz dexon-d73dff4d5b7ec88325cb605d9e3a56e7da979f8d.tar.xz dexon-d73dff4d5b7ec88325cb605d9e3a56e7da979f8d.tar.zst dexon-d73dff4d5b7ec88325cb605d9e3a56e7da979f8d.zip |
Merge pull request #303 from fjl/rlp-flat
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)} } |