Example #1
0
// store the body part to string buffer
int CMimeBody::Store(char* pszData, int nMaxSize) const
{
	// store header fields
	int nSize = CMimeHeader::Store(pszData, nMaxSize);
	if (nSize <= 0)
		return nSize;

	// store content
	char* pszDataBegin = pszData;	// preserve start position
	pszData += nSize;
	nMaxSize -= nSize;

	CMimeCodeBase* pCoder = CMimeEnvironment::CreateCoder(GetTransferEncoding());
	ASSERT(pCoder != NULL);
	pCoder->SetInput((const char*)m_pbText, m_nTextSize, true);
	int nOutput = pCoder->GetOutput((unsigned char*)pszData, nMaxSize);
	delete pCoder;
	if (nOutput < 0)
		return nOutput;

	pszData += nOutput;
	nMaxSize -= nOutput;
	if (m_listBodies.empty())
		return (int)(pszData - pszDataBegin);

	// store child body parts
	string strBoundary = GetBoundary();
	if (strBoundary.empty())
		return -1;					// boundary not be set

	int nBoundSize = (int)strBoundary.size() + 6;
	for (CBodyList::const_iterator it=m_listBodies.begin(); it!=m_listBodies.end(); it++)
	{
		if (nMaxSize < nBoundSize)
			break;
		if (m_listBodies.begin() == it && *(pszData-2) == '\r' && *(pszData-1) == '\n')
		{
			pszData -= 2;
			nMaxSize += 2;
		}
		::sprintf(pszData, "\r\n--%s\r\n", strBoundary.c_str());
		pszData += nBoundSize;
		nMaxSize -= nBoundSize;

		CMimeBody* pBP = *it;
		ASSERT(pBP != NULL);
		nOutput = pBP->Store(pszData, nMaxSize);
		if (nOutput < 0)
			return nOutput;
		pszData += nOutput;
		nMaxSize -= nOutput;
	}

	if (nMaxSize >= nBoundSize+2)	// add closing boundary delimiter
	{
		::sprintf(pszData, "\r\n--%s--\r\n", strBoundary.c_str());
		pszData += nBoundSize + 2;
	}
	return (int)(pszData - pszDataBegin);
}
Example #2
0
// return the length needed to store this body part to string buffer
int CMimeBody::GetLength() const
{
	int nLength = CMimeHeader::GetLength();
	CMimeCodeBase* pCoder = CMimeEnvironment::CreateCoder(GetTransferEncoding());
	ASSERT(pCoder != NULL);
	pCoder->SetInput((const char*)m_pbText, m_nTextSize, true);
	nLength += pCoder->GetOutputLength();
	delete pCoder;

	if (m_listBodies.empty())
		return nLength;

	string strBoundary = GetBoundary();
	int nBoundSize = (int) strBoundary.size();
	list<CMimeBody*>::const_iterator it;
	for (it=m_listBodies.begin(); it!=m_listBodies.end(); it++)
	{
		nLength += nBoundSize + 6;	// include 2 leading hyphens and 2 pair of CRLFs
		CMimeBody* pBP = *it;
		ASSERT(pBP != NULL);
		nLength += pBP->GetLength();
	}
	nLength += nBoundSize + 8;		// include 2 leading hyphens, 2 trailng hyphens and 2 pair of CRLFs
	return nLength;
}
Example #3
0
   // write the content (attachment) to a file
   bool MimeBody::WriteToFile(const String &sFilename)
   {
      // First de-code the content.
      MimeCodeBase* pCoder = MimeEnvironment::CreateCoder(GetTransferEncoding());
      ASSERT(pCoder != NULL);
      pCoder->SetInput(m_pbText, m_pbText.GetLength(), false);

      AnsiString decoded;
      pCoder->GetOutput(decoded);

      FileUtilities::WriteToFile(sFilename, decoded);

      return true;
   }
Example #4
0
   // initialize the content (attachment) by reading from a file
   bool MimeBody::ReadFromFile(const String &pszFilename)
   {
      File oFile;
      if (!oFile.Open(pszFilename, File::OTReadOnly))
      {
      if (IniFileSettings::Instance()->GetLogLevel() > 99) LOG_DEBUG("MimeBody::ReadFromFile - Error opening file RO");
         return false;
      }   
      

      shared_ptr<ByteBuffer> pUnencodedBuffer = oFile.ReadFile();

      if (!pUnencodedBuffer)
      {
      if (IniFileSettings::Instance()->GetLogLevel() > 99) LOG_DEBUG("MimeBody::ReadFromFile - pUnencodedBuffer empty");
         return false;
      }

      // Encode the file, to base64 or likewise.
      MimeCodeBase* pCoder = MimeEnvironment::CreateCoder(GetTransferEncoding());
      ASSERT(pCoder != NULL);
      pCoder->SetInput((const char*) pUnencodedBuffer->GetCharBuffer(), pUnencodedBuffer->GetSize(), true);

      // Copy the buffer
      pCoder->GetOutput(m_pbText);

      AnsiString sCharset = "utf-8";

      // Set params to this
      String sFileName = FileUtilities::GetFileNameFromFullPath(pszFilename);
      AnsiString sEncodedValue = MIMEUnicodeEncoder::EncodeValue(sCharset, sFileName);

      SetName(sEncodedValue);				// set 'name' parameter:      

      // Create an content-disposition header as well.
      SetRawFieldValue(CMimeConst::ContentDisposition(), CMimeConst::Inline(), "");
      SetParameter(CMimeConst::ContentDisposition(), CMimeConst::Filename(), sEncodedValue);
      if (IniFileSettings::Instance()->GetLogLevel() > 99) LOG_DEBUG("MimeBody::ReadFromFile - Attachment encoded successfully");

      return true;
   }
