Added StdStream, FileStream and SliceStream
parent
7d36b599d0
commit
674ac556cc
@ -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
|
@ -0,0 +1,26 @@
|
|||||||
|
#ifndef MANGLE_STREAM_FILESERVER_H
|
||||||
|
#define MANGLE_STREAM_FILESERVER_H
|
||||||
|
|
||||||
|
#include "std_stream.h"
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
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
|
@ -0,0 +1,55 @@
|
|||||||
|
#ifndef MANGLE_STREAM_FILESERVER_H
|
||||||
|
#define MANGLE_STREAM_FILESERVER_H
|
||||||
|
|
||||||
|
#include "../stream.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
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
|
Loading…
Reference in New Issue