/* * @(#)LineReader.cpp * * This file is part of webCDwriter - Network CD Writing. * * Copyright (C) 2001 Jörg P. M. Haeger * * webCDwriter is free software. See CDWserver.cpp for details. */ #include #include #include #include #include #include "Exception.h" #include "LineReader.h" const char BS = 8, LF = '\n', CR = '\r'; LineReader::LineReader(int fd) { cursor = 0; eob = 0; eof = 0; eol = 0; this->fd = fd; } int LineReader::available() { while (eol < eob && buf[eol] != BS && buf[eol] != CR && buf[eol] != LF) eol++; return eol < eob || eol == bufSize; } const char *LineReader::next(int timeout) { while (!available() && !eof) { if (timeout > 0) { fd_set fdSet; FD_ZERO(&fdSet); FD_SET(fd, &fdSet); struct timeval tv; tv.tv_sec = timeout; tv.tv_usec = 0; if (select(FD_SETSIZE, &fdSet, NULL, NULL, &tv) == 0) throw new Exception("timeout"); } read(); } if (eob == 0) return NULL; for (int i = 0; i < eol; i++) line[cursor++] = buf[i]; line[cursor] = 0; // go to the first character of the next line int next = eol; if (next == eob || buf[next] != BS) { cursor = 0; if (next + 1 < eob && buf[next + 1] == LF) next++; if (next < eob) next++; } else { for (; next < eob && buf[next] == BS; next++) if (cursor > 0) cursor--; } // for (int j = 0; j < eob - next; j++) // buf[j] = buf[j + next]; memmove(buf, buf + next, eob - next); eob -= next; eol = 0; return line; } void LineReader::read() { int n; while ((n = ::read(fd, &buf[eob], bufSize - eob)) == -1 && errno == EINTR) ; if (n == 0) eof = 1; else if (n > 0) eob += n; }