#ifndef SAUERLIB_STREAM_HH #define SAUERLIB_STREAM_HH #include "tools.hh" #include "endian.hh" /* workaround for some C platforms that have these two functions as macros - not used anywhere */ #ifdef getchar #undef getchar #endif #ifdef putchar #undef putchar #endif struct stream { #ifdef WIN32 #if defined(__GNUC__) && !defined(__MINGW32__) typedef off64_t offset; #else typedef __int64 offset; #endif #else typedef off_t offset; #endif virtual ~stream() {} virtual void close() = 0; virtual bool end() = 0; virtual offset tell() { return -1; } virtual offset rawtell() { return tell(); } virtual bool seek(offset pos, int whence = SEEK_SET) { return false; } virtual offset size(); virtual offset rawsize() { return size(); } virtual size_t read(void *buf, size_t len) { return 0; } virtual size_t write(const void *buf, size_t len) { return 0; } virtual bool flush() { return true; } virtual int getchar() { uchar c; return read(&c, 1) == 1 ? c : -1; } virtual bool putchar(int n) { uchar c = n; return write(&c, 1) == 1; } virtual bool getline(char *str, size_t len); virtual bool putstring(const char *str) { size_t len = strlen(str); return write(str, len) == len; } virtual bool putline(const char *str) { return putstring(str) && putchar('\n'); } virtual size_t printf(const char *fmt, ...) PRINTFARGS(2, 3); virtual uint getcrc() { return 0; } template size_t put(const T *v, size_t n) { return write(v, n*sizeof(T))/sizeof(T); } template bool put(T n) { return write(&n, sizeof(n)) == sizeof(n); } template bool putlil(T n) { return put(lilswap(n)); } template bool putbig(T n) { return put(bigswap(n)); } template size_t get(T *v, size_t n) { return read(v, n*sizeof(T))/sizeof(T); } template T get() { T n; return read(&n, sizeof(n)) == sizeof(n) ? n : 0; } template T getlil() { return lilswap(get()); } template T getbig() { return bigswap(get()); } }; template struct streambuf { stream *s; streambuf(stream *s) : s(s) {} T get() { return s->get(); } size_t get(T *vals, size_t numvals) { return s->get(vals, numvals); } void put(const T &val) { s->put(&val, 1); } void put(const T *vals, size_t numvals) { s->put(vals, numvals); } size_t length() { return s->size(); } }; stream *openrawfile(const char *filename, const char *mode); stream *openfile(const char *filename, const char *mode); stream *opentempfile(const char *filename, const char *mode); stream *openutf8file(const char *filename, const char *mode, stream *file = nullptr); char *loadfile(const char *fn, size_t *size, bool utf8 = true); #endif