Charbuffer

Contenu du snippet

Je sais que je réinvente la roue mais étant débutant en c++ je soumets ma première source aux commentaires.
Son but est aussi pédagogique pour les débutants qu'inutile pour les autres.

Cette classe permet de gérer un tampon de char géré par HeapAlloc(), HeapRealloc(), et HeapFree()

Les méthodes sont les suivantes :

// Constructeur permettant de spécifier la taille initiale du tampon
XCharBuffer(const unsigned int p_iSize);

// GESTION DE LA TAILLE
bool setBufferSize(const unsigned int p_size); // Défini la taille du tampon
bool pack(); // Ajuste la taille du tampon au contenu
unsigned int getValueSize(); // Retourne la taille de la chaine contenu (sans le \0)
unsigned int getBufferSize(); // Retourne la taille du tampon

// GESTION DU CONTENU
void clear(); // Efface le contenu du tampon
void append(const char* p_pszValue); // Ajoute une chaine
char* toCharArray(); // Retourne le contenu (char*)

Cette peut être spécialisée car les méthodes de gestion du tampon sont protected

Source / Exemple :


//    XCharBuffer.h

#include "Windows.h"

class XCharBuffer  
{
	public:

		// GESTION DE L'INSTANCE

		// Construteurs
		XCharBuffer(const unsigned int p_iSize);

		// Déstructeur
		virtual ~XCharBuffer();

		// GESTION DE LA TAILLE

		// Défini la taille du tampon
		bool setBufferSize(const unsigned int p_size);
		
		// Ajuste la taille du tampon au contenu
		bool pack();

		// Retourne la taille de la chaine contenu (sans le \0)
		unsigned int getValueSize();

		// Retourne la taille du tampon
		unsigned int getBufferSize();

		
		// GESTION DU CONTENU

		// Efface le contenu du tampon
		void clear();
	
		// Ajoute une chaine
		void append(const char* p_pszValue);
		void append(const unsigned char* p_pszValue);
		
		// Retourne le contenu (char*)
		char* toCharArray();

		// Retourne le contenu (BSTR)
		//const BSTR* toCharArray();

	protected:

		HANDLE			 m_hHeapHandle;		// Handle du Tas contenant le buffer

		char			*m_pszBuffer;		// Tampon de stockage
		char			*m_pBufferPos;		// Pointeur sur le prochain caratère à ecrire
		char			*m_pBufferPosMax;	// Pointeur sur le prochain caratère à ecrire
		unsigned int	 m_iBufferSize;		// Taille allouée au tampon 
		unsigned int	 m_iValueSize;		// Taille de la valeur contenue

		// Crée ou agrandi le buffer si necessaire pour y stocker (p_iSize) nouveaux caractères
		inline bool increaseBuffer(const unsigned int p_iSize);

		// Redéfinie la taille du tampon existant à (p_iSize) caractères
		inline bool resizeBuffer(const unsigned int p_iSize);

		// Retourne la taille de la chaine sans le \0
		inline unsigned int getLength(const char* p_pszValue);
		
		// Copie les (p_iSize) caractères du buffer (source) vers le buffer (target)
		inline void copyBuffer(const char* p_pszSrcValue, char* p_pszTrgValue, unsigned int p_iSize);
	
};
__________________________________________________________________________________________________
// XCharBuffer.cpp 

#include "XCharBuffer.h"

