Refactored CBotString to use std::string and CBotStringArray to use std::vector
parent
52a18de5c0
commit
5e23426b53
|
@ -25,6 +25,7 @@
|
|||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
//Map is filled with id-string pars that are needed for CBot language parsing
|
||||
const std::map<EID,const char *> CBotString::s_keywordString =
|
||||
|
@ -120,216 +121,97 @@ const std::map<EID,const char *> CBotString::s_keywordString =
|
|||
|
||||
CBotString::CBotString()
|
||||
{
|
||||
m_ptr = nullptr;
|
||||
m_lg = 0;
|
||||
m_str = "";
|
||||
}
|
||||
|
||||
CBotString::~CBotString()
|
||||
{
|
||||
delete[] m_ptr;
|
||||
m_ptr = nullptr;
|
||||
}
|
||||
|
||||
|
||||
CBotString::CBotString(const char* p)
|
||||
{
|
||||
m_lg = strlen(p);
|
||||
m_str = p;
|
||||
}
|
||||
|
||||
m_ptr = nullptr;
|
||||
if (m_lg>0)
|
||||
{
|
||||
m_ptr = new char[m_lg+1];
|
||||
strcpy(m_ptr, p);
|
||||
}
|
||||
CBotString::CBotString(const std::string &p)
|
||||
{
|
||||
m_str = p;
|
||||
}
|
||||
|
||||
CBotString::CBotString(const CBotString& srcString)
|
||||
{
|
||||
m_lg = srcString.m_lg;
|
||||
|
||||
m_ptr = nullptr;
|
||||
if (m_lg>0)
|
||||
{
|
||||
m_ptr = new char[m_lg+1];
|
||||
strcpy(m_ptr, srcString.m_ptr);
|
||||
}
|
||||
m_str = srcString.m_str;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int CBotString::GetLength()
|
||||
{
|
||||
if (m_ptr == nullptr) return 0;
|
||||
return strlen( m_ptr );
|
||||
return m_str.length();
|
||||
}
|
||||
|
||||
|
||||
|
||||
CBotString CBotString::Left(int nCount) const
|
||||
{
|
||||
char chain[2000];
|
||||
|
||||
// clamp nCount to correct value
|
||||
if(nCount < 0) nCount = 0;
|
||||
if(nCount > m_lg) nCount = m_lg;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < m_lg && i < nCount && i < 1999; ++i)
|
||||
{
|
||||
chain[i] = m_ptr[i];
|
||||
}
|
||||
chain[i] = 0 ;
|
||||
|
||||
return CBotString(chain);
|
||||
return CBotString(m_str.substr(0, nCount));
|
||||
}
|
||||
|
||||
CBotString CBotString::Right(int nCount) const
|
||||
{
|
||||
char chain[2000];
|
||||
|
||||
// clamp nCount to correct value
|
||||
if(nCount < 0) nCount = 0;
|
||||
if(nCount > m_lg) nCount = m_lg;
|
||||
|
||||
int i = m_lg - nCount;
|
||||
if ( i < 0 ) i = 0;
|
||||
|
||||
int j;
|
||||
for (j = 0 ; i < m_lg && i < 1999; ++i)
|
||||
{
|
||||
chain[j++] = m_ptr[i];
|
||||
}
|
||||
chain[j] = 0 ;
|
||||
|
||||
return CBotString(chain);
|
||||
return CBotString(m_str.substr(m_str.length()-nCount, std::string::npos));
|
||||
}
|
||||
|
||||
CBotString CBotString::Mid(int start, int lg)
|
||||
{
|
||||
CBotString res;
|
||||
|
||||
if (lg == -1) lg = 2000;
|
||||
|
||||
// clamp start to correct value
|
||||
if (start < 0) start = 0;
|
||||
if (start >= m_lg) return res;
|
||||
|
||||
int remaining = m_lg - start;
|
||||
if (lg > remaining) lg = remaining;
|
||||
if (lg < 0) lg = 0;
|
||||
|
||||
char* p = new char[m_lg+1];
|
||||
strcpy(p, m_ptr+start);
|
||||
p[lg] = 0;
|
||||
|
||||
res = p;
|
||||
delete[] p;
|
||||
return res;
|
||||
return CBotString(m_str.substr(start, lg));
|
||||
}
|
||||
|
||||
int CBotString::Find(const char c)
|
||||
{
|
||||
for (int i = 0; i < m_lg; ++i)
|
||||
{
|
||||
if (m_ptr[i] == c) return i;
|
||||
}
|
||||
return -1;
|
||||
std::size_t pos = m_str.find(c);
|
||||
return pos != std::string::npos ? pos : -1;
|
||||
}
|
||||
|
||||
int CBotString::Find(const char * lpsz)
|
||||
{
|
||||
int l = strlen(lpsz);
|
||||
|
||||
for (size_t i = 0; static_cast<int>(i) <= m_lg-l; ++i)
|
||||
{
|
||||
for (size_t j = 0; static_cast<int>(j) < l; ++j)
|
||||
{
|
||||
if (m_ptr[i+j] != lpsz[j]) goto bad;
|
||||
}
|
||||
return i;
|
||||
bad:;
|
||||
}
|
||||
return -1;
|
||||
std::size_t pos = m_str.find(lpsz);
|
||||
return pos != std::string::npos ? pos : -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;
|
||||
std::size_t pos = m_str.rfind(c);
|
||||
return pos != std::string::npos ? pos : -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;
|
||||
std::size_t pos = m_str.rfind(lpsz);
|
||||
return pos != std::string::npos ? pos : -1;
|
||||
}
|
||||
|
||||
void CBotString::MakeUpper()
|
||||
{
|
||||
for (size_t i = 0; static_cast<int>(i) < m_lg && static_cast<int>(i) < 1999 ; ++i)
|
||||
{
|
||||
char c = m_ptr[i];
|
||||
if ( c >= 'a' && c <= 'z' ) m_ptr[i] = c - 'a' + 'A';
|
||||
}
|
||||
boost::to_upper(m_str);
|
||||
}
|
||||
|
||||
void CBotString::MakeLower()
|
||||
{
|
||||
for (size_t i = 0; static_cast<int>(i) < m_lg && static_cast<int>(i) < 1999 ; ++i)
|
||||
{
|
||||
char c = m_ptr[i];
|
||||
if ( c >= 'A' && c <= 'Z' ) m_ptr[i] = c - 'A' + 'a';
|
||||
}
|
||||
boost::to_lower(m_str);
|
||||
}
|
||||
|
||||
bool CBotString::LoadString(unsigned int id)
|
||||
{
|
||||
const char * str = nullptr;
|
||||
str = MapIdToString(static_cast<EID>(id));
|
||||
if (m_ptr != nullptr)
|
||||
delete[] m_ptr;
|
||||
|
||||
m_lg = strlen(str);
|
||||
m_ptr = nullptr;
|
||||
if (m_lg > 0)
|
||||
{
|
||||
m_ptr = new char[m_lg+1];
|
||||
strcpy(m_ptr, str);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
m_str = MapIdToString(static_cast<EID>(id));
|
||||
return !m_str.empty();
|
||||
}
|
||||
|
||||
|
||||
const CBotString& CBotString::operator=(const CBotString& stringSrc)
|
||||
{
|
||||
delete[] m_ptr;
|
||||
m_ptr = nullptr;
|
||||
|
||||
m_lg = stringSrc.m_lg;
|
||||
|
||||
if (m_lg > 0)
|
||||
{
|
||||
m_ptr = new char[m_lg+1];
|
||||
strcpy(m_ptr, stringSrc.m_ptr);
|
||||
}
|
||||
|
||||
m_str = stringSrc.m_str;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -342,174 +224,114 @@ CBotString CBotString::operator+(const CBotString& stringSrc)
|
|||
|
||||
const CBotString& CBotString::operator=(const char ch)
|
||||
{
|
||||
delete[] m_ptr;
|
||||
|
||||
m_lg = 1;
|
||||
|
||||
m_ptr = new char[2];
|
||||
m_ptr[0] = ch;
|
||||
m_ptr[1] = 0;
|
||||
|
||||
m_str = ch;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const CBotString& CBotString::operator=(const char* pString)
|
||||
{
|
||||
delete[] m_ptr;
|
||||
m_ptr = nullptr;
|
||||
|
||||
if (pString != nullptr)
|
||||
{
|
||||
m_lg = strlen(pString);
|
||||
|
||||
if (m_lg != 0)
|
||||
{
|
||||
m_ptr = new char[m_lg+1];
|
||||
strcpy(m_ptr, pString);
|
||||
}
|
||||
}
|
||||
|
||||
m_str = pString;
|
||||
else
|
||||
m_str.clear();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
const CBotString& CBotString::operator+=(const char ch)
|
||||
{
|
||||
char* p = new char[m_lg+2];
|
||||
|
||||
if (m_ptr != nullptr) strcpy(p, m_ptr);
|
||||
p[m_lg++] = ch;
|
||||
p[m_lg] = 0;
|
||||
|
||||
delete[] m_ptr;
|
||||
|
||||
m_ptr = p;
|
||||
|
||||
m_str += ch;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const CBotString& CBotString::operator+=(const CBotString& str)
|
||||
{
|
||||
char* p = new char[m_lg+str.m_lg+1];
|
||||
|
||||
//-- Check if the pointer is not null befor trying to copy it
|
||||
if(m_ptr != nullptr)
|
||||
{
|
||||
strcpy(p, m_ptr);
|
||||
}
|
||||
|
||||
char* pp = p + m_lg;
|
||||
|
||||
//-- Check if the pointer is not null befor trying to copy it
|
||||
if(str.m_ptr != nullptr)
|
||||
{
|
||||
strcpy(pp, str.m_ptr);
|
||||
}
|
||||
|
||||
m_lg = m_lg + str.m_lg;
|
||||
|
||||
delete[] m_ptr;
|
||||
|
||||
m_ptr = p;
|
||||
|
||||
m_str += str.m_str;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool CBotString::operator==(const CBotString& str)
|
||||
{
|
||||
return Compare(str) == 0;
|
||||
return m_str == str.m_str;
|
||||
}
|
||||
|
||||
bool CBotString::operator==(const char* p)
|
||||
{
|
||||
return Compare(p) == 0;
|
||||
return m_str == p;
|
||||
}
|
||||
|
||||
bool CBotString::operator!=(const CBotString& str)
|
||||
{
|
||||
return Compare(str) != 0;
|
||||
return m_str != str.m_str;
|
||||
}
|
||||
|
||||
bool CBotString::operator!=(const char* p)
|
||||
{
|
||||
return Compare(p) != 0;
|
||||
return m_str != p;
|
||||
}
|
||||
|
||||
bool CBotString::operator>(const CBotString& str)
|
||||
{
|
||||
return Compare(str) > 0;
|
||||
return m_str > str.m_str;
|
||||
}
|
||||
|
||||
bool CBotString::operator>(const char* p)
|
||||
{
|
||||
return Compare(p) > 0;
|
||||
return m_str > p;
|
||||
}
|
||||
|
||||
bool CBotString::operator>=(const CBotString& str)
|
||||
{
|
||||
return Compare(str) >= 0;
|
||||
return m_str >= str.m_str;
|
||||
}
|
||||
|
||||
bool CBotString::operator>=(const char* p)
|
||||
{
|
||||
return Compare(p) >= 0;
|
||||
return m_str >= p;
|
||||
}
|
||||
|
||||
bool CBotString::operator<(const CBotString& str)
|
||||
{
|
||||
return Compare(str) < 0;
|
||||
return m_str < str.m_str;
|
||||
}
|
||||
|
||||
bool CBotString::operator<(const char* p)
|
||||
{
|
||||
return Compare(p) < 0;
|
||||
return m_str < p;
|
||||
}
|
||||
|
||||
bool CBotString::operator<=(const CBotString& str)
|
||||
{
|
||||
return Compare(str) <= 0;
|
||||
return m_str <= str.m_str;
|
||||
}
|
||||
|
||||
bool CBotString::operator<=(const char* p)
|
||||
{
|
||||
return Compare(p) <= 0;
|
||||
return m_str <= p;
|
||||
}
|
||||
|
||||
bool CBotString::IsEmpty() const
|
||||
{
|
||||
return (m_lg == 0);
|
||||
return m_str.empty();
|
||||
}
|
||||
|
||||
void CBotString::Empty()
|
||||
{
|
||||
delete[] m_ptr;
|
||||
m_ptr = nullptr;
|
||||
m_lg = 0;
|
||||
m_str.clear();
|
||||
}
|
||||
|
||||
static char emptyString[] = {0};
|
||||
static char emptyString[] = "";
|
||||
|
||||
CBotString::operator const char * () const
|
||||
{
|
||||
if (this == nullptr || m_ptr == nullptr) return emptyString;
|
||||
return m_ptr;
|
||||
if (this == nullptr) return emptyString; // TODO: can this be removed?
|
||||
return m_str.c_str();
|
||||
}
|
||||
|
||||
const char* CBotString::CStr() const
|
||||
{
|
||||
if (this == nullptr || m_ptr == nullptr)
|
||||
{
|
||||
return emptyString;
|
||||
}
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
int CBotString::Compare(const char * lpsz) const
|
||||
{
|
||||
char* p = m_ptr;
|
||||
if (lpsz == nullptr) lpsz = emptyString;
|
||||
if (m_ptr == nullptr) p = emptyString;
|
||||
return strcmp(p, lpsz); // wcscmp
|
||||
if (this == nullptr) return emptyString; // TODO: can this be removed?
|
||||
return m_str.c_str();
|
||||
}
|
||||
|
||||
const char * CBotString::MapIdToString(EID id)
|
||||
|
|
|
@ -31,13 +31,14 @@
|
|||
|
||||
/**
|
||||
* \brief CBotString Class used to work on strings
|
||||
* TODO: do not use this class, code should be refactored to use std::string instead
|
||||
*/
|
||||
class CBotString
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief CBotString Default constructor.
|
||||
* \brief CBotString Creates an empty string
|
||||
*/
|
||||
CBotString();
|
||||
|
||||
|
@ -47,6 +48,12 @@ public:
|
|||
*/
|
||||
CBotString(const char* p);
|
||||
|
||||
/**
|
||||
* \brief CBotString
|
||||
* \param p
|
||||
*/
|
||||
CBotString(const std::string& p);
|
||||
|
||||
/**
|
||||
* \brief CBotString
|
||||
* \param p
|
||||
|
@ -145,15 +152,6 @@ public:
|
|||
*/
|
||||
CBotString Right(int nCount) const;
|
||||
|
||||
/**
|
||||
* \brief Compare Compare a given string to an other.
|
||||
* \param lpsz The string to compare.
|
||||
* \return 0 if the two string matches. Less than 0 if the current
|
||||
* string is less than lpsz. Greater than 0 if the current
|
||||
* string is greater than lpsz.
|
||||
*/
|
||||
int Compare(const char* lpsz) const;
|
||||
|
||||
/**
|
||||
* \brief MakeUpper Uppercase the string.
|
||||
*/
|
||||
|
@ -198,11 +196,8 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
//! \brief Pointer to string
|
||||
char* m_ptr;
|
||||
|
||||
//! \brief Length of the string
|
||||
int m_lg;
|
||||
//! \brief String
|
||||
std::string m_str;
|
||||
|
||||
//! \brief Keeps the string corresponding to keyword ID
|
||||
static const std::map<EID, const char *> s_keywordString;
|
||||
|
|
|
@ -17,112 +17,35 @@
|
|||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
// Modules inlcude
|
||||
#include "CBot/CBotStringArray.h"
|
||||
|
||||
#include "CBot/CBotUtils.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
|
||||
// Forward declaration
|
||||
#include <cstring>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotStringArray::CBotStringArray()
|
||||
{
|
||||
m_pData = nullptr;
|
||||
m_nSize = m_nMaxSize = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotStringArray::~CBotStringArray()
|
||||
{
|
||||
SetSize(0); // destroys data !
|
||||
m_data.clear(); // destroys data !
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int CBotStringArray::GetSize()
|
||||
{
|
||||
return m_nSize;
|
||||
return m_data.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotStringArray::Add(const CBotString& str)
|
||||
{
|
||||
SetSize(m_nSize+1);
|
||||
|
||||
m_pData[m_nSize-1] = str;
|
||||
m_data.push_back(str);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void CBotStringArray::SetSize(int nNewSize)
|
||||
{
|
||||
if (nNewSize == 0)
|
||||
{
|
||||
// shrink to nothing
|
||||
|
||||
DestructElements(m_pData, m_nSize);
|
||||
delete[] reinterpret_cast<unsigned char *>(m_pData);
|
||||
m_pData = nullptr;
|
||||
m_nSize = m_nMaxSize = 0;
|
||||
}
|
||||
else if (m_pData == nullptr)
|
||||
{
|
||||
// create one with exact size
|
||||
m_pData = reinterpret_cast<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 = reinterpret_cast<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[] reinterpret_cast<unsigned char *>(m_pData);
|
||||
m_pData = pNewData;
|
||||
m_nSize = nNewSize;
|
||||
m_nMaxSize = nNewMax;
|
||||
}
|
||||
m_data.resize(nNewSize);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -134,5 +57,5 @@ CBotString& CBotStringArray::operator[](int nIndex)
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
CBotString& CBotStringArray::ElementAt(int nIndex)
|
||||
{
|
||||
return m_pData[nIndex];
|
||||
return m_data[nIndex];
|
||||
}
|
||||
|
|
|
@ -19,15 +19,13 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
// Modules inlcude
|
||||
#include "CBot/CBotString.h"
|
||||
|
||||
// Local include
|
||||
|
||||
// Global include
|
||||
#include <vector>
|
||||
|
||||
/*!
|
||||
* \brief The CBotStringArray class Class used to arrays of strings management.
|
||||
* TODO: refactor code to use std::vector instead
|
||||
*/
|
||||
class CBotStringArray : public CBotString
|
||||
{
|
||||
|
@ -77,9 +75,5 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
//! Number of elements.
|
||||
int m_nSize;
|
||||
//! Reserved size.
|
||||
int m_nMaxSize;
|
||||
CBotString* m_pData;
|
||||
std::vector<CBotString> m_data;
|
||||
};
|
||||
|
|
|
@ -159,22 +159,6 @@ TEST(CBotString_Test, Right)
|
|||
EXPECT_STREQ(str1.Right(7).CStr(), "Colobot");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CBotString_Test.Compare Check Compare function of class
|
||||
* CBotString_Test
|
||||
*/
|
||||
TEST(CBotString_Test, Compare)
|
||||
{
|
||||
CBotString str1("colobot");
|
||||
EXPECT_EQ(0, str1.Compare("colobot"));
|
||||
|
||||
CBotString str2("a");
|
||||
EXPECT_GT(0, str2.Compare("colobot"));
|
||||
|
||||
CBotString str3("z");
|
||||
EXPECT_LT(0, str3.Compare("colobot"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CBotString_Test.MakeUpper Check MakeUpper function of class
|
||||
* CBotString_Test
|
||||
|
|
Loading…
Reference in New Issue