Added: #1440 Simple library for serializing max storage through an IStream
--HG-- branch : build_pipeline_v3hg/feature/build_pipeline_v3
parent
9beb31bac4
commit
635092b0db
@ -0,0 +1,189 @@
|
|||||||
|
/**
|
||||||
|
* \file storage_chunks.cpp
|
||||||
|
* \brief CStorageChunks
|
||||||
|
* \date 2012-08-18 09:20GMT
|
||||||
|
* \author Jan Boon (Kaetemi)
|
||||||
|
* CStorageChunks
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2012 by authors
|
||||||
|
*
|
||||||
|
* This file is part of RYZOM CORE PIPELINE.
|
||||||
|
* RYZOM CORE PIPELINE is free software: you can redistribute it
|
||||||
|
* and/or modify it under the terms of the GNU Affero General Public
|
||||||
|
* License as published by the Free Software Foundation, either
|
||||||
|
* version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* RYZOM CORE PIPELINE is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||||
|
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
* License along with RYZOM CORE PIPELINE. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <nel/misc/types_nl.h>
|
||||||
|
#include "storage_chunks.h"
|
||||||
|
|
||||||
|
// STL includes
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/misc/debug.h>
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
|
||||||
|
// using namespace std;
|
||||||
|
// using namespace NLMISC;
|
||||||
|
|
||||||
|
// #define NL_DEBUG_STORAGE
|
||||||
|
|
||||||
|
namespace PIPELINE {
|
||||||
|
namespace MAX {
|
||||||
|
|
||||||
|
CStorageChunks::CStorageChunks(NLMISC::IStream &stream, sint64 size) : m_Stream(stream), m_Is64Bit(false)
|
||||||
|
{
|
||||||
|
if (size >= 2147483647L)
|
||||||
|
throw NLMISC::EStream("64bit chunks not supported");
|
||||||
|
m_Chunks.reserve(64);
|
||||||
|
m_Chunks.resize(1);
|
||||||
|
m_Chunks[0].HeaderSize = 0;
|
||||||
|
m_Chunks[0].OffsetBegin = stream.getPos();
|
||||||
|
if (stream.isReading())
|
||||||
|
{
|
||||||
|
m_Chunks[0].Id = 0;
|
||||||
|
m_Chunks[0].Size = 0x80000000 | (uint32)(size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_Chunks[0].Id = 1;
|
||||||
|
m_Chunks[0].Size = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CStorageChunks::~CStorageChunks()
|
||||||
|
{
|
||||||
|
#ifdef NL_DEBUG_STORAGE
|
||||||
|
if (m_Chunks.size() != 1)
|
||||||
|
nldebug("Not all chunks were closed");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CStorageChunks::enterChunk()
|
||||||
|
{
|
||||||
|
if (m_Stream.isReading())
|
||||||
|
{
|
||||||
|
// input logic
|
||||||
|
if (!isChunkContainer())
|
||||||
|
{
|
||||||
|
#ifdef NL_DEBUG_STORAGE
|
||||||
|
nldebug("Current chunk is not a container, cannot enter");
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (endOfChunk())
|
||||||
|
{
|
||||||
|
#ifdef NL_DEBUG_STORAGE
|
||||||
|
nldebug("End of chunk, cannot enter");
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_Chunks.resize(m_Chunks.size() + 1);
|
||||||
|
CChunk *chunk = currentChunk();
|
||||||
|
chunk->OffsetBegin = m_Stream.getPos();
|
||||||
|
m_Stream.serial(chunk->Id);
|
||||||
|
m_Stream.serial(chunk->Size);
|
||||||
|
chunk->HeaderSize = 6;
|
||||||
|
if (chunk->Size == 0)
|
||||||
|
{
|
||||||
|
// this is a 64bit chunk
|
||||||
|
uint64 size64;
|
||||||
|
m_Stream.serial(size64);
|
||||||
|
chunk->HeaderSize += 8;
|
||||||
|
bool iscont = (size64 & 0x8000000000000000) == 0x8000000000000000;
|
||||||
|
size64 &= 0x7FFFFFFFFFFFFFFF;
|
||||||
|
if (size64 >= 2147483647L)
|
||||||
|
throw NLMISC::EStream("64bit chunks not supported");
|
||||||
|
// downgrade to 32 bit chunk
|
||||||
|
chunk->Size = (uint32)size64;
|
||||||
|
if (iscont) chunk->Size |= 0x80000000;
|
||||||
|
m_Is64Bit = true; // it's true
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef NL_DEBUG_STORAGE
|
||||||
|
nldebug("No input, this function cannot output, throw exception");
|
||||||
|
#endif
|
||||||
|
throw NLMISC::EStream();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CStorageChunks::enterChunk(uint16 id, bool container)
|
||||||
|
{
|
||||||
|
if (!m_Stream.isReading())
|
||||||
|
{
|
||||||
|
if (m_Is64Bit)
|
||||||
|
throw NLMISC::EStream("64bit chunks not supported");
|
||||||
|
|
||||||
|
// enter the new chunk
|
||||||
|
m_Chunks.resize(m_Chunks.size() + 1);
|
||||||
|
CChunk *chunk = currentChunk();
|
||||||
|
uint32 sizeDummy = 0xFFFFFFFF;
|
||||||
|
chunk->Id = container ? 1 : 0;
|
||||||
|
chunk->OffsetBegin = m_Stream.getPos(); // store current pos
|
||||||
|
|
||||||
|
// write header
|
||||||
|
m_Stream.serial(id); // write the id
|
||||||
|
m_Stream.serial(sizeDummy); // write 32 bit size placeholder
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else // input or exception
|
||||||
|
{
|
||||||
|
while (enterChunk())
|
||||||
|
{
|
||||||
|
if (getChunkId() == id)
|
||||||
|
return true;
|
||||||
|
leaveChunk(); // skip data
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sint32 CStorageChunks::leaveChunk()
|
||||||
|
{
|
||||||
|
if (m_Stream.isReading())
|
||||||
|
{
|
||||||
|
// input logic
|
||||||
|
sint32 skipped = currentChunk()->endOfChunk() - m_Stream.getPos();
|
||||||
|
if (skipped)
|
||||||
|
{
|
||||||
|
m_Stream.seek(currentChunk()->endOfChunk(), NLMISC::IStream::begin);
|
||||||
|
#ifdef NL_DEBUG_STORAGE
|
||||||
|
nldebug("Skipped %i bytes in the current chunk", skipped);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
m_Chunks.resize(m_Chunks.size() - 1);
|
||||||
|
return skipped;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sint32 pos = m_Stream.getPos();
|
||||||
|
sint32 sizeWithHeader = pos - currentChunk()->OffsetBegin;
|
||||||
|
sint32 sizePos = currentChunk()->OffsetBegin + 2;
|
||||||
|
m_Stream.seek(sizePos, NLMISC::IStream::begin); // hopefully this correctly overwrites!!!
|
||||||
|
uint32 sizeField = (uint32)sizeWithHeader | (uint32)currentChunk()->Id << 31; // add container flag
|
||||||
|
m_Stream.serial(sizeField);
|
||||||
|
m_Stream.seek(pos, NLMISC::IStream::begin);
|
||||||
|
m_Chunks.resize(m_Chunks.size() - 1);
|
||||||
|
return sizeWithHeader;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace MAX */
|
||||||
|
} /* namespace PIPELINE */
|
||||||
|
|
||||||
|
/* end of file */
|
@ -0,0 +1,107 @@
|
|||||||
|
/**
|
||||||
|
* \file storage_chunks.h
|
||||||
|
* \brief CStorageChunks
|
||||||
|
* \date 2012-08-18 09:20GMT
|
||||||
|
* \author Jan Boon (Kaetemi)
|
||||||
|
* CStorageChunks
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2012 by authors
|
||||||
|
*
|
||||||
|
* This file is part of RYZOM CORE PIPELINE.
|
||||||
|
* RYZOM CORE PIPELINE is free software: you can redistribute it
|
||||||
|
* and/or modify it under the terms of the GNU Affero General Public
|
||||||
|
* License as published by the Free Software Foundation, either
|
||||||
|
* version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* RYZOM CORE PIPELINE is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||||
|
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
* License along with RYZOM CORE PIPELINE. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PIPELINE_STORAGE_CHUNKS_H
|
||||||
|
#define PIPELINE_STORAGE_CHUNKS_H
|
||||||
|
#include <nel/misc/types_nl.h>
|
||||||
|
|
||||||
|
// STL includes
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/misc/stream.h>
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
|
||||||
|
namespace PIPELINE {
|
||||||
|
namespace MAX {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief CStorageChunks
|
||||||
|
* \date 2012-08-18 09:20GMT
|
||||||
|
* \author Jan Boon (Kaetemi)
|
||||||
|
* CStorageChunks
|
||||||
|
*/
|
||||||
|
class CStorageChunks
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
struct CChunk
|
||||||
|
{
|
||||||
|
// Size of the chunk header, 6 for 32 bit, 14 for 64 bit
|
||||||
|
uint8 HeaderSize;
|
||||||
|
// Where the header starts
|
||||||
|
sint32 OffsetBegin;
|
||||||
|
|
||||||
|
// Identifier
|
||||||
|
uint16 Id;
|
||||||
|
// Size including header size
|
||||||
|
uint32 Size;
|
||||||
|
|
||||||
|
inline sint32 getSizeWithHeader() const { return (sint32)(Size & 0x7FFFFFFF); }
|
||||||
|
inline sint32 getSize() const { return getSizeWithHeader() - (sint32)HeaderSize; }
|
||||||
|
inline bool isContainer() const { return (Size & 0x80000000) == 0x80000000; }
|
||||||
|
inline sint32 endOfChunk() const { return OffsetBegin + getSizeWithHeader(); }
|
||||||
|
inline sint32 getDataBegin() const { return OffsetBegin + (sint32)HeaderSize; }
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
CStorageChunks(NLMISC::IStream &stream, sint64 size = 0);
|
||||||
|
virtual ~CStorageChunks();
|
||||||
|
|
||||||
|
// Returns true if there's another chunk, false if no more chunks in this container or if the current chunk is not a container
|
||||||
|
bool enterChunk();
|
||||||
|
// Reads and skips chunks until the one with given id is found, or writes a chunk with this id
|
||||||
|
bool enterChunk(uint16 id, bool container);
|
||||||
|
// Returns the number of skipped bytes in read more, returns chunk size including header in write mode
|
||||||
|
sint32 leaveChunk();
|
||||||
|
|
||||||
|
inline bool is64Bit() const { return m_Is64Bit; }
|
||||||
|
inline void set64Bit(bool enabled = true) { m_Is64Bit = enabled; }
|
||||||
|
|
||||||
|
inline uint16 getChunkId() const { return currentChunk()->Id; }
|
||||||
|
inline sint32 getChunkSize() const { return currentChunk()->getSize(); }
|
||||||
|
inline bool isChunkContainer() const { return currentChunk()->isContainer(); }
|
||||||
|
inline bool endOfChunk() const { return /*m_Chunks.size() == 1 ? eof() :*/ m_Stream.getPos() >= currentChunk()->endOfChunk(); }
|
||||||
|
|
||||||
|
inline NLMISC::IStream &stream() { return m_Stream; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
inline const CChunk *currentChunk() const { return &m_Chunks[m_Chunks.size() - 1]; }
|
||||||
|
inline CChunk *currentChunk() { return &m_Chunks[m_Chunks.size() - 1]; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
NLMISC::IStream &m_Stream;
|
||||||
|
std::vector<CChunk> m_Chunks;
|
||||||
|
bool m_Is64Bit;
|
||||||
|
|
||||||
|
}; /* class CStorageChunks */
|
||||||
|
|
||||||
|
} /* namespace MAX */
|
||||||
|
} /* namespace PIPELINE */
|
||||||
|
|
||||||
|
#endif /* #ifndef PIPELINE_STORAGE_CHUNKS_H */
|
||||||
|
|
||||||
|
/* end of file */
|
@ -0,0 +1,236 @@
|
|||||||
|
/**
|
||||||
|
* \file storage_object.cpp
|
||||||
|
* \brief CStorageObject
|
||||||
|
* \date 2012-08-18 09:02GMT
|
||||||
|
* \author Jan Boon (Kaetemi)
|
||||||
|
* CStorageObject
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2012 by authors
|
||||||
|
*
|
||||||
|
* This file is part of RYZOM CORE PIPELINE.
|
||||||
|
* RYZOM CORE PIPELINE is free software: you can redistribute it
|
||||||
|
* and/or modify it under the terms of the GNU Affero General Public
|
||||||
|
* License as published by the Free Software Foundation, either
|
||||||
|
* version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* RYZOM CORE PIPELINE is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||||
|
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
* License along with RYZOM CORE PIPELINE. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <nel/misc/types_nl.h>
|
||||||
|
#include "storage_object.h"
|
||||||
|
|
||||||
|
// STL includes
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
// #include <nel/misc/debug.h>
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "storage_stream.h"
|
||||||
|
#include "storage_chunks.h"
|
||||||
|
|
||||||
|
// using namespace std;
|
||||||
|
// using namespace NLMISC;
|
||||||
|
|
||||||
|
#define NL_DEBUG_STORAGE
|
||||||
|
|
||||||
|
namespace PIPELINE {
|
||||||
|
namespace MAX {
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
std::string IStorageObject::toString()
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
toString(ss);
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IStorageObject::setSize(sint32 size)
|
||||||
|
{
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IStorageObject::getSize(sint32 &size) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IStorageObject::isContainer() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
std::string CStorageContainer::getClassName() // why is this not const in IClassable?
|
||||||
|
{
|
||||||
|
return "StorageContainer";
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStorageContainer::serial(NLMISC::IStream &stream)
|
||||||
|
{
|
||||||
|
if (stream.getPos() == 0)
|
||||||
|
{
|
||||||
|
CStorageStream *storageStream = dynamic_cast<CStorageStream *>(&stream);
|
||||||
|
if (storageStream)
|
||||||
|
{
|
||||||
|
// implicitly assume the entire stream is the container
|
||||||
|
CStorageChunks chunks(stream, stream.isReading() ? storageStream->size() : 0);
|
||||||
|
serial(chunks);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// wrapping the container inside a stream with necessary size markers
|
||||||
|
{
|
||||||
|
const uint32 magic = 0xC0C01473;
|
||||||
|
stream.serialCheck(magic);
|
||||||
|
uint version = stream.serialVersion(1);
|
||||||
|
sint32 sizePos;
|
||||||
|
bool reading = stream.isReading();
|
||||||
|
if (!reading)
|
||||||
|
sizePos = stream.getPos();
|
||||||
|
sint64 size = 0;
|
||||||
|
stream.serial(size);
|
||||||
|
CStorageChunks chunks(stream, size);
|
||||||
|
serial(chunks);
|
||||||
|
if (!reading)
|
||||||
|
{
|
||||||
|
sint32 returnPos = stream.getPos();
|
||||||
|
stream.seek(sizePos, NLMISC::IStream::begin);
|
||||||
|
stream.serial(size);
|
||||||
|
stream.seek(returnPos, NLMISC::IStream::begin);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStorageContainer::toString(std::ostream &ostream, const std::string &pad)
|
||||||
|
{
|
||||||
|
// note: only use pad when multi-lining
|
||||||
|
// like Blah: (Something) "SingleValue"
|
||||||
|
// Blahblah: (Container) {
|
||||||
|
// Moo: (Foo) "What" }
|
||||||
|
// only increase pad when multi-lining sub-items
|
||||||
|
ostream << "(" << getClassName() << ") { ";
|
||||||
|
std::string padpad = pad + "\t";
|
||||||
|
for (TStorageObjectContainer::const_iterator it = Chunks.begin(), end = Chunks.end(); it != end; ++it)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << std::hex << std::setfill('0');
|
||||||
|
ss << std::setw(4) << it->first;
|
||||||
|
ostream << "\n" << pad << "0x" << ss.str() << ": ";
|
||||||
|
it->second->toString(ostream, padpad);
|
||||||
|
}
|
||||||
|
ostream << "} ";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CStorageContainer::isContainer() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStorageContainer::serial(CStorageChunks &chunks)
|
||||||
|
{
|
||||||
|
if (chunks.stream().isReading())
|
||||||
|
{
|
||||||
|
#ifdef NL_DEBUG_STORAGE
|
||||||
|
if (Chunks.size())
|
||||||
|
{
|
||||||
|
nldebug("Storage container not empty, clearing");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
Chunks.clear();
|
||||||
|
while (chunks.enterChunk())
|
||||||
|
{
|
||||||
|
uint16 id = chunks.getChunkId();
|
||||||
|
IStorageObject *storageObject = createChunkById(id, chunks.isChunkContainer());
|
||||||
|
storageObject->setSize(chunks.getChunkSize());
|
||||||
|
if (storageObject->isContainer()) static_cast<CStorageContainer *>(storageObject)->serial(chunks);
|
||||||
|
else storageObject->serial(chunks.stream());
|
||||||
|
Chunks.push_back(TStorageObjectWithId(id, storageObject));
|
||||||
|
if (chunks.leaveChunk()) // bytes were skipped while reading
|
||||||
|
throw EStorage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (TStorageObjectContainer::iterator it = Chunks.begin(), end = Chunks.end(); it != end; ++it)
|
||||||
|
{
|
||||||
|
chunks.enterChunk(it->first, it->second->isContainer());
|
||||||
|
it->second->serial(chunks.stream());
|
||||||
|
chunks.leaveChunk();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IStorageObject *CStorageContainer::createChunkById(uint16 id, bool container)
|
||||||
|
{
|
||||||
|
if (container)
|
||||||
|
{
|
||||||
|
return new CStorageContainer();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new CStorageRaw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
std::string CStorageRaw::getClassName()
|
||||||
|
{
|
||||||
|
return "StorageRaw";
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStorageRaw::serial(NLMISC::IStream &stream)
|
||||||
|
{
|
||||||
|
stream.serialBuffer(&Value[0], Value.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStorageRaw::toString(std::ostream &ostream, const std::string &pad)
|
||||||
|
{
|
||||||
|
// note: only use pad when multi-lining
|
||||||
|
// like Blah: (Something) "SingleValue"
|
||||||
|
// Blahblah: (Container) {
|
||||||
|
// Moo: (Foo) "What" }
|
||||||
|
// only increase pad when multi-lining sub-items
|
||||||
|
ostream << "(" << getClassName() << ") { ";
|
||||||
|
|
||||||
|
ostream << "} ";
|
||||||
|
}
|
||||||
|
|
||||||
|
void CStorageRaw::setSize(sint32 size)
|
||||||
|
{
|
||||||
|
Value.resize(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CStorageRaw::getSize(sint32 &size) const
|
||||||
|
{
|
||||||
|
size = Value.size();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
} /* namespace MAX */
|
||||||
|
} /* namespace PIPELINE */
|
||||||
|
|
||||||
|
/* end of file */
|
@ -0,0 +1,143 @@
|
|||||||
|
/**
|
||||||
|
* \file storage_object.h
|
||||||
|
* \brief CStorageObject
|
||||||
|
* \date 2012-08-18 09:02GMT
|
||||||
|
* \author Jan Boon (Kaetemi)
|
||||||
|
* CStorageObject
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2012 by authors
|
||||||
|
*
|
||||||
|
* This file is part of RYZOM CORE PIPELINE.
|
||||||
|
* RYZOM CORE PIPELINE is free software: you can redistribute it
|
||||||
|
* and/or modify it under the terms of the GNU Affero General Public
|
||||||
|
* License as published by the Free Software Foundation, either
|
||||||
|
* version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* RYZOM CORE PIPELINE is distributed in the hope that it will be
|
||||||
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||||
|
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public
|
||||||
|
* License along with RYZOM CORE PIPELINE. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PIPELINE_STORAGE_OBJECT_H
|
||||||
|
#define PIPELINE_STORAGE_OBJECT_H
|
||||||
|
#include <nel/misc/types_nl.h>
|
||||||
|
|
||||||
|
// STL includes
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/misc/stream.h>
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
|
||||||
|
namespace PIPELINE {
|
||||||
|
namespace MAX {
|
||||||
|
class CStorageChunks;
|
||||||
|
|
||||||
|
struct EStorage : public NLMISC::Exception
|
||||||
|
{
|
||||||
|
EStorage() : NLMISC::Exception("PIPELINE::MAX::EStorage") { }
|
||||||
|
virtual ~EStorage() throw() { }
|
||||||
|
};
|
||||||
|
|
||||||
|
// IStorageObject : exposes serial(CStorageStream &stream) and dump(const std::string &pad)
|
||||||
|
class IStorageObject : public NLMISC::IStreamable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// virtual std::string getClassName() = 0; // inherited from NLMISC::IClassable through NLMISC::IStreamable
|
||||||
|
// virtual void serial(NLMISC::IStream &stream); // inherited from NLMISC::IStreamable
|
||||||
|
std::string toString();
|
||||||
|
virtual void toString(std::ostream &ostream, const std::string &pad = "") = 0;
|
||||||
|
|
||||||
|
public: // should be protected but that doesn't compile, nice c++!
|
||||||
|
// Sets size when reading
|
||||||
|
virtual void setSize(sint32 size);
|
||||||
|
// Gets the size when writing, return false if unknown
|
||||||
|
virtual bool getSize(sint32 &size) const;
|
||||||
|
// Only true when inherting from CStorageContainer
|
||||||
|
virtual bool isContainer() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
// CStorageContainer : serializes a container chunk
|
||||||
|
class CStorageContainer : public IStorageObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// public data
|
||||||
|
typedef std::pair<uint16, IStorageObject *> TStorageObjectWithId;
|
||||||
|
typedef std::vector<TStorageObjectWithId> TStorageObjectContainer;
|
||||||
|
TStorageObjectContainer Chunks;
|
||||||
|
|
||||||
|
// inherited
|
||||||
|
virtual std::string getClassName();
|
||||||
|
virtual void serial(NLMISC::IStream &stream); // only used to wrap a container inside another stream
|
||||||
|
virtual void toString(std::ostream &ostream, const std::string &pad = "");
|
||||||
|
|
||||||
|
public: // should be protected but that doesn't compile, nice c++!
|
||||||
|
// inherited
|
||||||
|
virtual bool isContainer() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// override in subclasses, default to parent if not handled
|
||||||
|
virtual void serial(CStorageChunks &chunks);
|
||||||
|
virtual IStorageObject *createChunkById(uint16 id, bool container);
|
||||||
|
};
|
||||||
|
|
||||||
|
// CStorageRaw : serializes raw data, use for unknown data
|
||||||
|
class CStorageRaw : public IStorageObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// public data
|
||||||
|
typedef std::vector<uint8> TType;
|
||||||
|
TType Value;
|
||||||
|
|
||||||
|
// inherited
|
||||||
|
virtual std::string getClassName();
|
||||||
|
virtual void serial(NLMISC::IStream &stream);
|
||||||
|
virtual void toString(std::ostream &ostream, const std::string &pad = "");
|
||||||
|
|
||||||
|
public: // should be protected but that doesn't compile, nice c++!
|
||||||
|
// Sets size when reading
|
||||||
|
virtual void setSize(sint32 size);
|
||||||
|
// Gets the size when writing, return false if unknown
|
||||||
|
virtual bool getSize(sint32 &size) const;
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
// CStorageUCString : serializes an ucstring chunk
|
||||||
|
class CStorageUCString : public ucstring, public IStorageObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void serial(CStorageStream *stream);
|
||||||
|
virtual void dump(const std::string &pad);
|
||||||
|
};
|
||||||
|
|
||||||
|
// CStorageString : serializes a string chunk
|
||||||
|
class CStorageString : public std::string, public IStorageObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void serial(CStorageStream *stream);
|
||||||
|
virtual void dump(const std::string &pad);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class CStorageValue : public IStorageObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
T Value;
|
||||||
|
virtual void serial(CStorageStream *stream);
|
||||||
|
virtual void dump(const std::string &pad);
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
|
} /* namespace MAX */
|
||||||
|
} /* namespace PIPELINE */
|
||||||
|
|
||||||
|
#endif /* #ifndef PIPELINE_STORAGE_OBJECT_H */
|
||||||
|
|
||||||
|
/* end of file */
|
Loading…
Reference in New Issue