Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "assert.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// Qt includes
Toshihiro Shimizu 890ddd
#include <qdatastream></qdatastream>
Toshihiro Shimizu 890ddd
#include <qdebug></qdebug>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tipc.h"
Toshihiro Shimizu 890ddd
#include "tipcmsg.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tipcsrvP.h"
Toshihiro Shimizu 890ddd
#include "tipcsrv.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//*******************************************************************************
Toshihiro Shimizu 890ddd
//    Diagnostics stuff
Toshihiro Shimizu 890ddd
//*******************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//#define TIPC_DEBUG
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef TIPC_DEBUG
Toshihiro Shimizu 890ddd
#define tipc_debug(expr) expr
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#define tipc_debug(expr)
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef TIPC_DEBUG
Toshihiro Shimizu 890ddd
#include <qtime></qtime>
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//*******************************************************************************
Toshihiro Shimizu 890ddd
//    tipc::SocketListener implementation
Toshihiro Shimizu 890ddd
//*******************************************************************************
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void tipc::SocketController::onReadyRead() {
Shinya Kitaoka 120a6e
  // Deliver the message to the server for interpretation.
Shinya Kitaoka 120a6e
  m_server->dispatchSocket(m_socket);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void tipc::SocketController::onDisconnected() {
Shinya Kitaoka 120a6e
  m_socket->QObject::disconnect(SIGNAL(readyRead()));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Auto-delete this
Shinya Kitaoka 120a6e
  delete this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//*******************************************************************************
Toshihiro Shimizu 890ddd
//    Server implementation
Toshihiro Shimizu 890ddd
//*******************************************************************************
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
tipc::Server::Server() : m_lock(false) {
Shinya Kitaoka 120a6e
  connect(this, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Add default parsers
Shinya Kitaoka 120a6e
  addParser(new DefaultMessageParser<shmem_request>);</shmem_request>
Shinya Kitaoka 120a6e
  addParser(new DefaultMessageParser<shmem_release>);</shmem_release>
Shinya Kitaoka 120a6e
  addParser(new DefaultMessageParser<tmpfile_request>);</tmpfile_request>
Shinya Kitaoka 120a6e
  addParser(new DefaultMessageParser<tmpfile_release>);</tmpfile_release>
Shinya Kitaoka 120a6e
  addParser(new DefaultMessageParser<quit_on_error>);</quit_on_error>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
tipc::Server::~Server() {
Shinya Kitaoka 120a6e
  // Release parsers
Shinya Kitaoka 120a6e
  QHash<qstring, *="" messageparser="">::iterator it;</qstring,>
Shinya Kitaoka 120a6e
  for (it = m_parsers.begin(); it != m_parsers.end(); ++it) delete it.value();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void tipc::Server::addParser(MessageParser *parser) {
Shinya Kitaoka 120a6e
  m_parsers.insert(parser->header(), parser);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void tipc::Server::removeParser(QString header) {
Shinya Kitaoka 120a6e
  MessageParser *parser = m_parsers.take(header);
Shinya Kitaoka 120a6e
  if (parser) delete parser;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void tipc::Server::onNewConnection() {
Shinya Kitaoka 120a6e
  tipc_debug(qDebug("new connection"));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Accept the connection
Shinya Kitaoka 120a6e
  QLocalSocket *socket = nextPendingConnection();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Allocate a controller for the socket
Shinya Kitaoka 120a6e
  SocketController *controller = new SocketController;
Shinya Kitaoka 120a6e
  controller->m_server         = this;
Shinya Kitaoka 120a6e
  controller->m_socket         = socket;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Connect the controller to the socket's signals
Shinya Kitaoka 120a6e
  connect(socket, SIGNAL(readyRead()), controller, SLOT(onReadyRead()));
Shinya Kitaoka 120a6e
  connect(socket, SIGNAL(disconnected()), controller, SLOT(onDisconnected()));
Shinya Kitaoka 120a6e
  connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));
Shinya Kitaoka 120a6e
  connect(socket, SIGNAL(error(QLocalSocket::LocalSocketError)), this,
Shinya Kitaoka 120a6e
          SLOT(onError(QLocalSocket::LocalSocketError)));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void tipc::Server::onError(QLocalSocket::LocalSocketError error) {
Shinya Kitaoka 120a6e
  tipc_debug(qDebug() << "Server error #" << error << ": " << errorString());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void tipc::Server::dispatchSocket(QLocalSocket *socket) {
Shinya Kitaoka 120a6e
  // The lock is established when a message is currently being processed.
Shinya Kitaoka 120a6e
  // Returning if the lock is set avoids having recursive message processing;
Shinya Kitaoka 120a6e
  // which is possible if a parser expects further message packets.
Shinya Kitaoka 120a6e
  if (m_lock) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  tipc::Stream stream(socket);
Shinya Kitaoka 120a6e
  QString header;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  while (socket->bytesAvailable() > 0) {
Shinya Kitaoka 120a6e
    if (!stream.messageReady()) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    Message msg;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    stream >> msg;
Shinya Kitaoka 120a6e
    msg >> header;
Shinya Kitaoka 120a6e
    assert(!header.isEmpty());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    tipc_debug(qDebug() << header << endl);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    QHash<qstring, *="" messageparser="">::iterator it = m_parsers.find(header);</qstring,>
Shinya Kitaoka 120a6e
    if (it == m_parsers.end()) {
Shinya Kitaoka 120a6e
      tipc_debug(qDebug() << "Error: Unrecognized command" << endl);
Shinya Kitaoka 120a6e
      continue;
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    m_lock = true;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    MessageParser *parser = it.value();
Shinya Kitaoka 120a6e
    parser->m_socket      = socket;
Shinya Kitaoka 120a6e
    parser->m_stream      = &stream;
Shinya Kitaoka 120a6e
    parser->operator()(msg);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    m_lock = false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    // The Message has been read and processed. Send the reply.
Shinya Kitaoka 120a6e
    if (msg.ba().size() > 0) stream << msg;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}