AffxByteArray AffxByteArray::reverseComplement()
{
	AffxByteArray ba = *this;
    AffxString strComplement = "tvghefcdijmlknopqysaabwxrz";
    char by = 0;
	int iCount = getSize();
	int iIndex = 0;
    
    ba.toLowerCase();
    if (((iCount / 2) * 2) != iCount)
    {
		iIndex = (iCount / 2);
        ba.setAt(iIndex, strComplement.getAt(ba.getAt(iIndex) - 'a'));
    }
    
    for (int i = 0; (i < (iCount / 2)); i++)
    {
		iIndex = (iCount - i - 1);
        by = ba.getAt(i);
        ba.setAt(i, strComplement.getAt(ba.getAt(iIndex) - 'a'));
        ba.setAt(iIndex, strComplement.getAt(by - 'a'));
    }

	return ba;
}  
bool AffxByteArray::equals(const AffxString &str) const
{
	bool bEqual = false;

	int iThisSize = getSize();
	int iThatSize = (int)str.length();

	if (iThisSize == iThatSize)
	{
		if ((iThisSize == 0) && (iThatSize == 0)) {bEqual = true;}
		else
		{
			for (int i = 0; (i < iThisSize); i++)
			{
				if (getAt(i) == str.getAt(i))
					bEqual = true;
				else
				{
					bEqual = false;
					break;
				}
			}
		}
	}

	return bEqual;
}
AffxString CNReporter::prepareAscii(const AffxString& str, int iLength)
{
  AffxString strPrepared = str;
  int iActualLength = (int)strPrepared.length();
  strPrepared.padBlanks(iLength);
  strPrepared.setAt(iActualLength, 0);
  return strPrepared;
}
void CNReporter::loadBuffer(char* pBuffer, int& iIndex, AffxString& str, int iLength)
{
  if (iLength == -1) {
    iLength = str.length();
  }
  unsigned int ui = htonl(iLength);
  memcpy((void*)(pBuffer + iIndex), (void*)&ui, sizeof(unsigned int));
  iIndex += sizeof(unsigned int);
  memcpy((void*)(pBuffer + iIndex), str.c_str(), iLength); iIndex += iLength;
}
int AffxByteArray::append(const AffxString& srcIn)
{
	AffxString src = srcIn;

	int nOldSize = m_nSize;
	setSize(m_nSize + (int)src.length());

	memcpy(m_pData + nOldSize, src.c_str(), src.length() * sizeof(char));

	return nOldSize;
}
void CNReporter::loadParam(const AffxString& strName, PgOpt::PgOptType type, const AffxString& strValue, affymetrix_calvin_parameter::ParameterNameValueType& param)
{
  param.SetName(StringUtils::ConvertMBSToWCS(strName));
  switch (type) {
  case PgOpt::BOOL_OPT: param.SetValueInt8(((strValue == "true") ? (char)1 : (char)0)); break;
  case PgOpt::DOUBLE_OPT: param.SetValueFloat((float)::getDouble(strValue)); break;
  case PgOpt::INT_OPT: param.SetValueInt32(::getInt(strValue)); break;
  case PgOpt::STRING_OPT:
    if ((strName.indexOf("command-line") != -1) || (strName.indexOf("analysis") != -1) || (strName.indexOf("program-cvs-id") != -1) || (strName.indexOf("version-to-report") != -1) || (strName.endsWith("-dir"))) {
      param.SetValueText(StringUtils::ConvertMBSToWCS(strValue));
    } else {
      param.SetValueText(StringUtils::ConvertMBSToWCS(Fs::basename(strValue)));
    }
    break;
  default: throw(Except("Cannot find PgOpt type for: " + strName));
  }
}
/**
 * @brief Return the array name
 * @return AffxString - The array name
 */
