589 lines
9.7 KiB
C++
589 lines
9.7 KiB
C++
![]() |
/////////////////////////////////////////////////////
|
|||
|
// gestion de chaine
|
|||
|
// bas<61> sur le CString de MFC
|
|||
|
// mais moins complet
|
|||
|
|
|||
|
#include "CBot.h"
|
|||
|
|
|||
|
#include <string.h>
|
|||
|
|
|||
|
HINSTANCE CBotString::m_hInstance = (HINSTANCE)LoadLibrary("Cbot.dll"); // comment le r<>cup<75>rer autrement ??
|
|||
|
|
|||
|
|
|||
|
CBotString::CBotString()
|
|||
|
{
|
|||
|
m_ptr = NULL; // chaine vide
|
|||
|
m_lg = 0;
|
|||
|
}
|
|||
|
|
|||
|
CBotString::~CBotString()
|
|||
|
{
|
|||
|
if (m_ptr != NULL) free(m_ptr);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
CBotString::CBotString(const char* p)
|
|||
|
{
|
|||
|
m_lg = lstrlen( p );
|
|||
|
|
|||
|
m_ptr = NULL;
|
|||
|
if (m_lg>0)
|
|||
|
{
|
|||
|
m_ptr = (char*)malloc(m_lg+1);
|
|||
|
lstrcpy(m_ptr, p);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
CBotString::CBotString(const CBotString& srcString)
|
|||
|
{
|
|||
|
m_lg = srcString.m_lg;
|
|||
|
|
|||
|
m_ptr = NULL;
|
|||
|
if (m_lg>0)
|
|||
|
{
|
|||
|
m_ptr = (char*)malloc(m_lg+1);
|
|||
|
lstrcpy(m_ptr, srcString.m_ptr);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
int CBotString::GivLength()
|
|||
|
{
|
|||
|
if ( m_ptr == NULL ) return 0;
|
|||
|
return lstrlen( m_ptr );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
CBotString CBotString::Left(int nCount) const
|
|||
|
{
|
|||
|
char chaine[2000];
|
|||
|
|
|||
|
int i;
|
|||
|
for (i = 0; i < m_lg && i < nCount && i < 1999; i++)
|
|||
|
{
|
|||
|
chaine[i] = m_ptr[i];
|
|||
|
}
|
|||
|
chaine[i] = 0 ;
|
|||
|
|
|||
|
return CBotString( chaine );
|
|||
|
}
|
|||
|
|
|||
|
CBotString CBotString::Right(int nCount) const
|
|||
|
{
|
|||
|
char chaine[2000];
|
|||
|
|
|||
|
int i = m_lg - nCount;
|
|||
|
if ( i < 0 ) i = 0;
|
|||
|
|
|||
|
for ( int j = 0; i < m_lg && i < 1999; i++)
|
|||
|
{
|
|||
|
chaine[j++] = m_ptr[i];
|
|||
|
}
|
|||
|
chaine[j] = 0 ;
|
|||
|
|
|||
|
return CBotString( chaine );
|
|||
|
}
|
|||
|
|
|||
|
CBotString CBotString::Mid(int nFirst, int nCount) const
|
|||
|
{
|
|||
|
char chaine[2000];
|
|||
|
|
|||
|
int i;
|
|||
|
|
|||
|
for ( i = nFirst; i < m_lg && i < 1999 && i <= nFirst + nCount; i++)
|
|||
|
{
|
|||
|
chaine[i] = m_ptr[i];
|
|||
|
}
|
|||
|
chaine[i] = 0 ;
|
|||
|
|
|||
|
return CBotString( chaine );
|
|||
|
}
|
|||
|
|
|||
|
CBotString CBotString::Mid(int nFirst) const
|
|||
|
{
|
|||
|
char chaine[2000];
|
|||
|
|
|||
|
int i;
|
|||
|
|
|||
|
for ( i = nFirst; i < m_lg && i < 1999 ; i++)
|
|||
|
{
|
|||
|
chaine[i] = m_ptr[i];
|
|||
|
}
|
|||
|
chaine[i] = 0 ;
|
|||
|
|
|||
|
return CBotString( chaine );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
int CBotString::Find(const char c)
|
|||
|
{
|
|||
|
int i;
|
|||
|
for (i = 0; i < m_lg; i++)
|
|||
|
{
|
|||
|
if (m_ptr[i] == c) return i;
|
|||
|
}
|
|||
|
return -1;
|
|||
|
}
|
|||
|
|
|||
|
int CBotString::Find(LPCTSTR lpsz)
|
|||
|
{
|
|||
|
int i, j;
|
|||
|
int l = lstrlen(lpsz);
|
|||
|
|
|||
|
for (i = 0; i <= m_lg-l; i++)
|
|||
|
{
|
|||
|
for (j = 0; j < l; j++)
|
|||
|
{
|
|||
|
if (m_ptr[i+j] != lpsz[j]) goto bad;
|
|||
|
}
|
|||
|
return i;
|
|||
|
bad:;
|
|||
|
}
|
|||
|
return -1;
|
|||
|
}
|
|||
|
|
|||
|
int CBotString::ReverseFind(const char c)
|
|||
|
{
|
|||
|
int i;
|
|||
|
for (i = m_lg-1; i >= 0; i--)
|
|||
|
{
|
|||
|
if (m_ptr[i] == c) return i;
|
|||
|
}
|
|||
|
return -1;
|
|||
|
}
|
|||
|
|
|||
|
int CBotString::ReverseFind(LPCTSTR lpsz)
|
|||
|
{
|
|||
|
int i, j;
|
|||
|
int l = lstrlen(lpsz);
|
|||
|
|
|||
|
for (i = m_lg-l; i >= 0; i--)
|
|||
|
{
|
|||
|
for (j = 0; j < l; j++)
|
|||
|
{
|
|||
|
if (m_ptr[i+j] != lpsz[j]) goto bad;
|
|||
|
}
|
|||
|
return i;
|
|||
|
bad:;
|
|||
|
}
|
|||
|
return -1;
|
|||
|
}
|
|||
|
|
|||
|
CBotString CBotString::Mid(int start, int lg)
|
|||
|
{
|
|||
|
CBotString res;
|
|||
|
if (start >= m_lg) return res;
|
|||
|
|
|||
|
if ( lg < 0 ) lg = m_lg - start;
|
|||
|
|
|||
|
char* p = (char*)malloc(m_lg+1);
|
|||
|
lstrcpy(p, m_ptr+start);
|
|||
|
p[lg] = 0;
|
|||
|
|
|||
|
res = p;
|
|||
|
free(p);
|
|||
|
return res;
|
|||
|
}
|
|||
|
|
|||
|
void CBotString::MakeUpper()
|
|||
|
{
|
|||
|
int i;
|
|||
|
|
|||
|
for ( i = 0; i < m_lg && i < 1999 ; i++)
|
|||
|
{
|
|||
|
char c = m_ptr[i];
|
|||
|
if ( c >= 'a' && c <= 'z' ) m_ptr[i] = c - 'a' + 'A';
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void CBotString::MakeLower()
|
|||
|
{
|
|||
|
int i;
|
|||
|
|
|||
|
for ( i = 0; i < m_lg && i < 1999 ; i++)
|
|||
|
{
|
|||
|
char c = m_ptr[i];
|
|||
|
if ( c >= 'A' && c <= 'Z' ) m_ptr[i] = c - 'A' + 'a';
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#define MAXSTRING 256
|
|||
|
|
|||
|
BOOL CBotString::LoadString(UINT id)
|
|||
|
{
|
|||
|
char buffer[MAXSTRING];
|
|||
|
|
|||
|
m_lg = ::LoadString( m_hInstance, id, buffer, MAXSTRING );
|
|||
|
|
|||
|
if (m_ptr != NULL) free(m_ptr);
|
|||
|
|
|||
|
m_ptr = NULL;
|
|||
|
if (m_lg > 0)
|
|||
|
{
|
|||
|
m_ptr = (char*)malloc(m_lg+1);
|
|||
|
lstrcpy(m_ptr, buffer);
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
const CBotString& CBotString::operator=(const CBotString& stringSrc)
|
|||
|
{
|
|||
|
if (m_ptr != NULL) free(m_ptr);
|
|||
|
|
|||
|
m_lg = stringSrc.m_lg;
|
|||
|
m_ptr = NULL;
|
|||
|
|
|||
|
if (m_lg > 0)
|
|||
|
{
|
|||
|
m_ptr = (char*)malloc(m_lg+1);
|
|||
|
lstrcpy(m_ptr, stringSrc.m_ptr);
|
|||
|
}
|
|||
|
|
|||
|
return *this;
|
|||
|
}
|
|||
|
|
|||
|
CBotString operator+(const CBotString& string, LPCTSTR lpsz)
|
|||
|
{
|
|||
|
CBotString s ( string );
|
|||
|
s += lpsz;
|
|||
|
return s;
|
|||
|
}
|
|||
|
|
|||
|
const CBotString& CBotString::operator+(const CBotString& stringSrc)
|
|||
|
{
|
|||
|
char* p = (char*)malloc(m_lg+stringSrc.m_lg+1);
|
|||
|
|
|||
|
lstrcpy(p, m_ptr);
|
|||
|
char* pp = p + m_lg;
|
|||
|
lstrcpy(pp, stringSrc.m_ptr);
|
|||
|
|
|||
|
if (m_ptr != NULL) free(m_ptr);
|
|||
|
m_ptr = p;
|
|||
|
m_lg += stringSrc.m_lg;
|
|||
|
|
|||
|
return *this;
|
|||
|
}
|
|||
|
|
|||
|
const CBotString& CBotString::operator=(const char ch)
|
|||
|
{
|
|||
|
if (m_ptr != NULL) free(m_ptr);
|
|||
|
|
|||
|
m_lg = 1;
|
|||
|
|
|||
|
m_ptr = (char*)malloc(2);
|
|||
|
m_ptr[0] = ch;
|
|||
|
m_ptr[1] = 0;
|
|||
|
|
|||
|
return *this;
|
|||
|
}
|
|||
|
|
|||
|
const CBotString& CBotString::operator=(const char* pString)
|
|||
|
{
|
|||
|
if (m_ptr != NULL) free(m_ptr);
|
|||
|
m_ptr = NULL;
|
|||
|
|
|||
|
if ( pString != NULL )
|
|||
|
{
|
|||
|
m_lg = lstrlen(pString);
|
|||
|
|
|||
|
if (m_lg != 0)
|
|||
|
{
|
|||
|
m_ptr = (char*)malloc(m_lg+1);
|
|||
|
lstrcpy(m_ptr, pString);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return *this;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
const CBotString& CBotString::operator+=(const char ch)
|
|||
|
{
|
|||
|
char* p = (char*)malloc(m_lg+2);
|
|||
|
|
|||
|
if (m_ptr!=NULL) lstrcpy(p, m_ptr);
|
|||
|
p[m_lg++] = ch;
|
|||
|
p[m_lg] = 0;
|
|||
|
|
|||
|
if (m_ptr != NULL) free(m_ptr);
|
|||
|
|
|||
|
m_ptr = p;
|
|||
|
|
|||
|
return *this;
|
|||
|
}
|
|||
|
|
|||
|
const CBotString& CBotString::operator+=(const CBotString& str)
|
|||
|
{
|
|||
|
char* p = (char*)malloc(m_lg+str.m_lg+1);
|
|||
|
|
|||
|
lstrcpy(p, m_ptr);
|
|||
|
char* pp = p + m_lg;
|
|||
|
lstrcpy(pp, str.m_ptr);
|
|||
|
|
|||
|
m_lg = m_lg + str.m_lg;
|
|||
|
|
|||
|
if (m_ptr != NULL) free(m_ptr);
|
|||
|
|
|||
|
m_ptr = p;
|
|||
|
|
|||
|
return *this;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CBotString::operator==(const CBotString& str)
|
|||
|
{
|
|||
|
return Compare(str) == 0;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CBotString::operator==(const char* p)
|
|||
|
{
|
|||
|
return Compare(p) == 0;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CBotString::operator!=(const CBotString& str)
|
|||
|
{
|
|||
|
return Compare(str) != 0;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CBotString::operator!=(const char* p)
|
|||
|
{
|
|||
|
return Compare(p) != 0;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CBotString::operator>(const CBotString& str)
|
|||
|
{
|
|||
|
return Compare(str) > 0;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CBotString::operator>(const char* p)
|
|||
|
{
|
|||
|
return Compare(p) > 0;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CBotString::operator>=(const CBotString& str)
|
|||
|
{
|
|||
|
return Compare(str) >= 0;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CBotString::operator>=(const char* p)
|
|||
|
{
|
|||
|
return Compare(p) >= 0;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CBotString::operator<(const CBotString& str)
|
|||
|
{
|
|||
|
return Compare(str) < 0;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CBotString::operator<(const char* p)
|
|||
|
{
|
|||
|
return Compare(p) < 0;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CBotString::operator<=(const CBotString& str)
|
|||
|
{
|
|||
|
return Compare(str) <= 0;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CBotString::operator<=(const char* p)
|
|||
|
{
|
|||
|
return Compare(p) <= 0;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CBotString::IsEmpty()
|
|||
|
{
|
|||
|
return (m_lg == 0);
|
|||
|
}
|
|||
|
|
|||
|
void CBotString::Empty()
|
|||
|
{
|
|||
|
if (m_ptr != NULL) free(m_ptr);
|
|||
|
m_ptr = NULL;
|
|||
|
m_lg = 0;
|
|||
|
}
|
|||
|
|
|||
|
static char nilstring[] = {0};
|
|||
|
|
|||
|
CBotString::operator LPCTSTR() const
|
|||
|
{
|
|||
|
if (this == NULL || m_ptr == NULL) return nilstring;
|
|||
|
return m_ptr;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
int CBotString::Compare(LPCTSTR lpsz) const
|
|||
|
{
|
|||
|
char* p = m_ptr;
|
|||
|
if (lpsz == NULL) lpsz = nilstring;
|
|||
|
if (m_ptr == NULL) p = nilstring;
|
|||
|
return strcmp(p, lpsz); // wcscmp
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|||
|
// tableaux de chaines
|
|||
|
|
|||
|
CBotStringArray::CBotStringArray()
|
|||
|
{
|
|||
|
m_pData = NULL;
|
|||
|
m_nSize = m_nMaxSize = 0;
|
|||
|
}
|
|||
|
|
|||
|
CBotStringArray::~CBotStringArray()
|
|||
|
{
|
|||
|
SetSize(0); // d<>truit les donn<6E>es !
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
int CBotStringArray::GivSize()
|
|||
|
{
|
|||
|
return m_nSize;
|
|||
|
}
|
|||
|
|
|||
|
void CBotStringArray::Add(const CBotString& str)
|
|||
|
{
|
|||
|
SetSize(m_nSize+1);
|
|||
|
|
|||
|
m_pData[m_nSize-1] = str;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
///////////////////////////////////////////////////////////////////////
|
|||
|
// routines utilitaires
|
|||
|
|
|||
|
static inline void ConstructElement(CBotString* pNewData)
|
|||
|
{
|
|||
|
memset(pNewData, 0, sizeof(CBotString));
|
|||
|
}
|
|||
|
|
|||
|
static inline void DestructElement(CBotString* pOldData)
|
|||
|
{
|
|||
|
pOldData->~CBotString();
|
|||
|
}
|
|||
|
|
|||
|
static inline void CopyElement(CBotString* pSrc, CBotString* pDest)
|
|||
|
{
|
|||
|
*pSrc = *pDest;
|
|||
|
}
|
|||
|
|
|||
|
static void ConstructElements(CBotString* pNewData, int nCount)
|
|||
|
{
|
|||
|
while (nCount--)
|
|||
|
{
|
|||
|
ConstructElement(pNewData);
|
|||
|
pNewData++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static void DestructElements(CBotString* pOldData, int nCount)
|
|||
|
{
|
|||
|
while (nCount--)
|
|||
|
{
|
|||
|
DestructElement(pOldData);
|
|||
|
pOldData++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static void CopyElements(CBotString* pDest, CBotString* pSrc, int nCount)
|
|||
|
{
|
|||
|
while (nCount--)
|
|||
|
{
|
|||
|
*pDest = *pSrc;
|
|||
|
++pDest;
|
|||
|
++pSrc;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// s<>lect la taille du tableau
|
|||
|
|
|||
|
void CBotStringArray::SetSize(int nNewSize)
|
|||
|
{
|
|||
|
if (nNewSize == 0)
|
|||
|
{
|
|||
|
// shrink to nothing
|
|||
|
|
|||
|
DestructElements(m_pData, m_nSize);
|
|||
|
delete[] (BYTE*)m_pData;
|
|||
|
m_pData = NULL;
|
|||
|
m_nSize = m_nMaxSize = 0;
|
|||
|
}
|
|||
|
else if (m_pData == NULL)
|
|||
|
{
|
|||
|
// create one with exact size
|
|||
|
m_pData = (CBotString*) new BYTE[nNewSize * sizeof(CBotString)];
|
|||
|
|
|||
|
ConstructElements(m_pData, nNewSize);
|
|||
|
|
|||
|
m_nSize = m_nMaxSize = nNewSize;
|
|||
|
}
|
|||
|
else if (nNewSize <= m_nMaxSize)
|
|||
|
{
|
|||
|
// it fits
|
|||
|
if (nNewSize > m_nSize)
|
|||
|
{
|
|||
|
// initialize the new elements
|
|||
|
|
|||
|
ConstructElements(&m_pData[m_nSize], nNewSize-m_nSize);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
else if (m_nSize > nNewSize) // destroy the old elements
|
|||
|
DestructElements(&m_pData[nNewSize], m_nSize-nNewSize);
|
|||
|
|
|||
|
m_nSize = nNewSize;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// otherwise, grow array
|
|||
|
int nGrowBy;
|
|||
|
{
|
|||
|
// heuristically determine growth when nGrowBy == 0
|
|||
|
// (this avoids heap fragmentation in many situations)
|
|||
|
nGrowBy = min(1024, max(4, m_nSize / 8));
|
|||
|
}
|
|||
|
int nNewMax;
|
|||
|
if (nNewSize < m_nMaxSize + nGrowBy)
|
|||
|
nNewMax = m_nMaxSize + nGrowBy; // granularity
|
|||
|
else
|
|||
|
nNewMax = nNewSize; // no slush
|
|||
|
|
|||
|
CBotString* pNewData = (CBotString*) new BYTE[nNewMax * sizeof(CBotString)];
|
|||
|
|
|||
|
// copy new data from old
|
|||
|
memcpy(pNewData, m_pData, m_nSize * sizeof(CBotString));
|
|||
|
|
|||
|
// construct remaining elements
|
|||
|
ConstructElements(&pNewData[m_nSize], nNewSize-m_nSize);
|
|||
|
|
|||
|
|
|||
|
// Ret rid of old stuff (note: no destructors called)
|
|||
|
delete[] (BYTE*)m_pData;
|
|||
|
m_pData = pNewData;
|
|||
|
m_nSize = nNewSize;
|
|||
|
m_nMaxSize = nNewMax;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
CBotString& CBotStringArray::operator[](int nIndex)
|
|||
|
{
|
|||
|
return ElementAt(nIndex);
|
|||
|
}
|
|||
|
|
|||
|
CBotString& CBotStringArray::ElementAt(int nIndex)
|
|||
|
{
|
|||
|
return m_pData[nIndex];
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|