Example #5
0
   String
      MimeBody::GetUnicodeText()
   {
      String sWideStr;
      AnsiString sRawText = GetRawText();

if (IniFileSettings::Instance()->GetLogLevel() > 99) LOG_DEBUG("MimeBody::GetUnicodeText sRawText: " + sRawText)
else
if (IniFileSettings::Instance()->GetLogLevel() > 99) LOG_DEBUG("MimeBody::GetUnicodeText sRawText");

      if (sRawText.IsEmpty())
      {
if (IniFileSettings::Instance()->GetLogLevel() > 99) LOG_DEBUG("MimeBody::GetUnicodeText sRawText.IsEmpty!");
         return sRawText;
       }

      std::string strCharset = GetCharset();
      if (strCharset.size() == 0)
      {
if (IniFileSettings::Instance()->GetLogLevel() > 99) LOG_DEBUG("MimeBody::GetUnicodeText strCharset.size=0!");
         return sRawText;
      }

      // De-code the value to plain text.
      AnsiString sRetVal;
      MimeCodeBase* pCoder = MimeEnvironment::CreateCoder(GetTransferEncoding());
      pCoder->SetInput(sRawText, sRawText.GetLength(), false);
      pCoder->GetOutput(sRetVal);
      delete pCoder;

      sWideStr = Charset::ToWideChar(sRetVal, strCharset);
if (IniFileSettings::Instance()->GetLogLevel() > 99) LOG_DEBUG("MimeBody::GetUnicodeText sWideStr: " + sWideStr)
else
if (IniFileSettings::Instance()->GetLogLevel() > 99) LOG_DEBUG("MimeBody::GetUnicodeText sWideStr");

      return sWideStr;
   }
Example #6
0
// load a body part from string buffer
int CMimeBody::Load(const char* pszData, int nDataSize)
{
	// load header fields
	int nSize = CMimeHeader::Load(pszData, nDataSize);
	if (nSize <= 0)
		return nSize;

	const char* pszDataBegin = pszData;	// preserve start position
	pszData += nSize;
	nDataSize -= nSize;
	FreeBuffer();

	// determine the length of the content
	const char* pszEnd = pszData + nDataSize;
	int nMediaType = GetMediaType();
	if (MEDIA_MULTIPART == nMediaType)
	{
		// find the begin boundary
		string strBoundary = GetBoundary();
		if (!strBoundary.empty())
		{
			strBoundary = "\r\n--" + strBoundary;
			pszEnd = ::FindString(pszData-2, strBoundary.c_str(), pszEnd);
			if (!pszEnd)
				pszEnd = pszData + nDataSize;
			else
				pszEnd += 2;
		}
	}

	// load content
	nSize = (int)(pszEnd - pszData);
	if (nSize > 0)
	{
		CMimeCodeBase* pCoder = CMimeEnvironment::CreateCoder(GetTransferEncoding());
		ASSERT(pCoder != NULL);
		pCoder->SetInput(pszData, nSize, false);
		int nOutput = pCoder->GetOutputLength();
		if (AllocateBuffer(nOutput+4))
			nOutput = pCoder->GetOutput(m_pbText, nOutput);
		else
			nOutput = -1;
		delete pCoder;
		if (nOutput < 0)
			return nOutput;

		ASSERT(nOutput < m_nTextSize);
		m_pbText[nOutput] = 0;
		m_nTextSize = nOutput;
		pszData += nSize;
		nDataSize -= nSize;
	}
	if (nDataSize <= 0)
		return (int)(pszData - pszDataBegin);

	// load child body parts
	string strBoundary = GetBoundary();
	ASSERT(strBoundary.size() > 0);
	strBoundary = "\r\n--" + strBoundary;

	// look for the first boundary (case sensitive)
	pszData -= 2;					// go back to CRLF
	nDataSize += 2;
	pszEnd = pszData + nDataSize;
	const char* pszBound1 = ::FindString(pszData, strBoundary.c_str(), pszEnd);
	while (pszBound1 != NULL && pszBound1 < pszEnd)
	{
		const char* pszStart = ::FindString(pszBound1+2, "\r\n", pszEnd);
		if (!pszStart)
			break;
		pszStart += 2;
		if (pszBound1[strBoundary.size()] == '-' && pszBound1[strBoundary.size()+1] == '-')
			return (int)(pszStart - pszDataBegin);	// reach the closing boundary

		// look for the next boundary
		const char* pszBound2 = ::FindString(pszStart, strBoundary.c_str(), pszEnd);
		if (!pszBound2)				// overflow, boundary may be truncated
			pszBound2 = pszEnd;
		int nEntitySize = (int) (pszBound2 - pszStart);

		// find the media type of this body part:
		CMimeHeader header;
		header.Load(pszStart, nEntitySize);
		string strMediaType = header.GetMainType();
		CMimeBody* pBP = CreatePart(strMediaType.c_str());

		int nInputSize = pBP->Load(pszStart, nEntitySize);
		if (nInputSize < 0)
		{
			ErasePart(pBP);
			return nInputSize;
		}
		pszBound1 = pszBound2;
	}
	return (int)(pszEnd - pszDataBegin);
}