AffxString CNReporter::getArrayName()
{
  AffxString strArrayName;
  if (m_pEngine->getOpt("array-name") == "") {
    if ((m_pEngine->isOptDefined("cdf-file")) && (m_pEngine->getOpt("cdf-file") != "")) {
      strArrayName = Fs::basename(m_pEngine->getOpt("cdf-file"));
      int iFindIndex = strArrayName.indexOf(".");
      if (iFindIndex != -1) {
        strArrayName = strArrayName.substring(0, iFindIndex);
      }
    } else if ((m_pEngine->isOptDefined("spf-file")) && (m_pEngine->getOpt("spf-file") != "")) {
      strArrayName = Fs::basename(m_pEngine->getOpt("spf-file"));
      int iFindIndex = strArrayName.indexOf(".");
      if (iFindIndex != -1) {
        strArrayName = strArrayName.substring(0, iFindIndex);
      }
    } else {
      if (m_pEngine->isOptDefined("annotation-file")) {
        strArrayName =  Fs::basename(m_pEngine->getOpt("annotation-file"));
        int iFindIndex = strArrayName.indexOf(".");
        if (iFindIndex != -1) {
          strArrayName = strArrayName.substring(0, iFindIndex);
        }
      }
    }
  } else {
    strArrayName = m_pEngine->getOpt("array-name");
  }
  return strArrayName;
}
int AffxByteArray::compareTo(const AffxString & that) const
{
    int iResult = 0;
	int iLength = __minimum(this->m_nSize, (int)that.length());

	bool bEqual = true;
	for (int iIndex = 0; (iIndex < iLength); iIndex++)
	{
	    if (this->m_pData[iIndex] != that.charAt(iIndex))
	    {
	        bEqual = false;
	        iResult = (this->m_pData[iIndex] - that.charAt(iIndex));
	        break;
	    }
	}
	if (bEqual) {iResult = (this->m_nSize - (int)that.length());}

	return iResult;
}
bool AffxByteArray::startsWith(const AffxString& strCompare)
{
	bool bStartsWith = false;
	int iCompareLength = strCompare.getLength();

	if (getSize() >= iCompareLength)
	{
		bStartsWith = true;
		for (int iIndex = 0; (iIndex < iCompareLength); iIndex++)
		{
			if (getAt(iIndex) != strCompare.getAt(iIndex))
			{
				bStartsWith = false;
				break;
			}
		}
	}

	return bStartsWith;
}
bool AffxBinaryFile::open(const AffxString& strFileName, m_enumOpenOptions enumOpenOption)
{
	std::fstream fstrm;
	switch (enumOpenOption)
	{
	case LOAD:
		fstrm.open(strFileName.c_str(), std::fstream::in | std::fstream::binary);
		if (fstrm.is_open()) {fstrm.close();} else {return false;}
		m_pistrm = new std::ifstream(strFileName.c_str(), std::ios::in | std::ios::binary);
		if (m_pistrm == NULL) {return false;}
		break;
	case SAVE:
		m_postrm = new std::ofstream(strFileName.c_str(), std::ios::out | std::ios::binary);
		if (m_postrm == NULL) {return false;}
		break;
	case APPEND:
		m_postrm = new std::ofstream(strFileName.c_str(), std::ios::out | std::ios::binary | std::ios::app);
		if (m_postrm == NULL) {return false;}
		break;
	default:
		return false;
	}
	return true;
}
bool AffxByteArray::equalsIgnoreCase(const AffxString &str)
{
	bool bEqual = false;

	int iThisSize = getSize();
	int iThatSize = (int)str.length();

	if (iThisSize == iThatSize)
	{
		for (int i = 0; (i < iThisSize); i++)
		{
			if (getAt(i) >= 'A' && getAt(i) <= 'Z')
			{
				if ((getAt(i) == str.getAt(i)) || (getAt(i) + ' ' == str.getAt(i)))
					bEqual = true;
				else
				{
					bEqual = false;
					break;
				}
			}
			else if (getAt(i) >= 'a' && getAt(i) <= 'z')
			{
				if ((getAt(i) == str.getAt(i)) || (getAt(i) - ' ' == str.getAt(i)))
					bEqual = true;
				else
				{
					bEqual = false;
					break;
				}
			}
			else if (getAt(i) == str.getAt(i))
				bEqual = true;
			else
			{
				bEqual = false;
				break;
			}
		}
	}

	return bEqual;
}