PageRenderTime 25ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/Cpp/Source/ProtoBufRemote/Generators.h

https://code.google.com/p/protobuf-remote/
C Header | 213 lines | 158 code | 33 blank | 22 comment | 9 complexity | cf9584b87d71149be92b2179c07cbfe5 MD5 | raw file
  1. #ifndef PROTOBUFREMOTE_GENERATORS_H
  2. #define PROTOBUFREMOTE_GENERATORS_H 1
  3. #include <boost/preprocessor.hpp>
  4. #include "ProtoBufRemote/PendingCall.h"
  5. #include "ProtoBufRemote/Proxy.h"
  6. #include "ProtoBufRemote/RpcClient.h"
  7. #include "ProtoBufRemote/RpcService.h"
  8. /**
  9. * Declares both a proxy and a service stub. Here is a sample declaration, note that there are no commas between methods
  10. * or between parameters.
  11. * PBR_SERVICE(SampleService2,
  12. * PBR_METHOD(GetSquare, PBR_INT(PBR_INT))
  13. * PBR_METHOD(DoStuff, PBR_VOID(PBR_STRING))
  14. * PBR_METHOD(DoOtherStuff, PBR_VOID(PBR_STRING PBR_INT PBR_BOOL))
  15. * PBR_METHOD(DoEvenMoreStuff, PBR_VOID(PBR_VOID))
  16. * )
  17. */
  18. #define PBR_SERVICE(name, methods) \
  19. PBR_PROXY(name, methods) \
  20. PBR_SERVICE_STUB(name, methods)
  21. /**
  22. * Declares a proxy only, without a matching service stub. See PBR_SERVICE for a description.
  23. */
  24. #define PBR_PROXY(name, methods) \
  25. class name##Proxy : public ::ProtoBufRemote::Proxy \
  26. { \
  27. public: \
  28. name##Proxy(::ProtoBufRemote::RpcClient* client) : ::ProtoBufRemote::Proxy(client, #name) { } \
  29. BOOST_PP_SEQ_FOR_EACH(PBR_X_PROXY_METHOD, ~, methods) \
  30. };
  31. /**
  32. * Declares a service stub only, without a matching proxy. See PBR_SERVICE for a description.
  33. */
  34. #define PBR_SERVICE_STUB(name, methods) \
  35. class name##Stub : public ::ProtoBufRemote::RpcService \
  36. { \
  37. public: \
  38. name##Stub() : ::ProtoBufRemote::RpcService(#name) \
  39. { \
  40. } \
  41. virtual bool Call(const char* methodName, const ::ProtoBufRemote::ParameterList& parameters, \
  42. ::ProtoBufRemote::MutableParameter* result) \
  43. { \
  44. if (0) { } \
  45. BOOST_PP_SEQ_FOR_EACH(PBR_X_STUB_CALL_METHOD, ~, methods) \
  46. return false; \
  47. } \
  48. BOOST_PP_SEQ_FOR_EACH(PBR_X_STUB_METHOD, ~, methods) \
  49. };
  50. #define PBR_METHOD(name, signature) ((name, signature))
  51. //is non-void, is result as parameter ptr, can get ref, type, parameter type, return type, set func, get func, is set func
  52. #define PBR_VOID ((0, 0, 0, void, void, void, ~, ~, ~))
  53. #define PBR_CHAR ((1, 0, 1, signed char, signed char, signed char, SetChar, GetChar, IsChar))
  54. #define PBR_UCHAR ((1, 0, 1, unsigned char, unsigned char, unsigned char, SetUnsignedChar, GetUnsignedChar, IsUnsignedChar))
  55. #define PBR_SHORT ((1, 0, 1, short, short, short, SetShort, GetShort, IsShort))
  56. #define PBR_USHORT ((1, 0, 1, unsigned short, unsigned short, unsigned short, SetUnsignedShort, GetUnsignedShort, IsUnsignedShort))
  57. #define PBR_INT ((1, 0, 1, int, int, int, SetInt, GetInt, IsInt))
  58. #define PBR_UINT ((1, 0, 1, unsigned int, unsigned int, unsigned int, SetUnsignedInt, GetUnsignedInt, IsUnsignedInt))
  59. #define PBR_INT64 ((1, 0, 1, long long, long long, long long, SetInt64, GetInt64, IsInt64))
  60. #define PBR_UINT64 ((1, 0, 1, unsigned long long, unsigned long long, unsigned long long, SetUnsignedInt64, GetUnsignedInt64, IsUnsignedInt64))
  61. #define PBR_BOOL ((1, 0, 1, bool, bool, bool, SetBool, GetBool, IsBool))
  62. #define PBR_STRING ((1, 1, 1, std::string, const std::string&, void, SetString, GetString, IsString))
  63. #define PBR_WCHAR ((1, 0, 1, wchar_t, wchar_t, wchar_t, SetWChar, GetWChar, IsWChar))
  64. #define PBR_PROTO(protoType) ((1, 1, 0, protoType, const protoType&, void, SetProto, GetProto, IsProto))
  65. //=============================================================================================================
  66. // internal macros
  67. //=============================================================================================================
  68. #define PBR_X_PARAM_IS_NON_VOID(param) BOOST_PP_TUPLE_ELEM(9, 0, param)
  69. #define PBR_X_PARAM_IS_RESULT_PTR(param) BOOST_PP_TUPLE_ELEM(9, 1, param)
  70. #define PBR_X_PARAM_CAN_GET_REF(param) BOOST_PP_TUPLE_ELEM(9, 2, param)
  71. #define PBR_X_PARAM_TYPE(param) BOOST_PP_TUPLE_ELEM(9, 3, param)
  72. #define PBR_X_PARAM_PARAM_TYPE(param) BOOST_PP_TUPLE_ELEM(9, 4, param)
  73. #define PBR_X_PARAM_RETURN_TYPE(param) BOOST_PP_TUPLE_ELEM(9, 5, param)
  74. #define PBR_X_PARAM_SET_FUNC(param) BOOST_PP_TUPLE_ELEM(9, 6, param)
  75. #define PBR_X_PARAM_GET_FUNC(param) BOOST_PP_TUPLE_ELEM(9, 7, param)
  76. #define PBR_X_PARAM_CHECK_FUNC(param) BOOST_PP_TUPLE_ELEM(9, 8, param)
  77. #define PBR_X_METHOD_NAME(method) BOOST_PP_TUPLE_ELEM(2, 0, method)
  78. #define PBR_X_METHOD_SIG(method) BOOST_PP_TUPLE_ELEM(2, 1, method)
  79. #define PBR_X_METHOD_RETURN(method) BOOST_PP_SEQ_ELEM(0, PBR_X_METHOD_SIG(method))
  80. #define PBR_X_METHOD_PARAMS(method) BOOST_PP_SEQ_ELEM(1, PBR_X_METHOD_SIG(method))
  81. #define PBR_X_METHOD_HAS_RETURN(method) PBR_X_PARAM_IS_NON_VOID(PBR_X_METHOD_RETURN(method))
  82. #define PBR_X_METHOD_HAS_PARAMS(method) PBR_X_PARAM_IS_NON_VOID(BOOST_PP_SEQ_HEAD(PBR_X_METHOD_PARAMS(method)))
  83. #define PBR_X_DECLARE_METHOD_PARAMS(method) \
  84. BOOST_PP_EXPR_IF(PBR_X_METHOD_HAS_PARAMS(method), \
  85. BOOST_PP_SEQ_FOR_EACH_I(PBR_X_DECLARE_METHOD_PARAM, ~, PBR_X_METHOD_PARAMS(method))) \
  86. BOOST_PP_EXPR_IF( \
  87. BOOST_PP_AND(PBR_X_METHOD_HAS_PARAMS(method), PBR_X_PARAM_IS_RESULT_PTR(PBR_X_METHOD_RETURN(method))), \
  88. BOOST_PP_COMMA()) \
  89. BOOST_PP_EXPR_IF(PBR_X_PARAM_IS_RESULT_PTR(PBR_X_METHOD_RETURN(method)), \
  90. PBR_X_PARAM_TYPE(PBR_X_METHOD_RETURN(method))* resultPtr)
  91. #define PBR_X_DECLARE_METHOD_PARAM(r, data, i, param) \
  92. BOOST_PP_COMMA_IF(i) PBR_X_PARAM_PARAM_TYPE(param) BOOST_PP_CAT(p, i)
  93. //proxy
  94. #define PBR_X_PROXY_METHOD(r, data, method) \
  95. PBR_X_PARAM_RETURN_TYPE(PBR_X_METHOD_RETURN(method)) PBR_X_METHOD_NAME(method)( \
  96. PBR_X_DECLARE_METHOD_PARAMS(method)) \
  97. { \
  98. m_parameters.Clear(); \
  99. BOOST_PP_EXPR_IF(PBR_X_METHOD_HAS_PARAMS(method), PBR_X_PROXY_METHOD_PARAMS(method)) \
  100. BOOST_PP_IF(PBR_X_METHOD_HAS_RETURN(method), PBR_X_METHOD_CALL(method), PBR_X_METHOD_CALLWITHOUTRESULT(method)) \
  101. }
  102. #define PBR_X_PROXY_METHOD_PARAMS(method) \
  103. BOOST_PP_SEQ_FOR_EACH_I(PBR_X_PROXY_METHOD_PARAM, ~, PBR_X_METHOD_PARAMS(method))
  104. #define PBR_X_PROXY_METHOD_PARAM(r, data, i, param) \
  105. m_parameters.Add().PBR_X_PARAM_SET_FUNC(param) (BOOST_PP_CAT(p, i)); \
  106. #define PBR_X_METHOD_CALL(method) \
  107. ::ProtoBufRemote::PendingCall* call = m_client->Call(m_serviceName, BOOST_PP_STRINGIZE(PBR_X_METHOD_NAME(method)), \
  108. m_parameters); \
  109. call->Wait(); \
  110. BOOST_PP_IF(PBR_X_PARAM_IS_RESULT_PTR(PBR_X_METHOD_RETURN(method)), \
  111. call->GetResult()->PBR_X_PARAM_GET_FUNC(PBR_X_METHOD_RETURN(method))(resultPtr); \
  112. m_client->ReleaseCall(call); \
  113. , \
  114. PBR_X_PARAM_TYPE(PBR_X_METHOD_RETURN(method)) result \
  115. = call->GetResult()->PBR_X_PARAM_GET_FUNC(PBR_X_METHOD_RETURN(method))(); \
  116. m_client->ReleaseCall(call); \
  117. return result; \
  118. )
  119. #define PBR_X_METHOD_CALLWITHOUTRESULT(method) \
  120. m_client->CallWithoutResult(m_serviceName, BOOST_PP_STRINGIZE(PBR_X_METHOD_NAME(method)), m_parameters);
  121. //stub
  122. #define PBR_X_STUB_METHOD(r, data, method) \
  123. virtual PBR_X_PARAM_RETURN_TYPE(PBR_X_METHOD_RETURN(method)) PBR_X_METHOD_NAME(method)( \
  124. PBR_X_DECLARE_METHOD_PARAMS(method)) = 0;
  125. #define PBR_X_STUB_CALL_METHOD(r, data, method) \
  126. else if (strcmp(methodName, BOOST_PP_STRINGIZE(PBR_X_METHOD_NAME(method))) == 0) \
  127. { \
  128. BOOST_PP_IF(PBR_X_METHOD_HAS_PARAMS(method), PBR_X_STUB_CHECK_PARAMS(method), \
  129. PBR_X_STUB_CHECK_NO_PARAMS(method)) \
  130. }
  131. #define PBR_X_STUB_CHECK_PARAMS(method) \
  132. if (parameters.GetNumParameters() == BOOST_PP_SEQ_SIZE(PBR_X_METHOD_PARAMS(method))) \
  133. { \
  134. if (BOOST_PP_SEQ_FOR_EACH_I(PBR_X_STUB_CHECK_PARAM, ~, PBR_X_METHOD_PARAMS(method))) \
  135. { \
  136. PBR_X_STUB_MAKE_CALL(method) \
  137. } \
  138. }
  139. #define PBR_X_STUB_CHECK_NO_PARAMS(method) \
  140. if (parameters.GetNumParameters() == 0) \
  141. { \
  142. PBR_X_STUB_MAKE_CALL(method) \
  143. }
  144. #define PBR_X_STUB_CHECK_PARAM(r, data, i, param) \
  145. BOOST_PP_EXPR_IF(i, &&) parameters.GetParameter(i).PBR_X_PARAM_CHECK_FUNC(param)()
  146. #define PBR_X_STUB_MAKE_CALL(method) \
  147. BOOST_PP_EXPR_IF(PBR_X_METHOD_HAS_PARAMS(method), \
  148. BOOST_PP_SEQ_FOR_EACH_I(PBR_X_STUB_PREPARE_PARAM, ~, PBR_X_METHOD_PARAMS(method))) \
  149. BOOST_PP_IF(PBR_X_METHOD_HAS_RETURN(method), PBR_X_STUB_MAKE_CALL_WITH_RETURN(method), \
  150. PBR_X_STUB_MAKE_CALL_WITHOUT_RETURN(method))
  151. #define PBR_X_STUB_PREPARE_PARAM(r, data, i, param) \
  152. BOOST_PP_IF(PBR_X_PARAM_CAN_GET_REF(param), \
  153. PBR_X_PARAM_PARAM_TYPE(param) BOOST_PP_CAT(p, i) = parameters.GetParameter(i).PBR_X_PARAM_GET_FUNC(param)(); \
  154. , \
  155. PBR_X_PARAM_TYPE(param) BOOST_PP_CAT(p, i); \
  156. parameters.GetParameter(i).PBR_X_PARAM_GET_FUNC(param)(&BOOST_PP_CAT(p, i)); \
  157. )
  158. #define PBR_X_STUB_MAKE_CALL_WITH_RETURN(method) \
  159. BOOST_PP_IF(PBR_X_PARAM_IS_RESULT_PTR(PBR_X_METHOD_RETURN(method)), \
  160. PBR_X_STUB_MAKE_CALL_WITH_RETURN_PTR(method), \
  161. PBR_X_STUB_MAKE_CALL_WITH_RETURN_STD(method))
  162. #define PBR_X_STUB_MAKE_CALL_WITH_RETURN_STD(method) \
  163. PBR_X_PARAM_TYPE(PBR_X_METHOD_RETURN(method)) resultValue = \
  164. PBR_X_METHOD_NAME(method)(BOOST_PP_EXPR_IF(PBR_X_METHOD_HAS_PARAMS(method), \
  165. BOOST_PP_SEQ_FOR_EACH_I(PBR_X_STUB_MAKE_CALL_PARAM, ~, PBR_X_METHOD_PARAMS(method)))); \
  166. result->PBR_X_PARAM_SET_FUNC(PBR_X_METHOD_RETURN(method))(resultValue); \
  167. return true;
  168. #define PBR_X_STUB_MAKE_CALL_WITH_RETURN_PTR(method) \
  169. PBR_X_PARAM_TYPE(PBR_X_METHOD_RETURN(method)) resultValue; \
  170. PBR_X_METHOD_NAME(method)(BOOST_PP_EXPR_IF(PBR_X_METHOD_HAS_PARAMS(method), \
  171. BOOST_PP_SEQ_FOR_EACH_I(PBR_X_STUB_MAKE_CALL_PARAM, ~, PBR_X_METHOD_PARAMS(method)) BOOST_PP_COMMA()) &resultValue); \
  172. result->PBR_X_PARAM_SET_FUNC(PBR_X_METHOD_RETURN(method))(resultValue); \
  173. return true;
  174. #define PBR_X_STUB_MAKE_CALL_WITHOUT_RETURN(method) \
  175. PBR_X_METHOD_NAME(method)(BOOST_PP_EXPR_IF(PBR_X_METHOD_HAS_PARAMS(method), \
  176. BOOST_PP_SEQ_FOR_EACH_I(PBR_X_STUB_MAKE_CALL_PARAM, ~, PBR_X_METHOD_PARAMS(method)))); \
  177. return true;
  178. #define PBR_X_STUB_MAKE_CALL_PARAM(r, data, i, param) \
  179. BOOST_PP_COMMA_IF(i) BOOST_PP_CAT(p, i)
  180. #endif