PageRenderTime 41ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/Callback.cpp

https://gitlab.com/N3X15/sm-ext-socket
C++ | 208 lines | 171 code | 37 blank | 0 comment | 46 complexity | 2590a99bcfcc059945220694b8220729 MD5 | raw file
Possible License(s): GPL-2.0
  1. #include "Callback.h"
  2. #include <assert.h>
  3. #include <string>
  4. #include <boost/asio.hpp>
  5. #include "Define.h"
  6. #include "Extension.h"
  7. #include "Socket.h"
  8. #include "SocketHandler.h"
  9. using namespace boost::asio::ip;
  10. Callback::Callback(CallbackEvent callbackEvent,
  11. const void* socket) : callbackEvent(callbackEvent) {
  12. assert(callbackEvent == CallbackEvent_Connect || callbackEvent == CallbackEvent_Disconnect || callbackEvent == CallbackEvent_SendQueueEmpty);
  13. socketWrapper = socketHandler.GetSocketWrapper(socket);
  14. }
  15. Callback::Callback(CallbackEvent callbackEvent,
  16. const void* socket,
  17. const char* data,
  18. size_t dataLength) : callbackEvent(callbackEvent) {
  19. assert(callbackEvent == CallbackEvent_Receive);
  20. socketWrapper = socketHandler.GetSocketWrapper(socket);
  21. additionalData[0] = new std::string(data, dataLength);
  22. }
  23. Callback::Callback(CallbackEvent callbackEvent,
  24. const void* socket,
  25. const void* newSocket,
  26. const tcp::endpoint& remoteEndPoint) : callbackEvent(callbackEvent) {
  27. assert(callbackEvent == CallbackEvent_Incoming);
  28. socketWrapper = socketHandler.GetSocketWrapper(socket);
  29. additionalData[0] = socketHandler.GetSocketWrapper(newSocket);
  30. additionalData[1] = new tcp::endpoint(remoteEndPoint);
  31. }
  32. Callback::Callback(CallbackEvent callbackEvent,
  33. const void* socket,
  34. SM_ErrorType errorType,
  35. int errorNumber) : callbackEvent(callbackEvent) {
  36. assert(callbackEvent == CallbackEvent_Error);
  37. socketWrapper = socketHandler.GetSocketWrapper(socket);
  38. additionalData[0] = new SM_ErrorType(errorType);
  39. additionalData[1] = new int(errorNumber);
  40. }
  41. Callback::~Callback() {
  42. if (callbackEvent == CallbackEvent_Receive) {
  43. delete (std::string*) additionalData[0];
  44. } else if (callbackEvent == CallbackEvent_Incoming) {
  45. delete (tcp::endpoint*) additionalData[1];
  46. } else if (callbackEvent == CallbackEvent_Error) {
  47. delete (SM_ErrorType*) additionalData[0];
  48. delete (int*) additionalData[1];
  49. }
  50. }
  51. bool Callback::IsExecutable() {
  52. if (!socketWrapper) return false;
  53. switch (socketWrapper->socketType) {
  54. case SM_SocketType_Tcp: {
  55. Socket<tcp>* socket = (Socket<tcp>*) socketWrapper->socket;
  56. switch (callbackEvent) {
  57. case CallbackEvent_Connect:
  58. return (socket->connectCallback != NULL);
  59. case CallbackEvent_Disconnect:
  60. return (socket->disconnectCallback != NULL);
  61. case CallbackEvent_Incoming:
  62. return (socket->incomingCallback != NULL);
  63. case CallbackEvent_Receive:
  64. return (socket->receiveCallback != NULL);
  65. case CallbackEvent_SendQueueEmpty:
  66. return (socket->sendqueueEmptyCallback != NULL);
  67. case CallbackEvent_Error:
  68. return (socket->errorCallback != NULL);
  69. default:
  70. return false;
  71. }
  72. break;
  73. }
  74. case SM_SocketType_Udp: {
  75. Socket<udp>* socket = (Socket<udp>*) socketWrapper->socket;
  76. switch (callbackEvent) {
  77. case CallbackEvent_Connect:
  78. return (socket->connectCallback != NULL);
  79. case CallbackEvent_Disconnect:
  80. return (socket->disconnectCallback != NULL);
  81. case CallbackEvent_Incoming:
  82. return (socket->incomingCallback != NULL);
  83. case CallbackEvent_Receive:
  84. return (socket->receiveCallback != NULL);
  85. case CallbackEvent_SendQueueEmpty:
  86. return (socket->sendqueueEmptyCallback != NULL);
  87. case CallbackEvent_Error:
  88. return (socket->errorCallback != NULL);
  89. default:
  90. return false;
  91. }
  92. break;
  93. }
  94. }
  95. return false;
  96. }
  97. bool Callback::IsValid() {
  98. if (!socketWrapper) return false;
  99. if (callbackEvent == CallbackEvent_Incoming && (!additionalData[0] || !additionalData[1])) return false;
  100. return true;
  101. }
  102. void Callback::Execute() {
  103. switch (socketWrapper->socketType) {
  104. case SM_SocketType_Tcp: {
  105. ExecuteHelper<tcp>();
  106. break;
  107. }
  108. case SM_SocketType_Udp: {
  109. ExecuteHelper<udp>();
  110. break;
  111. }
  112. }
  113. }
  114. template<class SocketType>
  115. void Callback::ExecuteHelper() {
  116. if (!IsValid()) return;
  117. Socket<SocketType>* socket = (Socket<SocketType>*) socketWrapper->socket;
  118. switch (callbackEvent) {
  119. case CallbackEvent_Connect:
  120. if (!socket->connectCallback) return;
  121. socket->connectCallback->PushCell(socket->smHandle);
  122. socket->connectCallback->PushCell(socket->smCallbackArg);
  123. socket->connectCallback->Execute(NULL);
  124. return;
  125. case CallbackEvent_Disconnect:
  126. if (!socket->disconnectCallback) return;
  127. socket->disconnectCallback->PushCell(socket->smHandle);
  128. socket->disconnectCallback->PushCell(socket->smCallbackArg);
  129. socket->disconnectCallback->Execute(NULL);
  130. return;
  131. case CallbackEvent_Incoming: {
  132. if (!socket->incomingCallback) return;
  133. Socket<SocketType>* socket2 = (Socket<SocketType>*) ((SocketWrapper*)additionalData[0])->socket;
  134. socket2->smHandle = handlesys->CreateHandle(extension.socketHandleType, socketHandler.GetSocketWrapper(socket2), socket->incomingCallback->GetParentContext()->GetIdentity(), myself->GetIdentity(), NULL);
  135. socket->incomingCallback->PushCell(socket->smHandle);
  136. socket->incomingCallback->PushCell(socket2->smHandle);
  137. socket->incomingCallback->PushString(((typename SocketType::endpoint*)additionalData[1])->address().to_string().c_str());
  138. socket->incomingCallback->PushCell(((typename SocketType::endpoint*)additionalData[1])->port());
  139. socket->incomingCallback->PushCell(socket->smCallbackArg);
  140. socket->incomingCallback->Execute(NULL);
  141. return;
  142. }
  143. case CallbackEvent_Receive: {
  144. if (!socket->receiveCallback) return;
  145. size_t strLen = ((std::string*) additionalData[0])->length();
  146. char* tmp = new char[strLen+1];
  147. memcpy(tmp, ((std::string*) additionalData[0])->c_str(), strLen+1);
  148. socket->receiveCallback->PushCell(socket->smHandle);
  149. socket->receiveCallback->PushStringEx(tmp, strLen+1, SM_PARAM_STRING_COPY|SM_PARAM_STRING_BINARY, 0);
  150. socket->receiveCallback->PushCell(strLen);
  151. socket->receiveCallback->PushCell(socket->smCallbackArg);
  152. socket->receiveCallback->Execute(NULL);
  153. delete[] tmp;
  154. return;
  155. }
  156. case CallbackEvent_SendQueueEmpty:
  157. if (!socket->sendqueueEmptyCallback) return;
  158. socket->sendqueueEmptyCallback->PushCell(socket->smHandle);
  159. socket->sendqueueEmptyCallback->PushCell(socket->smCallbackArg);
  160. socket->sendqueueEmptyCallback->Execute(NULL);
  161. return;
  162. case CallbackEvent_Error:
  163. if (!socket->errorCallback) return;
  164. socket->errorCallback->PushCell(socket->smHandle);
  165. socket->errorCallback->PushCell(*(SM_ErrorType*) additionalData[0]);
  166. socket->errorCallback->PushCell(*(int*) additionalData[1]);
  167. socket->errorCallback->PushCell(socket->smCallbackArg);
  168. socket->errorCallback->Execute(NULL);
  169. return;
  170. }
  171. }