Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tmsgcore.h"
Toshihiro Shimizu 890ddd
#include <qlocalserver.h></qlocalserver.h>
Toshihiro Shimizu 890ddd
#include <qlocalsocket.h></qlocalsocket.h>
Toshihiro Shimizu 890ddd
#include <qstringlist></qstringlist>
Toshihiro Shimizu 890ddd
#include <qcoreapplication></qcoreapplication>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <qtcpserver></qtcpserver>
Toshihiro Shimizu 890ddd
#include <qtcpsocket></qtcpsocket>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TMsgCore *TMsgCore::instance() {
shun-iwasawa 443318
  static TMsgCore *theInstance = 0;
Shinya Kitaoka 120a6e
  if (!theInstance) theInstance = new TMsgCore();
Shinya Kitaoka 120a6e
  return theInstance;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TMsgCore::TMsgCore() : m_tcpServer(0), m_clientSocket(0) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TMsgCore::OnNewConnection()  // server side
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  QTcpSocket *socket;
Shinya Kitaoka 120a6e
  if (m_tcpServer) socket = m_tcpServer->nextPendingConnection();
Shinya Kitaoka 120a6e
  assert(socket);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool ret = connect(socket, SIGNAL(readyRead()), SLOT(OnReadyRead()));
Shinya Kitaoka 120a6e
  ret = ret && connect(socket, SIGNAL(disconnected()), SLOT(OnDisconnected()));
Shinya Kitaoka 120a6e
  assert(ret);
Shinya Kitaoka 120a6e
  m_sockets.insert(socket);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define TMSG_PORT 10545
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TMsgCore::openConnection()  // server side
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  // QHostAddress host = (remoteConnection) ?
Shinya Kitaoka 120a6e
  // QHostAddress::AnyQHostAddress::LocalHost : ;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_tcpServer != 0 && m_tcpServer->serverAddress() == QHostAddress::Any)
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  if (m_tcpServer != 0) delete m_tcpServer;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_tcpServer = new QTcpServer();
Shinya Kitaoka 120a6e
  bool ret =
Shinya Kitaoka 120a6e
      connect(m_tcpServer, SIGNAL(newConnection()), SLOT(OnNewConnection()));
Shinya Kitaoka 120a6e
  // bool listen =
Shinya Kitaoka 120a6e
  // m_tcpServer->listen(QString("tmsg")+QString::number(QCoreApplication::applicationPid()));
Shinya Kitaoka 120a6e
  bool listen = m_tcpServer->listen(
Shinya Kitaoka 120a6e
      QHostAddress::Any,
Shinya Kitaoka 120a6e
      TMSG_PORT);  // QString("tmsg")+QString::number(QCoreApplication::applicationPid()));
