This topic is an excerpt of the discussion in #82 (comment)
In event-driven I/O, we call unpackXXX after we receive new data from a network (or another resource). That indicates unpackXXX might be called even if insufficient amount of packed data is available.
Because of this, behavior of unpackXXX (e.g., unpackInt, unpackString, etc.) would be as follows:
- It returns the unpacked value and proceeds the cursor on success.
- If it fails due to lack of the incoming data, it throws an InsufficientDataException. The cursor does not move in this case, so that the user can call unpackXXX after sufficient amount of data becomes available.