diff options
Diffstat (limited to 'test-client-catchcopy')
22 files changed, 2344 insertions, 0 deletions
diff --git a/test-client-catchcopy/catchcopy-api-0002/ClientCatchcopy.cpp b/test-client-catchcopy/catchcopy-api-0002/ClientCatchcopy.cpp new file mode 100644 index 0000000..0ac9d04 --- /dev/null +++ b/test-client-catchcopy/catchcopy-api-0002/ClientCatchcopy.cpp @@ -0,0 +1,380 @@ +/** \file ClientCatchcopy.cpp +\brief Define the catchcopy client +\author alpha_one_x86 +\version 0002 +\date 2010 */ + +#include "ClientCatchcopy.h" +#include "VariablesCatchcopy.h" +#include "ExtraSocketCatchcopy.h" +#include <QDataStream> + +ClientCatchcopy::ClientCatchcopy() +{ + disconnectedFromSocket(); + error_string="Unknown error"; + detectTimeOut.setSingleShot(true); + detectTimeOut.setInterval(CATCHCOPY_COMMUNICATION_TIMEOUT); // the max time to without send packet + connect(&socket, SIGNAL(connected()), this, SIGNAL(connected())); + connect(&socket, SIGNAL(disconnected()), this, SIGNAL(disconnected())); + connect(&socket, SIGNAL(disconnected()), this, SLOT(disconnectedFromSocket())); + connect(&socket, SIGNAL(stateChanged(QLocalSocket::LocalSocketState)), this, SIGNAL(stateChanged(QLocalSocket::LocalSocketState))); + connect(&socket, SIGNAL(error(QLocalSocket::LocalSocketError)), this, SIGNAL(errorSocket(QLocalSocket::LocalSocketError))); + connect(&socket, SIGNAL(readyRead()), this, SLOT(readyRead())); + connect(&detectTimeOut, SIGNAL(timeout()), this, SLOT(checkTimeOut())); + connect(&socket, SIGNAL(connected()), this, SLOT(socketIsConnected())); +} + +void ClientCatchcopy::checkTimeOut() +{ + if(haveData) + { + error_string="The server is too long to send the next part of the reply"; + emit error(error_string); + disconnectFromServer(); + } +} + +const QString ClientCatchcopy::errorString() +{ + return error_string; +} + +void ClientCatchcopy::socketIsConnected() +{ + orderIdFirstSendProtocol=sendProtocol(); +} + +void ClientCatchcopy::connectToServer() +{ + socket.connectToServer(ExtraSocketCatchcopy::pathSocket()); +} + +void ClientCatchcopy::disconnectFromServer() +{ + socket.abort(); + socket.disconnectFromServer(); +} + +const QString ClientCatchcopy::errorStringSocket() +{ + return socket.errorString(); +} + +/// \brief to send stream of string list +quint32 ClientCatchcopy::sendRawOrderList(const QStringList & order) +{ + if(!socket.isValid()) + { + error_string="Socket is not valid, try send: "+order.join(";"); + emit error(error_string); + return -1; + } + if(socket.state()!=QLocalSocket::ConnectedState) + { + error_string="Socket is not connected "+QString::number(socket.state()); + emit error(error_string); + return -1; + } + do + { + idNextOrder++; + if(idNextOrder>2000000000) + idNextOrder=0; + } while(notRepliedQuery.contains(idNextOrder)); + notRepliedQuery << idNextOrder; + QByteArray block; + QDataStream out(&block, QIODevice::WriteOnly); + out.setVersion(QDataStream::Qt_4_4); + out << int(0); + out << idNextOrder; + out << order; + out.device()->seek(0); + out << block.size(); + if(idNextOrder!=1) // drop if internal protocol send + { + emit dataSend(idNextOrder,block); + emit dataSend(idNextOrder,order); + } + do //cut string list and send it as block of 32KB + { + QByteArray blockToSend; + int byteWriten; + blockToSend=block.left(32*1024);//32KB + block.remove(0,blockToSend.size()); + byteWriten = socket.write(blockToSend); + if(!socket.isValid()) + { + error_string="Socket is not valid"; + emit error(error_string); + return -1; + } + if(socket.errorString()!="Unknown error" && socket.errorString()!="") + { + error_string=socket.errorString(); + emit error(error_string); + return -1; + } + if(blockToSend.size()!=byteWriten) + { + error_string="All the bytes have not be written"; + emit error(error_string); + return -1; + } + } + while(block.size()); + return idNextOrder; +} + +void ClientCatchcopy::readyRead() +{ + while(socket.bytesAvailable()>0) + { + if(!haveData) + { + if(socket.bytesAvailable()<(int)sizeof(int))//int of size cuted + { + /* error_string="Bytes available is not sufficient to do a int"; + emit error(error_string); + disconnectFromServer();*/ + return; + } + QDataStream in(&socket); + in.setVersion(QDataStream::Qt_4_4); + in >> dataSize; + dataSize-=sizeof(int); + if(dataSize>64*1024*1024) // 64MB + { + error_string="Reply size is >64MB, seam corrupted"; + emit error(error_string); + disconnectFromServer(); + return; + } + if(dataSize<(int)(sizeof(int) //orderId + + sizeof(quint32) //returnCode + + sizeof(quint32) //string list size + )) + { + error_string="Reply size is too small to have correct code"; + emit error(error_string); + disconnectFromServer(); + return; + } + } + if(dataSize<(data.size()+socket.bytesAvailable())) + data.append(socket.read(dataSize-data.size())); + else + data.append(socket.readAll()); + if(dataSize==data.size()) + { + if(!checkDataIntegrity(data)) + { + data.clear(); + qWarning() << "Data of the reply is wrong"; + return; + } + QStringList returnList; + quint32 orderId; + quint32 returnCode; + QDataStream in(data); + in.setVersion(QDataStream::Qt_4_4); + in >> orderId; + in >> returnCode; + in >> returnList; + data.clear(); + if(orderId!=orderIdFirstSendProtocol) + { + if(!notRepliedQuery.contains(orderId)) + qWarning() << "Unknown query not replied:" << orderId; + else + { + if(!parseReply(orderId,returnCode,returnList)) + emit unknowReply(orderId); + emit newReply(orderId,returnCode,returnList); + } + } + else + { + if(!sendProtocolReplied) + { + sendProtocolReplied=true; + if(returnCode!=1000) + { + error_string="Protocol not supported"; + emit error(error_string); + disconnectFromServer(); + return; + } + } + else + { + error_string=QString("First send protocol send with the query id %1 have been already previously replied").arg(orderIdFirstSendProtocol); + emit error(error_string); + disconnectFromServer(); + return; + } + } + } + } + if(haveData) + detectTimeOut.start(); + else + detectTimeOut.stop(); +} + +bool ClientCatchcopy::checkDataIntegrity(QByteArray data) +{ + quint32 orderId; + qint32 replyCode; + qint32 listSize; + QDataStream in(data); + in.setVersion(QDataStream::Qt_4_4); + in >> orderId; + in >> replyCode; + in >> listSize; + if(listSize>65535) + { + emit error("List size is wrong"); + qWarning() << "List size is wrong"; + return false; + } + int index=0; + while(index<listSize) + { + qint32 stringSize; + in >> stringSize; + if(stringSize>65535) + { + emit error("String size is wrong"); + qWarning() << "String size is wrong"; + return false; + } + if(stringSize>(in.device()->size()-in.device()->pos())) + { + emit error(QString("String size is greater than the data: %1>(%2-%3)").arg(stringSize).arg(in.device()->size()).arg(in.device()->pos())); + qWarning() << QString("String size is greater than the data: %1>(%2-%3)").arg(stringSize).arg(in.device()->size()).arg(in.device()->pos()); + return false; + } + in.device()->seek(in.device()->pos()+stringSize); + index++; + } + if(in.device()->size()!=in.device()->pos()) + { + emit error("Remaining data after string list parsing"); + qWarning() << "Remaining data after string list parsing"; + return false; + } + return true; +} + +QLocalSocket::LocalSocketState ClientCatchcopy::state() +{ + return socket.state(); +} + +void ClientCatchcopy::disconnectedFromSocket() +{ + haveData = false; + orderIdFirstSendProtocol= 0; + idNextOrder = 0; + sendProtocolReplied = false; + notRepliedQuery.clear(); +} + +/// \brief to send the protocol version used +quint32 ClientCatchcopy::sendProtocol() +{ + return sendRawOrderList(QStringList() << "protocol" << CATCHCOPY_PROTOCOL_VERSION); +} + +quint32 ClientCatchcopy::askServerName() +{ + return sendRawOrderList(QStringList() << "server" << "name?"); +} + +quint32 ClientCatchcopy::setClientName(const QString & name) +{ + return sendRawOrderList(QStringList() << "client" << name); +} + +quint32 ClientCatchcopy::checkProtocolExtension(const QString & name) +{ + return sendRawOrderList(QStringList() << "protocol extension" << name); +} + +quint32 ClientCatchcopy::checkProtocolExtension(const QString & name,const QString & version) +{ + return sendRawOrderList(QStringList() << "protocol extension" << name << version); +} + +quint32 ClientCatchcopy::addCopyWithDestination(const QStringList & sources,const QString & destination) +{ + return sendRawOrderList(QStringList() << "cp" << sources << destination); +} + +quint32 ClientCatchcopy::addCopyWithoutDestination(const QStringList & sources) +{ + return sendRawOrderList(QStringList() << "cp-?" << sources); +} + +quint32 ClientCatchcopy::addMoveWithDestination(const QStringList & sources,const QString & destination) +{ + return sendRawOrderList(QStringList() << "mv" << sources << destination); +} + +quint32 ClientCatchcopy::addMoveWithoutDestination(const QStringList & sources) +{ + return sendRawOrderList(QStringList() << "mv-?" << sources); +} + +bool ClientCatchcopy::parseReply(quint32 orderId,quint32 returnCode,QStringList returnList) +{ + switch(returnCode) + { + case 1000: + emit protocolSupported(orderId); + break; + case 1001: + case 1002: + if(returnCode==1001) + emit protocolExtensionSupported(orderId,true); + else + emit protocolExtensionSupported(orderId,false); + break; + case 1003: + emit clientRegistered(orderId); + break; + case 1004: + if(returnList.size()!=1) + emit unknowOrder(orderId); + else + emit serverName(orderId,returnList.last()); + break; + case 1005: + case 1006: + if(returnCode==1005) + emit copyFinished(orderId,false); + else + emit copyFinished(orderId,true); + break; + case 1007: + emit copyCanceled(orderId); + break; + case 5000: + emit incorrectArgumentListSize(orderId); + break; + case 5001: + emit incorrectArgument(orderId); + break; + case 5002: + emit unknowOrder(orderId); //the server have not understand the order + break; + case 5003: + emit protocolNotSupported(orderId); + break; + default: + return false; + } + return true; +} + diff --git a/test-client-catchcopy/catchcopy-api-0002/ClientCatchcopy.h b/test-client-catchcopy/catchcopy-api-0002/ClientCatchcopy.h new file mode 100644 index 0000000..278b0cd --- /dev/null +++ b/test-client-catchcopy/catchcopy-api-0002/ClientCatchcopy.h @@ -0,0 +1,114 @@ +/** \file ClientCatchcopy.h +\brief Define the catchcopy client +\author alpha_one_x86 +\version 0002 +\date 2010 */ + +#ifndef CLIENTCATCHCOPY_H +#define CLIENTCATCHCOPY_H + +#include <QObject> +#include <QLocalSocket> +#include <QStringList> +#include <QString> +#include <QByteArray> +#include <QTimer> + +/// \brief Define the catchcopy client +class ClientCatchcopy : public QObject +{ + Q_OBJECT + public: + ClientCatchcopy(); + /// \brief get the socket stat + QLocalSocket::LocalSocketState state(); + /// \brief error string about the socket + const QString errorStringSocket(); + /// \brief general error string + const QString errorString(); + public slots: + void connectToServer(); + void disconnectFromServer(); + //to test and internal use + /// \brief to send order + quint32 sendProtocol(); + /// \brief ask the server name + quint32 askServerName(); + /// \brief set the client name + quint32 setClientName(const QString & name); + /// \brief check protocol extension + quint32 checkProtocolExtension(const QString & name); + /// \brief check protocol extension and version + quint32 checkProtocolExtension(const QString & name,const QString & version); + /// \brief add copy with destination + quint32 addCopyWithDestination(const QStringList & sources,const QString & destination); + /// \brief add copy without destination + quint32 addCopyWithoutDestination(const QStringList & sources); + /// \brief add move with destination + quint32 addMoveWithDestination(const QStringList & sources,const QString & destination); + /// \brief add move without destination + quint32 addMoveWithoutDestination(const QStringList & sources); + /// \brief to send stream of string list + quint32 sendRawOrderList(const QStringList & order); + signals: + /// \brief is connected + void connected(); + /// \brief is disconnected + void disconnected(); + /// \brief the socket state have changed + void stateChanged(QLocalSocket::LocalSocketState socketState); + /// \brief send the error string + void error(QString error); + /// \brief send socket error + void errorSocket(QLocalSocket::LocalSocketError socketError); + /// \brief have new reply + void newReply(quint32 orderId,quint32 returnCode,QStringList returnList); + /// \brief have data send + void dataSend(quint32 orderId,QByteArray data); + /// \brief have data send by string list + void dataSend(quint32 orderId,QStringList data); + /// \brief have unknow reply + void unknowReply(quint32 orderId); + //reply + /// \brief protocol is supported + void protocolSupported(quint32 orderId); + /// \brief incorrect argument list size + void incorrectArgumentListSize(quint32 orderId); + /// \brief incorrect argument + void incorrectArgument(quint32 orderId); + /// \brief protocol not supported + void protocolNotSupported(quint32 orderId); + /// \brief protocol extension supported + void protocolExtensionSupported(quint32 orderId,bool isSupported); + /// \brief client is registred + void clientRegistered(quint32 orderId); + /// \brief have the server name + void serverName(quint32 orderId,QString name); + /// \brief copy finished + void copyFinished(quint32 orderId,bool withError); + /// \brief copy canceled + void copyCanceled(quint32 orderId); + /// \brief have unknow order + void unknowOrder(quint32 orderId); //the server have not understand the order + private: + QLocalSocket socket; + QString error_string; + quint32 idNextOrder; + QByteArray data; + bool haveData; + int dataSize; + quint32 orderIdFirstSendProtocol; + QTimer detectTimeOut; + bool sendProtocolReplied; + QList<quint32> notRepliedQuery; + bool checkDataIntegrity(QByteArray data); + private slots: + void readyRead(); + void disconnectedFromSocket(); + void socketIsConnected(); + void checkTimeOut(); + protected: + bool parseReply(quint32 orderId,quint32 returnCode,QStringList returnList); +}; + +#endif // CLIENTCATCHCOPY_H diff --git a/test-client-catchcopy/catchcopy-api-0002/ExtraSocketCatchcopy.cpp b/test-client-catchcopy/catchcopy-api-0002/ExtraSocketCatchcopy.cpp new file mode 100644 index 0000000..7ee05ed --- /dev/null +++ b/test-client-catchcopy/catchcopy-api-0002/ExtraSocketCatchcopy.cpp @@ -0,0 +1,31 @@ +/** \file ExtraSocketCatchcopy.cpp +\brief Define the socket of catchcopy +\author alpha_one_x86 +\version 0002 +\date 2010 */ + +#include "ExtraSocketCatchcopy.h" + +const QString ExtraSocketCatchcopy::pathSocket() +{ +#ifdef Q_OS_UNIX + return "advanced-copier-"+QString::number(getuid()); +#else + QString userName; + DWORD size=0; + if(GetUserNameW(NULL,&size) || (GetLastError()!=ERROR_INSUFFICIENT_BUFFER)) + { + } + else + { + WCHAR * userNameW=new WCHAR[size]; + if(GetUserNameW(userNameW,&size)) + { + userName.fromWCharArray(userNameW,size*2); + userName=QString(QByteArray((char*)userNameW,size*2-2).toHex()); + } + delete userNameW; + } + return "advanced-copier-"+userName; +#endif +} diff --git a/test-client-catchcopy/catchcopy-api-0002/ExtraSocketCatchcopy.h b/test-client-catchcopy/catchcopy-api-0002/ExtraSocketCatchcopy.h new file mode 100644 index 0000000..623c668 --- /dev/null +++ b/test-client-catchcopy/catchcopy-api-0002/ExtraSocketCatchcopy.h @@ -0,0 +1,27 @@ +/** \file ExtraSocketCatchcopy.h +\brief Define the socket of catchcopy +\author alpha_one_x86 +\version 0002 +\date 2010 */ + +#ifndef EXTRASOCKETCATCHCOPY_H +#define EXTRASOCKETCATCHCOPY_H + +#include <QString> + +#ifdef Q_OS_UNIX + #include <unistd.h> + #include <sys/types.h> +#else + #include <windows.h> +#endif + +/// \brief to have extra socket function +class ExtraSocketCatchcopy +{ +public: + /// \brief to get the socket path + static const QString pathSocket(); +}; + +#endif // EXTRASOCKETCATCHCOPY_H diff --git a/test-client-catchcopy/catchcopy-api-0002/ServerCatchcopy.cpp b/test-client-catchcopy/catchcopy-api-0002/ServerCatchcopy.cpp new file mode 100644 index 0000000..b17fc0a --- /dev/null +++ b/test-client-catchcopy/catchcopy-api-0002/ServerCatchcopy.cpp @@ -0,0 +1,725 @@ +/** \file ServerCatchcopy.cpp +\brief Define the server of catchcopy +\author alpha_one_x86 +\version 0002 +\date 2010 */ + +#include "ServerCatchcopy.h" +#include "VariablesCatchcopy.h" +#include "ExtraSocketCatchcopy.h" + +ServerCatchcopy::ServerCatchcopy() +{ + name="Default avanced copier"; + autoReply=true; + idNextClient=0; + error_string="Unknown error"; + connect(&server, SIGNAL(newConnection()), this, SLOT(newConnection())); +} + +ServerCatchcopy::~ServerCatchcopy() +{ + close(); +} + +bool ServerCatchcopy::isListening() +{ + return server.isListening(); +} + +void ServerCatchcopy::setName(const QString & name) +{ + this->name=name; +} + +QString ServerCatchcopy::getName() +{ + return name; +} + +bool ServerCatchcopy::listen() +{ + QLocalSocket socketTestConnection; + pathSocket=ExtraSocketCatchcopy::pathSocket(); + socketTestConnection.connectToServer(pathSocket); + if(socketTestConnection.waitForConnected(CATCHCOPY_COMMUNICATION_TIMEOUT)) + { + error_string="Other server is listening"; + emit error(error_string); + return false; + } + else + { + server.removeServer(pathSocket); + if(server.listen(pathSocket)) + return true; + else + { + error_string=QString("Unable to listen %1: %2").arg(pathSocket).arg(server.errorString()); + emit error(error_string); + return false; + } + } +} + +void ServerCatchcopy::close() +{ + if(server.isListening()) + { + int index=0; + while(index<ClientList.size()) + { + ClientList.at(index).socket->disconnectFromServer(); + index++; + } + server.close(); + QLocalServer::removeServer(pathSocket); + } +} + +const QString ServerCatchcopy::errorStringServer() +{ + return server.errorString(); +} + +const QString ServerCatchcopy::errorString() +{ + return error_string; +} + +/// \brief New connexion +void ServerCatchcopy::newConnection() +{ + while(server.hasPendingConnections()) + { + QLocalSocket *clientSocket = server.nextPendingConnection(); + if(clientSocket!=NULL) + { + do + { + idNextClient++; + if(idNextClient>2000000000) + idNextClient=0; + } while(clientIdFound(idNextClient)); + Client newClient; + newClient.id = idNextClient; + newClient.socket = clientSocket; + newClient.haveData = false; + newClient.firstProtocolReplied = false; + newClient.detectTimeOut = new QTimer(this); + newClient.detectTimeOut->setSingleShot(true); + newClient.detectTimeOut->setInterval(CATCHCOPY_COMMUNICATION_TIMEOUT); + connect(newClient.socket, SIGNAL(error(QLocalSocket::LocalSocketError)), this, SLOT(connectionError(QLocalSocket::LocalSocketError))); + connect(newClient.socket, SIGNAL(readyRead()), this, SLOT(readyRead())); + connect(newClient.socket, SIGNAL(disconnected()), this, SLOT(disconnected())); + connect(newClient.detectTimeOut,SIGNAL(timeout()), this, SLOT(checkTimeOut())); + ClientList << newClient; + emit connectedClient(newClient.id); + } + } +} + +bool ServerCatchcopy::clientIdFound(quint32 id) +{ + int index=0; + while(index<ClientList.size()) + { + if(ClientList.at(index).id==id) + return true; + index++; + } + return false; +} + +/// \brief new error at connexion +void ServerCatchcopy::connectionError(QLocalSocket::LocalSocketError error) +{ + QLocalSocket *socket=qobject_cast<QLocalSocket *>(QObject::sender()); + if(socket==NULL) + { + qWarning() << "Unlocated client socket!"; + return; + } + int index=0; + while(index<ClientList.size()) + { + if(ClientList.at(index).socket==socket) + { + if(error!=QLocalSocket::PeerClosedError) + qWarning() << "error detected for the client: " << index << ", type: " << error; + ClientList.at(index).socket->disconnectFromServer(); + return; + } + index++; + } +} + +void ServerCatchcopy::disconnected() +{ + QLocalSocket *socket=qobject_cast<QLocalSocket *>(QObject::sender()); + if(socket==NULL) + { + qWarning() << "Unlocated client socket!"; + return; + } + int index=0; + while(index<ClientList.size()) + { + if(ClientList.at(index).socket==socket) + { + emit disconnectedClient(ClientList.at(index).id); + disconnect(ClientList.at(index).socket); + disconnect(ClientList.at(index).detectTimeOut); + delete ClientList.at(index).detectTimeOut; + ClientList.at(index).socket->abort(); + ClientList.at(index).socket->disconnectFromServer(); + ClientList.at(index).socket->deleteLater(); + ClientList.removeAt(index); + return; + } + index++; + } + qWarning() << "Unlocated client!"; +} + +void ServerCatchcopy::disconnectClient(quint32 id) +{ + int index=0; + while(index<ClientList.size()) + { + if(ClientList.at(index).id==id) + { + ClientList.at(index).socket->disconnectFromServer(); + return; + } + index++; + } + qWarning() << "Unlocated client!"; +} + +void ServerCatchcopy::readyRead() +{ + QLocalSocket *socket=qobject_cast<QLocalSocket *>(QObject::sender()); + if(socket==NULL) + { + qWarning() << "Unlocated client socket!"; + return; + } + int index=0; + while(index<ClientList.size()) + { + if(ClientList.at(index).socket==socket) + { + while(socket->bytesAvailable()>0) + { + if(!ClientList.at(index).haveData) + { + if(socket->bytesAvailable()<(int)sizeof(int))//ignore because first int is cuted! + { + /*error_string="Bytes available is not sufficient to do a int"; + emit error(error_string); + disconnectClient(ClientList.at(index).id);*/ + return; + } + QDataStream in(socket); + in.setVersion(QDataStream::Qt_4_4); + in >> ClientList[index].dataSize; + ClientList[index].dataSize-=sizeof(int); + if(ClientList.at(index).dataSize>64*1024*1024) // 64MB + { + error_string="Reply size is >64MB, seam corrupted"; + emit error(error_string); + disconnectClient(ClientList.at(index).id); + return; + } + if(ClientList.at(index).dataSize<(int)(sizeof(int) //orderId + + sizeof(quint32) //returnCode + + sizeof(quint32) //string list size + )) + { + error_string="Reply size is too small to have correct code"; + emit error(error_string); + disconnectClient(ClientList.at(index).id); + return; + } + ClientList[index].haveData=true; + } + if(ClientList.at(index).dataSize<(ClientList.at(index).data.size()+socket->bytesAvailable())) + ClientList[index].data.append(socket->read(ClientList.at(index).dataSize-ClientList.at(index).data.size())); + else + ClientList[index].data.append(socket->readAll()); + if(ClientList.at(index).dataSize==(quint32)ClientList.at(index).data.size()) + { + if(!checkDataIntegrity(ClientList.at(index).data)) + { + emit error("Data integrity wrong: "+QString(ClientList.at(index).data.toHex())); + ClientList[index].data.clear(); + ClientList[index].haveData=false; + qWarning() << "Data integrity wrong"; + return; + } + QStringList returnList; + quint32 orderId; + QDataStream in(ClientList.at(index).data); + in.setVersion(QDataStream::Qt_4_4); + in >> orderId; + in >> returnList; + ClientList[index].data.clear(); + ClientList[index].haveData=false; + if(ClientList.at(index).queryNoReplied.contains(orderId)) + { + emit error("Duplicate query id"); + qWarning() << "Duplicate query id"; + return; + } + ClientList[index].queryNoReplied << orderId; + if(!ClientList.at(index).firstProtocolReplied && returnList.size()==2 && returnList.first()=="protocol" && autoReply) + { + ClientList[index].firstProtocolReplied=true; + protocolSupported(ClientList.at(index).id,orderId,(returnList.last()==CATCHCOPY_PROTOCOL_VERSION)); + } + else + parseInput(ClientList.at(index).id,orderId,returnList); + } + } + if(ClientList.at(index).haveData) + ClientList.at(index).detectTimeOut->start(); + else + ClientList.at(index).detectTimeOut->stop(); + return; + } + index++; + } + emit error("Unallocated client!"); + qWarning() << "Unallocated client!"; +} + +bool ServerCatchcopy::checkDataIntegrity(QByteArray data) +{ + quint32 orderId; + qint32 listSize; + QDataStream in(data); + in.setVersion(QDataStream::Qt_4_4); + in >> orderId; + in >> listSize; + if(listSize>65535) + { + emit error("List size is wrong"); + qWarning() << "List size is wrong"; + return false; + } + int index=0; + while(index<listSize) + { + qint32 stringSize; + in >> stringSize; + if(stringSize>65535) + { + emit error("String size is wrong"); + return false; + } + if(stringSize>(in.device()->size()-in.device()->pos())) + { + emit error(QString("String size is greater than the data: %1>(%2-%3)").arg(stringSize).arg(in.device()->size()).arg(in.device()->pos())); + return false; + } + in.device()->seek(in.device()->pos()+stringSize); + index++; + } + if(in.device()->size()!=in.device()->pos()) + { + emit error("Remaining data after string list parsing"); + return false; + } + return true; +} + +void ServerCatchcopy::parseInput(quint32 client,quint32 orderId,QStringList returnList) +{ + switch(parseInputCurrentProtocol(client,orderId,returnList)) + { + case Ok: + emit newQuery(client,orderId,returnList); + break; + case Replied: + break; + case ExtensionWrong: + if(autoReply) + protocolExtensionSupported(client,orderId,false); + else + emit newQuery(client,orderId,returnList); + break; + case WrongArgument: + if(autoReply) + incorrectArgument(client,orderId); + else + emit newQuery(client,orderId,returnList); + break; + case WrongArgumentListSize: + if(autoReply) + incorrectArgumentListSize(client,orderId); + else + emit newQuery(client,orderId,returnList); + break; + case UnknowOrder: + emit error("Unknown query"); + qWarning() << "Unknown query"; + if(autoReply) + unknowOrder(client,orderId); + else + emit newQuery(client,orderId,returnList); + break; + } +} + +ServerCatchcopy::inputReturnType ServerCatchcopy::parseInputCurrentProtocol(quint32 client,quint32 orderId,QStringList returnList) +{ + if(returnList.size()==0) + return WrongArgumentListSize; + //if is supported + QString firstArgument=returnList.first(); + if(firstArgument=="protocol") + { + if(returnList.size()!=2) + return WrongArgumentListSize; + emit askProtocolCompatibility(client,orderId,returnList.last()); + return Ok; + } + else if(firstArgument=="protocol extension") + { + if(returnList.size()>3 || returnList.size()<2) + return WrongArgumentListSize; + if(!autoReply) + { + if(returnList.size()==2) + emit askProtocolExtension(client,orderId,returnList.last()); + else + emit askProtocolExtension(client,orderId,returnList.at(1),returnList.last()); + } + return ExtensionWrong; + } + else if(firstArgument=="client") + { + if(returnList.size()!=2) + return WrongArgumentListSize; + emit clientName(client,returnList.last()); + if(autoReply) + { + clientRegistered(client,orderId); + return Replied; + } + else + { + emit clientName(client,orderId,returnList.last()); + return Ok; + } + } + else if(firstArgument=="server") + { + if(returnList.size()!=2) + return WrongArgumentListSize; + if(returnList.last()!="name?") + return WrongArgument; + if(autoReply) + { + serverName(client,orderId,name); + return Replied; + } + else + { + askServerName(client,orderId); + return Ok; + } + } + else if(firstArgument=="cp") + { + if(returnList.size()<3) + return WrongArgumentListSize; + QStringList sourceList=returnList; + sourceList.removeFirst(); + sourceList.removeLast(); + emitNewCopy(client,orderId,sourceList,returnList.last()); + return Ok; + } + else if(firstArgument=="cp-?") + { + if(returnList.size()<2) + return WrongArgumentListSize; + QStringList sourceList=returnList; + sourceList.removeFirst(); + emitNewCopy(client,orderId,sourceList); + return Ok; + } + else if(firstArgument=="mv") + { + if(returnList.size()<3) + return WrongArgumentListSize; + QStringList sourceList=returnList; + sourceList.removeFirst(); + sourceList.removeLast(); + emitNewMove(client,orderId,sourceList,returnList.last()); + return Ok; + } + else if(firstArgument=="mv-?") + { + if(returnList.size()<2) + return WrongArgumentListSize; + QStringList sourceList=returnList; + sourceList.removeFirst(); + emitNewMove(client,orderId,sourceList); + return Ok; + } + else //if is not supported + return UnknowOrder; +} + +void ServerCatchcopy::emitNewCopy(quint32 client,quint32 orderId,QStringList sources) +{ + emit newCopy(client,orderId,sources); + LinkGlobalToLocalClient newAssociation; + newAssociation.idClient=client; + newAssociation.orderId=orderId; + newAssociation.globalOrderId=incrementOrderId(); + LinkGlobalToLocalClientList << newAssociation; + emit newCopy(newAssociation.globalOrderId,sources); +} + +void ServerCatchcopy::emitNewCopy(quint32 client,quint32 orderId,QStringList sources,QString destination) +{ + emit newCopy(client,orderId,sources,destination); + LinkGlobalToLocalClient newAssociation; + newAssociation.idClient=client; + newAssociation.orderId=orderId; + newAssociation.globalOrderId=incrementOrderId(); + LinkGlobalToLocalClientList << newAssociation; + emit newCopy(newAssociation.globalOrderId,sources,destination); +} + +void ServerCatchcopy::emitNewMove(quint32 client,quint32 orderId,QStringList sources) +{ + emit newMove(client,orderId,sources); + LinkGlobalToLocalClient newAssociation; + newAssociation.idClient=client; + newAssociation.orderId=orderId; + newAssociation.globalOrderId=incrementOrderId(); + LinkGlobalToLocalClientList << newAssociation; + emit newMove(newAssociation.globalOrderId,sources); +} + +void ServerCatchcopy::emitNewMove(quint32 client,quint32 orderId,QStringList sources,QString destination) +{ + emit newMove(client,orderId,sources,destination); + LinkGlobalToLocalClient newAssociation; + newAssociation.idClient=client; + newAssociation.orderId=orderId; + newAssociation.globalOrderId=incrementOrderId(); + LinkGlobalToLocalClientList << newAssociation; + emit newMove(newAssociation.globalOrderId,sources,destination); +} + +void ServerCatchcopy::copyFinished(quint32 globalOrderId,bool withError) +{ + int index=0; + while(index<LinkGlobalToLocalClientList.size()) + { + if(LinkGlobalToLocalClientList.at(index).globalOrderId==globalOrderId) + { + copyFinished(LinkGlobalToLocalClientList.at(index).idClient,LinkGlobalToLocalClientList.at(index).orderId,withError); + LinkGlobalToLocalClientList.removeAt(index); + orderList.removeOne(globalOrderId); + return; + } + index++; + } +} + +void ServerCatchcopy::copyCanceled(quint32 globalOrderId) +{ + int index=0; + while(index<LinkGlobalToLocalClientList.size()) + { + if(LinkGlobalToLocalClientList.at(index).globalOrderId==globalOrderId) + { + copyCanceled(LinkGlobalToLocalClientList.at(index).idClient,LinkGlobalToLocalClientList.at(index).orderId); + LinkGlobalToLocalClientList.removeAt(index); + orderList.removeOne(globalOrderId); + return; + } + index++; + } +} + +void ServerCatchcopy::setAutoReply(bool value) +{ + autoReply=value; +} + +bool ServerCatchcopy::getAutoReply() +{ + return autoReply; +} + +void ServerCatchcopy::reply(quint32 client,quint32 orderId,quint32 returnCode,QString returnString) +{ + reply(client,orderId,returnCode,QStringList() << returnString); +} + +void ServerCatchcopy::reply(quint32 client,quint32 orderId,quint32 returnCode,QStringList returnList) +{ + int index=0; + while(index<ClientList.size()) + { + if(ClientList.at(index).id==client) + { + if(ClientList.at(index).socket->isValid() && ClientList.at(index).socket->state()==QLocalSocket::ConnectedState) + { + if(!ClientList.at(index).queryNoReplied.contains(orderId)) + { + qWarning() << "Reply to missing query or previously replied"; + return; + } + ClientList[index].queryNoReplied.removeOne(orderId); + //cut string list and send it as block of 32KB + QByteArray block; + QDataStream out(&block, QIODevice::WriteOnly); + out.setVersion(QDataStream::Qt_4_4); + out << int(0); + out << orderId; + out << returnCode; + out << returnList; + out.device()->seek(0); + out << block.size(); + emit dataSend(client,orderId,returnCode,block); + emit dataSend(client,orderId,returnCode,returnList); + do + { + QByteArray blockToSend; + int byteWriten; + blockToSend=block.left(32*1024);//32KB + block.remove(0,blockToSend.size()); + byteWriten = ClientList[index].socket->write(blockToSend); + if(!ClientList[index].socket->isValid()) + { + error_string="Socket is not valid"; + emit error(error_string); + return; + } + if(ClientList[index].socket->errorString()!="Unknown error" && ClientList[index].socket->errorString()!="") + { + error_string="Error with socket: "+ClientList[index].socket->errorString(); + emit error(error_string); + return; + } + if(blockToSend.size()!=byteWriten) + { + error_string="All the bytes have not be written"; + emit error(error_string); + return; + } + } + while(block.size()); + } + else + { + error_string="Socket is not valid or not connected"; + emit error(error_string); + } + return; + } + index++; + } + qWarning() << "Client id not found:" << client; +} + +void ServerCatchcopy::protocolSupported(quint32 client,quint32 orderId,bool value) +{ + if(value) + reply(client,orderId,1000,"protocol supported"); + else + reply(client,orderId,5003,"protocol not supported"); +} + +void ServerCatchcopy::incorrectArgumentListSize(quint32 client,quint32 orderId) +{ + reply(client,orderId,5000,"incorrect argument list size"); +} + +void ServerCatchcopy::incorrectArgument(quint32 client,quint32 orderId) +{ + reply(client,orderId,5001,"incorrect argument"); +} + +void ServerCatchcopy::protocolExtensionSupported(quint32 client,quint32 orderId,bool value) +{ + if(value) + reply(client,orderId,1001,"protocol extension supported"); + else + reply(client,orderId,1002,"protocol extension not supported"); +} + +void ServerCatchcopy::clientRegistered(quint32 client,quint32 orderId) +{ + reply(client,orderId,1003,"client registered"); +} + +void ServerCatchcopy::serverName(quint32 client,quint32 orderId,QString name) +{ + reply(client,orderId,1004,name); +} + +void ServerCatchcopy::copyFinished(quint32 client,quint32 orderId,bool withError) +{ + if(!withError) + reply(client,orderId,1005,"finished"); + else + reply(client,orderId,1006,"finished with error(s)"); +} + +void ServerCatchcopy::copyCanceled(quint32 client,quint32 orderId) +{ + reply(client,orderId,1007,"canceled"); +} + +void ServerCatchcopy::unknowOrder(quint32 client,quint32 orderId) +{ + reply(client,orderId,5002,"unknown order"); +} + +void ServerCatchcopy::checkTimeOut() +{ + QTimer *timer=qobject_cast<QTimer *>(QObject::sender()); + if(timer==NULL) + { + qWarning() << "Unallocated client timer!"; + return; + } + int index=0; + while(index<ClientList.size()) + { + if(ClientList.at(index).detectTimeOut==timer) + { + ClientList.at(index).detectTimeOut->stop(); + if(ClientList.at(index).haveData) + { + error_string="The client is too long to send the next part of the reply: "+ClientList.at(index).data; + ClientList[index].haveData=false; + ClientList[index].data.clear(); + ClientList.at(index).socket->disconnectFromServer(); + emit error(error_string); + } + return; + } + index++; + } +} + +quint32 ServerCatchcopy::incrementOrderId() +{ + do + { + nextOrderId++; + if(nextOrderId>2000000) + nextOrderId=0; + } while(orderList.contains(nextOrderId)); + return nextOrderId; +} diff --git a/test-client-catchcopy/catchcopy-api-0002/ServerCatchcopy.h b/test-client-catchcopy/catchcopy-api-0002/ServerCatchcopy.h new file mode 100644 index 0000000..5f7af35 --- /dev/null +++ b/test-client-catchcopy/catchcopy-api-0002/ServerCatchcopy.h @@ -0,0 +1,162 @@ +/** \file ServerCatchcopy.h +\brief Define the server of catchcopy +\author alpha_one_x86 +\version 0002 +\date 2010 */ + +#ifndef SERVERCATCHCOPY_H +#define SERVERCATCHCOPY_H + +#include <QObject> +#include <QLocalSocket> +#include <QLocalServer> +#include <QStringList> +#include <QString> +#include <QByteArray> +#include <QTimer> + +/// \brief Define the server of catchcopy +class ServerCatchcopy : public QObject +{ + Q_OBJECT + public: + ServerCatchcopy(); + ~ServerCatchcopy(); + /// \brief return if is listening + bool isListening(); + /// \brief try listen + bool listen(); + /// \brief try close the server + void close(); + /// \brief get the error string on the QLocalServer + const QString errorStringServer(); + /// \brief get the general error string + const QString errorString(); + /// \brief set if automatic reply is used + void setAutoReply(bool value); + /// \brief get if autoReply is set + bool getAutoReply(); + /// \brief set the name of the server + void setName(const QString & name); + /// \brief get the name + QString getName(); + private: + QString pathSocket; + QString name; + QString error_string; + QLocalServer server; + quint32 idNextClient; + struct Client + { + quint32 id; + QLocalSocket *socket; + QByteArray data; + bool haveData; + quint32 dataSize; + bool firstProtocolReplied; + QList<quint32> queryNoReplied; + QTimer *detectTimeOut; + }; + QList<Client> ClientList; + struct LinkGlobalToLocalClient + { + quint32 idClient; + quint32 orderId; + quint32 globalOrderId; + }; + QList<LinkGlobalToLocalClient> LinkGlobalToLocalClientList; + enum inputReturnType{Ok,Replied,ExtensionWrong,WrongArgument,WrongArgumentListSize,UnknowOrder}; + inputReturnType parseInputCurrentProtocol(quint32 client,quint32 orderId,QStringList returnList); + bool autoReply; + bool clientIdFound(quint32 id); + quint32 nextOrderId; + QList<quint32> orderList; + quint32 incrementOrderId(); + void emitNewCopy(quint32 client,quint32 orderId,QStringList sources); + void emitNewCopy(quint32 client,quint32 orderId,QStringList sources,QString destination); + void emitNewMove(quint32 client,quint32 orderId,QStringList sources); + void emitNewMove(quint32 client,quint32 orderId,QStringList sources,QString destination); + bool checkDataIntegrity(QByteArray data); + protected: + void parseInput(quint32 client,quint32 orderId,QStringList returnList); + private slots: + void newConnection(); + void connectionError(QLocalSocket::LocalSocketError error); + void disconnected(); + void readyRead(); + void checkTimeOut(); + public slots: + /// \brief disconnect one client + void disconnectClient(quint32 id); + /// \brief reply to a client with QStringList + void reply(quint32 client,quint32 orderId,quint32 returnCode,QStringList returnList); + /// \brief reply to a client + void reply(quint32 client,quint32 orderId,quint32 returnCode,QString returnString); + //reply + /// \brief send if the protocol is supported + void protocolSupported(quint32 client,quint32 orderId,bool value); + /// \brief send incorrect arguement list size + void incorrectArgumentListSize(quint32 client,quint32 orderId); + /// \brief send incorrect arguement + void incorrectArgument(quint32 client,quint32 orderId); + /// \brief send if protocol extension is supported + void protocolExtensionSupported(quint32 client,quint32 orderId,bool value); + /// \brief the client is registred + void clientRegistered(quint32 client,quint32 orderId); + /// \brief send the server name + void serverName(quint32 client,quint32 orderId,QString name); + /// \brief send the copy is finished + void copyFinished(quint32 client,quint32 orderId,bool withError); + /// \brief send the copy is canceled + void copyCanceled(quint32 client,quint32 orderId); + /// \brief send the copy is finished by global is order + void copyFinished(quint32 globalOrderId,bool withError); + /// \brief send copy cancel by global is order + void copyCanceled(quint32 globalOrderId); + /// \brief send the unknow order + void unknowOrder(quint32 client,quint32 orderId); + signals: + /// \brief send connected client + void connectedClient(quint32 id); + /// \brief send disconnect client + void disconnectedClient(quint32 id); + /// \brief have new query + void newQuery(quint32 client,quint32 orderId,QStringList returnList); + /// \brief send new data as string list + void dataSend(quint32 client,quint32 orderId,quint32 returnCode,QStringList returnList); + /// \brief send new data as raw data + void dataSend(quint32 client,quint32 orderId,quint32 returnCode,QByteArray block); + /// \brief have new error + void error(QString error); + //query + /// \brief ask the protocol compatility + void askProtocolCompatibility(quint32 client,quint32 orderId,QString version); + /// \brief ask protocol extension + void askProtocolExtension(quint32 client,quint32 orderId,QString extension); + /// \brief ask protocol extension with version + void askProtocolExtension(quint32 client,quint32 orderId,QString extension,QString version); + /// \brief send the client name, with query id + void clientName(quint32 client,quint32 orderId,QString name); + /// \brief send the client name, without query id + void clientName(quint32 client,QString name); + /// \brief send the client have ask the server name + void askServerName(quint32 client,quint32 orderId); + /// \brief copy is send, without destination + void newCopy(quint32 client,quint32 orderId,QStringList sources); + /// \brief copy is send, with destination + void newCopy(quint32 client,quint32 orderId,QStringList sources,QString destination); + /// \brief move is send, without destination + void newMove(quint32 client,quint32 orderId,QStringList sources); + /// \brief move is send, with destination + void newMove(quint32 client,quint32 orderId,QStringList sources,QString destination); + /// \brief copy is send, by globalOrderId, without destination + void newCopy(quint32 globalOrderId,QStringList sources); + /// \brief copy is send, by globalOrderId, with destination + void newCopy(quint32 globalOrderId,QStringList sources,QString destination); + /// \brief move is send, by globalOrderId, without destination + void newMove(quint32 globalOrderId,QStringList sources); + /// \brief move is send, by globalOrderId, with destination + void newMove(quint32 globalOrderId,QStringList sources,QString destination); +}; + +#endif // SERVERCATCHCOPY_H diff --git a/test-client-catchcopy/catchcopy-api-0002/VariablesCatchcopy.h b/test-client-catchcopy/catchcopy-api-0002/VariablesCatchcopy.h new file mode 100644 index 0000000..ce73aee --- /dev/null +++ b/test-client-catchcopy/catchcopy-api-0002/VariablesCatchcopy.h @@ -0,0 +1,14 @@ +/** \file VariablesCatchcopy.h +\brief Define the variable for catchcopy +\author alpha_one_x86 +\version 0002 +\date 2010 */ + +#ifndef VARIABLECATCHCOPY_H +#define VARIABLECATCHCOPY_H + +#define CATCHCOPY_PROTOCOL_VERSION "0002" +#define CATCHCOPY_COMMUNICATION_TIMEOUT 200 + +#endif // VARIABLECATCHCOPY_H + diff --git a/test-client-catchcopy/catchcopy-api-0002/documentation.dox b/test-client-catchcopy/catchcopy-api-0002/documentation.dox new file mode 100755 index 0000000..8ee4177 --- /dev/null +++ b/test-client-catchcopy/catchcopy-api-0002/documentation.dox @@ -0,0 +1,31 @@ +/* -*- mode: C++ ; c-file-style: "stroustrup" -*- **/ + +/* + This file contains NO source code, just some documentation for doxygen to + parse. +*/ + +/*! + \mainpage Catchcopy API + + \section mainpage_overview Overview + + This code is to interface with the catchcopy protocol, the code is provided by the catchcopy projet: <a href="http://catchcopy.first-world.info/">Catchcopy web site</a> + + \section mainpage_platforms Platforms + + This plugin might be usable in all environments where you find Qt 4.\n + + \section mainpage_downloads Downloads + + You can found link on <a href="http://ultracopier.first-world.info/">Ultracopier (Supercopier/Teracopy)</a> project page, via git, snapshot sources, ... + + \section mainpage_algorithm Protocol + + The protocol in version 0.0.0.2 is used, you can see the documentation on <a href="http://catchcopy.first-world.info/">Catchcopy web site</a> + + \section license GPL Version 3 + The code source is under GPL3. The image is extacted from Oxygen icon pack of KDE4. + +*/ + diff --git a/test-client-catchcopy/icon.ico b/test-client-catchcopy/icon.ico Binary files differnew file mode 100644 index 0000000..f0296c0 --- /dev/null +++ b/test-client-catchcopy/icon.ico diff --git a/test-client-catchcopy/images/dialog-ok-apply.png b/test-client-catchcopy/images/dialog-ok-apply.png Binary files differnew file mode 100644 index 0000000..f5feac0 --- /dev/null +++ b/test-client-catchcopy/images/dialog-ok-apply.png diff --git a/test-client-catchcopy/images/download.png b/test-client-catchcopy/images/download.png Binary files differnew file mode 100755 index 0000000..4ffac41 --- /dev/null +++ b/test-client-catchcopy/images/download.png diff --git a/test-client-catchcopy/images/main.png b/test-client-catchcopy/images/main.png Binary files differnew file mode 100644 index 0000000..efdc90d --- /dev/null +++ b/test-client-catchcopy/images/main.png diff --git a/test-client-catchcopy/images/process-stop.png b/test-client-catchcopy/images/process-stop.png Binary files differnew file mode 100644 index 0000000..a76314c --- /dev/null +++ b/test-client-catchcopy/images/process-stop.png diff --git a/test-client-catchcopy/images/tools-report-bug.png b/test-client-catchcopy/images/tools-report-bug.png Binary files differnew file mode 100644 index 0000000..26af8d6 --- /dev/null +++ b/test-client-catchcopy/images/tools-report-bug.png diff --git a/test-client-catchcopy/images/upload.png b/test-client-catchcopy/images/upload.png Binary files differnew file mode 100755 index 0000000..4e9d532 --- /dev/null +++ b/test-client-catchcopy/images/upload.png diff --git a/test-client-catchcopy/main.cpp b/test-client-catchcopy/main.cpp new file mode 100644 index 0000000..bbda5ac --- /dev/null +++ b/test-client-catchcopy/main.cpp @@ -0,0 +1,10 @@ +#include <QApplication> +#include "mainwindow.h" + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + MainWindow w; + w.show(); + return a.exec(); +} diff --git a/test-client-catchcopy/mainwindow.cpp b/test-client-catchcopy/mainwindow.cpp new file mode 100644 index 0000000..59f2eda --- /dev/null +++ b/test-client-catchcopy/mainwindow.cpp @@ -0,0 +1,305 @@ +#include <QStringList> +#include <QListWidgetItem> + +#include "mainwindow.h" +#include "ui_mainwindow.h" + +MainWindow::MainWindow(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::MainWindow) +{ + ui->setupUi(this); + connect(&client,SIGNAL(connected()),this,SLOT(connected())); + connect(&client,SIGNAL(disconnected()),this,SLOT(disconnected())); + connect(&client,SIGNAL(errorSocket(QLocalSocket::LocalSocketError)),this,SLOT(errorSocket(QLocalSocket::LocalSocketError))); + connect(&client,SIGNAL(error(QString)),this,SLOT(error(QString))); + connect(&client,SIGNAL(dataSend(quint32 ,QStringList)),this,SLOT(dataSend(quint32 ,QStringList))); + connect(&client,SIGNAL(newReply(quint32 ,quint32,QStringList)),this,SLOT(newReply(quint32 ,quint32,QStringList))); + ui->groupBoxPredefinedFunction->setEnabled(false); + ui->groupBoxRaw->setEnabled(false); + ui->groupBoxRawSend->setEnabled(false); + ui->groupBoxCopyMove->setEnabled(false); +} + +MainWindow::~MainWindow() +{ + delete ui; +} + +void MainWindow::changeEvent(QEvent *e) +{ + QMainWindow::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + ui->retranslateUi(this); + break; + default: + break; + } +} + +void MainWindow::connected() +{ + ui->groupBoxPredefinedFunction->setEnabled(true); + ui->groupBoxRaw->setEnabled(true); + ui->groupBoxRawSend->setEnabled(true); + ui->groupBoxCopyMove->setEnabled(true); + ui->actionConnect->setEnabled(false); + ui->actionDisconnect->setEnabled(true); + ui->statusBar->showMessage(tr("Connected"),5000); +} + +void MainWindow::disconnected() +{ + ui->groupBoxPredefinedFunction->setEnabled(false); + ui->groupBoxRaw->setEnabled(false); + ui->groupBoxRawSend->setEnabled(false); + ui->groupBoxCopyMove->setEnabled(false); + ui->actionConnect->setEnabled(true); + ui->actionDisconnect->setEnabled(false); + ui->listCommand->clear(); + CommandList.clear(); + on_listCommand_itemSelectionChanged(); + ui->statusBar->showMessage(tr("Disconnected"),5000); +} + +void MainWindow::tryConnect() +{ + ui->statusBar->showMessage(tr("Connection..."),5000); + client.connectToServer(); +} + +void MainWindow::tryDisconnect() +{ + ui->statusBar->showMessage(tr("Disconnection..."),5000); + client.disconnectFromServer(); +} + +void MainWindow::errorSocket(QLocalSocket::LocalSocketError socketError) +{ + if(socketError==QLocalSocket::ConnectionRefusedError) + ui->statusBar->showMessage(tr("Connection refused"),5000); + else if(socketError==QLocalSocket::PeerClosedError) + ui->statusBar->showMessage(tr("Peer have close the connexion"),5000); + else + ui->statusBar->showMessage(client.errorStringSocket(),5000); +} + + +void MainWindow::on_actionDisconnect_triggered() +{ + tryDisconnect(); +} + +void MainWindow::on_actionConnect_triggered() +{ + tryConnect(); +} + +void MainWindow::on_RawSendRemove_clicked() +{ + int index=0; + QList<QListWidgetItem *> list=ui->listRawSend->selectedItems(); + while(index<list.size()) + { + + delete list.at(index); + index++; + } +} + +void MainWindow::on_RawSendAdd_clicked() +{ + ui->listRawSend->addItem(new QListWidgetItem(ui->lineEditRawSendText->text())); +} + +void MainWindow::on_sendProtocol_clicked() +{ + client.sendProtocol(); +} + +void MainWindow::on_sendRawList_clicked() +{ + QStringList list; + int index=0; + while(index<ui->listRawSend->count()) + { + list<<ui->listRawSend->item(index)->text(); + index++; + } + client.sendRawOrderList(list); +} + +void MainWindow::stateChanged(QLocalSocket::LocalSocketState socketState) +{ + if(socketState==QLocalSocket::UnconnectedState) + disconnected(); + else if(socketState==QLocalSocket::ConnectedState) + connected(); + else + { + ui->actionConnect->setEnabled(false); + ui->groupBoxPredefinedFunction->setEnabled(false); + ui->groupBoxRaw->setEnabled(false); + ui->groupBoxRawSend->setEnabled(false); + ui->groupBoxCopyMove->setEnabled(false); + } +} + +void MainWindow::dataSend(quint32 orderId,QStringList data) +{ + Command newCommand; + newCommand.orderId=orderId; + newCommand.sendTime=QTime::currentTime(); + newCommand.replied=false; + newCommand.sendList=data; + newCommand.returnCode=0; + CommandList << newCommand; + ui->listCommand->addItem(new QListWidgetItem(QString(newCommand.sendTime.toString()+" - "+QString::number(orderId)))); + int index=0; + while(index<CommandList.size()) + { + if(orderId==CommandList.at(index).orderId) + { + if(data.size()!=0) + ui->listCommand->item(index)->setText(QString(CommandList.at(index).sendTime.toString()+") "+QString::number(orderId)+" - "+data.first())); + return; + } + index++; + } +} + +void MainWindow::on_listCommand_itemSelectionChanged() +{ + ui->listCommandListSended->clear(); + ui->listReplyList->clear(); + ui->lineReplyCode->setText(""); + if(ui->listCommand->currentRow()<0) + { + ui->listCommandListSended->setEnabled(false); + ui->listReplyList->setEnabled(false); + ui->lineReplyCode->setEnabled(false); + ui->timeEditReply->setEnabled(false); + } + else + { + if(ui->listCommand->currentRow()<CommandList.size()) + { + ui->listCommandListSended->setEnabled(true); + ui->listCommandListSended->addItems(CommandList.at(ui->listCommand->currentRow()).sendList); + if(CommandList.at(ui->listCommand->currentRow()).replied) + { + ui->listReplyList->setEnabled(true); + ui->lineReplyCode->setEnabled(true); + ui->timeEditReply->setEnabled(true); + ui->listReplyList->addItems(CommandList.at(ui->listCommand->currentRow()).returnList); + ui->lineReplyCode->setText(QString::number(CommandList.at(ui->listCommand->currentRow()).returnCode)); + ui->timeEditReply->setTime(CommandList.at(ui->listCommand->currentRow()).replyTime); + } + else + { + ui->timeEditReply->setEnabled(false); + ui->listReplyList->setEnabled(false); + ui->lineReplyCode->setEnabled(false); + } + } + else + qWarning() << "out of bound!"; + } +} + +void MainWindow::newReply(quint32 orderId,quint32 returnCode,QStringList returnList) +{ + int index=0; + while(index<CommandList.size()) + { + if(orderId==CommandList.at(index).orderId) + { + CommandList[index].replied=true; + CommandList[index].replyTime=QTime::currentTime(); + CommandList[index].returnCode=returnCode; + CommandList[index].returnList=returnList; + if(ui->listCommand->currentRow()==index) + on_listCommand_itemSelectionChanged(); + return; + } + index++; + } +} + +void MainWindow::on_pushButtonAskServerName_clicked() +{ + client.askServerName(); +} + +void MainWindow::on_pushButtonClientName_clicked() +{ + client.setClientName(ui->lineEditClientName->text()); +} + +void MainWindow::on_pushButtonProtocolName_clicked() +{ + client.checkProtocolExtension(ui->lineEditProtocolName->text()); +} + +void MainWindow::on_pushButtonProtocolNameVersion_clicked() +{ + client.checkProtocolExtension(ui->lineEditProtocolName->text(),ui->lineEditProtocolVersion->text()); +} + +void MainWindow::on_pushButtonCopyAdd_clicked() +{ + ui->listWidgetCopy->addItem(new QListWidgetItem(ui->lineEditAddCopy->text())); +} + +void MainWindow::on_pushButtonCopyRemove_clicked() +{ + int index=0; + QList<QListWidgetItem *> list=ui->listWidgetCopy->selectedItems(); + while(index<list.size()) + { + + delete list.at(index); + index++; + } +} + +void MainWindow::on_pushButtonCopyWithoutDestination_clicked() +{ + QStringList list; + int index=0; + while(index<ui->listWidgetCopy->count()) + { + list<<ui->listWidgetCopy->item(index)->text(); + index++; + } + if(ui->comboBoxCopyType->currentIndex()==0) + client.addCopyWithoutDestination(list); + else + client.addMoveWithoutDestination(list); +} + +void MainWindow::on_pushButtonCopyWithDestination_clicked() +{ + QStringList list; + int index=0; + while(index<ui->listWidgetCopy->count()) + { + list<<ui->listWidgetCopy->item(index)->text(); + index++; + } + if(ui->comboBoxCopyType->currentIndex()==0) + client.addCopyWithDestination(list,ui->lineEditCopyDestination->text()); + else + client.addMoveWithDestination(list,ui->lineEditCopyDestination->text()); +} + +void MainWindow::error(QString error) +{ + ui->listError->addItem(error); +} + +void MainWindow::on_listCommandListSended_itemSelectionChanged() +{ + on_listCommand_itemSelectionChanged(); +} diff --git a/test-client-catchcopy/mainwindow.h b/test-client-catchcopy/mainwindow.h new file mode 100644 index 0000000..d2dca25 --- /dev/null +++ b/test-client-catchcopy/mainwindow.h @@ -0,0 +1,68 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include <QMainWindow> +#include <QTime> +#include <QStringList> +#include <QList> + +#include "catchcopy-api-0002/ClientCatchcopy.h" + +namespace Ui { + class MainWindow; +} + +class MainWindow : public QMainWindow +{ + Q_OBJECT + public: + explicit MainWindow(QWidget *parent = 0); + ~MainWindow(); + protected: + void changeEvent(QEvent *e); + private: + Ui::MainWindow *ui; + ClientCatchcopy client; + /// \brief Structure of plugins + struct Command + { + QTime sendTime; + quint32 orderId; + QStringList sendList; + bool replied; + QTime replyTime; + quint32 returnCode; + QStringList returnList; + }; + typedef struct Command Command; + QList<Command> CommandList; + void addCommand(int orderId); + private slots: + void connected(); + void disconnected(); + void tryConnect(); + void tryDisconnect(); + void errorSocket(QLocalSocket::LocalSocketError socketError); + void on_actionDisconnect_triggered(); + void on_actionConnect_triggered(); + void on_RawSendRemove_clicked(); + void on_RawSendAdd_clicked(); + void on_sendProtocol_clicked(); + void on_sendRawList_clicked(); + void stateChanged(QLocalSocket::LocalSocketState socketState); + void dataSend(quint32 orderId,QStringList data); + void on_listCommand_itemSelectionChanged(); + void newReply(quint32 orderId,quint32 returnCode,QStringList returnList); + void on_pushButtonAskServerName_clicked(); + void on_pushButtonClientName_clicked(); + void on_pushButtonProtocolName_clicked(); + void on_pushButtonProtocolNameVersion_clicked(); + void on_pushButtonCopyAdd_clicked(); + void on_pushButtonCopyRemove_clicked(); + void on_pushButtonCopyWithoutDestination_clicked(); + void on_pushButtonCopyWithDestination_clicked(); + void error(QString error); + void on_listCommandListSended_itemSelectionChanged(); +}; + +#endif // MAINWINDOW_H diff --git a/test-client-catchcopy/mainwindow.ui b/test-client-catchcopy/mainwindow.ui new file mode 100644 index 0000000..5b17ee7 --- /dev/null +++ b/test-client-catchcopy/mainwindow.ui @@ -0,0 +1,441 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>MainWindow</class> + <widget class="QMainWindow" name="MainWindow"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>569</width> + <height>864</height> + </rect> + </property> + <property name="windowTitle"> + <string>Test client catchcopy</string> + </property> + <property name="windowIcon"> + <iconset resource="resources.qrc"> + <normaloff>:/images/main.png</normaloff>:/images/main.png</iconset> + </property> + <widget class="QWidget" name="centralWidget"> + <layout class="QVBoxLayout" name="verticalLayout_7"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QGroupBox" name="groupBoxRawSend"> + <property name="maximumSize"> + <size> + <width>300</width> + <height>16777215</height> + </size> + </property> + <property name="title"> + <string>Raw send</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QLineEdit" name="lineEditRawSendText"> + <property name="minimumSize"> + <size> + <width>128</width> + <height>0</height> + </size> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="RawSendAdd"> + <property name="text"> + <string>+</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="RawSendRemove"> + <property name="text"> + <string>-</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QListWidget" name="listRawSend"> + <property name="styleSheet"> + <string notr="true">background-image: url(:/images/upload.png); +background-position : center; +background-repeat : no-repeat; +background-color : #fff; +background-attachment : fixed; +</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="sendRawList"> + <property name="text"> + <string>Send</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBoxPredefinedFunction"> + <property name="title"> + <string>Predefined function</string> + </property> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="0" column="0"> + <widget class="QPushButton" name="sendProtocol"> + <property name="text"> + <string>Send protocol</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>protocol extension</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <item> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>Name:</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="lineEditProtocolName"> + <property name="placeholderText"> + <string>extension</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButtonProtocolName"> + <property name="text"> + <string>Send name</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string>Version:</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="lineEditProtocolVersion"> + <property name="placeholderText"> + <string>version</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButtonProtocolNameVersion"> + <property name="text"> + <string>Send name and version</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="2" column="2"> + <widget class="QGroupBox" name="groupBox_2"> + <property name="title"> + <string>Client</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_5"> + <item> + <widget class="QLineEdit" name="lineEditClientName"> + <property name="placeholderText"> + <string>Test client catchcopy</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButtonClientName"> + <property name="text"> + <string>Send name</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="0" column="2"> + <widget class="QPushButton" name="pushButtonAskServerName"> + <property name="text"> + <string>Ask server name</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_4"> + <item> + <widget class="QGroupBox" name="groupBoxCopyMove"> + <property name="title"> + <string>Copy/Move</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_6"> + <item> + <widget class="QComboBox" name="comboBoxCopyType"> + <item> + <property name="text"> + <string>Copy</string> + </property> + </item> + <item> + <property name="text"> + <string>Move</string> + </property> + </item> + </widget> + </item> + <item> + <widget class="QLabel" name="label_6"> + <property name="text"> + <string>Source:</string> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <widget class="QLineEdit" name="lineEditAddCopy"/> + </item> + <item> + <widget class="QPushButton" name="pushButtonCopyAdd"> + <property name="text"> + <string>+</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButtonCopyRemove"> + <property name="text"> + <string>-</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QListWidget" name="listWidgetCopy"> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>50</height> + </size> + </property> + <property name="styleSheet"> + <string notr="true">background-image: url(:/images/upload.png); +background-position : center; +background-repeat : no-repeat; +background-color : #fff; +background-attachment : fixed;</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButtonCopyWithoutDestination"> + <property name="text"> + <string>Send without destination</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_7"> + <property name="text"> + <string>Destination:</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="lineEditCopyDestination"/> + </item> + <item> + <widget class="QPushButton" name="pushButtonCopyWithDestination"> + <property name="text"> + <string>Send with destination</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox_3"> + <property name="title"> + <string>Error</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <widget class="QListWidget" name="listError"/> + </item> + </layout> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QGroupBox" name="groupBoxRaw"> + <property name="title"> + <string>Raw</string> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="1"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Command</string> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Sended</string> + </property> + </widget> + </item> + <item row="2" column="2"> + <widget class="QListWidget" name="listCommandListSended"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="styleSheet"> + <string notr="true">background-image: url(:/images/upload.png); +background-position : center; +background-repeat : no-repeat; +background-color : #fff; +background-attachment : fixed; +</string> + </property> + </widget> + </item> + <item row="0" column="3"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Reply</string> + </property> + </widget> + </item> + <item row="2" column="3"> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLineEdit" name="lineReplyCode"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QTimeEdit" name="timeEditReply"> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QListWidget" name="listReplyList"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="styleSheet"> + <string notr="true">background-image: url(:/images/download.png); +background-position : center; +background-repeat : no-repeat; +background-color : #fff; +background-attachment : fixed; +</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="2" column="1"> + <widget class="QListWidget" name="listCommand"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>200</height> + </size> + </property> + <property name="styleSheet"> + <string notr="true">background-image: url(:/images/tools-report-bug.png); +background-position : center; +background-repeat : no-repeat; +background-color : #fff; +background-attachment : fixed; +</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <widget class="QToolBar" name="mainToolBar"> + <property name="iconSize"> + <size> + <width>48</width> + <height>48</height> + </size> + </property> + <property name="toolButtonStyle"> + <enum>Qt::ToolButtonTextBesideIcon</enum> + </property> + <attribute name="toolBarArea"> + <enum>TopToolBarArea</enum> + </attribute> + <attribute name="toolBarBreak"> + <bool>false</bool> + </attribute> + <addaction name="actionConnect"/> + <addaction name="actionDisconnect"/> + </widget> + <widget class="QStatusBar" name="statusBar"/> + <action name="actionConnect"> + <property name="icon"> + <iconset resource="resources.qrc"> + <normaloff>:/images/dialog-ok-apply.png</normaloff>:/images/dialog-ok-apply.png</iconset> + </property> + <property name="text"> + <string>Connect</string> + </property> + </action> + <action name="actionDisconnect"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="icon"> + <iconset resource="resources.qrc"> + <normaloff>:/images/process-stop.png</normaloff>:/images/process-stop.png</iconset> + </property> + <property name="text"> + <string>Disconnect</string> + </property> + </action> + </widget> + <layoutdefault spacing="6" margin="11"/> + <resources> + <include location="resources.qrc"/> + </resources> + <connections/> +</ui> diff --git a/test-client-catchcopy/resources-windows.rc b/test-client-catchcopy/resources-windows.rc new file mode 100755 index 0000000..9ca49be --- /dev/null +++ b/test-client-catchcopy/resources-windows.rc @@ -0,0 +1,2 @@ +IDI_ICON1 ICON DISCARDABLE "icon.ico" + diff --git a/test-client-catchcopy/resources.qrc b/test-client-catchcopy/resources.qrc new file mode 100644 index 0000000..061e445 --- /dev/null +++ b/test-client-catchcopy/resources.qrc @@ -0,0 +1,10 @@ +<RCC> + <qresource prefix="/"> + <file>images/dialog-ok-apply.png</file> + <file>images/download.png</file> + <file>images/main.png</file> + <file>images/process-stop.png</file> + <file>images/upload.png</file> + <file>images/tools-report-bug.png</file> + </qresource> +</RCC> diff --git a/test-client-catchcopy/test-client-catchcopy.pro b/test-client-catchcopy/test-client-catchcopy.pro new file mode 100644 index 0000000..40b9567 --- /dev/null +++ b/test-client-catchcopy/test-client-catchcopy.pro @@ -0,0 +1,24 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2010-11-14T13:02:19 +# +#------------------------------------------------- + +QT += core gui network widgets + +TARGET = test-client-catchcopy +TEMPLATE = app + + +SOURCES += main.cpp\ + mainwindow.cpp \ + catchcopy-api-0002/ClientCatchcopy.cpp \ + catchcopy-api-0002/ExtraSocketCatchcopy.cpp + +HEADERS += mainwindow.h \ + catchcopy-api-0002/ClientCatchcopy.h \ + catchcopy-api-0002/ExtraSocketCatchcopy.h + +FORMS += mainwindow.ui +win32:RC_FILE += resources-windows.rc +RESOURCES += resources.qrc |