fix and optimize toVarint

- need unsigned value for right shift

- src > 0x7F is faster than src & ~0x7FUL because the
  instruction can be encoded with fewer bytes (small constant)
avoid allocations during serialization

- count number of bytes before writing nested structs

- rewrite serialize functions to take an output range