summaryrefslogtreecommitdiffstats
path: root/examples/network/networkprotocol
diff options
context:
space:
mode:
Diffstat (limited to 'examples/network/networkprotocol')
-rw-r--r--examples/network/networkprotocol/README5
-rw-r--r--examples/network/networkprotocol/main.cpp29
-rw-r--r--examples/network/networkprotocol/networkprotocol.doc26
-rw-r--r--examples/network/networkprotocol/networkprotocol.pro10
-rw-r--r--examples/network/networkprotocol/nntp.cpp256
-rw-r--r--examples/network/networkprotocol/nntp.h49
-rw-r--r--examples/network/networkprotocol/view.cpp90
-rw-r--r--examples/network/networkprotocol/view.h37
8 files changed, 502 insertions, 0 deletions
diff --git a/examples/network/networkprotocol/README b/examples/network/networkprotocol/README
new file mode 100644
index 0000000..7c1e69d
--- /dev/null
+++ b/examples/network/networkprotocol/README
@@ -0,0 +1,5 @@
+This class shows you how to implement your own network protocols and how to
+use them in a program. This example is part of the network module.
+
+The class Nntp implements the nntp protocol. The implementation of the
+protocol is not complete and should not be used in real programs.
diff --git a/examples/network/networkprotocol/main.cpp b/examples/network/networkprotocol/main.cpp
new file mode 100644
index 0000000..8d636e4
--- /dev/null
+++ b/examples/network/networkprotocol/main.cpp
@@ -0,0 +1,29 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. 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 <qapplication.h>
+#include <qnetwork.h>
+
+#include "nntp.h"
+#include "view.h"
+
+int main( int argc, char **argv )
+{
+ QApplication a( argc, argv );
+
+ qInitNetworkProtocols();
+ QNetworkProtocol::registerNetworkProtocol( "nntp", new QNetworkProtocolFactory<Nntp> );
+
+ View v;
+ v.resize( 600, 600 );
+ v.show();
+ a.setMainWidget( &v );
+
+ return a.exec();
+}
diff --git a/examples/network/networkprotocol/networkprotocol.doc b/examples/network/networkprotocol/networkprotocol.doc
new file mode 100644
index 0000000..ea00797
--- /dev/null
+++ b/examples/network/networkprotocol/networkprotocol.doc
@@ -0,0 +1,26 @@
+/*
+*/
+
+/*! \page networkprotocol-example.html
+
+ \ingroup network-examples
+
+ \title A simple NNTP implementation
+
+ This example shows how to implement your own QNetworkProtocol. The
+ protocol that was chosen for this example is NTTP. Please note that this
+ implementation is very simple since it is designed to be an example. It
+ should not be used as a real NNTP implemention.
+
+ <hr>
+
+ Header file (nntp.h):
+
+ \include network/networkprotocol/nntp.h
+
+ <hr>
+
+ Implementation (nntp.cpp):
+
+ \include network/networkprotocol/nntp.cpp
+*/
diff --git a/examples/network/networkprotocol/networkprotocol.pro b/examples/network/networkprotocol/networkprotocol.pro
new file mode 100644
index 0000000..1c6ea07
--- /dev/null
+++ b/examples/network/networkprotocol/networkprotocol.pro
@@ -0,0 +1,10 @@
+TEMPLATE = app
+TARGET = networkprotocol
+
+CONFIG += qt warn_on release
+
+REQUIRES = network full-config
+
+HEADERS = nntp.h view.h
+SOURCES = main.cpp \
+ nntp.cpp view.cpp
diff --git a/examples/network/networkprotocol/nntp.cpp b/examples/network/networkprotocol/nntp.cpp
new file mode 100644
index 0000000..1307b9b
--- /dev/null
+++ b/examples/network/networkprotocol/nntp.cpp
@@ -0,0 +1,256 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. 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() + 1 );
+ 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() );
+ }
+ }
+}
diff --git a/examples/network/networkprotocol/nntp.h b/examples/network/networkprotocol/nntp.h
new file mode 100644
index 0000000..82a8142
--- /dev/null
+++ b/examples/network/networkprotocol/nntp.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+#ifndef NNTP_H
+#define NNTP_H
+
+#include <qsocket.h>
+#include <qnetworkprotocol.h>
+
+class Nntp : public QNetworkProtocol
+{
+ Q_OBJECT
+
+public:
+ Nntp();
+ virtual ~Nntp();
+ virtual int supportedOperations() const;
+
+protected:
+ virtual void operationListChildren( QNetworkOperation *op );
+ virtual void operationGet( QNetworkOperation *op );
+
+ QSocket *commandSocket;
+ bool connectionReady;
+ bool readGroups;
+ bool readArticle;
+
+private:
+ bool checkConnection( QNetworkOperation *op );
+ void close();
+ void parseGroups();
+ void parseArticle();
+
+protected slots:
+ void hostFound();
+ void connected();
+ void closed();
+ void readyRead();
+ void error( int );
+
+};
+
+#endif
diff --git a/examples/network/networkprotocol/view.cpp b/examples/network/networkprotocol/view.cpp
new file mode 100644
index 0000000..fed5bdf
--- /dev/null
+++ b/examples/network/networkprotocol/view.cpp
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. 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 "view.h"
+
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <qmultilineedit.h>
+#include <qfiledialog.h>
+
+View::View()
+ : QVBox()
+{
+ // setup the GUI
+ setSpacing( 5 );
+ setMargin( 5 );
+
+ QLabel *l = new QLabel( this );
+ l->setAlignment( Qt::WordBreak ),
+ l->setText( tr( "The button below opens the QFileDialog and you "
+ "can choose a file then which is downloaded and "
+ "opened below then. You can use for that the <b>local "
+ "filesystem</b> using the file protocol, you can download "
+ "files from an <b>FTP</b> server using the ftp protocol and "
+ "you can download and open <b>USENET</b> articles using the "
+ "demo implementation of the nntp protocol of this "
+ "example (<i>This implementation of the nntp protocol is a very "
+ "basic and incomplete one, so you need to connect to a news server "
+ "which allows reading without authentification</i>)\n"
+ "To open a file from the local filesystem, enter in the "
+ "path combobox of the file dialog a url starting with file "
+ "(like <u>file:/usr/bin</u>), to download something from an FTP "
+ "server, use something like <u>ftp://ftp.trolltech.com</u> as url, and "
+ "for downloading a news article start with an url like "
+ "<u>nntp://news.tu-graz.ac.at</u> " ) );
+ QPushButton *b = new QPushButton( tr( "Open a file..." ), this );
+ connect( b, SIGNAL( clicked() ),
+ this, SLOT( downloadFile() ) );
+
+ fileView = new QMultiLineEdit( this );
+ fileView->setReadOnly( TRUE );
+
+ // if new data comes in, display it
+ connect( &op, SIGNAL( data( const QByteArray &, QNetworkOperation * ) ),
+ this, SLOT( newData( const QByteArray & ) ) );
+}
+
+void View::downloadFile()
+{
+ // QString file = QFileDialog::getOpenFileName();
+ // under Windows you must not use the native file dialog
+ QString file = getOpenFileName();
+ if ( !file.isEmpty() ) {
+ // clear the view
+ fileView->clear();
+
+ // download the data
+ op = file;
+ op.get();
+ }
+}
+
+QString View::getOpenFileName()
+{
+ static QString workingDirectory = QDir::currentDirPath();
+
+ QFileDialog *dlg = new QFileDialog( workingDirectory,
+ QString::null, 0, 0, TRUE );
+ dlg->setCaption( QFileDialog::tr( "Open" ) );
+ dlg->setMode( QFileDialog::ExistingFile );
+ QString result;
+ if ( dlg->exec() == QDialog::Accepted ) {
+ result = dlg->selectedFile();
+ workingDirectory = dlg->url();
+ }
+ delete dlg;
+ return result;
+}
+
+void View::newData( const QByteArray &ba )
+{
+ // append new data
+ fileView->append( ba );
+}
diff --git a/examples/network/networkprotocol/view.h b/examples/network/networkprotocol/view.h
new file mode 100644
index 0000000..9baba75
--- /dev/null
+++ b/examples/network/networkprotocol/view.h
@@ -0,0 +1,37 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+#ifndef VIEW_H
+#define VIEW_H
+
+#include <qvbox.h>
+#include <qcstring.h>
+#include <qurloperator.h>
+
+class QMultiLineEdit;
+
+class View : public QVBox
+{
+ Q_OBJECT
+
+public:
+ View();
+
+private slots:
+ void downloadFile();
+ void newData( const QByteArray &ba );
+
+private:
+ QMultiLineEdit *fileView;
+ QUrlOperator op;
+
+ QString getOpenFileName();
+};
+
+#endif