[fnd] Added Vec, changed List. Remove MemoryBlob, replaced with Vec<byte_t>.

This commit is contained in:
jakcron 2018-06-24 12:45:45 +08:00
parent 43d243824c
commit 9b3a26806a
8 changed files with 404 additions and 278 deletions

View file

@ -126,9 +126,9 @@
<ClInclude Include="include\fnd\Exception.h" />
<ClInclude Include="include\fnd\IFile.h" />
<ClInclude Include="include\fnd\io.h" />
<ClInclude Include="include\fnd\ISerialiseableBinary.h" />
<ClInclude Include="include\fnd\ISerialisable.h" />
<ClInclude Include="include\fnd\List.h" />
<ClInclude Include="include\fnd\MemoryBlob.h" />
<ClInclude Include="include\fnd\Vec.h" />
<ClInclude Include="include\fnd\ResourceFileReader.h" />
<ClInclude Include="include\fnd\SimpleFile.h" />
<ClInclude Include="include\fnd\SimpleTextOutput.h" />
@ -138,7 +138,6 @@
<ItemGroup>
<ClCompile Include="source\Exception.cpp" />
<ClCompile Include="source\io.cpp" />
<ClCompile Include="source\MemoryBlob.cpp" />
<ClCompile Include="source\ResourceFileReader.cpp" />
<ClCompile Include="source\SimpleFile.cpp" />
<ClCompile Include="source\SimpleTextOutput.cpp" />

View file

@ -24,15 +24,6 @@
<ClInclude Include="include\fnd\io.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\fnd\ISerialiseableBinary.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\fnd\List.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\fnd\MemoryBlob.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\fnd\StringConv.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -57,6 +48,15 @@
<ClInclude Include="include\fnd\SimpleFile.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\fnd\List.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\fnd\Vec.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\fnd\ISerialisable.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="source\Exception.cpp">
@ -65,9 +65,6 @@
<ClCompile Include="source\io.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="source\MemoryBlob.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="source\StringConv.cpp">
<Filter>Source Files</Filter>
</ClCompile>

View file

@ -0,0 +1,21 @@
#pragma once
#include <fnd/types.h>
#include <fnd/Vec.h>
namespace fnd
{
class ISerialisable
{
public:
// serialise
virtual void toBytes() = 0;
// deserialise
virtual void fromBytes(const byte_t* data, size_t len) = 0;
// get byte vector
virtual const fnd::Vec<byte_t>& getBytes() const = 0;
// clear data
virtual void clear() = 0;
};
}

View file

@ -1,17 +0,0 @@
#pragma once
#include <fnd/types.h>
namespace fnd
{
class ISerialiseableBinary
{
public:
virtual const byte_t* getBytes() const = 0;
virtual size_t getSize() const = 0;
virtual void exportBinary() = 0;
virtual void importBinary(const byte_t* bytes, size_t len) = 0;
virtual void clear() = 0;
};
}

View file

