io: Add support for composite types to `read`

`read` is called for each field in the composite type. The result of
each `read` is stored in a tuple and then passed to the composite
type's constructor.