Revert "Move webrtc/{base => rtc_base}" (https://codereview.webrtc.org/2877023002)

Will reland in two different commits to preserve git blame history.

BUG=webrtc:7634
NOTRY=True
TBR=kwiberg@webrtc.org

Change-Id: I550da8525aeb9c5b8f96338fcf1c9714f3dcdab1
Reviewed-on: https://chromium-review.googlesource.com/554610
Reviewed-by: Henrik Kjellander <kjellander@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#18820}
This commit is contained in:
Henrik Kjellander
2017-06-29 07:52:50 +02:00
parent a4c113afe1
commit ec78f1cebc
546 changed files with 20456 additions and 28300 deletions

View File

@ -32,7 +32,6 @@ CPPLINT_BLACKLIST = [
'webrtc/modules/video_capture',
'webrtc/p2p',
'webrtc/pc',
'webrtc/rtc_base',
'webrtc/sdk/android/src/jni',
'webrtc/sdk/objc',
'webrtc/system_wrappers',

View File

@ -21,7 +21,6 @@ include_rules = [
"+webrtc/api",
"+webrtc/base",
"+webrtc/modules/include",
"+webrtc/rtc_base",
"+webrtc/test",
"+webrtc/tools",
]

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +0,0 @@
/**
* This class only exists as glue in a transition.
* TODO(kjellander): Remove.
* See https://bugs.webrtc.org/7634 for more details.
*/
class Dummy {
Dummy() {
}
}

View File

@ -11,9 +11,243 @@
#ifndef WEBRTC_BASE_ARRAY_VIEW_H_
#define WEBRTC_BASE_ARRAY_VIEW_H_
#include "webrtc/base/checks.h"
#include "webrtc/base/type_traits.h"
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/array_view.h"
namespace rtc {
// Many functions read from or write to arrays. The obvious way to do this is
// to use two arguments, a pointer to the first element and an element count:
//
// bool Contains17(const int* arr, size_t size) {
// for (size_t i = 0; i < size; ++i) {
// if (arr[i] == 17)
// return true;
// }
// return false;
// }
//
// This is flexible, since it doesn't matter how the array is stored (C array,
// std::vector, rtc::Buffer, ...), but it's error-prone because the caller has
// to correctly specify the array length:
//
// Contains17(arr, arraysize(arr)); // C array
// Contains17(arr.data(), arr.size()); // std::vector
// Contains17(arr, size); // pointer + size
// ...
//
// It's also kind of messy to have two separate arguments for what is
// conceptually a single thing.
//
// Enter rtc::ArrayView<T>. It contains a T pointer (to an array it doesn't
// own) and a count, and supports the basic things you'd expect, such as
// indexing and iteration. It allows us to write our function like this:
//
// bool Contains17(rtc::ArrayView<const int> arr) {
// for (auto e : arr) {
// if (e == 17)
// return true;
// }
// return false;
// }
//
// And even better, because a bunch of things will implicitly convert to
// ArrayView, we can call it like this:
//
// Contains17(arr); // C array
// Contains17(arr); // std::vector
// Contains17(rtc::ArrayView<int>(arr, size)); // pointer + size
// Contains17(nullptr); // nullptr -> empty ArrayView
// ...
//
// ArrayView<T> stores both a pointer and a size, but you may also use
// ArrayView<T, N>, which has a size that's fixed at compile time (which means
// it only has to store the pointer).
//
// One important point is that ArrayView<T> and ArrayView<const T> are
// different types, which allow and don't allow mutation of the array elements,
// respectively. The implicit conversions work just like you'd hope, so that
// e.g. vector<int> will convert to either ArrayView<int> or ArrayView<const
// int>, but const vector<int> will convert only to ArrayView<const int>.
// (ArrayView itself can be the source type in such conversions, so
// ArrayView<int> will convert to ArrayView<const int>.)
//
// Note: ArrayView is tiny (just a pointer and a count if variable-sized, just
// a pointer if fix-sized) and trivially copyable, so it's probably cheaper to
// pass it by value than by const reference.
namespace impl {
// Magic constant for indicating that the size of an ArrayView is variable
// instead of fixed.
enum : std::ptrdiff_t { kArrayViewVarSize = -4711 };
// Base class for ArrayViews of fixed nonzero size.
template <typename T, std::ptrdiff_t Size>
class ArrayViewBase {
static_assert(Size > 0, "ArrayView size must be variable or non-negative");
public:
ArrayViewBase(T* data, size_t size) : data_(data) {}
static constexpr size_t size() { return Size; }
static constexpr bool empty() { return false; }
T* data() const { return data_; }
protected:
static constexpr bool fixed_size() { return true; }
private:
T* data_;
};
// Specialized base class for ArrayViews of fixed zero size.
template <typename T>
class ArrayViewBase<T, 0> {
public:
explicit ArrayViewBase(T* data, size_t size) {}
static constexpr size_t size() { return 0; }
static constexpr bool empty() { return true; }
T* data() const { return nullptr; }
protected:
static constexpr bool fixed_size() { return true; }
};
// Specialized base class for ArrayViews of variable size.
template <typename T>
class ArrayViewBase<T, impl::kArrayViewVarSize> {
public:
ArrayViewBase(T* data, size_t size)
: data_(size == 0 ? nullptr : data), size_(size) {}
size_t size() const { return size_; }
bool empty() const { return size_ == 0; }
T* data() const { return data_; }
protected:
static constexpr bool fixed_size() { return false; }
private:
T* data_;
size_t size_;
};
} // namespace impl
template <typename T, std::ptrdiff_t Size = impl::kArrayViewVarSize>
class ArrayView final : public impl::ArrayViewBase<T, Size> {
public:
using value_type = T;
using const_iterator = const T*;
// Construct an ArrayView from a pointer and a length.
template <typename U>
ArrayView(U* data, size_t size)
: impl::ArrayViewBase<T, Size>::ArrayViewBase(data, size) {
RTC_DCHECK_EQ(size == 0 ? nullptr : data, this->data());
RTC_DCHECK_EQ(size, this->size());
RTC_DCHECK_EQ(!this->data(),
this->size() == 0); // data is null iff size == 0.
}
// Construct an empty ArrayView. Note that fixed-size ArrayViews of size > 0
// cannot be empty.
ArrayView() : ArrayView(nullptr, 0) {}
ArrayView(std::nullptr_t) : ArrayView() {}
ArrayView(std::nullptr_t, size_t size)
: ArrayView(static_cast<T*>(nullptr), size) {
static_assert(Size == 0 || Size == impl::kArrayViewVarSize, "");
RTC_DCHECK_EQ(0, size);
}
// Construct an ArrayView from an array.
template <typename U, size_t N>
ArrayView(U (&array)[N]) : ArrayView(array, N) {
static_assert(Size == N || Size == impl::kArrayViewVarSize,
"Array size must match ArrayView size");
}
// (Only if size is fixed.) Construct an ArrayView from any type U that has a
// static constexpr size() method whose return value is equal to Size, and a
// data() method whose return value converts implicitly to T*. In particular,
// this means we allow conversion from ArrayView<T, N> to ArrayView<const T,
// N>, but not the other way around. We also don't allow conversion from
// ArrayView<T> to ArrayView<T, N>, or from ArrayView<T, M> to ArrayView<T,
// N> when M != N.
template <typename U,
typename std::enable_if<
Size != impl::kArrayViewVarSize &&
HasDataAndSize<U, T>::value>::type* = nullptr>
ArrayView(U& u) : ArrayView(u.data(), u.size()) {
static_assert(U::size() == Size, "Sizes must match exactly");
}
// (Only if size is variable.) Construct an ArrayView from any type U that
// has a size() method whose return value converts implicitly to size_t, and
// a data() method whose return value converts implicitly to T*. In
// particular, this means we allow conversion from ArrayView<T> to
// ArrayView<const T>, but not the other way around. Other allowed
// conversions include
// ArrayView<T, N> to ArrayView<T> or ArrayView<const T>,
// std::vector<T> to ArrayView<T> or ArrayView<const T>,
// const std::vector<T> to ArrayView<const T>,
// rtc::Buffer to ArrayView<uint8_t> or ArrayView<const uint8_t>, and
// const rtc::Buffer to ArrayView<const uint8_t>.
template <
typename U,
typename std::enable_if<Size == impl::kArrayViewVarSize &&
HasDataAndSize<U, T>::value>::type* = nullptr>
ArrayView(U& u) : ArrayView(u.data(), u.size()) {}
// Indexing and iteration. These allow mutation even if the ArrayView is
// const, because the ArrayView doesn't own the array. (To prevent mutation,
// use a const element type.)
T& operator[](size_t idx) const {
RTC_DCHECK_LT(idx, this->size());
RTC_DCHECK(this->data());
return this->data()[idx];
}
T* begin() const { return this->data(); }
T* end() const { return this->data() + this->size(); }
const T* cbegin() const { return this->data(); }
const T* cend() const { return this->data() + this->size(); }
ArrayView<T> subview(size_t offset, size_t size) const {
return offset < this->size()
? ArrayView<T>(this->data() + offset,
std::min(size, this->size() - offset))
: ArrayView<T>();
}
ArrayView<T> subview(size_t offset) const {
return subview(offset, this->size());
}
};
// Comparing two ArrayViews compares their (pointer,size) pairs; it does *not*
// dereference the pointers.
template <typename T, std::ptrdiff_t Size1, std::ptrdiff_t Size2>
bool operator==(const ArrayView<T, Size1>& a, const ArrayView<T, Size2>& b) {
return a.data() == b.data() && a.size() == b.size();
}
template <typename T, std::ptrdiff_t Size1, std::ptrdiff_t Size2>
bool operator!=(const ArrayView<T, Size1>& a, const ArrayView<T, Size2>& b) {
return !(a == b);
}
// Variable-size ArrayViews are the size of two pointers; fixed-size ArrayViews
// are the size of one pointer. (And as a special case, fixed-size ArrayViews
// of size 0 require no storage.)
static_assert(sizeof(ArrayView<int>) == 2 * sizeof(int*), "");
static_assert(sizeof(ArrayView<int, 17>) == sizeof(int*), "");
static_assert(std::is_empty<ArrayView<int, 0>>::value, "");
template <typename T>
inline ArrayView<T> MakeArrayView(T* data, size_t size) {
return ArrayView<T>(data, size);
}
} // namespace rtc
#endif // WEBRTC_BASE_ARRAY_VIEW_H_

View File

@ -11,9 +11,21 @@
#ifndef WEBRTC_BASE_ARRAYSIZE_H_
#define WEBRTC_BASE_ARRAYSIZE_H_
#include <stddef.h>
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/arraysize.h"
// This file defines the arraysize() macro and is derived from Chromium's
// base/macros.h.
// The arraysize(arr) macro returns the # of elements in an array arr.
// The expression is a compile-time constant, and therefore can be
// used in defining new arrays, for example. If you use arraysize on
// a pointer by mistake, you will get a compile-time error.
// This template function declaration is used in defining arraysize.
// Note that the function doesn't need an implementation, as we only
// use its type.
template <typename T, size_t N> char (&ArraySizeHelper(T (&array)[N]))[N];
#define arraysize(array) (sizeof(ArraySizeHelper(array)))
#endif // WEBRTC_BASE_ARRAYSIZE_H_

View File

@ -11,9 +11,46 @@
#ifndef WEBRTC_BASE_ASYNCINVOKER_INL_H_
#define WEBRTC_BASE_ASYNCINVOKER_INL_H_
#include "webrtc/base/atomicops.h"
#include "webrtc/base/bind.h"
#include "webrtc/base/criticalsection.h"
#include "webrtc/base/messagehandler.h"
#include "webrtc/base/sigslot.h"
#include "webrtc/base/thread.h"
#include "webrtc/base/thread_annotations.h"
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/asyncinvoker-inl.h"
namespace rtc {
class AsyncInvoker;
// Helper class for AsyncInvoker. Runs a task and triggers a callback
// on the calling thread if necessary.
class AsyncClosure {
public:
explicit AsyncClosure(AsyncInvoker* invoker) : invoker_(invoker) {}
virtual ~AsyncClosure();
// Runs the asynchronous task, and triggers a callback to the calling
// thread if needed. Should be called from the target thread.
virtual void Execute() = 0;
protected:
AsyncInvoker* invoker_;
};
// Simple closure that doesn't trigger a callback for the calling thread.
template <class FunctorT>
class FireAndForgetAsyncClosure : public AsyncClosure {
public:
explicit FireAndForgetAsyncClosure(AsyncInvoker* invoker,
const FunctorT& functor)
: AsyncClosure(invoker), functor_(functor) {}
virtual void Execute() {
functor_();
}
private:
FunctorT functor_;
};
} // namespace rtc
#endif // WEBRTC_BASE_ASYNCINVOKER_INL_H_

View File

@ -11,9 +11,211 @@
#ifndef WEBRTC_BASE_ASYNCINVOKER_H_
#define WEBRTC_BASE_ASYNCINVOKER_H_
#include <memory>
#include <utility>
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/asyncinvoker.h"
#include "webrtc/base/asyncinvoker-inl.h"
#include "webrtc/base/bind.h"
#include "webrtc/base/constructormagic.h"
#include "webrtc/base/event.h"
#include "webrtc/base/sigslot.h"
#include "webrtc/base/thread.h"
namespace rtc {
// Invokes function objects (aka functors) asynchronously on a Thread, and
// owns the lifetime of calls (ie, when this object is destroyed, calls in
// flight are cancelled). AsyncInvoker can optionally execute a user-specified
// function when the asynchronous call is complete, or operates in
// fire-and-forget mode otherwise.
//
// AsyncInvoker does not own the thread it calls functors on.
//
// A note about async calls and object lifetimes: users should
// be mindful of object lifetimes when calling functions asynchronously and
// ensure objects used by the function _cannot_ be deleted between the
// invocation and execution of the functor. AsyncInvoker is designed to
// help: any calls in flight will be cancelled when the AsyncInvoker used to
// make the call is destructed, and any calls executing will be allowed to
// complete before AsyncInvoker destructs.
//
// The easiest way to ensure lifetimes are handled correctly is to create a
// class that owns the Thread and AsyncInvoker objects, and then call its
// methods asynchronously as needed.
//
// Example:
// class MyClass {
// public:
// void FireAsyncTaskWithResult(Thread* thread, int x) {
// // Specify a callback to get the result upon completion.
// invoker_.AsyncInvoke<int>(RTC_FROM_HERE,
// thread, Bind(&MyClass::AsyncTaskWithResult, this, x),
// &MyClass::OnTaskComplete, this);
// }
// void FireAnotherAsyncTask(Thread* thread) {
// // No callback specified means fire-and-forget.
// invoker_.AsyncInvoke<void>(RTC_FROM_HERE,
// thread, Bind(&MyClass::AnotherAsyncTask, this));
//
// private:
// int AsyncTaskWithResult(int x) {
// // Some long running process...
// return x * x;
// }
// void AnotherAsyncTask() {
// // Some other long running process...
// }
// void OnTaskComplete(int result) { result_ = result; }
//
// AsyncInvoker invoker_;
// int result_;
// };
class AsyncInvoker : public MessageHandler {
public:
AsyncInvoker();
~AsyncInvoker() override;
// Call |functor| asynchronously on |thread|, with no callback upon
// completion. Returns immediately.
template <class ReturnT, class FunctorT>
void AsyncInvoke(const Location& posted_from,
Thread* thread,
const FunctorT& functor,
uint32_t id = 0) {
std::unique_ptr<AsyncClosure> closure(
new FireAndForgetAsyncClosure<FunctorT>(this, functor));
DoInvoke(posted_from, thread, std::move(closure), id);
}
// Call |functor| asynchronously on |thread| with |delay_ms|, with no callback
// upon completion. Returns immediately.
template <class ReturnT, class FunctorT>
void AsyncInvokeDelayed(const Location& posted_from,
Thread* thread,
const FunctorT& functor,
uint32_t delay_ms,
uint32_t id = 0) {
std::unique_ptr<AsyncClosure> closure(
new FireAndForgetAsyncClosure<FunctorT>(this, functor));
DoInvokeDelayed(posted_from, thread, std::move(closure), delay_ms, id);
}
// Synchronously execute on |thread| all outstanding calls we own
// that are pending on |thread|, and wait for calls to complete
// before returning. Optionally filter by message id.
// The destructor will not wait for outstanding calls, so if that
// behavior is desired, call Flush() before destroying this object.
void Flush(Thread* thread, uint32_t id = MQID_ANY);
private:
void OnMessage(Message* msg) override;
void DoInvoke(const Location& posted_from,
Thread* thread,
std::unique_ptr<AsyncClosure> closure,
uint32_t id);
void DoInvokeDelayed(const Location& posted_from,
Thread* thread,
std::unique_ptr<AsyncClosure> closure,
uint32_t delay_ms,
uint32_t id);
volatile int pending_invocations_ = 0;
Event invocation_complete_;
bool destroying_ = false;
friend class AsyncClosure;
RTC_DISALLOW_COPY_AND_ASSIGN(AsyncInvoker);
};
// Similar to AsyncInvoker, but guards against the Thread being destroyed while
// there are outstanding dangling pointers to it. It will connect to the current
// thread in the constructor, and will get notified when that thread is
// destroyed. After GuardedAsyncInvoker is constructed, it can be used from
// other threads to post functors to the thread it was constructed on. If that
// thread dies, any further calls to AsyncInvoke() will be safely ignored.
class GuardedAsyncInvoker : public sigslot::has_slots<> {
public:
GuardedAsyncInvoker();
~GuardedAsyncInvoker() override;
// Synchronously execute all outstanding calls we own, and wait for calls to
// complete before returning. Optionally filter by message id. The destructor
// will not wait for outstanding calls, so if that behavior is desired, call
// Flush() first. Returns false if the thread has died.
bool Flush(uint32_t id = MQID_ANY);
// Call |functor| asynchronously with no callback upon completion. Returns
// immediately. Returns false if the thread has died.
template <class ReturnT, class FunctorT>
bool AsyncInvoke(const Location& posted_from,
const FunctorT& functor,
uint32_t id = 0) {
rtc::CritScope cs(&crit_);
if (thread_ == nullptr)
return false;
invoker_.AsyncInvoke<ReturnT, FunctorT>(posted_from, thread_, functor, id);
return true;
}
// Call |functor| asynchronously with |delay_ms|, with no callback upon
// completion. Returns immediately. Returns false if the thread has died.
template <class ReturnT, class FunctorT>
bool AsyncInvokeDelayed(const Location& posted_from,
const FunctorT& functor,
uint32_t delay_ms,
uint32_t id = 0) {
rtc::CritScope cs(&crit_);
if (thread_ == nullptr)
return false;
invoker_.AsyncInvokeDelayed<ReturnT, FunctorT>(posted_from, thread_,
functor, delay_ms, id);
return true;
}
// Call |functor| asynchronously, calling |callback| when done. Returns false
// if the thread has died.
template <class ReturnT, class FunctorT, class HostT>
bool AsyncInvoke(const Location& posted_from,
const Location& callback_posted_from,
const FunctorT& functor,
void (HostT::*callback)(ReturnT),
HostT* callback_host,
uint32_t id = 0) {
rtc::CritScope cs(&crit_);
if (thread_ == nullptr)
return false;
invoker_.AsyncInvoke<ReturnT, FunctorT, HostT>(
posted_from, callback_posted_from, thread_, functor, callback,
callback_host, id);
return true;
}
// Call |functor| asynchronously calling |callback| when done. Overloaded for
// void return. Returns false if the thread has died.
template <class ReturnT, class FunctorT, class HostT>
bool AsyncInvoke(const Location& posted_from,
const Location& callback_posted_from,
const FunctorT& functor,
void (HostT::*callback)(),
HostT* callback_host,
uint32_t id = 0) {
rtc::CritScope cs(&crit_);
if (thread_ == nullptr)
return false;
invoker_.AsyncInvoke<ReturnT, FunctorT, HostT>(
posted_from, callback_posted_from, thread_, functor, callback,
callback_host, id);
return true;
}
private:
// Callback when |thread_| is destroyed.
void ThreadDestroyed();
CriticalSection crit_;
Thread* thread_ GUARDED_BY(crit_);
AsyncInvoker invoker_ GUARDED_BY(crit_);
};
} // namespace rtc
#endif // WEBRTC_BASE_ASYNCINVOKER_H_

View File

@ -11,9 +11,133 @@
#ifndef WEBRTC_BASE_ASYNCPACKETSOCKET_H_
#define WEBRTC_BASE_ASYNCPACKETSOCKET_H_
#include "webrtc/base/constructormagic.h"
#include "webrtc/base/dscp.h"
#include "webrtc/base/sigslot.h"
#include "webrtc/base/socket.h"
#include "webrtc/base/timeutils.h"
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/asyncpacketsocket.h"
namespace rtc {
// This structure holds the info needed to update the packet send time header
// extension, including the information needed to update the authentication tag
// after changing the value.
struct PacketTimeUpdateParams {
PacketTimeUpdateParams();
~PacketTimeUpdateParams();
int rtp_sendtime_extension_id; // extension header id present in packet.
std::vector<char> srtp_auth_key; // Authentication key.
int srtp_auth_tag_len; // Authentication tag length.
int64_t srtp_packet_index; // Required for Rtp Packet authentication.
};
// This structure holds meta information for the packet which is about to send
// over network.
struct PacketOptions {
PacketOptions() : dscp(DSCP_NO_CHANGE), packet_id(-1) {}
explicit PacketOptions(DiffServCodePoint dscp) : dscp(dscp), packet_id(-1) {}
DiffServCodePoint dscp;
int packet_id; // 16 bits, -1 represents "not set".
PacketTimeUpdateParams packet_time_params;
};
// This structure will have the information about when packet is actually
// received by socket.
struct PacketTime {
PacketTime() : timestamp(-1), not_before(-1) {}
PacketTime(int64_t timestamp, int64_t not_before)
: timestamp(timestamp), not_before(not_before) {}
int64_t timestamp; // Receive time after socket delivers the data.
// Earliest possible time the data could have arrived, indicating the
// potential error in the |timestamp| value, in case the system, is busy. For
// example, the time of the last select() call.
// If unknown, this value will be set to zero.
int64_t not_before;
};
inline PacketTime CreatePacketTime(int64_t not_before) {
return PacketTime(TimeMicros(), not_before);
}
// Provides the ability to receive packets asynchronously. Sends are not
// buffered since it is acceptable to drop packets under high load.
class AsyncPacketSocket : public sigslot::has_slots<> {
public:
enum State {
STATE_CLOSED,
STATE_BINDING,
STATE_BOUND,
STATE_CONNECTING,
STATE_CONNECTED
};
AsyncPacketSocket();
~AsyncPacketSocket() override;
// Returns current local address. Address may be set to null if the
// socket is not bound yet (GetState() returns STATE_BINDING).
virtual SocketAddress GetLocalAddress() const = 0;
// Returns remote address. Returns zeroes if this is not a client TCP socket.
virtual SocketAddress GetRemoteAddress() const = 0;
// Send a packet.
virtual int Send(const void *pv, size_t cb, const PacketOptions& options) = 0;
virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr,
const PacketOptions& options) = 0;
// Close the socket.
virtual int Close() = 0;
// Returns current state of the socket.
virtual State GetState() const = 0;
// Get/set options.
virtual int GetOption(Socket::Option opt, int* value) = 0;
virtual int SetOption(Socket::Option opt, int value) = 0;
// Get/Set current error.
// TODO: Remove SetError().
virtual int GetError() const = 0;
virtual void SetError(int error) = 0;
// Emitted each time a packet is read. Used only for UDP and
// connected TCP sockets.
sigslot::signal5<AsyncPacketSocket*, const char*, size_t,
const SocketAddress&,
const PacketTime&> SignalReadPacket;
// Emitted each time a packet is sent.
sigslot::signal2<AsyncPacketSocket*, const SentPacket&> SignalSentPacket;
// Emitted when the socket is currently able to send.
sigslot::signal1<AsyncPacketSocket*> SignalReadyToSend;
// Emitted after address for the socket is allocated, i.e. binding
// is finished. State of the socket is changed from BINDING to BOUND
// (for UDP and server TCP sockets) or CONNECTING (for client TCP
// sockets).
sigslot::signal2<AsyncPacketSocket*, const SocketAddress&> SignalAddressReady;
// Emitted for client TCP sockets when state is changed from
// CONNECTING to CONNECTED.
sigslot::signal1<AsyncPacketSocket*> SignalConnect;
// Emitted for client TCP sockets when state is changed from
// CONNECTED to CLOSED.
sigslot::signal2<AsyncPacketSocket*, int> SignalClose;
// Used only for listening TCP sockets.
sigslot::signal2<AsyncPacketSocket*, AsyncPacketSocket*> SignalNewConnection;
private:
RTC_DISALLOW_COPY_AND_ASSIGN(AsyncPacketSocket);
};
} // namespace rtc
#endif // WEBRTC_BASE_ASYNCPACKETSOCKET_H_

View File

@ -11,9 +11,37 @@
#ifndef WEBRTC_BASE_ASYNCRESOLVERINTERFACE_H_
#define WEBRTC_BASE_ASYNCRESOLVERINTERFACE_H_
#include "webrtc/base/sigslot.h"
#include "webrtc/base/socketaddress.h"
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/asyncresolverinterface.h"
namespace rtc {
// This interface defines the methods to resolve the address asynchronously.
class AsyncResolverInterface {
public:
AsyncResolverInterface();
virtual ~AsyncResolverInterface();
// Start address resolve process.
virtual void Start(const SocketAddress& addr) = 0;
// Returns top most resolved address of |family|
virtual bool GetResolvedAddress(int family, SocketAddress* addr) const = 0;
// Returns error from resolver.
virtual int GetError() const = 0;
// Delete the resolver.
virtual void Destroy(bool wait) = 0;
// Returns top most resolved IPv4 address if address is resolved successfully.
// Otherwise returns address set in SetAddress.
SocketAddress address() const {
SocketAddress addr;
GetResolvedAddress(AF_INET, &addr);
return addr;
}
// This signal is fired when address resolve process is completed.
sigslot::signal1<AsyncResolverInterface*> SignalDone;
};
} // namespace rtc
#endif

View File

@ -11,9 +11,73 @@
#ifndef WEBRTC_BASE_ASYNCSOCKET_H_
#define WEBRTC_BASE_ASYNCSOCKET_H_
#include "webrtc/base/sigslot.h"
#include "webrtc/base/socket.h"
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/asyncsocket.h"
namespace rtc {
// TODO: Remove Socket and rename AsyncSocket to Socket.
// Provides the ability to perform socket I/O asynchronously.
class AsyncSocket : public Socket {
public:
AsyncSocket();
~AsyncSocket() override;
AsyncSocket* Accept(SocketAddress* paddr) override = 0;
// SignalReadEvent and SignalWriteEvent use multi_threaded_local to allow
// access concurrently from different thread.
// For example SignalReadEvent::connect will be called in AsyncUDPSocket ctor
// but at the same time the SocketDispatcher maybe signaling the read event.
// ready to read
sigslot::signal1<AsyncSocket*,
sigslot::multi_threaded_local> SignalReadEvent;
// ready to write
sigslot::signal1<AsyncSocket*,
sigslot::multi_threaded_local> SignalWriteEvent;
sigslot::signal1<AsyncSocket*> SignalConnectEvent; // connected
sigslot::signal2<AsyncSocket*, int> SignalCloseEvent; // closed
};
class AsyncSocketAdapter : public AsyncSocket, public sigslot::has_slots<> {
public:
// The adapted socket may explicitly be null, and later assigned using Attach.
// However, subclasses which support detached mode must override any methods
// that will be called during the detached period (usually GetState()), to
// avoid dereferencing a null pointer.
explicit AsyncSocketAdapter(AsyncSocket* socket);
~AsyncSocketAdapter() override;
void Attach(AsyncSocket* socket);
SocketAddress GetLocalAddress() const override;
SocketAddress GetRemoteAddress() const override;
int Bind(const SocketAddress& addr) override;
int Connect(const SocketAddress& addr) override;
int Send(const void* pv, size_t cb) override;
int SendTo(const void* pv, size_t cb, const SocketAddress& addr) override;
int Recv(void* pv, size_t cb, int64_t* timestamp) override;
int RecvFrom(void* pv,
size_t cb,
SocketAddress* paddr,
int64_t* timestamp) override;
int Listen(int backlog) override;
AsyncSocket* Accept(SocketAddress* paddr) override;
int Close() override;
int GetError() const override;
void SetError(int error) override;
ConnState GetState() const override;
int GetOption(Option opt, int* value) override;
int SetOption(Option opt, int value) override;
protected:
virtual void OnConnectEvent(AsyncSocket* socket);
virtual void OnReadEvent(AsyncSocket* socket);
virtual void OnWriteEvent(AsyncSocket* socket);
virtual void OnCloseEvent(AsyncSocket* socket, int err);
AsyncSocket* socket_;
};
} // namespace rtc
#endif // WEBRTC_BASE_ASYNCSOCKET_H_

View File

@ -11,9 +11,98 @@
#ifndef WEBRTC_BASE_ASYNCTCPSOCKET_H_
#define WEBRTC_BASE_ASYNCTCPSOCKET_H_
#include <memory>
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/asynctcpsocket.h"
#include "webrtc/base/asyncpacketsocket.h"
#include "webrtc/base/buffer.h"
#include "webrtc/base/constructormagic.h"
#include "webrtc/base/socketfactory.h"
namespace rtc {
// Simulates UDP semantics over TCP. Send and Recv packet sizes
// are preserved, and drops packets silently on Send, rather than
// buffer them in user space.
class AsyncTCPSocketBase : public AsyncPacketSocket {
public:
AsyncTCPSocketBase(AsyncSocket* socket, bool listen, size_t max_packet_size);
~AsyncTCPSocketBase() override;
// Pure virtual methods to send and recv data.
int Send(const void *pv, size_t cb,
const rtc::PacketOptions& options) override = 0;
virtual void ProcessInput(char* data, size_t* len) = 0;
// Signals incoming connection.
virtual void HandleIncomingConnection(AsyncSocket* socket) = 0;
SocketAddress GetLocalAddress() const override;
SocketAddress GetRemoteAddress() const override;
int SendTo(const void* pv,
size_t cb,
const SocketAddress& addr,
const rtc::PacketOptions& options) override;
int Close() override;
State GetState() const override;
int GetOption(Socket::Option opt, int* value) override;
int SetOption(Socket::Option opt, int value) override;
int GetError() const override;
void SetError(int error) override;
protected:
// Binds and connects |socket| and creates AsyncTCPSocket for
// it. Takes ownership of |socket|. Returns null if bind() or
// connect() fail (|socket| is destroyed in that case).
static AsyncSocket* ConnectSocket(AsyncSocket* socket,
const SocketAddress& bind_address,
const SocketAddress& remote_address);
virtual int SendRaw(const void* pv, size_t cb);
int FlushOutBuffer();
// Add data to |outbuf_|.
void AppendToOutBuffer(const void* pv, size_t cb);
// Helper methods for |outpos_|.
bool IsOutBufferEmpty() const { return outbuf_.size() == 0; }
void ClearOutBuffer() { outbuf_.Clear(); }
private:
// Called by the underlying socket
void OnConnectEvent(AsyncSocket* socket);
void OnReadEvent(AsyncSocket* socket);
void OnWriteEvent(AsyncSocket* socket);
void OnCloseEvent(AsyncSocket* socket, int error);
std::unique_ptr<AsyncSocket> socket_;
bool listen_;
Buffer inbuf_;
Buffer outbuf_;
size_t max_insize_;
size_t max_outsize_;
RTC_DISALLOW_COPY_AND_ASSIGN(AsyncTCPSocketBase);
};
class AsyncTCPSocket : public AsyncTCPSocketBase {
public:
// Binds and connects |socket| and creates AsyncTCPSocket for
// it. Takes ownership of |socket|. Returns null if bind() or
// connect() fail (|socket| is destroyed in that case).
static AsyncTCPSocket* Create(AsyncSocket* socket,
const SocketAddress& bind_address,
const SocketAddress& remote_address);
AsyncTCPSocket(AsyncSocket* socket, bool listen);
~AsyncTCPSocket() override {}
int Send(const void* pv,
size_t cb,
const rtc::PacketOptions& options) override;
void ProcessInput(char* data, size_t* len) override;
void HandleIncomingConnection(AsyncSocket* socket) override;
private:
RTC_DISALLOW_COPY_AND_ASSIGN(AsyncTCPSocket);
};
} // namespace rtc
#endif // WEBRTC_BASE_ASYNCTCPSOCKET_H_

View File

@ -11,9 +11,57 @@
#ifndef WEBRTC_BASE_ASYNCUDPSOCKET_H_
#define WEBRTC_BASE_ASYNCUDPSOCKET_H_
#include <memory>
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/asyncudpsocket.h"
#include "webrtc/base/asyncpacketsocket.h"
#include "webrtc/base/socketfactory.h"
namespace rtc {
// Provides the ability to receive packets asynchronously. Sends are not
// buffered since it is acceptable to drop packets under high load.
class AsyncUDPSocket : public AsyncPacketSocket {
public:
// Binds |socket| and creates AsyncUDPSocket for it. Takes ownership
// of |socket|. Returns null if bind() fails (|socket| is destroyed
// in that case).
static AsyncUDPSocket* Create(AsyncSocket* socket,
const SocketAddress& bind_address);
// Creates a new socket for sending asynchronous UDP packets using an
// asynchronous socket from the given factory.
static AsyncUDPSocket* Create(SocketFactory* factory,
const SocketAddress& bind_address);
explicit AsyncUDPSocket(AsyncSocket* socket);
~AsyncUDPSocket() override;
SocketAddress GetLocalAddress() const override;
SocketAddress GetRemoteAddress() const override;
int Send(const void* pv,
size_t cb,
const rtc::PacketOptions& options) override;
int SendTo(const void* pv,
size_t cb,
const SocketAddress& addr,
const rtc::PacketOptions& options) override;
int Close() override;
State GetState() const override;
int GetOption(Socket::Option opt, int* value) override;
int SetOption(Socket::Option opt, int value) override;
int GetError() const override;
void SetError(int error) override;
private:
// Called when the underlying socket is ready to be read from.
void OnReadEvent(AsyncSocket* socket);
// Called when the underlying socket is ready to send.
void OnWriteEvent(AsyncSocket* socket);
std::unique_ptr<AsyncSocket> socket_;
char* buf_;
size_t size_;
};
} // namespace rtc
#endif // WEBRTC_BASE_ASYNCUDPSOCKET_H_

View File

@ -11,9 +11,77 @@
#ifndef WEBRTC_BASE_ATOMICOPS_H_
#define WEBRTC_BASE_ATOMICOPS_H_
#if defined(WEBRTC_WIN)
// Include winsock2.h before including <windows.h> to maintain consistency with
// win32.h. We can't include win32.h directly here since it pulls in
// headers such as basictypes.h which causes problems in Chromium where webrtc
// exists as two separate projects, webrtc and libjingle.
#include <winsock2.h>
#include <windows.h>
#endif // defined(WEBRTC_WIN)
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/atomicops.h"
namespace rtc {
class AtomicOps {
public:
#if defined(WEBRTC_WIN)
// Assumes sizeof(int) == sizeof(LONG), which it is on Win32 and Win64.
static int Increment(volatile int* i) {
return ::InterlockedIncrement(reinterpret_cast<volatile LONG*>(i));
}
static int Decrement(volatile int* i) {
return ::InterlockedDecrement(reinterpret_cast<volatile LONG*>(i));
}
static int AcquireLoad(volatile const int* i) {
return *i;
}
static void ReleaseStore(volatile int* i, int value) {
*i = value;
}
static int CompareAndSwap(volatile int* i, int old_value, int new_value) {
return ::InterlockedCompareExchange(reinterpret_cast<volatile LONG*>(i),
new_value,
old_value);
}
// Pointer variants.
template <typename T>
static T* AcquireLoadPtr(T* volatile* ptr) {
return *ptr;
}
template <typename T>
static T* CompareAndSwapPtr(T* volatile* ptr, T* old_value, T* new_value) {
return static_cast<T*>(::InterlockedCompareExchangePointer(
reinterpret_cast<PVOID volatile*>(ptr), new_value, old_value));
}
#else
static int Increment(volatile int* i) {
return __sync_add_and_fetch(i, 1);
}
static int Decrement(volatile int* i) {
return __sync_sub_and_fetch(i, 1);
}
static int AcquireLoad(volatile const int* i) {
return __atomic_load_n(i, __ATOMIC_ACQUIRE);
}
static void ReleaseStore(volatile int* i, int value) {
__atomic_store_n(i, value, __ATOMIC_RELEASE);
}
static int CompareAndSwap(volatile int* i, int old_value, int new_value) {
return __sync_val_compare_and_swap(i, old_value, new_value);
}
// Pointer variants.
template <typename T>
static T* AcquireLoadPtr(T* volatile* ptr) {
return __atomic_load_n(ptr, __ATOMIC_ACQUIRE);
}
template <typename T>
static T* CompareAndSwapPtr(T* volatile* ptr, T* old_value, T* new_value) {
return __sync_val_compare_and_swap(ptr, old_value, new_value);
}
#endif
};
}
#endif // WEBRTC_BASE_ATOMICOPS_H_

View File

@ -9,12 +9,115 @@
//* intact.
//*********************************************************************
#ifndef WEBRTC_BASE_BASE64_H_
#define WEBRTC_BASE_BASE64_H_
#ifndef WEBRTC_BASE_BASE64_H__
#define WEBRTC_BASE_BASE64_H__
#include <string>
#include <vector>
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/base64.h"
namespace rtc {
#endif // WEBRTC_BASE_BASE64_H_
class Base64 {
public:
enum DecodeOption {
DO_PARSE_STRICT = 1, // Parse only base64 characters
DO_PARSE_WHITE = 2, // Parse only base64 and whitespace characters
DO_PARSE_ANY = 3, // Parse all characters
DO_PARSE_MASK = 3,
DO_PAD_YES = 4, // Padding is required
DO_PAD_ANY = 8, // Padding is optional
DO_PAD_NO = 12, // Padding is disallowed
DO_PAD_MASK = 12,
DO_TERM_BUFFER = 16, // Must termiante at end of buffer
DO_TERM_CHAR = 32, // May terminate at any character boundary
DO_TERM_ANY = 48, // May terminate at a sub-character bit offset
DO_TERM_MASK = 48,
// Strictest interpretation
DO_STRICT = DO_PARSE_STRICT | DO_PAD_YES | DO_TERM_BUFFER,
DO_LAX = DO_PARSE_ANY | DO_PAD_ANY | DO_TERM_CHAR,
};
typedef int DecodeFlags;
static bool IsBase64Char(char ch);
// Get the char next to the |ch| from the Base64Table.
// If the |ch| is the last one in the Base64Table then returns
// the first one from the table.
// Expects the |ch| be a base64 char.
// The result will be saved in |next_ch|.
// Returns true on success.
static bool GetNextBase64Char(char ch, char* next_ch);
// Determines whether the given string consists entirely of valid base64
// encoded characters.
static bool IsBase64Encoded(const std::string& str);
static void EncodeFromArray(const void* data,
size_t len,
std::string* result);
static bool DecodeFromArray(const char* data,
size_t len,
DecodeFlags flags,
std::string* result,
size_t* data_used);
static bool DecodeFromArray(const char* data,
size_t len,
DecodeFlags flags,
std::vector<char>* result,
size_t* data_used);
static bool DecodeFromArray(const char* data,
size_t len,
DecodeFlags flags,
std::vector<uint8_t>* result,
size_t* data_used);
// Convenience Methods
static inline std::string Encode(const std::string& data) {
std::string result;
EncodeFromArray(data.data(), data.size(), &result);
return result;
}
static inline std::string Decode(const std::string& data, DecodeFlags flags) {
std::string result;
DecodeFromArray(data.data(), data.size(), flags, &result, nullptr);
return result;
}
static inline bool Decode(const std::string& data,
DecodeFlags flags,
std::string* result,
size_t* data_used) {
return DecodeFromArray(data.data(), data.size(), flags, result, data_used);
}
static inline bool Decode(const std::string& data,
DecodeFlags flags,
std::vector<char>* result,
size_t* data_used) {
return DecodeFromArray(data.data(), data.size(), flags, result, data_used);
}
private:
static const char Base64Table[];
static const unsigned char DecodeTable[];
static size_t GetNextQuantum(DecodeFlags parse_flags,
bool illegal_pads,
const char* data,
size_t len,
size_t* dpos,
unsigned char qbuf[4],
bool* padded);
template <typename T>
static bool DecodeFromArrayTemplate(const char* data,
size_t len,
DecodeFlags flags,
T* result,
size_t* data_used);
};
} // namespace rtc
#endif // WEBRTC_BASE_BASE64_H__

View File

@ -11,9 +11,60 @@
#ifndef WEBRTC_BASE_BASICTYPES_H_
#define WEBRTC_BASE_BASICTYPES_H_
#include <stddef.h> // for NULL, size_t
#include <stdint.h> // for uintptr_t and (u)int_t types.
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/basictypes.h"
// Detect compiler is for x86 or x64.
#if defined(__x86_64__) || defined(_M_X64) || \
defined(__i386__) || defined(_M_IX86)
#define CPU_X86 1
#endif
// Detect compiler is for arm.
#if defined(__arm__) || defined(_M_ARM)
#define CPU_ARM 1
#endif
#if defined(CPU_X86) && defined(CPU_ARM)
#error CPU_X86 and CPU_ARM both defined.
#endif
#if !defined(RTC_ARCH_CPU_BIG_ENDIAN) && !defined(RTC_ARCH_CPU_LITTLE_ENDIAN)
// x86, arm or GCC provided __BYTE_ORDER__ macros
#if defined(CPU_X86) || defined(CPU_ARM) || \
(defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
#define RTC_ARCH_CPU_LITTLE_ENDIAN
#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#define RTC_ARCH_CPU_BIG_ENDIAN
#else
#error RTC_ARCH_CPU_BIG_ENDIAN or RTC_ARCH_CPU_LITTLE_ENDIAN should be defined.
#endif
#endif
#if defined(RTC_ARCH_CPU_BIG_ENDIAN) && defined(RTC_ARCH_CPU_LITTLE_ENDIAN)
#error RTC_ARCH_CPU_BIG_ENDIAN and RTC_ARCH_CPU_LITTLE_ENDIAN both defined.
#endif
#if defined(WEBRTC_WIN)
typedef int socklen_t;
#endif
// The following only works for C++
#ifdef __cplusplus
#ifndef ALIGNP
#define ALIGNP(p, t) \
(reinterpret_cast<uint8_t*>(((reinterpret_cast<uintptr_t>(p) + \
((t) - 1)) & ~((t) - 1))))
#endif
#define RTC_IS_ALIGNED(p, a) (!((uintptr_t)(p) & ((a) - 1)))
// Use these to declare and define a static local variable that gets leaked so
// that its destructors are not called at exit.
#define RTC_DEFINE_STATIC_LOCAL(type, name, arguments) \
static type& name = *new type arguments
#endif // __cplusplus
#endif // WEBRTC_BASE_BASICTYPES_H_

View File

@ -61,9 +61,224 @@
#ifndef WEBRTC_BASE_BIND_H_
#define WEBRTC_BASE_BIND_H_
#include <tuple>
#include <type_traits>
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/bind.h"
#include "webrtc/base/scoped_ref_ptr.h"
#include "webrtc/base/template_util.h"
#define NONAME
namespace rtc {
namespace detail {
// This is needed because the template parameters in Bind can't be resolved
// if they're used both as parameters of the function pointer type and as
// parameters to Bind itself: the function pointer parameters are exact
// matches to the function prototype, but the parameters to bind have
// references stripped. This trick allows the compiler to dictate the Bind
// parameter types rather than deduce them.
template <class T> struct identity { typedef T type; };
// IsRefCounted<T>::value will be true for types that can be used in
// rtc::scoped_refptr<T>, i.e. types that implements nullary functions AddRef()
// and Release(), regardless of their return types. AddRef() and Release() can
// be defined in T or any superclass of T.
template <typename T>
class IsRefCounted {
// This is a complex implementation detail done with SFINAE.
// Define types such that sizeof(Yes) != sizeof(No).
struct Yes { char dummy[1]; };
struct No { char dummy[2]; };
// Define two overloaded template functions with return types of different
// size. This way, we can use sizeof() on the return type to determine which
// function the compiler would have chosen. One function will be preferred
// over the other if it is possible to create it without compiler errors,
// otherwise the compiler will simply remove it, and default to the less
// preferred function.
template <typename R>
static Yes test(R* r, decltype(r->AddRef(), r->Release(), 42));
template <typename C> static No test(...);
public:
// Trick the compiler to tell if it's possible to call AddRef() and Release().
static const bool value = sizeof(test<T>((T*)nullptr, 42)) == sizeof(Yes);
};
// TernaryTypeOperator is a helper class to select a type based on a static bool
// value.
template <bool condition, typename IfTrueT, typename IfFalseT>
struct TernaryTypeOperator {};
template <typename IfTrueT, typename IfFalseT>
struct TernaryTypeOperator<true, IfTrueT, IfFalseT> {
typedef IfTrueT type;
};
template <typename IfTrueT, typename IfFalseT>
struct TernaryTypeOperator<false, IfTrueT, IfFalseT> {
typedef IfFalseT type;
};
// PointerType<T>::type will be scoped_refptr<T> for ref counted types, and T*
// otherwise.
template <class T>
struct PointerType {
typedef typename TernaryTypeOperator<IsRefCounted<T>::value,
scoped_refptr<T>,
T*>::type type;
};
template <typename T>
class UnretainedWrapper {
public:
explicit UnretainedWrapper(T* o) : ptr_(o) {}
T* get() const { return ptr_; }
private:
T* ptr_;
};
} // namespace detail
template <typename T>
static inline detail::UnretainedWrapper<T> Unretained(T* o) {
return detail::UnretainedWrapper<T>(o);
}
template <class ObjectT, class MethodT, class R, typename... Args>
class MethodFunctor {
public:
MethodFunctor(MethodT method, ObjectT* object, Args... args)
: method_(method), object_(object), args_(args...) {}
R operator()() const {
return CallMethod(typename sequence_generator<sizeof...(Args)>::type());
}
private:
// Use sequence_generator (see template_util.h) to expand a MethodFunctor
// with 2 arguments to (std::get<0>(args_), std::get<1>(args_)), for
// instance.
template <int... S>
R CallMethod(sequence<S...>) const {
return (object_->*method_)(std::get<S>(args_)...);
}
MethodT method_;
typename detail::PointerType<ObjectT>::type object_;
typename std::tuple<typename std::remove_reference<Args>::type...> args_;
};
template <class ObjectT, class MethodT, class R, typename... Args>
class UnretainedMethodFunctor {
public:
UnretainedMethodFunctor(MethodT method,
detail::UnretainedWrapper<ObjectT> object,
Args... args)
: method_(method), object_(object.get()), args_(args...) {}
R operator()() const {
return CallMethod(typename sequence_generator<sizeof...(Args)>::type());
}
private:
// Use sequence_generator (see template_util.h) to expand an
// UnretainedMethodFunctor with 2 arguments to (std::get<0>(args_),
// std::get<1>(args_)), for instance.
template <int... S>
R CallMethod(sequence<S...>) const {
return (object_->*method_)(std::get<S>(args_)...);
}
MethodT method_;
ObjectT* object_;
typename std::tuple<typename std::remove_reference<Args>::type...> args_;
};
template <class FunctorT, class R, typename... Args>
class Functor {
public:
Functor(const FunctorT& functor, Args... args)
: functor_(functor), args_(args...) {}
R operator()() const {
return CallFunction(typename sequence_generator<sizeof...(Args)>::type());
}
private:
// Use sequence_generator (see template_util.h) to expand a Functor
// with 2 arguments to (std::get<0>(args_), std::get<1>(args_)), for
// instance.
template <int... S>
R CallFunction(sequence<S...>) const {
return functor_(std::get<S>(args_)...);
}
FunctorT functor_;
typename std::tuple<typename std::remove_reference<Args>::type...> args_;
};
#define FP_T(x) R (ObjectT::*x)(Args...)
template <class ObjectT, class R, typename... Args>
MethodFunctor<ObjectT, FP_T(NONAME), R, Args...> Bind(
FP_T(method),
ObjectT* object,
typename detail::identity<Args>::type... args) {
return MethodFunctor<ObjectT, FP_T(NONAME), R, Args...>(method, object,
args...);
}
template <class ObjectT, class R, typename... Args>
MethodFunctor<ObjectT, FP_T(NONAME), R, Args...> Bind(
FP_T(method),
const scoped_refptr<ObjectT>& object,
typename detail::identity<Args>::type... args) {
return MethodFunctor<ObjectT, FP_T(NONAME), R, Args...>(method, object.get(),
args...);
}
template <class ObjectT, class R, typename... Args>
UnretainedMethodFunctor<ObjectT, FP_T(NONAME), R, Args...> Bind(
FP_T(method),
detail::UnretainedWrapper<ObjectT> object,
typename detail::identity<Args>::type... args) {
return UnretainedMethodFunctor<ObjectT, FP_T(NONAME), R, Args...>(
method, object, args...);
}
#undef FP_T
#define FP_T(x) R (ObjectT::*x)(Args...) const
template <class ObjectT, class R, typename... Args>
MethodFunctor<const ObjectT, FP_T(NONAME), R, Args...> Bind(
FP_T(method),
const ObjectT* object,
typename detail::identity<Args>::type... args) {
return MethodFunctor<const ObjectT, FP_T(NONAME), R, Args...>(method, object,
args...);
}
template <class ObjectT, class R, typename... Args>
UnretainedMethodFunctor<const ObjectT, FP_T(NONAME), R, Args...> Bind(
FP_T(method),
detail::UnretainedWrapper<const ObjectT> object,
typename detail::identity<Args>::type... args) {
return UnretainedMethodFunctor<const ObjectT, FP_T(NONAME), R, Args...>(
method, object, args...);
}
#undef FP_T
#define FP_T(x) R (*x)(Args...)
template <class R, typename... Args>
Functor<FP_T(NONAME), R, Args...> Bind(
FP_T(function),
typename detail::identity<Args>::type... args) {
return Functor<FP_T(NONAME), R, Args...>(function, args...);
}
#undef FP_T
} // namespace rtc
#undef NONAME
#endif // WEBRTC_BASE_BIND_H_

View File

@ -11,9 +11,116 @@
#ifndef WEBRTC_BASE_BITBUFFER_H_
#define WEBRTC_BASE_BITBUFFER_H_
#include <stdint.h> // For integer types.
#include <stddef.h> // For size_t.
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/bitbuffer.h"
#include "webrtc/base/constructormagic.h"
namespace rtc {
// A class, similar to ByteBuffer, that can parse bit-sized data out of a set of
// bytes. Has a similar API to ByteBuffer, plus methods for reading bit-sized
// and exponential golomb encoded data. For a writable version, use
// BitBufferWriter. Unlike ByteBuffer, this class doesn't make a copy of the
// source bytes, so it can be used on read-only data.
// Sizes/counts specify bits/bytes, for clarity.
// Byte order is assumed big-endian/network.
class BitBuffer {
public:
BitBuffer(const uint8_t* bytes, size_t byte_count);
// Gets the current offset, in bytes/bits, from the start of the buffer. The
// bit offset is the offset into the current byte, in the range [0,7].
void GetCurrentOffset(size_t* out_byte_offset, size_t* out_bit_offset);
// The remaining bits in the byte buffer.
uint64_t RemainingBitCount() const;
// Reads byte-sized values from the buffer. Returns false if there isn't
// enough data left for the specified type.
bool ReadUInt8(uint8_t* val);
bool ReadUInt16(uint16_t* val);
bool ReadUInt32(uint32_t* val);
// Reads bit-sized values from the buffer. Returns false if there isn't enough
// data left for the specified bit count..
bool ReadBits(uint32_t* val, size_t bit_count);
// Peeks bit-sized values from the buffer. Returns false if there isn't enough
// data left for the specified number of bits. Doesn't move the current
// offset.
bool PeekBits(uint32_t* val, size_t bit_count);
// Reads the exponential golomb encoded value at the current offset.
// Exponential golomb values are encoded as:
// 1) x = source val + 1
// 2) In binary, write [countbits(x) - 1] 0s, then x
// To decode, we count the number of leading 0 bits, read that many + 1 bits,
// and increment the result by 1.
// Returns false if there isn't enough data left for the specified type, or if
// the value wouldn't fit in a uint32_t.
bool ReadExponentialGolomb(uint32_t* val);
// Reads signed exponential golomb values at the current offset. Signed
// exponential golomb values are just the unsigned values mapped to the
// sequence 0, 1, -1, 2, -2, etc. in order.
bool ReadSignedExponentialGolomb(int32_t* val);
// Moves current position |byte_count| bytes forward. Returns false if
// there aren't enough bytes left in the buffer.
bool ConsumeBytes(size_t byte_count);
// Moves current position |bit_count| bits forward. Returns false if
// there aren't enough bits left in the buffer.
bool ConsumeBits(size_t bit_count);
// Sets the current offset to the provied byte/bit offsets. The bit
// offset is from the given byte, in the range [0,7].
bool Seek(size_t byte_offset, size_t bit_offset);
protected:
const uint8_t* const bytes_;
// The total size of |bytes_|.
size_t byte_count_;
// The current offset, in bytes, from the start of |bytes_|.
size_t byte_offset_;
// The current offset, in bits, into the current byte.
size_t bit_offset_;
RTC_DISALLOW_COPY_AND_ASSIGN(BitBuffer);
};
// A BitBuffer API for write operations. Supports symmetric write APIs to the
// reading APIs of BitBuffer. Note that the read/write offset is shared with the
// BitBuffer API, so both reading and writing will consume bytes/bits.
class BitBufferWriter : public BitBuffer {
public:
// Constructs a bit buffer for the writable buffer of |bytes|.
BitBufferWriter(uint8_t* bytes, size_t byte_count);
// Writes byte-sized values from the buffer. Returns false if there isn't
// enough data left for the specified type.
bool WriteUInt8(uint8_t val);
bool WriteUInt16(uint16_t val);
bool WriteUInt32(uint32_t val);
// Writes bit-sized values to the buffer. Returns false if there isn't enough
// room left for the specified number of bits.
bool WriteBits(uint64_t val, size_t bit_count);
// Writes the exponential golomb encoded version of the supplied value.
// Returns false if there isn't enough room left for the value.
bool WriteExponentialGolomb(uint32_t val);
// Writes the signed exponential golomb version of the supplied value.
// Signed exponential golomb values are just the unsigned values mapped to the
// sequence 0, 1, -1, 2, -2, etc. in order.
bool WriteSignedExponentialGolomb(int32_t val);
private:
// The buffer, as a writable array.
uint8_t* const writable_bytes_;
RTC_DISALLOW_COPY_AND_ASSIGN(BitBufferWriter);
};
} // namespace rtc
#endif // WEBRTC_BASE_BITBUFFER_H_

View File

@ -11,8 +11,373 @@
#ifndef WEBRTC_BASE_BUFFER_H_
#define WEBRTC_BASE_BUFFER_H_
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/buffer.h"
#include <algorithm>
#include <cstring>
#include <memory>
#include <type_traits>
#include <utility>
#include "webrtc/base/array_view.h"
#include "webrtc/base/checks.h"
#include "webrtc/base/type_traits.h"
namespace rtc {
namespace internal {
// (Internal; please don't use outside this file.) Determines if elements of
// type U are compatible with a BufferT<T>. For most types, we just ignore
// top-level const and forbid top-level volatile and require T and U to be
// otherwise equal, but all byte-sized integers (notably char, int8_t, and
// uint8_t) are compatible with each other. (Note: We aim to get rid of this
// behavior, and treat all types the same.)
template <typename T, typename U>
struct BufferCompat {
static constexpr bool value =
!std::is_volatile<U>::value &&
((std::is_integral<T>::value && sizeof(T) == 1)
? (std::is_integral<U>::value && sizeof(U) == 1)
: (std::is_same<T, typename std::remove_const<U>::type>::value));
};
} // namespace internal
// Basic buffer class, can be grown and shrunk dynamically.
// Unlike std::string/vector, does not initialize data when increasing size.
template <typename T>
class BufferT {
// We want T's destructor and default constructor to be trivial, i.e. perform
// no action, so that we don't have to touch the memory we allocate and
// deallocate. And we want T to be trivially copyable, so that we can copy T
// instances with std::memcpy. This is precisely the definition of a trivial
// type.
static_assert(std::is_trivial<T>::value, "T must be a trivial type.");
// This class relies heavily on being able to mutate its data.
static_assert(!std::is_const<T>::value, "T may not be const");
public:
using value_type = T;
// An empty BufferT.
BufferT() : size_(0), capacity_(0), data_(nullptr) {
RTC_DCHECK(IsConsistent());
}
// Disable copy construction and copy assignment, since copying a buffer is
// expensive enough that we want to force the user to be explicit about it.
BufferT(const BufferT&) = delete;
BufferT& operator=(const BufferT&) = delete;
BufferT(BufferT&& buf)
: size_(buf.size()),
capacity_(buf.capacity()),
data_(std::move(buf.data_)) {
RTC_DCHECK(IsConsistent());
buf.OnMovedFrom();
}
// Construct a buffer with the specified number of uninitialized elements.
explicit BufferT(size_t size) : BufferT(size, size) {}
BufferT(size_t size, size_t capacity)
: size_(size),
capacity_(std::max(size, capacity)),
data_(new T[capacity_]) {
RTC_DCHECK(IsConsistent());
}
// Construct a buffer and copy the specified number of elements into it.
template <typename U,
typename std::enable_if<
internal::BufferCompat<T, U>::value>::type* = nullptr>
BufferT(const U* data, size_t size) : BufferT(data, size, size) {}
template <typename U,
typename std::enable_if<
internal::BufferCompat<T, U>::value>::type* = nullptr>
BufferT(U* data, size_t size, size_t capacity) : BufferT(size, capacity) {
static_assert(sizeof(T) == sizeof(U), "");
std::memcpy(data_.get(), data, size * sizeof(U));
}
// Construct a buffer from the contents of an array.
template <typename U,
size_t N,
typename std::enable_if<
internal::BufferCompat<T, U>::value>::type* = nullptr>
BufferT(U (&array)[N]) : BufferT(array, N) {}
// Get a pointer to the data. Just .data() will give you a (const) T*, but if
// T is a byte-sized integer, you may also use .data<U>() for any other
// byte-sized integer U.
template <typename U = T,
typename std::enable_if<
internal::BufferCompat<T, U>::value>::type* = nullptr>
const U* data() const {
RTC_DCHECK(IsConsistent());
return reinterpret_cast<U*>(data_.get());
}
template <typename U = T,
typename std::enable_if<
internal::BufferCompat<T, U>::value>::type* = nullptr>
U* data() {
RTC_DCHECK(IsConsistent());
return reinterpret_cast<U*>(data_.get());
}
bool empty() const {
RTC_DCHECK(IsConsistent());
return size_ == 0;
}
size_t size() const {
RTC_DCHECK(IsConsistent());
return size_;
}
size_t capacity() const {
RTC_DCHECK(IsConsistent());
return capacity_;
}
BufferT& operator=(BufferT&& buf) {
RTC_DCHECK(IsConsistent());
RTC_DCHECK(buf.IsConsistent());
size_ = buf.size_;
capacity_ = buf.capacity_;
data_ = std::move(buf.data_);
buf.OnMovedFrom();
return *this;
}
bool operator==(const BufferT& buf) const {
RTC_DCHECK(IsConsistent());
if (size_ != buf.size_) {
return false;
}
if (std::is_integral<T>::value) {
// Optimization.
return std::memcmp(data_.get(), buf.data_.get(), size_ * sizeof(T)) == 0;
}
for (size_t i = 0; i < size_; ++i) {
if (data_[i] != buf.data_[i]) {
return false;
}
}
return true;
}
bool operator!=(const BufferT& buf) const { return !(*this == buf); }
T& operator[](size_t index) {
RTC_DCHECK_LT(index, size_);
return data()[index];
}
T operator[](size_t index) const {
RTC_DCHECK_LT(index, size_);
return data()[index];
}
T* begin() { return data(); }
T* end() { return data() + size(); }
const T* begin() const { return data(); }
const T* end() const { return data() + size(); }
const T* cbegin() const { return data(); }
const T* cend() const { return data() + size(); }
// The SetData functions replace the contents of the buffer. They accept the
// same input types as the constructors.
template <typename U,
typename std::enable_if<
internal::BufferCompat<T, U>::value>::type* = nullptr>
void SetData(const U* data, size_t size) {
RTC_DCHECK(IsConsistent());
size_ = 0;
AppendData(data, size);
}
template <typename U,
size_t N,
typename std::enable_if<
internal::BufferCompat<T, U>::value>::type* = nullptr>
void SetData(const U (&array)[N]) {
SetData(array, N);
}
template <typename W,
typename std::enable_if<
HasDataAndSize<const W, const T>::value>::type* = nullptr>
void SetData(const W& w) {
SetData(w.data(), w.size());
}
// Replace the data in the buffer with at most |max_elements| of data, using
// the function |setter|, which should have the following signature:
// size_t setter(ArrayView<U> view)
// |setter| is given an appropriately typed ArrayView of the area in which to
// write the data (i.e. starting at the beginning of the buffer) and should
// return the number of elements actually written. This number must be <=
// |max_elements|.
template <typename U = T,
typename F,
typename std::enable_if<
internal::BufferCompat<T, U>::value>::type* = nullptr>
size_t SetData(size_t max_elements, F&& setter) {
RTC_DCHECK(IsConsistent());
size_ = 0;
return AppendData<U>(max_elements, std::forward<F>(setter));
}
// The AppendData functions add data to the end of the buffer. They accept
// the same input types as the constructors.
template <typename U,
typename std::enable_if<
internal::BufferCompat<T, U>::value>::type* = nullptr>
void AppendData(const U* data, size_t size) {
RTC_DCHECK(IsConsistent());
const size_t new_size = size_ + size;
EnsureCapacityWithHeadroom(new_size, true);
static_assert(sizeof(T) == sizeof(U), "");
std::memcpy(data_.get() + size_, data, size * sizeof(U));
size_ = new_size;
RTC_DCHECK(IsConsistent());
}
template <typename U,
size_t N,
typename std::enable_if<
internal::BufferCompat<T, U>::value>::type* = nullptr>
void AppendData(const U (&array)[N]) {
AppendData(array, N);
}
template <typename W,
typename std::enable_if<
HasDataAndSize<const W, const T>::value>::type* = nullptr>
void AppendData(const W& w) {
AppendData(w.data(), w.size());
}
template <typename U,
typename std::enable_if<
internal::BufferCompat<T, U>::value>::type* = nullptr>
void AppendData(const U& item) {
AppendData(&item, 1);
}
// Append at most |max_elements| to the end of the buffer, using the function
// |setter|, which should have the following signature:
// size_t setter(ArrayView<U> view)
// |setter| is given an appropriately typed ArrayView of the area in which to
// write the data (i.e. starting at the former end of the buffer) and should
// return the number of elements actually written. This number must be <=
// |max_elements|.
template <typename U = T,
typename F,
typename std::enable_if<
internal::BufferCompat<T, U>::value>::type* = nullptr>
size_t AppendData(size_t max_elements, F&& setter) {
RTC_DCHECK(IsConsistent());
const size_t old_size = size_;
SetSize(old_size + max_elements);
U* base_ptr = data<U>() + old_size;
size_t written_elements = setter(rtc::ArrayView<U>(base_ptr, max_elements));
RTC_CHECK_LE(written_elements, max_elements);
size_ = old_size + written_elements;
RTC_DCHECK(IsConsistent());
return written_elements;
}
// Sets the size of the buffer. If the new size is smaller than the old, the
// buffer contents will be kept but truncated; if the new size is greater,
// the existing contents will be kept and the new space will be
// uninitialized.
void SetSize(size_t size) {
EnsureCapacityWithHeadroom(size, true);
size_ = size;
}
// Ensure that the buffer size can be increased to at least capacity without
// further reallocation. (Of course, this operation might need to reallocate
// the buffer.)
void EnsureCapacity(size_t capacity) {
// Don't allocate extra headroom, since the user is asking for a specific
// capacity.
EnsureCapacityWithHeadroom(capacity, false);
}
// Resets the buffer to zero size without altering capacity. Works even if the
// buffer has been moved from.
void Clear() {
size_ = 0;
RTC_DCHECK(IsConsistent());
}
// Swaps two buffers. Also works for buffers that have been moved from.
friend void swap(BufferT& a, BufferT& b) {
using std::swap;
swap(a.size_, b.size_);
swap(a.capacity_, b.capacity_);
swap(a.data_, b.data_);
}
private:
void EnsureCapacityWithHeadroom(size_t capacity, bool extra_headroom) {
RTC_DCHECK(IsConsistent());
if (capacity <= capacity_)
return;
// If the caller asks for extra headroom, ensure that the new capacity is
// >= 1.5 times the old capacity. Any constant > 1 is sufficient to prevent
// quadratic behavior; as to why we pick 1.5 in particular, see
// https://github.com/facebook/folly/blob/master/folly/docs/FBVector.md and
// http://www.gahcep.com/cpp-internals-stl-vector-part-1/.
const size_t new_capacity =
extra_headroom ? std::max(capacity, capacity_ + capacity_ / 2)
: capacity;
std::unique_ptr<T[]> new_data(new T[new_capacity]);
std::memcpy(new_data.get(), data_.get(), size_ * sizeof(T));
data_ = std::move(new_data);
capacity_ = new_capacity;
RTC_DCHECK(IsConsistent());
}
// Precondition for all methods except Clear and the destructor.
// Postcondition for all methods except move construction and move
// assignment, which leave the moved-from object in a possibly inconsistent
// state.
bool IsConsistent() const {
return (data_ || capacity_ == 0) && capacity_ >= size_;
}
// Called when *this has been moved from. Conceptually it's a no-op, but we
// can mutate the state slightly to help subsequent sanity checks catch bugs.
void OnMovedFrom() {
#if RTC_DCHECK_IS_ON
// Make *this consistent and empty. Shouldn't be necessary, but better safe
// than sorry.
size_ = 0;
capacity_ = 0;
#else
// Ensure that *this is always inconsistent, to provoke bugs.
size_ = 1;
capacity_ = 0;
#endif
}
size_t size_;
size_t capacity_;
std::unique_ptr<T[]> data_;
};
// By far the most common sort of buffer.
using Buffer = BufferT<uint8_t>;
} // namespace rtc
#endif // WEBRTC_BASE_BUFFER_H_

View File

@ -11,9 +11,51 @@
#ifndef WEBRTC_BASE_BUFFERQUEUE_H_
#define WEBRTC_BASE_BUFFERQUEUE_H_
#include <deque>
#include <vector>
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/bufferqueue.h"
#include "webrtc/base/buffer.h"
#include "webrtc/base/constructormagic.h"
#include "webrtc/base/criticalsection.h"
namespace rtc {
class BufferQueue {
public:
// Creates a buffer queue with a given capacity and default buffer size.
BufferQueue(size_t capacity, size_t default_size);
virtual ~BufferQueue();
// Return number of queued buffers.
size_t size() const;
// Clear the BufferQueue by moving all Buffers from |queue_| to |free_list_|.
void Clear();
// ReadFront will only read one buffer at a time and will truncate buffers
// that don't fit in the passed memory.
// Returns true unless no data could be returned.
bool ReadFront(void* data, size_t bytes, size_t* bytes_read);
// WriteBack always writes either the complete memory or nothing.
// Returns true unless no data could be written.
bool WriteBack(const void* data, size_t bytes, size_t* bytes_written);
protected:
// These methods are called when the state of the queue changes.
virtual void NotifyReadableForTest() {}
virtual void NotifyWritableForTest() {}
private:
size_t capacity_;
size_t default_size_;
CriticalSection crit_;
std::deque<Buffer*> queue_ GUARDED_BY(crit_);
std::vector<Buffer*> free_list_ GUARDED_BY(crit_);
RTC_DISALLOW_COPY_AND_ASSIGN(BufferQueue);
};
} // namespace rtc
#endif // WEBRTC_BASE_BUFFERQUEUE_H_

View File

@ -11,9 +11,129 @@
#ifndef WEBRTC_BASE_BYTEBUFFER_H_
#define WEBRTC_BASE_BYTEBUFFER_H_
#include <string>
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/bytebuffer.h"
#include "webrtc/base/basictypes.h"
#include "webrtc/base/buffer.h"
#include "webrtc/base/constructormagic.h"
namespace rtc {
class ByteBuffer {
public:
enum ByteOrder {
ORDER_NETWORK = 0, // Default, use network byte order (big endian).
ORDER_HOST, // Use the native order of the host.
};
explicit ByteBuffer(ByteOrder byte_order) : byte_order_(byte_order) {}
ByteOrder Order() const { return byte_order_; }
private:
ByteOrder byte_order_;
RTC_DISALLOW_COPY_AND_ASSIGN(ByteBuffer);
};
class ByteBufferWriter : public ByteBuffer {
public:
// |byte_order| defines order of bytes in the buffer.
ByteBufferWriter();
explicit ByteBufferWriter(ByteOrder byte_order);
ByteBufferWriter(const char* bytes, size_t len);
ByteBufferWriter(const char* bytes, size_t len, ByteOrder byte_order);
~ByteBufferWriter();
const char* Data() const { return bytes_; }
size_t Length() const { return end_; }
size_t Capacity() const { return size_; }
// Write value to the buffer. Resizes the buffer when it is
// neccessary.
void WriteUInt8(uint8_t val);
void WriteUInt16(uint16_t val);
void WriteUInt24(uint32_t val);
void WriteUInt32(uint32_t val);
void WriteUInt64(uint64_t val);
void WriteUVarint(uint64_t val);
void WriteString(const std::string& val);
void WriteBytes(const char* val, size_t len);
// Reserves the given number of bytes and returns a char* that can be written
// into. Useful for functions that require a char* buffer and not a
// ByteBufferWriter.
char* ReserveWriteBuffer(size_t len);
// Resize the buffer to the specified |size|.
void Resize(size_t size);
// Clears the contents of the buffer. After this, Length() will be 0.
void Clear();
private:
void Construct(const char* bytes, size_t size);
char* bytes_;
size_t size_;
size_t end_;
// There are sensible ways to define these, but they aren't needed in our code
// base.
RTC_DISALLOW_COPY_AND_ASSIGN(ByteBufferWriter);
};
// The ByteBufferReader references the passed data, i.e. the pointer must be
// valid during the lifetime of the reader.
class ByteBufferReader : public ByteBuffer {
public:
ByteBufferReader(const char* bytes, size_t len);
ByteBufferReader(const char* bytes, size_t len, ByteOrder byte_order);
// Initializes buffer from a zero-terminated string.
explicit ByteBufferReader(const char* bytes);
explicit ByteBufferReader(const Buffer& buf);
explicit ByteBufferReader(const ByteBufferWriter& buf);
// Returns start of unprocessed data.
const char* Data() const { return bytes_ + start_; }
// Returns number of unprocessed bytes.
size_t Length() const { return end_ - start_; }
// Read a next value from the buffer. Return false if there isn't
// enough data left for the specified type.
bool ReadUInt8(uint8_t* val);
bool ReadUInt16(uint16_t* val);
bool ReadUInt24(uint32_t* val);
bool ReadUInt32(uint32_t* val);
bool ReadUInt64(uint64_t* val);
bool ReadUVarint(uint64_t* val);
bool ReadBytes(char* val, size_t len);
// Appends next |len| bytes from the buffer to |val|. Returns false
// if there is less than |len| bytes left.
bool ReadString(std::string* val, size_t len);
// Moves current position |size| bytes forward. Returns false if
// there is less than |size| bytes left in the buffer. Consume doesn't
// permanently remove data, so remembered read positions are still valid
// after this call.
bool Consume(size_t size);
private:
void Construct(const char* bytes, size_t size);
const char* bytes_;
size_t size_;
size_t start_;
size_t end_;
RTC_DISALLOW_COPY_AND_ASSIGN(ByteBufferReader);
};
} // namespace rtc
#endif // WEBRTC_BASE_BYTEBUFFER_H_

View File

@ -11,9 +11,168 @@
#ifndef WEBRTC_BASE_BYTEORDER_H_
#define WEBRTC_BASE_BYTEORDER_H_
#if defined(WEBRTC_POSIX) && !defined(__native_client__)
#include <arpa/inet.h>
#endif
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/byteorder.h"
#include "webrtc/base/basictypes.h"
#if defined(WEBRTC_MAC)
#include <libkern/OSByteOrder.h>
#define htobe16(v) OSSwapHostToBigInt16(v)
#define htobe32(v) OSSwapHostToBigInt32(v)
#define htobe64(v) OSSwapHostToBigInt64(v)
#define be16toh(v) OSSwapBigToHostInt16(v)
#define be32toh(v) OSSwapBigToHostInt32(v)
#define be64toh(v) OSSwapBigToHostInt64(v)
#define htole16(v) OSSwapHostToLittleInt16(v)
#define htole32(v) OSSwapHostToLittleInt32(v)
#define htole64(v) OSSwapHostToLittleInt64(v)
#define le16toh(v) OSSwapLittleToHostInt16(v)
#define le32toh(v) OSSwapLittleToHostInt32(v)
#define le64toh(v) OSSwapLittleToHostInt64(v)
#elif defined(WEBRTC_WIN) || defined(__native_client__)
#if defined(WEBRTC_WIN)
#include <stdlib.h>
#include <winsock2.h>
#else
#include <netinet/in.h>
#endif
#define htobe16(v) htons(v)
#define htobe32(v) htonl(v)
#define be16toh(v) ntohs(v)
#define be32toh(v) ntohl(v)
#if defined(WEBRTC_WIN)
#define htobe64(v) htonll(v)
#define be64toh(v) ntohll(v)
#endif
#if defined(RTC_ARCH_CPU_LITTLE_ENDIAN)
#define htole16(v) (v)
#define htole32(v) (v)
#define htole64(v) (v)
#define le16toh(v) (v)
#define le32toh(v) (v)
#define le64toh(v) (v)
#if defined(__native_client__)
#define htobe64(v) __builtin_bswap64(v)
#define be64toh(v) __builtin_bswap64(v)
#endif
#elif defined(RTC_ARCH_CPU_BIG_ENDIAN)
#define htole16(v) __builtin_bswap16(v)
#define htole32(v) __builtin_bswap32(v)
#define htole64(v) __builtin_bswap64(v)
#define le16toh(v) __builtin_bswap16(v)
#define le32toh(v) __builtin_bswap32(v)
#define le64toh(v) __builtin_bswap64(v)
#if defined(__native_client__)
#define htobe64(v) (v)
#define be64toh(v) (v)
#endif
#else
#error RTC_ARCH_CPU_BIG_ENDIAN or RTC_ARCH_CPU_LITTLE_ENDIAN must be defined.
#endif // defined(RTC_ARCH_CPU_LITTLE_ENDIAN)
#elif defined(WEBRTC_POSIX)
#include <endian.h>
#endif
namespace rtc {
// Reading and writing of little and big-endian numbers from memory
inline void Set8(void* memory, size_t offset, uint8_t v) {
static_cast<uint8_t*>(memory)[offset] = v;
}
inline uint8_t Get8(const void* memory, size_t offset) {
return static_cast<const uint8_t*>(memory)[offset];
}
inline void SetBE16(void* memory, uint16_t v) {
*static_cast<uint16_t*>(memory) = htobe16(v);
}
inline void SetBE32(void* memory, uint32_t v) {
*static_cast<uint32_t*>(memory) = htobe32(v);
}
inline void SetBE64(void* memory, uint64_t v) {
*static_cast<uint64_t*>(memory) = htobe64(v);
}
inline uint16_t GetBE16(const void* memory) {
return be16toh(*static_cast<const uint16_t*>(memory));
}
inline uint32_t GetBE32(const void* memory) {
return be32toh(*static_cast<const uint32_t*>(memory));
}
inline uint64_t GetBE64(const void* memory) {
return be64toh(*static_cast<const uint64_t*>(memory));
}
inline void SetLE16(void* memory, uint16_t v) {
*static_cast<uint16_t*>(memory) = htole16(v);
}
inline void SetLE32(void* memory, uint32_t v) {
*static_cast<uint32_t*>(memory) = htole32(v);
}
inline void SetLE64(void* memory, uint64_t v) {
*static_cast<uint64_t*>(memory) = htole64(v);
}
inline uint16_t GetLE16(const void* memory) {
return le16toh(*static_cast<const uint16_t*>(memory));
}
inline uint32_t GetLE32(const void* memory) {
return le32toh(*static_cast<const uint32_t*>(memory));
}
inline uint64_t GetLE64(const void* memory) {
return le64toh(*static_cast<const uint64_t*>(memory));
}
// Check if the current host is big endian.
inline bool IsHostBigEndian() {
#if defined(RTC_ARCH_CPU_BIG_ENDIAN)
return true;
#else
return false;
#endif
}
inline uint16_t HostToNetwork16(uint16_t n) {
return htobe16(n);
}
inline uint32_t HostToNetwork32(uint32_t n) {
return htobe32(n);
}
inline uint64_t HostToNetwork64(uint64_t n) {
return htobe64(n);
}
inline uint16_t NetworkToHost16(uint16_t n) {
return be16toh(n);
}
inline uint32_t NetworkToHost32(uint32_t n) {
return be32toh(n);
}
inline uint64_t NetworkToHost64(uint64_t n) {
return be64toh(n);
}
} // namespace rtc
#endif // WEBRTC_BASE_BYTEORDER_H_

View File

@ -62,9 +62,199 @@
#ifndef WEBRTC_BASE_CALLBACK_H_
#define WEBRTC_BASE_CALLBACK_H_
#include "webrtc/base/refcount.h"
#include "webrtc/base/scoped_ref_ptr.h"
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/callback.h"
namespace rtc {
template <class R>
class Callback0 {
public:
// Default copy operations are appropriate for this class.
Callback0() {}
template <class T> Callback0(const T& functor)
: helper_(new RefCountedObject< HelperImpl<T> >(functor)) {}
R operator()() {
if (empty())
return R();
return helper_->Run();
}
bool empty() const { return !helper_; }
private:
struct Helper : RefCountInterface {
virtual ~Helper() {}
virtual R Run() = 0;
};
template <class T> struct HelperImpl : Helper {
explicit HelperImpl(const T& functor) : functor_(functor) {}
virtual R Run() {
return functor_();
}
T functor_;
};
scoped_refptr<Helper> helper_;
};
template <class R,
class P1>
class Callback1 {
public:
// Default copy operations are appropriate for this class.
Callback1() {}
template <class T> Callback1(const T& functor)
: helper_(new RefCountedObject< HelperImpl<T> >(functor)) {}
R operator()(P1 p1) {
if (empty())
return R();
return helper_->Run(p1);
}
bool empty() const { return !helper_; }
private:
struct Helper : RefCountInterface {
virtual ~Helper() {}
virtual R Run(P1 p1) = 0;
};
template <class T> struct HelperImpl : Helper {
explicit HelperImpl(const T& functor) : functor_(functor) {}
virtual R Run(P1 p1) {
return functor_(p1);
}
T functor_;
};
scoped_refptr<Helper> helper_;
};
template <class R,
class P1,
class P2>
class Callback2 {
public:
// Default copy operations are appropriate for this class.
Callback2() {}
template <class T> Callback2(const T& functor)
: helper_(new RefCountedObject< HelperImpl<T> >(functor)) {}
R operator()(P1 p1, P2 p2) {
if (empty())
return R();
return helper_->Run(p1, p2);
}
bool empty() const { return !helper_; }
private:
struct Helper : RefCountInterface {
virtual ~Helper() {}
virtual R Run(P1 p1, P2 p2) = 0;
};
template <class T> struct HelperImpl : Helper {
explicit HelperImpl(const T& functor) : functor_(functor) {}
virtual R Run(P1 p1, P2 p2) {
return functor_(p1, p2);
}
T functor_;
};
scoped_refptr<Helper> helper_;
};
template <class R,
class P1,
class P2,
class P3>
class Callback3 {
public:
// Default copy operations are appropriate for this class.
Callback3() {}
template <class T> Callback3(const T& functor)
: helper_(new RefCountedObject< HelperImpl<T> >(functor)) {}
R operator()(P1 p1, P2 p2, P3 p3) {
if (empty())
return R();
return helper_->Run(p1, p2, p3);
}
bool empty() const { return !helper_; }
private:
struct Helper : RefCountInterface {
virtual ~Helper() {}
virtual R Run(P1 p1, P2 p2, P3 p3) = 0;
};
template <class T> struct HelperImpl : Helper {
explicit HelperImpl(const T& functor) : functor_(functor) {}
virtual R Run(P1 p1, P2 p2, P3 p3) {
return functor_(p1, p2, p3);
}
T functor_;
};
scoped_refptr<Helper> helper_;
};
template <class R,
class P1,
class P2,
class P3,
class P4>
class Callback4 {
public:
// Default copy operations are appropriate for this class.
Callback4() {}
template <class T> Callback4(const T& functor)
: helper_(new RefCountedObject< HelperImpl<T> >(functor)) {}
R operator()(P1 p1, P2 p2, P3 p3, P4 p4) {
if (empty())
return R();
return helper_->Run(p1, p2, p3, p4);
}
bool empty() const { return !helper_; }
private:
struct Helper : RefCountInterface {
virtual ~Helper() {}
virtual R Run(P1 p1, P2 p2, P3 p3, P4 p4) = 0;
};
template <class T> struct HelperImpl : Helper {
explicit HelperImpl(const T& functor) : functor_(functor) {}
virtual R Run(P1 p1, P2 p2, P3 p3, P4 p4) {
return functor_(p1, p2, p3, p4);
}
T functor_;
};
scoped_refptr<Helper> helper_;
};
template <class R,
class P1,
class P2,
class P3,
class P4,
class P5>
class Callback5 {
public:
// Default copy operations are appropriate for this class.
Callback5() {}
template <class T> Callback5(const T& functor)
: helper_(new RefCountedObject< HelperImpl<T> >(functor)) {}
R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
if (empty())
return R();
return helper_->Run(p1, p2, p3, p4, p5);
}
bool empty() const { return !helper_; }
private:
struct Helper : RefCountInterface {
virtual ~Helper() {}
virtual R Run(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) = 0;
};
template <class T> struct HelperImpl : Helper {
explicit HelperImpl(const T& functor) : functor_(functor) {}
virtual R Run(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
return functor_(p1, p2, p3, p4, p5);
}
T functor_;
};
scoped_refptr<Helper> helper_;
};
} // namespace rtc
#endif // WEBRTC_BASE_CALLBACK_H_

View File

@ -54,8 +54,8 @@
// my_callback = Callback1<int, int>();
// cout << my_callback.empty() << endl; // true
#ifndef WEBRTC_RTC_BASE_CALLBACK_H_
#define WEBRTC_RTC_BASE_CALLBACK_H_
#ifndef WEBRTC_BASE_CALLBACK_H_
#define WEBRTC_BASE_CALLBACK_H_
#include "webrtc/base/refcount.h"
#include "webrtc/base/scoped_ref_ptr.h"
@ -100,4 +100,4 @@ class Callback$i {
]]
} // namespace rtc
#endif // WEBRTC_RTC_BASE_CALLBACK_H_
#endif // WEBRTC_BASE_CALLBACK_H_

