123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
- // Original authors: ekr@rtfm.com; ryan@tokbox.com
- #ifndef MTRANSPORT_DUMMY_SOCKET_H_
- #define MTRANSPORT_DUMMY_SOCKET_H_
- #include "nr_socket_prsock.h"
- extern "C" {
- #include "transport_addr.h"
- }
- #include "databuffer.h"
- #include "mozilla/UniquePtr.h"
- #define GTEST_HAS_RTTI 0
- #include "gtest/gtest.h"
- #include "gtest_utils.h"
- namespace mozilla {
- static UniquePtr<DataBuffer> merge(UniquePtr<DataBuffer> a, UniquePtr<DataBuffer> b) {
- if (a && a->len() && b && b->len()) {
- UniquePtr<DataBuffer> merged(new DataBuffer());
- merged->Allocate(a->len() + b->len());
- memcpy(merged->data(), a->data(), a->len());
- memcpy(merged->data() + a->len(), b->data(), b->len());
- return merged;
- }
- if (a && a->len()) {
- return a;
- }
- if (b && b->len()) {
- return b;
- }
- return nullptr;
- }
- class DummySocket : public NrSocketBase {
- public:
- DummySocket()
- : writable_(UINT_MAX),
- write_buffer_(nullptr),
- readable_(UINT_MAX),
- read_buffer_(nullptr),
- cb_(nullptr),
- cb_arg_(nullptr),
- self_(nullptr) {}
- // the nr_socket APIs
- virtual int create(nr_transport_addr *addr) {
- return 0;
- }
- virtual int sendto(const void *msg, size_t len,
- int flags, nr_transport_addr *to) {
- MOZ_CRASH();
- return 0;
- }
- virtual int recvfrom(void * buf, size_t maxlen,
- size_t *len, int flags,
- nr_transport_addr *from) {
- MOZ_CRASH();
- return 0;
- }
- virtual int getaddr(nr_transport_addr *addrp) {
- MOZ_CRASH();
- return 0;
- }
- virtual void close() {
- }
- virtual int connect(nr_transport_addr *addr) {
- nr_transport_addr_copy(&connect_addr_, addr);
- return 0;
- }
- virtual int listen(int backlog) {
- return 0;
- }
- virtual int accept(nr_transport_addr *addrp, nr_socket **sockp) {
- return 0;
- }
- virtual int write(const void *msg, size_t len, size_t *written) {
- size_t to_write = std::min(len, writable_);
- if (to_write) {
- UniquePtr<DataBuffer> msgbuf(new DataBuffer(static_cast<const uint8_t *>(msg), to_write));
- write_buffer_ = merge(Move(write_buffer_), Move(msgbuf));
- }
- *written = to_write;
- return 0;
- }
- virtual int read(void* buf, size_t maxlen, size_t *len) {
- if (!read_buffer_.get()) {
- return R_WOULDBLOCK;
- }
- size_t to_read = std::min(read_buffer_->len(),
- std::min(maxlen, readable_));
- memcpy(buf, read_buffer_->data(), to_read);
- *len = to_read;
- if (to_read < read_buffer_->len()) {
- read_buffer_.reset(new DataBuffer(read_buffer_->data() + to_read,
- read_buffer_->len() - to_read));
- } else {
- read_buffer_.reset();
- }
- return 0;
- }
- // Implementations of the async_event APIs.
- // These are no-ops because we handle scheduling manually
- // for test purposes.
- virtual int async_wait(int how, NR_async_cb cb, void *cb_arg,
- char *function, int line) {
- EXPECT_EQ(nullptr, cb_);
- cb_ = cb;
- cb_arg_ = cb_arg;
- return 0;
- }
- virtual int cancel(int how) {
- cb_ = nullptr;
- cb_arg_ = nullptr;
- return 0;
- }
- // Read/Manipulate the current state.
- void CheckWriteBuffer(const uint8_t *data, size_t len) {
- if (!len) {
- EXPECT_EQ(nullptr, write_buffer_.get());
- } else {
- EXPECT_NE(nullptr, write_buffer_.get());
- ASSERT_EQ(len, write_buffer_->len());
- ASSERT_EQ(0, memcmp(data, write_buffer_->data(), len));
- }
- }
- void ClearWriteBuffer() {
- write_buffer_.reset();
- }
- void SetWritable(size_t val) {
- writable_ = val;
- }
- void FireWritableCb() {
- NR_async_cb cb = cb_;
- void *cb_arg = cb_arg_;
- cb_ = nullptr;
- cb_arg_ = nullptr;
- cb(this, NR_ASYNC_WAIT_WRITE, cb_arg);
- }
- void SetReadBuffer(const uint8_t *data, size_t len) {
- EXPECT_EQ(nullptr, write_buffer_.get());
- read_buffer_.reset(new DataBuffer(data, len));
- }
- void ClearReadBuffer() {
- read_buffer_.reset();
- }
- void SetReadable(size_t val) {
- readable_ = val;
- }
- nr_socket *get_nr_socket() {
- if (!self_) {
- int r = nr_socket_create_int(this, vtbl(), &self_);
- AddRef();
- if (r)
- return nullptr;
- }
- return self_;
- }
- nr_transport_addr *get_connect_addr() {
- return &connect_addr_;
- }
- NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DummySocket);
- private:
- ~DummySocket() {}
- DISALLOW_COPY_ASSIGN(DummySocket);
- size_t writable_; // Amount we allow someone to write.
- UniquePtr<DataBuffer> write_buffer_;
- size_t readable_; // Amount we allow someone to read.
- UniquePtr<DataBuffer> read_buffer_;
- NR_async_cb cb_;
- void *cb_arg_;
- nr_socket *self_;
- nr_transport_addr connect_addr_;
- };
- } //namespace mozilla
- #endif
|