Exemple #1
0
   // load a body part from string buffer
   int MimeBody::Load(const char* pszData, int nDataSize, int &index)
   {
      index++;
      m_iPartIndex = index;

      // load header fields
      int nSize = MimeHeader::Load(pszData, nDataSize, true);
      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 + "\r\n";
            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)
      {
         if (AllocateBuffer(nSize+4))
         {
            m_pbText.append(pszData, nSize);

            pszData += nSize;
            nDataSize -= nSize;
         }
         else
            return -1;
      }
      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 = GetBoundaryEnd(pszData, pszEnd, strBoundary.c_str());

      int counter = 10000;
      while (pszBound1 != NULL && pszBound1 < pszEnd && counter > 0)
      {
         counter--;
         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
         string strBoundaryLine = strBoundary + "\r\n";

         const char* pszBound2 = GetBoundaryEnd(pszStart, pszEnd, strBoundary.c_str());

         if (!pszBound2)				// overflow, boundary may be truncated
            pszBound2 = pszEnd;
         int nEntitySize = (int) (pszBound2 - pszStart);

         shared_ptr<MimeBody> pBP = shared_ptr<MimeBody>(new MimeBody());

         m_listBodies.push_back(pBP);

         int nInputSize = pBP->Load(pszStart, nEntitySize, m_iPartIndex);
         if (nInputSize < 0)
         {
            ErasePart(pBP);
            return nInputSize;
         }
         pszBound1 = pszBound2;
      }
      return (int)(pszEnd - pszDataBegin);
   }
Exemple #2
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);
}