For those of you that are particularly good at coding, can I pick your brains?
I have 3 particular versions of CString::replace(...) to cater for all possible combinations of parameters:
void replace(const char* strFind, const char* strReplace, const uint16_t nStartFrom = 0);
#ifndef __SAM3X8E__
void replace(const char* strFind, const __FlashStringHelper* strReplace, const uint16_t nStartFrom = 0);
void replace(const __FlashStringHelper* strFind, const char* strReplace, const uint16_t nStartFrom = 0);
void replace(const __FlashStringHelper* strFind, const __FlashStringHelper* strReplace, const uint16_t nStartFrom = 0);
#endif
Only the first version of this function implements the actual algorithm. The other versions simply copy the strings in flash memory to global memory and then call the call void replace(const char* strFind, const char* strReplace, const uint16_t nStartFrom = 0);
But the problem is the consecutive function calls are loading global memory and it is increasing the risk of memory corruption.
Is there are better way to implement these functions, that has not occurred to me, and that does not load global memory while also not requiring me to have 3 separate chunks of code that I need to change should I need to make changes to the algorithm.
#ifndef __SAM3X8E__
void CString::replace(const __FlashStringHelper* strFind, const __FlashStringHelper* strReplace, const uint16_t nStartFrom)
{
const uint16_t nLength = 256;
char strTemp1[nLength], strTemp2[nLength];
memset(strTemp1, 0, nLength);
memset(strTemp2, 0, nLength);
strcpy_P(strTemp1, (char*)strFind);
strcpy_P(strTemp2, (char*)strReplace);
replace(strTemp1, strTemp2, nStartFrom);
}
void CString::replace(const char* strFind, const __FlashStringHelper* strReplace, const uint16_t nStartFrom)
{
const uint16_t nLength = 256;
char strTemp[nLength], strTemp2[nLength];
memset(strTemp, 0, nLength);
strcpy_P(strTemp, (char*)strReplace);
replace(strFind, strTemp, nStartFrom);
}
void CString::replace(const __FlashStringHelper* strFind, const char* strReplace, const uint16_t nStartFrom)
{
const uint16_t nLength = 256;
char strTemp[nLength], strTemp2[nLength];
memset(strTemp, 0, nLength);
strcpy_P(strTemp, (char*)strFind);
replace(strTemp, strReplace, nStartFrom);
}
#endif
void CString::replace(const char* strFind, const char* strReplace, const uint16_t nStartFrom)
{
uint16_t nLengthMove = 0, nNewLength = 0;
const uint16_t nLength = 512;
char strTempBuff[nLength];
if ((strlen(m_strBuff) - strlen(strFind) + strlen_P((PGM_P)strReplace) + 1) <= m_nBuffSize)
{
if (nStartFrom < strlen(m_strBuff))
{
m_strStartPtr = m_strBuff + nStartFrom;
m_strEndPtr = strstr(m_strStartPtr, strFind);
if (m_strEndPtr)
{
nNewLength = strlen(m_strBuff) + strlen(strReplace) - strlen(strFind);
if (nNewLength < m_nBuffSize)
{
memset(strTempBuff, 0, nLength);
strncpy(strTempBuff, m_strBuff, m_strEndPtr - m_strStartPtr);
strcat(strTempBuff, strReplace);
strcat(strTempBuff, m_strEndPtr + strlen(strFind));
memset(m_strBuff, 0, m_nBuffSize);
strcpy(m_strBuff, strTempBuff);
}
}
}
}
}