1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/mtransport/transportlayerloopback.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,138 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set ts=2 et sw=2 tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.8 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +// Original author: ekr@rtfm.com 1.11 + 1.12 +#ifndef transportlayerloopback_h__ 1.13 +#define transportlayerloopback_h__ 1.14 + 1.15 +#include "nspr.h" 1.16 +#include "prio.h" 1.17 +#include "prlock.h" 1.18 + 1.19 +#include <memory> 1.20 +#include <queue> 1.21 + 1.22 + 1.23 +#include "nsAutoPtr.h" 1.24 +#include "nsCOMPtr.h" 1.25 +#include "nsITimer.h" 1.26 + 1.27 + 1.28 +#include "m_cpp_utils.h" 1.29 +#include "transportflow.h" 1.30 +#include "transportlayer.h" 1.31 + 1.32 +// A simple loopback transport layer that is used for testing. 1.33 +namespace mozilla { 1.34 + 1.35 +class TransportLayerLoopback : public TransportLayer { 1.36 + public: 1.37 + TransportLayerLoopback() : 1.38 + peer_(nullptr), 1.39 + timer_(nullptr), 1.40 + packets_(), 1.41 + packets_lock_(nullptr), 1.42 + deliverer_(nullptr) {} 1.43 + 1.44 + ~TransportLayerLoopback() { 1.45 + while (!packets_.empty()) { 1.46 + QueuedPacket *packet = packets_.front(); 1.47 + packets_.pop(); 1.48 + delete packet; 1.49 + } 1.50 + if (packets_lock_) { 1.51 + PR_DestroyLock(packets_lock_); 1.52 + } 1.53 + timer_->Cancel(); 1.54 + deliverer_->Detach(); 1.55 + } 1.56 + 1.57 + // Init 1.58 + nsresult Init(); 1.59 + 1.60 + // Connect to the other side 1.61 + void Connect(TransportLayerLoopback* peer); 1.62 + 1.63 + // Disconnect 1.64 + void Disconnect() { 1.65 + TransportLayerLoopback *peer = peer_; 1.66 + 1.67 + peer_ = nullptr; 1.68 + if (peer) { 1.69 + peer->Disconnect(); 1.70 + } 1.71 + } 1.72 + 1.73 + // Overrides for TransportLayer 1.74 + virtual TransportResult SendPacket(const unsigned char *data, size_t len); 1.75 + 1.76 + // Deliver queued packets 1.77 + void DeliverPackets(); 1.78 + 1.79 + TRANSPORT_LAYER_ID("loopback") 1.80 + 1.81 + private: 1.82 + DISALLOW_COPY_ASSIGN(TransportLayerLoopback); 1.83 + 1.84 + // A queued packet 1.85 + class QueuedPacket { 1.86 + public: 1.87 + QueuedPacket() : data_(nullptr), len_(0) {} 1.88 + ~QueuedPacket() { 1.89 + delete [] data_; 1.90 + } 1.91 + 1.92 + void Assign(const unsigned char *data, size_t len) { 1.93 + data_ = new unsigned char[len]; 1.94 + memcpy(static_cast<void *>(data_), 1.95 + static_cast<const void *>(data), len); 1.96 + len_ = len; 1.97 + } 1.98 + 1.99 + const unsigned char *data() const { return data_; } 1.100 + size_t len() const { return len_; } 1.101 + 1.102 + private: 1.103 + DISALLOW_COPY_ASSIGN(QueuedPacket); 1.104 + 1.105 + unsigned char *data_; 1.106 + size_t len_; 1.107 + }; 1.108 + 1.109 + // A timer to deliver packets if some are available 1.110 + // Fires every 100 ms 1.111 + class Deliverer : public nsITimerCallback { 1.112 + public: 1.113 + Deliverer(TransportLayerLoopback *layer) : 1.114 + layer_(layer) {} 1.115 + virtual ~Deliverer() { 1.116 + } 1.117 + void Detach() { 1.118 + layer_ = nullptr; 1.119 + } 1.120 + 1.121 + NS_DECL_THREADSAFE_ISUPPORTS 1.122 + NS_DECL_NSITIMERCALLBACK 1.123 + 1.124 + private: 1.125 + DISALLOW_COPY_ASSIGN(Deliverer); 1.126 + 1.127 + TransportLayerLoopback *layer_; 1.128 + }; 1.129 + 1.130 + // Queue a packet for delivery 1.131 + nsresult QueuePacket(const unsigned char *data, size_t len); 1.132 + 1.133 + TransportLayerLoopback* peer_; 1.134 + nsCOMPtr<nsITimer> timer_; 1.135 + std::queue<QueuedPacket *> packets_; 1.136 + PRLock *packets_lock_; 1.137 + nsRefPtr<Deliverer> deliverer_; 1.138 +}; 1.139 + 1.140 +} // close namespace 1.141 +#endif