SocketStream.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. #include "SocketStream.h"
  2. #include <stdint.h> // for uint8_t
  3. #include <cstdio> // for NULL, ssize_t
  4. #include "TCPSocket.h" // for TCPSocket
  5. #include "TLSSocket.h" // for TLSSocket
  6. using namespace bell;
  7. int SocketBuffer::open(const std::string& hostname, int port, bool isSSL) {
  8. if (internalSocket != nullptr) {
  9. close();
  10. }
  11. if (isSSL) {
  12. internalSocket = std::make_unique<bell::TLSSocket>();
  13. } else {
  14. internalSocket = std::make_unique<bell::TCPSocket>();
  15. }
  16. internalSocket->open(hostname, port);
  17. return 0;
  18. }
  19. int SocketBuffer::close() {
  20. if (internalSocket != nullptr && isOpen()) {
  21. pubsync();
  22. internalSocket->close();
  23. internalSocket = nullptr;
  24. }
  25. return 0;
  26. }
  27. int SocketBuffer::sync() {
  28. ssize_t bw, n = pptr() - pbase();
  29. while (n > 0) {
  30. bw = internalSocket->write(reinterpret_cast<uint8_t*>(pptr() - n), n);
  31. if (bw < 0) {
  32. setp(pptr() - n, obuf + bufLen);
  33. pbump(n);
  34. return -1;
  35. }
  36. n -= bw;
  37. }
  38. setp(obuf, obuf + bufLen);
  39. return 0;
  40. }
  41. SocketBuffer::int_type SocketBuffer::underflow() {
  42. ssize_t br = internalSocket->read(reinterpret_cast<uint8_t*>(ibuf), bufLen);
  43. if (br <= 0) {
  44. setg(NULL, NULL, NULL);
  45. return traits_type::eof();
  46. }
  47. setg(ibuf, ibuf, ibuf + br);
  48. return traits_type::to_int_type(*ibuf);
  49. }
  50. SocketBuffer::int_type SocketBuffer::overflow(int_type c) {
  51. if (sync() < 0)
  52. return traits_type::eof();
  53. if (traits_type::eq_int_type(c, traits_type::eof()))
  54. return traits_type::not_eof(c);
  55. *pptr() = traits_type::to_char_type(c);
  56. pbump(1);
  57. return c;
  58. }
  59. std::streamsize SocketBuffer::xsgetn(char_type* __s, std::streamsize __n) {
  60. const std::streamsize bn = egptr() - gptr();
  61. if (__n <= bn) {
  62. traits_type::copy(__s, gptr(), __n);
  63. gbump(__n);
  64. return __n;
  65. }
  66. traits_type::copy(__s, gptr(), bn);
  67. setg(NULL, NULL, NULL);
  68. std::streamsize remain = __n - bn;
  69. char_type* end = __s + __n;
  70. ssize_t br;
  71. while (remain > 0) {
  72. br = internalSocket->read(reinterpret_cast<uint8_t*>(end - remain), remain);
  73. if (br <= 0)
  74. return (__n - remain);
  75. remain -= br;
  76. }
  77. return __n;
  78. }
  79. std::streamsize SocketBuffer::xsputn(const char_type* __s,
  80. std::streamsize __n) {
  81. if (pptr() + __n <= epptr()) {
  82. traits_type::copy(pptr(), __s, __n);
  83. pbump(__n);
  84. return __n;
  85. }
  86. if (sync() < 0)
  87. return 0;
  88. ssize_t bw;
  89. std::streamsize remain = __n;
  90. const char_type* end = __s + __n;
  91. while (remain > bufLen) {
  92. bw = internalSocket->write((uint8_t*)(end - remain), remain);
  93. if (bw < 0)
  94. return (__n - remain);
  95. remain -= bw;
  96. }
  97. if (remain > 0) {
  98. traits_type::copy(pptr(), end - remain, remain);
  99. pbump(remain);
  100. }
  101. return __n;
  102. }