You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Code/CryEngine/CrySystem/Serialization/BinArchive.h

181 lines
6.5 KiB
C++

/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#pragma once
// For tags 16-bit xor-hash is used, with check for uniquness in debug
// Block size is automatic: 8, 16 or 32 bits
#include "Serialization/IArchive.h"
#include "MemoryWriter.h"
namespace Serialization {
inline unsigned short calcHash(const char* str)
{
unsigned short hash = 0;
const unsigned short* p = (const unsigned short*)(str);
for (;; )
{
unsigned short w = *p++;
if (!(w & 0xff))
{
break;
}
hash ^= w;
if (!(w & 0xff00))
{
break;
}
}
return hash;
}
class BinOArchive
: public IArchive
{
public:
BinOArchive();
~BinOArchive() {}
void clear();
size_t length() const;
const char* buffer() const { return stream_.buffer(); }
bool save(const char* fileName);
bool operator()(bool& value, const char* name, const char* label);
bool operator()(IString& value, const char* name, const char* label);
bool operator()(IWString& value, const char* name, const char* label);
bool operator()(float& value, const char* name, const char* label);
bool operator()(double& value, const char* name, const char* label);
bool operator()(int32& value, const char* name, const char* label);
bool operator()(uint32& value, const char* name, const char* label);
bool operator()(int16& value, const char* name, const char* label);
bool operator()(uint16& value, const char* name, const char* label);
bool operator()(int64& value, const char* name, const char* label);
bool operator()(uint64& value, const char* name, const char* label);
bool operator()(int8& value, const char* name, const char* label);
bool operator()(uint8& value, const char* name, const char* label);
bool operator()(char& value, const char* name, const char* label);
bool operator()(const SStruct& ser, const char* name, const char* label);
bool operator()(IContainer& ser, const char* name, const char* label);
bool operator()(IPointer& ptr, const char* name, const char* label);
using IArchive::operator();
private:
void openContainer(const char* name, int size, const char* typeName);
void openNode(const char* name, bool size8 = true);
void closeNode(const char* name, bool size8 = true);
std::vector<unsigned int> blockSizeOffsets_;
MemoryWriter stream_;
};
//////////////////////////////////////////////////////////////////////////
class BinIArchive
: public IArchive
{
public:
BinIArchive();
~BinIArchive();
bool load(const char* fileName);
bool open(const char* buffer, size_t length); // doesn't copy the buffer
bool open(const BinOArchive& ar) { return open(ar.buffer(), ar.length()); }
void close();
bool operator()(bool& value, const char* name, const char* label);
bool operator()(IString& value, const char* name, const char* label);
bool operator()(IWString& value, const char* name, const char* label);
bool operator()(float& value, const char* name, const char* label);
bool operator()(double& value, const char* name, const char* label);
bool operator()(int16& value, const char* name, const char* label);
bool operator()(uint16& value, const char* name, const char* label);
bool operator()(int32& value, const char* name, const char* label);
bool operator()(uint32& value, const char* name, const char* label);
bool operator()(int64& value, const char* name, const char* label);
bool operator()(uint64& value, const char* name, const char* label);
bool operator()(int8& value, const char* name, const char* label);
bool operator()(uint8& value, const char* name, const char* label);
bool operator()(char& value, const char* name, const char* label);
bool operator()(const SStruct& ser, const char* name, const char* label);
bool operator()(IContainer& ser, const char* name, const char* label);
bool operator()(IPointer& ptr, const char* name, const char* label);
using IArchive::operator();
private:
class Block
{
public:
Block(const char* data, int size)
: begin_(data)
, end_(data + size)
, curr_(data)
, complex_(false) {}
bool get(const char* name, Block& block);
void read(void* data, int size)
{
YASLI_ASSERT(curr_ + size <= end_);
memcpy(data, curr_, size);
curr_ += size;
}
template<class T>
void read(T& x){ read(&x, sizeof(x)); }
void read(string& s)
{
YASLI_ASSERT(curr_ + strlen(curr_) < end_);
s = curr_;
curr_ += strlen(curr_) + 1;
}
void read(wstring& s)
{
YASLI_ASSERT(curr_ + sizeof(wchar_t) * wcslen((wchar_t*)curr_) < end_);
s = (wchar_t*)curr_;
curr_ += (wcslen((wchar_t*)curr_) + 1) * sizeof(wchar_t);
}
unsigned int readPackedSize();
bool validToClose() const { return complex_ || curr_ == end_; }
private:
const char* begin_;
const char* end_;
const char* curr_;
bool complex_;
};
typedef std::vector<Block> Blocks;
Blocks blocks_;
const char* loadedData_;
bool openNode(const char* name);
void closeNode(const char* name, bool check = true);
Block& currentBlock() { return blocks_.back(); }
template<class T>
void read(T& t) { currentBlock().read(t); }
};
}