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
inline File::CreateMode operator~(File::CreateMode m)
{ return File::CreateMode(~static_cast<int>(m)); }
-typedef Filtered<File, Buffered> 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
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<File, Buffered> causes
+seeks to behave incorrectly.
+*/
template<typename B, typename F>
class Filtered: public B
{