Shinya Kitaoka 810553
#pragma once
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef TIPC_H
Toshihiro Shimizu 890ddd
#define TIPC_H
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// Qt includes
Toshihiro Shimizu 890ddd
#include <qdatastream></qdatastream>
Toshihiro Shimizu 890ddd
#include <qbytearray></qbytearray>
Toshihiro Shimizu 890ddd
#include <qlocalsocket></qlocalsocket>
Toshihiro Shimizu 890ddd
#include <qeventloop></qeventloop>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// STL includes
Toshihiro Shimizu 890ddd
#include <limits></limits>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// Toonz includes
Toshihiro Shimizu 890ddd
#include "tcommon.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#undef DVAPI
Toshihiro Shimizu 890ddd
#undef DVVAR
Toshihiro Shimizu 890ddd
#ifdef TNZCORE_EXPORTS
Toshihiro Shimizu 890ddd
#define DVAPI DV_EXPORT_API
Toshihiro Shimizu 890ddd
#define DVVAR DV_EXPORT_VAR
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#define DVAPI DV_IMPORT_API
Toshihiro Shimizu 890ddd
#define DVVAR DV_IMPORT_VAR
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//  Forward declarations
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class QSharedMemory;
Toshihiro Shimizu 890ddd
class QProcess;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//********************************************************
Toshihiro Shimizu 890ddd
//    Toonz Inter-Process Communication namespace
Toshihiro Shimizu 890ddd
//********************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*! \namespace tipc
Toshihiro Shimizu 890ddd
  The tipc namespace provides facilities to deal with
Toshihiro Shimizu 890ddd
  inter-process communication tasks.
Toshihiro Shimizu 890ddd
  The tipc inner workings make use of Qt's
Toshihiro Shimizu 890ddd
  QLocalServer/QLocalSocket standard ipc framework;
Toshihiro Shimizu 890ddd
  but moreover, it helps the user hiding some of the
Toshihiro Shimizu 890ddd
  intricacies of ipc management.
Toshihiro Shimizu 890ddd
\m \m
Toshihiro Shimizu 890ddd
  The tipc model assumes there is a server process
Toshihiro Shimizu 890ddd
  running to which several processes can connect to in order
Toshihiro Shimizu 890ddd
  to require services through appropriate server-supported
Toshihiro Shimizu 890ddd
  commands. Communication happens by sending tipc::Message
Toshihiro Shimizu 890ddd
  instances through a tipc::Stream constructed on a
Toshihiro Shimizu 890ddd
  QLocalSocket device connected to the server in a Qt-like
Toshihiro Shimizu 890ddd
  manner.
Toshihiro Shimizu 890ddd
\n\n
Toshihiro Shimizu 890ddd
  Messages encapsulate an atomic communication that must be
Toshihiro Shimizu 890ddd
  received in its entirety to be understood by the receiver.
Toshihiro Shimizu 890ddd
  Any message sent by a client must provide a QString header
Toshihiro Shimizu 890ddd
  to identify the message type, which must be recognizable
Toshihiro Shimizu 890ddd
  by the server side to be appropriately parsed.
Toshihiro Shimizu 890ddd
  Each message understood by the server process will be replied
Toshihiro Shimizu 890ddd
  with a message to ensure the client that the parsing has
Toshihiro Shimizu 890ddd
  been completed.
Toshihiro Shimizu 890ddd
\n\n
Toshihiro Shimizu 890ddd
  A tipc::Server instance must be used on the server side to
Toshihiro Shimizu 890ddd
  process supported messages. Message parsing is responsibility
Toshihiro Shimizu 890ddd
  of specific subclasses of the tipc::MessageParser base class,
Toshihiro Shimizu 890ddd
  which must be implemented and added to the server.
Toshihiro Shimizu 890ddd
\n \n
Toshihiro Shimizu 890ddd
  Tipc standard messages include requests for temporary files
