void CConnection::LogOutgoing() { if ( ! theApp.IsLogDisabled( MSG_DEBUG | MSG_FACILITY_OUTGOING ) ) { CLockedBuffer pOutput( GetOutput() ); if ( pOutput->m_nLength ) { CStringA msg( (const char*)pOutput->m_pBuffer, pOutput->m_nLength ); theApp.Message( MSG_DEBUG | MSG_FACILITY_OUTGOING, _T("%s << %s"), (LPCTSTR)m_sAddress, (LPCTSTR)CString( msg ) ); } } }
// Compress data and send it to the connected computer BOOL CNeighbour::OnWrite() { // If we're not sending compressed data to the remote computer, just call CConnection::OnWrite to send the output buffer if ( m_pZOutput == NULL ) return CConnection::OnWrite(); // Return the result and leave now // Start or continue using zlib with m_pZSInput and pStream pointers BOOL bNew = ( m_pZSOutput == NULL ); // Make bNew true if zlib compression isn't setup yet if ( bNew ) m_pZSOutput = new z_stream; // Create a new z_stream structure and point m_pZSOutput and pStream at it // If we are starting to use zlib now if ( bNew ) { // Zero the z_stream structure and set it up for compression ZeroMemory( m_pZSOutput, sizeof(z_stream) ); if ( deflateInit( m_pZSOutput, Settings.Connection.ZLibCompressionLevel ) != Z_OK ) { // There was an error setting up zlib, clean up and leave now delete m_pZSOutput; delete m_pZOutput; m_pZOutput = NULL; m_pZSOutput = NULL; return TRUE; // Report success anyway } } CLockedBuffer pOutput( GetOutput() ); // If there is data in the output buffer already if ( pOutput->m_nLength ) { // Send it to the other computer CConnection::OnWrite(); if ( pOutput->m_nLength ) return TRUE; // Return true if there is still more to send after this (do) } // If it's been more than 2 seconds since we've flushed the compressed output buffer to the remote computer, set the flag to do it next const DWORD tNow = GetTickCount(); if ( tNow >= m_tZOutput + Z_TIMER ) m_bZFlush = TRUE; // Loop until all the data in ZOutput has been compressed into Output while ( ( m_pZOutput->m_nLength && ! pOutput->m_nLength ) // ZOutput has data to compress and Output is empty || m_pZSOutput->avail_out == 0 ) // Or, zlib says it has no more room left (do) { // Make sure the output buffer is 1 KB (do) if ( ! pOutput->EnsureBuffer( 1024u ) ) return FALSE; // Tell zlib where the data to compress is, and where it should put the compressed data m_pZSOutput->next_in = m_pZOutput->m_pBuffer; // Start next_in and avail_in on the data in ZOutput m_pZSOutput->avail_in = m_pZOutput->m_nLength; m_pZSOutput->next_out = pOutput->m_pBuffer + pOutput->m_nLength; // Start next_out and avail_out on the empty space in Output m_pZSOutput->avail_out = pOutput->GetBufferSize() - pOutput->m_nLength; // Call zlib inflate to decompress the contents of m_pInput into the end of m_pZInput CBuffer::Deflate( m_pZSOutput, m_bZFlush ? Z_SYNC_FLUSH : Z_NO_FLUSH ); // Zlib adjusts next in, avail in, next out, and avail out to record what it did // Add the number of uncompressed bytes that zlib compressed to the m_nZOutput count m_nZOutput += m_pZOutput->m_nLength - m_pZSOutput->avail_in; // Remove the chunk that zlib compressed from the start of ZOutput m_pZOutput->Remove( m_pZOutput->m_nLength - m_pZSOutput->avail_in ); // Set nOutput to the size of the new compressed block in the output buffer between the data already there, and the empty space afterwards int nOutput = ( pOutput->GetBufferSize() - pOutput->m_nLength ) - m_pZSOutput->avail_out; // Zlib compressed something if ( nOutput ) { // Add the new block to the length, and record when this happened pOutput->m_nLength += nOutput; m_tZOutput = tNow; } else if ( m_bZFlush ) { // Zlib didn't compress anything, and the flush flag is true m_bZFlush = FALSE; // Make the flush flag false } // Send the contents of the output buffer to the remote computer CConnection::OnWrite(); } return TRUE; }
BOOL CUploadTransferDC::OnUpload(const std::string& strType, const std::string& strFilename, QWORD nOffset, QWORD nLength, const std::string& strOptions) { ASSERT( m_pClient ); if ( m_nState >= upsUploading ) { // Drop unsent data CLockedBuffer pOutput( m_pClient->GetOutput() ); pOutput->Clear(); m_nState = upsRequest; } ClearRequest(); m_sUserAgent = m_pClient->GetUserAgent(); m_pHost = m_pClient->m_pHost; m_sAddress = m_pClient->m_sAddress; UpdateCountry(); m_pClient->m_mInput.pLimit = &Settings.Bandwidth.Request; m_pClient->m_mOutput.pLimit = &m_nBandwidth; m_tRequest = GetTickCount(); BOOL bZip = ( strOptions.find("ZL1") != std::string::npos ); if ( strType == "tthl" ) { m_bGet = FALSE; if ( strFilename.substr( 0, 4 ) == "TTH/" ) { Hashes::TigerHash oTiger; if ( oTiger.fromString( CA2W( strFilename.substr( 4 ).c_str() ) ) ) { CSingleLock oLock( &Library.m_pSection ); if ( oLock.Lock( 1000 ) ) { if ( CLibraryFile* pFile = LibraryMaps.LookupFileByTiger( oTiger, TRUE, TRUE ) ) { if ( RequestTigerTree( pFile, nOffset, nLength ) ) return TRUE; } } } } } else if ( strType == "file" || strType =="get" ) { m_bGet = ( strType == "get" ); if ( strFilename == "files.xml" || strFilename == "files.xml.bz2" ) { if ( RequestFileList( TRUE, bZip, strFilename, nOffset, nLength ) ) return TRUE; } else if ( strFilename.substr( 0, 4 ) == "TTH/" ) { Hashes::TigerHash oTiger; if ( oTiger.fromString( CA2W( strFilename.substr( 4 ).c_str() ) ) ) { CSingleLock oLock( &Library.m_pSection ); if ( oLock.Lock( 1000 ) ) { if ( CLibraryFile* pFile = LibraryMaps.LookupFileByTiger( oTiger, TRUE, TRUE ) ) { if ( RequestFile( pFile, nOffset, nLength ) ) return TRUE; } } } } } else if ( strType == "list" ) { m_bGet = FALSE; if ( RequestFileList( FALSE, bZip, strFilename, nOffset, nLength ) ) return TRUE; } else if ( strType == "send" ) { if ( m_bGet ) { if ( m_pXML.GetCount() ) { // Send cached file list m_bGet = FALSE; StartSending( upsBrowse ); m_pClient->Write( &m_pXML ); m_pXML.Clear(); return TRUE; } else if ( SendFile() ) { // Send already requested file return TRUE; } } // else $Send without $Get } else { // Invalid request type theApp.Message( MSG_ERROR, _T("DC++ Invalid request type from %s"), (LPCTSTR)m_sAddress ); return FALSE; } theApp.Message( MSG_ERROR, IDS_UPLOAD_FILENOTFOUND, (LPCTSTR)m_sAddress, (LPCTSTR)CA2CT( strFilename.c_str() ) ); m_pClient->SendCommand( FILE_NOT_AVAILABLE ); return TRUE; }
bool Logger::Test( ) { bool ok = true; cout << "Testing Logger" << endl; cout << "Five lines of log output should follow:" << endl; Talk( ); ostringstream lss; cout << "log1.SetOutputStream( lss )" << endl; log1.SetOutputStream( lss ); cout << "Two lines of log output (just [Two]) should follow:" << endl; Talk( ); TESTCHECK( lss.str(), string( "[One] >>ALERT<< An alert\n" "[One] ERROR: Can't do something\n" "[One] Warning: This could be bad\n" ), &ok ); cout << "log2.SetOutputStream( lss )" << endl; log2.SetOutputStream( lss ); lss.str( "" ); cout << "No more lines of log output outside of TESTCHECK." << endl; Talk( ); TESTCHECK( lss.str(), string( "[One] >>ALERT<< An alert\n" "[Two] >>ALERT<< Alert #2\n" "[One] ERROR: Can't do something\n" "[Two] ERROR: Uh oh!\n" "[One] Warning: This could be bad\n" ), &ok ); cout << "log2.SetVerbosity( Info )" << endl; log2.SetVerbosity( Logger::Info ); lss.str( "" ); Talk( ); TESTCHECK( lss.str(), string( "[One] >>ALERT<< An alert\n" "[Two] >>ALERT<< Alert #2\n" "[One] ERROR: Can't do something\n" "[Two] ERROR: Uh oh!\n" "[One] Warning: This could be bad\n" "[Two] Info: Interestingly...\n" ), &ok ); cout << "log1.SetVerbosity( Error )" << endl; log1.SetVerbosity( Logger::Error ); lss.str( "" ); Talk( ); TESTCHECK( lss.str(), string( "[One] >>ALERT<< An alert\n" "[Two] >>ALERT<< Alert #2\n" "[One] ERROR: Can't do something\n" "[Two] ERROR: Uh oh!\n" "[Two] Info: Interestingly...\n" ), &ok ); shared_ptr< string > pStr2( new string ); shared_ptr< OutputToString > pOutput( new OutputToString( pStr2 ) ); cout << "log2.SetOutputFunc()" << endl; log2.SetOutputFunc( pOutput ); lss.str( "" ); Talk( ); TESTCHECK( lss.str(), string( "[One] >>ALERT<< An alert\n" "[One] ERROR: Can't do something\n" ), &ok ); TESTCHECK( *pStr2, string( "(Two) {level 1} Alert #2\n" "(Two) {level 3} Uh oh!\n" "(Two) {level 6} Interestingly...\n" ), &ok ); if ( ok ) cout << "Logger PASSED." << endl << endl; else cout << "Logger FAILED." << endl << endl; return ok; }