separate StreamRange from Stream
This commit is contained in:
parent
9677274b3f
commit
45e468fed3
|
@ -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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue