Make FrameInputStream not extend InputStream.
Fixed record reading with buffered input.

With unbuffered input, the read() call always returned the number of bytes
expected. Now in the presence of buffering, the read() call can return fewer
than the number of bytes expected once we've read to the end of the buffer.
Putting the read() call in a loop until we've read the entire record ensures
that the buffer can be re-filled and reading can resume.