void VMIMEMessage::_AddTextPart (const XBOX::VString& inName, bool inIsInline, const XBOX::VString& inContentType, const XBOX::VString& inContentID, XBOX::VPtrStream& inStream) { VMIMEMessagePart *partSource = new VMIMEMessagePart(); if (NULL != partSource) { partSource->SetName (inName); partSource->SetIsInline(inIsInline); partSource->SetMediaType (inContentType); partSource->SetContentID(inContentID); if (XBOX::VE_OK == inStream.OpenReading()) partSource->PutData (inStream.GetDataPtr(), inStream.GetDataSize()); inStream.CloseReading(); fMIMEParts.push_back (partSource); partSource->Release(); } }
XBOX::VError DecompressStream (XBOX::VStream& ioStream) { XBOX::VError error = VE_COMP_LIBRARY_NOT_FOUND; if (XBOX::VComponentManager::IsComponentAvailable ((XBOX::CType)CZipComponent::Component_Type)) { CZipComponent *zipComponent = (CZipComponent *)VComponentManager::RetainComponent ((CType)CZipComponent::Component_Type); if (zipComponent) { XBOX::VPtrStream decompressedStream; if ((XBOX::VE_OK == (error = ioStream.OpenReading())) && !decompressedStream.OpenWriting()) { error = zipComponent->ExpandStream (&ioStream, &decompressedStream); ioStream.CloseReading(); decompressedStream.CloseWriting(); if ((XBOX::VE_OK == error) && (!decompressedStream.IsEmpty())) { if (XBOX::VE_OK == (error = ioStream.OpenWriting())) { ioStream.SetSize (0); ioStream.PutData (decompressedStream.GetDataPtr(), decompressedStream.GetDataSize()); error = ioStream.CloseWriting(); } } } zipComponent->Release(); } } return error; }
XBOX::VError CompressStream (XBOX::VStream& ioStream, HTTPCompressionMethod inMethod) { if ((inMethod == COMPRESSION_NONE) || (inMethod > COMPRESSION_LAST_SUPPORTED_METHOD)) return VE_INVALID_PARAMETER; XBOX::VError error = VE_COMP_LIBRARY_NOT_FOUND; if (VHTTPServer::GetZipComponentAvailable()) { CZipComponent *zipComponent = VHTTPServer::RetainZipComponent(); if (NULL != zipComponent) { XBOX::VPtrStream compressedStream; EZipCompressionLevel compressionLevel = ((inMethod == COMPRESSION_GZIP) || (inMethod == COMPRESSION_X_GZIP)) ? eCompressionLevel_GZip_BestSpeed : eCompressionLevel_BestSpeed; if ((XBOX::VE_OK == (error = ioStream.OpenReading())) && !compressedStream.OpenWriting()) { error = zipComponent->CompressStream (&ioStream, compressionLevel, &compressedStream); ioStream.CloseReading(); compressedStream.CloseWriting(); if ((XBOX::VE_OK == error) && (!compressedStream.IsEmpty())) { if (XBOX::VE_OK == (error = ioStream.OpenWriting())) { ioStream.SetSize (0); ioStream.PutData (compressedStream.GetDataPtr(), compressedStream.GetDataSize()); ioStream.CloseWriting(); } } } XBOX::QuickReleaseRefCountable (zipComponent); } } return error; }
void VMIMEMessage::_ReadSinglePartMail (const VMIMEMailHeader *inHeader, VStream &inStream) { xbox_assert(inHeader != NULL); // Read header information. XBOX::VString name, fileName, contentType, contentID; bool isInline, isBase64, isQuotedPrintable; isInline = isBase64 = isQuotedPrintable = false; XBOX::VString string; XBOX::VNameValueCollection params; if (!inHeader->fContentType.IsEmpty()) { contentType = inHeader->fContentType; VHTTPHeader::SplitParameters(inHeader->fContentType, string, params); if (params.Has("name")) { name = params.Get("name"); _UnQuote(&name, '"', '"'); } } if (!inHeader->fContentDisposition.IsEmpty()) { VHTTPHeader::SplitParameters(inHeader->fContentDisposition, string, params); isInline = HTTPTools::EqualASCIIVString(string, "inline"); if (params.Has("filename")) { fileName = params.Get("filename"); _UnQuote(&fileName, '"', '"'); } } if (!inHeader->fContentTransferEncoding.IsEmpty()) { VHTTPHeader::SplitParameters(inHeader->fContentTransferEncoding, string, params); if (!(isBase64 = HTTPTools::EqualASCIIVString(string, "base64"))) isQuotedPrintable = HTTPTools::EqualASCIIVString(string, "quoted-printable"); } // Read body (a single part). Must be bigger than 5 bytes because of the ending "\r\n.\r\n" sequence. XBOX::VError error; VSize size; if ((error = inStream.OpenReading()) != XBOX::VE_OK) XBOX::vThrowError(error); else if ((size = (VSize) inStream.GetSize()) > 5) { uBYTE *buffer; size -= 5; if ((buffer = new uBYTE[size]) == NULL) XBOX::vThrowError(XBOX::VE_MEMORY_FULL); else { XBOX::VMemoryBuffer<> decodedData; XBOX::VPtrStream decodedBody; inStream.GetData(buffer, size); if (isBase64) { XBOX::Base64Coder::Decode(buffer, size, decodedData); decodedBody.SetDataPtr(decodedData.GetDataPtr(), decodedData.GetDataSize()); decodedData.ForgetData(); } else if (isQuotedPrintable) { VMIMEReader::DecodeQuotedPrintable(buffer, size, &decodedData); decodedBody.SetDataPtr(decodedData.GetDataPtr(), decodedData.GetDataSize()); decodedData.ForgetData(); } else decodedBody.SetDataPtr(buffer, size); inStream.CloseReading(); if (fileName.IsEmpty()) _AddTextPart(name, isInline, contentType, contentID, decodedBody); else _AddFilePart(name, fileName, isInline, contentType, contentID, decodedBody); if (isBase64 || isQuotedPrintable) decodedBody.Clear(); else decodedBody.StealData(); // Prevent VPtrStream from freeing buffer. delete[] buffer; } } else inStream.CloseReading(); }
void VMIMEMessage::_ReadMultiPartMail (const XBOX::VStream &inStream) { XBOX::VStream &stream = const_cast<XBOX::VStream&>(inStream); VMIMEReader reader(fBoundary, stream); while (reader.HasNextPart()) { XBOX::VHTTPMessage message; reader.GetNextPart(message); // Parse header of part. XBOX::VHTTPHeader header = message.GetHeaders(); const XBOX::VNameValueCollection &headerList = header.GetHeaderList(); XBOX::VNameValueCollection::ConstIterator it; XBOX::VString name, fileName, contentType, contentID; bool isInline, isBase64, isQuotedPrintable; isInline = isBase64 = isQuotedPrintable = false; for (it = headerList.begin(); it != headerList.end(); it++) { XBOX::VString value; XBOX::VNameValueCollection params; if (HTTPTools::EqualASCIIVString(it->first, "Content-Type", false)) { header.GetHeaderValue(it->first, contentType); VHTTPHeader::SplitParameters(contentType, value, params); if (params.Has("name")) { name = params.Get("name"); _UnQuote(&name, '"', '"'); } } else if (HTTPTools::EqualASCIIVString(it->first, "Content-Disposition", false)) { XBOX::VString disposition; header.GetHeaderValue(it->first, value); VHTTPHeader::SplitParameters(value, disposition, params); isInline = HTTPTools::EqualASCIIVString(disposition, "inline"); if (params.Has("filename")) { fileName = params.Get("filename"); _UnQuote(&fileName, '"', '"'); } } else if (HTTPTools::EqualASCIIVString(it->first, "Content-Transfer-Encoding", false)) { XBOX::VString encoding; header.GetHeaderValue(it->first, value); VHTTPHeader::SplitParameters(value, encoding, params); if (!(isBase64 = HTTPTools::EqualASCIIVString(encoding, "base64"))) isQuotedPrintable = HTTPTools::EqualASCIIVString(encoding, "quoted-printable"); } else if (HTTPTools::EqualASCIIVString(it->first, "Content-ID", false)) { header.GetHeaderValue(it->first, value); VHTTPHeader::SplitParameters(value, contentID, params); _UnQuote(&contentID, '<', '>'); } else { // Ignore unknown fields. } } // Get body of part, decode it if need. XBOX::VMemoryBuffer<> decodedData; XBOX::VPtrStream decodedBody; XBOX::VPtrStream *body = message.GetBodyPtr(); if (isBase64) { XBOX::Base64Coder::Decode(body->GetDataPtr(), body->GetDataSize(), decodedData); decodedBody.SetDataPtr(decodedData.GetDataPtr(), decodedData.GetDataSize()); decodedData.ForgetData(); body = &decodedBody; } else if (isQuotedPrintable) { VMIMEReader::DecodeQuotedPrintable (body->GetDataPtr(), body->GetDataSize(), &decodedData); decodedBody.SetDataPtr(decodedData.GetDataPtr(), decodedData.GetDataSize()); decodedData.ForgetData(); body = &decodedBody; } if (fileName.IsEmpty()) _AddTextPart(name, isInline, contentType, contentID, *body); else _AddFilePart(name, fileName, isInline, contentType, contentID, *body); decodedBody.Clear(); } }