Implementations should perform final operations on their buffered input, AND reset any stateful variables they may have. This is called by both flush and doFinal.
Implementations can check which was called, if necessary, by:
If isClosed is true, doFinal was invoked.
If isClosed is false, flush was invoked.