// 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); }
// 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); }