diff options
Diffstat (limited to 'src/CBot/CBotString.cpp')
-rw-r--r-- | src/CBot/CBotString.cpp | 1383 |
1 files changed, 692 insertions, 691 deletions
diff --git a/src/CBot/CBotString.cpp b/src/CBot/CBotString.cpp index 9d5d257..1b42c23 100644 --- a/src/CBot/CBotString.cpp +++ b/src/CBot/CBotString.cpp @@ -1,691 +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]; +} + |