Algorithm-VSM

 view release on metacpan or  search on metacpan

examples/corpus_with_java_and_cpp/ChatServer.cc  view on Meta::CPAN

    if ( !ok() ) {
        qWarning( "Failed to register the server port" );
        exit( 1 );
    }
}

// You must provide an override implementation for
// this method.  When a client requests a connection,
// this method will be called automatically with the
// socket argument set to the filedescriptor associated
// with the socket.
void ChatServer::newConnection( int socketFD ) {
    QSocket* socket = new QSocket();
    socket->setSocket( socketFD );
    ClientHandler* clh = new ClientHandler( socket, this );
    cout << "A new client checked in on socket FD " 
         << socketFD << endl;
}

ChatServer::~ChatServer(){}

ClientHandler::ClientHandler() {}

// Copy constructor is needed since it is the copies of
// the ClientHandler objects that will be stored in the
// vector clientVector
ClientHandler::ClientHandler( const ClientHandler& other )
    : handlerSocket( other.handlerSocket ),
      chatName( other.chatName ),
      chatServer( other.chatServer ),
      os( other.os )
{}

ClientHandler& ClientHandler::operator=( const ClientHandler& other ) {
    if ( this == &other ) return *this;

    cout << "ClientHandler assignment op invoked" << endl;

    if ( handlerSocket != 0 ) delete handlerSocket;
    handlerSocket = other.handlerSocket;
    if ( chatName != 0 ) delete chatName;
    chatName = other.chatName;
    if ( os != 0 ) delete os;
    os = other.os;
    chatServer = other.chatServer;
}

ClientHandler::ClientHandler( QSocket* socket, ChatServer* chatserver )
    : chatName(0), 
      chatServer( chatserver ),
      handlerSocket( socket )
{
    os = new QTextStream( handlerSocket );

    (*os) << "Welcome to a chat room powered by C++\n";      
    (*os) << ">>>>    Enter 'bye' to exit   <<<\n";      
    (*os) << "Enter chat name: ";      

    connect( handlerSocket, SIGNAL( readyRead() ),
             this, SLOT( readFromClient() ) );
    connect( handlerSocket, SIGNAL( error( int ) ),
             this,   SLOT( reportError( int ) ) );
}

// The destructor definition intentionally does not invoke 
// the delete operator on any of the objects pointed to 
// by the data members of a ClientHandler.  In this program, 
// the most frequent invocation of the destructor is caused 
// by the push_back statement in the readFromClient() 
// function.  The push_back invocation causes the vector 
// to be moved to a different location in the memory.  The 
// memory occupied by the ClientHandler objects in the 
// vector is freed by invoking the destructor.  Deleting 
// the memory occupied by the socket and other objects 
// pointed to by the data members of the ClientHandler 
// objects would lead to disastrous results.
ClientHandler::~ClientHandler(){}

void ClientHandler::reportError( int e ) {
    cout << "error report from connectToHost" << endl; 
    cout << "error id: " << e << endl;
}

void ClientHandler::readFromClient() {
    QSocket* sock = (QSocket*) sender();
    while ( sock->canReadLine() ) {
        QString qstr = sock->readLine();

        // This block is for the case when a new chatter 
        // has just signed in and supplied his/her chat name. 
        // The block sets the chatname of the ClientHandler 
        // object assigned to this new user.  Next it pushes 
        // the ClientHandler object for this new user in the 
        // vector clientVector.  Subsequently, The block informs 
        // all other current chatters that this new user has
        // signed in.
        if ( chatName == 0 ) {
            chatName = new QString( qstr.stripWhiteSpace() );
            chatServer->clientVector.push_back( *this );
            for ( int i=0; i<chatServer->clientVector.size(); i++ ) {
                if ( *chatServer->clientVector[i].chatName 
                                          != *chatName &&
                     chatServer->clientVector[i].handlerSocket != 0 ) {
                    QString outgoing = "\nMessage from chat server: " 
                                    + *chatName + " signed in ";
                    *chatServer->clientVector[i].os << outgoing;
                }
            }
        }

        // This block treats the case when a chatter wants 
        // to sign out by typing "bye".  It broadcasts a message 
        // to all the other chatters that this chatter is signing 
        // off.  This block than closes the socket.  Note that 
        // socket pointer is set to null in both the ClientHandler 
        // object assigned to the exiting chatter and its copy the 
        // vector clientVector.
        else if ( qstr.stripWhiteSpace() == "bye" ) {
            for ( int i=0; i<chatServer->clientVector.size(); i++ ) {
                QString outgoing( "\nMessage from the chat server: " +
                          *chatName + " signed off" );
                if ( *chatServer->clientVector[i].chatName 
                                                 != *chatName  &&
                     chatServer->clientVector[i].handlerSocket != 0 ) {
                    *chatServer->clientVector[i].os << outgoing;
                }
            }
            handlerSocket->close();
            handlerSocket = 0;
            for ( int i=0; i<chatServer->clientVector.size(); i++ ) {
                if (*chatServer->clientVector[i].chatName == *chatName)
                    chatServer->clientVector[i].handlerSocket = 0;
            }
        }

        // This is the normal case encountered during the 
        // course of a chat.  The string typed in by a 
        // chatter is broadcast to all the other chatters.  
        // The string is pre-pended by the name of the 
        // chatter who typed in the string.
        else {



( run in 1.161 second using v1.01-cache-2.11-cpan-97f6503c9c8 )