summaryrefslogtreecommitdiffstats
path: root/examples/network/infoprotocol/infourlclient/qip.cpp
blob: aa1535013981b251f1074449369d698f408c01e8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/****************************************************************************
**
** Copyright (C) 1992-2008 Trolltech ASA.  All rights reserved.
**
** This file is part of an example program for TQt.  This example
** program may be used, distributed and modified without limitation.
**
*****************************************************************************/

#include <ntqsocket.h>
#include <ntqurlinfo.h>
#include <ntqurloperator.h>
#include <ntqtextstream.h>

#include "qip.h"


Qip::Qip()
{
    state = Start;
    socket = new TQSocket( this );
    connect( socket, SIGNAL(connected()), SLOT(socketConnected()) );
    connect( socket, SIGNAL(connectionClosed()), SLOT(socketConnectionClosed()) );
    connect( socket, SIGNAL(readyRead()), SLOT(socketReadyRead()) );
    connect( socket, SIGNAL(error(int)), SLOT(socketError(int)) );
}

int Qip::supportedOperations() const
{
    return OpListChildren | OpGet;
}

bool Qip::checkConnection( TQNetworkOperation * )
{
    if ( socket->isOpen() )
	return TRUE;

    // don't call connectToHost() if we are already trying to connect
    if ( socket->state() == TQSocket::Connecting )
	return FALSE;

    socket->connectToHost( url()->host(), url()->port() != -1 ? url()->port() : infoPort );
    return FALSE;
}

void Qip::operationListChildren( TQNetworkOperation * )
{
    TQTextStream os(socket);
    os << "LIST " + url()->path() + "\r\n";
    operationInProgress()->setState( StInProgress );
}

void Qip::operationGet( TQNetworkOperation * )
{
    TQTextStream os(socket);
    os << "GET " + url()->path() + "\r\n";
    operationInProgress()->setState( StInProgress );
}

void Qip::socketConnected()
{
    if ( url() )
	emit connectionStateChanged( ConConnected, tr( "Connected to host %1" ).arg( url()->host() ) );
    else
	emit connectionStateChanged( ConConnected, tr ("Connected to host" ) );
}

void Qip::socketConnectionClosed()
{
    if ( url() )
	emit connectionStateChanged( ConClosed, tr( "Connection to %1 closed" ).arg( url()->host() ) );
    else
	emit connectionStateChanged( ConClosed, tr ("Connection closed" ) );
}

void Qip::socketError( int code )
{
    if ( code == TQSocket::ErrHostNotFound ||
	 code == TQSocket::ErrConnectionRefused ) {
	error( ErrHostNotFound, tr( "Host not found or couldn't connect to: %1\n" ).arg( url()->host() ) );
    } else
	error( ErrUnsupported, tr( "Error" ) );
}

void Qip::socketReadyRead()
{
    // read from the server
    TQTextStream stream( socket );
    TQString line;
    while ( socket->canReadLine() ) {
	line = stream.readLine();
	if ( line.startsWith( "500" ) ) {
	    error( ErrValid, line.mid( 4 ) ); 
	} else if ( line.startsWith( "550" ) ) {
	    error( ErrFileNotExisting, line.mid( 4 ) ); 
	} else if ( line.startsWith( "212+" ) ) {
	    if ( state != List ) {
		state = List;
	        emit start( operationInProgress() );
	    }
	    TQUrlInfo inf;
	    inf.setName( line.mid( 6 ) + TQString( ( line[ 4 ] == 'D' ) ? "/" : "" ) );
	    inf.setDir( line[ 4 ] == 'D' );
	    inf.setSymLink( FALSE );
	    inf.setFile( line[ 4 ] == 'F' );
	    inf.setWritable( FALSE );
	    inf.setReadable( TRUE );
	    emit newChild( inf, operationInProgress() );
	} else if ( line.startsWith( "213+" ) ) {
	    state = Data;
	    emit data( line.mid( 4 ).utf8(), operationInProgress() );
	}
	if( line[3] == ' ' && state != Start) {
	    state = Start;
	    operationInProgress()->setState( StDone );
	    emit finished( operationInProgress() );
	}
    }
}

void Qip::error( int code, const TQString& msg )
{
    if ( operationInProgress() ) {
	operationInProgress()->setState( StFailed );
	operationInProgress()->setErrorCode( code );
	operationInProgress()->setProtocolDetail( msg );
	clearOperationQueue();
	emit finished( operationInProgress() );
    }
    state = Start;
}