View File

@ -11,9 +11,279 @@
#ifndef WEBRTC_BASE_CHECKS_H_
#define WEBRTC_BASE_CHECKS_H_
#include "webrtc/typedefs.h"
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/checks.h"
// If you for some reson need to know if DCHECKs are on, test the value of
// RTC_DCHECK_IS_ON. (Test its value, not if it's defined; it'll always be
// defined, to either a true or a false value.)
#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
#define RTC_DCHECK_IS_ON 1
#else
#define RTC_DCHECK_IS_ON 0
#endif
#ifdef __cplusplus
extern "C" {
#endif
NO_RETURN void rtc_FatalMessage(const char* file, int line, const char* msg);
#ifdef __cplusplus
} // extern "C"
#endif
#ifdef __cplusplus
// C++ version.
#include <sstream>
#include <string>
#include "webrtc/base/safe_compare.h"
// The macros here print a message to stderr and abort under various
// conditions. All will accept additional stream messages. For example:
// RTC_DCHECK_EQ(foo, bar) << "I'm printed when foo != bar.";
//
// - RTC_CHECK(x) is an assertion that x is always true, and that if it isn't,
// it's better to terminate the process than to continue. During development,
// the reason that it's better to terminate might simply be that the error
// handling code isn't in place yet; in production, the reason might be that
// the author of the code truly believes that x will always be true, but that
// she recognizes that if she is wrong, abrupt and unpleasant process
// termination is still better than carrying on with the assumption violated.
//
// RTC_CHECK always evaluates its argument, so it's OK for x to have side
// effects.
//
// - RTC_DCHECK(x) is the same as RTC_CHECK(x)---an assertion that x is always
// true---except that x will only be evaluated in debug builds; in production
// builds, x is simply assumed to be true. This is useful if evaluating x is
// expensive and the expected cost of failing to detect the violated
// assumption is acceptable. You should not handle cases where a production
// build fails to spot a violated condition, even those that would result in
// crashes. If the code needs to cope with the error, make it cope, but don't
// call RTC_DCHECK; if the condition really can't occur, but you'd sleep
// better at night knowing that the process will suicide instead of carrying
// on in case you were wrong, use RTC_CHECK instead of RTC_DCHECK.
//
// RTC_DCHECK only evaluates its argument in debug builds, so if x has visible
// side effects, you need to write e.g.
// bool w = x; RTC_DCHECK(w);
//
// - RTC_CHECK_EQ, _NE, _GT, ..., and RTC_DCHECK_EQ, _NE, _GT, ... are
// specialized variants of RTC_CHECK and RTC_DCHECK that print prettier
// messages if the condition doesn't hold. Prefer them to raw RTC_CHECK and
// RTC_DCHECK.
//
// - FATAL() aborts unconditionally.
//
// TODO(ajm): Ideally, checks.h would be combined with logging.h, but
// consolidation with system_wrappers/logging.h should happen first.
namespace rtc {
// Helper macro which avoids evaluating the arguments to a stream if
// the condition doesn't hold.
#define RTC_LAZY_STREAM(stream, condition) \
!(condition) ? static_cast<void>(0) : rtc::FatalMessageVoidify() & (stream)
// The actual stream used isn't important. We reference |ignored| in the code
// but don't evaluate it; this is to avoid "unused variable" warnings (we do so
// in a particularly convoluted way with an extra ?: because that appears to be
// the simplest construct that keeps Visual Studio from complaining about
// condition being unused).
#define RTC_EAT_STREAM_PARAMETERS(ignored) \
(true ? true : ((void)(ignored), true)) \
? static_cast<void>(0) \
: rtc::FatalMessageVoidify() & rtc::FatalMessage("", 0).stream()
// Call RTC_EAT_STREAM_PARAMETERS with an argument that fails to compile if
// values of the same types as |a| and |b| can't be compared with the given
// operation, and that would evaluate |a| and |b| if evaluated.
#define RTC_EAT_STREAM_PARAMETERS_OP(op, a, b) \
RTC_EAT_STREAM_PARAMETERS(((void)rtc::Safe##op(a, b)))
// RTC_CHECK dies with a fatal error if condition is not true. It is *not*
// controlled by NDEBUG or anything else, so the check will be executed
// regardless of compilation mode.
//
// We make sure RTC_CHECK et al. always evaluates their arguments, as
// doing RTC_CHECK(FunctionWithSideEffect()) is a common idiom.
#define RTC_CHECK(condition) \
RTC_LAZY_STREAM(rtc::FatalMessage(__FILE__, __LINE__).stream(), \
!(condition)) \
<< "Check failed: " #condition << std::endl << "# "
// Helper macro for binary operators.
// Don't use this macro directly in your code, use RTC_CHECK_EQ et al below.
//
// TODO(akalin): Rewrite this so that constructs like if (...)
// RTC_CHECK_EQ(...) else { ... } work properly.
#define RTC_CHECK_OP(name, op, val1, val2) \
if (std::string* _result = \
rtc::Check##name##Impl((val1), (val2), #val1 " " #op " " #val2)) \
rtc::FatalMessage(__FILE__, __LINE__, _result).stream()
// Build the error message string. This is separate from the "Impl"
// function template because it is not performance critical and so can
// be out of line, while the "Impl" code should be inline. Caller
// takes ownership of the returned string.
template<class t1, class t2>
std::string* MakeCheckOpString(const t1& v1, const t2& v2, const char* names) {
std::ostringstream ss;
ss << names << " (" << v1 << " vs. " << v2 << ")";
std::string* msg = new std::string(ss.str());
return msg;
}
// MSVC doesn't like complex extern templates and DLLs.
#if !defined(COMPILER_MSVC)
// Commonly used instantiations of MakeCheckOpString<>. Explicitly instantiated
// in logging.cc.
extern template std::string* MakeCheckOpString<int, int>(
const int&, const int&, const char* names);
extern template
std::string* MakeCheckOpString<unsigned long, unsigned long>(
const unsigned long&, const unsigned long&, const char* names);
extern template
std::string* MakeCheckOpString<unsigned long, unsigned int>(
const unsigned long&, const unsigned int&, const char* names);
extern template
std::string* MakeCheckOpString<unsigned int, unsigned long>(
const unsigned int&, const unsigned long&, const char* names);
extern template
std::string* MakeCheckOpString<std::string, std::string>(
const std::string&, const std::string&, const char* name);
#endif
// Helper functions for RTC_CHECK_OP macro.
// The (int, int) specialization works around the issue that the compiler
// will not instantiate the template version of the function on values of
// unnamed enum type - see comment below.
#define DEFINE_RTC_CHECK_OP_IMPL(name) \
template <class t1, class t2> \
inline std::string* Check##name##Impl(const t1& v1, const t2& v2, \
const char* names) { \
if (rtc::Safe##name(v1, v2)) \
return nullptr; \
else \
return rtc::MakeCheckOpString(v1, v2, names); \
} \
inline std::string* Check##name##Impl(int v1, int v2, const char* names) { \
if (rtc::Safe##name(v1, v2)) \
return nullptr; \
else \
return rtc::MakeCheckOpString(v1, v2, names); \
}
DEFINE_RTC_CHECK_OP_IMPL(Eq)
DEFINE_RTC_CHECK_OP_IMPL(Ne)
DEFINE_RTC_CHECK_OP_IMPL(Le)
DEFINE_RTC_CHECK_OP_IMPL(Lt)
DEFINE_RTC_CHECK_OP_IMPL(Ge)
DEFINE_RTC_CHECK_OP_IMPL(Gt)
#undef DEFINE_RTC_CHECK_OP_IMPL
#define RTC_CHECK_EQ(val1, val2) RTC_CHECK_OP(Eq, ==, val1, val2)
#define RTC_CHECK_NE(val1, val2) RTC_CHECK_OP(Ne, !=, val1, val2)
#define RTC_CHECK_LE(val1, val2) RTC_CHECK_OP(Le, <=, val1, val2)
#define RTC_CHECK_LT(val1, val2) RTC_CHECK_OP(Lt, <, val1, val2)
#define RTC_CHECK_GE(val1, val2) RTC_CHECK_OP(Ge, >=, val1, val2)
#define RTC_CHECK_GT(val1, val2) RTC_CHECK_OP(Gt, >, val1, val2)
// The RTC_DCHECK macro is equivalent to RTC_CHECK except that it only generates
// code in debug builds. It does reference the condition parameter in all cases,
// though, so callers won't risk getting warnings about unused variables.
#if RTC_DCHECK_IS_ON
#define RTC_DCHECK(condition) RTC_CHECK(condition)
#define RTC_DCHECK_EQ(v1, v2) RTC_CHECK_EQ(v1, v2)
#define RTC_DCHECK_NE(v1, v2) RTC_CHECK_NE(v1, v2)
#define RTC_DCHECK_LE(v1, v2) RTC_CHECK_LE(v1, v2)
#define RTC_DCHECK_LT(v1, v2) RTC_CHECK_LT(v1, v2)
#define RTC_DCHECK_GE(v1, v2) RTC_CHECK_GE(v1, v2)
#define RTC_DCHECK_GT(v1, v2) RTC_CHECK_GT(v1, v2)
#else
#define RTC_DCHECK(condition) RTC_EAT_STREAM_PARAMETERS(condition)
#define RTC_DCHECK_EQ(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Eq, v1, v2)
#define RTC_DCHECK_NE(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Ne, v1, v2)
#define RTC_DCHECK_LE(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Le, v1, v2)
#define RTC_DCHECK_LT(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Lt, v1, v2)
#define RTC_DCHECK_GE(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Ge, v1, v2)
#define RTC_DCHECK_GT(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Gt, v1, v2)
#endif
// This is identical to LogMessageVoidify but in name.
class FatalMessageVoidify {
public:
FatalMessageVoidify() { }
// This has to be an operator with a precedence lower than << but
// higher than ?:
void operator&(std::ostream&) { }
};
#define RTC_UNREACHABLE_CODE_HIT false
#define RTC_NOTREACHED() RTC_DCHECK(RTC_UNREACHABLE_CODE_HIT)
#define FATAL() rtc::FatalMessage(__FILE__, __LINE__).stream()
// TODO(ajm): Consider adding RTC_NOTIMPLEMENTED macro when
// base/logging.h and system_wrappers/logging.h are consolidated such that we
// can match the Chromium behavior.
// Like a stripped-down LogMessage from logging.h, except that it aborts.
class FatalMessage {
public:
FatalMessage(const char* file, int line);
// Used for RTC_CHECK_EQ(), etc. Takes ownership of the given string.
FatalMessage(const char* file, int line, std::string* result);
NO_RETURN ~FatalMessage();
std::ostream& stream() { return stream_; }
private:
void Init(const char* file, int line);
std::ostringstream stream_;
};
// Performs the integer division a/b and returns the result. CHECKs that the
// remainder is zero.
template <typename T>
inline T CheckedDivExact(T a, T b) {
RTC_CHECK_EQ(a % b, 0) << a << " is not evenly divisible by " << b;
return a / b;
}
} // namespace rtc
#else // __cplusplus not defined
// C version. Lacks many features compared to the C++ version, but usage
// guidelines are the same.
#define RTC_CHECK(condition) \
do { \
if (!(condition)) { \
rtc_FatalMessage(__FILE__, __LINE__, "CHECK failed: " #condition); \
} \
} while (0)
#define RTC_CHECK_EQ(a, b) RTC_CHECK((a) == (b))
#define RTC_CHECK_NE(a, b) RTC_CHECK((a) != (b))
#define RTC_CHECK_LE(a, b) RTC_CHECK((a) <= (b))
#define RTC_CHECK_LT(a, b) RTC_CHECK((a) < (b))
#define RTC_CHECK_GE(a, b) RTC_CHECK((a) >= (b))
#define RTC_CHECK_GT(a, b) RTC_CHECK((a) > (b))
#define RTC_DCHECK(condition) \
do { \
if (RTC_DCHECK_IS_ON && !(condition)) { \
rtc_FatalMessage(__FILE__, __LINE__, "DCHECK failed: " #condition); \
} \
} while (0)
#define RTC_DCHECK_EQ(a, b) RTC_DCHECK((a) == (b))
#define RTC_DCHECK_NE(a, b) RTC_DCHECK((a) != (b))
#define RTC_DCHECK_LE(a, b) RTC_DCHECK((a) <= (b))
#define RTC_DCHECK_LT(a, b) RTC_DCHECK((a) < (b))
#define RTC_DCHECK_GE(a, b) RTC_DCHECK((a) >= (b))
#define RTC_DCHECK_GT(a, b) RTC_DCHECK((a) > (b))
#endif // __cplusplus
#endif // WEBRTC_BASE_CHECKS_H_

View File

@ -11,8 +11,11 @@
#ifndef WEBRTC_BASE_COMPILE_ASSERT_C_H_
#define WEBRTC_BASE_COMPILE_ASSERT_C_H_
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/compile_assert_c.h"
// Use this macro to verify at compile time that certain restrictions are met.
// The argument is the boolean expression to evaluate.
// Example:
// RTC_COMPILE_ASSERT(sizeof(foo) < 128);
// Note: In C++, use static_assert instead!
#define RTC_COMPILE_ASSERT(expression) switch (0) {case 0: case expression:;}
#endif // WEBRTC_BASE_COMPILE_ASSERT_C_H_

View File

@ -11,9 +11,24 @@
#ifndef WEBRTC_BASE_CONSTRUCTORMAGIC_H_
#define WEBRTC_BASE_CONSTRUCTORMAGIC_H_
// Put this in the declarations for a class to be unassignable.
#define RTC_DISALLOW_ASSIGN(TypeName) \
void operator=(const TypeName&) = delete
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/constructormagic.h"
// A macro to disallow the copy constructor and operator= functions. This should
// be used in the declarations for a class.
#define RTC_DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&) = delete; \
RTC_DISALLOW_ASSIGN(TypeName)
// A macro to disallow all the implicit constructors, namely the default
// constructor, copy constructor and operator= functions.
//
// This should be used in the declarations for a class that wants to prevent
// anyone from instantiating it. This is especially useful for classes
// containing only static methods.
#define RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
TypeName() = delete; \
RTC_DISALLOW_COPY_AND_ASSIGN(TypeName)
#endif // WEBRTC_BASE_CONSTRUCTORMAGIC_H_

View File

@ -11,9 +11,231 @@
#ifndef WEBRTC_BASE_COPYONWRITEBUFFER_H_
#define WEBRTC_BASE_COPYONWRITEBUFFER_H_
#include <algorithm>
#include <utility>
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/copyonwritebuffer.h"
#include "webrtc/base/buffer.h"
#include "webrtc/base/checks.h"
#include "webrtc/base/refcount.h"
#include "webrtc/base/scoped_ref_ptr.h"
namespace rtc {
class CopyOnWriteBuffer {
public:
// An empty buffer.
CopyOnWriteBuffer();
// Copy size and contents of an existing buffer.
CopyOnWriteBuffer(const CopyOnWriteBuffer& buf);
// Move contents from an existing buffer.
CopyOnWriteBuffer(CopyOnWriteBuffer&& buf);
// Construct a buffer with the specified number of uninitialized bytes.
explicit CopyOnWriteBuffer(size_t size);
CopyOnWriteBuffer(size_t size, size_t capacity);
// Construct a buffer and copy the specified number of bytes into it. The
// source array may be (const) uint8_t*, int8_t*, or char*.
template <typename T,
typename std::enable_if<
internal::BufferCompat<uint8_t, T>::value>::type* = nullptr>
CopyOnWriteBuffer(const T* data, size_t size)
: CopyOnWriteBuffer(data, size, size) {}
template <typename T,
typename std::enable_if<
internal::BufferCompat<uint8_t, T>::value>::type* = nullptr>
CopyOnWriteBuffer(const T* data, size_t size, size_t capacity)
: CopyOnWriteBuffer(size, capacity) {
if (buffer_) {
std::memcpy(buffer_->data(), data, size);
}
}
// Construct a buffer from the contents of an array.
template <typename T,
size_t N,
typename std::enable_if<
internal::BufferCompat<uint8_t, T>::value>::type* = nullptr>
CopyOnWriteBuffer(const T (&array)[N]) // NOLINT: runtime/explicit
: CopyOnWriteBuffer(array, N) {}
~CopyOnWriteBuffer();
// Get a pointer to the data. Just .data() will give you a (const) uint8_t*,
// but you may also use .data<int8_t>() and .data<char>().
template <typename T = uint8_t,
typename std::enable_if<
internal::BufferCompat<uint8_t, T>::value>::type* = nullptr>
const T* data() const {
return cdata<T>();
}
// Get writable pointer to the data. This will create a copy of the underlying
// data if it is shared with other buffers.
template <typename T = uint8_t,
typename std::enable_if<
internal::BufferCompat<uint8_t, T>::value>::type* = nullptr>
T* data() {
RTC_DCHECK(IsConsistent());
if (!buffer_) {
return nullptr;
}
CloneDataIfReferenced(buffer_->capacity());
return buffer_->data<T>();
}
// Get const pointer to the data. This will not create a copy of the
// underlying data if it is shared with other buffers.
template <typename T = uint8_t,
typename std::enable_if<
internal::BufferCompat<uint8_t, T>::value>::type* = nullptr>
const T* cdata() const {
RTC_DCHECK(IsConsistent());
if (!buffer_) {
return nullptr;
}
return buffer_->data<T>();
}
size_t size() const {
RTC_DCHECK(IsConsistent());
return buffer_ ? buffer_->size() : 0;
}
size_t capacity() const {
RTC_DCHECK(IsConsistent());
return buffer_ ? buffer_->capacity() : 0;
}
CopyOnWriteBuffer& operator=(const CopyOnWriteBuffer& buf) {
RTC_DCHECK(IsConsistent());
RTC_DCHECK(buf.IsConsistent());
if (&buf != this) {
buffer_ = buf.buffer_;
}
return *this;
}
CopyOnWriteBuffer& operator=(CopyOnWriteBuffer&& buf) {
RTC_DCHECK(IsConsistent());
RTC_DCHECK(buf.IsConsistent());
buffer_ = std::move(buf.buffer_);
return *this;
}
bool operator==(const CopyOnWriteBuffer& buf) const;
bool operator!=(const CopyOnWriteBuffer& buf) const {
return !(*this == buf);
}
uint8_t& operator[](size_t index) {
RTC_DCHECK_LT(index, size());
return data()[index];
}
uint8_t operator[](size_t index) const {
RTC_DCHECK_LT(index, size());
return cdata()[index];
}
// Replace the contents of the buffer. Accepts the same types as the
// constructors.
template <typename T,
typename std::enable_if<
internal::BufferCompat<uint8_t, T>::value>::type* = nullptr>
void SetData(const T* data, size_t size) {
RTC_DCHECK(IsConsistent());
if (!buffer_) {
buffer_ = size > 0 ? new RefCountedObject<Buffer>(data, size) : nullptr;
} else if (!buffer_->HasOneRef()) {
buffer_ = new RefCountedObject<Buffer>(data, size, buffer_->capacity());
} else {
buffer_->SetData(data, size);
}
RTC_DCHECK(IsConsistent());
}
template <typename T,
size_t N,
typename std::enable_if<
internal::BufferCompat<uint8_t, T>::value>::type* = nullptr>
void SetData(const T (&array)[N]) {
SetData(array, N);
}
void SetData(const CopyOnWriteBuffer& buf) {
RTC_DCHECK(IsConsistent());
RTC_DCHECK(buf.IsConsistent());
if (&buf != this) {
buffer_ = buf.buffer_;
}
}
// Append data to the buffer. Accepts the same types as the constructors.
template <typename T,
typename std::enable_if<
internal::BufferCompat<uint8_t, T>::value>::type* = nullptr>
void AppendData(const T* data, size_t size) {
RTC_DCHECK(IsConsistent());
if (!buffer_) {
buffer_ = new RefCountedObject<Buffer>(data, size);
RTC_DCHECK(IsConsistent());
return;
}
CloneDataIfReferenced(std::max(buffer_->capacity(),
buffer_->size() + size));
buffer_->AppendData(data, size);
RTC_DCHECK(IsConsistent());
}
template <typename T,
size_t N,
typename std::enable_if<
internal::BufferCompat<uint8_t, T>::value>::type* = nullptr>
void AppendData(const T (&array)[N]) {
AppendData(array, N);
}
void AppendData(const CopyOnWriteBuffer& buf) {
AppendData(buf.data(), buf.size());
}
// Sets the size of the buffer. If the new size is smaller than the old, the
// buffer contents will be kept but truncated; if the new size is greater,
// the existing contents will be kept and the new space will be
// uninitialized.
void SetSize(size_t size);
// Ensure that the buffer size can be increased to at least capacity without
// further reallocation. (Of course, this operation might need to reallocate
// the buffer.)
void EnsureCapacity(size_t capacity);
// Resets the buffer to zero size without altering capacity. Works even if the
// buffer has been moved from.
void Clear();
// Swaps two buffers.
friend void swap(CopyOnWriteBuffer& a, CopyOnWriteBuffer& b) {
std::swap(a.buffer_, b.buffer_);
}
private:
// Create a copy of the underlying data if it is referenced from other Buffer
// objects.
void CloneDataIfReferenced(size_t new_capacity);
// Pre- and postcondition of all methods.
bool IsConsistent() const {
return (!buffer_ || buffer_->capacity() > 0);
}
// buffer_ is either null, or points to an rtc::Buffer with capacity > 0.
scoped_refptr<RefCountedObject<Buffer>> buffer_;
};
} // namespace rtc
#endif // WEBRTC_BASE_COPYONWRITEBUFFER_H_

View File

@ -11,9 +11,18 @@
#ifndef WEBRTC_BASE_CPU_TIME_H_
#define WEBRTC_BASE_CPU_TIME_H_
#include <stdint.h>
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/cpu_time.h"
namespace rtc {
// Returns total CPU time of a current process in nanoseconds.
// Time base is unknown, therefore use only to calculate deltas.
int64_t GetProcessCpuTimeNanos();
// Returns total CPU time of a current thread in nanoseconds.
// Time base is unknown, therefore use only to calculate deltas.
int64_t GetThreadCpuTimeNanos();
} // namespace rtc
#endif // WEBRTC_BASE_CPU_TIME_H_

View File

@ -11,9 +11,24 @@
#ifndef WEBRTC_BASE_CRC32_H_
#define WEBRTC_BASE_CRC32_H_
#include <string>
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/crc32.h"
#include "webrtc/base/basictypes.h"
namespace rtc {
// Updates a CRC32 checksum with |len| bytes from |buf|. |initial| holds the
// checksum result from the previous update; for the first call, it should be 0.
uint32_t UpdateCrc32(uint32_t initial, const void* buf, size_t len);
// Computes a CRC32 checksum using |len| bytes from |buf|.
inline uint32_t ComputeCrc32(const void* buf, size_t len) {
return UpdateCrc32(0, buf, len);
}
inline uint32_t ComputeCrc32(const std::string& str) {
return ComputeCrc32(str.c_str(), str.size());
}
} // namespace rtc
#endif // WEBRTC_BASE_CRC32_H_

View File

@ -11,8 +11,146 @@
#ifndef WEBRTC_BASE_CRITICALSECTION_H_
#define WEBRTC_BASE_CRITICALSECTION_H_
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/criticalsection.h"
#include "webrtc/base/atomicops.h"
#include "webrtc/base/checks.h"
#include "webrtc/base/constructormagic.h"
#include "webrtc/base/platform_thread_types.h"
#include "webrtc/base/thread_annotations.h"
#include "webrtc/typedefs.h"
#if defined(WEBRTC_WIN)
// Include winsock2.h before including <windows.h> to maintain consistency with
// win32.h. We can't include win32.h directly here since it pulls in
// headers such as basictypes.h which causes problems in Chromium where webrtc
// exists as two separate projects, webrtc and libjingle.
#include <winsock2.h>
#include <windows.h>
#include <sal.h> // must come after windows headers.
#endif // defined(WEBRTC_WIN)
#if defined(WEBRTC_POSIX)
#include <pthread.h>
#endif
// See notes in the 'Performance' unit test for the effects of this flag.
#define USE_NATIVE_MUTEX_ON_MAC 0
#if defined(WEBRTC_MAC) && !USE_NATIVE_MUTEX_ON_MAC
#include <dispatch/dispatch.h>
#endif
#define CS_DEBUG_CHECKS RTC_DCHECK_IS_ON
#if CS_DEBUG_CHECKS
#define CS_DEBUG_CODE(x) x
#else // !CS_DEBUG_CHECKS
#define CS_DEBUG_CODE(x)
#endif // !CS_DEBUG_CHECKS
namespace rtc {
// Locking methods (Enter, TryEnter, Leave)are const to permit protecting
// members inside a const context without requiring mutable CriticalSections
// everywhere.
class LOCKABLE CriticalSection {
public:
CriticalSection();
~CriticalSection();
void Enter() const EXCLUSIVE_LOCK_FUNCTION();
bool TryEnter() const EXCLUSIVE_TRYLOCK_FUNCTION(true);
void Leave() const UNLOCK_FUNCTION();
private:
// Use only for RTC_DCHECKing.
bool CurrentThreadIsOwner() const;
#if defined(WEBRTC_WIN)
mutable CRITICAL_SECTION crit_;
#elif defined(WEBRTC_POSIX)
# if defined(WEBRTC_MAC) && !USE_NATIVE_MUTEX_ON_MAC
// Number of times the lock has been locked + number of threads waiting.
// TODO(tommi): We could use this number and subtract the recursion count
// to find places where we have multiple threads contending on the same lock.
mutable volatile int lock_queue_;
// |recursion_| represents the recursion count + 1 for the thread that owns
// the lock. Only modified by the thread that owns the lock.
mutable int recursion_;
// Used to signal a single waiting thread when the lock becomes available.
mutable dispatch_semaphore_t semaphore_;
// The thread that currently holds the lock. Required to handle recursion.
mutable PlatformThreadRef owning_thread_;
# else
mutable pthread_mutex_t mutex_;
# endif
mutable PlatformThreadRef thread_; // Only used by RTC_DCHECKs.
mutable int recursion_count_; // Only used by RTC_DCHECKs.
#else // !defined(WEBRTC_WIN) && !defined(WEBRTC_POSIX)
# error Unsupported platform.
#endif
};
// CritScope, for serializing execution through a scope.
class SCOPED_LOCKABLE CritScope {
public:
explicit CritScope(const CriticalSection* cs) EXCLUSIVE_LOCK_FUNCTION(cs);
~CritScope() UNLOCK_FUNCTION();
private:
const CriticalSection* const cs_;
RTC_DISALLOW_COPY_AND_ASSIGN(CritScope);
};
// Tries to lock a critical section on construction via
// CriticalSection::TryEnter, and unlocks on destruction if the
// lock was taken. Never blocks.
//
// IMPORTANT: Unlike CritScope, the lock may not be owned by this thread in
// subsequent code. Users *must* check locked() to determine if the
// lock was taken. If you're not calling locked(), you're doing it wrong!
class TryCritScope {
public:
explicit TryCritScope(const CriticalSection* cs);
~TryCritScope();
#if defined(WEBRTC_WIN)
_Check_return_ bool locked() const;
#elif defined(WEBRTC_POSIX)
bool locked() const __attribute__ ((__warn_unused_result__));
#else // !defined(WEBRTC_WIN) && !defined(WEBRTC_POSIX)
# error Unsupported platform.
#endif
private:
const CriticalSection* const cs_;
const bool locked_;
mutable bool lock_was_called_; // Only used by RTC_DCHECKs.
RTC_DISALLOW_COPY_AND_ASSIGN(TryCritScope);
};
// A POD lock used to protect global variables. Do NOT use for other purposes.
// No custom constructor or private data member should be added.
class LOCKABLE GlobalLockPod {
public:
void Lock() EXCLUSIVE_LOCK_FUNCTION();
void Unlock() UNLOCK_FUNCTION();
volatile int lock_acquired;
};
class GlobalLock : public GlobalLockPod {
public:
GlobalLock();
};
// GlobalLockScope, for serializing execution through a scope.
class SCOPED_LOCKABLE GlobalLockScope {
public:
explicit GlobalLockScope(GlobalLockPod* lock) EXCLUSIVE_LOCK_FUNCTION(lock);
~GlobalLockScope() UNLOCK_FUNCTION();
private:
GlobalLockPod* const lock_;
RTC_DISALLOW_COPY_AND_ASSIGN(GlobalLockScope);
};
} // namespace rtc
#endif // WEBRTC_BASE_CRITICALSECTION_H_

View File

@ -8,12 +8,160 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_BASE_CRYPTSTRING_H_
#define WEBRTC_BASE_CRYPTSTRING_H_
#ifndef _WEBRTC_BASE_CRYPTSTRING_H_
#define _WEBRTC_BASE_CRYPTSTRING_H_
#include <string.h>
#include <memory>
#include <string>
#include <vector>
namespace rtc {
class CryptStringImpl {
public:
virtual ~CryptStringImpl() {}
virtual size_t GetLength() const = 0;
virtual void CopyTo(char * dest, bool nullterminate) const = 0;
virtual std::string UrlEncode() const = 0;
virtual CryptStringImpl * Copy() const = 0;
virtual void CopyRawTo(std::vector<unsigned char> * dest) const = 0;
};
class EmptyCryptStringImpl : public CryptStringImpl {
public:
~EmptyCryptStringImpl() override {}
size_t GetLength() const override;
void CopyTo(char* dest, bool nullterminate) const override;
std::string UrlEncode() const override;
CryptStringImpl* Copy() const override;
void CopyRawTo(std::vector<unsigned char>* dest) const override;
};
class CryptString {
public:
CryptString();
size_t GetLength() const { return impl_->GetLength(); }
void CopyTo(char * dest, bool nullterminate) const { impl_->CopyTo(dest, nullterminate); }
CryptString(const CryptString& other);
explicit CryptString(const CryptStringImpl& impl);
~CryptString();
CryptString & operator=(const CryptString & other) {
if (this != &other) {
impl_.reset(other.impl_->Copy());
}
return *this;
}
void Clear() { impl_.reset(new EmptyCryptStringImpl()); }
std::string UrlEncode() const { return impl_->UrlEncode(); }
void CopyRawTo(std::vector<unsigned char> * dest) const {
return impl_->CopyRawTo(dest);
}
private:
std::unique_ptr<const CryptStringImpl> impl_;
};
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/cryptstring.h"
// Used for constructing strings where a password is involved and we
// need to ensure that we zero memory afterwards
class FormatCryptString {
public:
FormatCryptString() {
storage_ = new char[32];
capacity_ = 32;
length_ = 0;
storage_[0] = 0;
}
void Append(const std::string & text) {
Append(text.data(), text.length());
}
#endif // WEBRTC_BASE_CRYPTSTRING_H_
void Append(const char * data, size_t length) {
EnsureStorage(length_ + length + 1);
memcpy(storage_ + length_, data, length);
length_ += length;
storage_[length_] = '\0';
}
void Append(const CryptString * password) {
size_t len = password->GetLength();
EnsureStorage(length_ + len + 1);
password->CopyTo(storage_ + length_, true);
length_ += len;
}
size_t GetLength() {
return length_;
}
const char * GetData() {
return storage_;
}
// Ensures storage of at least n bytes
void EnsureStorage(size_t n) {
if (capacity_ >= n) {
return;
}
size_t old_capacity = capacity_;
char * old_storage = storage_;
for (;;) {
capacity_ *= 2;
if (capacity_ >= n)
break;
}
storage_ = new char[capacity_];
if (old_capacity) {
memcpy(storage_, old_storage, length_);
// zero memory in a way that an optimizer won't optimize it out
old_storage[0] = 0;
for (size_t i = 1; i < old_capacity; i++) {
old_storage[i] = old_storage[i - 1];
}
delete[] old_storage;
}
}
~FormatCryptString() {
if (capacity_) {
storage_[0] = 0;
for (size_t i = 1; i < capacity_; i++) {
storage_[i] = storage_[i - 1];
}
}
delete[] storage_;
}
private:
char * storage_;
size_t capacity_;
size_t length_;
};
class InsecureCryptStringImpl : public CryptStringImpl {
public:
std::string& password() { return password_; }
const std::string& password() const { return password_; }
~InsecureCryptStringImpl() override = default;
size_t GetLength() const override;
void CopyTo(char* dest, bool nullterminate) const override;
std::string UrlEncode() const override;
CryptStringImpl* Copy() const override;
void CopyRawTo(std::vector<unsigned char>* dest) const override;
private:
std::string password_;
};
}
#endif // _WEBRTC_BASE_CRYPTSTRING_H_

View File

@ -11,9 +11,35 @@
#ifndef WEBRTC_BASE_DEPRECATION_H_
#define WEBRTC_BASE_DEPRECATION_H_
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/deprecation.h"
// Annotate the declarations of deprecated functions with this to cause a
// compiler warning when they're used. Like so:
//
// RTC_DEPRECATED std::pony PonyPlz(const std::pony_spec& ps);
//
// NOTE 1: The annotation goes on the declaration in the .h file, not the
// definition in the .cc file!
//
// NOTE 2: In order to keep unit testing the deprecated function without
// getting warnings, do something like this:
//
// std::pony DEPRECATED_PonyPlz(const std::pony_spec& ps);
// RTC_DEPRECATED inline std::pony PonyPlz(const std::pony_spec& ps) {
// return DEPRECATED_PonyPlz(ps);
// }
//
// In other words, rename the existing function, and provide an inline wrapper
// using the original name that calls it. That way, callers who are willing to
// call it using the DEPRECATED_-prefixed name don't get the warning.
//
// TODO(kwiberg): Remove this when we can use [[deprecated]] from C++14.
#if defined(_MSC_VER)
// Note: Deprecation warnings seem to fail to trigger on Windows
// (https://bugs.chromium.org/p/webrtc/issues/detail?id=5368).
#define RTC_DEPRECATED __declspec(deprecated)
#elif defined(__GNUC__)
#define RTC_DEPRECATED __attribute__ ((__deprecated__))
#else
#define RTC_DEPRECATED
#endif
#endif // WEBRTC_BASE_DEPRECATION_H_

View File

@ -11,9 +11,35 @@
#ifndef WEBRTC_BASE_DSCP_H_
#define WEBRTC_BASE_DSCP_H_
namespace rtc {
// Differentiated Services Code Point.
// See http://tools.ietf.org/html/rfc2474 for details.
enum DiffServCodePoint {
DSCP_NO_CHANGE = -1,
DSCP_DEFAULT = 0, // Same as DSCP_CS0
DSCP_CS0 = 0, // The default
DSCP_CS1 = 8, // Bulk/background traffic
DSCP_AF11 = 10,
DSCP_AF12 = 12,
DSCP_AF13 = 14,
DSCP_CS2 = 16,
DSCP_AF21 = 18,
DSCP_AF22 = 20,
DSCP_AF23 = 22,
DSCP_CS3 = 24,
DSCP_AF31 = 26,
DSCP_AF32 = 28,
DSCP_AF33 = 30,
DSCP_CS4 = 32,
DSCP_AF41 = 34, // Video
DSCP_AF42 = 36, // Video
DSCP_AF43 = 38, // Video
DSCP_CS5 = 40, // Video
DSCP_EF = 46, // Voice
DSCP_CS6 = 48, // Voice
DSCP_CS7 = 56, // Control messages
};
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/dscp.h"
} // namespace rtc
#endif // WEBRTC_BASE_DSCP_H_
#endif // WEBRTC_BASE_DSCP_H_

View File

@ -8,12 +8,47 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_BASE_EVENT_H_
#define WEBRTC_BASE_EVENT_H_
#ifndef WEBRTC_BASE_EVENT_H__
#define WEBRTC_BASE_EVENT_H__
#include "webrtc/base/constructormagic.h"
#if defined(WEBRTC_WIN)
#include "webrtc/base/win32.h" // NOLINT: consider this a system header.
#elif defined(WEBRTC_POSIX)
#include <pthread.h>
#else
#error "Must define either WEBRTC_WIN or WEBRTC_POSIX."
#endif
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/event.h"
namespace rtc {
#endif // WEBRTC_BASE_EVENT_H_
class Event {
public:
static const int kForever = -1;
Event(bool manual_reset, bool initially_signaled);
~Event();
void Set();
void Reset();
// Wait for the event to become signaled, for the specified number of
// |milliseconds|. To wait indefinetly, pass kForever.
bool Wait(int milliseconds);
private:
#if defined(WEBRTC_WIN)
HANDLE event_handle_;
#elif defined(WEBRTC_POSIX)
pthread_mutex_t event_mutex_;
pthread_cond_t event_cond_;
const bool is_manual_reset_;
bool event_status_;
#endif
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(Event);
};
} // namespace rtc
#endif // WEBRTC_BASE_EVENT_H__

View File

@ -26,9 +26,60 @@
#ifndef WEBRTC_BASE_EVENT_TRACER_H_
#define WEBRTC_BASE_EVENT_TRACER_H_
#include <stdio.h>
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/event_tracer.h"
namespace webrtc {
typedef const unsigned char* (*GetCategoryEnabledPtr)(const char* name);
typedef void (*AddTraceEventPtr)(char phase,
const unsigned char* category_enabled,
const char* name,
unsigned long long id,
int num_args,
const char** arg_names,
const unsigned char* arg_types,
const unsigned long long* arg_values,
unsigned char flags);
// User of WebRTC can call this method to setup event tracing.
//
// This method must be called before any WebRTC methods. Functions
// provided should be thread-safe.
void SetupEventTracer(
GetCategoryEnabledPtr get_category_enabled_ptr,
AddTraceEventPtr add_trace_event_ptr);
// This class defines interface for the event tracing system to call
// internally. Do not call these methods directly.
class EventTracer {
public:
static const unsigned char* GetCategoryEnabled(
const char* name);
static void AddTraceEvent(
char phase,
const unsigned char* category_enabled,
const char* name,
unsigned long long id,
int num_args,
const char** arg_names,
const unsigned char* arg_types,
const unsigned long long* arg_values,
unsigned char flags);
};
} // namespace webrtc
namespace rtc {
namespace tracing {
// Set up internal event tracer.
void SetupInternalTracer();
bool StartInternalCapture(const char* filename);
void StartInternalCaptureToFile(FILE* file);
void StopInternalCapture();
// Make sure we run this, this will tear down the internal tracing.
void ShutdownInternalTracer();
} // namespace tracing
} // namespace rtc
#endif // WEBRTC_BASE_EVENT_TRACER_H_

View File

@ -11,9 +11,61 @@
#ifndef WEBRTC_BASE_FAKECLOCK_H_
#define WEBRTC_BASE_FAKECLOCK_H_
#include "webrtc/base/criticalsection.h"
#include "webrtc/base/timedelta.h"
#include "webrtc/base/timeutils.h"
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/fakeclock.h"
namespace rtc {
// Fake clock for use with unit tests, which does not tick on its own.
// Starts at time 0.
//
// TODO(deadbeef): Unify with webrtc::SimulatedClock.
class FakeClock : public ClockInterface {
public:
~FakeClock() override {}
// ClockInterface implementation.
int64_t TimeNanos() const override;
// Methods that can be used by the test to control the time.
// Should only be used to set a time in the future.
void SetTimeNanos(int64_t nanos);
void SetTimeMicros(int64_t micros) {
SetTimeNanos(kNumNanosecsPerMicrosec * micros);
}
void AdvanceTime(TimeDelta delta);
void AdvanceTimeMicros(int64_t micros) {
AdvanceTime(rtc::TimeDelta::FromMicroseconds(micros));
}
private:
CriticalSection lock_;
int64_t time_ GUARDED_BY(lock_) = 0;
};
// Helper class that sets itself as the global clock in its constructor and
// unsets it in its destructor.
class ScopedFakeClock : public FakeClock {
public:
ScopedFakeClock();
~ScopedFakeClock() override;
private:
ClockInterface* prev_clock_;
};
// Helper class to "undo" the fake clock temporarily.
class ScopedRealClock {
public:
ScopedRealClock();
~ScopedRealClock();
private:
ClockInterface* prev_clock_;
};
} // namespace rtc
#endif // WEBRTC_BASE_FAKECLOCK_H_

View File

@ -11,9 +11,119 @@
#ifndef WEBRTC_BASE_FAKENETWORK_H_
#define WEBRTC_BASE_FAKENETWORK_H_
#include <memory>
#include <string>
#include <utility>
#include <vector>
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/fakenetwork.h"
#include "webrtc/base/network.h"
#include "webrtc/base/messagehandler.h"
#include "webrtc/base/socketaddress.h"
#include "webrtc/base/stringencode.h"
#include "webrtc/base/thread.h"
namespace rtc {
const int kFakeIPv4NetworkPrefixLength = 24;
const int kFakeIPv6NetworkPrefixLength = 64;
// Fake network manager that allows us to manually specify the IPs to use.
class FakeNetworkManager : public NetworkManagerBase,
public MessageHandler {
public:
FakeNetworkManager() {}
typedef std::vector<std::pair<SocketAddress, AdapterType>> IfaceList;
void AddInterface(const SocketAddress& iface) {
// Ensure a unique name for the interface if its name is not given.
AddInterface(iface, "test" + rtc::ToString(next_index_++));
}
void AddInterface(const SocketAddress& iface, const std::string& if_name) {
AddInterface(iface, if_name, ADAPTER_TYPE_UNKNOWN);
}
void AddInterface(const SocketAddress& iface,
const std::string& if_name,
AdapterType type) {
SocketAddress address(if_name, 0);
address.SetResolvedIP(iface.ipaddr());
ifaces_.push_back(std::make_pair(address, type));
DoUpdateNetworks();
}
void RemoveInterface(const SocketAddress& iface) {
for (IfaceList::iterator it = ifaces_.begin();
it != ifaces_.end(); ++it) {
if (it->first.EqualIPs(iface)) {
ifaces_.erase(it);
break;
}
}
DoUpdateNetworks();
}
virtual void StartUpdating() {
++start_count_;
if (start_count_ == 1) {
sent_first_update_ = false;
rtc::Thread::Current()->Post(RTC_FROM_HERE, this);
} else {
if (sent_first_update_) {
SignalNetworksChanged();
}
}
}
virtual void StopUpdating() { --start_count_; }
// MessageHandler interface.
virtual void OnMessage(Message* msg) {
DoUpdateNetworks();
}
using NetworkManagerBase::set_enumeration_permission;
using NetworkManagerBase::set_default_local_addresses;
private:
void DoUpdateNetworks() {
if (start_count_ == 0)
return;
std::vector<Network*> networks;
for (IfaceList::iterator it = ifaces_.begin();
it != ifaces_.end(); ++it) {
int prefix_length = 0;
if (it->first.ipaddr().family() == AF_INET) {
prefix_length = kFakeIPv4NetworkPrefixLength;
} else if (it->first.ipaddr().family() == AF_INET6) {
prefix_length = kFakeIPv6NetworkPrefixLength;
}
IPAddress prefix = TruncateIP(it->first.ipaddr(), prefix_length);
std::unique_ptr<Network> net(new Network(it->first.hostname(),
it->first.hostname(), prefix,
prefix_length, it->second));
net->set_default_local_address_provider(this);
net->AddIP(it->first.ipaddr());
networks.push_back(net.release());
}
bool changed;
MergeNetworkList(networks, &changed);
if (changed || !sent_first_update_) {
SignalNetworksChanged();
sent_first_update_ = true;
}
}
IfaceList ifaces_;
int next_index_ = 0;
int start_count_ = 0;
bool sent_first_update_ = false;
IPAddress default_local_ipv4_address_;
IPAddress default_local_ipv6_address_;
};
} // namespace rtc
#endif // WEBRTC_BASE_FAKENETWORK_H_

View File

@ -11,9 +11,110 @@
#ifndef WEBRTC_BASE_FAKESSLIDENTITY_H_
#define WEBRTC_BASE_FAKESSLIDENTITY_H_
#include <algorithm>
#include <memory>
#include <vector>
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/fakesslidentity.h"
#include "webrtc/base/checks.h"
#include "webrtc/base/messagedigest.h"
#include "webrtc/base/sslidentity.h"
namespace rtc {
class FakeSSLCertificate : public rtc::SSLCertificate {
public:
// SHA-1 is the default digest algorithm because it is available in all build
// configurations used for unit testing.
explicit FakeSSLCertificate(const std::string& data)
: data_(data), digest_algorithm_(DIGEST_SHA_1), expiration_time_(-1) {}
explicit FakeSSLCertificate(const std::vector<std::string>& certs)
: data_(certs.front()),
digest_algorithm_(DIGEST_SHA_1),
expiration_time_(-1) {
std::vector<std::string>::const_iterator it;
// Skip certs[0].
for (it = certs.begin() + 1; it != certs.end(); ++it) {
certs_.push_back(FakeSSLCertificate(*it));
}
}
FakeSSLCertificate* GetReference() const override {
return new FakeSSLCertificate(*this);
}
std::string ToPEMString() const override {
return data_;
}
void ToDER(Buffer* der_buffer) const override {
std::string der_string;
RTC_CHECK(SSLIdentity::PemToDer(kPemTypeCertificate, data_, &der_string));
der_buffer->SetData(der_string.c_str(), der_string.size());
}
int64_t CertificateExpirationTime() const override {
return expiration_time_;
}
void SetCertificateExpirationTime(int64_t expiration_time) {
expiration_time_ = expiration_time;
}
void set_digest_algorithm(const std::string& algorithm) {
digest_algorithm_ = algorithm;
}
bool GetSignatureDigestAlgorithm(std::string* algorithm) const override {
*algorithm = digest_algorithm_;
return true;
}
bool ComputeDigest(const std::string& algorithm,
unsigned char* digest,
size_t size,
size_t* length) const override {
*length = rtc::ComputeDigest(algorithm, data_.c_str(), data_.size(),
digest, size);
return (*length != 0);
}
std::unique_ptr<SSLCertChain> GetChain() const override {
if (certs_.empty())
return nullptr;
std::vector<SSLCertificate*> new_certs(certs_.size());
std::transform(certs_.begin(), certs_.end(), new_certs.begin(), DupCert);
std::unique_ptr<SSLCertChain> chain(new SSLCertChain(new_certs));
std::for_each(new_certs.begin(), new_certs.end(), DeleteCert);
return chain;
}
private:
static FakeSSLCertificate* DupCert(FakeSSLCertificate cert) {
return cert.GetReference();
}
static void DeleteCert(SSLCertificate* cert) { delete cert; }
std::string data_;
std::vector<FakeSSLCertificate> certs_;
std::string digest_algorithm_;
// Expiration time in seconds relative to epoch, 1970-01-01T00:00:00Z (UTC).
int64_t expiration_time_;
};
class FakeSSLIdentity : public rtc::SSLIdentity {
public:
explicit FakeSSLIdentity(const std::string& data) : cert_(data) {}
explicit FakeSSLIdentity(const FakeSSLCertificate& cert) : cert_(cert) {}
virtual FakeSSLIdentity* GetReference() const {
return new FakeSSLIdentity(*this);
}
virtual const FakeSSLCertificate& certificate() const { return cert_; }
virtual std::string PrivateKeyToPEMString() const {
RTC_NOTREACHED(); // Not implemented.
return "";
}
virtual std::string PublicKeyToPEMString() const {
RTC_NOTREACHED(); // Not implemented.
return "";
}
virtual bool operator==(const SSLIdentity& other) const {
RTC_NOTREACHED(); // Not implemented.
return false;
}
private:
FakeSSLCertificate cert_;
};
} // namespace rtc
#endif // WEBRTC_BASE_FAKESSLIDENTITY_H_

View File

@ -11,9 +11,72 @@
#ifndef WEBRTC_BASE_FILE_H_
#define WEBRTC_BASE_FILE_H_
#include <stdint.h>
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/file.h"
#include <string>
#include "webrtc/base/constructormagic.h"
#include "webrtc/base/pathutils.h"
#include "webrtc/base/platform_file.h"
namespace rtc {
// This class wraps the platform specific APIs for simple file interactions.
//
// The various read and write methods are best effort, i.e. if an underlying
// call does not manage to read/write all the data more calls will be performed,
// until an error is detected or all data is read/written.
class File {
public:
// Wraps the given PlatformFile. This class is then responsible for closing
// the file, which will be done in the destructor if Close is never called.
explicit File(PlatformFile);
// The default constructor produces a closed file.
File();
~File();
File(File&& other);
File& operator=(File&& other);
// Open and Create give files with both reading and writing enabled.
static File Open(const std::string& path);
static File Open(Pathname&& path);
static File Open(const Pathname& path);
// If the file already exists it will be overwritten.
static File Create(const std::string& path);
static File Create(Pathname&& path);
static File Create(const Pathname& path);
// Remove a file in the file system.
static bool Remove(const std::string& path);
static bool Remove(Pathname&& path);
static bool Remove(const Pathname& path);
size_t Write(const uint8_t* data, size_t length);
size_t Read(uint8_t* buffer, size_t length);
// The current position in the file after a call to these methods is platform
// dependent (MSVC gives position offset+length, most other
// compilers/platforms do not alter the position), i.e. do not depend on it,
// do a Seek before any subsequent Read/Write.
size_t WriteAt(const uint8_t* data, size_t length, size_t offset);
size_t ReadAt(uint8_t* buffer, size_t length, size_t offset);
// Attempt to position the file at the given offset from the start.
// Returns true if successful, false otherwise.
bool Seek(size_t offset);
// Attempt to close the file. Returns true if successful, false otherwise,
// most notably when the file is already closed.
bool Close();
bool IsOpen();
private:
PlatformFile file_;
RTC_DISALLOW_COPY_AND_ASSIGN(File);
};
} // namespace rtc
#endif // WEBRTC_BASE_FILE_H_

View File

@ -11,9 +11,163 @@
#ifndef WEBRTC_BASE_FILEROTATINGSTREAM_H_
#define WEBRTC_BASE_FILEROTATINGSTREAM_H_
#include <memory>
#include <string>
#include <vector>
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/filerotatingstream.h"
#include "webrtc/base/constructormagic.h"
#include "webrtc/base/stream.h"
namespace rtc {
// FileRotatingStream writes to a file in the directory specified in the
// constructor. It rotates the files once the current file is full. The
// individual file size and the number of files used is configurable in the
// constructor. Open() must be called before using this stream.
class FileRotatingStream : public StreamInterface {
public:
// Use this constructor for reading a directory previously written to with
// this stream.
FileRotatingStream(const std::string& dir_path,
const std::string& file_prefix);
// Use this constructor for writing to a directory. Files in the directory
// matching the prefix will be deleted on open.
FileRotatingStream(const std::string& dir_path,
const std::string& file_prefix,
size_t max_file_size,
size_t num_files);
~FileRotatingStream() override;
// StreamInterface methods.
StreamState GetState() const override;
StreamResult Read(void* buffer,
size_t buffer_len,
size_t* read,
int* error) override;
StreamResult Write(const void* data,
size_t data_len,
size_t* written,
int* error) override;
bool Flush() override;
// Returns the total file size currently used on disk.
bool GetSize(size_t* size) const override;
void Close() override;
// Opens the appropriate file(s). Call this before using the stream.
bool Open();
// Disabling buffering causes writes to block until disk is updated. This is
// enabled by default for performance.
bool DisableBuffering();
// Returns the path used for the i-th newest file, where the 0th file is the
// newest file. The file may or may not exist, this is just used for
// formatting. Index must be less than GetNumFiles().
std::string GetFilePath(size_t index) const;
// Returns the number of files that will used by this stream.
size_t GetNumFiles() const { return file_names_.size(); }
protected:
size_t GetMaxFileSize() const { return max_file_size_; }
void SetMaxFileSize(size_t size) { max_file_size_ = size; }
size_t GetRotationIndex() const { return rotation_index_; }
void SetRotationIndex(size_t index) { rotation_index_ = index; }
virtual void OnRotation() {}
private:
enum Mode { kRead, kWrite };
FileRotatingStream(const std::string& dir_path,
const std::string& file_prefix,
size_t max_file_size,
size_t num_files,
Mode mode);
bool OpenCurrentFile();
void CloseCurrentFile();
// Rotates the files by creating a new current file, renaming the
// existing files, and deleting the oldest one. e.g.
// file_0 -> file_1
// file_1 -> file_2
// file_2 -> delete
// create new file_0
void RotateFiles();
// Returns a list of file names in the directory beginning with the prefix.
std::vector<std::string> GetFilesWithPrefix() const;
// Private version of GetFilePath.
std::string GetFilePath(size_t index, size_t num_files) const;
const std::string dir_path_;
const std::string file_prefix_;
const Mode mode_;
// FileStream is used to write to the current file.
std::unique_ptr<FileStream> file_stream_;
// Convenience storage for file names so we don't generate them over and over.
std::vector<std::string> file_names_;
size_t max_file_size_;
size_t current_file_index_;
// The rotation index indicates the index of the file that will be
// deleted first on rotation. Indices lower than this index will be rotated.
size_t rotation_index_;
// Number of bytes written to current file. We need this because with
// buffering the file size read from disk might not be accurate.
size_t current_bytes_written_;
bool disable_buffering_;
RTC_DISALLOW_COPY_AND_ASSIGN(FileRotatingStream);
};
// CallSessionFileRotatingStream is meant to be used in situations where we will
// have limited disk space. Its purpose is to read and write logs up to a
// maximum size. Once the maximum size is exceeded, logs from the middle are
// deleted whereas logs from the beginning and end are preserved. The reason for
// this is because we anticipate that in WebRTC the beginning and end of the
// logs are most useful for call diagnostics.
//
// This implementation simply writes to a single file until
// |max_total_log_size| / 2 bytes are written to it, and subsequently writes to
// a set of rotating files. We do this by inheriting FileRotatingStream and
// setting the appropriate internal variables so that we don't delete the last
// (earliest) file on rotate, and that that file's size is bigger.
//
// Open() must be called before using this stream.
class CallSessionFileRotatingStream : public FileRotatingStream {
public:
// Use this constructor for reading a directory previously written to with
// this stream.
explicit CallSessionFileRotatingStream(const std::string& dir_path);
// Use this constructor for writing to a directory. Files in the directory
// matching what's used by the stream will be deleted. |max_total_log_size|
// must be at least 4.
CallSessionFileRotatingStream(const std::string& dir_path,
size_t max_total_log_size);
~CallSessionFileRotatingStream() override {}
protected:
void OnRotation() override;
private:
static size_t GetRotatingLogSize(size_t max_total_log_size);
static size_t GetNumRotatingLogFiles(size_t max_total_log_size);
static const char* kLogPrefix;
static const size_t kRotatingLogFileDefaultSize;
const size_t max_total_log_size_;
size_t num_rotations_;
RTC_DISALLOW_COPY_AND_ASSIGN(CallSessionFileRotatingStream);
};
} // namespace rtc
#endif // WEBRTC_BASE_FILEROTATINGSTREAM_H_

View File

@ -1,4 +1,3 @@
/*
* Copyright 2004 The WebRTC Project Authors. All rights reserved.
*
@ -12,9 +11,172 @@
#ifndef WEBRTC_BASE_FILEUTILS_H_
#define WEBRTC_BASE_FILEUTILS_H_
#include <string>
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/fileutils.h"
#if !defined(WEBRTC_WIN)
#include <dirent.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#endif
#include "webrtc/base/checks.h"
#include "webrtc/base/constructormagic.h"
#include "webrtc/base/platform_file.h"
namespace rtc {
class FileStream;
class Pathname;
//////////////////////////
// Directory Iterator //
//////////////////////////
// A DirectoryIterator is created with a given directory. It originally points
// to the first file in the directory, and can be advanecd with Next(). This
// allows you to get information about each file.
class DirectoryIterator {
friend class Filesystem;
public:
// Constructor
DirectoryIterator();
// Destructor
virtual ~DirectoryIterator();
// Starts traversing a directory
// dir is the directory to traverse
// returns true if the directory exists and is valid
// The iterator will point to the first entry in the directory
virtual bool Iterate(const Pathname &path);
// Advances to the next file
// returns true if there were more files in the directory.
virtual bool Next();
// returns true if the file currently pointed to is a directory
virtual bool IsDirectory() const;
// returns the name of the file currently pointed to
virtual std::string Name() const;
private:
std::string directory_;
#if defined(WEBRTC_WIN)
WIN32_FIND_DATA data_;
HANDLE handle_;
#else
DIR *dir_;
struct dirent *dirent_;
struct stat stat_;
#endif
};
class FilesystemInterface {
public:
virtual ~FilesystemInterface() {}
// This will attempt to delete the path located at filename.
// It DCHECKs and returns false if the path points to a folder or a
// non-existent file.
virtual bool DeleteFile(const Pathname &filename) = 0;
// Creates a directory. This will call itself recursively to create /foo/bar
// even if /foo does not exist. Returns true if the function succeeds.
virtual bool CreateFolder(const Pathname &pathname) = 0;
// This moves a file from old_path to new_path, where "old_path" is a
// plain file. This DCHECKs and returns false if old_path points to a
// directory, and returns true if the function succeeds.
virtual bool MoveFile(const Pathname &old_path, const Pathname &new_path) = 0;
// Returns true if pathname refers to a directory
virtual bool IsFolder(const Pathname& pathname) = 0;
// Returns true if pathname refers to a file
virtual bool IsFile(const Pathname& pathname) = 0;
// Returns true if pathname refers to no filesystem object, every parent
// directory either exists, or is also absent.
virtual bool IsAbsent(const Pathname& pathname) = 0;
// A folder appropriate for storing temporary files (Contents are
// automatically deleted when the program exits)
virtual bool GetTemporaryFolder(Pathname &path, bool create,
const std::string *append) = 0;
virtual std::string TempFilename(const Pathname &dir,
const std::string &prefix) = 0;
// Determines the size of the file indicated by path.
virtual bool GetFileSize(const Pathname& path, size_t* size) = 0;
};
class Filesystem {
public:
static FilesystemInterface *default_filesystem() {
RTC_DCHECK(default_filesystem_);
return default_filesystem_;
}
static void set_default_filesystem(FilesystemInterface *filesystem) {
default_filesystem_ = filesystem;
}
static FilesystemInterface *swap_default_filesystem(
FilesystemInterface *filesystem) {
FilesystemInterface *cur = default_filesystem_;
default_filesystem_ = filesystem;
return cur;
}
static bool CreateFolder(const Pathname &pathname) {
return EnsureDefaultFilesystem()->CreateFolder(pathname);
}
static bool DeleteFile(const Pathname &filename) {
return EnsureDefaultFilesystem()->DeleteFile(filename);
}
static bool MoveFile(const Pathname &old_path, const Pathname &new_path) {
return EnsureDefaultFilesystem()->MoveFile(old_path, new_path);
}
static bool IsFolder(const Pathname& pathname) {
return EnsureDefaultFilesystem()->IsFolder(pathname);
}
static bool IsFile(const Pathname &pathname) {
return EnsureDefaultFilesystem()->IsFile(pathname);
}
static bool IsAbsent(const Pathname &pathname) {
return EnsureDefaultFilesystem()->IsAbsent(pathname);
}
static bool GetTemporaryFolder(Pathname &path, bool create,
const std::string *append) {
return EnsureDefaultFilesystem()->GetTemporaryFolder(path, create, append);
}
static std::string TempFilename(const Pathname &dir,
const std::string &prefix) {
return EnsureDefaultFilesystem()->TempFilename(dir, prefix);
}
static bool GetFileSize(const Pathname& path, size_t* size) {
return EnsureDefaultFilesystem()->GetFileSize(path, size);
}
private:
static FilesystemInterface* default_filesystem_;
static FilesystemInterface *EnsureDefaultFilesystem();
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(Filesystem);
};
} // namespace rtc
#endif // WEBRTC_BASE_FILEUTILS_H_

View File

@ -11,9 +11,115 @@
#ifndef WEBRTC_BASE_FIREWALLSOCKETSERVER_H_
#define WEBRTC_BASE_FIREWALLSOCKETSERVER_H_
#include <vector>
#include "webrtc/base/socketserver.h"
#include "webrtc/base/criticalsection.h"
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/firewallsocketserver.h"
namespace rtc {
class FirewallManager;
// This SocketServer shim simulates a rule-based firewall server.
enum FirewallProtocol { FP_UDP, FP_TCP, FP_ANY };
enum FirewallDirection { FD_IN, FD_OUT, FD_ANY };
class FirewallSocketServer : public SocketServer {
public:
FirewallSocketServer(SocketServer* server,
FirewallManager* manager = nullptr,
bool should_delete_server = false);
~FirewallSocketServer() override;
SocketServer* socketserver() const { return server_; }
void set_socketserver(SocketServer* server) {
if (server_ && should_delete_server_) {
delete server_;
server_ = nullptr;
should_delete_server_ = false;
}
server_ = server;
}
// Settings to control whether CreateSocket or Socket::Listen succeed.
void set_udp_sockets_enabled(bool enabled) { udp_sockets_enabled_ = enabled; }
void set_tcp_sockets_enabled(bool enabled) { tcp_sockets_enabled_ = enabled; }
bool tcp_listen_enabled() const { return tcp_listen_enabled_; }
void set_tcp_listen_enabled(bool enabled) { tcp_listen_enabled_ = enabled; }
// Rules govern the behavior of Connect/Accept/Send/Recv attempts.
void AddRule(bool allow, FirewallProtocol p = FP_ANY,
FirewallDirection d = FD_ANY,
const SocketAddress& addr = SocketAddress());
void AddRule(bool allow, FirewallProtocol p,
const SocketAddress& src, const SocketAddress& dst);
void ClearRules();
bool Check(FirewallProtocol p,
const SocketAddress& src, const SocketAddress& dst);
// Set the IP addresses for which Bind will fail. By default this list is
// empty. This can be used to simulate a real OS that refuses to bind to
// addresses under various circumstances.
//
// No matter how many addresses are added (including INADDR_ANY), the server
// will still allow creating outgoing TCP connections, since they don't
// require explicitly binding a socket.
void SetUnbindableIps(const std::vector<rtc::IPAddress>& unbindable_ips);
bool IsBindableIp(const rtc::IPAddress& ip);
Socket* CreateSocket(int type) override;
Socket* CreateSocket(int family, int type) override;
AsyncSocket* CreateAsyncSocket(int type) override;
AsyncSocket* CreateAsyncSocket(int family, int type) override;
void SetMessageQueue(MessageQueue* queue) override;
bool Wait(int cms, bool process_io) override;
void WakeUp() override;
Socket * WrapSocket(Socket * sock, int type);
AsyncSocket * WrapSocket(AsyncSocket * sock, int type);
private:
SocketServer * server_;
FirewallManager * manager_;
CriticalSection crit_;
struct Rule {
bool allow;
FirewallProtocol p;
FirewallDirection d;
SocketAddress src;
SocketAddress dst;
};
std::vector<Rule> rules_;
std::vector<rtc::IPAddress> unbindable_ips_;
bool should_delete_server_;
bool udp_sockets_enabled_;
bool tcp_sockets_enabled_;
bool tcp_listen_enabled_;
};
// FirewallManager allows you to manage firewalls in multiple threads together
class FirewallManager {
public:
FirewallManager();
~FirewallManager();
void AddServer(FirewallSocketServer * server);
void RemoveServer(FirewallSocketServer * server);
void AddRule(bool allow, FirewallProtocol p = FP_ANY,
FirewallDirection d = FD_ANY,
const SocketAddress& addr = SocketAddress());
void ClearRules();
private:
CriticalSection crit_;
std::vector<FirewallSocketServer *> servers_;
};
} // namespace rtc
#endif // WEBRTC_BASE_FIREWALLSOCKETSERVER_H_

View File

@ -20,12 +20,249 @@
// The implementation only relies and basic C++ functionality
// and needs no special library or STL support.
#ifndef WEBRTC_BASE_FLAGS_H_
#define WEBRTC_BASE_FLAGS_H_
#ifndef WEBRTC_BASE_FLAGS_H__
#define WEBRTC_BASE_FLAGS_H__
#include "webrtc/base/checks.h"
#include "webrtc/base/constructormagic.h"
namespace rtc {
// Internal use only.
union FlagValue {
// Note: Because in C++ non-bool values are silently converted into
// bool values ('bool b = "false";' results in b == true!), we pass
// and int argument to New_BOOL as this appears to be safer - sigh.
// In particular, it prevents the (not uncommon!) bug where a bool
// flag is defined via: DEFINE_bool(flag, "false", "some comment");.
static FlagValue New_BOOL(int b) {
FlagValue v;
v.b = (b != 0);
return v;
}
static FlagValue New_INT(int i) {
FlagValue v;
v.i = i;
return v;
}
static FlagValue New_FLOAT(float f) {
FlagValue v;
v.f = f;
return v;
}
static FlagValue New_STRING(const char* s) {
FlagValue v;
v.s = s;
return v;
}
bool b;
int i;
double f;
const char* s;
};
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/flags.h"
// Each flag can be accessed programmatically via a Flag object.
class Flag {
public:
enum Type { BOOL, INT, FLOAT, STRING };
#endif // SHARED_COMMANDLINEFLAGS_FLAGS_H_
// Internal use only.
Flag(const char* file, const char* name, const char* comment,
Type type, void* variable, FlagValue default_);
// General flag information
const char* file() const { return file_; }
const char* name() const { return name_; }
const char* comment() const { return comment_; }
// Flag type
Type type() const { return type_; }
// Flag variables
bool* bool_variable() const {
RTC_DCHECK_EQ(BOOL, type_);
return &variable_->b;
}
int* int_variable() const {
RTC_DCHECK_EQ(INT, type_);
return &variable_->i;
}
double* float_variable() const {
RTC_DCHECK_EQ(FLOAT, type_);
return &variable_->f;
}
const char** string_variable() const {
RTC_DCHECK_EQ(STRING, type_);
return &variable_->s;
}
// Default values
bool bool_default() const {
RTC_DCHECK_EQ(BOOL, type_);
return default_.b;
}
int int_default() const {
RTC_DCHECK_EQ(INT, type_);
return default_.i;
}
double float_default() const {
RTC_DCHECK_EQ(FLOAT, type_);
return default_.f;
}
const char* string_default() const {
RTC_DCHECK_EQ(STRING, type_);
return default_.s;
}
// Resets a flag to its default value
void SetToDefault();
// Iteration support
Flag* next() const { return next_; }
// Prints flag information. The current flag value is only printed
// if print_current_value is set.
void Print(bool print_current_value);
private:
const char* file_;
const char* name_;
const char* comment_;
Type type_;
FlagValue* variable_;
FlagValue default_;
Flag* next_;
friend class FlagList; // accesses next_
};
// Internal use only.
#define DEFINE_FLAG(type, c_type, name, default, comment) \
/* define and initialize the flag */ \
c_type FLAG_##name = (default); \
/* register the flag */ \
static rtc::Flag Flag_##name(__FILE__, #name, (comment), \
rtc::Flag::type, &FLAG_##name, \
rtc::FlagValue::New_##type(default))
// Internal use only.
#define DECLARE_FLAG(c_type, name) \
/* declare the external flag */ \
extern c_type FLAG_##name
// Use the following macros to define a new flag:
#define DEFINE_bool(name, default, comment) \
DEFINE_FLAG(BOOL, bool, name, default, comment)
#define DEFINE_int(name, default, comment) \
DEFINE_FLAG(INT, int, name, default, comment)
#define DEFINE_float(name, default, comment) \
DEFINE_FLAG(FLOAT, double, name, default, comment)
#define DEFINE_string(name, default, comment) \
DEFINE_FLAG(STRING, const char*, name, default, comment)
// Use the following macros to declare a flag defined elsewhere:
#define DECLARE_bool(name) DECLARE_FLAG(bool, name)
#define DECLARE_int(name) DECLARE_FLAG(int, name)
#define DECLARE_float(name) DECLARE_FLAG(double, name)
#define DECLARE_string(name) DECLARE_FLAG(const char*, name)
// The global list of all flags.
class FlagList {
public:
FlagList();
// The null-terminated list of all flags. Traverse with Flag::next().
static Flag* list() { return list_; }
// If file != nullptr, prints information for all flags defined in file;
// otherwise prints information for all flags in all files. The current flag
// value is only printed if print_current_value is set.
static void Print(const char* file, bool print_current_value);
// Lookup a flag by name. Returns the matching flag or null.
static Flag* Lookup(const char* name);
// Helper function to parse flags: Takes an argument arg and splits it into
// a flag name and flag value (or null if they are missing). is_bool is set
// if the arg started with "-no" or "--no". The buffer may be used to NUL-
// terminate the name, it must be large enough to hold any possible name.
static void SplitArgument(const char* arg,
char* buffer, int buffer_size,
const char** name, const char** value,
bool* is_bool);
// Set the flag values by parsing the command line. If remove_flags
// is set, the flags and associated values are removed from (argc,
// argv). Returns 0 if no error occurred. Otherwise, returns the
// argv index > 0 for the argument where an error occurred. In that
// case, (argc, argv) will remain unchanged indepdendent of the
// remove_flags value, and no assumptions about flag settings should
// be made.
//
// The following syntax for flags is accepted (both '-' and '--' are ok):
//
// --flag (bool flags only)
// --noflag (bool flags only)
// --flag=value (non-bool flags only, no spaces around '=')
// --flag value (non-bool flags only)
static int SetFlagsFromCommandLine(int* argc,
const char** argv,
bool remove_flags);
static inline int SetFlagsFromCommandLine(int* argc,
char** argv,
bool remove_flags) {
return SetFlagsFromCommandLine(argc, const_cast<const char**>(argv),
remove_flags);
}
// Registers a new flag. Called during program initialization. Not
// thread-safe.
static void Register(Flag* flag);
private:
static Flag* list_;
};
#if defined(WEBRTC_WIN)
// A helper class to translate Windows command line arguments into UTF8,
// which then allows us to just pass them to the flags system.
// This encapsulates all the work of getting the command line and translating
// it to an array of 8-bit strings; all you have to do is create one of these,
// and then call argc() and argv().
class WindowsCommandLineArguments {
public:
WindowsCommandLineArguments();
~WindowsCommandLineArguments();
int argc() { return argc_; }
char **argv() { return argv_; }
private:
int argc_;
char **argv_;
private:
RTC_DISALLOW_COPY_AND_ASSIGN(WindowsCommandLineArguments);
};
#endif // WEBRTC_WIN
} // namespace rtc
#endif // SHARED_COMMANDLINEFLAGS_FLAGS_H__

View File

@ -11,9 +11,86 @@
#ifndef WEBRTC_BASE_FORMAT_MACROS_H_
#define WEBRTC_BASE_FORMAT_MACROS_H_
// This file defines the format macros for some integer types and is derived
// from Chromium's base/format_macros.h.
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/format_macros.h"
// To print a 64-bit value in a portable way:
// int64_t value;
// printf("xyz:%" PRId64, value);
// The "d" in the macro corresponds to %d; you can also use PRIu64 etc.
//
// To print a size_t value in a portable way:
// size_t size;
// printf("xyz: %" PRIuS, size);
// The "u" in the macro corresponds to %u, and S is for "size".
#include "webrtc/typedefs.h"
#if defined(WEBRTC_POSIX)
#if (defined(_INTTYPES_H) || defined(_INTTYPES_H_)) && !defined(PRId64)
#error "inttypes.h has already been included before this header file, but "
#error "without __STDC_FORMAT_MACROS defined."
#endif
#if !defined(__STDC_FORMAT_MACROS)
#define __STDC_FORMAT_MACROS
#endif
#include <inttypes.h>
#if !defined(PRIuS)
#define PRIuS "zu"
#endif
// The size of NSInteger and NSUInteger varies between 32-bit and 64-bit
// architectures and Apple does not provides standard format macros and
// recommends casting. This has many drawbacks, so instead define macros
// for formatting those types.
#if defined(WEBRTC_MAC)
#if defined(WEBRTC_ARCH_64_BITS)
#if !defined(PRIdNS)
#define PRIdNS "ld"
#endif
#if !defined(PRIuNS)
#define PRIuNS "lu"
#endif
#if !defined(PRIxNS)
#define PRIxNS "lx"
#endif
#else // defined(WEBRTC_ARCH_64_BITS)
#if !defined(PRIdNS)
#define PRIdNS "d"
#endif
#if !defined(PRIuNS)
#define PRIuNS "u"
#endif
#if !defined(PRIxNS)
#define PRIxNS "x"
#endif
#endif
#endif // defined(WEBRTC_MAC)
#else // WEBRTC_WIN
#include <inttypes.h>
#if !defined(PRId64)
#define PRId64 "I64d"
#endif
#if !defined(PRIu64)
#define PRIu64 "I64u"
#endif
#if !defined(PRIx64)
#define PRIx64 "I64x"
#endif
#if !defined(PRIuS)
#define PRIuS "Iu"
#endif
#endif
#endif // WEBRTC_BASE_FORMAT_MACROS_H_

View File

@ -11,9 +11,120 @@
#ifndef WEBRTC_BASE_FUNCTION_VIEW_H_
#define WEBRTC_BASE_FUNCTION_VIEW_H_
#include <type_traits>
#include <utility>
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/function_view.h"
#include "webrtc/base/checks.h"
// Just like std::function, FunctionView will wrap any callable and hide its
// actual type, exposing only its signature. But unlike std::function,
// FunctionView doesn't own its callable---it just points to it. Thus, it's a
// good choice mainly as a function argument when the callable argument will
// not be called again once the function has returned.
//
// Its constructors are implicit, so that callers won't have to convert lambdas
// and other callables to FunctionView<Blah(Blah, Blah)> explicitly. This is
// safe because FunctionView is only a reference to the real callable.
//
// Example use:
//
// void SomeFunction(rtc::FunctionView<int(int)> index_transform);
// ...
// SomeFunction([](int i) { return 2 * i + 1; });
//
// Note: FunctionView is tiny (essentially just two pointers) and trivially
// copyable, so it's probably cheaper to pass it by value than by const
// reference.
namespace rtc {
template <typename T>
class FunctionView; // Undefined.
template <typename RetT, typename... ArgT>
class FunctionView<RetT(ArgT...)> final {
public:
// Constructor for lambdas and other callables; it accepts every type of
// argument except those noted in its enable_if call.
template <
typename F,
typename std::enable_if<
// Not for function pointers; we have another constructor for that
// below.
!std::is_function<typename std::remove_pointer<
typename std::remove_reference<F>::type>::type>::value &&
// Not for nullptr; we have another constructor for that below.
!std::is_same<std::nullptr_t,
typename std::remove_cv<F>::type>::value &&
// Not for FunctionView objects; we have another constructor for that
// (the implicitly declared copy constructor).
!std::is_same<FunctionView,
typename std::remove_cv<typename std::remove_reference<
F>::type>::type>::value>::type* = nullptr>
FunctionView(F&& f)
: call_(CallVoidPtr<typename std::remove_reference<F>::type>) {
f_.void_ptr = &f;
}
// Constructor that accepts function pointers. If the argument is null, the
// result is an empty FunctionView.
template <
typename F,
typename std::enable_if<std::is_function<typename std::remove_pointer<
typename std::remove_reference<F>::type>::type>::value>::type* =
nullptr>
FunctionView(F&& f)
: call_(f ? CallFunPtr<typename std::remove_pointer<F>::type> : nullptr) {
f_.fun_ptr = reinterpret_cast<void (*)()>(f);
}
// Constructor that accepts nullptr. It creates an empty FunctionView.
template <typename F,
typename std::enable_if<std::is_same<
std::nullptr_t,
typename std::remove_cv<F>::type>::value>::type* = nullptr>
FunctionView(F&& f) : call_(nullptr) {}
// Default constructor. Creates an empty FunctionView.
FunctionView() : call_(nullptr) {}
RetT operator()(ArgT... args) const {
RTC_DCHECK(call_);
return call_(f_, std::forward<ArgT>(args)...);
}
// Returns true if we have a function, false if we don't (i.e., we're null).
explicit operator bool() const { return !!call_; }
private:
union VoidUnion {
void* void_ptr;
void (*fun_ptr)();
};
template <typename F>
static RetT CallVoidPtr(VoidUnion vu, ArgT... args) {
return (*static_cast<F*>(vu.void_ptr))(std::forward<ArgT>(args)...);
}
template <typename F>
static RetT CallFunPtr(VoidUnion vu, ArgT... args) {
return (reinterpret_cast<typename std::add_pointer<F>::type>(vu.fun_ptr))(
std::forward<ArgT>(args)...);
}
// A pointer to the callable thing, with type information erased. It's a
// union because we have to use separate types depending on if the callable
// thing is a function pointer or something else.
VoidUnion f_;
// Pointer to a dispatch function that knows the type of the callable thing
// that's stored in f_, and how to call it. A FunctionView object is empty
// (null) iff call_ is null.
RetT (*call_)(VoidUnion, ArgT...);
};
} // namespace rtc
#endif // WEBRTC_BASE_FUNCTION_VIEW_H_

View File

@ -11,9 +11,28 @@
#ifndef WEBRTC_BASE_GTEST_PROD_UTIL_H_
#define WEBRTC_BASE_GTEST_PROD_UTIL_H_
// Define our own version of FRIEND_TEST here rather than including
// gtest_prod.h to avoid depending on any part of GTest in production code.
#define FRIEND_TEST_WEBRTC(test_case_name, test_name)\
friend class test_case_name##_##test_name##_Test
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/gtest_prod_util.h"
// This file is a plain copy of Chromium's base/gtest_prod_util.h.
//
// This is a wrapper for gtest's FRIEND_TEST macro that friends
// test with all possible prefixes. This is very helpful when changing the test
// prefix, because the friend declarations don't need to be updated.
//
// Example usage:
//
// class MyClass {
// private:
// void MyMethod();
// FRIEND_TEST_ALL_PREFIXES(MyClassTest, MyMethod);
// };
#define FRIEND_TEST_ALL_PREFIXES(test_case_name, test_name) \
FRIEND_TEST_WEBRTC(test_case_name, test_name); \
FRIEND_TEST_WEBRTC(test_case_name, DISABLED_##test_name); \
FRIEND_TEST_WEBRTC(test_case_name, FLAKY_##test_name); \
FRIEND_TEST_WEBRTC(test_case_name, FAILS_##test_name)
#endif // WEBRTC_BASE_GTEST_PROD_UTIL_H_

View File

@ -11,9 +11,140 @@
#ifndef WEBRTC_BASE_GUNIT_H_
#define WEBRTC_BASE_GUNIT_H_
#include "webrtc/base/fakeclock.h"
#include "webrtc/base/logging.h"
#include "webrtc/base/thread.h"
#if defined(GTEST_RELATIVE_PATH)
#include "webrtc/test/gtest.h"
#else
#include "testing/base/public/gunit.h"
#endif
// This header is deprecated and is just left here temporarily during
// refactoring. See https://bugs.webrtc.org/7634 for more details.
#include "webrtc/rtc_base/gunit.h"
// Wait until "ex" is true, or "timeout" expires.
#define WAIT(ex, timeout) \
for (int64_t start = rtc::SystemTimeMillis(); \
!(ex) && rtc::SystemTimeMillis() < start + (timeout);) { \
rtc::Thread::Current()->ProcessMessages(0); \
rtc::Thread::Current()->SleepMs(1); \
}
// This returns the result of the test in res, so that we don't re-evaluate
// the expression in the XXXX_WAIT macros below, since that causes problems
// when the expression is only true the first time you check it.
#define WAIT_(ex, timeout, res) \
do { \
int64_t start = rtc::SystemTimeMillis(); \
res = (ex); \
while (!res && rtc::SystemTimeMillis() < start + (timeout)) { \
rtc::Thread::Current()->ProcessMessages(0); \
rtc::Thread::Current()->SleepMs(1); \
res = (ex); \
} \
} while (0)
// The typical EXPECT_XXXX and ASSERT_XXXXs, but done until true or a timeout.
#define EXPECT_TRUE_WAIT(ex, timeout) \
do { \
bool res; \
WAIT_(ex, timeout, res); \
if (!res) EXPECT_TRUE(ex); \
} while (0)
#define EXPECT_EQ_WAIT(v1, v2, timeout) \
do { \
bool res; \
WAIT_(v1 == v2, timeout, res); \
if (!res) EXPECT_EQ(v1, v2); \
} while (0)
#define ASSERT_TRUE_WAIT(ex, timeout) \
do { \
bool res; \
WAIT_(ex, timeout, res); \
if (!res) ASSERT_TRUE(ex); \
} while (0)
#define ASSERT_EQ_WAIT(v1, v2, timeout) \
do { \
bool res; \
WAIT_(v1 == v2, timeout, res); \
if (!res) ASSERT_EQ(v1, v2); \
} while (0)
// Version with a "soft" timeout and a margin. This logs if the timeout is
// exceeded, but it only fails if the expression still isn't true after the
// margin time passes.
#define EXPECT_TRUE_WAIT_MARGIN(ex, timeout, margin) \
do { \
bool res; \
WAIT_(ex, timeout, res); \
if (res) { \
break; \
} \
LOG(LS_WARNING) << "Expression " << #ex << " still not true after " \
<< (timeout) << "ms; waiting an additional " << margin \
<< "ms"; \
WAIT_(ex, margin, res); \
if (!res) { \
EXPECT_TRUE(ex); \
} \
} while (0)
// Wait until "ex" is true, or "timeout" expires, using fake clock where
// messages are processed every millisecond.
// TODO(pthatcher): Allow tests to control how many milliseconds to advance.
#define SIMULATED_WAIT(ex, timeout, clock) \
for (int64_t start = rtc::TimeMillis(); \
!(ex) && rtc::TimeMillis() < start + (timeout);) { \
(clock).AdvanceTime(rtc::TimeDelta::FromMilliseconds(1)); \
}
// This returns the result of the test in res, so that we don't re-evaluate
// the expression in the XXXX_WAIT macros below, since that causes problems
// when the expression is only true the first time you check it.
#define SIMULATED_WAIT_(ex, timeout, res, clock) \
do { \
int64_t start = rtc::TimeMillis(); \
res = (ex); \
while (!res && rtc::TimeMillis() < start + (timeout)) { \
(clock).AdvanceTime(rtc::TimeDelta::FromMilliseconds(1)); \
res = (ex); \
} \
} while (0)
// The typical EXPECT_XXXX, but done until true or a timeout with a fake clock.
#define EXPECT_TRUE_SIMULATED_WAIT(ex, timeout, clock) \
do { \
bool res; \
SIMULATED_WAIT_(ex, timeout, res, clock); \
if (!res) { \
EXPECT_TRUE(ex); \
} \
} while (0)
#define EXPECT_EQ_SIMULATED_WAIT(v1, v2, timeout, clock) \
do { \
bool res; \
SIMULATED_WAIT_(v1 == v2, timeout, res, clock); \
if (!res) { \
EXPECT_EQ(v1, v2); \
} \
} while (0)
#define ASSERT_TRUE_SIMULATED_WAIT(ex, timeout, clock) \
do { \
bool res; \
SIMULATED_WAIT_(ex, timeout, res, clock); \
if (!res) \
ASSERT_TRUE(ex); \
} while (0)
#define ASSERT_EQ_SIMULATED_WAIT(v1, v2, timeout, clock) \
do { \
bool res; \
SIMULATED_WAIT_(v1 == v2, timeout, res, clock); \
if (!res) \
ASSERT_EQ(v1, v2); \
} while (0)
#endif // WEBRTC_BASE_GUNIT_H_

Some files were not shown because too many files have changed in this diff Show More