diff options
| -rw-r--r-- | includes/Handle.h | 10 | ||||
| -rw-r--r-- | includes/Input.h | 1 | ||||
| -rw-r--r-- | src/Handle.cc | 3 | ||||
| -rw-r--r-- | src/Input.cc | 22 | ||||
| -rw-r--r-- | tests/test-Handles.cc | 20 | 
5 files changed, 51 insertions, 5 deletions
| diff --git a/includes/Handle.h b/includes/Handle.h index 489ab75..e3e22cd 100644 --- a/includes/Handle.h +++ b/includes/Handle.h @@ -9,6 +9,11 @@ class EAgain : public GeneralException {        EAgain() : GeneralException("Try Again") { }  }; +class ENoEnt : public GeneralException { +  public: +      ENoEnt(const char * name) : GeneralException(String("No such file or directory: `") + name + "'") { } +}; +  class IO;  class Handle { @@ -16,6 +21,7 @@ class Handle {        virtual ~Handle() { Assert(m_refCount == 0); }      virtual void close() throw (GeneralException) = 0;      virtual bool isClosed() = 0; +    virtual bool isEOF() = 0;      virtual bool canSeek();      virtual bool canRead();      virtual bool canWrite(); @@ -59,6 +65,10 @@ class SeekableHandle : public Handle {      virtual void wseek(off_t offset, int whence = SEEK_SET) throw (GeneralException);      virtual off_t rtell() throw (GeneralException);      virtual off_t wtell() throw (GeneralException); +    virtual bool isEOF(); +  protected: +    off_t getWOffset() { return m_wOffset; } +    off_t getROffset() { return m_rOffset; }    private:      off_t m_wOffset, m_rOffset;  }; diff --git a/includes/Input.h b/includes/Input.h index 71e6845..518db39 100644 --- a/includes/Input.h +++ b/includes/Input.h @@ -8,6 +8,7 @@ class Input : public SeekableHandle {    public:        Input(const char * fname) throw (GeneralException);      virtual void close() throw (GeneralException); +    virtual ssize_t read(void * buf, size_t count) throw (GeneralException);      virtual bool isClosed();      virtual bool canRead();      virtual const char * getName(); diff --git a/src/Handle.cc b/src/Handle.cc index e00bcf2..7bb6c19 100644 --- a/src/Handle.cc +++ b/src/Handle.cc @@ -153,3 +153,6 @@ off_t Balau::SeekableHandle::wtell() throw (GeneralException) {      return m_wOffset;  } +bool Balau::SeekableHandle::isEOF() { +    return m_rOffset == getSize(); +} diff --git a/src/Input.cc b/src/Input.cc index 09b2903..3fece65 100644 --- a/src/Input.cc +++ b/src/Input.cc @@ -1,3 +1,4 @@ +#include <errno.h>  #include <string.h>  #include <sys/types.h>  #include <sys/stat.h> @@ -44,7 +45,11 @@ Balau::Input::Input(const char * fname) throw (GeneralException) : m_fd(-1), m_s      Assert(cbResults.evt.gotSignal());      if (cbResults.result < 0) {          char str[4096]; -        throw GeneralException(String("Unable to open file ") + m_name + " for reading: " + strerror_r(cbResults.errorno, str, sizeof(str)) + " (err#" + cbResults.errorno + ")"); +        if (cbResults.errorno == ENOENT) { +            throw ENoEnt(fname); +        } else { +            throw GeneralException(String("Unable to open file ") + m_name + " for reading: " + strerror_r(cbResults.errorno, str, sizeof(str)) + " (err#" + cbResults.errorno + ")"); +        }      } else {          m_fd = cbResults.result;      } @@ -78,6 +83,21 @@ void Balau::Input::close() throw (GeneralException) {      }  } +ssize_t Balau::Input::read(void * buf, size_t count) throw (GeneralException) { +    cbResults_t cbResults; +    eio_req * r = eio_read(m_fd, buf, count, getROffset(), 0, eioDone, &cbResults); +    Assert(r != 0); +    Task::yield(&cbResults.evt); +    Assert(cbResults.evt.gotSignal()); +    if (cbResults.result > 0) { +        rseek(cbResults.result, SEEK_CUR); +    } else { +        char str[4096]; +        throw GeneralException(String("Unable to read file ") + m_name + ": " + strerror_r(cbResults.errorno, str, sizeof(str)) + " (err#" + cbResults.errorno + ")"); +    } +    return cbResults.result; +} +  bool Balau::Input::isClosed() {      return m_fd < 0;  } diff --git a/tests/test-Handles.cc b/tests/test-Handles.cc index 8c3c190..36ad998 100644 --- a/tests/test-Handles.cc +++ b/tests/test-Handles.cc @@ -12,7 +12,7 @@ void MainTask::Do() {      try {          IO i(new Input("SomeInexistantFile.txt"));      } -    catch (GeneralException) { +    catch (ENoEnt e) {          failed = true;      }      Assert(failed); @@ -36,9 +36,21 @@ void MainTask::Do() {      Assert(s == i->getSize());      i->rseek(0, SEEK_SET); -    char * buf = (char *) malloc(i->getSize()); -    ssize_t r = i->read(buf, s + 15); -    Printer::log(M_STATUS, "Read %i bytes", r); +    char * buf1 = (char *) malloc(i->getSize()); +    ssize_t r = i->read(buf1, s + 15); +    Printer::log(M_STATUS, "Read %i bytes (instead of %i)", r, s + 15); +    Assert(i->isEOF()) + +    char * buf2 = (char *) malloc(i->getSize()); +    i->rseek(0, SEEK_SET); +    Assert(!i->isEOF()); +    Assert(i->rtell() == 0); +    r = i->read(buf2, 5); +    Assert(r == 5); +    Assert(i->rtell() == 5); +    r = i->read(buf2 + 5, s - 5); +    Assert(r == (s - 5)); +    Assert(memcmp(buf1, buf2, s) == 0);      Printer::log(M_STATUS, "Test::Handles passed.");  } | 
