forked from mirror/openmw-tes3mp
Finished memory and buffer streams (for now)
This commit is contained in:
parent
c7701ace82
commit
aafe01dccc
4 changed files with 97 additions and 9 deletions
|
@ -2,20 +2,63 @@
|
||||||
#define MANGLE_STREAM_BUFFER_H
|
#define MANGLE_STREAM_BUFFER_H
|
||||||
|
|
||||||
#include "../servers/memory_stream.h"
|
#include "../servers/memory_stream.h"
|
||||||
#include "../clients/iwrapper.h"
|
#include <vector>
|
||||||
|
|
||||||
namespace Mangle {
|
namespace Mangle {
|
||||||
namespace Stream {
|
namespace Stream {
|
||||||
|
|
||||||
/** A Stream that reads another Stream into a buffer, and serves it as
|
/** A Stream that reads another Stream into a buffer, and serves it as
|
||||||
a MemoryStream.
|
a MemoryStream. Might be expanded with other capabilities later.
|
||||||
*/
|
*/
|
||||||
class BufferStream : public MemoryStream
|
class BufferStream : public MemoryStream
|
||||||
{
|
{
|
||||||
|
std::vector<char> buffer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BufferStream(Stream *input)
|
BufferStream(Stream *input)
|
||||||
{
|
{
|
||||||
// Allocate memory, read the stream into it. Then call set()
|
// 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.
|
||||||
|
const int ADD = 32*1024;
|
||||||
|
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 || 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());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3,15 +3,14 @@
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "../stream.h"
|
#include "../stream.h"
|
||||||
#include <boost/smart_ptr.h>
|
|
||||||
|
|
||||||
namespace Mangle {
|
namespace Mangle {
|
||||||
namespace Stream {
|
namespace Stream {
|
||||||
|
|
||||||
// Do this before the class declaration, since the class itself
|
// Do this before the class declaration, since the class itself
|
||||||
// depends on it
|
// depends on it. TODO: Postponed for later
|
||||||
class MemoryStream;
|
//class MemoryStream;
|
||||||
typedef boost::shared_ptr<MemoryStream> MemoryStreamPtr;
|
//typedef boost::shared_ptr<MemoryStream> MemoryStreamPtr;
|
||||||
|
|
||||||
/** A Stream wrapping a memory buffer
|
/** A Stream wrapping a memory buffer
|
||||||
|
|
||||||
|
@ -33,7 +32,7 @@ class MemoryStream : public Stream
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryStream()
|
MemoryStream()
|
||||||
: data(NULL), length(0), pos(0);
|
: data(NULL), length(0), pos(0)
|
||||||
{
|
{
|
||||||
isSeekable = true;
|
isSeekable = true;
|
||||||
hasPosition = true;
|
hasPosition = true;
|
||||||
|
@ -89,10 +88,12 @@ class MemoryStream : public Stream
|
||||||
|
|
||||||
No memory is copied during this operation, the new stream is
|
No memory is copied during this operation, the new stream is
|
||||||
just another 'view' into the same shared memory buffer.
|
just another 'view' into the same shared memory buffer.
|
||||||
|
|
||||||
|
TODO: Rewrite to use smart pointers
|
||||||
*/
|
*/
|
||||||
MemoryStreamPtr clone(bool setPos=false) const
|
MemoryStream* clone(bool setPos=false) const
|
||||||
{
|
{
|
||||||
MemoryStreamPtr res = new MemoryStream(data, length);
|
MemoryStream* res = new MemoryStream(data, length);
|
||||||
if(setPos) res->seek(pos);
|
if(setPos) res->seek(pos);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,5 +15,8 @@ audiere_client_test: audiere_client_test.cpp ../stream.h ../clients/iwrapper.h .
|
||||||
memory_test: memory_test.cpp ../stream.h ../servers/memory_stream.h
|
memory_test: memory_test.cpp ../stream.h ../servers/memory_stream.h
|
||||||
$(GCC) $< -o $@
|
$(GCC) $< -o $@
|
||||||
|
|
||||||
|
buffer_test: buffer_test.cpp ../stream.h ../servers/memory_stream.h ../filters/buffer_stream.h
|
||||||
|
$(GCC) $< -o $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm *_test
|
rm *_test
|
||||||
|
|
41
stream/tests/buffer_test.cpp
Normal file
41
stream/tests/buffer_test.cpp
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "../filters/buffer_stream.h"
|
||||||
|
|
||||||
|
using namespace Mangle::Stream;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
Stream *orig = new MemoryStream("hello world", 11);
|
||||||
|
Stream *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;
|
||||||
|
}
|
Loading…
Reference in a new issue