@ -1,6 +1,6 @@
#pragma once
#include <fnd/types.h>
#include <vector>
#include <fnd/Vec.h>
namespace fnd
{
@ -8,130 +8,199 @@ namespace fnd
class List
{
public:
List() :
mElements()
{
}
// constructors
List();
List(const List<T>& other);
List(const T* elements, size_t num) :
mElements(num)
{
initList(elements, num);
}
// copy operator
const List<T>& operator=(const List<T>& other);
// assignment operator
const List& operator=(const List& other)
{
mElements.clear();
for (size_t i = 0; i < other.getSize(); i++)
{
mElements.push_back(other[i]);
}
// equivalence operators
bool operator==(const List<T>& other) const;
bool operator!=(const List<T>& other) const;
return *this;
}
// back relative insertion
void addElement(const T& element);
// element access
const T& operator[](size_t index) const;
T& operator[](size_t index);
const T& atBack() const;
T& atBack();
// comparision operator
bool operator==(const List& other) const
{
if (other.getSize() != this->getSize())
{
return false;
}
// element num
size_t size() const;
for (size_t i = 0; i < this->getSize(); i++)
{
if (getElement(i) != other[i])
{
return false;
}
}
// clear List
void clear();
return true;
}
bool operator!=(const List& other) const
{
return !operator==(other);
}
// access operators
const T& getElement(size_t index) const
{
return mElements[index];
}
T& getElement(size_t index)
{
if (index == mElements.size()) mElements.push_back(T());
return mElements[index];
}
const T& operator[](size_t index) const { return getElement(index); }
T& operator[](size_t index) { return getElement(index); }
const T& atBack() const { return getElement(getSize() - 1); }
T& atBack() { return getElement(getSize() - 1); }
// functions
void addElement(const T& element) { mElements.push_back(element); }
size_t getIndexOf(const T& key) const
{
for (size_t i = 0; i < getSize(); i++)
{
if (getElement(i) == key) return i;
}
throw Exception("LIST", "Element does not exist");
}
bool hasElement(const T& key) const
{
try
{
getIndexOf(key);
} catch (const Exception&)
{
return false;
}
return true;
}
// special
template <class X>
size_t getIndexOf(const X& key) const
{
for (size_t i = 0; i < getSize(); i++)
{
if (getElement(i) == key) return i;
}
throw Exception("LIST", "Element does not exist");
}
template <class X>
bool hasElement(const X& key) const
{
try
{
getIndexOf(key);
} catch (const Exception&)
{
return false;
}
return true;
}
size_t getSize() const { return mElements.size(); }
void clear() { mElements.clear(); }
// element access by key
template <class K>
bool hasElement(const K& key) const;
template <class K>
const T& getElement(const K& key) const;
template <class K>
T& getElement(const K& key);
private:
std::vector<T> mElements;
static const size_t kDefaultSize = 20;
void initList(T* elements, size_t num)
fnd::Vec<T> m_Vec;
size_t m_Num;
};
template<class T>
inline List<T>::List() :
m_Vec(),
m_Num(0)
{
m_Vec.alloc(kDefaultSize);
}
template<class T>
inline List<T>::List(const List<T>& other) :
m_Vec(other.m_Vec),
m_Size(other.m_Size)
{}
template<class T>
inline const List<T>& List<T>::operator=(const List<T>& other)
{
m_Vec = other.m_Vec;
m_Size = other.m_Size;
}
template<class T>
inline bool List<T>::operator==(const List<T>& other) const
{
bool isEqual = true;
if (m_Num == other.m_Num)
{
mElements.clear();
for (size_t i = 0; i < num; i++)
for (size_t i = 0; i < m_Num && isEqual == true; i++)
{
mElements.push_back(elements[i]);
if ((*this)[i] != other[i])
isEqual = false;
}
}
};
}
else
{
isEqual = false;
}
return isEqual;
}
template<class T>
inline bool List<T>::operator!=(const List<T>& other) const
{
return !(*this == other);
}
template<class T>
inline void List<T>::addElement(const T & element)
{
(*this)[m_Num] = element;
}
template<class T>
inline const T & List<T>::operator[](size_t index) const
{
if (index >= m_Num)
{
throw fnd::Exception("List", "Out of bound read");
}
return m_Vec[index];
}
template<class T>
inline T & List<T>::operator[](size_t index)
{
if (index > m_Num)
{
throw fnd::Exception("List", "Out of bound read");
}
else if (index == m_Num)
{
if ((m_Num * 2) >= m_Vec.size())
{
m_Vec.alloc((m_Num + 1) * 2);
}
m_Num++;
}
return m_Vec[index];
}
template<class T>
inline const T & List<T>::atBack() const
{
return m_Vec[m_Num - 1];
}
template<class T>
inline T & List<T>::atBack()
{
return m_Vec[m_Num - 1];
}
template<class T>
inline size_t List<T>::size() const
{
return m_Num;
}
template<class T>
inline void List<T>::clear()
{
m_Num = 0;
m_Vec.clear();
}
template<class T>
template<class K>
inline bool List<T>::hasElement(const K & key) const
{
for (size_t i = 0; i < m_Num; i++)
{
if (m_List[i] == key)
{
return true;
}
}
return false;
}
template<class T>
template<class K>
inline const T & List<T>::getElement(const K & key) const
{
for (size_t i = 0; i < m_Num; i++)
{
if (m_List[i] == key)
{
return m_List[i];
}
}
throw fnd::Exception("getElement(): element does not exist");
}
template<class T>
template<class K>
inline T & List<T>::getElement(const K & key)
{
for (size_t i = 0; i < m_Num; i++)
{
if (m_List[i] == key)
{
return m_List[i];
}
}
throw fnd::Exception("getElement(): element does not exist");
}
}

View file

@ -1,42 +0,0 @@
#pragma once
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <vector>
#include <fnd/types.h>
namespace fnd
{
class MemoryBlob
{
public:
MemoryBlob();
MemoryBlob(const byte_t* bytes, size_t len);
bool operator==(const MemoryBlob& other) const;
bool operator!=(const MemoryBlob& other) const;
void operator=(const MemoryBlob& other);
void alloc(size_t size);
void extend(size_t new_size);
void clear();
inline byte_t& operator[](size_t index) { return mData[index]; }
inline const byte_t& operator[](size_t index) const { return mData[index]; }
inline byte_t* getBytes() { return mData.data(); }
inline const byte_t* getBytes() const { return mData.data(); }
inline size_t getSize() const { return mVisableSize; }
private:
const std::string kModuleName = "MEMORY_BLOB";
static const size_t kAllocBlockSize = 0x1000;
std::vector<byte_t> mData;
size_t mSize;
size_t mVisableSize;
void allocateMemory(size_t size);
void clearMemory();
};
}

View file