/***********************************************************************
 *

  • INTERFACTION PUBLIQUE
*
                                                                                                                                              • /
/****************************************************************
  • GESTION DE L'INSTANCE
                                                                                                                                • /
// Construteur XCharBuffer::XCharBuffer(const unsigned int p_iSize) { // Définition du tas à utiliser this->m_hHeapHandle = GetProcessHeap(); this->m_pszBuffer = NULL; // Tampon de stockage this->m_pBufferPos = NULL; // Pointeur sur le prochain caratère à ecrire this->m_pBufferPosMax = NULL; // Valeur maxi du pointeur this->m_iBufferSize = 0; // Taille allouée au tampon this->m_iValueSize = 0; // Taille de la valeur contenue // Mise à jour de la taille du tampon this->increaseBuffer(p_iSize); } // Déstructeur XCharBuffer::~XCharBuffer() { // Destruction du tampon si créé if (this->m_pszBuffer) if (!HeapFree(this->m_hHeapHandle, 0, this->m_pszBuffer)) { ;// Ya Erreur ! ; } } /****************************************************************
  • GESTION DE LA TAILLE
                                                                                                                                • /
// Redefini la taille de (p_size) caratère bool XCharBuffer::setBufferSize(const unsigned int p_size) { return this->resizeBuffer(p_size); } // Ajuste la taille du tampon au contenu bool XCharBuffer::pack() { return this->resizeBuffer(this->m_iValueSize); } // Retourne la taille de la chaine contenu (sans le \0) unsigned int XCharBuffer::getValueSize() { return this->m_iValueSize; } // Retourne la taille du tampon unsigned int XCharBuffer::getBufferSize() { return this->m_iBufferSize; } /****************************************************************
  • GESTION DU CONTENU
                                                                                                                                • /
// Efface le contenu du tampon void XCharBuffer::clear() { // Mise à 0 de tous les caractères for (char* pChar = this->m_pszBuffer; pChar < this->m_pBufferPosMax; pChar++)
  • pChar = 0;
// Positionement sur le premier caractère this->m_pBufferPos = this->m_pszBuffer; // Réajustement de la taille de la valeur this->m_iValueSize = 0; } // Ajoute une chaine void XCharBuffer::append(const char* p_pszValue) { // Lecture du nombre de caractère à ajouter unsigned int iSize = this->getLength(p_pszValue); // Agrandissement du tampon if (this->increaseBuffer(iSize)) { // Copie de la nouvelle chaine this->copyBuffer(p_pszValue, this->m_pBufferPos, iSize); // Positionement sur le prochain caractère this->m_pBufferPos += iSize; // Mise à jour de la taille de la valeur this->m_iValueSize += iSize; } } // Ajoute une chaine void XCharBuffer::append(const unsigned char* p_pszValue) { this->append((const char*)p_pszValue); } // Retourne le contenu (char*) char* XCharBuffer::toCharArray() {
  • this->m_pBufferPos = 0;
return this->m_pszBuffer; } /***************************************************************** *
  • METHODES PROTEGEES
*
                                                                                                                                  • /
// Crée ou agrandi le buffer si necessaire pour y stocker (p_iSize) nouveaux caractères inline bool XCharBuffer::increaseBuffer(const unsigned int p_iSize) { // Si aucune taille nécessaire if (p_iSize == 0) return false; // Si pas de mémoire allouée if (!this->m_pBufferPos) { // Allocation pour le tampon (+ 1 pour le \0) this->m_pszBuffer = (char*)HeapAlloc(this->m_hHeapHandle, HEAP_ZERO_MEMORY, p_iSize + 1); if (!this->m_pszBuffer) { return false; // Ya Erreur } // Initialisation du tampon this->m_pBufferPos = this->m_pszBuffer; // Positionement sur le premier caractère this->m_pBufferPosMax = this->m_pBufferPos + p_iSize; // Définition du dernier caractère this->m_iBufferSize = (unsigned int)p_iSize; // Définition de la taille du tampon } // Si mémoire déja allouée else { // Calcul de l'espace restant unsigned int iFreeSize = this->m_pBufferPosMax - this->m_pBufferPos; // Si pas suffisement d'espace dans le tampon if (iFreeSize < p_iSize) { // Calcul de l'espace nécessaire unsigned int iRequiredSize = this->m_iBufferSize + (p_iSize - iFreeSize); // Redimensionnement du tampon if (!this->resizeBuffer(iRequiredSize)) { return false; // Ya Erreur } } } return true; } // Redéfinie la taille du tampon existant à (p_iSize) caractères inline bool XCharBuffer::resizeBuffer(const unsigned int p_iSize) { // Si pas de mémoire allouée if (!this->m_pBufferPos) return false; // Ya Erreur // Reallocation du tampon (+1 pour le \0) char* pNewBuffer = (char*)HeapReAlloc(this->m_hHeapHandle, HEAP_ZERO_MEMORY, this->m_pszBuffer, p_iSize + 1); // Vérification si alloué if (pNewBuffer) { this->m_pszBuffer = pNewBuffer; // Mise à jour de l'adresse du tampon this->m_pBufferPos = this->m_pszBuffer + m_iBufferSize; // Positionement sur le prochain caractère this->m_pBufferPosMax = this->m_pBufferPos + p_iSize; // Définition du dernier caractère this->m_iBufferSize = p_iSize; // Définition de la taille du tampon } else { return false; // Ya Erreur } return true; } // Retourne la taille de la chaine sans le \0 inline unsigned int XCharBuffer::getLength(const char* p_pszValue) { unsigned int iSize = 0; const char* pszPos = p_pszValue; while(*pszPos++) iSize++; return iSize; } // Copie les (p_iSize) caractères du buffer (source) vers le buffer (target) inline void XCharBuffer::copyBuffer(const char* p_pszSrcValue, char* p_pszTrgValue, unsigned int p_iSize) { const char* pSrc = p_pszSrcValue; char* pTrg = p_pszTrgValue; for (unsigned int i = 0; i < p_iSize; i++)
  • pTrg++ = *pSrc++;
}

Conclusion :


Voici la procédure que j'utilise pour les test

En testant différentes tailles lors de l'initialisation (dans le constructeur)
il m'arrive que le return 0 du main() génére une exception avec le message suivant
Free Heap block 1345b0 modified at 1345e4 after it was freed
Je cherche mais je n'ai toujours pas compris pourkoi ??????
Je sais qu'avait la valeur 100, le code suivant termine en erreur

int main(int argc, char* argv[])
{
//XCharBuffer *poBuffer = new XCharBuffer(0);
XCharBuffer *poBuffer = new XCharBuffer(32);

poBuffer->append("toto");
std::cout << poBuffer->toCharArray() << " - "
<< (int)poBuffer->getValueSize() << " - "
<< (int)poBuffer->getBufferSize() << std::endl;
poBuffer->append(" et pis tata");
std::cout << poBuffer->toCharArray() << " - "
<< (int)poBuffer->getValueSize() << " - "
<< (int)poBuffer->getBufferSize() << std::endl;
poBuffer->pack();
std::cout << poBuffer->toCharArray() << " - "
<< (int)poBuffer->getValueSize() << " - "
<< (int)poBuffer->getBufferSize() << std::endl;
delete poBuffer;
return 0;
}

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.