separate StreamRange from Stream

master
Daniel Kolesa 2015-06-26 21:14:54 +01:00
parent 9677274b3f
commit 45e468fed3
1 changed files with 28 additions and 15 deletions

View File

@ -25,6 +25,8 @@ enum class StreamSeek {
set = SEEK_SET set = SEEK_SET
}; };
struct StreamRange;
struct Stream: InputRange< struct Stream: InputRange<
Stream, octa::InputRangeTag, char, char, octa::Size, StreamOffset Stream, octa::InputRangeTag, char, char, octa::Size, StreamOffset
> { > {
@ -54,32 +56,45 @@ struct Stream: InputRange<
virtual octa::Size read(char *, octa::Size) { return 0; } virtual octa::Size read(char *, octa::Size) { return 0; }
virtual octa::Size write(const char *, octa::Size) { return 0; } virtual octa::Size write(const char *, octa::Size) { return 0; }
/* range interface */ StreamRange iter();
};
bool empty() const { return end(); } struct StreamRange: InputRange<
Stream, octa::InputRangeTag, char, char, octa::Size, StreamOffset
> {
StreamRange(Stream &s): p_stream(&s) {}
StreamRange(const StreamRange &r): p_stream(r.p_stream) {}
bool empty() const { return p_stream->end(); }
bool pop_front() { bool pop_front() {
if (empty()) return false; if (empty()) return false;
char val; char val;
return !!read(&val, 1); return !!p_stream->read(&val, 1);
} }
char front() const { char front() const {
Stream *f = (Stream *)this;
char val; char val;
f->seek(-f->read(&val, 1), StreamSeek::cur); p_stream->seek(-p_stream->read(&val, 1), StreamSeek::cur);
return val; return val;
} }
virtual bool equals_front(const Stream &s) const { virtual bool equals_front(const StreamRange &s) const {
return s.tell() == tell(); return p_stream->tell() == s.p_stream->tell();
} }
void put(const char &val) { void put(const char &val) {
write(&val, 1); p_stream->write(&val, 1);
} }
private:
Stream *p_stream;
}; };
inline StreamRange Stream::iter() {
return StreamRange(*this);
}
enum class StreamMode { enum class StreamMode {
read, write, append, read, write, append,
update = 1 << 2 update = 1 << 2
@ -92,24 +107,23 @@ namespace detail {
} }
struct FileStream: Stream { struct FileStream: Stream {
FileStream(): p_f(), p_owned(false) {} FileStream(): p_f() {}
FileStream(const FileStream &s): p_f(s.p_f), p_owned(false) {} FileStream(const FileStream &s): p_f(s.p_f) {}
FileStream(const octa::String &path, StreamMode mode): p_f(), p_owned(false) { FileStream(const octa::String &path, StreamMode mode): p_f() {
open(path, mode); open(path, mode);
} }
~FileStream() { close(); } ~FileStream() { close(); }
bool open(const octa::String &path, StreamMode mode) { bool open(const octa::String &path, StreamMode mode) {
if (p_f && !p_owned) return false; if (p_f) return false;
p_f = fopen(path.data(), octa::detail::filemodes[octa::Size(mode)]); p_f = fopen(path.data(), octa::detail::filemodes[octa::Size(mode)]);
p_owned = true;
return p_f != nullptr; return p_f != nullptr;
} }
void close() { void close() {
if (p_owned && p_f) fclose(p_f); if (p_f) fclose(p_f);
p_f = nullptr; p_f = nullptr;
} }
@ -137,7 +151,6 @@ struct FileStream: Stream {
private: private:
FILE *p_f; FILE *p_f;
bool p_owned;
}; };
} }