#pragma once #include #ifdef _WIN32 // Windows-specific #include #define LONG long #else // Linux and Mac variants #include #include #define INVALID_SOCKET -1 #define SOCKET_ERROR -1 #define SOCKET int #define SOCKADDR_IN struct sockaddr_in #define PSOCKADDR struct sockaddr * #define BOOL int #define LONG int #define sprintf_s snprintf #define vsprintf_s vsnprintf #define strcpy_s(dst, siz, src) strncpy(dst, src, (siz)); dst[(siz) - 1] = 0x00 #define strncpy_s(dst, siz, src, d) strncpy(dst, src, (siz)); (dst)[(siz) - 1] = 0x00 #endif // Supported MRC file types/data types #define MRC_MODE_BYTE 0 #define MRC_MODE_SHORT 1 #define MRC_MODE_FLOAT 2 #define MRC_MODE_USHORT 6 #define MRC_MODE_RGB 16 #define ERR_BUF_SIZE 320 #define MAX_SCRIPT_LANG_ARGS 20 #define MAX_REPORTED_VALS 6 #define B3DMIN(a,b) ((a) < (b) ? (a) : (b)) // Macros for adding arguments #define LONG_ARG(b) mLongArgs[mNumLongSend++] = b; #define BOOL_ARG(b) mBoolArgs[mNumBoolSend++] = b; #define DOUBLE_ARG(b) mDoubleArgs[mNumDblSend++] = b; enum {PSS_RegularCommand = 1, PSS_ChunkHandshake, PSS_OKtoRunExternalScript, PSS_GetBufferImage, PSS_PutImageInbuffer}; // Modified version of the script data structure used in SerialEM struct ScriptLangData { int functionCode; // Command code (index) from plugin std::string strItems[MAX_SCRIPT_LANG_ARGS]; // String items from plugin (use from 1) int itemInt[MAX_SCRIPT_LANG_ARGS]; // Integer value by atoi, from plugin double itemDbl[MAX_SCRIPT_LANG_ARGS]; // double value from plugin int lastNonEmptyInd; // Index of last non-empty item from plugin std::string reportedStrs[MAX_REPORTED_VALS]; // Reported string values after command double reportedVals[MAX_REPORTED_VALS]; // Reported double values after command bool repValIsString[MAX_REPORTED_VALS]; // Flag for whether reported value is string int highestReportInd; // Index of highest reported value (from 0) int errorOccurred; // Flag that an error occurred in the command int commandReady; // Flag set by plugin that command is ready bool gotExceptionText; // Flag that strItems has exception text }; // The class class CPySEMSocket { public: CPySEMSocket(void); ~CPySEMSocket(void); char mErrorBuf[ERR_BUF_SIZE]; ScriptLangData *mScriptData; private: bool mWSAinitialized; unsigned short mPort; char *mIPaddress; SOCKET mServer; SOCKADDR_IN mSockAddr; int mChunkSize; int mSuperChunkSize; bool mCloseBeforeNextUse; // Declarations needed on both sides (without array on other side) // IF A MAX IS CHANGED, PLUGINS BUILT WITH OLDER SIZE WILL NOT LOAD #define ARGS_BUFFER_CHUNK 1024 #define MAX_LONG_ARGS 16 #define MAX_DBL_ARGS 8 #define MAX_BOOL_ARGS 8 int mHandshakeCode; int mNumLongSend; int mNumBoolSend; int mNumDblSend; int mNumLongRecv; int mNumBoolRecv; int mNumDblRecv; bool mRecvLongArray; LONG *mLongArray; LONG mLongArgs[MAX_LONG_ARGS]; // Max is 16 double mDoubleArgs[MAX_DBL_ARGS]; // Max is 8 BOOL mBoolArgs[MAX_BOOL_ARGS]; // Max is 8 char *mArgsBuffer; int mArgBufSize; int mNumBytesSend; float mBufImageTimeout; public: int InitializeSocket(int port = 0, const char *ipAddress = NULL); int ExchangeMessages(int *numExtraBytes); int OpenServerSocket(); void CloseServer(); int ReallocArgsBufIfNeeded(int needSize); void InitializePacking(int funcCode); void SendAndReceiveArgs(int *numExtraBytes = NULL); int SendOneArgReturnRetVal(int funcCode, int argument); const char *GetOneString(int funcCode); void AddStringAsLongArray(const char *name, LONG *longArr, int maxLen); LONG *AddLongsAndStrings(LONG *longVals, int numLongs, const char **strings, int numStrings); LONG *AddItemArrays(); int ReceiveImage(char *imArray, int numBytes, int numChunks, int NumExtraBytes); int SendImage(void *imArray, int imSize); int SendBuffer(char *buffer, int numBytes); void ReportErrorAndClose(int retval, const char *message); int FinishGettingBuffer(char *buffer, int numReceived, int numExpected, int bufSize); int FinishSendingBuffer(char *buffer, int numBytes, int numTotalSent); int UnpackReceivedData(int limitedNum); int PackDataToSend(); void CloseBeforeNextUse(); void UninitializeWSA(void); int RegularCommand(void); int OKtoRunExternalScript(BOOL &OKtoRun); void *GetBufferImage(int bufInd, int ifFFT, const char *bufStr, int &imType, int &rowBytes, int &sizeX, int &sizeY, int &itemSize, char *format); int PutImageInbuffer(void *imArray, int imType, int sizeX, int sizeY, int itemBytes, int toBuf, int baseBuf, int moreBinning, int capFlag); void SetBufImageTimeout(float seconds) {mBufImageTimeout = seconds;}; void SetTimeout(float seconds); };