split filestreams into octa/io.hh + add more funcs, methods etc
This commit is contained in:
parent
1e7640031a
commit
656ddb76af
136
octa/io.hh
Normal file
136
octa/io.hh
Normal file
|
@ -0,0 +1,136 @@
|
|||
/* Standard I/O implementation for OctaSTD.
|
||||
*
|
||||
* This file is part of OctaSTD. See COPYING.md for futher information.
|
||||
*/
|
||||
|
||||
#ifndef OCTA_IO_HH
|
||||
#define OCTA_IO_HH
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "octa/string.hh"
|
||||
#include "octa/stream.hh"
|
||||
|
||||
namespace octa {
|
||||
|
||||
enum class StreamMode {
|
||||
read, write, append,
|
||||
update = 1 << 2
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
static const char *filemodes[] = {
|
||||
"rb", "wb", "ab", nullptr, "rb+", "wb+", "ab+"
|
||||
};
|
||||
}
|
||||
|
||||
struct FileStream: Stream {
|
||||
FileStream(): p_f(), p_owned(false) {}
|
||||
FileStream(const FileStream &) = delete;
|
||||
FileStream(FileStream &&s): p_f(s.p_f), p_owned(s.p_owned) {
|
||||
s.p_f = nullptr;
|
||||
s.p_owned = false;
|
||||
}
|
||||
|
||||
FileStream(const octa::String &path, StreamMode mode): p_f() {
|
||||
open(path, mode);
|
||||
}
|
||||
|
||||
FileStream(FILE *f): p_f(f), p_owned(false) {}
|
||||
|
||||
~FileStream() { close(); }
|
||||
|
||||
FileStream &operator=(const FileStream &) = delete;
|
||||
FileStream &operator=(FileStream &&s) {
|
||||
close();
|
||||
swap(s);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool open(const octa::String &path, StreamMode mode) {
|
||||
if (p_f) return false;
|
||||
p_f = fopen(path.data(), octa::detail::filemodes[octa::Size(mode)]);
|
||||
p_owned = true;
|
||||
return is_open();
|
||||
}
|
||||
|
||||
bool open(FILE *f) {
|
||||
if (p_f) return false;
|
||||
p_f = f;
|
||||
p_owned = false;
|
||||
return is_open();
|
||||
}
|
||||
|
||||
bool is_open() const { return p_f != nullptr; }
|
||||
bool is_owned() const { return p_owned; }
|
||||
|
||||
void close() {
|
||||
if (p_f && p_owned) fclose(p_f);
|
||||
p_f = nullptr;
|
||||
p_owned = false;
|
||||
}
|
||||
|
||||
bool end() const {
|
||||
return feof(p_f) != 0;
|
||||
}
|
||||
|
||||
bool seek(StreamOffset pos, StreamSeek whence = StreamSeek::set) {
|
||||
return fseeko(p_f, pos, int(whence)) >= 0;
|
||||
}
|
||||
|
||||
StreamOffset tell() const {
|
||||
return ftello(p_f);
|
||||
}
|
||||
|
||||
bool flush() { return !fflush(p_f); }
|
||||
|
||||
using Stream::read;
|
||||
using Stream::write;
|
||||
|
||||
octa::Size read(void *buf, octa::Size count) {
|
||||
return fread(buf, 1, count, p_f);
|
||||
}
|
||||
|
||||
octa::Size write(const void *buf, octa::Size count) {
|
||||
return fwrite(buf, 1, count, p_f);
|
||||
}
|
||||
|
||||
void swap(FileStream &s) {
|
||||
octa::swap(p_f, s.p_f);
|
||||
octa::swap(p_owned, s.p_owned);
|
||||
}
|
||||
|
||||
FILE *get_file() { return p_f; }
|
||||
|
||||
private:
|
||||
FILE *p_f;
|
||||
bool p_owned;
|
||||
};
|
||||
|
||||
static FileStream in(::stdin);
|
||||
static FileStream out(::stdout);
|
||||
static FileStream err(::stderr);
|
||||
|
||||
/* no need to call anything from FileStream, prefer simple calls... */
|
||||
|
||||
static inline void write(const char *s) {
|
||||
fputs(s, ::stdout);
|
||||
}
|
||||
|
||||
static inline void write(const octa::String &s) {
|
||||
fwrite(s.data(), 1, s.size(), ::stdout);
|
||||
}
|
||||
|
||||
static inline void writeln(const char *s) {
|
||||
octa::write(s);
|
||||
putc('\n', ::stdout);
|
||||
}
|
||||
|
||||
static inline void writeln(const octa::String &s) {
|
||||
octa::write(s);
|
||||
putc('\n', ::stdout);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
112
octa/stream.hh
112
octa/stream.hh
|
@ -6,13 +6,13 @@
|
|||
#ifndef OCTA_STREAM_HH
|
||||
#define OCTA_STREAM_HH
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "octa/types.hh"
|
||||
#include "octa/range.hh"
|
||||
#include "octa/string.hh"
|
||||
#include "octa/type_traits.hh"
|
||||
#include "octa/string.hh"
|
||||
#include "octa/utility.hh"
|
||||
|
||||
namespace octa {
|
||||
|
||||
|
@ -55,8 +55,56 @@ struct Stream {
|
|||
virtual octa::Size read(void *, octa::Size) { return 0; }
|
||||
virtual octa::Size write(const void *, octa::Size) { return 0; }
|
||||
|
||||
virtual int read() {
|
||||
octa::uchar c;
|
||||
return (read(&c, 1) == 1) ? c : -1;
|
||||
}
|
||||
|
||||
virtual bool write(int c) {
|
||||
octa::uchar wc = octa::uchar(c);
|
||||
return write(&wc, 1) == 1;
|
||||
}
|
||||
|
||||
virtual bool write(const char *s) {
|
||||
octa::Size len = strlen(s);
|
||||
return write(s, len) == len;
|
||||
}
|
||||
|
||||
virtual bool write(const octa::String &s) {
|
||||
return write(s.data(), s.size()) == s.size();
|
||||
}
|
||||
|
||||
virtual bool writeln(const octa::String &s) {
|
||||
return write(s) && write('\n');
|
||||
}
|
||||
|
||||
virtual bool writeln(const char *s) {
|
||||
return write(s) && write('\n');
|
||||
}
|
||||
|
||||
template<typename T = char>
|
||||
StreamRange<T> iter();
|
||||
|
||||
template<typename T> octa::Size put(const T *v, octa::Size count) {
|
||||
return write(v, count * sizeof(T)) / sizeof(T);
|
||||
}
|
||||
|
||||
template<typename T> bool put(T v) {
|
||||
return write(&v, sizeof(T)) == sizeof(T);
|
||||
}
|
||||
|
||||
template<typename T> octa::Size get(T *v, octa::Size count) {
|
||||
return read(v, count * sizeof(T)) / sizeof(T);
|
||||
}
|
||||
|
||||
template<typename T> bool get(T &v) {
|
||||
return read(&v, sizeof(T)) == sizeof(T);
|
||||
}
|
||||
|
||||
template<typename T> T get() {
|
||||
T r;
|
||||
return get(r) ? r : T();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
|
@ -83,7 +131,7 @@ struct StreamRange<T, true>: InputRange<
|
|||
return val;
|
||||
}
|
||||
|
||||
virtual bool equals_front(const StreamRange &s) const {
|
||||
bool equals_front(const StreamRange &s) const {
|
||||
return p_stream->tell() == s.p_stream->tell();
|
||||
}
|
||||
|
||||
|
@ -101,64 +149,6 @@ inline StreamRange<T> Stream::iter() {
|
|||
return StreamRange<T>(*this);
|
||||
}
|
||||
|
||||
enum class StreamMode {
|
||||
read, write, append,
|
||||
update = 1 << 2
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
static const char *filemodes[] = {
|
||||
"rb", "wb", "ab", nullptr, "rb+", "wb+", "ab+"
|
||||
};
|
||||
}
|
||||
|
||||
struct FileStream: Stream {
|
||||
FileStream(): p_f() {}
|
||||
FileStream(const FileStream &s) = delete;
|
||||
|
||||
FileStream(const octa::String &path, StreamMode mode): p_f() {
|
||||
open(path, mode);
|
||||
}
|
||||
|
||||
~FileStream() { close(); }
|
||||
|
||||
bool open(const octa::String &path, StreamMode mode) {
|
||||
if (p_f) return false;
|
||||
p_f = fopen(path.data(), octa::detail::filemodes[octa::Size(mode)]);
|
||||
return p_f != nullptr;
|
||||
}
|
||||
|
||||
void close() {
|
||||
if (p_f) fclose(p_f);
|
||||
p_f = nullptr;
|
||||
}
|
||||
|
||||
bool end() const {
|
||||
return feof(p_f) != 0;
|
||||
}
|
||||
|
||||
bool seek(StreamOffset pos, StreamSeek whence = StreamSeek::set) {
|
||||
return fseeko(p_f, pos, int(whence)) >= 0;
|
||||
}
|
||||
|
||||
StreamOffset tell() const {
|
||||
return ftello(p_f);
|
||||
}
|
||||
|
||||
bool flush() { return !fflush(p_f); }
|
||||
|
||||
octa::Size read(void *buf, octa::Size count) {
|
||||
return fread(buf, 1, count, p_f);
|
||||
}
|
||||
|
||||
octa::Size write(const void *buf, octa::Size count) {
|
||||
return fwrite(buf, 1, count, p_f);
|
||||
}
|
||||
|
||||
private:
|
||||
FILE *p_f;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue