forked from OctaForge/libostd
filesystem module enhancements
parent
d0662f2b08
commit
baaa1e790d
|
@ -167,6 +167,8 @@ private:
|
||||||
struct DirectoryRange;
|
struct DirectoryRange;
|
||||||
|
|
||||||
struct DirectoryStream {
|
struct DirectoryStream {
|
||||||
|
friend struct DirectoryRange;
|
||||||
|
|
||||||
DirectoryStream(): p_d(), p_path(), p_owned(false) {}
|
DirectoryStream(): p_d(), p_path(), p_owned(false) {}
|
||||||
DirectoryStream(const DirectoryStream &) = delete;
|
DirectoryStream(const DirectoryStream &) = delete;
|
||||||
DirectoryStream(DirectoryStream &&s): p_d(s.p_d), p_path(move(s.p_path)),
|
DirectoryStream(DirectoryStream &&s): p_d(s.p_d), p_path(move(s.p_path)),
|
||||||
|
@ -208,15 +210,17 @@ struct DirectoryStream {
|
||||||
p_owned = false;
|
p_owned = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool seek(long offset) {
|
long size() const {
|
||||||
if (!p_d) return false;
|
|
||||||
seekdir(p_d, offset);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
long tell() const {
|
|
||||||
if (!p_d) return -1;
|
if (!p_d) return -1;
|
||||||
return telldir(p_d);
|
long cs = telldir(p_d);
|
||||||
|
if (cs < 0) return cs;
|
||||||
|
seekdir(p_d, 0);
|
||||||
|
long ret = 0;
|
||||||
|
struct dirent *rd = nullptr;
|
||||||
|
while ((rd = readdir(p_d)))
|
||||||
|
ret += (strcmp(rd->d_name, ".") && strcmp(rd->d_name, ".."));
|
||||||
|
seekdir(p_d, cs);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rewind() {
|
bool rewind() {
|
||||||
|
@ -246,53 +250,71 @@ struct DirectoryStream {
|
||||||
DirectoryRange iter();
|
DirectoryRange iter();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool compare(const DirectoryStream &ds) {
|
||||||
|
if (!p_d) return !ds.p_d;
|
||||||
|
return (p_d == ds.p_d) && (telldir(p_d) == telldir(ds.p_d));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool empty(long n) const {
|
||||||
|
return !p_d || (telldir(p_d) >= n);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pop_front() const {
|
||||||
|
if (!p_d) return false;
|
||||||
|
long cs = telldir(p_d);
|
||||||
|
if (cs < 0) return false;
|
||||||
|
seekdir(p_d, cs + 1);
|
||||||
|
return telldir(p_d) == (cs + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void push_front() const {
|
||||||
|
if (!p_d) return;
|
||||||
|
long cs = telldir(p_d);
|
||||||
|
if (cs < 0) return;
|
||||||
|
seekdir(p_d, cs - 1);
|
||||||
|
}
|
||||||
|
|
||||||
DIR *p_d;
|
DIR *p_d;
|
||||||
String p_path;
|
String p_path;
|
||||||
bool p_owned;
|
bool p_owned;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DirectoryRange: InputRange<
|
struct DirectoryRange: InputRange<
|
||||||
DirectoryRange, InputRangeTag, FileInfo, FileInfo &, Size, long
|
DirectoryRange, InputRangeTag, FileInfo, FileInfo, Size, long
|
||||||
> {
|
> {
|
||||||
DirectoryRange() = delete;
|
DirectoryRange() = delete;
|
||||||
DirectoryRange(DirectoryStream &s): p_stream(&s) {
|
DirectoryRange(DirectoryStream &s): p_stream(&s), p_ssize(s.size()) {}
|
||||||
p_curr = move(s.read());
|
|
||||||
}
|
|
||||||
DirectoryRange(const DirectoryRange &r):
|
DirectoryRange(const DirectoryRange &r):
|
||||||
p_stream(r.p_stream), p_curr(r.p_curr) {}
|
p_stream(r.p_stream), p_ssize(r.p_ssize) {}
|
||||||
DirectoryRange(DirectoryRange &&r): p_stream(r.p_stream),
|
|
||||||
p_curr(move(r.p_curr)) {
|
|
||||||
r.p_stream = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
DirectoryRange &operator=(const DirectoryRange &) = delete;
|
DirectoryRange &operator=(const DirectoryRange &r) {
|
||||||
DirectoryRange &operator=(DirectoryRange &&r) {
|
p_stream = r.p_stream;
|
||||||
detail::swap_adl(p_stream, r.p_stream);
|
p_ssize = r.p_ssize;
|
||||||
detail::swap_adl(p_curr, r.p_curr);
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool empty() const {
|
bool empty() const {
|
||||||
return p_curr.type() == FileType::unknown;
|
return p_stream->empty(p_ssize);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pop_front() {
|
bool pop_front() {
|
||||||
if (empty()) return false;
|
return p_stream->pop_front();
|
||||||
p_curr = move(p_stream->read());
|
|
||||||
return empty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FileInfo &front() const {
|
FileInfo front() const {
|
||||||
return p_curr;
|
FileInfo ret(p_stream->read());
|
||||||
|
p_stream->push_front();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool equals_front(const DirectoryRange &s) const {
|
bool equals_front(const DirectoryRange &s) const {
|
||||||
return p_stream->tell() == s.p_stream->tell();
|
if (!p_stream) return !s.p_stream;
|
||||||
|
return p_stream->compare(*s.p_stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DirectoryStream *p_stream;
|
DirectoryStream *p_stream;
|
||||||
mutable FileInfo p_curr;
|
long p_ssize;
|
||||||
};
|
};
|
||||||
|
|
||||||
DirectoryRange DirectoryStream::iter() {
|
DirectoryRange DirectoryStream::iter() {
|
||||||
|
|
Loading…
Reference in New Issue