AppOctetStream.cpp
上传用户:xmpantheon
上传日期:2016-10-20
资源大小:7502k
文件大小:4k
源码类别:

Email服务器

开发平台:

Visual C++

  1. // AppOctetStream.cpp: implementation of the CAppOctetStream class.
  2. // Author: Wes Clyburn (clyburnw@enmu.edu)
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "AppOctetStream.h"
  6. #include "Base64.h"
  7. #include "MIMEMessage.h"
  8. #ifdef _DEBUG
  9. #undef THIS_FILE
  10. static char THIS_FILE[]=__FILE__;
  11. #define new DEBUG_NEW
  12. #endif
  13. // IMPORTANT: The number of bytes we read must be
  14. //  a multiple of 3 because CBase64's Encode()
  15. //  method will append padding characters ('=')
  16. //  to make the output's size a multiple of 4.
  17. //  (Base64 treats 3 8-bit bytes as 4 6-bit 'bytes').
  18. //  MIME decoders are free to treat '=' as a signal
  19. //  that there's no more data, so we don't want to pad
  20. //  until we're supposed to.
  21. // When at the end of the file, the # of bytes read
  22. //  may not be a multiple of 3, but that's okay
  23. //  because we DO want the padding chars then.
  24. #define BYTES_TO_READ 54 // This number guarantess output won't
  25.  // won't exceed line-length limit
  26. //////////////////////////////////////////////////////////////////////
  27. // Construction/Destruction
  28. //////////////////////////////////////////////////////////////////////
  29. CAppOctetStream::CAppOctetStream( int nContentType )
  30. :CMIMEContentAgent( nContentType )
  31. {
  32. }
  33. CAppOctetStream::~CAppOctetStream()
  34. {
  35. }
  36. BOOL CAppOctetStream::AppendPart(LPCTSTR szContent, 
  37.  LPCTSTR szParameters, 
  38.  int nEncoding, 
  39.  BOOL bPath, 
  40.  CString & sDestination)
  41. {
  42. CStdioFile fAttachment;
  43. ASSERT( szContent != NULL );
  44. // This class handles only file attachments, so
  45. // it ignores the bPath parameter.
  46. if( szContent == NULL )
  47. return FALSE;
  48. if( !fAttachment.Open( szContent, (CFile::modeRead | CFile::shareDenyWrite | CFile::typeBinary) ) )
  49. return FALSE;
  50. sDestination += build_sub_header( szContent,
  51.       szParameters,
  52.   nEncoding,
  53.   TRUE );
  54. attach_file( &fAttachment, CMIMEMessage::BASE64, sDestination );
  55. fAttachment.Close();
  56. return TRUE;
  57. }
  58. CString CAppOctetStream::build_sub_header(LPCTSTR szContent, 
  59.   LPCTSTR szParameters, 
  60.   int nEncoding, 
  61.   BOOL bPath)
  62. {
  63. CString sSubHeader;
  64. CString sTemp;
  65. TCHAR szFName[ _MAX_FNAME ];
  66. TCHAR szExt[ _MAX_EXT ];
  67. _tsplitpath( szContent, NULL, NULL, szFName, szExt );
  68. // This class ignores szParameters and nEncoding.
  69. // It controls its own parameters and only handles
  70. // Base64 encoding.
  71. if( bPath )
  72. sTemp.Format( "; file=%s%s", szFName, szExt );
  73. else
  74. sTemp = _T( "" );
  75. sSubHeader.Format( _T( "Content-Type: %s%srn" ),
  76. (LPCTSTR)GetContentTypeString(),
  77. (LPCTSTR)sTemp );
  78. sSubHeader += _T( "Content-Transfer-Encoding: base64rn" );
  79. sTemp.Format( _T( "Content-Disposition: attachment; filename=%s%srn" ),
  80.   szFName, szExt );
  81. sSubHeader += sTemp;
  82. // Signal end of sub-header.
  83. sSubHeader += _T( "rn" ); // Warning: numerous concatenations
  84. // are inefficient.
  85. return sSubHeader;
  86. }
  87. CString CAppOctetStream::GetContentTypeString()
  88. {
  89. CString s;
  90. s = _T( "application/octet-stream" );
  91. return s;
  92. }
  93. // Caller is responsible for opening and closing the file
  94. void CAppOctetStream::attach_file(CStdioFile* pFileAtt, 
  95.   int nEncoding, 
  96.   CString & sDestination)
  97. {
  98. CMIMECode* pEncoder;
  99. int nBytesRead;
  100. TCHAR szBuffer[ BYTES_TO_READ + 1 ];
  101. ASSERT( pFileAtt != NULL );
  102. if( pFileAtt == NULL )
  103. return;
  104. switch( nEncoding )
  105. {
  106. // This class handles only Base64 encoding, but others
  107. //  may be added here.
  108. default:
  109. // Fall through to...
  110. case CMIMEMessage::BASE64:
  111. try 
  112. {
  113. pEncoder = new CBase64;
  114. }
  115. catch( CMemoryException* e )
  116. {
  117. delete e;
  118. return;
  119. }
  120. }
  121. if( pEncoder == NULL ) // Old habits are hard to break
  122. return;
  123. do
  124. {
  125. try
  126. {
  127. nBytesRead = pFileAtt->Read( szBuffer, BYTES_TO_READ );
  128. }
  129. catch( CFileException* e )
  130. {
  131. delete e;
  132. break;
  133. }
  134. szBuffer[ nBytesRead ] = 0; // Terminate the string
  135. sDestination += pEncoder->Encode( szBuffer, nBytesRead );
  136. sDestination += _T( "rn" );
  137. } while( nBytesRead == BYTES_TO_READ );
  138. sDestination += _T( "rn" );
  139. delete pEncoder;
  140. }