Shinya Kitaoka 810553
#pragma once
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef TIPC_H
Toshihiro Shimizu 890ddd
#define TIPC_H
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//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
Toshihiro Shimizu 890ddd
//STL includes
Toshihiro Shimizu 890ddd
#include <limits></limits>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//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
Toshihiro Shimizu 890ddd
namespace tipc
Toshihiro Shimizu 890ddd
{
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
*/
Toshihiro Shimizu 890ddd
class Message
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QByteArray m_ba;
Toshihiro Shimizu 890ddd
	QDataStream m_ds;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	Message() : m_ba(), m_ds(&m_ba, QIODevice::ReadWrite) {}
Toshihiro Shimizu 890ddd
	~Message() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	const QByteArray &ba() const { return m_ba; }
Toshihiro Shimizu 890ddd
	QByteArray &ba() { return m_ba; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	const QDataStream &ds() const { return m_ds; }
Toshihiro Shimizu 890ddd
	QDataStream &ds() { return m_ds; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	template <typename type=""></typename>
Toshihiro Shimizu 890ddd
	Message &operator<<(const Type &data)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_ds << data;
Toshihiro Shimizu 890ddd
		return *this;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	template <typename type=""></typename>
Toshihiro Shimizu 890ddd
	Message &operator>>(Type &data)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_ds >> data;
Toshihiro Shimizu 890ddd
		return *this;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Message &operator<<(const char *str) { return operator<<(QString(str)); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void clear()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_ba.clear();
Toshihiro Shimizu 890ddd
		m_ds.device()->seek(0);
Toshihiro Shimizu 890ddd
	}
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
*/
Toshihiro Shimizu 890ddd
class DVAPI Stream : public QDataStream
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QLocalSocket *m_socket;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	Stream(QLocalSocket *socket) : QDataStream(socket), m_socket(socket) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QLocalSocket *socket() { return m_socket; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int readSize();
Toshihiro Shimizu 890ddd
	bool messageReady();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool readData(char *data, qint64 dataSize, int msecs = -1);
Toshihiro Shimizu 890ddd
	bool readMessage(Message &msg, int msecs = -1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool readDataNB(char *data, qint64 dataSize, int msecs = -1,
Toshihiro Shimizu 890ddd
					QEventLoop::ProcessEventsFlag flag = QEventLoop::AllEvents);
Toshihiro Shimizu 890ddd
	bool readMessageNB(Message &msg, int msecs = -1,
Toshihiro Shimizu 890ddd
					   QEventLoop::ProcessEventsFlag flag = QEventLoop::AllEvents);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool flush(int msecs = -1);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} //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
Toshihiro Shimizu 890ddd
inline tipc::Message &operator<<(tipc::Message &msg, tipc::Message &(*func)(tipc::Message &))
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return func(msg);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline tipc::Message &operator>>(tipc::Message &msg, tipc::Message &(*func)(tipc::Message &))
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	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
Toshihiro Shimizu 890ddd
namespace tipc
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline Message &clr(Message &msg)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	msg.clear();
Toshihiro Shimizu 890ddd
	return msg;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline Message &reset(Message &msg)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	msg.ds().device()->seek(0);
Toshihiro Shimizu 890ddd
	return msg;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} //namespace tipc
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//********************************************************
Toshihiro Shimizu 890ddd
//    tipc Utility Functions
Toshihiro Shimizu 890ddd
//********************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace tipc
Toshihiro Shimizu 890ddd
{
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);
Toshihiro Shimizu 890ddd
DVAPI bool startSlaveConnection(QLocalSocket *socket, QString srvName, int msecs = -1,
Toshihiro Shimizu 890ddd
								QString cmdline = QString(), 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);
Toshihiro Shimizu 890ddd
DVAPI QString readMessageNB(Stream &stream, Message &msg, int msecs = -1,
Toshihiro Shimizu 890ddd
							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
Toshihiro Shimizu 890ddd
DVAPI void shm_set(int maxSegmentSize, int maxSegmentCount, int maxSharedSize, 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
Toshihiro Shimizu 890ddd
class ShMemReader
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	virtual int read(const char *srcBuf, int len) = 0;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
class ShMemWriter
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	virtual int write(char *dstBuf, int len) = 0;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DVAPI bool readShMemBuffer(Stream &stream, Message &msg, ShMemReader *dataReader);
Toshihiro Shimizu 890ddd
DVAPI bool writeShMemBuffer(Stream &stream, Message &msg, int bufSize, ShMemWriter *dataWriter);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} //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>
Toshihiro Shimizu 890ddd
QDataStream &operator<<(QDataStream &ds, const std::vector<t> &vec)</t>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	unsigned int i, size = vec.size();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ds << size;
Toshihiro Shimizu 890ddd
	for (i = 0; i < size; ++i)
Toshihiro Shimizu 890ddd
		ds << vec[i];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return ds;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename t=""></typename>
Toshihiro Shimizu 890ddd
QDataStream &operator>>(QDataStream &ds, T &vec)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return ds >> vec;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename t=""></typename>
Toshihiro Shimizu 890ddd
QDataStream &operator>>(QDataStream &ds, std::vector<t> &vec)</t>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	unsigned int i, size;
Toshihiro Shimizu 890ddd
	T val;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ds >> size;
Toshihiro Shimizu 890ddd
	vec.reserve(size);
Toshihiro Shimizu 890ddd
	for (i = 0; i < size; ++i) {
Toshihiro Shimizu 890ddd
		ds >> val;
Toshihiro Shimizu 890ddd
		vec.push_back(val);
Toshihiro Shimizu 890ddd
		if (ds.atEnd())
Toshihiro Shimizu 890ddd
			break;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return ds;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline QDataStream &operator<<(QDataStream &ds, const std::string &str)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	ds << QString::fromStdString(str);
Toshihiro Shimizu 890ddd
	return ds;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
inline QDataStream &operator>>(QDataStream &ds, std::string &str)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QString qstr;
Toshihiro Shimizu 890ddd
	ds >> qstr;
Toshihiro Shimizu 890ddd
	str = qstr.toStdString();
Toshihiro Shimizu 890ddd
	return ds;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline QDataStream &operator<<(QDataStream &ds, const std::wstring &str)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	ds << QString::fromStdWString(str);
Toshihiro Shimizu 890ddd
	return ds;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
inline QDataStream &operator>>(QDataStream &ds, std::wstring &str)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QString qstr;
Toshihiro Shimizu 890ddd
	ds >> qstr;
Toshihiro Shimizu 890ddd
	str = qstr.toStdWString();
Toshihiro Shimizu 890ddd
	return ds;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline QDataStream &operator<<(QDataStream &ds, const wchar_t &ch)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	ds.writeRawData((const char *)&ch, sizeof(wchar_t));
Toshihiro Shimizu 890ddd
	return ds;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
inline QDataStream &operator>>(QDataStream &ds, wchar_t &ch)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	ds.readRawData((char *)&ch, sizeof(wchar_t));
Toshihiro Shimizu 890ddd
	return ds;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif //TIPC_H