Shinya Kitaoka 120a6e
  if (!listen) {
Shinya Kitaoka 120a6e
    QString err = m_tcpServer->errorString();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  assert(ret && listen);
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
QString TMsgCore::getConnectionName()  // server side
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  assert(m_tcpServer);
Shinya Kitaoka 120a6e
  QString serverName = "pippo";  // m_tcpServer->serverName();
Shinya Kitaoka 120a6e
  return serverName;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TMsgCore::OnDisconnected()  // server side
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  std::set<qtcpsocket *="">::iterator it = m_sockets.begin();</qtcpsocket>
Shinya Kitaoka 120a6e
  while (it != m_sockets.end()) {
Shinya Kitaoka 120a6e
    if ((*it)->state() != QTcpSocket::ConnectedState)
Shinya Kitaoka 120a6e
      m_sockets.erase(it++);
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      it++;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // if (m_socketIn)
Shinya Kitaoka 120a6e
  // delete m_socketIn;
Shinya Kitaoka 120a6e
  // m_socketIn = 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TMsgCore::OnReadyRead()  // server side
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  std::set<qtcpsocket *="">::iterator it = m_sockets.begin();</qtcpsocket>
Shinya Kitaoka 120a6e
  for (; it != m_sockets.end(); it++)  // devo scorrerli tutti perche' non so da
Shinya Kitaoka 120a6e
                                       // quale socket viene il messaggio...
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    if ((*it)->state() == QTcpSocket::ConnectedState &&
Shinya Kitaoka 120a6e
        (*it)->bytesAvailable() > 0)
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (it != m_sockets.end()) {
Shinya Kitaoka 120a6e
    readFromSocket(*it);
Shinya Kitaoka 120a6e
    OnReadyRead();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TMsgCore::readFromSocket(QTcpSocket *socket)  // server side
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  static char data[1024];
Shinya Kitaoka 120a6e
  static QString prevMessage;
Shinya Kitaoka 120a6e
  QString str;
Shinya Kitaoka 120a6e
  int byteread;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while ((byteread = socket->read(data, 1023)) != 0) {
Shinya Kitaoka 120a6e
    data[byteread] = '\0';
Shinya Kitaoka 120a6e
    str += QString(data);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  QString message = prevMessage + str;
Shinya Kitaoka 120a6e
  prevMessage     = QString();
Shinya Kitaoka 120a6e
  if (message.isEmpty()) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int lastEnd   = message.lastIndexOf("#END");
Shinya Kitaoka 120a6e
  int lastbegin = message.lastIndexOf("#TMSG");
Shinya Kitaoka 120a6e
  if (lastbegin == -1 && lastEnd == -1) {
Shinya Kitaoka 120a6e
    prevMessage = message;
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  } else if (lastbegin != -1 && lastEnd != -1 && lastEnd < lastbegin) {
Shinya Kitaoka 120a6e
    prevMessage = message.right(message.size() - lastbegin);
Shinya Kitaoka 120a6e
    message.chop(lastbegin);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
shun-iwasawa 443318
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
shun-iwasawa 443318
  QStringList messages = message.split("#TMSG", Qt::SkipEmptyParts);
shun-iwasawa 443318
#else
Shinya Kitaoka 120a6e
  QStringList messages = message.split("#TMSG", QString::SkipEmptyParts);
shun-iwasawa 443318
#endif
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (int i = 0; i < messages.size(); i++) {
Shinya Kitaoka 120a6e
    QString str = messages.at(i).simplified();
Shinya Kitaoka 120a6e
    str.chop(4);  // rimuovo i "#END" alla fine
Shinya Kitaoka 120a6e
    if (str.startsWith("ERROR"))
Shinya Kitaoka 120a6e
      DVGui::error(str.right(str.size() - 5));
Shinya Kitaoka 120a6e
    else if (str.startsWith("WARNING"))
Shinya Kitaoka 120a6e
      DVGui::warning(str.right(str.size() - 7));
Shinya Kitaoka 120a6e
    else if (str.startsWith("INFO"))
Shinya Kitaoka 120a6e
      DVGui::info(str.right(str.size() - 4));
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      assert(false);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TMsgCore::~TMsgCore() {
Shinya Kitaoka 120a6e
  if (m_tcpServer == 0 && m_clientSocket != 0)  // client side
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    // m_socketIn->waitForBytesWritten (-1);
Shinya Kitaoka 120a6e
    //   m_clientSocket->disconnectFromServer();
Shinya Kitaoka 120a6e
    // m_clientSocket->waitForDisconnected();
Shinya Kitaoka 120a6e
    delete m_clientSocket;
Shinya Kitaoka 120a6e
    m_clientSocket = 0;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TMsgCore::send(DVGui::MsgType type, const QString &message)  // client side
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  if (receivers(SIGNAL(sendMessage(int, const QString &))) == 0) {
Shinya Kitaoka 120a6e
    if (m_clientSocket == 0 ||
Shinya Kitaoka 120a6e
        m_clientSocket->state() != QTcpSocket::ConnectedState)
Shinya Kitaoka 120a6e
      return false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    QString socketMessage =
Shinya Kitaoka 120a6e
        (type == DVGui::CRITICAL
Shinya Kitaoka 120a6e
             ? "#TMSG ERROR "
Shinya Kitaoka 120a6e
             : (type == DVGui::WARNING ? "#TMSG WARNING " : "#TMSG INFO ")) +
Shinya Kitaoka 120a6e
        message + " #END\n";
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    m_clientSocket->write(socketMessage.toLatin1());
Shinya Kitaoka 120a6e
    m_clientSocket->flush();
Shinya Kitaoka 120a6e
    // m_clientSocket->waitForBytesWritten (1000);
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    Q_EMIT sendMessage(type, message);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TMsgCore::connectTo(const QString &address)  // client side
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  m_clientSocket = new QTcpSocket();
Shinya Kitaoka 120a6e
  m_clientSocket->connectToHost(
Shinya Kitaoka 120a6e
      address == "" ? QHostAddress::LocalHost : QHostAddress(address),
Shinya Kitaoka 120a6e
      TMSG_PORT);
Shinya Kitaoka 120a6e
  // m_clientSocket->connectToServer (connectionName, QIODevice::ReadWrite |
Shinya Kitaoka 120a6e
  // QIODevice::Text);
Shinya Kitaoka 120a6e
  bool ret = m_clientSocket->waitForConnected(1000);
Shinya Kitaoka 120a6e
  if (!ret) {
Shinya Kitaoka 120a6e
    // std::cout << "cannot connect to "<< address.toStdString() << std::endl;
Shinya Kitaoka 120a6e
    // std::cout << "error "<< m_clientSocket->errorString().toStdString() <<
Shinya Kitaoka 120a6e
    // std::endl;
Shinya Kitaoka 120a6e
    int err = m_clientSocket->error();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void DVGui::MsgBox(MsgType type, const QString &text) {
Shinya Kitaoka 120a6e
  TMsgCore::instance()->send(type, text);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void DVGui::error(const QString &msg) { DVGui::MsgBox(DVGui::CRITICAL, msg); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void DVGui::warning(const QString &msg) { DVGui::MsgBox(DVGui::WARNING, msg); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void DVGui::info(const QString &msg) { DVGui::MsgBox(DVGui::INFORMATION, msg); }