summaryrefslogtreecommitdiffstats
path: root/src/CBot/CBotString.cpp
diff options
context:
space:
mode:
authorZaba999 <zaba.marcin@gmail.com>2012-07-10 22:58:52 +0200
committerZaba999 <zaba.marcin@gmail.com>2012-07-10 22:58:52 +0200
commit1910219518afb26edf7329e0945b9ddba8061a08 (patch)
tree57e72fa1803ab58358cab01055d883aa2fc32e60 /src/CBot/CBotString.cpp
parentdbd62c96aa351dc1c21e3392348edda2eb012e09 (diff)
downloadcolobot-1910219518afb26edf7329e0945b9ddba8061a08.tar.gz
colobot-1910219518afb26edf7329e0945b9ddba8061a08.tar.bz2
colobot-1910219518afb26edf7329e0945b9ddba8061a08.zip
Dependency on WINAPI completely removed.
Diffstat (limited to 'src/CBot/CBotString.cpp')
-rw-r--r--src/CBot/CBotString.cpp710
1 files changed, 398 insertions, 312 deletions
diff --git a/src/CBot/CBotString.cpp b/src/CBot/CBotString.cpp
index 5f35337..33e1d04 100644
--- a/src/CBot/CBotString.cpp
+++ b/src/CBot/CBotString.cpp
@@ -13,53 +13,145 @@
// *
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/./////////////////////////////////////////////////////
-// gestion de chaine
-// basé sur le CString de MFC
-// mais moins complet
+
+//strings management
#include "CBot.h"
#include <cstdlib>
#include <cstring>
#include <algorithm>
-/// TODO need to be implemented to be able to load library
-// HINSTANCE CBotString::m_hInstance = (HINSTANCE)LoadLibrary("libCbot.dll"); // how to retrieve it otherwise ??
+//Map is filled with id-string pars that are needed for CBot language parsing
+const std::map<EID, const char const *> CBotString::s_keywordString =
+{
+ {ID_IF, "if"},
+ {ID_ELSE, "else"},
+ {ID_WHILE, "while"},
+ {ID_DO, "do"},
+ {ID_FOR, "for"},
+ {ID_BREAK, "break"},
+ {ID_CONTINUE, "continue"},
+ {ID_SWITCH, "switch"},
+ {ID_CASE, "case"},
+ {ID_DEFAULT, "default"},
+ {ID_TRY, "try"},
+ {ID_THROW, "throw"},
+ {ID_CATCH, "catch"},
+ {ID_FINALLY, "finally"},
+ {ID_TXT_AND, "and"},
+ {ID_TXT_OR, "or"},
+ {ID_TXT_NOT, "not"},
+ {ID_RETURN, "return"},
+ {ID_CLASS, "class"},
+ {ID_EXTENDS, "extends"},
+ {ID_SYNCHO, "synchronized"},
+ {ID_NEW, "new"},
+ {ID_PUBLIC, "public"},
+ {ID_EXTERN, "extern"},
+ {ID_FINAL, "final"},
+ {ID_STATIC, "static"},
+ {ID_PROTECTED, "protected"},
+ {ID_PRIVATE, "private"},
+ {ID_REPEAT, "repeat"},
+ {ID_DEBUGDD, "STARTDEBUGDD"},
+ {ID_INT, "int"},
+ {ID_FLOAT, "float"},
+ {ID_BOOLEAN, "boolean"},
+ {ID_STRING, "string"},
+ {ID_VOID, "void"},
+ {ID_BOOL, "bool"},
+ {ID_TRUE, "true"},
+ {ID_FALSE, "false"},
+ {ID_NULL, "null"},
+ {ID_NAN, "nan"},
+ {ID_OPENPAR, "("},
+ {ID_CLOSEPAR, ")"},
+ {ID_OPBLK, "{"},
+ {ID_CLBLK, "}"},
+ {ID_SEP, "},"},
+ {ID_COMMA, ","},
+ {ID_DOTS, ":"},
+ {ID_DOT, "."},
+ {ID_OPBRK, "["},
+ {ID_CLBRK, "]"},
+ {ID_DBLDOTS, "::"},
+ {ID_LOGIC, "?"},
+ {ID_ADD, "+"},
+ {ID_SUB, "-"},
+ {ID_MUL, "*"},
+ {ID_DIV, "/"},
+ {ID_ASS, "="},
+ {ID_ASSADD, "+="},
+ {ID_ASSSUB, "-="},
+ {ID_ASSMUL, "*="},
+ {ID_ASSDIV, "/="},
+ {ID_ASSOR, "|="},
+ {ID_ASSAND, "&="},
+ {ID_ASSXOR, "^="},
+ {ID_ASSSL, "<<="},
+ {ID_ASSSR, ">>>="},
+ {ID_ASSASR, ">>="},
+ {ID_SL, "<<"},
+ {ID_SR, ">>"},
+ {ID_ASR, ">>"},
+ {ID_INC, "++"},
+ {ID_DEC, "--"},
+ {ID_LO, "<"},
+ {ID_HI, ">"},
+ {ID_LS, "<<"},
+ {ID_HS, ">="},
+ {ID_EQ, "=="},
+ {ID_NE, "!="},
+ {ID_AND, "&"},
+ {ID_XOR, "^"},
+ {ID_OR, "|"},
+ {ID_LOG_AND, "&&"},
+ {ID_LOG_OR, "||"},
+ {ID_LOG_NOT, "!"},
+ {ID_NOT, "~"},
+ {ID_MODULO, "%"},
+ {ID_POWER, "**"},
+ {ID_ASSMODULO, "%="},
+ {TX_UNDEF, "undefined"},
+ {TX_NAN, "not a number"},
+ {ID_SUPER, "super"}
+};
CBotString::CBotString()
{
- m_ptr = NULL; // chaine vide
- m_lg = 0;
+ m_ptr = NULL;
+ m_lg = 0;
}
CBotString::~CBotString()
{
- if (m_ptr != NULL) free(m_ptr);
+ free(m_ptr); //we can call free on null pointer as it's save
}
CBotString::CBotString(const char* p)
{
- m_lg = strlen( p );
+ m_lg = strlen(p);
- m_ptr = NULL;
- if (m_lg>0)
- {
- m_ptr = (char*)malloc(m_lg+1);
- strcpy(m_ptr, p);
- }
+ m_ptr = NULL;
+ if (m_lg>0)
+ {
+ m_ptr = (char*)malloc(m_lg+1);
+ strcpy(m_ptr, p);
+ }
}
CBotString::CBotString(const CBotString& srcString)
{
- m_lg = srcString.m_lg;
+ m_lg = srcString.m_lg;
- m_ptr = NULL;
- if (m_lg>0)
- {
- m_ptr = (char*)malloc(m_lg+1);
- strcpy(m_ptr, srcString.m_ptr);
- }
+ m_ptr = NULL;
+ if (m_lg>0)
+ {
+ m_ptr = (char*)malloc(m_lg+1);
+ strcpy(m_ptr, srcString.m_ptr);
+ }
}
@@ -67,539 +159,533 @@ CBotString::CBotString(const CBotString& srcString)
int CBotString::GivLength()
{
- if ( m_ptr == NULL ) return 0;
- return strlen( m_ptr );
+ if (m_ptr == NULL) return 0;
+ return strlen( 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 ;
+ char chain[2000];
+
+ size_t i;
+ for (i = 0; i < m_lg && i < nCount && i < 1999; ++i)
+ {
+ chain[i] = m_ptr[i];
+ }
+ chain[i] = 0 ;
- return CBotString( chaine );
+ return CBotString(chain);
}
CBotString CBotString::Right(int nCount) const
{
- char chaine[2000];
-
- int i = m_lg - nCount;
- if ( i < 0 ) i = 0;
+ char chain[2000];
+
+ int i = m_lg - nCount;
+ if ( i < 0 ) i = 0;
- int j;
- for ( j = 0 ; i < m_lg && i < 1999; i++)
- {
- chaine[j++] = m_ptr[i];
- }
- chaine[j] = 0 ;
+ size_t j;
+ for (size_t j = 0 ; i < m_lg && i < 1999; ++i)
+ {
+ chain[j++] = m_ptr[i];
+ }
+ chain[j] = 0 ;
- return CBotString( chaine );
+ return CBotString(chain);
}
CBotString CBotString::Mid(int nFirst, int nCount) const
{
- char chaine[2000];
-
- int i;
+ char chain[2000];
- for ( i = nFirst; i < m_lg && i < 1999 && i <= nFirst + nCount; i++)
- {
- chaine[i] = m_ptr[i];
- }
- chaine[i] = 0 ;
+ size_t i;
+ for (i = nFirst; i < m_lg && i < 1999 && i <= nFirst + nCount; ++i)
+ {
+ chain[i] = m_ptr[i];
+ }
+ chain[i] = 0 ;
- return CBotString( chaine );
+ return CBotString(chain);
}
CBotString CBotString::Mid(int nFirst) const
{
- char chaine[2000];
-
- int i;
+ char chain[2000];
- for ( i = nFirst; i < m_lg && i < 1999 ; i++)
- {
- chaine[i] = m_ptr[i];
- }
- chaine[i] = 0 ;
+ size_t i;
+ for (i = nFirst; i < m_lg && i < 1999 ; ++i)
+ {
+ chain[i] = m_ptr[i];
+ }
+ chain[i] = 0 ;
- return CBotString( chaine );
+ return CBotString(chain);
}
int CBotString::Find(const char c)
{
- int i;
- for (i = 0; i < m_lg; i++)
- {
- if (m_ptr[i] == c) return i;
- }
- return -1;
+ for (size_t i = 0; i < m_lg; ++i)
+ {
+ if (m_ptr[i] == c) return i;
+ }
+ return -1;
}
int CBotString::Find(const char * lpsz)
{
- int i, j;
- int l = strlen(lpsz);
+ int l = strlen(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;
+ for (size_t i = 0; i <= m_lg-l; ++i)
+ {
+ for (size_t j = 0; j < l; ++j)
+ {
+ if (m_ptr[i+j] != lpsz[j]) goto bad;
+ }
+ return i;
bad:;
- }
- return -1;
+ }
+ 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 i;
+ for (i = m_lg-1; i >= 0; --i)
+ {
+ if (m_ptr[i] == c) return i;
+ }
+ return -1;
}
int CBotString::ReverseFind(const char * lpsz)
{
- int i, j;
- int l = strlen(lpsz);
+ int i, j;
+ int l = strlen(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;
+ 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;
+ }
+ return -1;
}
CBotString CBotString::Mid(int start, int lg)
{
- CBotString res;
- if (start >= m_lg) return res;
+ CBotString res;
+ if (start >= m_lg) return res;
- if ( lg < 0 ) lg = m_lg - start;
+ if ( lg < 0 ) lg = m_lg - start;
- char* p = (char*)malloc(m_lg+1);
- strcpy(p, m_ptr+start);
- p[lg] = 0;
+ char* p = (char*)malloc(m_lg+1);
+ strcpy(p, m_ptr+start);
+ p[lg] = 0;
- res = p;
- free(p);
- return res;
+ 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';
- }
+ for (size_t 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';
- }
+ for (size_t 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(unsigned int id)
{
- char buffer[MAXSTRING];
- /// \TODO implement loading strings from resources. Figure out how to do it
- // m_lg = ::LoadString( m_hInstance, id, buffer, MAXSTRING );
-
- if (m_ptr != NULL) free(m_ptr);
+ const char * str = NULL;
+ str = MapIdToString((EID)id);
+ if (m_ptr != NULL) free(m_ptr);
- m_ptr = NULL;
- if (m_lg > 0)
- {
- m_ptr = (char*)malloc(m_lg+1);
- strcpy(m_ptr, buffer);
- return true;
- }
- return false;
+ m_lg = strlen(str);
+ m_ptr = NULL;
+ if (m_lg > 0)
+ {
+ m_ptr = (char*)malloc(m_lg+1);
+ strcpy(m_ptr, str);
+ return true;
+ }
+ return false;
}
-
+
const CBotString& CBotString::operator=(const CBotString& stringSrc)
{
- if (m_ptr != NULL) free(m_ptr);
+ free(m_ptr);
+ m_ptr = NULL;
- m_lg = stringSrc.m_lg;
- m_ptr = NULL;
+ m_lg = stringSrc.m_lg;
- if (m_lg > 0)
- {
- m_ptr = (char*)malloc(m_lg+1);
- strcpy(m_ptr, stringSrc.m_ptr);
- }
+ if (m_lg > 0)
+ {
+ m_ptr = (char*)malloc(m_lg+1);
+ strcpy(m_ptr, stringSrc.m_ptr);
+ }
- return *this;
+ return *this;
}
CBotString operator+(const CBotString& string, const char * lpsz)
{
- CBotString s ( string );
- s += lpsz;
- return s;
+ CBotString s(string);
+ s += lpsz;
+ return s;
}
const CBotString& CBotString::operator+(const CBotString& stringSrc)
{
- char* p = (char*)malloc(m_lg+stringSrc.m_lg+1);
+ char* p = (char*)malloc(m_lg+stringSrc.m_lg+1);
- strcpy(p, m_ptr);
- char* pp = p + m_lg;
- strcpy(pp, stringSrc.m_ptr);
+ strcpy(p, m_ptr);
+ char* pp = p + m_lg;
+ strcpy(pp, stringSrc.m_ptr);
- if (m_ptr != NULL) free(m_ptr);
- m_ptr = p;
- m_lg += stringSrc.m_lg;
+ free(m_ptr);
+ m_ptr = p;
+ m_lg += stringSrc.m_lg;
- return *this;
+ return *this;
}
const CBotString& CBotString::operator=(const char ch)
{
- if (m_ptr != NULL) free(m_ptr);
+ free(m_ptr);
+
+ m_lg = 1;
- m_lg = 1;
+ m_ptr = (char*)malloc(2);
+ m_ptr[0] = ch;
+ m_ptr[1] = 0;
- m_ptr = (char*)malloc(2);
- m_ptr[0] = ch;
- m_ptr[1] = 0;
-
- return *this;
+ return *this;
}
const CBotString& CBotString::operator=(const char* pString)
{
- if (m_ptr != NULL) free(m_ptr);
- m_ptr = NULL;
+ free(m_ptr);
+ m_ptr = NULL;
+
+ if (pString != NULL)
+ {
+ m_lg = strlen(pString);
- if ( pString != NULL )
- {
- m_lg = strlen(pString);
+ if (m_lg != 0)
+ {
+ m_ptr = (char*)malloc(m_lg+1);
+ strcpy(m_ptr, pString);
+ }
+ }
- if (m_lg != 0)
- {
- m_ptr = (char*)malloc(m_lg+1);
- strcpy(m_ptr, pString);
- }
- }
-
- return *this;
+ return *this;
}
const CBotString& CBotString::operator+=(const char ch)
{
- char* p = (char*)malloc(m_lg+2);
+ char* p = (char*)malloc(m_lg+2);
- if (m_ptr!=NULL) strcpy(p, m_ptr);
- p[m_lg++] = ch;
- p[m_lg] = 0;
+ if (m_ptr!=NULL) strcpy(p, m_ptr);
+ p[m_lg++] = ch;
+ p[m_lg] = 0;
- if (m_ptr != NULL) free(m_ptr);
+ free(m_ptr);
- m_ptr = p;
+ m_ptr = p;
- return *this;
+ return *this;
}
const CBotString& CBotString::operator+=(const CBotString& str)
{
- char* p = (char*)malloc(m_lg+str.m_lg+1);
+ char* p = (char*)malloc(m_lg+str.m_lg+1);
- strcpy(p, m_ptr);
- char* pp = p + m_lg;
- strcpy(pp, str.m_ptr);
+ strcpy(p, m_ptr);
+ char* pp = p + m_lg;
+ strcpy(pp, str.m_ptr);
- m_lg = m_lg + str.m_lg;
+ m_lg = m_lg + str.m_lg;
- if (m_ptr != NULL) free(m_ptr);
+ free(m_ptr);
- m_ptr = p;
+ m_ptr = p;
- return *this;
+ return *this;
}
bool CBotString::operator==(const CBotString& str)
{
- return Compare(str) == 0;
+ return Compare(str) == 0;
}
bool CBotString::operator==(const char* p)
{
- return Compare(p) == 0;
+ return Compare(p) == 0;
}
bool CBotString::operator!=(const CBotString& str)
{
- return Compare(str) != 0;
+ return Compare(str) != 0;
}
bool CBotString::operator!=(const char* p)
{
- return Compare(p) != 0;
+ return Compare(p) != 0;
}
bool CBotString::operator>(const CBotString& str)
{
- return Compare(str) > 0;
+ return Compare(str) > 0;
}
bool CBotString::operator>(const char* p)
{
- return Compare(p) > 0;
+ return Compare(p) > 0;
}
bool CBotString::operator>=(const CBotString& str)
{
- return Compare(str) >= 0;
+ return Compare(str) >= 0;
}
bool CBotString::operator>=(const char* p)
{
- return Compare(p) >= 0;
+ return Compare(p) >= 0;
}
bool CBotString::operator<(const CBotString& str)
{
- return Compare(str) < 0;
+ return Compare(str) < 0;
}
bool CBotString::operator<(const char* p)
{
- return Compare(p) < 0;
+ return Compare(p) < 0;
}
bool CBotString::operator<=(const CBotString& str)
{
- return Compare(str) <= 0;
+ return Compare(str) <= 0;
}
bool CBotString::operator<=(const char* p)
{
- return Compare(p) <= 0;
+ return Compare(p) <= 0;
}
bool CBotString::IsEmpty() const
{
- return (m_lg == 0);
+ return (m_lg == 0);
}
void CBotString::Empty()
{
- if (m_ptr != NULL) free(m_ptr);
- m_ptr = NULL;
- m_lg = 0;
+ free(m_ptr);
+ m_ptr = NULL;
+ m_lg = 0;
}
static char emptyString[] = {0};
CBotString::operator const char * () const
{
- if (this == NULL || m_ptr == NULL) return emptyString;
- return m_ptr;
+ if (this == NULL || m_ptr == NULL) return emptyString;
+ return m_ptr;
}
int CBotString::Compare(const char * lpsz) const
{
- char* p = m_ptr;
- if (lpsz == NULL) lpsz = emptyString;
- if (m_ptr == NULL) p = emptyString;
- return strcmp(p, lpsz); // wcscmp
+ char* p = m_ptr;
+ if (lpsz == NULL) lpsz = emptyString;
+ if (m_ptr == NULL) p = emptyString;
+ return strcmp(p, lpsz); // wcscmp
}
-
+const char * CBotString::MapIdToString(EID id)
+{
+ if (s_keywordString.find(id) != s_keywordString.end())
+ {
+ return s_keywordString.at(id);
+ }
+ else
+ {
+ return emptyString;
+ }
+}
///////////////////////////////////////////////////////////////////////////////////////////
-// tableaux de chaines
+// arrays of strings
CBotStringArray::CBotStringArray()
{
- m_pData = NULL;
- m_nSize = m_nMaxSize = 0;
+ m_pData = NULL;
+ m_nSize = m_nMaxSize = 0;
}
CBotStringArray::~CBotStringArray()
{
- SetSize(0); // détruit les données !
+ SetSize(0); // destroys data !
}
int CBotStringArray::GivSize()
{
- return m_nSize;
+ return m_nSize;
}
void CBotStringArray::Add(const CBotString& str)
{
- SetSize(m_nSize+1);
+ SetSize(m_nSize+1);
- m_pData[m_nSize-1] = str;
+ m_pData[m_nSize-1] = str;
}
-
///////////////////////////////////////////////////////////////////////
-// routines utilitaires
+// utility routines
static inline void ConstructElement(CBotString* pNewData)
{
- memset(pNewData, 0, sizeof(CBotString));
+ memset(pNewData, 0, sizeof(CBotString));
}
static inline void DestructElement(CBotString* pOldData)
{
- pOldData->~CBotString();
+ pOldData->~CBotString();
}
static inline void CopyElement(CBotString* pSrc, CBotString* pDest)
{
- *pSrc = *pDest;
+ *pSrc = *pDest;
}
static void ConstructElements(CBotString* pNewData, int nCount)
{
- while (nCount--)
- {
- ConstructElement(pNewData);
- pNewData++;
- }
+ while (nCount--)
+ {
+ ConstructElement(pNewData);
+ pNewData++;
+ }
}
static void DestructElements(CBotString* pOldData, int nCount)
{
- while (nCount--)
- {
- DestructElement(pOldData);
- pOldData++;
- }
+ while (nCount--)
+ {
+ DestructElement(pOldData);
+ pOldData++;
+ }
}
static void CopyElements(CBotString* pDest, CBotString* pSrc, int nCount)
{
- while (nCount--)
- {
- *pDest = *pSrc;
- ++pDest;
- ++pSrc;
- }
+ while (nCount--)
+ {
+ *pDest = *pSrc;
+ ++pDest;
+ ++pSrc;
+ }
}
-// sélect la taille du tableau
+// set the array size
void CBotStringArray::SetSize(int nNewSize)
{
- if (nNewSize == 0)
- {
- // shrink to nothing
-
- DestructElements(m_pData, m_nSize);
- delete[] (unsigned char *)m_pData;
- m_pData = NULL;
- m_nSize = m_nMaxSize = 0;
- }
- else if (m_pData == NULL)
- {
- // create one with exact size
- m_pData = (CBotString*) new unsigned char[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 = std::min(1024, std::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 unsigned char[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[] (unsigned char *)m_pData;
- m_pData = pNewData;
- m_nSize = nNewSize;
- m_nMaxSize = nNewMax;
- }
+ if (nNewSize == 0)
+ {
+ // shrink to nothing
+
+ DestructElements(m_pData, m_nSize);
+ delete[] (unsigned char *)m_pData;
+ m_pData = NULL;
+ m_nSize = m_nMaxSize = 0;
+ }
+ else if (m_pData == NULL)
+ {
+ // create one with exact size
+ m_pData = (CBotString*) new unsigned char[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 = std::min(1024, std::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 unsigned char[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);
+
+
+ // Get rid of old stuff (note: no destructors called)
+ delete[] (unsigned char *)m_pData;
+ m_pData = pNewData;
+ m_nSize = nNewSize;
+ m_nMaxSize = nNewMax;
+ }
}
CBotString& CBotStringArray::operator[](int nIndex)
{
- return ElementAt(nIndex);
+ return ElementAt(nIndex);
}
CBotString& CBotStringArray::ElementAt(int nIndex)
{
- return m_pData[nIndex];
+ return m_pData[nIndex];
}
-
-