|
| 1 | +/** |
| 2 | + * Similar to Read N Characters Given Read4, but the read |
| 3 | + * function may be called multiple times |
| 4 | + * |
| 5 | + * Tags: |
| 6 | + */ |
| 7 | +class ReadNMultipleRead4 { |
| 8 | + |
| 9 | + public static void main(String[] args) { |
| 10 | + |
| 11 | + } |
| 12 | + |
| 13 | + /** |
| 14 | + * Store state of previous call |
| 15 | + * Including a buffer, an offset index of the buffer, |
| 16 | + */ |
| 17 | + private char[] buffer = new char[4]; |
| 18 | + int offset = 0, bufsize = 0; |
| 19 | + |
| 20 | + /** |
| 21 | + * Call multiple times, storing states |
| 22 | + * The difference between single time multiple times is: |
| 23 | + * There can be some characters return by read4 in the buffer |
| 24 | + * We need to get them for the next call |
| 25 | + * For example, supppose n is 5, read4 will be call twice, 3 chars remain |
| 26 | + * Next read5 call needs to get those 3 characters |
| 27 | + * |
| 28 | + * So we make buffer as a field variable, along with offset and bufsize |
| 29 | + * If bufsize > 0, means something in buffer |
| 30 | + * |
| 31 | + * @param buf Destination buffer |
| 32 | + * @param n Maximum number of characters to read |
| 33 | + * @return The number of characters read |
| 34 | + */ |
| 35 | + public int read(char[] buf, int n) { |
| 36 | + int readBytes = 0; |
| 37 | + boolean eof = false; // flag |
| 38 | + while (!eof && readBytes < n) { |
| 39 | + int sz = (bufsize > 0) ? bufsize : read4(buffer); |
| 40 | + if (bufsize == 0 && sz < 4) eof = true; // empty buffer, no more |
| 41 | + int bytes = Math.min(n - readBytes, sz); |
| 42 | + // from offset in buffer, to readBytes in output buffer |
| 43 | + System.arraycopy(buffer, offset, buf, readBytes, bytes); |
| 44 | + offset = (offset + bytes) % 4; // update offset |
| 45 | + bufsize = sz - bytes; // size read - size copied |
| 46 | + readBytes += bytes; // update readBytes |
| 47 | + } |
| 48 | + return readBytes; |
| 49 | + } |
| 50 | +} |
0 commit comments