Optimize overall memory usage

* Fixes in otbm loader
* Rework BinaryTree
This commit is contained in:
Eduardo Bart
2012-07-15 10:23:13 -03:00
parent 03ca792dbd
commit 7a08fed689
25 changed files with 376 additions and 186 deletions

View File

@@ -23,21 +23,54 @@
#include "binarytree.h"
#include "filestream.h"
void BinaryTree::unserialize(const FileStreamPtr& fin)
BinaryTree::BinaryTree(const FileStreamPtr& fin) :
m_fin(fin), m_pos(0xFFFFFFFF)
{
m_startPos = fin->tell();
}
BinaryTree::~BinaryTree()
{
}
void BinaryTree::skipNodes()
{
while(true) {
uint8 byte = fin->getU8();
uint8 byte = m_fin->getU8();
switch(byte) {
case BINARYTREE_NODE_START: {
BinaryTreePtr node(new BinaryTree(shared_from_this()));
m_children.push_back(node);
node->unserialize(fin);
skipNodes();
break;
}
case BINARYTREE_NODE_END:
return;
case BINARYTREE_ESCAPE_CHAR:
m_buffer.add(fin->getU8());
m_fin->getU8();
break;
default:
break;
}
}
}
void BinaryTree::unserialize()
{
if(m_pos != 0xFFFFFFFF)
return;
m_pos = 0;
m_fin->seek(m_startPos);
while(true) {
uint8 byte = m_fin->getU8();
switch(byte) {
case BINARYTREE_NODE_START: {
skipNodes();
break;
}
case BINARYTREE_NODE_END:
return;
case BINARYTREE_ESCAPE_CHAR:
m_buffer.add(m_fin->getU8());
break;
default:
m_buffer.add(byte);
@@ -46,13 +79,33 @@ void BinaryTree::unserialize(const FileStreamPtr& fin)
}
}
void BinaryTree::serialize(const FileStreamPtr& fin)
BinaryTreeVec BinaryTree::getChildren()
{
BinaryTreeVec children;
m_fin->seek(m_startPos);
while(true) {
uint8 byte = m_fin->getU8();
switch(byte) {
case BINARYTREE_NODE_START: {
BinaryTreePtr node(new BinaryTree(m_fin));
children.push_back(node);
node->skipNodes();
break;
}
case BINARYTREE_NODE_END:
return children;
case BINARYTREE_ESCAPE_CHAR:
m_fin->getU8();
break;
default:
break;
}
}
}
void BinaryTree::seek(uint pos)
{
unserialize();
if(pos > m_buffer.size())
stdext::throw_exception("BinaryTree: seek failed");
m_pos = pos;
@@ -60,6 +113,7 @@ void BinaryTree::seek(uint pos)
uint8 BinaryTree::getU8()
{
unserialize();
if(m_pos+1 > m_buffer.size())
stdext::throw_exception("BinaryTree: getU8 failed");
uint8 v = m_buffer[m_pos];
@@ -69,6 +123,7 @@ uint8 BinaryTree::getU8()
uint16 BinaryTree::getU16()
{
unserialize();
if(m_pos+2 > m_buffer.size())
stdext::throw_exception("BinaryTree: getU16 failed");
uint16 v = stdext::readLE16(&m_buffer[m_pos]);
@@ -78,6 +133,7 @@ uint16 BinaryTree::getU16()
uint32 BinaryTree::getU32()
{
unserialize();
if(m_pos+4 > m_buffer.size())
stdext::throw_exception("BinaryTree: getU32 failed");
uint32 v = stdext::readLE32(&m_buffer[m_pos]);
@@ -87,6 +143,7 @@ uint32 BinaryTree::getU32()
uint64 BinaryTree::getU64()
{
unserialize();
if(m_pos+8 > m_buffer.size())
stdext::throw_exception("BinaryTree: getU64 failed");
uint64 v = stdext::readLE64(&m_buffer[m_pos]);
@@ -96,10 +153,8 @@ uint64 BinaryTree::getU64()
std::string BinaryTree::getString()
{
unserialize();
uint16 len = getU16();
if(len == 0 || len > 8192)
stdext::throw_exception("BinaryTree: getString failed: invalid or too large string length");
if(m_pos+len > m_buffer.size())
stdext::throw_exception("BinaryTree: getString failed: string length exceeded buffer size.");

View File

@@ -32,18 +32,16 @@ enum {
BINARYTREE_NODE_END = 0xFF
};
class BinaryTree : public std::enable_shared_from_this<BinaryTree>
class BinaryTree
{
public:
BinaryTree(const BinaryTreePtr& parent = nullptr) : m_pos(0), m_parent(parent) { }
void unserialize(const FileStreamPtr& fin);
void serialize(const FileStreamPtr& fin);
BinaryTree(const FileStreamPtr& fin);
~BinaryTree();
void seek(uint pos);
void skip(uint len) { seek(tell() + len); }
uint tell() { return m_pos; }
uint size() { return m_buffer.size(); }
uint size() { unserialize(); return m_buffer.size(); }
uint8 getU8();
uint16 getU16();
@@ -51,16 +49,17 @@ public:
uint64 getU64();
std::string getString();
BinaryTreeVec getChildren() { return m_children; }
BinaryTreePtr getParent() { return m_parent.lock(); }
bool canRead() { return m_pos < m_buffer.size(); }
BinaryTreeVec getChildren();
bool canRead() { unserialize(); return m_pos < m_buffer.size(); }
private:
uint m_pos;
void unserialize();
void skipNodes();
BinaryTreeVec m_children;
BinaryTreeWeakPtr m_parent;
FileStreamPtr m_fin;
DataBuffer<uint8> m_buffer;
uint m_pos;
uint m_startPos;
};
#endif

View File

@@ -143,7 +143,7 @@ void FileStream::skip(uint len)
seek(tell() + len);
}
int FileStream::size()
uint FileStream::size()
{
if(!m_caching)
return PHYSFS_fileLength(m_fileHandle);
@@ -151,7 +151,7 @@ int FileStream::size()
return m_data.size();
}
int FileStream::tell()
uint FileStream::tell()
{
if(!m_caching)
return PHYSFS_tell(m_fileHandle);
@@ -249,13 +249,11 @@ std::string FileStream::getString()
BinaryTreePtr FileStream::getBinaryTree()
{
BinaryTreePtr root = BinaryTreePtr(new BinaryTree);
uint8 byte = getU8();
if(byte == BINARYTREE_NODE_START)
root->unserialize(asFileStream());
else
if(byte != BINARYTREE_NODE_START)
stdext::throw_exception(stdext::format("failed to read node start (getBinaryTree): %d", byte));
return root;
return BinaryTreePtr(new BinaryTree(asFileStream()));
}
void FileStream::addU8(uint8 v)

View File

@@ -43,8 +43,8 @@ public:
int read(void *buffer, uint size, uint nmemb = 1);
void seek(uint pos);
void skip(uint len);
int size();
int tell();
uint size();
uint tell();
std::string name() { return m_name; }
uint8 getU8();