?? nntp.cpp
字號:
/****************************************************************************** $Id: qt/nntp.cpp 3.1.1 edited Nov 8 10:35 $**** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.**** This file is part of an example program for Qt. This example** program may be used, distributed and modified without limitation.*******************************************************************************/#include "nntp.h"#include <qurlinfo.h>#include <stdlib.h>#include <qurloperator.h>#include <qstringlist.h>#include <qregexp.h>Nntp::Nntp() : QNetworkProtocol(), connectionReady( FALSE ), readGroups( FALSE ), readArticle( FALSE ){ // create the command socket and connect to its signals commandSocket = new QSocket( this ); connect( commandSocket, SIGNAL( hostFound() ), this, SLOT( hostFound() ) ); connect( commandSocket, SIGNAL( connected() ), this, SLOT( connected() ) ); connect( commandSocket, SIGNAL( connectionClosed() ), this, SLOT( closed() ) ); connect( commandSocket, SIGNAL( readyRead() ), this, SLOT( readyRead() ) ); connect( commandSocket, SIGNAL( error( int ) ), this, SLOT( error( int ) ) );}Nntp::~Nntp(){ close(); delete commandSocket;}void Nntp::operationListChildren( QNetworkOperation * ){ // create a command QString path = url()->path(), cmd; if ( path.isEmpty() || path == "/" ) { // if the path is empty or we are in the root dir, // we want to read the list of available newsgroups cmd = "list newsgroups\r\n"; } else if ( url()->isDir() ) { // if the path is a directory (in our case a news group) // we want to list the articles of this group path = path.replace( "/", "" ); cmd = "listgroup " + path + "\r\n"; } else return; // write the command to the socket commandSocket->writeBlock( cmd.latin1(), cmd.length() ); readGroups = TRUE;}void Nntp::operationGet( QNetworkOperation *op ){ // get the dirPath of the URL (this is our news group) // and the filename (which is the article we want to read) QUrl u( op->arg( 0 ) ); QString dirPath = u.dirPath(), file = u.fileName(); dirPath = dirPath.replace( "/", "" ); // go to the group in which the article is QString cmd; cmd = "group " + dirPath + "\r\n"; commandSocket->writeBlock( cmd.latin1(), cmd.length() ); // read the head of the article cmd = "article " + file + "\r\n"; commandSocket->writeBlock( cmd.latin1(), cmd.length() ); readArticle = TRUE;}bool Nntp::checkConnection( QNetworkOperation * ){ // we are connected, return TRUE if ( commandSocket->isOpen() && connectionReady ) return TRUE; // seems that there is no chance to connect if ( commandSocket->isOpen() ) return FALSE; // don't call connectToHost() if we are already trying to connect if ( commandSocket->state() == QSocket::Connecting ) return FALSE; // start connecting connectionReady = FALSE; commandSocket->connectToHost( url()->host(), url()->port() != -1 ? url()->port() : 119 ); return FALSE;}void Nntp::close(){ // close the command socket if ( commandSocket->isOpen() ) { commandSocket->writeBlock( "quit\r\n", strlen( "quit\r\n" ) ); commandSocket->close(); }}int Nntp::supportedOperations() const{ // we only support listing children and getting data return OpListChildren | OpGet;}void Nntp::hostFound(){ if ( url() ) emit connectionStateChanged( ConHostFound, tr( "Host %1 found" ).arg( url()->host() ) ); else emit connectionStateChanged( ConHostFound, tr( "Host found" ) );}void Nntp::connected(){ if ( url() ) emit connectionStateChanged( ConConnected, tr( "Connected to host %1" ).arg( url()->host() ) ); else emit connectionStateChanged( ConConnected, tr( "Connected to host" ) );}void Nntp::closed(){ if ( url() ) emit connectionStateChanged( ConClosed, tr( "Connection to %1 closed" ).arg( url()->host() ) ); else emit connectionStateChanged( ConClosed, tr( "Connection closed" ) );}void Nntp::readyRead(){ // new data arrived on the command socket // of we should read the list of available groups, let's do so if ( readGroups ) { parseGroups(); return; } // of we should read an article, let's do so if ( readArticle ) { parseArticle(); return; } // read the new data from the socket QCString s; s.resize( commandSocket->bytesAvailable() ); commandSocket->readBlock( s.data(), commandSocket->bytesAvailable() ); if ( !url() ) return; // of the code of the server response was 200, we know that the // server is ready to get commands from us now if ( s.left( 3 ) == "200" ) connectionReady = TRUE;}void Nntp::parseGroups(){ if ( !commandSocket->canReadLine() ) return; // read one line after the other while ( commandSocket->canReadLine() ) { QString s = commandSocket->readLine(); // if the line starts with a dot, all groups or articles have been listed, // so we finished processing the listChildren() command if ( s[ 0 ] == '.' ) { readGroups = FALSE; operationInProgress()->setState( StDone ); emit finished( operationInProgress() ); return; } // if the code of the server response is 215 or 211 // the next line will be the first group or article (depending on what we read). // So let others know that we start reading now... if ( s.left( 3 ) == "215" || s.left( 3 ) == "211" ) { operationInProgress()->setState( StInProgress ); emit start( operationInProgress() ); continue; } // parse the line and create a QUrlInfo object // which describes the child (group or article) bool tab = s.find( '\t' ) != -1; QString group = s.mid( 0, s.find( tab ? '\t' : ' ' ) ); QUrlInfo inf; inf.setName( group ); QString path = url()->path(); inf.setDir( path.isEmpty() || path == "/" ); inf.setSymLink( FALSE ); inf.setFile( !inf.isDir() ); inf.setWritable( FALSE ); inf.setReadable( TRUE ); // let others know about our new child emit newChild( inf, operationInProgress() ); }}void Nntp::parseArticle(){ if ( !commandSocket->canReadLine() ) return; // read an article one line after the other while ( commandSocket->canReadLine() ) { QString s = commandSocket->readLine(); // if the line starts with a dot, we finished reading something if ( s[ 0 ] == '.' ) { readArticle = FALSE; operationInProgress()->setState( StDone ); emit finished( operationInProgress() ); return; } if ( s.right( 1 ) == "\n" ) s.remove( s.length() - 1, 1 ); // emit the new data of the article which we read emit data( QCString( s.ascii() ), operationInProgress() ); }}void Nntp::error( int code ){ if ( code == QSocket::ErrHostNotFound || code == QSocket::ErrConnectionRefused ) { // this signal is called if connecting to the server failed if ( operationInProgress() ) { QString msg = tr( "Host not found or couldn't connect to: \n" + url()->host() ); operationInProgress()->setState( StFailed ); operationInProgress()->setProtocolDetail( msg ); operationInProgress()->setErrorCode( (int)ErrHostNotFound ); clearOperationQueue(); emit finished( operationInProgress() ); } }}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -