Socket.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. /*
  2. * Author: Patrick-Christopher Mattulat
  3. * Company: Lynar Studios
  4. * E-Mail: webmaster@lynarstudios.com
  5. * Created: 2022-11-16
  6. * Changed: 2022-12-25
  7. *
  8. * */
  9. #include <ls_std/network/socket/Socket.hpp>
  10. #include <ls_std/network/core/ProtocolFamilyMapper.hpp>
  11. #include <ls_std/network/core/ProtocolMapper.hpp>
  12. #include <ls_std/network/socket/ConvertedSocketAddress.hpp>
  13. #include <ls_std/network/socket/SocketAddressMapper.hpp>
  14. #include <ls_std/common/api/socket/PosixSocket.hpp>
  15. #include <ls_std/common/api/io/PosixReader.hpp>
  16. #include <ls_std/common/api/io/PosixWriter.hpp>
  17. #include <ls_std/core/exception/WrongProtocolException.hpp>
  18. #include <ls_std/core/exception/IllegalArgumentException.hpp>
  19. #include <ls_std/core/exception/FileOperationException.hpp>
  20. #include <memory>
  21. ls::std::network::Socket::Socket(ls::std::network::SocketParameter _parameter) : ls::std::core::Class("Socket"),
  22. parameter(::std::move(_parameter))
  23. {
  24. #if defined(unix) || defined(__APPLE__)
  25. this->unixDescriptor = ls::std::network::Socket::_initUnix();
  26. this->initialized = this->unixDescriptor != -1;
  27. #endif
  28. }
  29. ls::std::network::Socket::~Socket()
  30. {
  31. delete[] this->readBuffer;
  32. }
  33. ls::std::core::type::byte_field ls::std::network::Socket::read()
  34. {
  35. if (!this->readBufferSet)
  36. {
  37. this->_initReadBuffer(); // TODO: is this really wise to initialize once? what if reading second time wouldn't work? - test it with unit tests and remove it
  38. this->readBufferSet = true;
  39. }
  40. return this->_read();
  41. }
  42. bool ls::std::network::Socket::write(const ls::std::core::type::byte_field &_data)
  43. {
  44. return this->_write(_data);
  45. }
  46. bool ls::std::network::Socket::accept()
  47. {
  48. if (this->parameter.socketAddress.protocolType != PROTOCOL_TYPE_TCP)
  49. {
  50. throw ls::std::core::WrongProtocolException{};
  51. }
  52. #if defined(unix) || defined(__APPLE__)
  53. return ls::std::network::Socket::_acceptUnix();
  54. #endif
  55. }
  56. bool ls::std::network::Socket::bind()
  57. {
  58. #if defined(unix) || defined(__APPLE__)
  59. return ls::std::network::Socket::_bindUnix();
  60. #endif
  61. }
  62. bool ls::std::network::Socket::close()
  63. {
  64. #if defined(unix) || defined(__APPLE__)
  65. return ls::std::network::Socket::_closeUnix();
  66. #endif
  67. }
  68. bool ls::std::network::Socket::connect()
  69. {
  70. #if defined(unix) || defined(__APPLE__)
  71. return ls::std::network::Socket::_connectUnix();
  72. #endif
  73. }
  74. bool ls::std::network::Socket::isInitialized() const
  75. {
  76. return this->initialized;
  77. }
  78. bool ls::std::network::Socket::listen()
  79. {
  80. if (this->parameter.socketAddress.protocolType != PROTOCOL_TYPE_TCP)
  81. {
  82. throw ls::std::core::WrongProtocolException{};
  83. }
  84. #if defined(unix) || defined(__APPLE__)
  85. return ls::std::network::Socket::_listenUnix();
  86. #endif
  87. }
  88. #if defined(unix) || defined(__APPLE__)
  89. bool ls::std::network::Socket::_acceptUnix()
  90. {
  91. ls::std::network::ConvertedSocketAddress convertedSocketAddress = ls::std::network::SocketAddressMapper::from(ls::std::network::Socket::_createSocketAddressMapperParameter());
  92. return this->parameter.posixSocket->accept(this->unixDescriptor, reinterpret_cast<sockaddr *>(&convertedSocketAddress.socketAddressUnix), &convertedSocketAddress.addressLength) >= 0;
  93. }
  94. bool ls::std::network::Socket::_bindUnix()
  95. {
  96. ls::std::network::ConvertedSocketAddress convertedSocketAddress = ls::std::network::SocketAddressMapper::from(ls::std::network::Socket::_createSocketAddressMapperParameter());
  97. return this->parameter.posixSocket->bind(this->unixDescriptor, reinterpret_cast<const sockaddr *>(&convertedSocketAddress.socketAddressUnix), convertedSocketAddress.addressLength) == 0;
  98. }
  99. bool ls::std::network::Socket::_closeUnix()
  100. {
  101. return this->parameter.posixSocket->close(this->unixDescriptor) == 0;
  102. }
  103. bool ls::std::network::Socket::_connectUnix()
  104. {
  105. ls::std::network::ConvertedSocketAddress convertedSocketAddress = ls::std::network::SocketAddressMapper::from(ls::std::network::Socket::_createSocketAddressMapperParameter());
  106. return this->parameter.posixSocket->connect(this->unixDescriptor, reinterpret_cast<const sockaddr *>(&convertedSocketAddress.socketAddressUnix), convertedSocketAddress.addressLength) == 0;
  107. }
  108. #endif
  109. ls::std::network::SocketAddressMapperParameter ls::std::network::Socket::_createSocketAddressMapperParameter() const
  110. {
  111. ls::std::network::SocketAddressMapperParameter mapperParameter{};
  112. mapperParameter.socketAddress = this->parameter.socketAddress;
  113. mapperParameter.protocolFamilyType = this->parameter.protocolFamilyType;
  114. return mapperParameter;
  115. }
  116. bool ls::std::network::Socket::_init()
  117. {
  118. #if defined(unix) || defined(__APPLE__)
  119. return this->_initUnix();
  120. #endif
  121. }
  122. void ls::std::network::Socket::_initReadBuffer()
  123. {
  124. if (this->parameter.readBufferSize <= 0)
  125. {
  126. throw ls::std::core::IllegalArgumentException{};
  127. }
  128. this->readBuffer = new ls::std::core::type::byte[this->parameter.readBufferSize];
  129. }
  130. #if defined(unix) || defined(__APPLE__)
  131. bool ls::std::network::Socket::_initUnix()
  132. {
  133. this->_setPosixReaderApi();
  134. this->_setPosixSocketApi();
  135. this->_setPosixWriterApi();
  136. ls::std::network::ConvertedProtocolFamily convertedProtocolFamily = ls::std::network::ProtocolFamilyMapper::from(this->parameter.protocolFamilyType);
  137. ls::std::network::Protocol protocol = ls::std::network::ProtocolMapper::from(this->parameter.socketAddress.protocolType);
  138. return this->parameter.posixSocket->create(convertedProtocolFamily.unixDomain, protocol.unixProtocol, 0) != -1;
  139. }
  140. bool ls::std::network::Socket::_listenUnix()
  141. {
  142. return this->parameter.posixSocket->listen(this->unixDescriptor, this->parameter.queueSize) == 0;
  143. }
  144. #endif
  145. ls::std::core::type::byte_field ls::std::network::Socket::_read()
  146. {
  147. #if defined(unix) || defined(__APPLE__)
  148. return this->_readUnix();
  149. #endif
  150. }
  151. #if defined(unix) || defined(__APPLE__)
  152. ls::std::core::type::byte_field ls::std::network::Socket::_readUnix()
  153. {
  154. size_t size = this->parameter.posixReader->read(this->unixDescriptor, this->readBuffer, this->parameter.readBufferSize);
  155. if (size == -1)
  156. {
  157. throw ls::std::core::FileOperationException{}; // TODO: write test
  158. }
  159. return ls::std::core::type::byte_field{this->readBuffer, size};
  160. }
  161. void ls::std::network::Socket::_setPosixReaderApi()
  162. {
  163. if (this->parameter.posixReader == nullptr)
  164. {
  165. this->parameter.posixReader = ::std::make_shared<ls::std::common::api::PosixReader>();
  166. }
  167. }
  168. void ls::std::network::Socket::_setPosixSocketApi()
  169. {
  170. if (this->parameter.posixSocket == nullptr)
  171. {
  172. this->parameter.posixSocket = ::std::make_shared<ls::std::common::api::PosixSocket>();
  173. }
  174. }
  175. void ls::std::network::Socket::_setPosixWriterApi()
  176. {
  177. if (this->parameter.posixWriter == nullptr)
  178. {
  179. this->parameter.posixWriter = ::std::make_shared<ls::std::common::api::PosixWriter>();
  180. }
  181. }
  182. #endif
  183. bool ls::std::network::Socket::_write(const ls::std::core::type::byte_field &_data)
  184. {
  185. #if defined(unix) || defined(__APPLE__)
  186. return this->_writeUnix(_data);
  187. #endif
  188. }
  189. #if defined(unix) || defined(__APPLE__)
  190. bool ls::std::network::Socket::_writeUnix(const ls::std::core::type::byte_field &_data)
  191. {
  192. bool written{};
  193. if (!_data.empty())
  194. {
  195. size_t size = _data.size() + 1;
  196. char* buffer = new char[size];
  197. ::std::strcpy(buffer, _data.c_str());
  198. written = this->parameter.posixWriter->write(this->unixDescriptor, buffer, size) != -1;
  199. delete[] buffer;
  200. }
  201. return written;
  202. }
  203. #endif