// DataBundle.h
//
#pragma once
typedef unsigned char Byte;
class CDataBundle
{
// Konstruktoren und Destruktoren //
public:
CDataBundle();
virtual ~CDataBundle();
CDataBundle(CDataBundle& db)
{
m_pMemory = db.m_pMemory;
m_nSizeArray = db.m_nSizeArray;
m_nCount = db.m_nCount;
m_nMemorySize = db.m_nMemorySize;
};
// Operatoren //
CDataBundle& operator =(CDataBundle& db)
{
m_pMemory = db.m_pMemory;
m_nSizeArray = db.m_nSizeArray;
m_nCount = db.m_nCount;
m_nMemorySize = db.m_nMemorySize;
return *this;
};
// Attribute //
private:
Byte* m_pMemory;
size_t* m_nSizeArray;
size_t m_nMemorySize;
int m_nCount;
// Funktionen //
public:
// Objekt dazufügen, holen und Objektgrösse holen.
int AddObject(void* pObject, size_t nObjectSize);
void GetObject(int nIndex, void* pBuffer) const;
size_t GetObjectSize(int nIndex) const;
// Grössen zurückgeben.
int GetCount() const { return m_nCount; };
int GetUpperBound() const { return m_nCount - 1; };
// CDataBundle aufräumen.
void Delete() { delete [] m_pMemory; delete [] m_nSizeArray; m_nCount = 0; m_nMemorySize = 0; };
};
// DataBundle.cpp
//
#include "StdAfx.h"
#include ".\databundle.h"
CDataBundle::CDataBundle()
: m_pMemory(NULL)
, m_nSizeArray(NULL)
, m_nMemorySize(0)
, m_nCount(0)
{
}
CDataBundle::~CDataBundle()
{
}
int CDataBundle::AddObject(void* pObject, size_t nObjectSize)
{
// Prüfen ob pObjekt ungleich NULL ist,
// wenn nicht dann negativen Wert als Fehler zurückgeben.
if(!pObject)
{ return -1; }
// void-Zeiger nach unsigned char* casten.
Byte* pBuffer = static_cast<Byte*>(pObject);
// Die neue Memorygrösse berechnen.
size_t nNewMemorySize = m_nMemorySize + nObjectSize;
// Neues Memoryarray und neues Array für die Objektgrössen anlegen.
Byte* pNewMemory = new Byte[nNewMemorySize];
size_t* nSizeArray = new size_t[m_nCount + 1];
// Prüfen ob beide neuen Arrays auch existieren.
if(!pNewMemory || !nSizeArray)
{
// Sicherstellen, wenn nur eines nicht erstellt worden ist,
// dass trotzdem der Speicher wieder komplett freigegeben wird.
delete [] pNewMemory;
delete [] nSizeArray;
// Negativen Wert als Fehler zurückgeben.
return -1;
}
// Das neue Memoryarray durchlaufen.
size_t nOldIndex = 0, nNewIndex = 0;
for(size_t i = 0; i < nNewMemorySize; ++i)
{
if(i < m_nMemorySize)
{
// Alte Bytes eintragen.
pNewMemory[i] = m_pMemory[nOldIndex];
++nOldIndex;
}
else
{
// Neue Bytes eintragen.
pNewMemory[i] = pBuffer[nNewIndex];
++nNewIndex;
}
}
// Alte Grössen ins neue Grössenarray eintragen.
for(int i = 0; i < m_nCount; ++i)
{ nSizeArray[i] = m_nSizeArray[i]; }
// Neue Grösse an der letzten Stelle eintragen.
nSizeArray[m_nCount] = nObjectSize;
// Altes Memoryarray und Grössenarray löschen.
delete [] m_pMemory;
delete [] m_nSizeArray;
// Die Zeiger der neuen Arrays den Membervariablen zuweisen.
m_pMemory = pNewMemory;
m_nSizeArray = nSizeArray;
// Die neue Gesamtgrösse der Membervariable zuweisen.
m_nMemorySize = nNewMemorySize;
// Die Anzahl der Objekte inkrementieren.
++m_nCount;
// Den Index des dazugefügten Objektes zurückgeben.
return (m_nCount - 1);
}
void CDataBundle::GetObject(int nIndex, void* pObject) const
{
// Prüfen ob der Buffer ungleich NULL ist und ob der Index gültig ist,
// wenn nicht dann die Funktion abbrechen.
if(!pObject || nIndex < 0 || nIndex >= m_nCount)
{ return; }
// void-Zeiger nach unsigned char* casten.
Byte* pBuffer = static_cast<Byte*>(pObject);
// Die Grösse des Objektes holen.
size_t nSize = m_nSizeArray[nIndex];
// Das Startbyte herausfinden.
size_t nStart = 0;
for(int i = 0; i < nIndex; ++i)
{ nStart += m_nSizeArray[i]; }
// Die entsprechenden Bytes in den Puffer kopieren.
for(size_t i = 0; i < nSize; ++i)
{ pBuffer[i] = m_pMemory[nStart + i]; }
}
size_t CDataBundle::GetObjectSize(int nIndex) const
{
// Prüfen ob der Index gültig ist, wenn nicht dann 0 zurückgeben.
if(nIndex < 0 || nIndex >= m_nCount)
{ return 0; }
// Die Grösse des Objektes zurückgeben.
return m_nSizeArray[nIndex];
}
Ist zwar noch nicht wirklich das Wahre und ich baue es womöglich noch ein wenig um, aber das war so der Ansatz meiner Idee. Gehört allerdings langsam ins C++ Forum ^^
Wenn wer Vorschläge/Verbesserungen hat, dann her damit. Vor allem was das Kopieren der Bytes angeht, bin ich noch nicht wirklich zufrieden. Aber wollte nicht memcpy und co brauchen, da diese ja C und nicht C++ sind. Allerdings habe ich keine Ahnung wie man in C++ dann ein memcpy ausführt. Und wenn man in C++ memcpy verwendet, dann jage ich alle zum Teufel, welche behaupten C++ und C seien zwei verschiedene Sprachen.
*so macht nun Pause* ^^
Grüssli