use CntRange to avoid temporary allocations

- count number of bytes before writing nested structs