/src/mozilla-central/media/mtransport/test/dummysocket.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=2 et sw=2 tw=80: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
5 | | * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | // Original authors: ekr@rtfm.com; ryan@tokbox.com |
8 | | |
9 | | #ifndef MTRANSPORT_DUMMY_SOCKET_H_ |
10 | | #define MTRANSPORT_DUMMY_SOCKET_H_ |
11 | | |
12 | | #include "nr_socket_prsock.h" |
13 | | |
14 | | extern "C" { |
15 | | #include "transport_addr.h" |
16 | | } |
17 | | |
18 | | #include "mediapacket.h" |
19 | | #include "mozilla/UniquePtr.h" |
20 | | |
21 | | #define GTEST_HAS_RTTI 0 |
22 | | #include "gtest/gtest.h" |
23 | | #include "gtest_utils.h" |
24 | | |
25 | | namespace mozilla { |
26 | | |
27 | 0 | static UniquePtr<MediaPacket> merge(UniquePtr<MediaPacket> a, UniquePtr<MediaPacket> b) { |
28 | 0 | if (a && a->len() && b && b->len()) { |
29 | 0 | UniquePtr<uint8_t[]> data(new uint8_t[a->len() + b->len()]); |
30 | 0 | memcpy(data.get(), a->data(), a->len()); |
31 | 0 | memcpy(data.get() + a->len(), b->data(), b->len()); |
32 | 0 |
|
33 | 0 | UniquePtr<MediaPacket> merged(new MediaPacket); |
34 | 0 | merged->Take(std::move(data), a->len() + b->len()); |
35 | 0 | return merged; |
36 | 0 | } |
37 | 0 | |
38 | 0 | if (a && a->len()) { |
39 | 0 | return a; |
40 | 0 | } |
41 | 0 | |
42 | 0 | if (b && b->len()) { |
43 | 0 | return b; |
44 | 0 | } |
45 | 0 | |
46 | 0 | return nullptr; |
47 | 0 | } Unexecuted instantiation: buffered_stun_socket_unittest.cpp:mozilla::merge(mozilla::UniquePtr<mozilla::MediaPacket, mozilla::DefaultDelete<mozilla::MediaPacket> >, mozilla::UniquePtr<mozilla::MediaPacket, mozilla::DefaultDelete<mozilla::MediaPacket> >) Unexecuted instantiation: proxy_tunnel_socket_unittest.cpp:mozilla::merge(mozilla::UniquePtr<mozilla::MediaPacket, mozilla::DefaultDelete<mozilla::MediaPacket> >, mozilla::UniquePtr<mozilla::MediaPacket, mozilla::DefaultDelete<mozilla::MediaPacket> >) |
48 | | |
49 | | class DummySocket : public NrSocketBase { |
50 | | public: |
51 | | DummySocket() |
52 | | : writable_(UINT_MAX), |
53 | | write_buffer_(nullptr), |
54 | | readable_(UINT_MAX), |
55 | | read_buffer_(nullptr), |
56 | | cb_(nullptr), |
57 | | cb_arg_(nullptr), |
58 | 0 | self_(nullptr) {} |
59 | | |
60 | | // the nr_socket APIs |
61 | 0 | virtual int create(nr_transport_addr *addr) override { |
62 | 0 | return 0; |
63 | 0 | } |
64 | | |
65 | | virtual int sendto(const void *msg, size_t len, |
66 | 0 | int flags, nr_transport_addr *to) override { |
67 | 0 | MOZ_CRASH(); |
68 | 0 | return 0; |
69 | 0 | } |
70 | | |
71 | | virtual int recvfrom(void * buf, size_t maxlen, |
72 | | size_t *len, int flags, |
73 | 0 | nr_transport_addr *from) override { |
74 | 0 | MOZ_CRASH(); |
75 | 0 | return 0; |
76 | 0 | } |
77 | | |
78 | 0 | virtual int getaddr(nr_transport_addr *addrp) override { |
79 | 0 | MOZ_CRASH(); |
80 | 0 | return 0; |
81 | 0 | } |
82 | | |
83 | 0 | virtual void close() override { |
84 | 0 | } |
85 | | |
86 | 0 | virtual int connect(nr_transport_addr *addr) override { |
87 | 0 | nr_transport_addr_copy(&connect_addr_, addr); |
88 | 0 | return 0; |
89 | 0 | } |
90 | | |
91 | 0 | virtual int listen(int backlog) override { |
92 | 0 | return 0; |
93 | 0 | } |
94 | | |
95 | 0 | virtual int accept(nr_transport_addr *addrp, nr_socket **sockp) override { |
96 | 0 | return 0; |
97 | 0 | } |
98 | | |
99 | 0 | virtual int write(const void *msg, size_t len, size_t *written) override { |
100 | 0 | size_t to_write = std::min(len, writable_); |
101 | 0 |
|
102 | 0 | if (to_write) { |
103 | 0 | UniquePtr<MediaPacket> msgbuf(new MediaPacket); |
104 | 0 | msgbuf->Copy(static_cast<const uint8_t *>(msg), to_write); |
105 | 0 | write_buffer_ = merge(std::move(write_buffer_), std::move(msgbuf)); |
106 | 0 | } |
107 | 0 |
|
108 | 0 | *written = to_write; |
109 | 0 |
|
110 | 0 | return 0; |
111 | 0 | } |
112 | | |
113 | 0 | virtual int read(void* buf, size_t maxlen, size_t *len) override { |
114 | 0 | if (!read_buffer_.get()) { |
115 | 0 | return R_WOULDBLOCK; |
116 | 0 | } |
117 | 0 |
|
118 | 0 | size_t to_read = std::min(read_buffer_->len(), |
119 | 0 | std::min(maxlen, readable_)); |
120 | 0 |
|
121 | 0 | memcpy(buf, read_buffer_->data(), to_read); |
122 | 0 | *len = to_read; |
123 | 0 |
|
124 | 0 | if (to_read < read_buffer_->len()) { |
125 | 0 | MediaPacket* newPacket = new MediaPacket; |
126 | 0 | newPacket->Copy(read_buffer_->data() + to_read, |
127 | 0 | read_buffer_->len() - to_read); |
128 | 0 | read_buffer_.reset(newPacket); |
129 | 0 | } else { |
130 | 0 | read_buffer_.reset(); |
131 | 0 | } |
132 | 0 |
|
133 | 0 | return 0; |
134 | 0 | } |
135 | | |
136 | | // Implementations of the async_event APIs. |
137 | | // These are no-ops because we handle scheduling manually |
138 | | // for test purposes. |
139 | | virtual int async_wait(int how, NR_async_cb cb, void *cb_arg, |
140 | 0 | char *function, int line) override { |
141 | 0 | EXPECT_EQ(nullptr, cb_); |
142 | 0 | cb_ = cb; |
143 | 0 | cb_arg_ = cb_arg; |
144 | 0 |
|
145 | 0 | return 0; |
146 | 0 | } |
147 | | |
148 | 0 | virtual int cancel(int how) override { |
149 | 0 | cb_ = nullptr; |
150 | 0 | cb_arg_ = nullptr; |
151 | 0 |
|
152 | 0 | return 0; |
153 | 0 | } |
154 | | |
155 | | // Read/Manipulate the current state. |
156 | 0 | void CheckWriteBuffer(const uint8_t *data, size_t len) { |
157 | 0 | if (!len) { |
158 | 0 | EXPECT_EQ(nullptr, write_buffer_.get()); |
159 | 0 | } else { |
160 | 0 | EXPECT_NE(nullptr, write_buffer_.get()); |
161 | 0 | ASSERT_EQ(len, write_buffer_->len()); |
162 | 0 | ASSERT_EQ(0, memcmp(data, write_buffer_->data(), len)); |
163 | 0 | } |
164 | 0 | } |
165 | | |
166 | 0 | void ClearWriteBuffer() { |
167 | 0 | write_buffer_.reset(); |
168 | 0 | } |
169 | | |
170 | 0 | void SetWritable(size_t val) { |
171 | 0 | writable_ = val; |
172 | 0 | } |
173 | | |
174 | 0 | void FireWritableCb() { |
175 | 0 | NR_async_cb cb = cb_; |
176 | 0 | void *cb_arg = cb_arg_; |
177 | 0 |
|
178 | 0 | cb_ = nullptr; |
179 | 0 | cb_arg_ = nullptr; |
180 | 0 |
|
181 | 0 | cb(this, NR_ASYNC_WAIT_WRITE, cb_arg); |
182 | 0 | } |
183 | | |
184 | 0 | void SetReadBuffer(const uint8_t *data, size_t len) { |
185 | 0 | EXPECT_EQ(nullptr, write_buffer_.get()); |
186 | 0 | read_buffer_.reset(new MediaPacket); |
187 | 0 | read_buffer_->Copy(data, len); |
188 | 0 | } |
189 | | |
190 | 0 | void ClearReadBuffer() { |
191 | 0 | read_buffer_.reset(); |
192 | 0 | } |
193 | | |
194 | 0 | void SetReadable(size_t val) { |
195 | 0 | readable_ = val; |
196 | 0 | } |
197 | | |
198 | 0 | nr_socket *get_nr_socket() { |
199 | 0 | if (!self_) { |
200 | 0 | int r = nr_socket_create_int(this, vtbl(), &self_); |
201 | 0 | AddRef(); |
202 | 0 | if (r) |
203 | 0 | return nullptr; |
204 | 0 | } |
205 | 0 | |
206 | 0 | return self_; |
207 | 0 | } |
208 | | |
209 | 0 | nr_transport_addr *get_connect_addr() { |
210 | 0 | return &connect_addr_; |
211 | 0 | } |
212 | | |
213 | | NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DummySocket, override); |
214 | | |
215 | | private: |
216 | 0 | ~DummySocket() {} |
217 | | |
218 | | DISALLOW_COPY_ASSIGN(DummySocket); |
219 | | |
220 | | size_t writable_; // Amount we allow someone to write. |
221 | | UniquePtr<MediaPacket> write_buffer_; |
222 | | size_t readable_; // Amount we allow someone to read. |
223 | | UniquePtr<MediaPacket> read_buffer_; |
224 | | |
225 | | NR_async_cb cb_; |
226 | | void *cb_arg_; |
227 | | nr_socket *self_; |
228 | | |
229 | | nr_transport_addr connect_addr_; |
230 | | }; |
231 | | |
232 | | } //namespace mozilla |
233 | | |
234 | | #endif |