summaryrefslogtreecommitdiffstats
path: root/src/CBot/CBotString.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/CBot/CBotString.cpp')
-rw-r--r--src/CBot/CBotString.cpp1384
1 files changed, 692 insertions, 692 deletions
diff --git a/src/CBot/CBotString.cpp b/src/CBot/CBotString.cpp
index 6acd96e..1b42c23 100644
--- a/src/CBot/CBotString.cpp
+++ b/src/CBot/CBotString.cpp
@@ -1,692 +1,692 @@
-// * This file is part of the COLOBOT source code
-// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
-// *
-// * This program is free software: you can redistribute it and/or modify
-// * it under the terms of the GNU General Public License as published by
-// * the Free Software Foundation, either version 3 of the License, or
-// * (at your option) any later version.
-// *
-// * This program is distributed in the hope that it will be useful,
-// * but WITHOUT ANY WARRANTY; without even the implied warranty of
-// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// * GNU General Public License for more details.
-// *
-// * You should have received a copy of the GNU General Public License
-// * along with this program. If not, see http://www.gnu.org/licenses/.
-/////////////////////////////////////////////////////
-
-//strings management
-
-#include "CBot.h"
-
-#include <cstdlib>
-#include <cstring>
-#include <algorithm>
-
-//Map is filled with id-string pars that are needed for CBot language parsing
-const std::map<EID, char *> 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, "%="},
- {ID_SUPER, "super"},
- {TX_UNDEF, "undefined"},
- {TX_NAN, "not a number"}
-};
-
-CBotString::CBotString()
-{
- m_ptr = NULL;
- m_lg = 0;
-}
-
-CBotString::~CBotString()
-{
- free(m_ptr); //we can call free on null pointer as it's save
-}
-
-
-CBotString::CBotString(const char* p)
-{
- m_lg = strlen(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_ptr = NULL;
- if (m_lg>0)
- {
- m_ptr = (char*)malloc(m_lg+1);
- strcpy(m_ptr, srcString.m_ptr);
- }
-}
-
-
-
-
-int CBotString::GivLength()
-{
- if (m_ptr == NULL) return 0;
- return strlen( m_ptr );
-}
-
-
-
-CBotString CBotString::Left(int nCount) const
-{
- 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(chain);
-}
-
-CBotString CBotString::Right(int nCount) const
-{
- char chain[2000];
-
- int i = m_lg - nCount;
- if ( i < 0 ) i = 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(chain);
-}
-
-CBotString CBotString::Mid(int nFirst, int nCount) const
-{
- char chain[2000];
-
- 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(chain);
-}
-
-CBotString CBotString::Mid(int nFirst) const
-{
- char chain[2000];
-
- size_t i;
- for (i = nFirst; i < m_lg && i < 1999 ; ++i)
- {
- chain[i] = m_ptr[i];
- }
- chain[i] = 0 ;
-
- return CBotString(chain);
-}
-
-
-int CBotString::Find(const char c)
-{
- 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 l = strlen(lpsz);
-
- 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;
-}
-
-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(const char * 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;
-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);
- strcpy(p, m_ptr+start);
- p[lg] = 0;
-
- res = p;
- free(p);
- return res;
-}
-
-void CBotString::MakeUpper()
-{
- 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()
-{
- 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';
- }
-}
-
-bool CBotString::LoadString(unsigned int id)
-{
- const char * str = NULL;
- str = MapIdToString((EID)id);
- if (m_ptr != NULL) free(m_ptr);
-
- 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)
-{
- free(m_ptr);
- 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);
- }
-
- return *this;
-}
-
-CBotString operator+(const CBotString& string, const char * 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);
-
- strcpy(p, m_ptr);
- char* pp = p + m_lg;
- strcpy(pp, stringSrc.m_ptr);
-
- free(m_ptr);
- m_ptr = p;
- m_lg += stringSrc.m_lg;
-
- return *this;
-}
-
-const CBotString& CBotString::operator=(const char ch)
-{
- 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)
-{
- free(m_ptr);
- m_ptr = NULL;
-
- if (pString != NULL)
- {
- m_lg = strlen(pString);
-
- if (m_lg != 0)
- {
- m_ptr = (char*)malloc(m_lg+1);
- strcpy(m_ptr, pString);
- }
- }
-
- return *this;
-}
-
-
-const CBotString& CBotString::operator+=(const char ch)
-{
- char* p = (char*)malloc(m_lg+2);
-
- if (m_ptr!=NULL) strcpy(p, m_ptr);
- p[m_lg++] = ch;
- p[m_lg] = 0;
-
- 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);
-
- strcpy(p, m_ptr);
- char* pp = p + m_lg;
- strcpy(pp, str.m_ptr);
-
- m_lg = m_lg + str.m_lg;
-
- 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() const
-{
- return (m_lg == 0);
-}
-
-void CBotString::Empty()
-{
- 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;
-}
-
-
-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
-}
-
-const char * CBotString::MapIdToString(EID id)
-{
- if (s_keywordString.find(id) != s_keywordString.end())
- {
- return s_keywordString.at(id);
- }
- else
- {
- return emptyString;
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////
-// arrays of strings
-
-CBotStringArray::CBotStringArray()
-{
- m_pData = NULL;
- m_nSize = m_nMaxSize = 0;
-}
-
-CBotStringArray::~CBotStringArray()
-{
- SetSize(0); // destroys data !
-}
-
-
-int CBotStringArray::GivSize()
-{
- return m_nSize;
-}
-
-void CBotStringArray::Add(const CBotString& str)
-{
- SetSize(m_nSize+1);
-
- m_pData[m_nSize-1] = str;
-}
-
-///////////////////////////////////////////////////////////////////////
-// utility routines
-
-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;
- }
-}
-
-
-
-// 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);
-
-
- // 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);
-}
-
-CBotString& CBotStringArray::ElementAt(int nIndex)
-{
- return m_pData[nIndex];
-}
-
+// * This file is part of the COLOBOT source code
+// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
+// *
+// * This program is free software: you can redistribute it and/or modify
+// * it under the terms of the GNU General Public License as published by
+// * the Free Software Foundation, either version 3 of the License, or
+// * (at your option) any later version.
+// *
+// * This program is distributed in the hope that it will be useful,
+// * but WITHOUT ANY WARRANTY; without even the implied warranty of
+// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// * GNU General Public License for more details.
+// *
+// * You should have received a copy of the GNU General Public License
+// * along with this program. If not, see http://www.gnu.org/licenses/.
+/////////////////////////////////////////////////////
+
+//strings management
+
+#include "CBot.h"
+
+#include <cstdlib>
+#include <cstring>
+#include <algorithm>
+
+//Map is filled with id-string pars that are needed for CBot language parsing
+const std::map<EID, char *> 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, "%="},
+ {ID_SUPER, "super"},
+ {TX_UNDEF, "undefined"},
+ {TX_NAN, "not a number"}
+};
+
+CBotString::CBotString()
+{
+ m_ptr = NULL;
+ m_lg = 0;
+}
+
+CBotString::~CBotString()
+{
+ free(m_ptr); //we can call free on null pointer as it's save
+}
+
+
+CBotString::CBotString(const char* p)
+{
+ m_lg = strlen(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_ptr = NULL;
+ if (m_lg>0)
+ {
+ m_ptr = (char*)malloc(m_lg+1);
+ strcpy(m_ptr, srcString.m_ptr);
+ }
+}
+
+
+
+
+int CBotString::GivLength()
+{
+ if (m_ptr == NULL) return 0;
+ return strlen( m_ptr );
+}
+
+
+
+CBotString CBotString::Left(int nCount) const
+{
+ 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(chain);
+}
+
+CBotString CBotString::Right(int nCount) const
+{
+ char chain[2000];
+
+ int i = m_lg - nCount;
+ if ( i < 0 ) i = 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(chain);
+}
+
+CBotString CBotString::Mid(int nFirst, int nCount) const
+{
+ char chain[2000];
+
+ 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(chain);
+}
+
+CBotString CBotString::Mid(int nFirst) const
+{
+ char chain[2000];
+
+ size_t i;
+ for (i = nFirst; i < m_lg && i < 1999 ; ++i)
+ {
+ chain[i] = m_ptr[i];
+ }
+ chain[i] = 0 ;
+
+ return CBotString(chain);
+}
+
+
+int CBotString::Find(const char c)
+{
+ 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 l = strlen(lpsz);
+
+ 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;
+}
+
+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(const char * 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;
+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);
+ strcpy(p, m_ptr+start);
+ p[lg] = 0;
+
+ res = p;
+ free(p);
+ return res;
+}
+
+void CBotString::MakeUpper()
+{
+ 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()
+{
+ 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';
+ }
+}
+
+bool CBotString::LoadString(unsigned int id)
+{
+ const char * str = NULL;
+ str = MapIdToString((EID)id);
+ if (m_ptr != NULL) free(m_ptr);
+
+ 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)
+{
+ free(m_ptr);
+ 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);
+ }
+
+ return *this;
+}
+
+CBotString operator+(const CBotString& string, const char * 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);
+
+ strcpy(p, m_ptr);
+ char* pp = p + m_lg;
+ strcpy(pp, stringSrc.m_ptr);
+
+ free(m_ptr);
+ m_ptr = p;
+ m_lg += stringSrc.m_lg;
+
+ return *this;
+}
+
+const CBotString& CBotString::operator=(const char ch)
+{
+ 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)
+{
+ free(m_ptr);
+ m_ptr = NULL;
+
+ if (pString != NULL)
+ {
+ m_lg = strlen(pString);
+
+ if (m_lg != 0)
+ {
+ m_ptr = (char*)malloc(m_lg+1);
+ strcpy(m_ptr, pString);
+ }
+ }
+
+ return *this;
+}
+
+
+const CBotString& CBotString::operator+=(const char ch)
+{
+ char* p = (char*)malloc(m_lg+2);
+
+ if (m_ptr!=NULL) strcpy(p, m_ptr);
+ p[m_lg++] = ch;
+ p[m_lg] = 0;
+
+ 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);
+
+ strcpy(p, m_ptr);
+ char* pp = p + m_lg;
+ strcpy(pp, str.m_ptr);
+
+ m_lg = m_lg + str.m_lg;
+
+ 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() const
+{
+ return (m_lg == 0);
+}
+
+void CBotString::Empty()
+{
+ 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;
+}
+
+
+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
+}
+
+const char * CBotString::MapIdToString(EID id)
+{
+ if (s_keywordString.find(id) != s_keywordString.end())
+ {
+ return s_keywordString.at(id);
+ }
+ else
+ {
+ return emptyString;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////
+// arrays of strings
+
+CBotStringArray::CBotStringArray()
+{
+ m_pData = NULL;
+ m_nSize = m_nMaxSize = 0;
+}
+
+CBotStringArray::~CBotStringArray()
+{
+ SetSize(0); // destroys data !
+}
+
+
+int CBotStringArray::GivSize()
+{
+ return m_nSize;
+}
+
+void CBotStringArray::Add(const CBotString& str)
+{
+ SetSize(m_nSize+1);
+
+ m_pData[m_nSize-1] = str;
+}
+
+///////////////////////////////////////////////////////////////////////
+// utility routines
+
+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;
+ }
+}
+
+
+
+// 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);
+
+
+ // 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);
+}
+
+CBotString& CBotStringArray::ElementAt(int nIndex)
+{
+ return m_pData[nIndex];
+}
+