sclass ByteCountingLineReader implements Closeable { InputStream in; long _byteCount; int bufferedByte = -1; bool ended; *(InputStream *in) {} // in should be buffered! ByteCountingLineReader(File f) { in = bufferedInputStream(f); } S readLine() ctex { new ByteArrayOutputStream baos; while (licensed() && !ended) { int c = read(); if (c == '\n') break; if (c == '\r') { c = read(); if (c != '\n' && !ended) bufferedByte = c; break; } baos.write(c); } ret fromUtf8(baos.toByteArray()); } int read() ctex { if (bufferedByte >= 0) { int b = bufferedByte; bufferedByte = -1; ret b; } int c = in.read(); if (c < 0) ended = true; ++_byteCount; ret c; } long byteCount() { ret bufferedByte >= 0 ? _byteCount-1 : _byteCount; } public void close() ctex { in.close(); } }