Toshihiro Shimizu 890ddd
  or shared memory segments, which must be released after use.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace tipc {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//********************************************************
Toshihiro Shimizu 890ddd
//    tipc Fundamental Classes
Toshihiro Shimizu 890ddd
//********************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  The tipc::Message class encapsulates several data into one single byte array
Toshihiro Shimizu 890ddd
  in order to make data transfer among sockets an atomic operation.
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
class Message {
Shinya Kitaoka 120a6e
  QByteArray m_ba;
Shinya Kitaoka 120a6e
  QDataStream m_ds;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  Message() : m_ba(), m_ds(&m_ba, QIODevice::ReadWrite) {}
Shinya Kitaoka 120a6e
  ~Message() {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  const QByteArray &ba() const { return m_ba; }
Shinya Kitaoka 120a6e
  QByteArray &ba() { return m_ba; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  const QDataStream &ds() const { return m_ds; }
Shinya Kitaoka 120a6e
  QDataStream &ds() { return m_ds; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  template <typename type=""></typename>
Shinya Kitaoka 120a6e
  Message &operator<<(const Type &data) {
Shinya Kitaoka 120a6e
    m_ds << data;
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  template <typename type=""></typename>
Shinya Kitaoka 120a6e
  Message &operator>>(Type &data) {
Shinya Kitaoka 120a6e
    m_ds >> data;
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  Message &operator<<(const char *str) { return operator<<(QString(str)); }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void clear() {
Shinya Kitaoka 120a6e
    m_ba.clear();
Shinya Kitaoka 120a6e
    m_ds.device()->seek(0);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  A tipc::Stream is a specialized QDataStream designed to work with a tipc-based
Toshihiro Shimizu 890ddd
  QLocalSocket instance.
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka d1f6c4
class DVAPI Stream final : public QDataStream {
Shinya Kitaoka 120a6e
  QLocalSocket *m_socket;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  Stream(QLocalSocket *socket) : QDataStream(socket), m_socket(socket) {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  QLocalSocket *socket() { return m_socket; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int readSize();
Shinya Kitaoka 120a6e
  bool messageReady();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bool readData(char *data, qint64 dataSize, int msecs = -1);
Shinya Kitaoka 120a6e
  bool readMessage(Message &msg, int msecs = -1);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bool readDataNB(char *data, qint64 dataSize, int msecs = -1,
Shinya Kitaoka 120a6e
                  QEventLoop::ProcessEventsFlag flag = QEventLoop::AllEvents);
Shinya Kitaoka 120a6e
  bool readMessageNB(
Shinya Kitaoka 120a6e
      Message &msg, int msecs = -1,
Shinya Kitaoka 120a6e
      QEventLoop::ProcessEventsFlag flag = QEventLoop::AllEvents);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bool flush(int msecs = -1);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace tipc
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//********************************************************
Toshihiro Shimizu 890ddd
//    tipc Stream Operators
Toshihiro Shimizu 890ddd
//********************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI tipc::Stream &operator>>(tipc::Stream &stream, tipc::Message &msg);
Toshihiro Shimizu 890ddd
DVAPI tipc::Stream &operator<<(tipc::Stream &stream, tipc::Message &msg);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline tipc::Message &operator<<(tipc::Message &msg,
Shinya Kitaoka 120a6e
                                 tipc::Message &(*func)(tipc::Message &)) {
Shinya Kitaoka 120a6e
  return func(msg);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline tipc::Message &operator>>(tipc::Message &msg,
Shinya Kitaoka 120a6e
                                 tipc::Message &(*func)(tipc::Message &)) {
Shinya Kitaoka 120a6e
  return func(msg);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//********************************************************
Toshihiro Shimizu 890ddd
//    tipc Stream Manipulator Functions
Toshihiro Shimizu 890ddd
//********************************************************
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace tipc {
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline Message &clr(Message &msg) {
Shinya Kitaoka 120a6e
  msg.clear();
Shinya Kitaoka 120a6e
  return msg;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline Message &reset(Message &msg) {
Shinya Kitaoka 120a6e
  msg.ds().device()->seek(0);
Shinya Kitaoka 120a6e
  return msg;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace tipc
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//********************************************************
Toshihiro Shimizu 890ddd
//    tipc Utility Functions
Toshihiro Shimizu 890ddd
//********************************************************
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace tipc {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------- Connection-message utilities ----------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI bool startBackgroundProcess(QString cmdline);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI QString applicationSpecificServerName(QString srvName);
Shinya Kitaoka 120a6e
DVAPI bool startSlaveConnection(QLocalSocket *socket, QString srvName,
Shinya Kitaoka 120a6e
                                int msecs = -1, QString cmdline = QString(),
Shinya Kitaoka 120a6e
                                QString threadName = QString());
Toshihiro Shimizu 890ddd
DVAPI bool startSlaveServer(QString srvName, QString cmdline);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI QString readMessage(Stream &stream, Message &msg, int msecs = -1);
Shinya Kitaoka 120a6e
DVAPI QString
Shinya Kitaoka 120a6e
readMessageNB(Stream &stream, Message &msg, int msecs = -1,
Shinya Kitaoka 120a6e
              QEventLoop::ProcessEventsFlag flag = QEventLoop::AllEvents);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------- Shared Memory utilities ----------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI int shm_maxSegmentSize();
Toshihiro Shimizu 890ddd
DVAPI int shm_maxSegmentCount();
Toshihiro Shimizu 890ddd
DVAPI int shm_maxSharedPages();
Toshihiro Shimizu 890ddd
DVAPI int shm_maxSharedCount();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
DVAPI void shm_set(int maxSegmentSize, int maxSegmentCount, int maxSharedSize,
Shinya Kitaoka 120a6e
                   int maxSharedCount);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI QString uniqueId();
Toshihiro Shimizu 890ddd
DVAPI int create(QSharedMemory &shmem, int size, bool strictSize = false);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class ShMemReader {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  virtual int read(const char *srcBuf, int len) = 0;
Toshihiro Shimizu 890ddd
};
Shinya Kitaoka 120a6e
class ShMemWriter {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  virtual int write(char *dstBuf, int len) = 0;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
DVAPI bool readShMemBuffer(Stream &stream, Message &msg,
Shinya Kitaoka 120a6e
                           ShMemReader *dataReader);
Shinya Kitaoka 120a6e
DVAPI bool writeShMemBuffer(Stream &stream, Message &msg, int bufSize,
Shinya Kitaoka 120a6e
                            ShMemWriter *dataWriter);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace tipc
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//********************************************************
Toshihiro Shimizu 890ddd
//    STL compatibility Stream operators
Toshihiro Shimizu 890ddd
//********************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename t=""></typename>
Shinya Kitaoka 120a6e
QDataStream &operator<<(QDataStream &ds, const std::vector<t> &vec) {</t>
Shinya Kitaoka 120a6e
  unsigned int i, size = vec.size();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ds << size;
Shinya Kitaoka 120a6e
  for (i = 0; i < size; ++i) ds << vec[i];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return ds;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename t=""></typename>
Shinya Kitaoka 120a6e
QDataStream &operator>>(QDataStream &ds, T &vec) {
Shinya Kitaoka 120a6e
  return ds >> vec;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename t=""></typename>
Shinya Kitaoka 120a6e
QDataStream &operator>>(QDataStream &ds, std::vector<t> &vec) {</t>
Shinya Kitaoka 120a6e
  unsigned int i, size;
Shinya Kitaoka 120a6e
  T val;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ds >> size;
Shinya Kitaoka 120a6e
  vec.reserve(size);
Shinya Kitaoka 120a6e
  for (i = 0; i < size; ++i) {
Shinya Kitaoka 120a6e
    ds >> val;
Shinya Kitaoka 120a6e
    vec.push_back(val);
Shinya Kitaoka 120a6e
    if (ds.atEnd()) break;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return ds;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline QDataStream &operator<<(QDataStream &ds, const std::string &str) {
Shinya Kitaoka 120a6e
  ds << QString::fromStdString(str);
Shinya Kitaoka 120a6e
  return ds;
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 120a6e
inline QDataStream &operator>>(QDataStream &ds, std::string &str) {
Shinya Kitaoka 120a6e
  QString qstr;
Shinya Kitaoka 120a6e
  ds >> qstr;
Shinya Kitaoka 120a6e
  str = qstr.toStdString();
Shinya Kitaoka 120a6e
  return ds;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline QDataStream &operator<<(QDataStream &ds, const std::wstring &str) {
Shinya Kitaoka 120a6e
  ds << QString::fromStdWString(str);
Shinya Kitaoka 120a6e
  return ds;
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 120a6e
inline QDataStream &operator>>(QDataStream &ds, std::wstring &str) {
Shinya Kitaoka 120a6e
  QString qstr;
Shinya Kitaoka 120a6e
  ds >> qstr;
Shinya Kitaoka 120a6e
  str = qstr.toStdWString();
Shinya Kitaoka 120a6e
  return ds;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline QDataStream &operator<<(QDataStream &ds, const wchar_t &ch) {
Shinya Kitaoka 120a6e
  ds.writeRawData((const char *)&ch, sizeof(wchar_t));
Shinya Kitaoka 120a6e
  return ds;
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 120a6e
inline QDataStream &operator>>(QDataStream &ds, wchar_t &ch) {
Shinya Kitaoka 120a6e
  ds.readRawData((char *)&ch, sizeof(wchar_t));
Shinya Kitaoka 120a6e
  return ds;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#endif  // TIPC_H