diff --git a/stream/filters/slice_stream.h b/stream/filters/slice_stream.h new file mode 100644 index 000000000..5bd47d978 --- /dev/null +++ b/stream/filters/slice_stream.h @@ -0,0 +1,54 @@ +#ifndef MANGLE_STREAM_SLICE_H +#define MANGLE_STREAM_SLICE_H + +#include "../stream.h" + +namespace Mangle { +namespace Stream { + +/** A Stream that represents a subset (called a slice) of another stream. + */ +class SliceStream : public Stream +{ + Stream *src; + size_t offset, length, pos; + + public: + SliceStream(Stream *_src, size_t _offset, size_t _length) + : src(_src), offset(_offset), length(_length), pos(0) + { + assert(src->hasSize); + assert(src->isSeekable); + + // Make sure we can actually fit inside the source stream + assert(src->size() <= offset+length); + } + + size_t read(void *buf, size_t count) + { + // Check that we're not reading past our slice + if(count > length-pos) + count = length-pos; + + // Seek into place and reading + src->seek(offset+pos); + count = src->read(buf, count); + + pos += count; + assert(pos <= length); + return count; + } + + void seek(size_t _pos) + { + pos = _pos; + if(pos > length) pos = length; + } + + bool eof() { return pos == length; } + size_t tell() { return pos; } + size_t size() { return length; } +}; + +}} // namespaces +#endif diff --git a/stream/servers/file_stream.h b/stream/servers/file_stream.h new file mode 100644 index 000000000..1d6f92032 --- /dev/null +++ b/stream/servers/file_stream.h @@ -0,0 +1,26 @@ +#ifndef MANGLE_STREAM_FILESERVER_H +#define MANGLE_STREAM_FILESERVER_H + +#include "std_stream.h" +#include + +namespace Mangle { +namespace Stream { + +/** Very simple file input stream, based on std::ifstream + */ +class FileStream : public StdStream +{ + std::ifstream file; + + public: + FileStream(const std::string &name) + : StdStream(&file) + { + file.open(name, ios::binary); + } + ~FileStream() { file.close(); } +}; + +}} // namespaces +#endif diff --git a/stream/servers/std_stream.h b/stream/servers/std_stream.h new file mode 100644 index 000000000..e93295f15 --- /dev/null +++ b/stream/servers/std_stream.h @@ -0,0 +1,55 @@ +#ifndef MANGLE_STREAM_FILESERVER_H +#define MANGLE_STREAM_FILESERVER_H + +#include "../stream.h" +#include + +namespace Mangle { +namespace Stream { + +/** Simplest wrapper for std::istream. + + TODO: No error checking yet. + */ +class StdStream : public Stream +{ + std::istream *inf; + + public: + StdStream(std::istream *_inf) + : inf(_inf) + { + isSeekable = true; + hasPosition = true; + hasSize = true; + } + + size_t read(void* buf, size_t len) + { + inf->read((char*)buf, len); + return inf->gcount(); + } + + void seek(size_t pos) + { inf->seekg(pos); } + + size_t tell() const + // Hack around the fact that ifstream->tellg() isn't const + { return ((StdStream*)this)->inf->tellg(); } + + size_t size() const + { + // Use the standard iostream size hack, terrible as it is. + std::streampos pos = inf->tellg(); + inf->seekg(0, ios_base::end); + size_t res = inf->tellg(); + inf->seekg(pos); + return res; + } + + bool eof() const + { return inf->eof(); } +}; + +}} // namespaces +#endif