@ -0,0 +1,188 @@
#pragma once
#include <fnd/types.h>
namespace fnd
{
template <class T>
class Vec
{
public:
// constructors
Vec();
Vec(const Vec<T>& other);
Vec(const T* array, size_t num);
~Vec();
// copy operator
const Vec<T>& operator=(const Vec<T>& other);
// equivalence operators
bool operator==(const Vec<T>& other) const;
bool operator!=(const Vec<T>& other) const;
// element access
const T& operator[](size_t index) const;
T& operator[](size_t index);
// raw access
const T* data() const;
T* data();
// element num
size_t size() const;
// allocate vector
void alloc(size_t new_size);
// clear vector
void clear();
private:
T * m_Vec;
size_t m_Size;
void copyFrom(const T * array, size_t num);
};
template<class T>
inline Vec<T>::Vec() :
m_Vec(nullptr),
m_Size(0)
{}
template<class T>
inline Vec<T>::Vec(const Vec<T>& other) :
Vec()
{
copyFrom(other.data(), other.size());
}
template<class T>
inline Vec<T>::Vec(const T * array, size_t num) :
Vec()
{
copyFrom(array, num);
}
template<class T>
inline Vec<T>::~Vec()
{
clear();
}
template<class T>
inline const Vec<T>& Vec<T>::operator=(const Vec<T>& other)
{
copyFrom(other.data(), other.size());
}
template<class T>
inline bool Vec<T>::operator==(const Vec<T>& other) const
{
bool isEqual = true;
if (m_Size == other.m_Size)
{
for (size_t i = 0; i < m_Size && isEqual; i++)
{
if (m_Vec[i] != other.m_Vec[i])
{
isEqual = false;
}
}
}
else
{
isEqual = false;
}
return isEqual;
}
template<class T>
inline bool Vec<T>::operator!=(const Vec<T>& other) const
{
return !(*this == other);
}
template<class T>
inline const T & Vec<T>::operator[](size_t index) const
{
return m_Vec[index];
}
template<class T>
inline T & Vec<T>::operator[](size_t index)
{
return m_Vec[index];
}
template<class T>
inline const T * Vec<T>::data() const
{
return m_Vec;
}
template<class T>
inline T * Vec<T>::data()
{
return m_Vec;
}
template<class T>
inline size_t Vec<T>::size() const
{
return m_Size;
}
template<class T>
inline void Vec<T>::alloc(size_t new_size)
{
if (m_Vec != nullptr)
{
T* new_vec = new T[new_size];
if (new_vec == nullptr)
{
fnd::Exception("Vec", "Failed to allocate memory for vector");
}
for (size_t i = 0; i < MIN(m_Size, new_size); i++)
{
new_vec[i] = m_Vec[i];
}
delete[] m_Vec;
m_Vec = new_vec;
m_Size = new_size;
}
else
{
m_Vec = new T[new_size];
if (m_Vec == nullptr)
{
fnd::Exception("Vec", "Failed to allocate memory for vector");
}
m_Size = new_size;
}
}
template<class T>
inline void Vec<T>::clear()
{
if (m_Vec != nullptr)
{
delete[] m_Vec;
}
m_Vec = nullptr;
m_Size = 0;
}
template<class T>
inline void Vec<T>::copyFrom(const T * array, size_t num)
{
clear();
alloc(num);
for (size_t i = 0; i < m_Size; i++)
{
m_Vec[i] = array[i];
}
}
}

View file

@ -1,89 +0,0 @@
#include <fnd/MemoryBlob.h>
using namespace fnd;
MemoryBlob::MemoryBlob() :
mData(),
mSize(0),
mVisableSize(0)
{
}
fnd::MemoryBlob::MemoryBlob(const byte_t * bytes, size_t len) :
mData(),
mSize(0),
mVisableSize(0)
{
alloc(len);
memcpy(getBytes(), bytes, getSize());
}
bool fnd::MemoryBlob::operator==(const MemoryBlob & other) const
{
bool isEqual = true;
if (this->getSize() == other.getSize())
{
isEqual = memcmp(this->getBytes(), other.getBytes(), this->getSize()) == 0;
}
else
{
isEqual = false;
}
return isEqual;
}
bool fnd::MemoryBlob::operator!=(const MemoryBlob & other) const
{
return !operator==(other);
}
void fnd::MemoryBlob::operator=(const MemoryBlob & other)
{
alloc(other.getSize());
memcpy(getBytes(), other.getBytes(), getSize());
}
void MemoryBlob::alloc(size_t size)
{
if (size > mSize)
{
allocateMemory(size);
}
else
{
mVisableSize = size;
clearMemory();
}
}
void MemoryBlob::extend(size_t new_size)
{
try {
mData.resize(new_size);
}
catch (...) {
throw fnd::Exception(kModuleName, "extend() failed to allocate memory");
}
}
void fnd::MemoryBlob::clear()
{
mVisableSize = 0;
}
void MemoryBlob::allocateMemory(size_t size)
{
mSize = (size_t)align(size, kAllocBlockSize);
mVisableSize = size;
extend(mSize);
clearMemory();
}
void MemoryBlob::clearMemory()
{
memset(mData.data(), 0, mSize);
}