From d2252afcd74af0248c6141c8086d03e12a0a316f Mon Sep 17 00:00:00 2001 From: Pixel Date: Tue, 11 Oct 2011 00:47:18 -0700 Subject: Input class seems to be done. --- includes/Handle.h | 10 ++++++++++ includes/Input.h | 1 + src/Handle.cc | 3 +++ src/Input.cc | 22 +++++++++++++++++++++- 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 #include #include #include @@ -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."); } -- cgit v1.2.3