forked from mirror/openmw-tes3mp
Added Stream::InputStream interface, and a client implementation to Ogre::DataStream
parent
325f2f17b3
commit
7139f5284d
@ -0,0 +1,30 @@
|
||||
#ifndef MANGLE_STREAM_IWRAPPER_H
|
||||
#define MANGLE_STREAM_IWRAPPER_H
|
||||
|
||||
#include "../input.h"
|
||||
#include <assert.h>
|
||||
|
||||
namespace Mangle {
|
||||
namespace Stream {
|
||||
|
||||
/** A generic wrapper class for a Stream::Input object.
|
||||
|
||||
This is used by other implementations.
|
||||
*/
|
||||
class _IWrapper
|
||||
{
|
||||
private:
|
||||
bool autoDel;
|
||||
|
||||
protected:
|
||||
InputStream *inp;
|
||||
|
||||
public:
|
||||
_IWrapper(InputStream *_inp, bool _autoDel = false)
|
||||
: inp(_inp), autoDel(_autoDel) { assert(inp != NULL); }
|
||||
|
||||
virtual ~_IWrapper() { if(autoDel) delete inp; }
|
||||
};
|
||||
|
||||
}} // namespaces
|
||||
#endif
|
@ -0,0 +1,60 @@
|
||||
#ifndef MANGLE_STREAM_OGRECLIENT_H
|
||||
#define MANGLE_STREAM_OGRECLIENT_H
|
||||
|
||||
#include <OgreDataStream.h>
|
||||
#include <assert.h>
|
||||
#include "iwrapper.h"
|
||||
|
||||
namespace Mangle {
|
||||
namespace Stream {
|
||||
|
||||
/** An OGRE DataStream that wraps a Mangle::Stream input.
|
||||
|
||||
This has been built and tested against OGRE 1.6.2. You might have
|
||||
to make your own modifications if you're working with newer (or
|
||||
older) versions.
|
||||
*/
|
||||
class MangleDataStream : public Ogre::DataStream, _IWrapper
|
||||
{
|
||||
void init()
|
||||
{
|
||||
// Get the size, if possible
|
||||
if(inp->hasSize)
|
||||
mSize = inp->size();
|
||||
}
|
||||
|
||||
public:
|
||||
/// Constructor without name
|
||||
MangleDataStream(InputStream *inp, bool autoDel=false)
|
||||
: _IWrapper(inp, autoDel) { init(); }
|
||||
|
||||
/// Constructor for a named data stream
|
||||
MangleDataStream(const Ogre::String &name, InputStream *inp, bool autoDel=false)
|
||||
: _IWrapper(inp, autoDel), Ogre::DataStream(name) { init(); }
|
||||
|
||||
|
||||
// Only implement the DataStream functions we have to implement
|
||||
|
||||
size_t read(void *buf, size_t count)
|
||||
{ return inp->read(buf,count); }
|
||||
|
||||
void skip(long count)
|
||||
{
|
||||
assert(inp->isSeekable && inp->hasPosition);
|
||||
inp->seek(inp->tell() + count);
|
||||
}
|
||||
|
||||
void seek(size_t pos)
|
||||
{ assert(inp->isSeekable); inp->seek(pos); }
|
||||
|
||||
size_t tell() const
|
||||
{ assert(inp->hasPosition); return inp->tell(); }
|
||||
|
||||
bool eof() const { return inp->eof(); }
|
||||
|
||||
/// Does nothing
|
||||
void close() {}
|
||||
};
|
||||
|
||||
}} // namespaces
|
||||
#endif
|
@ -0,0 +1,50 @@
|
||||
#ifndef MANGLE_STREAM_INPUT_H
|
||||
#define MANGLE_STREAM_INPUT_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace Mangle {
|
||||
namespace Stream {
|
||||
|
||||
/// An abstract interface for a stream data.
|
||||
class InputStream
|
||||
{
|
||||
public:
|
||||
// Feature options. These should be set in the constructor.
|
||||
|
||||
/// If true, seek() works
|
||||
bool isSeekable;
|
||||
|
||||
/// If true, tell() works
|
||||
bool hasPosition;
|
||||
|
||||
/// If true, size() works
|
||||
bool hasSize;
|
||||
|
||||
/// Virtual destructor
|
||||
virtual ~InputStream() {}
|
||||
|
||||
/** Read a given number of bytes from the stream. Returns the actual
|
||||
number read. If the return value is less than count, then the
|
||||
stream is empty or an error occured.
|
||||
*/
|
||||
virtual size_t read(void* buf, size_t count) = 0;
|
||||
|
||||
/// Seek to an absolute position in this stream. Not all streams are
|
||||
/// seekable.
|
||||
virtual void seek(size_t pos) = 0;
|
||||
|
||||
/// Get the current position in the stream. Non-seekable streams are
|
||||
/// not required to keep track of this.
|
||||
virtual size_t tell() const = 0;
|
||||
|
||||
/// Return the total size of the stream. For streams where this is
|
||||
/// not applicable, size() should return zero.
|
||||
virtual size_t size() const = 0;
|
||||
|
||||
/// Returns true if the stream is empty
|
||||
virtual bool eof() const = 0;
|
||||
};
|
||||
|
||||
}} // namespaces
|
||||
#endif
|
@ -0,0 +1 @@
|
||||
*_test
|
@ -0,0 +1,15 @@
|
||||
GCC=g++ -I../ -I../imp_client/
|
||||
|
||||
all: ogre_client_test dummy_test
|
||||
|
||||
I_OGRE=$(shell pkg-config --cflags OGRE)
|
||||
L_OGRE=$(shell pkg-config --libs OGRE)
|
||||
|
||||
ogre_client_test: ogre_client_test.cpp dummy_input.cpp ../input.h ../imp_client/iwrapper.h ../imp_client/ogre_datastream.h
|
||||
$(GCC) $< -o $@ $(I_OGRE) $(L_OGRE)
|
||||
|
||||
dummy_test: dummy_test.cpp dummy_input.cpp ../input.h
|
||||
$(GCC) $< -o $@
|
||||
|
||||
clean:
|
||||
rm *_test
|
@ -0,0 +1,48 @@
|
||||
// This file is shared between several test programs
|
||||
#include "input.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
using namespace Mangle::Stream;
|
||||
|
||||
// A simple dummy stream
|
||||
const char _data[12] = "hello world";
|
||||
|
||||
class DummyInput : public InputStream
|
||||
{
|
||||
private:
|
||||
int pos;
|
||||
|
||||
public:
|
||||
DummyInput() : pos(0)
|
||||
{
|
||||
isSeekable = true;
|
||||
hasPosition = true;
|
||||
hasSize = true;
|
||||
}
|
||||
|
||||
size_t read(void *buf, size_t count)
|
||||
{
|
||||
assert(pos >= 0 && pos <= 11);
|
||||
if(count+pos > 11)
|
||||
count = 11-pos;
|
||||
assert(count <= 11);
|
||||
|
||||
memcpy(buf, _data+pos, count);
|
||||
pos += count;
|
||||
|
||||
assert(pos >= 0 && pos <= 11);
|
||||
return count;
|
||||
}
|
||||
|
||||
void seek(size_t npos)
|
||||
{
|
||||
if(npos > 11) npos = 11;
|
||||
pos = npos;
|
||||
}
|
||||
|
||||
size_t tell() const { return pos; }
|
||||
size_t size() const { return 11; }
|
||||
|
||||
bool eof() const { return pos == 11; }
|
||||
};
|
@ -0,0 +1,39 @@
|
||||
#include "dummy_input.cpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <string.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
InputStream *inp = new DummyInput();
|
||||
|
||||
cout << "Size: " << inp->size() << endl;
|
||||
cout << "Pos: " << inp->tell() << "\nSeeking...\n";
|
||||
inp->seek(3);
|
||||
cout << "Pos: " << inp->tell() << endl;
|
||||
char data[12];
|
||||
memset(data, 0, 12);
|
||||
cout << "Reading: " << inp->read(data, 4) << endl;
|
||||
cout << "Four bytes: " << data << endl;
|
||||
cout << "Eof: " << inp->eof() << endl;
|
||||
cout << "Pos: " << inp->tell() << "\nSeeking again...\n";
|
||||
inp->seek(33);
|
||||
cout << "Pos: " << inp->tell() << endl;
|
||||
cout << "Eof: " << inp->eof() << "\nSeek to 6\n";
|
||||
inp->seek(6);
|
||||
cout << "Eof: " << inp->eof() << endl;
|
||||
cout << "Pos: " << inp->tell() << endl;
|
||||
cout << "Over-reading: " << inp->read(data, 200) << endl;
|
||||
cout << "Result: " << data << endl;
|
||||
cout << "Eof: " << inp->eof() << endl;
|
||||
cout << "Pos: " << inp->tell() << endl;
|
||||
inp->seek(0);
|
||||
cout << "Finally, reading the entire string: " << inp->read(data,11) << endl;
|
||||
cout << "Result: " << data << endl;
|
||||
cout << "Eof: " << inp->eof() << endl;
|
||||
cout << "Pos: " << inp->tell() << endl;
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
#include "dummy_input.cpp"
|
||||
#include "ogre_datastream.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace Ogre;
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
InputStream *inp = new DummyInput();
|
||||
DataStreamPtr p(new MangleDataStream("hello", inp, true));
|
||||
cout << "Name: " << p->getName() << endl;
|
||||
cout << "As string: " << p->getAsString() << endl;
|
||||
cout << "pos=" << p->tell() << " eof=" << p->eof() << endl;
|
||||
p->seek(0);
|
||||
cout << "pos=" << p->tell() << " eof=" << p->eof() << endl;
|
||||
p->skip(5);
|
||||
p->skip(-2);
|
||||
cout << "pos=" << p->tell() << " eof=" << p->eof() << endl;
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue