Refactor serialize to pack all values at once

Instead of building subclasses in their own BitStream and appending
them, this gathers all of the values at once, and using a pre-computed
flat format, packs everything in one call.