#ifndef INPUTSTREAM_H #define INPUTSTREAM_H /* * @(#)InputStream.h * * This file is part of webCDwriter - Network CD/DVD Writing. * * Copyright (C) 2004-2005 Jörg P. M. Haeger * * webCDwriter is free software. See CDWserver.cpp for details. */ #include #include #include #include #include #include "Exception.h" #include "String.h" #include "StringBuffer.h" class InputStream { int fd; protected: char *buf; protected: int size; protected: int p1, p2; public: InputStream(int fd, int size = 16 * 1024) { this->fd = fd; buf = new char[size]; this->size = size; p1 = p2 = 0; } ~InputStream() { delete[] buf; } int read() { if (p1 == p2) { if (readInternal() <= 0) return -1; } return buf[p1++]; } int readWithoutSSLException() { try { return read(); } catch (Exception *e) { if (e->getMessage().indexOf("SSL connection") < 0) throw e; delete e; } return -1; } int read(char *aBuf, int off, int len) { if (len <= 0) return len; if (p1 == p2) { int n = readInternal(); if (n < 0) return n; } if (len > p2 - p1) len = p2 - p1; memcpy(&aBuf[off], &buf[p1], len); p1 += len; return len; } protected: virtual int readInternal() { if (p1 == p2) p1 = p2 = 0; int n = readInternal(fd, &buf[p2], size - p2); if (n > 0) p2 += n; return n; } public: static int readInternal(int fd, char *buf, int size) { while (true) { int res = ::read(fd, buf, size); if (res != -1 || errno != EINTR); return res; } } public: String *readLine() { StringBuffer sb = new StringBuffer(); while (true) { int ch = readWithoutSSLException(); if (ch < 0) break; if (ch == '\n') break; sb.append((char) ch); } return new String(sb); } char *readLine(char *buf, int len) { int i = 0; while (i < len - 1) { int ch = readWithoutSSLException(); if (ch < 0) if (i == 0) return NULL; else break; if (ch == '\n') break; buf[i++] = ch; } buf[i] = 0; return buf; } long skip(long n) { if (p1 + n <= p2) { p1 += n; return n; } long bytesToSkip = n; bytesToSkip -= p2 - p1; p1 = p2; while (bytesToSkip > 0) { int m = readInternal(); if (m <= 0) break; m = p2 - p1; if (m > bytesToSkip) m = bytesToSkip; p1 += m; bytesToSkip -= m; } return n - bytesToSkip; } int waitForInput(int seconds) { fd_set fdSet; FD_ZERO(&fdSet); FD_SET(fd, &fdSet); struct timeval timeout; timeout.tv_sec = seconds; timeout.tv_usec = 0; int res; do { res = select(FD_SETSIZE, &fdSet, NULL, NULL, &timeout); } while (res == -1L && errno == EINTR); return res; } }; #endif