forked from mirror/openmw-tes3mp
Merge remote branch 'zini/master' into nif-cleanup
Conflicts: components/bsa/bsa_archive.cppactorid
commit
b4c8375f3c
@ -1,32 +0,0 @@
|
|||||||
#include "audiere_file.hpp"
|
|
||||||
|
|
||||||
using namespace audiere;
|
|
||||||
using namespace Mangle::Stream;
|
|
||||||
|
|
||||||
bool AudiereFile::seek(int pos, SeekMode mode)
|
|
||||||
{
|
|
||||||
assert(inp->isSeekable);
|
|
||||||
assert(inp->hasPosition);
|
|
||||||
|
|
||||||
size_t newPos;
|
|
||||||
|
|
||||||
switch(mode)
|
|
||||||
{
|
|
||||||
case BEGIN: newPos = pos; break;
|
|
||||||
case CURRENT: newPos = pos+tell(); break;
|
|
||||||
case END:
|
|
||||||
// Seeking from the end. This requires that we're able to get
|
|
||||||
// the entire size of the stream. The pos also has to be
|
|
||||||
// non-positive.
|
|
||||||
assert(inp->hasSize);
|
|
||||||
assert(pos <= 0);
|
|
||||||
newPos = inp->size() + pos;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(0 && "invalid seek mode");
|
|
||||||
}
|
|
||||||
|
|
||||||
inp->seek(newPos);
|
|
||||||
return inp->tell() == newPos;
|
|
||||||
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
#ifndef MANGLE_STREAM_AUDIERECLIENT_H
|
|
||||||
#define MANGLE_STREAM_AUDIERECLIENT_H
|
|
||||||
|
|
||||||
#include <audiere.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include "../stream.hpp"
|
|
||||||
|
|
||||||
namespace Mangle {
|
|
||||||
namespace Stream {
|
|
||||||
|
|
||||||
/** @brief An Audiere::File that wraps a Mangle::Stream input.
|
|
||||||
|
|
||||||
This lets Audiere read sound files from any generic archive or
|
|
||||||
file manager that supports Mangle streams.
|
|
||||||
*/
|
|
||||||
class AudiereFile : public audiere::RefImplementation<audiere::File>
|
|
||||||
{
|
|
||||||
StreamPtr inp;
|
|
||||||
|
|
||||||
public:
|
|
||||||
AudiereFile(StreamPtr _inp)
|
|
||||||
: inp(_inp) {}
|
|
||||||
|
|
||||||
/// Read 'count' bytes, return bytes successfully read
|
|
||||||
int ADR_CALL read(void *buf, int count)
|
|
||||||
{ return inp->read(buf,count); }
|
|
||||||
|
|
||||||
/// Seek, relative to specified seek mode. Returns true if successful.
|
|
||||||
bool ADR_CALL seek(int pos, audiere::File::SeekMode mode);
|
|
||||||
|
|
||||||
/// Get current position
|
|
||||||
int ADR_CALL tell()
|
|
||||||
{ assert(inp->hasPosition); return inp->tell(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
}} // namespaces
|
|
||||||
#endif
|
|
@ -1,221 +0,0 @@
|
|||||||
#include "io_stream.hpp"
|
|
||||||
|
|
||||||
// This seems to work
|
|
||||||
#ifndef EOF
|
|
||||||
#define EOF -1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using namespace Mangle::Stream;
|
|
||||||
|
|
||||||
#define BSIZE 1024
|
|
||||||
|
|
||||||
// Streambuf for normal stream reading
|
|
||||||
class _istreambuf : public std::streambuf
|
|
||||||
{
|
|
||||||
StreamPtr client;
|
|
||||||
char buf[BSIZE];
|
|
||||||
|
|
||||||
public:
|
|
||||||
_istreambuf(StreamPtr strm) : client(strm)
|
|
||||||
{
|
|
||||||
// Make sure we picked the right class
|
|
||||||
assert(client->isReadable);
|
|
||||||
assert(!client->hasPtr);
|
|
||||||
|
|
||||||
// Tell streambuf to delegate reading operations to underflow()
|
|
||||||
setg(NULL,NULL,NULL);
|
|
||||||
|
|
||||||
// Disallow writing
|
|
||||||
setp(NULL,NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Underflow is called when there is no more info to read in the
|
|
||||||
input buffer. We need to refill buf with new data (if any), and
|
|
||||||
set up the internal pointers with setg() to reflect the new
|
|
||||||
state.
|
|
||||||
*/
|
|
||||||
int underflow()
|
|
||||||
{
|
|
||||||
// Read some more data
|
|
||||||
size_t read = client->read(buf, BSIZE);
|
|
||||||
assert(read <= BSIZE);
|
|
||||||
|
|
||||||
// If we're out of data, then EOF
|
|
||||||
if(read == 0)
|
|
||||||
return EOF;
|
|
||||||
|
|
||||||
// Otherwise, set up input buffer
|
|
||||||
setg(buf, buf, buf+read);
|
|
||||||
|
|
||||||
// Return the first char
|
|
||||||
return *((unsigned char*)buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Seek stream, if the source supports it. Ignores the second
|
|
||||||
// parameter as Mangle doesn't separate input and output pointers.
|
|
||||||
std::streampos seekpos(std::streampos pos, std::ios_base::openmode = std::ios_base::in)
|
|
||||||
{
|
|
||||||
// Does this stream know how to seek?
|
|
||||||
if(!client->isSeekable || !client->hasPosition)
|
|
||||||
// If not, signal an error.
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
// Set stream position and reset the buffer.
|
|
||||||
client->seek(pos);
|
|
||||||
setg(NULL,NULL,NULL);
|
|
||||||
|
|
||||||
return client->tell();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Streambuf optimized for pointer-based input streams
|
|
||||||
class _ptrstreambuf : public std::streambuf
|
|
||||||
{
|
|
||||||
StreamPtr client;
|
|
||||||
|
|
||||||
public:
|
|
||||||
_ptrstreambuf(StreamPtr strm) : client(strm)
|
|
||||||
{
|
|
||||||
// Make sure we picked the right class
|
|
||||||
assert(client->isReadable);
|
|
||||||
assert(client->hasPtr);
|
|
||||||
|
|
||||||
// seekpos() does all the work
|
|
||||||
seekpos(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Underflow is only called when we're at the end of the file
|
|
||||||
int underflow() { return EOF; }
|
|
||||||
|
|
||||||
// Seek to a new position within the memory stream. This bypasses
|
|
||||||
// client->seek() entirely so isSeekable doesn't have to be set.
|
|
||||||
std::streampos seekpos(std::streampos pos, std::ios_base::openmode = std::ios_base::in)
|
|
||||||
{
|
|
||||||
// All pointer streams need a size
|
|
||||||
assert(client->hasSize);
|
|
||||||
|
|
||||||
// Figure out how much will be left of the stream after seeking
|
|
||||||
size_t size = client->size() - pos;
|
|
||||||
|
|
||||||
// Get a pointer
|
|
||||||
char* ptr = (char*)client->getPtr(pos,size);
|
|
||||||
|
|
||||||
// And use it
|
|
||||||
setg(ptr,ptr,ptr+size);
|
|
||||||
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Streambuf for stream writing
|
|
||||||
class _ostreambuf : public std::streambuf
|
|
||||||
{
|
|
||||||
StreamPtr client;
|
|
||||||
char buf[BSIZE];
|
|
||||||
|
|
||||||
public:
|
|
||||||
_ostreambuf(StreamPtr strm) : client(strm)
|
|
||||||
{
|
|
||||||
// Make sure we picked the right class
|
|
||||||
assert(client->isWritable);
|
|
||||||
|
|
||||||
// Inform streambuf about our nice buffer
|
|
||||||
setp(buf, buf+BSIZE);
|
|
||||||
|
|
||||||
// Disallow reading
|
|
||||||
setg(NULL,NULL,NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sync means to flush (write) all current data to the output
|
|
||||||
stream. It will also set up the entire output buffer to be usable
|
|
||||||
again.
|
|
||||||
*/
|
|
||||||
int sync()
|
|
||||||
{
|
|
||||||
// Get the number of bytes that streambuf wants us to write
|
|
||||||
int num = pptr() - pbase();
|
|
||||||
assert(num >= 0);
|
|
||||||
|
|
||||||
// Is there any work to do?
|
|
||||||
if(num == 0) return 0;
|
|
||||||
|
|
||||||
if((int)client->write(pbase(), num) != num)
|
|
||||||
// Inform caller that writing failed
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
// Reset output buffer pointers
|
|
||||||
setp(buf, buf+BSIZE);
|
|
||||||
|
|
||||||
// No error
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Called whenever the output buffer is full.
|
|
||||||
*/
|
|
||||||
int overflow(int c)
|
|
||||||
{
|
|
||||||
// First, write all existing data
|
|
||||||
if(sync()) return EOF;
|
|
||||||
|
|
||||||
// Put the requested character in the next round of output
|
|
||||||
if(c != EOF)
|
|
||||||
{
|
|
||||||
*pptr() = c;
|
|
||||||
pbump(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// No error
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Seek stream, if the source supports it.
|
|
||||||
std::streampos seekpos(std::streampos pos, std::ios_base::openmode = std::ios_base::out)
|
|
||||||
{
|
|
||||||
if(!client->isSeekable || !client->hasPosition)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
// Flush data and reset buffers
|
|
||||||
sync();
|
|
||||||
|
|
||||||
// Set stream position
|
|
||||||
client->seek(pos);
|
|
||||||
|
|
||||||
return client->tell();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
MangleIStream::MangleIStream(StreamPtr inp)
|
|
||||||
: std::istream(NULL)
|
|
||||||
{
|
|
||||||
assert(inp->isReadable);
|
|
||||||
|
|
||||||
// Pick the right streambuf implementation based on whether the
|
|
||||||
// input supports pointers or not.
|
|
||||||
if(inp->hasPtr)
|
|
||||||
buf = new _ptrstreambuf(inp);
|
|
||||||
else
|
|
||||||
buf = new _istreambuf(inp);
|
|
||||||
|
|
||||||
rdbuf(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
MangleIStream::~MangleIStream()
|
|
||||||
{
|
|
||||||
delete buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
MangleOStream::MangleOStream(StreamPtr out)
|
|
||||||
: std::ostream(NULL)
|
|
||||||
{
|
|
||||||
assert(out->isWritable);
|
|
||||||
buf = new _ostreambuf(out);
|
|
||||||
|
|
||||||
rdbuf(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
MangleOStream::~MangleOStream()
|
|
||||||
{
|
|
||||||
// Make sure we don't have lingering data on exit
|
|
||||||
flush();
|
|
||||||
delete buf;
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
#ifndef MANGLE_STREAM_IOSTREAM_H
|
|
||||||
#define MANGLE_STREAM_IOSTREAM_H
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include "../stream.hpp"
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace Mangle {
|
|
||||||
namespace Stream {
|
|
||||||
|
|
||||||
/** This file contains classes for wrapping an std::istream or
|
|
||||||
std::ostream around a Mangle::Stream.
|
|
||||||
|
|
||||||
This allows you to use Mangle streams in places that require std
|
|
||||||
streams.
|
|
||||||
|
|
||||||
This is much easier than trying to make your own custom streams
|
|
||||||
into iostreams. The std::iostream interface is horrible and NOT
|
|
||||||
designed for easy subclassing. Create a Mangle::Stream instead,
|
|
||||||
and use this wrapper.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// An istream wrapping a readable Mangle::Stream. Has extra
|
|
||||||
// optimizations for pointer-based streams.
|
|
||||||
class MangleIStream : public std::istream
|
|
||||||
{
|
|
||||||
std::streambuf *buf;
|
|
||||||
public:
|
|
||||||
MangleIStream(StreamPtr inp);
|
|
||||||
~MangleIStream();
|
|
||||||
};
|
|
||||||
|
|
||||||
// An ostream wrapping a writable Mangle::Stream.
|
|
||||||
class MangleOStream : public std::ostream
|
|
||||||
{
|
|
||||||
std::streambuf *buf;
|
|
||||||
public:
|
|
||||||
MangleOStream(StreamPtr inp);
|
|
||||||
~MangleOStream();
|
|
||||||
};
|
|
||||||
|
|
||||||
}} // namespaces
|
|
||||||
#endif
|
|
@ -1,68 +0,0 @@
|
|||||||
#ifndef MANGLE_STREAM_OGRECLIENT_H
|
|
||||||
#define MANGLE_STREAM_OGRECLIENT_H
|
|
||||||
|
|
||||||
#include <OgreDataStream.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include "../stream.hpp"
|
|
||||||
|
|
||||||
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 Mangle2OgreStream : public Ogre::DataStream
|
|
||||||
{
|
|
||||||
StreamPtr inp;
|
|
||||||
|
|
||||||
void init()
|
|
||||||
{
|
|
||||||
// Get the size, if possible
|
|
||||||
if(inp->hasSize)
|
|
||||||
mSize = inp->size();
|
|
||||||
|
|
||||||
// Allow writing if inp supports it
|
|
||||||
if(inp->isWritable)
|
|
||||||
mAccess |= Ogre::DataStream::WRITE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
/// Constructor without name
|
|
||||||
Mangle2OgreStream(StreamPtr _inp)
|
|
||||||
: inp(_inp) { init(); }
|
|
||||||
|
|
||||||
/// Constructor for a named data stream
|
|
||||||
Mangle2OgreStream(const Ogre::String &name, StreamPtr _inp)
|
|
||||||
: Ogre::DataStream(name), inp(_inp) { init(); }
|
|
||||||
|
|
||||||
// Only implement the DataStream functions we have to implement
|
|
||||||
|
|
||||||
size_t read(void *buf, size_t count)
|
|
||||||
{ return inp->read(buf,count); }
|
|
||||||
|
|
||||||
size_t write(const void *buf, size_t count)
|
|
||||||
{ assert(inp->isWritable); return inp->write(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
|
|
@ -1,74 +0,0 @@
|
|||||||
#ifndef MANGLE_STREAM_BUFFER_H
|
|
||||||
#define MANGLE_STREAM_BUFFER_H
|
|
||||||
|
|
||||||
#include "../servers/memory_stream.hpp"
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace Mangle {
|
|
||||||
namespace Stream {
|
|
||||||
|
|
||||||
/** A Stream that reads another Stream into a buffer, and serves it as
|
|
||||||
a MemoryStream. Might be expanded with other capabilities later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class BufferStream : public MemoryStream
|
|
||||||
{
|
|
||||||
std::vector<char> buffer;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/*
|
|
||||||
input = stream to copy
|
|
||||||
ADD = each read increment (for streams without size())
|
|
||||||
*/
|
|
||||||
BufferStream(StreamPtr input, size_t ADD = 32*1024)
|
|
||||||
{
|
|
||||||
assert(input);
|
|
||||||
|
|
||||||
// Allocate memory, read the stream into it. Then call set()
|
|
||||||
if(input->hasSize)
|
|
||||||
{
|
|
||||||
// We assume that we can get the position as well
|
|
||||||
assert(input->hasPosition);
|
|
||||||
|
|
||||||
// Calculate how much is left of the stream
|
|
||||||
size_t left = input->size() - input->tell();
|
|
||||||
|
|
||||||
// Allocate the buffer and fill it
|
|
||||||
buffer.resize(left);
|
|
||||||
input->read(&buffer[0], left);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// We DON'T know how big the stream is. We'll have to read
|
|
||||||
// it in increments.
|
|
||||||
size_t len=0, newlen;
|
|
||||||
|
|
||||||
while(!input->eof())
|
|
||||||
{
|
|
||||||
// Read one block
|
|
||||||
newlen = len + ADD;
|
|
||||||
buffer.resize(newlen);
|
|
||||||
size_t read = input->read(&buffer[len], ADD);
|
|
||||||
|
|
||||||
// Increase the total length
|
|
||||||
len += read;
|
|
||||||
|
|
||||||
// If we read less than expected, we should be at the
|
|
||||||
// end of the stream
|
|
||||||
assert(read == ADD || (read < ADD && input->eof()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Downsize to match the real length
|
|
||||||
buffer.resize(len);
|
|
||||||
}
|
|
||||||
|
|
||||||
// After the buffer has been filled, set up our MemoryStream
|
|
||||||
// ancestor to reference it.
|
|
||||||
set(&buffer[0], buffer.size());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef boost::shared_ptr<BufferStream> BufferStreamPtr;
|
|
||||||
|
|
||||||
}} // namespaces
|
|
||||||
#endif
|
|
@ -1,46 +0,0 @@
|
|||||||
#ifndef MANGLE_STREAM_FILTER_H
|
|
||||||
#define MANGLE_STREAM_FILTER_H
|
|
||||||
|
|
||||||
#include "../stream.hpp"
|
|
||||||
|
|
||||||
namespace Mangle {
|
|
||||||
namespace Stream {
|
|
||||||
|
|
||||||
/** A stream that filters another stream with no changes. Intended as
|
|
||||||
a base class for other filters.
|
|
||||||
*/
|
|
||||||
class PureFilter : public Stream
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
StreamPtr src;
|
|
||||||
|
|
||||||
public:
|
|
||||||
PureFilter() {}
|
|
||||||
PureFilter(StreamPtr _src)
|
|
||||||
{ setStream(_src); }
|
|
||||||
|
|
||||||
void setStream(StreamPtr _src)
|
|
||||||
{
|
|
||||||
src = _src;
|
|
||||||
isSeekable = src->isSeekable;
|
|
||||||
isWritable = src->isWritable;
|
|
||||||
hasPosition = src->hasPosition;
|
|
||||||
hasSize = src->hasSize;
|
|
||||||
hasPtr = src->hasPtr;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t read(void *buf, size_t count) { return src->read(buf, count); }
|
|
||||||
size_t write(const void *buf, size_t count) { return src->write(buf,count); }
|
|
||||||
void flush() { src->flush(); }
|
|
||||||
void seek(size_t pos) { src->seek(pos); }
|
|
||||||
size_t tell() const { return src->tell(); }
|
|
||||||
size_t size() const { return src->size(); }
|
|
||||||
bool eof() const { return src->eof(); }
|
|
||||||
const void *getPtr() { return src->getPtr(); }
|
|
||||||
const void *getPtr(size_t size) { return src->getPtr(size); }
|
|
||||||
const void *getPtr(size_t pos, size_t size)
|
|
||||||
{ return src->getPtr(pos, size); }
|
|
||||||
};
|
|
||||||
|
|
||||||
}} // namespaces
|
|
||||||
#endif
|
|
@ -1,101 +0,0 @@
|
|||||||
#ifndef MANGLE_STREAM_SLICE_H
|
|
||||||
#define MANGLE_STREAM_SLICE_H
|
|
||||||
|
|
||||||
#include "../stream.hpp"
|
|
||||||
|
|
||||||
namespace Mangle {
|
|
||||||
namespace Stream {
|
|
||||||
|
|
||||||
/** A Stream that represents a subset (called a slice) of another stream.
|
|
||||||
*/
|
|
||||||
class SliceStream : public Stream
|
|
||||||
{
|
|
||||||
StreamPtr src;
|
|
||||||
size_t offset, length, pos;
|
|
||||||
|
|
||||||
public:
|
|
||||||
SliceStream(StreamPtr _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);
|
|
||||||
|
|
||||||
isSeekable = true;
|
|
||||||
hasPosition = true;
|
|
||||||
hasSize = true;
|
|
||||||
hasPtr = src->hasPtr;
|
|
||||||
isWritable = src->isWritable;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 start reading
|
|
||||||
src->seek(offset+pos);
|
|
||||||
count = src->read(buf, count);
|
|
||||||
|
|
||||||
pos += count;
|
|
||||||
assert(pos <= length);
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note that writing to a slice does not allow you to append data,
|
|
||||||
// you may only overwrite existing data.
|
|
||||||
size_t write(const void *buf, size_t count)
|
|
||||||
{
|
|
||||||
assert(isWritable);
|
|
||||||
// Check that we're not reading past our slice
|
|
||||||
if(count > length-pos)
|
|
||||||
count = length-pos;
|
|
||||||
|
|
||||||
// Seek into place and action
|
|
||||||
src->seek(offset+pos);
|
|
||||||
count = src->write(buf, count);
|
|
||||||
|
|
||||||
pos += count;
|
|
||||||
assert(pos <= length);
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
void seek(size_t _pos)
|
|
||||||
{
|
|
||||||
pos = _pos;
|
|
||||||
if(pos > length) pos = length;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool eof() const { return pos == length; }
|
|
||||||
size_t tell() const { return pos; }
|
|
||||||
size_t size() const { return length; }
|
|
||||||
void flush() { src->flush(); }
|
|
||||||
|
|
||||||
const void *getPtr() { return getPtr(0, length); }
|
|
||||||
const void *getPtr(size_t size)
|
|
||||||
{
|
|
||||||
const void *ptr = getPtr(pos, size);
|
|
||||||
seek(pos+size);
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
const void *getPtr(size_t pos, size_t size)
|
|
||||||
{
|
|
||||||
// Boundry checks on pos and size. Bounding the size is
|
|
||||||
// important even when getting pointers, as the source stream
|
|
||||||
// may use the size parameter for something (such as memory
|
|
||||||
// mapping or buffering.)
|
|
||||||
if(pos > length) pos = length;
|
|
||||||
if(pos+size > length) size = length-pos;
|
|
||||||
|
|
||||||
// Ask the source to kindly give us a pointer
|
|
||||||
return src->getPtr(offset+pos, size);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef boost::shared_ptr<SliceStream> SliceStreamPtr;
|
|
||||||
|
|
||||||
}} // namespaces
|
|
||||||
#endif
|
|
@ -1,32 +0,0 @@
|
|||||||
#ifndef MANGLE_STREAM_FILESERVER_H
|
|
||||||
#define MANGLE_STREAM_FILESERVER_H
|
|
||||||
|
|
||||||
#include "std_stream.hpp"
|
|
||||||
#include <fstream>
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
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.c_str(), std::ios::binary);
|
|
||||||
|
|
||||||
if(file.fail())
|
|
||||||
throw std::runtime_error("FileStream: failed to open file " + name);
|
|
||||||
}
|
|
||||||
~FileStream() { file.close(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef boost::shared_ptr<FileStream> FileStreamPtr;
|
|
||||||
|
|
||||||
}} // namespaces
|
|
||||||
#endif
|
|
@ -1,116 +0,0 @@
|
|||||||
#ifndef MANGLE_STREAM_MEMSERVER_H
|
|
||||||
#define MANGLE_STREAM_MEMSERVER_H
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include "../stream.hpp"
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
namespace Mangle {
|
|
||||||
namespace Stream {
|
|
||||||
|
|
||||||
// Do this before the class declaration, since the class itself
|
|
||||||
// uses it.
|
|
||||||
class MemoryStream;
|
|
||||||
typedef boost::shared_ptr<MemoryStream> MemoryStreamPtr;
|
|
||||||
|
|
||||||
/** A Stream wrapping a memory buffer
|
|
||||||
|
|
||||||
This will create a fully seekable stream out of any pointer/length
|
|
||||||
pair you give it.
|
|
||||||
*/
|
|
||||||
class MemoryStream : public Stream
|
|
||||||
{
|
|
||||||
const void *data;
|
|
||||||
size_t length, pos;
|
|
||||||
|
|
||||||
public:
|
|
||||||
MemoryStream(const void *ptr, size_t len)
|
|
||||||
: data(ptr), length(len), pos(0)
|
|
||||||
{
|
|
||||||
isSeekable = true;
|
|
||||||
hasPosition = true;
|
|
||||||
hasSize = true;
|
|
||||||
hasPtr = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
MemoryStream()
|
|
||||||
: data(NULL), length(0), pos(0)
|
|
||||||
{
|
|
||||||
isSeekable = true;
|
|
||||||
hasPosition = true;
|
|
||||||
hasSize = true;
|
|
||||||
hasPtr = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t read(void *buf, size_t count)
|
|
||||||
{
|
|
||||||
assert(data != NULL);
|
|
||||||
assert(pos <= length);
|
|
||||||
|
|
||||||
// Don't read more than we have
|
|
||||||
if(count > (length - pos))
|
|
||||||
count = length - pos;
|
|
||||||
|
|
||||||
// Copy data
|
|
||||||
if(count)
|
|
||||||
memcpy(buf, ((char*)data)+pos, count);
|
|
||||||
|
|
||||||
// aaand remember to increase the count
|
|
||||||
pos += count;
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
void seek(size_t _pos)
|
|
||||||
{
|
|
||||||
pos = _pos;
|
|
||||||
if(pos > length)
|
|
||||||
pos = length;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t tell() const { return pos; }
|
|
||||||
size_t size() const { return length; }
|
|
||||||
bool eof() const { return pos == length; }
|
|
||||||
|
|
||||||
const void *getPtr() { return data; }
|
|
||||||
const void *getPtr(size_t size)
|
|
||||||
{
|
|
||||||
// This variant of getPtr must move the position pointer
|
|
||||||
size_t opos = pos;
|
|
||||||
pos += size;
|
|
||||||
if(pos > length) pos = length;
|
|
||||||
return ((char*)data)+opos;
|
|
||||||
}
|
|
||||||
const void *getPtr(size_t pos, size_t size)
|
|
||||||
{
|
|
||||||
if(pos > length) pos = length;
|
|
||||||
return ((char*)data)+pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
// New members in MemoryStream:
|
|
||||||
|
|
||||||
/// Set a new buffer and length. This will rewind the position to zero.
|
|
||||||
void set(const void* _data, size_t _length)
|
|
||||||
{
|
|
||||||
data = _data;
|
|
||||||
length = _length;
|
|
||||||
pos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Clone this memory stream
|
|
||||||
/** Make a new stream of the same buffer. If setPos is true, we also
|
|
||||||
set the clone's position to be the same as ours.
|
|
||||||
|
|
||||||
No memory is copied during this operation, the new stream is
|
|
||||||
just another 'view' into the same shared memory buffer.
|
|
||||||
*/
|
|
||||||
MemoryStreamPtr clone(bool setPos=false) const
|
|
||||||
{
|
|
||||||
MemoryStreamPtr res(new MemoryStream(data, length));
|
|
||||||
if(setPos) res->seek(pos);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}} // namespaces
|
|
||||||
#endif
|
|
@ -1,37 +0,0 @@
|
|||||||
#ifndef MANGLE_STREAM_OGRESERVER_H
|
|
||||||
#define MANGLE_STREAM_OGRESERVER_H
|
|
||||||
|
|
||||||
#include <OgreDataStream.h>
|
|
||||||
|
|
||||||
namespace Mangle {
|
|
||||||
namespace Stream {
|
|
||||||
|
|
||||||
/** A Stream wrapping an OGRE DataStream.
|
|
||||||
|
|
||||||
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 OgreStream : public Stream
|
|
||||||
{
|
|
||||||
Ogre::DataStreamPtr inp;
|
|
||||||
|
|
||||||
public:
|
|
||||||
OgreStream(Ogre::DataStreamPtr _inp) : inp(_inp)
|
|
||||||
{
|
|
||||||
isSeekable = true;
|
|
||||||
hasPosition = true;
|
|
||||||
hasSize = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t read(void *buf, size_t count) { return inp->read(buf,count); }
|
|
||||||
void seek(size_t pos) { inp->seek(pos); }
|
|
||||||
size_t tell() const { return inp->tell(); }
|
|
||||||
size_t size() const { return inp->size(); }
|
|
||||||
bool eof() const { return inp->eof(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef boost::shared_ptr<OgreStream> OgreStreamPtr;
|
|
||||||
|
|
||||||
}} // namespaces
|
|
||||||
#endif
|
|
@ -1,41 +0,0 @@
|
|||||||
#ifndef MANGLE_OSTREAM_FILESERVER_H
|
|
||||||
#define MANGLE_OSTREAM_FILESERVER_H
|
|
||||||
|
|
||||||
#include "std_ostream.hpp"
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
namespace Mangle {
|
|
||||||
namespace Stream {
|
|
||||||
|
|
||||||
/** File stream based on std::ofstream, only supports writing.
|
|
||||||
*/
|
|
||||||
class OutFileStream : public StdOStream
|
|
||||||
{
|
|
||||||
std::ofstream file;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
By default we overwrite the file. If append=true, then we will
|
|
||||||
open an existing file and seek to the end instead.
|
|
||||||
*/
|
|
||||||
OutFileStream(const std::string &name, bool append=false)
|
|
||||||
: StdOStream(&file)
|
|
||||||
{
|
|
||||||
std::ios::openmode mode = std::ios::binary;
|
|
||||||
if(append)
|
|
||||||
mode |= std::ios::app;
|
|
||||||
else
|
|
||||||
mode |= std::ios::trunc;
|
|
||||||
|
|
||||||
file.open(name.c_str(), mode);
|
|
||||||
|
|
||||||
if(file.fail())
|
|
||||||
throw std::runtime_error("OutFileStream: failed to open file " + name);
|
|
||||||
}
|
|
||||||
~OutFileStream() { file.close(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef boost::shared_ptr<OutFileStream> OutFileStreamPtr;
|
|
||||||
|
|
||||||
}} // namespaces
|
|
||||||
#endif
|
|
@ -1,36 +0,0 @@
|
|||||||
#ifndef MANGLE_STREAM_OGRESERVER_H
|
|
||||||
#define MANGLE_STREAM_OGRESERVER_H
|
|
||||||
|
|
||||||
#include <physfs.h>
|
|
||||||
|
|
||||||
namespace Mangle {
|
|
||||||
namespace Stream {
|
|
||||||
|
|
||||||
/// A Stream wrapping a PHYSFS_file stream from the PhysFS library.
|
|
||||||
class PhysFile : public Stream
|
|
||||||
{
|
|
||||||
PHYSFS_file *file;
|
|
||||||
|
|
||||||
public:
|
|
||||||
PhysFile(PHYSFS_file *inp) : file(inp)
|
|
||||||
{
|
|
||||||
isSeekable = true;
|
|
||||||
hasPosition = true;
|
|
||||||
hasSize = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
~PhysFile() { PHYSFS_close(file); }
|
|
||||||
|
|
||||||
size_t read(void *buf, size_t count)
|
|
||||||
{ return PHYSFS_read(file, buf, 1, count); }
|
|
||||||
|
|
||||||
void seek(size_t pos) { PHYSFS_seek(file, pos); }
|
|
||||||
size_t tell() const { return PHYSFS_tell(file); }
|
|
||||||
size_t size() const { return PHYSFS_fileLength(file); }
|
|
||||||
bool eof() const { return PHYSFS_eof(file); }
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef boost::shared_ptr<PhysFile> PhysFilePtr;
|
|
||||||
|
|
||||||
}} // namespaces
|
|
||||||
#endif
|
|
@ -1,78 +0,0 @@
|
|||||||
#ifndef MANGLE_OSTREAM_STDIOSERVER_H
|
|
||||||
#define MANGLE_OSTREAM_STDIOSERVER_H
|
|
||||||
|
|
||||||
#include "../stream.hpp"
|
|
||||||
#include <iostream>
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
namespace Mangle {
|
|
||||||
namespace Stream {
|
|
||||||
|
|
||||||
/** Simple wrapper for std::ostream, only supports output.
|
|
||||||
*/
|
|
||||||
class StdOStream : public Stream
|
|
||||||
{
|
|
||||||
std::ostream *inf;
|
|
||||||
|
|
||||||
static void fail(const std::string &msg)
|
|
||||||
{ throw std::runtime_error("StdOStream: " + msg); }
|
|
||||||
|
|
||||||
public:
|
|
||||||
StdOStream(std::ostream *_inf)
|
|
||||||
: inf(_inf)
|
|
||||||
{
|
|
||||||
isSeekable = true;
|
|
||||||
hasPosition = true;
|
|
||||||
hasSize = true;
|
|
||||||
isWritable = true;
|
|
||||||
isReadable = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t write(const void* buf, size_t len)
|
|
||||||
{
|
|
||||||
inf->write((const char*)buf, len);
|
|
||||||
if(inf->fail())
|
|
||||||
fail("error writing to stream");
|
|
||||||
// Just return len, but that is ok. The only cases where we would
|
|
||||||
// return less than len is when an error occured.
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
void flush()
|
|
||||||
{
|
|
||||||
inf->flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
void seek(size_t pos)
|
|
||||||
{
|
|
||||||
inf->seekp(pos);
|
|
||||||
if(inf->fail())
|
|
||||||
fail("seek error");
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t tell() const
|
|
||||||
// Hack around the fact that ifstream->tellp() isn't const
|
|
||||||
{ return ((StdOStream*)this)->inf->tellp(); }
|
|
||||||
|
|
||||||
size_t size() const
|
|
||||||
{
|
|
||||||
// Use the standard iostream size hack, terrible as it is.
|
|
||||||
std::streampos pos = inf->tellp();
|
|
||||||
inf->seekp(0, std::ios::end);
|
|
||||||
size_t res = inf->tellp();
|
|
||||||
inf->seekp(pos);
|
|
||||||
|
|
||||||
if(inf->fail())
|
|
||||||
fail("could not get stream size");
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool eof() const
|
|
||||||
{ return inf->eof(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef boost::shared_ptr<StdOStream> StdOStreamPtr;
|
|
||||||
|
|
||||||
}} // namespaces
|
|
||||||
#endif
|
|
@ -1,70 +0,0 @@
|
|||||||
#ifndef MANGLE_STREAM_STDIOSERVER_H
|
|
||||||
#define MANGLE_STREAM_STDIOSERVER_H
|
|
||||||
|
|
||||||
#include "../stream.hpp"
|
|
||||||
#include <iostream>
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
namespace Mangle {
|
|
||||||
namespace Stream {
|
|
||||||
|
|
||||||
/** Simple wrapper for std::istream.
|
|
||||||
*/
|
|
||||||
class StdStream : public Stream
|
|
||||||
{
|
|
||||||
std::istream *inf;
|
|
||||||
|
|
||||||
static void fail(const std::string &msg)
|
|
||||||
{ throw std::runtime_error("StdStream: " + msg); }
|
|
||||||
|
|
||||||
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);
|
|
||||||
if(inf->bad())
|
|
||||||
fail("error reading from stream");
|
|
||||||
return inf->gcount();
|
|
||||||
}
|
|
||||||
|
|
||||||
void seek(size_t pos)
|
|
||||||
{
|
|
||||||
inf->clear();
|
|
||||||
inf->seekg(pos);
|
|
||||||
if(inf->fail())
|
|
||||||
fail("seek error");
|
|
||||||
}
|
|
||||||
|
|
||||||
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, std::ios::end);
|
|
||||||
size_t res = inf->tellg();
|
|
||||||
inf->seekg(pos);
|
|
||||||
|
|
||||||
if(inf->fail())
|
|
||||||
fail("could not get stream size");
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool eof() const
|
|
||||||
{ return inf->eof(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef boost::shared_ptr<StdStream> StdStreamPtr;
|
|
||||||
|
|
||||||
}} // namespaces
|
|
||||||
#endif
|
|
@ -1,103 +0,0 @@
|
|||||||
#ifndef MANGLE_STREAM_INPUT_H
|
|
||||||
#define MANGLE_STREAM_INPUT_H
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "../tools/shared_ptr.hpp"
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
namespace Mangle {
|
|
||||||
namespace Stream {
|
|
||||||
|
|
||||||
/// An abstract interface for a stream data.
|
|
||||||
class Stream
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
|
|
||||||
/// If true, write() works. Writing through pointer operations is
|
|
||||||
/// not (yet) supported.
|
|
||||||
bool isWritable;
|
|
||||||
|
|
||||||
/// If true, read() and eof() works.
|
|
||||||
bool isReadable;
|
|
||||||
|
|
||||||
/// If true, the getPtr() functions work
|
|
||||||
bool hasPtr;
|
|
||||||
|
|
||||||
/// Initialize all bools to false by default, except isReadable.
|
|
||||||
Stream() :
|
|
||||||
isSeekable(false), hasPosition(false), hasSize(false),
|
|
||||||
isWritable(false), isReadable(true), hasPtr(false) {}
|
|
||||||
|
|
||||||
/// Virtual destructor
|
|
||||||
virtual ~Stream() {}
|
|
||||||
|
|
||||||
/** 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. Only required for readable
|
|
||||||
streams.
|
|
||||||
*/
|
|
||||||
virtual size_t read(void* buf, size_t count) { assert(0); return 0; }
|
|
||||||
|
|
||||||
/** Write a given number of bytes from the stream. Semantics is
|
|
||||||
similar to read(). Only valid if isWritable is true.
|
|
||||||
|
|
||||||
The returned value is the number of bytes written. However in
|
|
||||||
most cases, unlike for read(), a write-count less than requested
|
|
||||||
usually indicates an error. The implementation should throw such
|
|
||||||
errors as exceptions rather than expect the caller to handle
|
|
||||||
them.
|
|
||||||
|
|
||||||
Since most implementations do NOT support writing we default to
|
|
||||||
an assert(0) here.
|
|
||||||
*/
|
|
||||||
virtual size_t write(const void *buf, size_t count) { assert(0); return 0; }
|
|
||||||
|
|
||||||
/// Flush an output stream. Does nothing for non-writing streams.
|
|
||||||
virtual void flush() {}
|
|
||||||
|
|
||||||
/// Seek to an absolute position in this stream. Not all streams are
|
|
||||||
/// seekable.
|
|
||||||
virtual void seek(size_t pos) { assert(0); }
|
|
||||||
|
|
||||||
/// Get the current position in the stream. Non-seekable streams are
|
|
||||||
/// not required to keep track of this.
|
|
||||||
virtual size_t tell() const { assert(0); return 0; }
|
|
||||||
|
|
||||||
/// Return the total size of the stream. For streams hasSize is
|
|
||||||
/// false, size() should fail in some way, since it is an error to
|
|
||||||
/// call it in those cases.
|
|
||||||
virtual size_t size() const { assert(0); return 0; }
|
|
||||||
|
|
||||||
/// Returns true if the stream is empty. Required for readable
|
|
||||||
/// streams.
|
|
||||||
virtual bool eof() const { assert(0); return 0; }
|
|
||||||
|
|
||||||
/// Return a pointer to the entire stream. This function (and the
|
|
||||||
/// other getPtr() variants below) should only be implemented for
|
|
||||||
/// memory-based streams where using them would be an optimization.
|
|
||||||
virtual const void *getPtr() { assert(0); return NULL; }
|
|
||||||
|
|
||||||
/// Get a pointer to a memory region of 'size' bytes starting from
|
|
||||||
/// position 'pos'
|
|
||||||
virtual const void *getPtr(size_t pos, size_t size) { assert(0); return NULL; }
|
|
||||||
|
|
||||||
/// Get a pointer to a memory region of 'size' bytes from the
|
|
||||||
/// current position. Unlike the two other getPtr variants, this
|
|
||||||
/// will advance the position past the returned area.
|
|
||||||
virtual const void *getPtr(size_t size) { assert(0); return NULL; }
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef boost::shared_ptr<Stream> StreamPtr;
|
|
||||||
|
|
||||||
}} // namespaces
|
|
||||||
#endif
|
|
@ -1,2 +0,0 @@
|
|||||||
*_test
|
|
||||||
test.file
|
|
@ -1,34 +0,0 @@
|
|||||||
GCC=g++ -I../ -Wall -Werror
|
|
||||||
|
|
||||||
all: ogre_client_test audiere_client_test memory_server_test buffer_filter_test file_server_test slice_filter_test file_write_test iostream_test
|
|
||||||
|
|
||||||
I_OGRE=$(shell pkg-config --cflags OGRE)
|
|
||||||
L_OGRE=$(shell pkg-config --libs OGRE)
|
|
||||||
L_AUDIERE=-laudiere
|
|
||||||
|
|
||||||
ogre_client_test: ogre_client_test.cpp ../stream.hpp ../clients/ogre_datastream.hpp
|
|
||||||
$(GCC) $< -o $@ $(I_OGRE) $(L_OGRE)
|
|
||||||
|
|
||||||
audiere_client_test: audiere_client_test.cpp ../stream.hpp ../clients/audiere_file.hpp ../clients/audiere_file.cpp
|
|
||||||
$(GCC) $< -o $@ ../clients/audiere_file.cpp $(L_AUDIERE)
|
|
||||||
|
|
||||||
iostream_test: iostream_test.cpp ../clients/io_stream.cpp
|
|
||||||
$(GCC) $^ -o $@
|
|
||||||
|
|
||||||
file_server_test: file_server_test.cpp ../stream.hpp ../servers/file_stream.hpp ../servers/std_stream.hpp
|
|
||||||
$(GCC) $< -o $@
|
|
||||||
|
|
||||||
file_write_test: file_write_test.cpp ../stream.hpp ../servers/outfile_stream.hpp ../servers/std_ostream.hpp
|
|
||||||
$(GCC) $< -o $@
|
|
||||||
|
|
||||||
memory_server_test: memory_server_test.cpp ../stream.hpp ../servers/memory_stream.hpp
|
|
||||||
$(GCC) $< -o $@
|
|
||||||
|
|
||||||
buffer_filter_test: buffer_filter_test.cpp ../stream.hpp ../servers/memory_stream.hpp ../filters/buffer_stream.hpp
|
|
||||||
$(GCC) $< -o $@
|
|
||||||
|
|
||||||
slice_filter_test: slice_filter_test.cpp ../stream.hpp ../servers/memory_stream.hpp ../filters/slice_stream.hpp
|
|
||||||
$(GCC) $< -o $@
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm *_test
|
|
@ -1,34 +0,0 @@
|
|||||||
#include "../servers/memory_stream.hpp"
|
|
||||||
#include "../clients/audiere_file.hpp"
|
|
||||||
#include <audiere.h>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
using namespace Mangle::Stream;
|
|
||||||
using namespace audiere;
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
char str[12];
|
|
||||||
memset(str, 0, 12);
|
|
||||||
StreamPtr inp(new MemoryStream("hello world", 11));
|
|
||||||
FilePtr p(new AudiereFile(inp));
|
|
||||||
cout << "pos=" << p->tell() << endl;
|
|
||||||
p->read(str, 2);
|
|
||||||
cout << "2 bytes: " << str << endl;
|
|
||||||
cout << "pos=" << p->tell() << endl;
|
|
||||||
p->seek(4, File::BEGIN);
|
|
||||||
cout << "pos=" << p->tell() << endl;
|
|
||||||
p->read(str, 3);
|
|
||||||
cout << "3 bytes: " << str << endl;
|
|
||||||
p->seek(-1, File::CURRENT);
|
|
||||||
cout << "pos=" << p->tell() << endl;
|
|
||||||
p->seek(-4, File::END);
|
|
||||||
cout << "pos=" << p->tell() << endl;
|
|
||||||
p->read(str, 4);
|
|
||||||
cout << "last 4 bytes: " << str << endl;
|
|
||||||
p->seek(0, File::BEGIN);
|
|
||||||
p->read(str, 11);
|
|
||||||
cout << "entire stream: " << str << endl;
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
#include <iostream>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "../filters/buffer_stream.hpp"
|
|
||||||
|
|
||||||
using namespace Mangle::Stream;
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
StreamPtr orig (new MemoryStream("hello world", 11));
|
|
||||||
StreamPtr inp (new BufferStream(orig));
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
#include "../servers/file_stream.hpp"
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
using namespace Mangle::Stream;
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
StreamPtr inp(new FileStream("file_server_test.cpp"));
|
|
||||||
|
|
||||||
char buf[21];
|
|
||||||
buf[20] = 0;
|
|
||||||
cout << "pos=" << inp->tell() << " eof=" << inp->eof() << endl;
|
|
||||||
inp->read(buf, 20);
|
|
||||||
cout << "First 20 bytes: " << buf << endl;
|
|
||||||
cout << "pos=" << inp->tell() << " eof=" << inp->eof() << endl;
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
#include "../servers/outfile_stream.hpp"
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
using namespace Mangle::Stream;
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
void print(Stream &str)
|
|
||||||
{
|
|
||||||
cout << "size=" << str.size()
|
|
||||||
<< " pos=" << str.tell()
|
|
||||||
<< " eof=" << str.eof()
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
{
|
|
||||||
cout << "\nCreating file\n";
|
|
||||||
OutFileStream out("test.file");
|
|
||||||
print(out);
|
|
||||||
out.write("hello",5);
|
|
||||||
print(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
cout << "\nAppending to file\n";
|
|
||||||
OutFileStream out("test.file", true);
|
|
||||||
print(out);
|
|
||||||
out.write(" again\n",7);
|
|
||||||
print(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
cout << "\nOverwriting file\n";
|
|
||||||
OutFileStream out("test.file");
|
|
||||||
print(out);
|
|
||||||
out.write("overwrite!\n",11);
|
|
||||||
print(out);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,176 +0,0 @@
|
|||||||
#include <iostream>
|
|
||||||
#include "../clients/io_stream.hpp"
|
|
||||||
#include "../servers/memory_stream.hpp"
|
|
||||||
|
|
||||||
using namespace Mangle::Stream;
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
void test1()
|
|
||||||
{
|
|
||||||
cout << "Testing ASCII reading from memory:\n";
|
|
||||||
StreamPtr input(new MemoryStream("hello you world you", 19));
|
|
||||||
MangleIStream inp(input);
|
|
||||||
|
|
||||||
string str;
|
|
||||||
while(!inp.eof())
|
|
||||||
{
|
|
||||||
inp >> str;
|
|
||||||
cout << "Got: " << str << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Dummy : public Stream
|
|
||||||
{
|
|
||||||
int count;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Dummy() : count(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t read(void *ptr, size_t num)
|
|
||||||
{
|
|
||||||
char *p = (char*)ptr;
|
|
||||||
char *start = p;
|
|
||||||
for(; (count < 2560) && (p-start < (int)num); count++)
|
|
||||||
{
|
|
||||||
*p = count / 10;
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
return p-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool eof() const { return count == 2560; }
|
|
||||||
};
|
|
||||||
|
|
||||||
void test2()
|
|
||||||
{
|
|
||||||
cout << "\nTesting binary reading from non-memory:\n";
|
|
||||||
|
|
||||||
StreamPtr input(new Dummy);
|
|
||||||
MangleIStream inp(input);
|
|
||||||
|
|
||||||
int x = 0;
|
|
||||||
while(!inp.eof())
|
|
||||||
{
|
|
||||||
unsigned char buf[5];
|
|
||||||
inp.read((char*)buf,5);
|
|
||||||
|
|
||||||
// istream doesn't set eof() until we read _beyond_ the end of
|
|
||||||
// the stream, so we need an extra check.
|
|
||||||
if(inp.gcount() == 0) break;
|
|
||||||
|
|
||||||
/*
|
|
||||||
for(int i=0;i<5;i++)
|
|
||||||
cout << (int)buf[i] << " ";
|
|
||||||
cout << endl;
|
|
||||||
*/
|
|
||||||
|
|
||||||
assert(buf[4] == buf[0]);
|
|
||||||
assert(buf[0] == x/2);
|
|
||||||
x++;
|
|
||||||
}
|
|
||||||
cout << " Done\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Dummy2 : Stream
|
|
||||||
{
|
|
||||||
Dummy2()
|
|
||||||
{
|
|
||||||
isWritable = true;
|
|
||||||
isReadable = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t write(const void *ptr, size_t num)
|
|
||||||
{
|
|
||||||
const char *p = (const char*)ptr;
|
|
||||||
cout << " Got: ";
|
|
||||||
for(unsigned i=0;i<num;i++)
|
|
||||||
cout << *(p++) << " ";
|
|
||||||
cout << endl;
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void test3()
|
|
||||||
{
|
|
||||||
cout << "\nWriting to dummy stream:\n";
|
|
||||||
|
|
||||||
cout << " Pure dummy test:\n";
|
|
||||||
StreamPtr output(new Dummy2);
|
|
||||||
output->write("testing", 7);
|
|
||||||
|
|
||||||
cout << " Running through MangleOStream:\n";
|
|
||||||
MangleOStream out(output);
|
|
||||||
out << "hello";
|
|
||||||
out << " - are you ok?";
|
|
||||||
cout << " Flushing:\n";
|
|
||||||
out.flush();
|
|
||||||
|
|
||||||
cout << " Writing a hell of a lot of characters:\n";
|
|
||||||
for(int i=0; i<127; i++)
|
|
||||||
out << "xxxxxxxx"; // 127 * 8 = 1016
|
|
||||||
out << "fffffff"; // +7 = 1023
|
|
||||||
cout << " Just one more:\n";
|
|
||||||
out << "y";
|
|
||||||
cout << " And oooone more:\n";
|
|
||||||
out << "z";
|
|
||||||
|
|
||||||
cout << " Flushing again:\n";
|
|
||||||
out.flush();
|
|
||||||
cout << " Writing some more and exiting:\n";
|
|
||||||
out << "blah bleh blob";
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Dummy3 : Stream
|
|
||||||
{
|
|
||||||
int pos;
|
|
||||||
|
|
||||||
Dummy3() : pos(0)
|
|
||||||
{
|
|
||||||
hasPosition = true;
|
|
||||||
isSeekable = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t read(void*, size_t num)
|
|
||||||
{
|
|
||||||
cout << " Reading " << num << " bytes from " << pos << endl;
|
|
||||||
pos += num;
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
|
|
||||||
void seek(size_t npos) { pos = npos; }
|
|
||||||
size_t tell() const { return pos; }
|
|
||||||
};
|
|
||||||
|
|
||||||
void test4()
|
|
||||||
{
|
|
||||||
cout << "\nTesting seeking;\n";
|
|
||||||
StreamPtr input(new Dummy3);
|
|
||||||
|
|
||||||
cout << " Direct reading:\n";
|
|
||||||
input->read(0,10);
|
|
||||||
input->read(0,5);
|
|
||||||
|
|
||||||
MangleIStream inp(input);
|
|
||||||
|
|
||||||
cout << " Reading from istream:\n";
|
|
||||||
char buf[20];
|
|
||||||
inp.read(buf, 20);
|
|
||||||
inp.read(buf, 20);
|
|
||||||
inp.read(buf, 20);
|
|
||||||
|
|
||||||
cout << " Seeking to 30 and reading again:\n";
|
|
||||||
inp.seekg(30);
|
|
||||||
inp.read(buf, 20);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
test1();
|
|
||||||
test2();
|
|
||||||
test3();
|
|
||||||
test4();
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
#include <iostream>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "../servers/memory_stream.hpp"
|
|
||||||
|
|
||||||
using namespace Mangle::Stream;
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
Stream* inp = new MemoryStream("hello world\0", 12);
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
cout << "Entire stream from pointer: " << (char*)inp->getPtr() << endl;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
#include "../servers/memory_stream.hpp"
|
|
||||||
#include "../clients/ogre_datastream.hpp"
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
using namespace Mangle::Stream;
|
|
||||||
using namespace Ogre;
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
StreamPtr inp(new MemoryStream("hello world", 11));
|
|
||||||
DataStreamPtr p(new Mangle2OgreStream("hello", inp));
|
|
||||||
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;
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
pos=0
|
|
||||||
2 bytes: he
|
|
||||||
pos=2
|
|
||||||
pos=4
|
|
||||||
3 bytes: o w
|
|
||||||
pos=6
|
|
||||||
pos=7
|
|
||||||
last 4 bytes: orld
|
|
||||||
entire stream: hello world
|
|
@ -1,22 +0,0 @@
|
|||||||
Size: 11
|
|
||||||
Pos: 0
|
|
||||||
Seeking...
|
|
||||||
Pos: 3
|
|
||||||
Reading: 4
|
|
||||||
Four bytes: lo w
|
|
||||||
Eof: 0
|
|
||||||
Pos: 7
|
|
||||||
Seeking again...
|
|
||||||
Pos: 11
|
|
||||||
Eof: 1
|
|
||||||
Seek to 6
|
|
||||||
Eof: 0
|
|
||||||
Pos: 6
|
|
||||||
Over-reading: 5
|
|
||||||
Result: world
|
|
||||||
Eof: 1
|
|
||||||
Pos: 11
|
|
||||||
Finally, reading the entire string: 11
|
|
||||||
Result: hello world
|
|
||||||
Eof: 1
|
|
||||||
Pos: 11
|
|
@ -1,3 +0,0 @@
|
|||||||
pos=0 eof=0
|
|
||||||
First 20 bytes: #include "../servers
|
|
||||||
pos=20 eof=0
|
|
@ -1,12 +0,0 @@
|
|||||||
|
|
||||||
Creating file
|
|
||||||
size=0 pos=0 eof=0
|
|
||||||
size=5 pos=5 eof=0
|
|
||||||
|
|
||||||
Appending to file
|
|
||||||
size=5 pos=5 eof=0
|
|
||||||
size=12 pos=12 eof=0
|
|
||||||
|
|
||||||
Overwriting file
|
|
||||||
size=0 pos=0 eof=0
|
|
||||||
size=11 pos=11 eof=0
|
|
@ -1,32 +0,0 @@
|
|||||||
Testing ASCII reading from memory:
|
|
||||||
Got: hello
|
|
||||||
Got: you
|
|
||||||
Got: world
|
|
||||||
Got: you
|
|
||||||
|
|
||||||
Testing binary reading from non-memory:
|
|
||||||
Done
|
|
||||||
|
|
||||||
Writing to dummy stream:
|
|
||||||
Pure dummy test:
|
|
||||||
Got: t e s t i n g
|
|
||||||
Running through MangleOStream:
|
|
||||||
Flushing:
|
|
||||||
Got: h e l l o - a r e y o u o k ?
|
|
||||||
Writing a hell of a lot of characters:
|
|
||||||
Just one more:
|
|
||||||
And oooone more:
|
|
||||||
Got: x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x f f f f f f f y
|
|
||||||
Flushing again:
|
|
||||||
Got: z
|
|
||||||
Writing some more and exiting:
|
|
||||||
Got: b l a h b l e h b l o b
|
|
||||||
|
|
||||||
Testing seeking;
|
|
||||||
Direct reading:
|
|
||||||
Reading 10 bytes from 0
|
|
||||||
Reading 5 bytes from 10
|
|
||||||
Reading from istream:
|
|
||||||
Reading 1024 bytes from 15
|
|
||||||
Seeking to 30 and reading again:
|
|
||||||
Reading 1024 bytes from 30
|
|
@ -1,23 +0,0 @@
|
|||||||
Size: 12
|
|
||||||
Pos: 0
|
|
||||||
Seeking...
|
|
||||||
Pos: 3
|
|
||||||
Reading: 4
|
|
||||||
Four bytes: lo w
|
|
||||||
Eof: 0
|
|
||||||
Pos: 7
|
|
||||||
Seeking again...
|
|
||||||
Pos: 12
|
|
||||||
Eof: 1
|
|
||||||
Seek to 6
|
|
||||||
Eof: 0
|
|
||||||
Pos: 6
|
|
||||||
Over-reading: 6
|
|
||||||
Result: world
|
|
||||||
Eof: 1
|
|
||||||
Pos: 12
|
|
||||||
Finally, reading the entire string: 11
|
|
||||||
Result: hello world
|
|
||||||
Eof: 0
|
|
||||||
Pos: 11
|
|
||||||
Entire stream from pointer: hello world
|
|
@ -1,5 +0,0 @@
|
|||||||
Name: hello
|
|
||||||
As string: hello world
|
|
||||||
pos=11 eof=1
|
|
||||||
pos=0 eof=0
|
|
||||||
pos=3 eof=0
|
|
@ -1,36 +0,0 @@
|
|||||||
|
|
||||||
Slice 1:
|
|
||||||
--------
|
|
||||||
Size: 6
|
|
||||||
Pos: 0
|
|
||||||
Seeking...
|
|
||||||
Reading 6 bytes
|
|
||||||
Result: hello
|
|
||||||
Pos: 6
|
|
||||||
Eof: 1
|
|
||||||
Seeking:
|
|
||||||
Pos: 2
|
|
||||||
Eof: 0
|
|
||||||
Reading 4 bytes
|
|
||||||
Result: llo
|
|
||||||
Pos: 6
|
|
||||||
Eof: 1
|
|
||||||
Entire stream as pointer: hello
|
|
||||||
|
|
||||||
Slice 2:
|
|
||||||
--------
|
|
||||||
Size: 6
|
|
||||||
Pos: 0
|
|
||||||
Seeking...
|
|
||||||
Reading 6 bytes
|
|
||||||
Result: world
|
|
||||||
Pos: 6
|
|
||||||
Eof: 1
|
|
||||||
Seeking:
|
|
||||||
Pos: 2
|
|
||||||
Eof: 0
|
|
||||||
Reading 4 bytes
|
|
||||||
Result: rld
|
|
||||||
Pos: 6
|
|
||||||
Eof: 1
|
|
||||||
Entire stream as pointer: world
|
|
@ -1,42 +0,0 @@
|
|||||||
#include <iostream>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "../filters/slice_stream.hpp"
|
|
||||||
#include "../servers/memory_stream.hpp"
|
|
||||||
|
|
||||||
using namespace Mangle::Stream;
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
void test(StreamPtr inp)
|
|
||||||
{
|
|
||||||
cout << "Size: " << inp->size() << endl;
|
|
||||||
cout << "Pos: " << inp->tell() << "\nSeeking...\n";
|
|
||||||
char data[6];
|
|
||||||
memset(data, 0, 6);
|
|
||||||
cout << "Reading " << inp->read(data, 6) << " bytes\n";
|
|
||||||
cout << "Result: " << data << endl;
|
|
||||||
cout << "Pos: " << inp->tell() << endl;
|
|
||||||
cout << "Eof: " << inp->eof() << endl;
|
|
||||||
inp->seek(2);
|
|
||||||
cout << "Seeking:\nPos: " << inp->tell() << endl;
|
|
||||||
cout << "Eof: " << inp->eof() << endl;
|
|
||||||
cout << "Reading " << inp->read(data, 6) << " bytes\n";
|
|
||||||
cout << "Result: " << data << endl;
|
|
||||||
cout << "Pos: " << inp->tell() << endl;
|
|
||||||
cout << "Eof: " << inp->eof() << endl;
|
|
||||||
cout << "Entire stream as pointer: " << (char*)inp->getPtr() << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
StreamPtr orig (new MemoryStream("hello\0world\0", 12));
|
|
||||||
StreamPtr slice1 (new SliceStream(orig,0,6));
|
|
||||||
StreamPtr slice2 (new SliceStream(orig,6,6));
|
|
||||||
|
|
||||||
cout << "\nSlice 1:\n--------\n";
|
|
||||||
test(slice1);
|
|
||||||
cout << "\nSlice 2:\n--------\n";
|
|
||||||
test(slice2);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
make || exit
|
|
||||||
|
|
||||||
mkdir -p output
|
|
||||||
|
|
||||||
PROGS=*_test
|
|
||||||
|
|
||||||
for a in $PROGS; do
|
|
||||||
if [ -f "output/$a.out" ]; then
|
|
||||||
echo "Running $a:"
|
|
||||||
./$a | diff output/$a.out -
|
|
||||||
else
|
|
||||||
echo "Creating $a.out"
|
|
||||||
./$a > "output/$a.out"
|
|
||||||
git add "output/$a.out"
|
|
||||||
fi
|
|
||||||
done
|
|
@ -1,85 +0,0 @@
|
|||||||
#include "ogre_archive.hpp"
|
|
||||||
|
|
||||||
#include "../../stream/clients/ogre_datastream.hpp"
|
|
||||||
|
|
||||||
using namespace Mangle::VFS;
|
|
||||||
using namespace Mangle::Stream;
|
|
||||||
|
|
||||||
Ogre::DataStreamPtr MangleArchive::open(const Ogre::String& filename) const
|
|
||||||
{
|
|
||||||
return Ogre::DataStreamPtr(new Mangle2OgreStream
|
|
||||||
(filename, vfs->open(filename)));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fill(Ogre::FileInfoList &out, FileInfoList &in)
|
|
||||||
{
|
|
||||||
int size = in.size();
|
|
||||||
out.resize(size);
|
|
||||||
|
|
||||||
for(int i=0; i<size; i++)
|
|
||||||
{
|
|
||||||
out[i].filename = in[i].name;
|
|
||||||
out[i].basename = in[i].basename;
|
|
||||||
out[i].path = ""; // FIXME
|
|
||||||
out[i].uncompressedSize = in[i].size;
|
|
||||||
out[i].compressedSize = in[i].size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fill(Ogre::StringVector &out, FileInfoList &in)
|
|
||||||
{
|
|
||||||
int size = in.size();
|
|
||||||
out.resize(size);
|
|
||||||
|
|
||||||
for(int i=0; i<size; i++)
|
|
||||||
out[i] = in[i].name;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ogre::StringVectorPtr MangleArchive::list(bool recursive, bool dirs)
|
|
||||||
{
|
|
||||||
assert(vfs->hasList);
|
|
||||||
FileInfoListPtr lst = vfs->list("", recursive, dirs);
|
|
||||||
Ogre::StringVector *res = new Ogre::StringVector;
|
|
||||||
|
|
||||||
fill(*res, *lst);
|
|
||||||
|
|
||||||
return Ogre::StringVectorPtr(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ogre::FileInfoListPtr MangleArchive::listFileInfo(bool recursive, bool dirs)
|
|
||||||
{
|
|
||||||
assert(vfs->hasList);
|
|
||||||
FileInfoListPtr lst = vfs->list("", recursive, dirs);
|
|
||||||
Ogre::FileInfoList *res = new Ogre::FileInfoList;
|
|
||||||
|
|
||||||
fill(*res, *lst);
|
|
||||||
|
|
||||||
return Ogre::FileInfoListPtr(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find functions will only work if vfs->hasFind is set.
|
|
||||||
Ogre::StringVectorPtr MangleArchive::find(const Ogre::String& pattern,
|
|
||||||
bool recursive,
|
|
||||||
bool dirs)
|
|
||||||
{
|
|
||||||
assert(vfs->hasFind);
|
|
||||||
FileInfoListPtr lst = vfs->find(pattern, recursive, dirs);
|
|
||||||
Ogre::StringVector *res = new Ogre::StringVector;
|
|
||||||
|
|
||||||
fill(*res, *lst);
|
|
||||||
|
|
||||||
return Ogre::StringVectorPtr(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ogre::FileInfoListPtr MangleArchive::findFileInfo(const Ogre::String& pattern,
|
|
||||||
bool recursive,
|
|
||||||
bool dirs)
|
|
||||||
{
|
|
||||||
assert(vfs->hasFind);
|
|
||||||
FileInfoListPtr lst = vfs->find(pattern, recursive, dirs);
|
|
||||||
Ogre::FileInfoList *res = new Ogre::FileInfoList;
|
|
||||||
|
|
||||||
fill(*res, *lst);
|
|
||||||
|
|
||||||
return Ogre::FileInfoListPtr(res);
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
#ifndef MANGLE_VFS_OGRECLIENT_H
|
|
||||||
#define MANGLE_VFS_OGRECLIENT_H
|
|
||||||
|
|
||||||
#include <OgreArchive.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include "../vfs.hpp"
|
|
||||||
|
|
||||||
namespace Mangle {
|
|
||||||
namespace VFS {
|
|
||||||
|
|
||||||
/** An OGRE Archive implementation that wraps a Mangle::VFS
|
|
||||||
filesystem.
|
|
||||||
|
|
||||||
This has been built and tested against OGRE 1.6.2, and has been
|
|
||||||
extended for OGRE 1.7. You might have to make your own
|
|
||||||
modifications if you're working with newer (or older) versions.
|
|
||||||
*/
|
|
||||||
class MangleArchive : public Ogre::Archive
|
|
||||||
{
|
|
||||||
VFSPtr vfs;
|
|
||||||
|
|
||||||
public:
|
|
||||||
MangleArchive(VFSPtr _vfs, const std::string &name,
|
|
||||||
const std::string &archType = "Mangle")
|
|
||||||
: Ogre::Archive(name, archType)
|
|
||||||
, vfs(_vfs)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool isCaseSensitive() const { return vfs->isCaseSensitive; }
|
|
||||||
|
|
||||||
// These do nothing. You have to load / unload the archive in the
|
|
||||||
// constructor/destructor.
|
|
||||||
void load() {}
|
|
||||||
void unload() {}
|
|
||||||
|
|
||||||
bool exists(const Ogre::String& filename)
|
|
||||||
{ return vfs->isFile(filename); }
|
|
||||||
|
|
||||||
time_t getModifiedTime(const Ogre::String& filename)
|
|
||||||
{ return vfs->stat(filename)->time; }
|
|
||||||
|
|
||||||
// With both these we support both OGRE 1.6 and 1.7
|
|
||||||
Ogre::DataStreamPtr open(const Ogre::String& filename) const;
|
|
||||||
Ogre::DataStreamPtr open(const Ogre::String& filename, bool readOnly) const
|
|
||||||
{ return open(filename); }
|
|
||||||
|
|
||||||
Ogre::StringVectorPtr list(bool recursive = true, bool dirs = false);
|
|
||||||
Ogre::FileInfoListPtr listFileInfo(bool recursive = true, bool dirs = false);
|
|
||||||
|
|
||||||
// Find functions will only work if vfs->hasFind is set.
|
|
||||||
Ogre::StringVectorPtr find(const Ogre::String& pattern, bool recursive = true,
|
|
||||||
bool dirs = false);
|
|
||||||
Ogre::FileInfoListPtr findFileInfo(const Ogre::String& pattern,
|
|
||||||
bool recursive = true,
|
|
||||||
bool dirs = false);
|
|
||||||
};
|
|
||||||
|
|
||||||
}} // namespaces
|
|
||||||
#endif
|
|
@ -1,61 +0,0 @@
|
|||||||
#include "ogre_vfs.hpp"
|
|
||||||
#include "../../stream/servers/ogre_datastream.hpp"
|
|
||||||
|
|
||||||
using namespace Mangle::VFS;
|
|
||||||
using namespace Mangle::Stream;
|
|
||||||
|
|
||||||
OgreVFS::OgreVFS(const std::string &_group)
|
|
||||||
: group(_group)
|
|
||||||
{
|
|
||||||
hasList = true;
|
|
||||||
hasFind = true;
|
|
||||||
isCaseSensitive = true;
|
|
||||||
|
|
||||||
// Get the group manager once
|
|
||||||
gm = Ogre::ResourceGroupManager::getSingletonPtr();
|
|
||||||
|
|
||||||
// Use the default group if none was specified
|
|
||||||
if(group.empty())
|
|
||||||
group = gm->getWorldResourceGroupName();
|
|
||||||
}
|
|
||||||
|
|
||||||
StreamPtr OgreVFS::open(const std::string &name)
|
|
||||||
{
|
|
||||||
Ogre::DataStreamPtr data = gm->openResource(name, group);
|
|
||||||
return StreamPtr(new OgreStream(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fill(FileInfoList &out, Ogre::FileInfoList &in, bool dirs)
|
|
||||||
{
|
|
||||||
int size = in.size();
|
|
||||||
out.resize(size);
|
|
||||||
|
|
||||||
for(int i=0; i<size; i++)
|
|
||||||
{
|
|
||||||
out[i].name = in[i].filename;
|
|
||||||
out[i].basename = in[i].basename;
|
|
||||||
out[i].size = in[i].uncompressedSize;
|
|
||||||
out[i].isDir = dirs;
|
|
||||||
out[i].time = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FileInfoListPtr OgreVFS::list(const std::string& dir,
|
|
||||||
bool recurse,
|
|
||||||
bool dirs) const
|
|
||||||
{
|
|
||||||
Ogre::FileInfoListPtr olist = gm->listResourceFileInfo(group, dirs);
|
|
||||||
FileInfoListPtr res(new FileInfoList);
|
|
||||||
fill(*res, *olist, dirs);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileInfoListPtr OgreVFS::find(const std::string& pattern,
|
|
||||||
bool recursive,
|
|
||||||
bool dirs) const
|
|
||||||
{
|
|
||||||
Ogre::FileInfoListPtr olist = gm->findResourceFileInfo(group, pattern, dirs);
|
|
||||||
FileInfoListPtr res(new FileInfoList);
|
|
||||||
fill(*res, *olist, dirs);
|
|
||||||
return res;
|
|
||||||
}
|
|
@ -1,70 +0,0 @@
|
|||||||
#ifndef MANGLE_VFS_OGRESERVER_H
|
|
||||||
#define MANGLE_VFS_OGRESERVER_H
|
|
||||||
|
|
||||||
#include "../vfs.hpp"
|
|
||||||
#include <OgreResourceGroupManager.h>
|
|
||||||
|
|
||||||
namespace Mangle {
|
|
||||||
namespace VFS {
|
|
||||||
|
|
||||||
/** @brief An interface into the OGRE VFS system.
|
|
||||||
|
|
||||||
This class does NOT wrap a single Ogre::Archive, but rather an
|
|
||||||
entire resource group in Ogre. You can use this class to tap into
|
|
||||||
all paths, Zip files, custom archives on so on that have been
|
|
||||||
inserted into Ogre as resource locations.
|
|
||||||
|
|
||||||
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 OgreVFS : public VFS
|
|
||||||
{
|
|
||||||
std::string group;
|
|
||||||
Ogre::ResourceGroupManager *gm;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/** @brief Constructor
|
|
||||||
|
|
||||||
OGRE must be initialized (ie. you must have created an
|
|
||||||
Ogre::Root object somewhere) before calling this.
|
|
||||||
|
|
||||||
@param group Optional resource group name. If none is given,
|
|
||||||
OGRE's default (or 'World') resource group is used.
|
|
||||||
*/
|
|
||||||
OgreVFS(const std::string &_group = "");
|
|
||||||
|
|
||||||
/// Open a new data stream. Deleting the object should be enough to
|
|
||||||
/// close it.
|
|
||||||
virtual Stream::StreamPtr open(const std::string &name);
|
|
||||||
|
|
||||||
/// Check for the existence of a file
|
|
||||||
virtual bool isFile(const std::string &name) const
|
|
||||||
{ return gm->resourceExists(group, name); }
|
|
||||||
|
|
||||||
/// This doesn't work, always returns false.
|
|
||||||
virtual bool isDir(const std::string &name) const
|
|
||||||
{ return false; }
|
|
||||||
|
|
||||||
/// This doesn't work.
|
|
||||||
virtual FileInfoPtr stat(const std::string &name) const
|
|
||||||
{ return FileInfoPtr(); }
|
|
||||||
|
|
||||||
/// List all entries in a given directory. A blank dir should be
|
|
||||||
/// interpreted as a the root/current directory of the archive. If
|
|
||||||
/// dirs is true, list directories instead of files. OGRE note: The
|
|
||||||
/// ogre resource systemd does not support recursive listing of
|
|
||||||
/// files. We might make a separate filter for this later.
|
|
||||||
virtual FileInfoListPtr list(const std::string& dir = "",
|
|
||||||
bool recurse=true,
|
|
||||||
bool dirs=false) const;
|
|
||||||
|
|
||||||
/// Find files after a given pattern. Wildcards (*) are
|
|
||||||
/// supported.
|
|
||||||
virtual FileInfoListPtr find(const std::string& pattern,
|
|
||||||
bool recursive=true,
|
|
||||||
bool dirs=false) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
}} // namespaces
|
|
||||||
#endif
|
|
@ -1,71 +0,0 @@
|
|||||||
#ifndef MANGLE_VFS_PHYSFS_SERVER_H
|
|
||||||
#define MANGLE_VFS_PHYSFS_SERVER_H
|
|
||||||
|
|
||||||
#include "../vfs.hpp"
|
|
||||||
#include "../../stream/servers/phys_stream.hpp"
|
|
||||||
|
|
||||||
#include <physfs.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
namespace Mangle {
|
|
||||||
namespace VFS {
|
|
||||||
|
|
||||||
/** @brief An interface into the PhysFS virtual file system library
|
|
||||||
|
|
||||||
You have to set up PhysFS on your own before using this class.
|
|
||||||
*/
|
|
||||||
class PhysVFS : public VFS
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
PhysVFS()
|
|
||||||
{
|
|
||||||
hasList = true;
|
|
||||||
hasFind = false;
|
|
||||||
isCaseSensitive = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Open a new data stream. Deleting the object should be enough to
|
|
||||||
/// close it.
|
|
||||||
virtual Stream::StreamPtr open(const std::string &name)
|
|
||||||
{ return Stream::StreamPtr(new Stream::PhysFile(PHYSFS_openRead(name.c_str()))); }
|
|
||||||
|
|
||||||
/// Check for the existence of a file
|
|
||||||
virtual bool isFile(const std::string &name) const
|
|
||||||
{ return PHYSFS_exists(name.c_str()); }
|
|
||||||
|
|
||||||
/// Checks for a directory
|
|
||||||
virtual bool isDir(const std::string &name) const
|
|
||||||
{ return PHYSFS_isDirectory(name.c_str()); }
|
|
||||||
|
|
||||||
/// This doesn't work
|
|
||||||
virtual FileInfoPtr stat(const std::string &name) const
|
|
||||||
{ assert(0); return FileInfoPtr(); }
|
|
||||||
|
|
||||||
virtual FileInfoListPtr list(const std::string& dir = "",
|
|
||||||
bool recurse=true,
|
|
||||||
bool dirs=false) const
|
|
||||||
{
|
|
||||||
char **files = PHYSFS_enumerateFiles(dir.c_str());
|
|
||||||
FileInfoListPtr lst(new FileInfoList);
|
|
||||||
|
|
||||||
// Add all teh files
|
|
||||||
int i = 0;
|
|
||||||
while(files[i] != NULL)
|
|
||||||
{
|
|
||||||
FileInfo fi;
|
|
||||||
fi.name = files[i];
|
|
||||||
fi.isDir = false;
|
|
||||||
|
|
||||||
lst->push_back(fi);
|
|
||||||
}
|
|
||||||
return lst;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual FileInfoListPtr find(const std::string& pattern,
|
|
||||||
bool recursive=true,
|
|
||||||
bool dirs=false) const
|
|
||||||
{ assert(0); }
|
|
||||||
};
|
|
||||||
|
|
||||||
}} // namespaces
|
|
||||||
#endif
|
|
@ -1 +0,0 @@
|
|||||||
*_test
|
|
@ -1,25 +0,0 @@
|
|||||||
GCC=g++ -I../ -Wall
|
|
||||||
|
|
||||||
all: dummy_test ogre_client_test ogre_resource_test ogre_server_test physfs_server_test
|
|
||||||
|
|
||||||
I_OGRE=$(shell pkg-config --cflags OGRE)
|
|
||||||
L_OGRE=$(shell pkg-config --libs OGRE)
|
|
||||||
L_PHYSFS=-lphysfs
|
|
||||||
|
|
||||||
ogre_client_test: ogre_client_test.cpp dummy_vfs.cpp ../vfs.hpp ../clients/ogre_archive.hpp ../clients/ogre_archive.cpp
|
|
||||||
$(GCC) $< ../clients/ogre_archive.cpp -o $@ $(I_OGRE) $(L_OGRE)
|
|
||||||
|
|
||||||
ogre_resource_test: ogre_resource_test.cpp
|
|
||||||
$(GCC) $< -o $@ $(I_OGRE) $(L_OGRE)
|
|
||||||
|
|
||||||
ogre_server_test: ogre_server_test.cpp ../vfs.hpp ../servers/ogre_vfs.hpp ../servers/ogre_vfs.cpp
|
|
||||||
$(GCC) $< -o $@ $(I_OGRE) $(L_OGRE) ../servers/ogre_vfs.cpp
|
|
||||||
|
|
||||||
physfs_server_test: physfs_server_test.cpp ../vfs.hpp ../servers/physfs_vfs.hpp
|
|
||||||
$(GCC) $< -o $@ $(L_PHYSFS)
|
|
||||||
|
|
||||||
dummy_test: dummy_test.cpp dummy_vfs.cpp ../vfs.hpp
|
|
||||||
$(GCC) $< -o $@
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm *_test
|
|
@ -1,42 +0,0 @@
|
|||||||
#include "dummy_vfs.cpp"
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
void print(FileInfo &inf)
|
|
||||||
{
|
|
||||||
cout << "name: " << inf.name << endl;
|
|
||||||
cout << "basename: " << inf.basename << endl;
|
|
||||||
cout << "isDir: " << inf.isDir << endl;
|
|
||||||
cout << "size: " << inf.size << endl;
|
|
||||||
cout << "time: " << inf.time << endl;
|
|
||||||
}
|
|
||||||
void print(FileInfoPtr inf) { print(*inf); }
|
|
||||||
|
|
||||||
void print(FileInfoList &lst)
|
|
||||||
{
|
|
||||||
for(unsigned i=0; i<lst.size(); i++)
|
|
||||||
print(lst[i]);
|
|
||||||
}
|
|
||||||
void print(FileInfoListPtr lst) { print(*lst); }
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
DummyVFS vfs;
|
|
||||||
|
|
||||||
cout << "Listing all files:\n";
|
|
||||||
print(vfs.list());
|
|
||||||
cout << "\nStat for single files:\n";
|
|
||||||
print(vfs.stat("file1"));
|
|
||||||
cout << endl;
|
|
||||||
print(vfs.stat("dir/file2"));
|
|
||||||
cout << endl;
|
|
||||||
print(vfs.stat("dir"));
|
|
||||||
|
|
||||||
StreamPtr inp = vfs.open("file1");
|
|
||||||
cout << "filesize: " << inp->size() << endl;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,117 +0,0 @@
|
|||||||
// This file is shared between several test programs
|
|
||||||
#include "vfs.hpp"
|
|
||||||
#include <assert.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "../../stream/servers/memory_stream.hpp"
|
|
||||||
|
|
||||||
using namespace Mangle::VFS;
|
|
||||||
using namespace Mangle::Stream;
|
|
||||||
|
|
||||||
class DummyVFS : public VFS
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
DummyVFS()
|
|
||||||
{
|
|
||||||
hasFind = false;
|
|
||||||
hasList = true;
|
|
||||||
isCaseSensitive = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We only support opening 'file1' at the moment.
|
|
||||||
StreamPtr open(const std::string &name)
|
|
||||||
{
|
|
||||||
assert(name == "file1");
|
|
||||||
return StreamPtr(new MemoryStream("hello world", 11));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isFile(const std::string &name) const
|
|
||||||
{
|
|
||||||
return (name == "file1" ||
|
|
||||||
name == "dir/file2");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isDir(const std::string &name) const
|
|
||||||
{
|
|
||||||
return name == "dir";
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get info about a single file
|
|
||||||
FileInfoPtr stat(const std::string &name) const
|
|
||||||
{
|
|
||||||
FileInfoPtr fi(new FileInfo);
|
|
||||||
fi->name = name;
|
|
||||||
fi->time = 0;
|
|
||||||
|
|
||||||
if(isFile(name))
|
|
||||||
{
|
|
||||||
if(name == "dir/file2")
|
|
||||||
{
|
|
||||||
fi->basename = "file2";
|
|
||||||
fi->size = 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fi->basename = "file1";
|
|
||||||
fi->size = 1;
|
|
||||||
}
|
|
||||||
fi->isDir = false;
|
|
||||||
}
|
|
||||||
else if(isDir(name))
|
|
||||||
{
|
|
||||||
fi->basename = "dir";
|
|
||||||
fi->isDir = true;
|
|
||||||
fi->size = 0;
|
|
||||||
}
|
|
||||||
else assert(0);
|
|
||||||
|
|
||||||
return fi;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// List all entries in a given directory. A blank dir should be
|
|
||||||
/// interpreted as a the root/current directory of the archive. If
|
|
||||||
/// dirs is true, list directories instead of files.
|
|
||||||
virtual FileInfoListPtr list(const std::string& dir = "",
|
|
||||||
bool recurse=true,
|
|
||||||
bool dirs=false) const
|
|
||||||
{
|
|
||||||
assert(dir == "");
|
|
||||||
|
|
||||||
FileInfoListPtr fl(new FileInfoList);
|
|
||||||
|
|
||||||
FileInfo fi;
|
|
||||||
|
|
||||||
if(!dirs)
|
|
||||||
{
|
|
||||||
fi.name = "file1";
|
|
||||||
fi.basename = "file1";
|
|
||||||
fi.isDir = false;
|
|
||||||
fi.size = 1;
|
|
||||||
fi.time = 0;
|
|
||||||
fl->push_back(fi);
|
|
||||||
|
|
||||||
if(recurse)
|
|
||||||
{
|
|
||||||
fi.name = "dir/file2";
|
|
||||||
fi.basename = "file2";
|
|
||||||
fi.size = 2;
|
|
||||||
fl->push_back(fi);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fi.name = "dir";
|
|
||||||
fi.basename = "dir";
|
|
||||||
fi.isDir = true;
|
|
||||||
fi.size = 0;
|
|
||||||
fi.time = 0;
|
|
||||||
fl->push_back(fi);
|
|
||||||
}
|
|
||||||
return fl;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileInfoListPtr find(const std::string& pattern,
|
|
||||||
bool recursive=true,
|
|
||||||
bool dirs=false) const
|
|
||||||
{ assert(0); }
|
|
||||||
};
|
|
@ -1,39 +0,0 @@
|
|||||||
#include "dummy_vfs.cpp"
|
|
||||||
#include "../clients/ogre_archive.hpp"
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
using namespace Ogre;
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
void print(StringVectorPtr lst)
|
|
||||||
{
|
|
||||||
int s = lst->size();
|
|
||||||
|
|
||||||
for(int i=0; i<s; i++)
|
|
||||||
{
|
|
||||||
cout << " " << (*lst)[i] << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
VFSPtr vfs(new DummyVFS());
|
|
||||||
MangleArchive arc(vfs, "dummy");
|
|
||||||
|
|
||||||
cout << "Case: " << arc.isCaseSensitive() << endl;
|
|
||||||
cout << "Name: " << arc.getName() << endl;
|
|
||||||
cout << "Type: " << arc.getType() << endl;
|
|
||||||
cout << "All files:\n";
|
|
||||||
print(arc.list());
|
|
||||||
cout << "Non-recursive:\n";
|
|
||||||
print(arc.list(false, false));
|
|
||||||
cout << "Dirs:\n";
|
|
||||||
print(arc.list(false, true));
|
|
||||||
|
|
||||||
DataStreamPtr file = arc.open("file1");
|
|
||||||
|
|
||||||
cout << "filesize: " << file->size() << endl;
|
|
||||||
cout << "contents: " << file->getAsString() << endl;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,61 +0,0 @@
|
|||||||
#include <iostream>
|
|
||||||
#include <OgreRoot.h>
|
|
||||||
#include <OgreResourceGroupManager.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
This isn't really a test of our implementation, but a test of using
|
|
||||||
the Ogre resource system to find files. If the Ogre interface
|
|
||||||
changes and you have to change this test, you will have to change
|
|
||||||
the servers/ogre_vfs.cpp implementation equivalently.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace Ogre;
|
|
||||||
|
|
||||||
ResourceGroupManager *gm;
|
|
||||||
String group;
|
|
||||||
|
|
||||||
void find(const std::string &fileName)
|
|
||||||
{
|
|
||||||
cout << "\nFile: " << fileName << endl;
|
|
||||||
|
|
||||||
if(!gm->resourceExists(group, fileName))
|
|
||||||
{
|
|
||||||
cout << "Does not exist\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DataStreamPtr data = gm->openResource(fileName, group);
|
|
||||||
|
|
||||||
cout << "Size: " << data->size() << endl;
|
|
||||||
cout << "First line: " << data->getLine() << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
// Disable logging
|
|
||||||
new LogManager;
|
|
||||||
Log *log = LogManager::getSingleton().createLog("");
|
|
||||||
log->setDebugOutputEnabled(false);
|
|
||||||
|
|
||||||
// Set up Ogre
|
|
||||||
Root root("","","");
|
|
||||||
|
|
||||||
root.addResourceLocation("./", "FileSystem", "General");
|
|
||||||
|
|
||||||
gm = ResourceGroupManager::getSingletonPtr();
|
|
||||||
group = gm->getWorldResourceGroupName();
|
|
||||||
|
|
||||||
find("Makefile");
|
|
||||||
find("ogre_resource_test.cpp");
|
|
||||||
find("bleh");
|
|
||||||
|
|
||||||
cout << "\nAll source files:\n";
|
|
||||||
FileInfoListPtr list = gm->findResourceFileInfo(group, "*.cpp");
|
|
||||||
FileInfoList::iterator it, end;
|
|
||||||
it = list->begin();
|
|
||||||
end = list->end();
|
|
||||||
for(; it != end; it++)
|
|
||||||
cout << " " << it->filename << endl;
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
#include "../servers/ogre_vfs.hpp"
|
|
||||||
|
|
||||||
#include <Ogre.h>
|
|
||||||
|
|
||||||
#include "server_common.cpp"
|
|
||||||
|
|
||||||
Ogre::Root *root;
|
|
||||||
|
|
||||||
void setupOgre()
|
|
||||||
{
|
|
||||||
using namespace Ogre;
|
|
||||||
|
|
||||||
// Disable logging
|
|
||||||
new LogManager;
|
|
||||||
Log *log = LogManager::getSingleton().createLog("");
|
|
||||||
log->setDebugOutputEnabled(false);
|
|
||||||
|
|
||||||
// Set up Root
|
|
||||||
root = new Root("","","");
|
|
||||||
|
|
||||||
// Add a zip file and the current directory
|
|
||||||
root->addResourceLocation("test.zip", "Zip", "General");
|
|
||||||
root->addResourceLocation("./", "FileSystem", "General");
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
// Set up the engine
|
|
||||||
setupOgre();
|
|
||||||
|
|
||||||
// This is our entry point into the resource file system
|
|
||||||
OgreVFS vfs("General");
|
|
||||||
|
|
||||||
// Run the test
|
|
||||||
testAll(vfs);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
Listing all files:
|
|
||||||
name: file1
|
|
||||||
basename: file1
|
|
||||||
isDir: 0
|
|
||||||
size: 1
|
|
||||||
time: 0
|
|
||||||
name: dir/file2
|
|
||||||
basename: file2
|
|
||||||
isDir: 0
|
|
||||||
size: 2
|
|
||||||
time: 0
|
|
||||||
|
|
||||||
Stat for single files:
|
|
||||||
name: file1
|
|
||||||
basename: file1
|
|
||||||
isDir: 0
|
|
||||||
size: 1
|
|
||||||
time: 0
|
|
||||||
|
|
||||||
name: dir/file2
|
|
||||||
basename: file2
|
|
||||||
isDir: 0
|
|
||||||
size: 2
|
|
||||||
time: 0
|
|
||||||
|
|
||||||
name: dir
|
|
||||||
basename: dir
|
|
||||||
isDir: 1
|
|
||||||
size: 0
|
|
||||||
time: 0
|
|
||||||
filesize: 11
|
|
@ -1,12 +0,0 @@
|
|||||||
Case: 1
|
|
||||||
Name: dummy
|
|
||||||
Type: Mangle
|
|
||||||
All files:
|
|
||||||
file1
|
|
||||||
dir/file2
|
|
||||||
Non-recursive:
|
|
||||||
file1
|
|
||||||
Dirs:
|
|
||||||
dir
|
|
||||||
filesize: 11
|
|
||||||
contents: hello world
|
|
@ -1,20 +0,0 @@
|
|||||||
|
|
||||||
File: Makefile
|
|
||||||
Size: 828
|
|
||||||
First line: GCC=g++ -I../
|
|
||||||
|
|
||||||
File: ogre_resource_test.cpp
|
|
||||||
Size: 1437
|
|
||||||
First line: #include <iostream>
|
|
||||||
|
|
||||||
File: bleh
|
|
||||||
Does not exist
|
|
||||||
|
|
||||||
All source files:
|
|
||||||
physfs_server_test.cpp
|
|
||||||
dummy_test.cpp
|
|
||||||
ogre_resource_test.cpp
|
|
||||||
server_common.cpp
|
|
||||||
dummy_vfs.cpp
|
|
||||||
ogre_client_test.cpp
|
|
||||||
ogre_server_test.cpp
|
|
@ -1,11 +0,0 @@
|
|||||||
|
|
||||||
File: Makefile
|
|
||||||
Size: 828
|
|
||||||
First 12 bytes: GCC=g++ -I..
|
|
||||||
|
|
||||||
File: testfile.txt
|
|
||||||
Size: 13
|
|
||||||
First 12 bytes: hello world!
|
|
||||||
|
|
||||||
File: blah_bleh
|
|
||||||
File doesn't exist
|
|
@ -1,11 +0,0 @@
|
|||||||
|
|
||||||
File: Makefile
|
|
||||||
Size: 828
|
|
||||||
First 12 bytes: GCC=g++ -I..
|
|
||||||
|
|
||||||
File: testfile.txt
|
|
||||||
Size: 13
|
|
||||||
First 12 bytes: hello world!
|
|
||||||
|
|
||||||
File: blah_bleh
|
|
||||||
File doesn't exist
|
|
@ -1,21 +0,0 @@
|
|||||||
#include "../servers/physfs_vfs.hpp"
|
|
||||||
|
|
||||||
#include "server_common.cpp"
|
|
||||||
|
|
||||||
#include <physfs.h>
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
// Set up the library and paths
|
|
||||||
PHYSFS_init("blah");
|
|
||||||
PHYSFS_addToSearchPath("test.zip", 1);
|
|
||||||
PHYSFS_addToSearchPath("./", 1);
|
|
||||||
|
|
||||||
// Create our interface
|
|
||||||
PhysVFS vfs;
|
|
||||||
|
|
||||||
// Run the test
|
|
||||||
testAll(vfs);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
#include <iostream>
|
|
||||||
|
|
||||||
using namespace Mangle::VFS;
|
|
||||||
using namespace Mangle::Stream;
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
void find(VFS &vfs, const std::string &file)
|
|
||||||
{
|
|
||||||
cout << "\nFile: " << file << endl;
|
|
||||||
|
|
||||||
if(!vfs.isFile(file))
|
|
||||||
{
|
|
||||||
cout << "File doesn't exist\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
StreamPtr data = vfs.open(file);
|
|
||||||
|
|
||||||
cout << "Size: " << data->size() << endl;
|
|
||||||
|
|
||||||
char buf[13];
|
|
||||||
buf[12] = 0;
|
|
||||||
data->read(buf, 12);
|
|
||||||
|
|
||||||
cout << "First 12 bytes: " << buf << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
void testAll(VFS &vfs)
|
|
||||||
{
|
|
||||||
find(vfs, "Makefile"); // From the file system
|
|
||||||
find(vfs, "testfile.txt"); // From the zip
|
|
||||||
find(vfs, "blah_bleh"); // Doesn't exist
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
make || exit
|
|
||||||
|
|
||||||
mkdir -p output
|
|
||||||
|
|
||||||
PROGS=*_test
|
|
||||||
|
|
||||||
for a in $PROGS; do
|
|
||||||
if [ -f "output/$a.out" ]; then
|
|
||||||
echo "Running $a:"
|
|
||||||
./$a | diff output/$a.out -
|
|
||||||
else
|
|
||||||
echo "Creating $a.out"
|
|
||||||
./$a > "output/$a.out"
|
|
||||||
git add "output/$a.out"
|
|
||||||
fi
|
|
||||||
done
|
|
Binary file not shown.
@ -1,87 +0,0 @@
|
|||||||
#ifndef MANGLE_VFS_H
|
|
||||||
#define MANGLE_VFS_H
|
|
||||||
|
|
||||||
#include "../stream/stream.hpp"
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace Mangle {
|
|
||||||
namespace VFS {
|
|
||||||
|
|
||||||
/// Generic file info structure
|
|
||||||
struct FileInfo
|
|
||||||
{
|
|
||||||
/// Full name, including path
|
|
||||||
std::string name;
|
|
||||||
|
|
||||||
/// Base name, not including path
|
|
||||||
std::string basename;
|
|
||||||
|
|
||||||
/// Is this a directory?
|
|
||||||
bool isDir;
|
|
||||||
|
|
||||||
/// File size
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
/// Last modification date
|
|
||||||
time_t time;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::vector<FileInfo> FileInfoList;
|
|
||||||
|
|
||||||
typedef boost::shared_ptr<FileInfo> FileInfoPtr;
|
|
||||||
typedef boost::shared_ptr<FileInfoList> FileInfoListPtr;
|
|
||||||
|
|
||||||
/** An interface to any file system or other provider of named data
|
|
||||||
streams
|
|
||||||
*/
|
|
||||||
class VFS
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// Feature options. These should be set in the constructor.
|
|
||||||
|
|
||||||
/// If true, the list() function work
|
|
||||||
bool hasList;
|
|
||||||
|
|
||||||
/// If true, the find() function work
|
|
||||||
bool hasFind;
|
|
||||||
|
|
||||||
/// If true, the file system is case sensitive
|
|
||||||
bool isCaseSensitive;
|
|
||||||
|
|
||||||
/// Virtual destructor
|
|
||||||
virtual ~VFS() {}
|
|
||||||
|
|
||||||
/// Open a new data stream. Deleting the object (letting all the
|
|
||||||
/// pointers to it go out of scope) should be enough to close it.
|
|
||||||
virtual Stream::StreamPtr open(const std::string &name) = 0;
|
|
||||||
|
|
||||||
/// Check for the existence of a file
|
|
||||||
virtual bool isFile(const std::string &name) const = 0;
|
|
||||||
|
|
||||||
/// Check for the existence of a directory
|
|
||||||
virtual bool isDir(const std::string &name) const = 0;
|
|
||||||
|
|
||||||
/// Get info about a single file
|
|
||||||
virtual FileInfoPtr stat(const std::string &name) const = 0;
|
|
||||||
|
|
||||||
/// List all entries in a given directory. A blank dir should be
|
|
||||||
/// interpreted as a the root/current directory of the archive. If
|
|
||||||
/// dirs is true, list directories instead of files.
|
|
||||||
virtual FileInfoListPtr list(const std::string& dir = "",
|
|
||||||
bool recurse=true,
|
|
||||||
bool dirs=false) const = 0;
|
|
||||||
|
|
||||||
/// Find files after a given pattern. Wildcards (*) are
|
|
||||||
/// supported. Only valid if 'hasFind' is true. Don't implement your
|
|
||||||
/// own pattern matching here if the backend doesn't support it
|
|
||||||
/// natively; use a filter instead.
|
|
||||||
virtual FileInfoListPtr find(const std::string& pattern,
|
|
||||||
bool recursive=true,
|
|
||||||
bool dirs=false) const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef boost::shared_ptr<VFS> VFSPtr;
|
|
||||||
|
|
||||||
}} // namespaces
|
|
||||||
#endif
|
|
Loading…
Reference in New Issue