Split out encode/decode logic

The encode/decode logic for vectors and maps is generic and applies to
other vector-like and map-like data structures.  Split this out so that
it can be reused when other data structures are added.

Also, splitting these out makes the code a tad easier to look at.