From 7b81490ae4ed6c7c8566f889d146677827f5d4a5 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Mon, 7 Oct 2013 19:36:04 +0300 Subject: [PATCH] Rewrite BufferedFile as a standalone class The generic Filtered template is unable to account for the complexities of buffering a seekable object. In particular, relative seeks were broken. I may revisit the template form at a later date if I come up with a workable design. For now its use is discouraged. --- source/io/file.cpp | 61 ++++++++++++++++++++++++++++++++++++++++++++ source/io/file.h | 24 ++++++++++++++++- source/io/filtered.h | 6 ++++- 3 files changed, 89 insertions(+), 2 deletions(-) diff --git a/source/io/file.cpp b/source/io/file.cpp index 9069432..666b1ed 100644 --- a/source/io/file.cpp +++ b/source/io/file.cpp @@ -81,5 +81,66 @@ const Handle &File::get_handle(Mode m) return handle; } + +BufferedFile::BufferedFile(const string &fn, Mode m, File::CreateMode cm): + file(fn, m, cm), + buffer(file), + position(0) +{ + mode = m; + file.signal_end_of_file.connect(sigc::mem_fun(this, &BufferedFile::set_eof)); +} + +unsigned BufferedFile::do_write(const char *buf, unsigned size) +{ + unsigned ret = buffer.write(buf, size); + position += ret; + return ret; +} + +unsigned BufferedFile::do_read(char *buf, unsigned size) +{ + unsigned ret = buffer.read(buf, size); + position += ret; + return ret; +} + +unsigned BufferedFile::put(char c) +{ + unsigned ret = buffer.put(c); + position += ret; + return ret; +} + +bool BufferedFile::getline(string &line) +{ + bool ret = buffer.getline(line); + if(ret) + position += line.size(); + return ret; +} + +int BufferedFile::get() +{ + int ret = buffer.get(); + if(ret>=0) + ++position; + return ret; +} + +SeekOffset BufferedFile::seek(SeekOffset offset, SeekType type) +{ + if(type==S_CUR) + { + offset += position; + type = S_BEG; + } + + signal_flush_required.emit(); + position = file.seek(offset, type); + eof_flag = false; + return position; +} + } // namespace IO } // namespace Msp diff --git a/source/io/file.h b/source/io/file.h index d106561..d342734 100644 --- a/source/io/file.h +++ b/source/io/file.h @@ -81,7 +81,29 @@ inline File::CreateMode operator&(File::CreateMode m, File::CreateMode n) inline File::CreateMode operator~(File::CreateMode m) { return File::CreateMode(~static_cast(m)); } -typedef Filtered BufferedFile; + +class BufferedFile: public Seekable +{ +private: + File file; + Buffered buffer; + SeekOffset position; + +public: + BufferedFile(const std::string &, Mode = M_READ, File::CreateMode = File::C_OVERWRITE); + +protected: + virtual unsigned do_write(const char *, unsigned); + virtual unsigned do_read(char *, unsigned); +public: + virtual unsigned put(char); + + virtual bool getline(std::string &); + virtual int get(); + + virtual SeekOffset seek(SeekOffset, SeekType); + virtual SeekOffset tell() const { return position; } +}; } // namespace IO } // namespace Msp diff --git a/source/io/filtered.h b/source/io/filtered.h index a4a4319..2092743 100644 --- a/source/io/filtered.h +++ b/source/io/filtered.h @@ -4,7 +4,11 @@ namespace Msp { namespace IO { -// XXX This needs a redesign +/** +This class is broken by design. Do not use. It exposes base class methods in +an unsafe and misleading way. In particular, a Filtered causes +seeks to behave incorrectly. +*/ template class Filtered: public B { -- 2.45.2