#ifndef __SP_HELPER_H #define __SP_HELPER_H #pragma once #include "ErrorCode.h" #include "SpBase.h" #include "Blob.h" /** provide some helper functions */ class SPBASE_API SpBuffer { private: typedef struct iobuffer_t iobuffer_t; public: enum { SUGGEST_BUF_SIZE = 256 }; enum OP_MODE { OP_READ, OP_WRITE }; SpBuffer(); ~SpBuffer(); bool OpenRead(const char *buf, int size); bool OpenRead(iobuffer_t **iobuf); bool OpenWrite(int cap = SUGGEST_BUF_SIZE); void Close(); bool IsRead() { return m_iMode == OP_READ; } bool IsWrite() { return m_iMode == OP_WRITE; } void SetCapacity(int cap); void SetLength(int len); int GetCapacity(); int GetLength(); SpBuffer & operator &(bool&); SpBuffer & operator &(ULONGLONG&); SpBuffer& operator &(LONGLONG&); SpBuffer & operator &(INT&); SpBuffer & operator &(SHORT&); SpBuffer & operator &(CHAR&); SpBuffer & operator &(DWORD&); SpBuffer & operator &(WORD&); SpBuffer & operator &(BYTE&); SpBuffer & operator &(FLOAT&); SpBuffer & operator &(DOUBLE&); SpBuffer & operator &(CSimpleStringA &); SpBuffer & operator &(CSimpleStringW &); SpBuffer & operator &(CBlob&); SpBuffer & operator &(CAutoArray&); SpBuffer & operator &(CAutoArray&); SpBuffer & operator &(CAutoArray&); SpBuffer & operator &(CAutoArray&); SpBuffer & operator &(CAutoArray&); SpBuffer & operator &(CAutoArray&); SpBuffer & operator &(CAutoArray&); SpBuffer & operator &(CAutoArray&); SpBuffer & operator &(CAutoArray&); SpBuffer & operator &(CAutoArray&); SpBuffer & operator &(CAutoArray&); SpBuffer & operator &(CAutoArray &); SpBuffer & operator &(CAutoArray &); SpBuffer & operator &(CAutoArray&); SpBuffer & operator &(const bool&); SpBuffer & operator &(const ULONGLONG&); SpBuffer & operator &(const LONGLONG&); SpBuffer & operator &(const INT&); SpBuffer & operator &(const SHORT&); SpBuffer & operator &(const CHAR&); SpBuffer & operator &(const DWORD&); SpBuffer & operator &(const WORD&); SpBuffer & operator &(const BYTE&); SpBuffer & operator &(const FLOAT&); SpBuffer & operator &(const DOUBLE&); SpBuffer & operator &(const CSimpleStringA &); SpBuffer & operator &(const CSimpleStringW &); SpBuffer & operator &(const CBlob&); SpBuffer & operator &(const CAutoArray&); SpBuffer & operator &(const CAutoArray&); SpBuffer & operator &(const CAutoArray&); SpBuffer & operator &(const CAutoArray&); SpBuffer & operator &(const CAutoArray&); SpBuffer & operator &(const CAutoArray&); SpBuffer & operator &(const CAutoArray&); SpBuffer & operator &(const CAutoArray&); SpBuffer & operator &(const CAutoArray&); SpBuffer & operator &(const CAutoArray&); SpBuffer & operator &(const CAutoArray&); SpBuffer & operator &(const CAutoArray &); SpBuffer & operator &(const CAutoArray &); SpBuffer & operator &(const CAutoArray&); #ifdef _WIN32 SpBuffer& operator &(LONG&); SpBuffer& operator &(const LONG&); SpBuffer& operator &(const CAutoArray&); SpBuffer& operator &(CAutoArray&); SpBuffer& operator &(UINT&); SpBuffer& operator &(const UINT&); SpBuffer& operator &(CAutoArray&); SpBuffer& operator &(const CAutoArray&); //SpBuffer& operator &(ULONG&); //SpBuffer& operator &(CAutoArray&); //SpBuffer& operator &(const ULONG&); //SpBuffer& operator &(const CAutoArray&); #else SpBuffer& operator &(CSimpleString16Bit&); SpBuffer& operator &(CAutoArray&); SpBuffer& operator &(const CSimpleString16Bit&); SpBuffer& operator &(const CAutoArray&); #endif //_WIN32 // use for write CAutoBuffer ToBuffer(); CBlob ToBlob(); private: int m_iMode; iobuffer_t *m_pInternalBuf; }; // helper for convert CAutoBuffer to T object, T must has Serialize method template static inline ErrorCodeEnum SpBuffer2Object(CAutoBuffer Buf, T &t) { ErrorCodeEnum Error; SpBuffer spbuf; if (spbuf.OpenRead((const char*)&Buf[0], Buf.GetCount())) { t.Serialize(spbuf); Error = Error_Succeed; } else { Error = Error_Bug; } return Error; } // helper for convert T object to CAutoBuffer, T must has Serialize method template static inline CAutoBuffer SpObject2Buffer(T &t) { SpBuffer spbuf; spbuf.OpenWrite(); t.Serialize(spbuf); return spbuf.ToBuffer(); } // helper for wait answer object template //static inline ErrorCodeEnum SpWaitAnswerObject(IAsynWaitSp *pAsyncWait, T &t, bool &bEnd, DWORD dwTimeout = INFINITE) static inline ErrorCodeEnum SpWaitAnswerObject(const CSmartPointer &pAsyncWait, T &t, bool &bEnd, DWORD dwTimeout = INFINITE) { //LOG_ASSERT(pAsyncWait); ErrorCodeEnum Error = pAsyncWait->WaitAnswer(dwTimeout); if (Error == Error_Succeed) { CAutoBuffer Buf; Error = pAsyncWait->AsyncGetAnswer(Buf, bEnd); if (Error == Error_Succeed) { Error = SpBuffer2Object(Buf, t); } } else DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("SpWaitAnswerObject wait timeout"); return Error; } template static inline ErrorCodeEnum SpWaitAnswerObject(const CSmartPointer &pAsyncWait, T &t, bool &bEnd, DWORD &dwUserError, CSimpleString &str, DWORD dwTimeout) { //LOG_ASSERT(pAsyncWait); ErrorCodeEnum Error = pAsyncWait->WaitAnswer(dwUserError, str, dwTimeout); if (Error == Error_Succeed) { CAutoBuffer Buf; Error = pAsyncWait->AsyncGetAnswer(Buf, bEnd, dwUserError, str); if (Error == Error_Succeed) { Error = SpBuffer2Object(Buf, t); } } return Error; } template struct SpOnewayCallContext { typedef CSmartPointer > Pointer; TInfo Info; linkContext link; }; template struct SpReqAnsContext { typedef CSmartPointer > Pointer; SpReqAnsContext(const CSmartPointer &pTransactionContext) : m_spTransactionContext(pTransactionContext) {} virtual ~SpReqAnsContext() {} TReq Req; TAns Ans; linkContext link; virtual ErrorCodeEnum Answer(ErrorCodeEnum Error = Error_Succeed) { EntityResource::clearLink(); //static_assert(Error == Error_Succeed, "Input parameter must be Error_Succeed!"); if (Error == Error_Succeed) { CAutoBuffer Buf = SpObject2Buffer(Ans); return m_spTransactionContext->SendAnswer(Buf, true); } else { return m_spTransactionContext->SendAnswer(Error); } } virtual ErrorCodeEnum Answer(ErrorCodeEnum eSysError, DWORD dwUserError) { EntityResource::clearLink(); if (eSysError == Error_Succeed) { CAutoBuffer Buf = SpObject2Buffer(Ans); return m_spTransactionContext->SendAnswer(Buf, true); } CSimpleString str = ""; return m_spTransactionContext->SendAnswer(eSysError, dwUserError, str); } virtual ErrorCodeEnum Answer(ErrorCodeEnum eSysError, DWORD dwUserError, CSimpleString str) { EntityResource::clearLink(); if (eSysError == Error_Succeed) { CAutoBuffer Buf = SpObject2Buffer(Ans); return m_spTransactionContext->SendAnswer(Buf, true); } return m_spTransactionContext->SendAnswer(eSysError, dwUserError, str); } DWORD GetRequestId() { return m_spTransactionContext->GetRequestID(); } virtual DWORD GetExpireLeftTime() { // this method content is invalid, TODO: get the real ExpireLeftTime. [3/20/2020 17:27 Gifur] DWORD dwWholeTime = 0; DWORD dwLeftTime = 0; m_spTransactionContext->GetExpireTime(dwWholeTime, dwLeftTime); return dwLeftTime; } ErrorCodeEnum GetLinkContext(linkContext& curLink) { return m_spTransactionContext->GetLinkContext(curLink); } private: CSmartPointer m_spTransactionContext; }; template struct SpSubscribeContext { typedef CSmartPointer > Pointer; SpSubscribeContext(CSmartPointer &spTransactionContext) : m_spTransactionContext(spTransactionContext) {} TSubReq Req; ErrorCodeEnum SendMessage(TMsg &msg) { CAutoBuffer Buf = SpObject2Buffer(msg); return m_spTransactionContext->SendAnswer(Buf, false); } ErrorCodeEnum EndMessage() { return m_spTransactionContext->SendAnswer(Error_Closed); } private: CSmartPointer m_spTransactionContext; }; // helper for IBroadcastListener #define SP_BEGIN_MSG_DISPATCH_MAP(cls) \ virtual void OnBroadcastEvent(CUUID SubID, const char *pszEntityName,DWORD dwMessageId, DWORD dwMessageSignature,CAutoBuffer Buffer) \ { \ if (!pszEntityName) \ { \ LOG_TRACE("pszEntityName cannot empty!"); \ } #define SP_BEGIN_ENTITY_MSG(entity_name) \ else if (_stricmp(entity_name, pszEntityName) == 0) \ { \ switch (dwMessageId) { #define SP_MSG_HANDLE_NS(ns, msg, OnMsg) \ case eMsg_##msg: \ if (eMsgSig_##msg == dwMessageSignature) { \ ns##::msg t; \ ErrorCodeEnum Error = SpBuffer2Object(Buffer, t); \ if (Error == Error_Succeed) \ OnMsg(pszEntityName, dwMessageId, dwMessageSignature, t); \ } else { \ LOG_TRACE("%s signature mismatched!", #msg); \ } \ break; // void OnMsg(const char *pszEntityName, DWORD dwMessageId, DWORD dwMessageSignature, ); #define SP_MSG_HANDLER(msg, OnMsg) \ case eMsg_##msg: \ if (eMsgSig_##msg == dwMessageSignature) { \ msg t; \ ErrorCodeEnum Error = SpBuffer2Object(Buffer, t); \ if (Error == Error_Succeed) \ OnMsg(pszEntityName, dwMessageId, dwMessageSignature, t); \ } else { \ LOG_TRACE("%s signature mismatched!", #msg); \ } \ break; #define SP_END_ENTITY_MSG() \ default: \ LOG_TRACE("msg id %d ignored!", dwMessageId); \ break; \ } \ } #define SP_END_MSG_DISPATCH_MAP() \ else \ { \ LOG_TRACE("ignore pszEntityName"); \ } \ } template static ErrorCodeEnum SpSendBroadcast(CSmartPointer pFunc, DWORD dwMessageId, DWORD dwMessageSignature, T &t) { CAutoBuffer Buffer = SpObject2Buffer(t); return pFunc->SendBroadcast(dwMessageId, dwMessageSignature, Buffer); } #define SP_MSG_OF(cs) eMsg_##cs #define SP_MSG_SIG_OF(cs) eMsgSig_##cs // :: // :: // SPBASE_API ErrorCodeEnum SpExtractClassFunctionName(const char *pszParam, CSimpleStringA &strClassName, CSimpleStringA &strFunctionName); //SpBase Enum Stringtify SPBASE_API LPCTSTR SpStrEntityState(const EntityStateEnum state); SPBASE_API LPCTSTR SpStrCloseCause(const EntityCloseCauseEnum cause); SPBASE_API LPCTSTR SpStrRebootTrigger(const RebootTriggerEnum trigger); SPBASE_API LPCTSTR SpStrRebootWay(const RebootWayEnum way); SPBASE_API LPCTSTR SpStrFrameworkState(const FrameworkStateEnum state); #define IS_SUCCEED(hr) ((hr) == Error_Succeed) #define IS_FAILURED(hr) (!(IS_SUCCEED(hr))) template inline void SP_UNUSED(T const&) { // deprecated: warning C4100 } #endif // __SP_HELPER_H