diff options
author | Pixel <pixel@nobis-crew.org> | 2011-10-17 21:04:34 -0700 |
---|---|---|
committer | Pixel <pixel@nobis-crew.org> | 2011-10-17 21:04:34 -0700 |
commit | 1e0ba312edbe0feea88737380ef1a71782779437 (patch) | |
tree | cd1225ab42ae1f66b070c19660e47a21e7fbc1bc | |
parent | 10d0f503fb68946c265bad18dd755fdc816075c1 (diff) |
Redefined how the IO class works. The ref counting should now work properly.
-rw-r--r-- | includes/Handle.h | 39 | ||||
-rw-r--r-- | tests/test-Handles.cc | 4 |
2 files changed, 31 insertions, 12 deletions
diff --git a/includes/Handle.h b/includes/Handle.h index 0e19e50..2f2a029 100644 --- a/includes/Handle.h +++ b/includes/Handle.h @@ -10,6 +10,9 @@ class ENoEnt : public GeneralException { ENoEnt(const char * name) : GeneralException(String("No such file or directory: `") + name + "'") { } }; +class IOBase; + +template<class T> class IO; class Handle { @@ -34,25 +37,41 @@ class Handle { Handle() : m_refCount(0) { } private: void addRef() { m_refCount++; } - void delRef() { if (--m_refCount == 0) { if (!isClosed()) close(); delete this; } } - int refCount() { return m_refCount; } + void delRef() { + if (--m_refCount == 0) { + if (!isClosed()) + close(); + delete this; + } + } + friend class IOBase; + template<class T> friend class IO; int m_refCount; }; -class IO { +class IOBase { public: - IO() : m_h(NULL) { } - IO(Handle * h) { setHandle(h); } - ~IO() { if (m_h) m_h->delRef(); } - IO(const IO & io) { setHandle(io.m_h); } - IO & operator=(const IO & io) { if (m_h) m_h->delRef(); setHandle(io.m_h); return *this; } - Handle * operator->() { Assert(m_h); return m_h; } + IOBase() : m_h(NULL) { } + ~IOBase() { if (m_h) m_h->delRef(); } protected: void setHandle(Handle * h) { m_h = h; m_h->addRef(); } - private: Handle * m_h; + template<class T> + friend class IO; +}; + +template<class T> +class IO : public IOBase { + public: + IO() { } + IO(T * h) { setHandle(h); } + IO(const IO<T> & io) { setHandle(io.m_h); } + template<class U> + IO(const IO<U> & io) { setHandle(io.m_h); } + IO<T> & operator=(const IO<T> & io) { if (m_h) m_h->delRef(); setHandle(io.m_h); return *this; } + T * operator->() { Assert(m_h); return dynamic_cast<T *>(m_h); } }; class SeekableHandle : public Handle { diff --git a/tests/test-Handles.cc b/tests/test-Handles.cc index dffdc9a..c500394 100644 --- a/tests/test-Handles.cc +++ b/tests/test-Handles.cc @@ -20,13 +20,13 @@ void MainTask::Do() { bool failed = false; try { - IO i(new Input("SomeInexistantFile.txt")); + IO<Handle> i(new Input("SomeInexistantFile.txt")); } catch (ENoEnt e) { failed = true; } Assert(failed); - IO i(new Input("tests/rtest.txt")); + IO<Handle> i(new Input("tests/rtest.txt")); Printer::log(M_STATUS, "Opened file %s:", i->getName()); Printer::log(M_STATUS, " - size = %lli", i->getSize()); |