TcpTransportFactory.cpp

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 2006-2007 by Peter Dimov.
00004 
00005 This file is part of Calitko (http://www.calitko.org).
00006 
00007 Calitko is free software; you can redistribute it and/or modify
00008 it under the terms of the GNU General Public License as published by
00009 the Free Software Foundation; either version 2 of the License, or
00010 (at your option) any later version.
00011 
00012 Calitko is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Calitko; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 
00021 */
00022 
00023 #include "Qt.h"
00024 #include "TcpTransportFactory.h"
00025 #include "SocketTransport.h"
00026 #include "TcpSocket.h"
00027 #include "TcpSocketBuffer.h"
00028 #include "TransportFactoryStatus.h"
00029 #include "Imports.cpp"
00030 
00031 namespace Protocols {
00032 namespace Generics {
00033 
00035 
00039 class TcpTransport : public SocketTransport
00040 {
00041 public:
00042     TcpTransport (int readBufferSize, int writeBufferSize,
00043                   TransportStatus *status)
00044      :  SocketTransport (&socket, &socketBuffer, status),
00045         socket (auto_ptr <QTcpSocket> (new QTcpSocket), this),
00046         socketBuffer (readBufferSize, writeBufferSize)
00047     {}
00048 
00049 private:
00050     TcpSocket           socket;
00051     TcpSocketBuffer     socketBuffer;
00052 };
00053 
00054 } // namespace Generics
00055 } // namespace Protocols
00056 
00057 TcpTransportFactory::TcpTransportFactory()
00058  :  establishingTransports(), transports()
00059 {
00060 }
00061 
00062 TcpTransportFactory::~TcpTransportFactory()
00063 {
00064     foreach (Transport *transport, establishingTransports.keys())
00065         delete transport;
00066     foreach (EstablishingTransport *transport, establishingTransports.values())
00067         delete transport;
00068     establishingTransports.clear();
00069 
00070     foreach (Transport *transport, transports)
00071         delete transport;
00072     transports.clear();
00073 }
00074 
00075 // \todo test buffer sizes are set correctly!
00076 void TcpTransportFactory::createTransport (const Uri &uri,
00077                                            TransportFactoryStatus *status)
00078 {
00079     Q_ASSERT (uri.scheme() == "tcp");
00080     const int readBufferSize = uri.queryItemValue ("rb").toInt();
00081     Q_ASSERT (readBufferSize > 0);
00082     const int writeBufferSize = uri.queryItemValue ("wb").toInt();
00083     Q_ASSERT (writeBufferSize > 0);
00084 
00085     auto_ptr <Transport> transport (
00086         new TcpTransport (readBufferSize, writeBufferSize, this));
00087     auto_ptr <EstablishingTransport> establishingTransport (
00088         new EstablishingTransport);
00089     establishingTransport->uri = uri;
00090     establishingTransport->status = status;
00091 
00092     establishingTransports.insert (transport.get(),
00093                                    establishingTransport.get());
00094 
00095     establishingTransport.release();
00096     transport.release()->connectToNode (uri);
00097 }
00098 
00099 void TcpTransportFactory::destroyTransport (Transport *transport)
00100 {
00101     Q_ASSERT (transports.contains (transport));
00102     transports.remove(transport);
00103     delete transport;
00104 }
00105 
00106 void TcpTransportFactory::transportConnected (Transport *transport)
00107 {
00108     Q_ASSERT (!transports.contains (transport));
00109     Q_ASSERT (establishingTransports.contains (transport));
00110     auto_ptr <Transport> connectedTransport (transport);
00111     auto_ptr <EstablishingTransport> establishingTransport (
00112         establishingTransports.take (transport));
00113     transports.insert (transport); // may throw
00114     connectedTransport.release(); // ownership already passed to transports
00115 
00116     establishingTransport->status->transportFactorySucceeded (
00117         establishingTransport->uri, transport);
00118 }
00119 
00120 void TcpTransportFactory::transportReadyRead (Transport *)
00121 {
00122     Q_ASSERT (false);
00123 }
00124 
00125 void TcpTransportFactory::transportReadyWrite (Transport *)
00126 {
00127     Q_ASSERT (false);
00128 }
00129 
00130 void TcpTransportFactory::transportDisconnected (Transport *transport)
00131 {
00132     // If transport was already established, then
00133     // transport->setTransportStatus() must have been called,
00134     // otherwise we may receive the transportDisconnected notification:
00135     Q_ASSERT (!transports.contains (transport));
00136     // We are only supposed to receive the notification for our
00137     // establishingTransports:
00138     Q_ASSERT (establishingTransports.contains (transport));
00139     auto_ptr <Transport> disconnectedTransport (transport);
00140     auto_ptr <EstablishingTransport> establishingTransport (
00141         establishingTransports.take (transport));
00142 
00143     establishingTransport->status->transportFactoryFailed (
00144         establishingTransport->uri);
00145 }