dummysocket.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  4. * You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. // Original authors: ekr@rtfm.com; ryan@tokbox.com
  6. #ifndef MTRANSPORT_DUMMY_SOCKET_H_
  7. #define MTRANSPORT_DUMMY_SOCKET_H_
  8. #include "nr_socket_prsock.h"
  9. extern "C" {
  10. #include "transport_addr.h"
  11. }
  12. #include "databuffer.h"
  13. #include "mozilla/UniquePtr.h"
  14. #define GTEST_HAS_RTTI 0
  15. #include "gtest/gtest.h"
  16. #include "gtest_utils.h"
  17. namespace mozilla {
  18. static UniquePtr<DataBuffer> merge(UniquePtr<DataBuffer> a, UniquePtr<DataBuffer> b) {
  19. if (a && a->len() && b && b->len()) {
  20. UniquePtr<DataBuffer> merged(new DataBuffer());
  21. merged->Allocate(a->len() + b->len());
  22. memcpy(merged->data(), a->data(), a->len());
  23. memcpy(merged->data() + a->len(), b->data(), b->len());
  24. return merged;
  25. }
  26. if (a && a->len()) {
  27. return a;
  28. }
  29. if (b && b->len()) {
  30. return b;
  31. }
  32. return nullptr;
  33. }
  34. class DummySocket : public NrSocketBase {
  35. public:
  36. DummySocket()
  37. : writable_(UINT_MAX),
  38. write_buffer_(nullptr),
  39. readable_(UINT_MAX),
  40. read_buffer_(nullptr),
  41. cb_(nullptr),
  42. cb_arg_(nullptr),
  43. self_(nullptr) {}
  44. // the nr_socket APIs
  45. virtual int create(nr_transport_addr *addr) {
  46. return 0;
  47. }
  48. virtual int sendto(const void *msg, size_t len,
  49. int flags, nr_transport_addr *to) {
  50. MOZ_CRASH();
  51. return 0;
  52. }
  53. virtual int recvfrom(void * buf, size_t maxlen,
  54. size_t *len, int flags,
  55. nr_transport_addr *from) {
  56. MOZ_CRASH();
  57. return 0;
  58. }
  59. virtual int getaddr(nr_transport_addr *addrp) {
  60. MOZ_CRASH();
  61. return 0;
  62. }
  63. virtual void close() {
  64. }
  65. virtual int connect(nr_transport_addr *addr) {
  66. nr_transport_addr_copy(&connect_addr_, addr);
  67. return 0;
  68. }
  69. virtual int listen(int backlog) {
  70. return 0;
  71. }
  72. virtual int accept(nr_transport_addr *addrp, nr_socket **sockp) {
  73. return 0;
  74. }
  75. virtual int write(const void *msg, size_t len, size_t *written) {
  76. size_t to_write = std::min(len, writable_);
  77. if (to_write) {
  78. UniquePtr<DataBuffer> msgbuf(new DataBuffer(static_cast<const uint8_t *>(msg), to_write));
  79. write_buffer_ = merge(Move(write_buffer_), Move(msgbuf));
  80. }
  81. *written = to_write;
  82. return 0;
  83. }
  84. virtual int read(void* buf, size_t maxlen, size_t *len) {
  85. if (!read_buffer_.get()) {
  86. return R_WOULDBLOCK;
  87. }
  88. size_t to_read = std::min(read_buffer_->len(),
  89. std::min(maxlen, readable_));
  90. memcpy(buf, read_buffer_->data(), to_read);
  91. *len = to_read;
  92. if (to_read < read_buffer_->len()) {
  93. read_buffer_.reset(new DataBuffer(read_buffer_->data() + to_read,
  94. read_buffer_->len() - to_read));
  95. } else {
  96. read_buffer_.reset();
  97. }
  98. return 0;
  99. }
  100. // Implementations of the async_event APIs.
  101. // These are no-ops because we handle scheduling manually
  102. // for test purposes.
  103. virtual int async_wait(int how, NR_async_cb cb, void *cb_arg,
  104. char *function, int line) {
  105. EXPECT_EQ(nullptr, cb_);
  106. cb_ = cb;
  107. cb_arg_ = cb_arg;
  108. return 0;
  109. }
  110. virtual int cancel(int how) {
  111. cb_ = nullptr;
  112. cb_arg_ = nullptr;
  113. return 0;
  114. }
  115. // Read/Manipulate the current state.
  116. void CheckWriteBuffer(const uint8_t *data, size_t len) {
  117. if (!len) {
  118. EXPECT_EQ(nullptr, write_buffer_.get());
  119. } else {
  120. EXPECT_NE(nullptr, write_buffer_.get());
  121. ASSERT_EQ(len, write_buffer_->len());
  122. ASSERT_EQ(0, memcmp(data, write_buffer_->data(), len));
  123. }
  124. }
  125. void ClearWriteBuffer() {
  126. write_buffer_.reset();
  127. }
  128. void SetWritable(size_t val) {
  129. writable_ = val;
  130. }
  131. void FireWritableCb() {
  132. NR_async_cb cb = cb_;
  133. void *cb_arg = cb_arg_;
  134. cb_ = nullptr;
  135. cb_arg_ = nullptr;
  136. cb(this, NR_ASYNC_WAIT_WRITE, cb_arg);
  137. }
  138. void SetReadBuffer(const uint8_t *data, size_t len) {
  139. EXPECT_EQ(nullptr, write_buffer_.get());
  140. read_buffer_.reset(new DataBuffer(data, len));
  141. }
  142. void ClearReadBuffer() {
  143. read_buffer_.reset();
  144. }
  145. void SetReadable(size_t val) {
  146. readable_ = val;
  147. }
  148. nr_socket *get_nr_socket() {
  149. if (!self_) {
  150. int r = nr_socket_create_int(this, vtbl(), &self_);
  151. AddRef();
  152. if (r)
  153. return nullptr;
  154. }
  155. return self_;
  156. }
  157. nr_transport_addr *get_connect_addr() {
  158. return &connect_addr_;
  159. }
  160. NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DummySocket);
  161. private:
  162. ~DummySocket() {}
  163. DISALLOW_COPY_ASSIGN(DummySocket);
  164. size_t writable_; // Amount we allow someone to write.
  165. UniquePtr<DataBuffer> write_buffer_;
  166. size_t readable_; // Amount we allow someone to read.
  167. UniquePtr<DataBuffer> read_buffer_;
  168. NR_async_cb cb_;
  169. void *cb_arg_;
  170. nr_socket *self_;
  171. nr_transport_addr connect_addr_;
  172. };
  173. } //namespace mozilla
  174. #endif