Move webrtc/{base => rtc_base}
This refactoring takes a careful approach to avoid rushing the change: * stub headers are left in all the old locations of webrtc/base * existing GN targets are kept and now just forward to the moved ones using public_deps. The only exception to the above is the base_java target and its .java files, which were moved to webrtc/rtc_base right away since it's not possible to use public_deps for android_library. To avoid breaking builds, a temporary Dummy.java file was added to the new intermediate target in webrtc/rtc_base:base_java as well to avoid hitting a GN assert in the android_library template. The above approach should make the transition smooth without breaking downstream. A helper script was created (https://codereview.webrtc.org/2879203002/) and was run like this: stub-headers.py -s webrtc/base -d webrtc/rtc_base -i 7634 stub-headers.py -s webrtc/base/numerics -d webrtc/rtc_base/numerics -i 7634 Fixed invalid header guards in the following files: webrtc/base/base64.h webrtc/base/cryptstring.h webrtc/base/event.h webrtc/base/flags.h webrtc/base/httpbase.h webrtc/base/httpcommon-inl.h webrtc/base/httpcommon.h webrtc/base/httpserver.h webrtc/base/logsinks.h webrtc/base/macutils.h webrtc/base/nattypes.h webrtc/base/openssladapter.h webrtc/base/opensslstreamadapter.h webrtc/base/pathutils.h webrtc/base/physicalsocketserver.h webrtc/base/proxyinfo.h webrtc/base/sigslot.h webrtc/base/sigslotrepeater.h webrtc/base/socket.h webrtc/base/socketaddresspair.h webrtc/base/socketfactory.h webrtc/base/stringutils.h webrtc/base/testbase64.h webrtc/base/testutils.h webrtc/base/transformadapter.h webrtc/base/win32filesystem.h Added new header guards to: sslroots.h testbase64.h BUG=webrtc:7634 NOTRY=True NOPRESUBMIT=True R=kwiberg@webrtc.org Review-Url: https://codereview.webrtc.org/2877023002 . Cr-Commit-Position: refs/heads/master@{#18816}
This commit is contained in:
@ -32,6 +32,7 @@ CPPLINT_BLACKLIST = [
|
||||
'webrtc/modules/video_capture',
|
||||
'webrtc/p2p',
|
||||
'webrtc/pc',
|
||||
'webrtc/rtc_base',
|
||||
'webrtc/sdk/android/src/jni',
|
||||
'webrtc/sdk/objc',
|
||||
'webrtc/system_wrappers',
|
||||
|
||||
@ -21,6 +21,7 @@ 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
9
webrtc/base/Dummy.java
Normal file
9
webrtc/base/Dummy.java
Normal file
@ -0,0 +1,9 @@
|
||||
/**
|
||||
* This class only exists as glue in a transition.
|
||||
* TODO(kjellander): Remove.
|
||||
* See https://bugs.webrtc.org/7634 for more details.
|
||||
*/
|
||||
class Dummy {
|
||||
Dummy() {
|
||||
}
|
||||
}
|
||||
@ -11,243 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_ARRAY_VIEW_H_
|
||||
#define WEBRTC_BASE_ARRAY_VIEW_H_
|
||||
|
||||
#include "webrtc/base/checks.h"
|
||||
#include "webrtc/base/type_traits.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
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_ARRAY_VIEW_H_
|
||||
|
||||
@ -11,21 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_ARRAYSIZE_H_
|
||||
#define WEBRTC_BASE_ARRAYSIZE_H_
|
||||
|
||||
#include <stddef.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)))
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_ARRAYSIZE_H_
|
||||
|
||||
@ -11,46 +11,9 @@
|
||||
#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"
|
||||
|
||||
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
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_ASYNCINVOKER_INL_H_
|
||||
|
||||
@ -11,211 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_ASYNCINVOKER_H_
|
||||
#define WEBRTC_BASE_ASYNCINVOKER_H_
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#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
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_ASYNCINVOKER_H_
|
||||
|
||||
@ -11,133 +11,9 @@
|
||||
#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"
|
||||
|
||||
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
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_ASYNCPACKETSOCKET_H_
|
||||
|
||||
@ -11,37 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_ASYNCRESOLVERINTERFACE_H_
|
||||
#define WEBRTC_BASE_ASYNCRESOLVERINTERFACE_H_
|
||||
|
||||
#include "webrtc/base/sigslot.h"
|
||||
#include "webrtc/base/socketaddress.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
|
||||
// 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"
|
||||
|
||||
#endif
|
||||
|
||||
@ -11,73 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_ASYNCSOCKET_H_
|
||||
#define WEBRTC_BASE_ASYNCSOCKET_H_
|
||||
|
||||
#include "webrtc/base/sigslot.h"
|
||||
#include "webrtc/base/socket.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
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_ASYNCSOCKET_H_
|
||||
|
||||
@ -11,98 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_ASYNCTCPSOCKET_H_
|
||||
#define WEBRTC_BASE_ASYNCTCPSOCKET_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#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
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_ASYNCTCPSOCKET_H_
|
||||
|
||||
@ -11,57 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_ASYNCUDPSOCKET_H_
|
||||
#define WEBRTC_BASE_ASYNCUDPSOCKET_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#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
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_ASYNCUDPSOCKET_H_
|
||||
|
||||
@ -11,77 +11,9 @@
|
||||
#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)
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_ATOMICOPS_H_
|
||||
|
||||
@ -9,115 +9,12 @@
|
||||
//* 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>
|
||||
|
||||
namespace rtc {
|
||||
// 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"
|
||||
|
||||
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__
|
||||
#endif // WEBRTC_BASE_BASE64_H_
|
||||
|
||||
@ -11,60 +11,9 @@
|
||||
#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.
|
||||
|
||||
// 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
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_BASICTYPES_H_
|
||||
|
||||
@ -61,224 +61,9 @@
|
||||
#ifndef WEBRTC_BASE_BIND_H_
|
||||
#define WEBRTC_BASE_BIND_H_
|
||||
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
|
||||
#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
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_BIND_H_
|
||||
|
||||
@ -11,116 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_BITBUFFER_H_
|
||||
#define WEBRTC_BASE_BITBUFFER_H_
|
||||
|
||||
#include <stdint.h> // For integer types.
|
||||
#include <stddef.h> // For size_t.
|
||||
|
||||
#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
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_BITBUFFER_H_
|
||||
|
||||
@ -11,373 +11,8 @@
|
||||
#ifndef WEBRTC_BASE_BUFFER_H_
|
||||
#define WEBRTC_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
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_BUFFER_H_
|
||||
|
||||
@ -11,51 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_BUFFERQUEUE_H_
|
||||
#define WEBRTC_BASE_BUFFERQUEUE_H_
|
||||
|
||||
#include <deque>
|
||||
#include <vector>
|
||||
|
||||
#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
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_BUFFERQUEUE_H_
|
||||
|
||||
@ -11,129 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_BYTEBUFFER_H_
|
||||
#define WEBRTC_BASE_BYTEBUFFER_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#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
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_BYTEBUFFER_H_
|
||||
|
||||
@ -11,168 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_BYTEORDER_H_
|
||||
#define WEBRTC_BASE_BYTEORDER_H_
|
||||
|
||||
#if defined(WEBRTC_POSIX) && !defined(__native_client__)
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#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
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_BYTEORDER_H_
|
||||
|
||||
@ -62,199 +62,9 @@
|
||||
#ifndef WEBRTC_BASE_CALLBACK_H_
|
||||
#define WEBRTC_BASE_CALLBACK_H_
|
||||
|
||||
#include "webrtc/base/refcount.h"
|
||||
#include "webrtc/base/scoped_ref_ptr.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
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_CALLBACK_H_
|
||||
|
||||
@ -11,279 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_CHECKS_H_
|
||||
#define WEBRTC_BASE_CHECKS_H_
|
||||
|
||||
#include "webrtc/typedefs.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
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_CHECKS_H_
|
||||
|
||||
@ -11,11 +11,8 @@
|
||||
#ifndef WEBRTC_BASE_COMPILE_ASSERT_C_H_
|
||||
#define WEBRTC_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:;}
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_COMPILE_ASSERT_C_H_
|
||||
|
||||
@ -11,24 +11,9 @@
|
||||
#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
|
||||
|
||||
// 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)
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_CONSTRUCTORMAGIC_H_
|
||||
|
||||
@ -11,231 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_COPYONWRITEBUFFER_H_
|
||||
#define WEBRTC_BASE_COPYONWRITEBUFFER_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
#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
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_COPYONWRITEBUFFER_H_
|
||||
|
||||
@ -11,18 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_CPU_TIME_H_
|
||||
#define WEBRTC_BASE_CPU_TIME_H_
|
||||
|
||||
#include <stdint.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
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_CPU_TIME_H_
|
||||
|
||||
@ -11,24 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_CRC32_H_
|
||||
#define WEBRTC_BASE_CRC32_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#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
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_CRC32_H_
|
||||
|
||||
@ -11,146 +11,8 @@
|
||||
#ifndef WEBRTC_BASE_CRITICALSECTION_H_
|
||||
#define WEBRTC_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
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_CRITICALSECTION_H_
|
||||
|
||||
@ -8,160 +8,12 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#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_;
|
||||
};
|
||||
#ifndef WEBRTC_BASE_CRYPTSTRING_H_
|
||||
#define WEBRTC_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;
|
||||
}
|
||||
// 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"
|
||||
|
||||
void Append(const std::string & text) {
|
||||
Append(text.data(), text.length());
|
||||
}
|
||||
|
||||
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_
|
||||
#endif // WEBRTC_BASE_CRYPTSTRING_H_
|
||||
|
||||
@ -11,35 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_DEPRECATION_H_
|
||||
#define WEBRTC_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
|
||||
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_DEPRECATION_H_
|
||||
|
||||
@ -11,35 +11,9 @@
|
||||
#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
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_DSCP_H_
|
||||
|
||||
@ -8,47 +8,12 @@
|
||||
* 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
|
||||
|
||||
namespace rtc {
|
||||
// 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"
|
||||
|
||||
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__
|
||||
#endif // WEBRTC_BASE_EVENT_H_
|
||||
|
||||
@ -26,60 +26,9 @@
|
||||
#ifndef WEBRTC_BASE_EVENT_TRACER_H_
|
||||
#define WEBRTC_BASE_EVENT_TRACER_H_
|
||||
|
||||
#include <stdio.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
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_EVENT_TRACER_H_
|
||||
|
||||
@ -11,61 +11,9 @@
|
||||
#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"
|
||||
|
||||
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
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_FAKECLOCK_H_
|
||||
|
||||
@ -11,119 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_FAKENETWORK_H_
|
||||
#define WEBRTC_BASE_FAKENETWORK_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#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
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_FAKENETWORK_H_
|
||||
|
||||
@ -11,110 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_FAKESSLIDENTITY_H_
|
||||
#define WEBRTC_BASE_FAKESSLIDENTITY_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#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
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_FAKESSLIDENTITY_H_
|
||||
|
||||
@ -11,72 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_FILE_H_
|
||||
#define WEBRTC_BASE_FILE_H_
|
||||
|
||||
#include <stdint.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
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_FILE_H_
|
||||
|
||||
@ -11,163 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_FILEROTATINGSTREAM_H_
|
||||
#define WEBRTC_BASE_FILEROTATINGSTREAM_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_FILEROTATINGSTREAM_H_
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
* Copyright 2004 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
@ -11,172 +12,9 @@
|
||||
#ifndef WEBRTC_BASE_FILEUTILS_H_
|
||||
#define WEBRTC_BASE_FILEUTILS_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#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
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_FILEUTILS_H_
|
||||
|
||||
@ -11,115 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_FIREWALLSOCKETSERVER_H_
|
||||
#define WEBRTC_BASE_FIREWALLSOCKETSERVER_H_
|
||||
|
||||
#include <vector>
|
||||
#include "webrtc/base/socketserver.h"
|
||||
#include "webrtc/base/criticalsection.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
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_FIREWALLSOCKETSERVER_H_
|
||||
|
||||
@ -20,249 +20,12 @@
|
||||
// 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__
|
||||
|
||||
#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;
|
||||
};
|
||||
#ifndef WEBRTC_BASE_FLAGS_H_
|
||||
#define WEBRTC_BASE_FLAGS_H_
|
||||
|
||||
|
||||
// Each flag can be accessed programmatically via a Flag object.
|
||||
class Flag {
|
||||
public:
|
||||
enum Type { BOOL, INT, FLOAT, 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/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__
|
||||
#endif // SHARED_COMMANDLINEFLAGS_FLAGS_H_
|
||||
|
||||
@ -11,86 +11,9 @@
|
||||
#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.
|
||||
|
||||
// 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
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_FORMAT_MACROS_H_
|
||||
|
||||
@ -11,120 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_FUNCTION_VIEW_H_
|
||||
#define WEBRTC_BASE_FUNCTION_VIEW_H_
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#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
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_FUNCTION_VIEW_H_
|
||||
|
||||
@ -11,28 +11,9 @@
|
||||
#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 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)
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_GTEST_PROD_UTIL_H_
|
||||
|
||||
@ -11,140 +11,9 @@
|
||||
#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
|
||||
|
||||
// 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)
|
||||
// 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"
|
||||
|
||||
#endif // WEBRTC_BASE_GUNIT_H_
|
||||
|
||||
@ -11,14 +11,8 @@
|
||||
#ifndef WEBRTC_BASE_GUNIT_PROD_H_
|
||||
#define WEBRTC_BASE_GUNIT_PROD_H_
|
||||
|
||||
#if defined(WEBRTC_ANDROID)
|
||||
// Android doesn't use gtest at all, so anything that relies on gtest should
|
||||
// check this define first.
|
||||
#define NO_GTEST
|
||||
#elif defined (GTEST_RELATIVE_PATH)
|
||||
#include "gtest/gtest_prod.h"
|
||||
#else
|
||||
#include "testing/base/gunit_prod.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_prod.h"
|
||||
|
||||
#endif // WEBRTC_BASE_GUNIT_PROD_H_
|
||||
|
||||
@ -11,54 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_HELPERS_H_
|
||||
#define WEBRTC_BASE_HELPERS_H_
|
||||
|
||||
#include <string>
|
||||
#include "webrtc/base/basictypes.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
// For testing, we can return predictable data.
|
||||
void SetRandomTestMode(bool test);
|
||||
|
||||
// Initializes the RNG, and seeds it with the specified entropy.
|
||||
bool InitRandom(int seed);
|
||||
bool InitRandom(const char* seed, size_t len);
|
||||
|
||||
// Generates a (cryptographically) random string of the given length.
|
||||
// We generate base64 values so that they will be printable.
|
||||
std::string CreateRandomString(size_t length);
|
||||
|
||||
// Generates a (cryptographically) random string of the given length.
|
||||
// We generate base64 values so that they will be printable.
|
||||
// Return false if the random number generator failed.
|
||||
bool CreateRandomString(size_t length, std::string* str);
|
||||
|
||||
// Generates a (cryptographically) random string of the given length,
|
||||
// with characters from the given table. Return false if the random
|
||||
// number generator failed.
|
||||
// For ease of implementation, the function requires that the table
|
||||
// size evenly divide 256; otherwise, it returns false.
|
||||
bool CreateRandomString(size_t length, const std::string& table,
|
||||
std::string* str);
|
||||
|
||||
// Generates (cryptographically) random data of the given length.
|
||||
// Return false if the random number generator failed.
|
||||
bool CreateRandomData(size_t length, std::string* data);
|
||||
|
||||
// Generates a (cryptographically) random UUID version 4 string.
|
||||
std::string CreateRandomUuid();
|
||||
|
||||
// Generates a random id.
|
||||
uint32_t CreateRandomId();
|
||||
|
||||
// Generates a 64 bit random id.
|
||||
uint64_t CreateRandomId64();
|
||||
|
||||
// Generates a random id > 0.
|
||||
uint32_t CreateRandomNonZeroId();
|
||||
|
||||
// Generates a random double between 0.0 (inclusive) and 1.0 (exclusive).
|
||||
double CreateRandomDouble();
|
||||
|
||||
} // namespace rtc
|
||||
// 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/helpers.h"
|
||||
|
||||
#endif // WEBRTC_BASE_HELPERS_H_
|
||||
|
||||
@ -9,179 +9,12 @@
|
||||
*/
|
||||
|
||||
|
||||
#ifndef WEBRTC_BASE_HTTPBASE_H__
|
||||
#define WEBRTC_BASE_HTTPBASE_H__
|
||||
#ifndef WEBRTC_BASE_HTTPBASE_H_
|
||||
#define WEBRTC_BASE_HTTPBASE_H_
|
||||
|
||||
#include "webrtc/base/httpcommon.h"
|
||||
|
||||
namespace rtc {
|
||||
// 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/httpbase.h"
|
||||
|
||||
class StreamInterface;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// HttpParser - Parses an HTTP stream provided via Process and end_of_input, and
|
||||
// generates events for:
|
||||
// Structural Elements: Leader, Headers, Document Data
|
||||
// Events: End of Headers, End of Document, Errors
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class HttpParser {
|
||||
public:
|
||||
enum ProcessResult { PR_CONTINUE, PR_BLOCK, PR_COMPLETE };
|
||||
HttpParser();
|
||||
virtual ~HttpParser();
|
||||
|
||||
void reset();
|
||||
ProcessResult Process(const char* buffer, size_t len, size_t* processed,
|
||||
HttpError* error);
|
||||
bool is_valid_end_of_input() const;
|
||||
void complete(HttpError err);
|
||||
|
||||
size_t GetDataRemaining() const { return data_size_; }
|
||||
|
||||
protected:
|
||||
ProcessResult ProcessLine(const char* line, size_t len, HttpError* error);
|
||||
|
||||
// HttpParser Interface
|
||||
virtual ProcessResult ProcessLeader(const char* line, size_t len,
|
||||
HttpError* error) = 0;
|
||||
virtual ProcessResult ProcessHeader(const char* name, size_t nlen,
|
||||
const char* value, size_t vlen,
|
||||
HttpError* error) = 0;
|
||||
virtual ProcessResult ProcessHeaderComplete(bool chunked, size_t& data_size,
|
||||
HttpError* error) = 0;
|
||||
virtual ProcessResult ProcessData(const char* data, size_t len, size_t& read,
|
||||
HttpError* error) = 0;
|
||||
virtual void OnComplete(HttpError err) = 0;
|
||||
|
||||
private:
|
||||
enum State {
|
||||
ST_LEADER, ST_HEADERS,
|
||||
ST_CHUNKSIZE, ST_CHUNKTERM, ST_TRAILERS,
|
||||
ST_DATA, ST_COMPLETE
|
||||
} state_;
|
||||
bool chunked_;
|
||||
size_t data_size_;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// IHttpNotify
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
enum HttpMode { HM_NONE, HM_CONNECT, HM_RECV, HM_SEND };
|
||||
|
||||
class IHttpNotify {
|
||||
public:
|
||||
virtual ~IHttpNotify() {}
|
||||
virtual HttpError onHttpHeaderComplete(bool chunked, size_t& data_size) = 0;
|
||||
virtual void onHttpComplete(HttpMode mode, HttpError err) = 0;
|
||||
virtual void onHttpClosed(HttpError err) = 0;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// HttpBase - Provides a state machine for implementing HTTP-based components.
|
||||
// Attach HttpBase to a StreamInterface which represents a bidirectional HTTP
|
||||
// stream, and then call send() or recv() to initiate sending or receiving one
|
||||
// side of an HTTP transaction. By default, HttpBase operates as an I/O pump,
|
||||
// moving data from the HTTP stream to the HttpData object and vice versa.
|
||||
// However, it can also operate in stream mode, in which case the user of the
|
||||
// stream interface drives I/O via calls to Read().
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class HttpBase
|
||||
: private HttpParser,
|
||||
public sigslot::has_slots<>
|
||||
{
|
||||
public:
|
||||
HttpBase();
|
||||
~HttpBase() override;
|
||||
|
||||
void notify(IHttpNotify* notify) { notify_ = notify; }
|
||||
bool attach(StreamInterface* stream);
|
||||
StreamInterface* stream() { return http_stream_; }
|
||||
StreamInterface* detach();
|
||||
bool isConnected() const;
|
||||
|
||||
void send(HttpData* data);
|
||||
void recv(HttpData* data);
|
||||
void abort(HttpError err);
|
||||
|
||||
HttpMode mode() const { return mode_; }
|
||||
|
||||
void set_ignore_data(bool ignore) { ignore_data_ = ignore; }
|
||||
bool ignore_data() const { return ignore_data_; }
|
||||
|
||||
// Obtaining this stream puts HttpBase into stream mode until the stream
|
||||
// is closed. HttpBase can only expose one open stream interface at a time.
|
||||
// Further calls will return null.
|
||||
StreamInterface* GetDocumentStream();
|
||||
|
||||
protected:
|
||||
// Do cleanup when the http stream closes (error may be 0 for a clean
|
||||
// shutdown), and return the error code to signal.
|
||||
HttpError HandleStreamClose(int error);
|
||||
|
||||
// DoReceiveLoop acts as a data pump, pulling data from the http stream,
|
||||
// pushing it through the HttpParser, and then populating the HttpData object
|
||||
// based on the callbacks from the parser. One of the most interesting
|
||||
// callbacks is ProcessData, which provides the actual http document body.
|
||||
// This data is then written to the HttpData::document. As a result, data
|
||||
// flows from the network to the document, with some incidental protocol
|
||||
// parsing in between.
|
||||
// Ideally, we would pass in the document* to DoReceiveLoop, to more easily
|
||||
// support GetDocumentStream(). However, since the HttpParser is callback
|
||||
// driven, we are forced to store the pointer somewhere until the callback
|
||||
// is triggered.
|
||||
// Returns true if the received document has finished, and
|
||||
// HttpParser::complete should be called.
|
||||
bool DoReceiveLoop(HttpError* err);
|
||||
|
||||
void read_and_process_data();
|
||||
void flush_data();
|
||||
bool queue_headers();
|
||||
void do_complete(HttpError err = HE_NONE);
|
||||
|
||||
void OnHttpStreamEvent(StreamInterface* stream, int events, int error);
|
||||
void OnDocumentEvent(StreamInterface* stream, int events, int error);
|
||||
|
||||
// HttpParser Interface
|
||||
ProcessResult ProcessLeader(const char* line,
|
||||
size_t len,
|
||||
HttpError* error) override;
|
||||
ProcessResult ProcessHeader(const char* name,
|
||||
size_t nlen,
|
||||
const char* value,
|
||||
size_t vlen,
|
||||
HttpError* error) override;
|
||||
ProcessResult ProcessHeaderComplete(bool chunked,
|
||||
size_t& data_size,
|
||||
HttpError* error) override;
|
||||
ProcessResult ProcessData(const char* data,
|
||||
size_t len,
|
||||
size_t& read,
|
||||
HttpError* error) override;
|
||||
void OnComplete(HttpError err) override;
|
||||
|
||||
private:
|
||||
class DocumentStream;
|
||||
friend class DocumentStream;
|
||||
|
||||
enum { kBufferSize = 32 * 1024 };
|
||||
|
||||
HttpMode mode_;
|
||||
HttpData* data_;
|
||||
IHttpNotify* notify_;
|
||||
StreamInterface* http_stream_;
|
||||
DocumentStream* doc_stream_;
|
||||
char buffer_[kBufferSize];
|
||||
size_t len_;
|
||||
|
||||
bool ignore_data_, chunk_data_;
|
||||
HttpData::const_iterator header_;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // WEBRTC_BASE_HTTPBASE_H__
|
||||
#endif // WEBRTC_BASE_HTTPBASE_H_
|
||||
|
||||
@ -8,125 +8,12 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_BASE_HTTPCOMMON_INL_H__
|
||||
#define WEBRTC_BASE_HTTPCOMMON_INL_H__
|
||||
#ifndef WEBRTC_BASE_HTTPCOMMON_INL_H_
|
||||
#define WEBRTC_BASE_HTTPCOMMON_INL_H_
|
||||
|
||||
#include "webrtc/base/arraysize.h"
|
||||
#include "webrtc/base/checks.h"
|
||||
#include "webrtc/base/httpcommon.h"
|
||||
|
||||
namespace rtc {
|
||||
// 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/httpcommon-inl.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Url
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class CTYPE>
|
||||
void Url<CTYPE>::do_set_url(const CTYPE* val, size_t len) {
|
||||
if (ascnicmp(val, "http://", 7) == 0) {
|
||||
val += 7; len -= 7;
|
||||
secure_ = false;
|
||||
} else if (ascnicmp(val, "https://", 8) == 0) {
|
||||
val += 8; len -= 8;
|
||||
secure_ = true;
|
||||
} else {
|
||||
clear();
|
||||
return;
|
||||
}
|
||||
const CTYPE* path = strchrn(val, len, static_cast<CTYPE>('/'));
|
||||
if (!path) {
|
||||
path = val + len;
|
||||
}
|
||||
size_t address_length = (path - val);
|
||||
do_set_address(val, address_length);
|
||||
do_set_full_path(path, len - address_length);
|
||||
}
|
||||
|
||||
template<class CTYPE>
|
||||
void Url<CTYPE>::do_set_address(const CTYPE* val, size_t len) {
|
||||
if (const CTYPE* at = strchrn(val, len, static_cast<CTYPE>('@'))) {
|
||||
// Everything before the @ is a user:password combo, so skip it.
|
||||
len -= at - val + 1;
|
||||
val = at + 1;
|
||||
}
|
||||
if (const CTYPE* colon = strchrn(val, len, static_cast<CTYPE>(':'))) {
|
||||
host_.assign(val, colon - val);
|
||||
// Note: In every case, we're guaranteed that colon is followed by a null,
|
||||
// or non-numeric character.
|
||||
port_ = static_cast<uint16_t>(::strtoul(colon + 1, nullptr, 10));
|
||||
// TODO: Consider checking for invalid data following port number.
|
||||
} else {
|
||||
host_.assign(val, len);
|
||||
port_ = HttpDefaultPort(secure_);
|
||||
}
|
||||
}
|
||||
|
||||
template<class CTYPE>
|
||||
void Url<CTYPE>::do_set_full_path(const CTYPE* val, size_t len) {
|
||||
const CTYPE* query = strchrn(val, len, static_cast<CTYPE>('?'));
|
||||
if (!query) {
|
||||
query = val + len;
|
||||
}
|
||||
size_t path_length = (query - val);
|
||||
if (0 == path_length) {
|
||||
// TODO: consider failing in this case.
|
||||
path_.assign(1, static_cast<CTYPE>('/'));
|
||||
} else {
|
||||
RTC_DCHECK(val[0] == static_cast<CTYPE>('/'));
|
||||
path_.assign(val, path_length);
|
||||
}
|
||||
query_.assign(query, len - path_length);
|
||||
}
|
||||
|
||||
template<class CTYPE>
|
||||
void Url<CTYPE>::do_get_url(string* val) const {
|
||||
CTYPE protocol[9];
|
||||
asccpyn(protocol, arraysize(protocol), secure_ ? "https://" : "http://");
|
||||
val->append(protocol);
|
||||
do_get_address(val);
|
||||
do_get_full_path(val);
|
||||
}
|
||||
|
||||
template<class CTYPE>
|
||||
void Url<CTYPE>::do_get_address(string* val) const {
|
||||
val->append(host_);
|
||||
if (port_ != HttpDefaultPort(secure_)) {
|
||||
CTYPE format[5], port[32];
|
||||
asccpyn(format, arraysize(format), ":%hu");
|
||||
sprintfn(port, arraysize(port), format, port_);
|
||||
val->append(port);
|
||||
}
|
||||
}
|
||||
|
||||
template<class CTYPE>
|
||||
void Url<CTYPE>::do_get_full_path(string* val) const {
|
||||
val->append(path_);
|
||||
val->append(query_);
|
||||
}
|
||||
|
||||
template<class CTYPE>
|
||||
bool Url<CTYPE>::get_attribute(const string& name, string* value) const {
|
||||
if (query_.empty())
|
||||
return false;
|
||||
|
||||
std::string::size_type pos = query_.find(name, 1);
|
||||
if (std::string::npos == pos)
|
||||
return false;
|
||||
|
||||
pos += name.length() + 1;
|
||||
if ((pos > query_.length()) || (static_cast<CTYPE>('=') != query_[pos-1]))
|
||||
return false;
|
||||
|
||||
std::string::size_type end = query_.find(static_cast<CTYPE>('&'), pos);
|
||||
if (std::string::npos == end) {
|
||||
end = query_.length();
|
||||
}
|
||||
value->assign(query_.substr(pos, end - pos));
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // WEBRTC_BASE_HTTPCOMMON_INL_H__
|
||||
#endif // WEBRTC_BASE_HTTPCOMMON_INL_H_
|
||||
|
||||
@ -8,451 +8,12 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_BASE_HTTPCOMMON_H__
|
||||
#define WEBRTC_BASE_HTTPCOMMON_H__
|
||||
#ifndef WEBRTC_BASE_HTTPCOMMON_H_
|
||||
#define WEBRTC_BASE_HTTPCOMMON_H_
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "webrtc/base/basictypes.h"
|
||||
#include "webrtc/base/checks.h"
|
||||
#include "webrtc/base/stringutils.h"
|
||||
#include "webrtc/base/stream.h"
|
||||
|
||||
namespace rtc {
|
||||
// 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/httpcommon.h"
|
||||
|
||||
class CryptString;
|
||||
class SocketAddress;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Constants
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
enum HttpCode {
|
||||
HC_OK = 200,
|
||||
HC_NON_AUTHORITATIVE = 203,
|
||||
HC_NO_CONTENT = 204,
|
||||
HC_PARTIAL_CONTENT = 206,
|
||||
|
||||
HC_MULTIPLE_CHOICES = 300,
|
||||
HC_MOVED_PERMANENTLY = 301,
|
||||
HC_FOUND = 302,
|
||||
HC_SEE_OTHER = 303,
|
||||
HC_NOT_MODIFIED = 304,
|
||||
HC_MOVED_TEMPORARILY = 307,
|
||||
|
||||
HC_BAD_REQUEST = 400,
|
||||
HC_UNAUTHORIZED = 401,
|
||||
HC_FORBIDDEN = 403,
|
||||
HC_NOT_FOUND = 404,
|
||||
HC_PROXY_AUTHENTICATION_REQUIRED = 407,
|
||||
HC_GONE = 410,
|
||||
|
||||
HC_INTERNAL_SERVER_ERROR = 500,
|
||||
HC_NOT_IMPLEMENTED = 501,
|
||||
HC_SERVICE_UNAVAILABLE = 503,
|
||||
};
|
||||
|
||||
enum HttpVersion {
|
||||
HVER_1_0, HVER_1_1, HVER_UNKNOWN,
|
||||
HVER_LAST = HVER_UNKNOWN
|
||||
};
|
||||
|
||||
enum HttpVerb {
|
||||
HV_GET, HV_POST, HV_PUT, HV_DELETE, HV_CONNECT, HV_HEAD,
|
||||
HV_LAST = HV_HEAD
|
||||
};
|
||||
|
||||
enum HttpError {
|
||||
HE_NONE,
|
||||
HE_PROTOCOL, // Received non-valid HTTP data
|
||||
HE_DISCONNECTED, // Connection closed unexpectedly
|
||||
HE_OVERFLOW, // Received too much data for internal buffers
|
||||
HE_CONNECT_FAILED, // The socket failed to connect.
|
||||
HE_SOCKET_ERROR, // An error occurred on a connected socket
|
||||
HE_SHUTDOWN, // Http object is being destroyed
|
||||
HE_OPERATION_CANCELLED, // Connection aborted locally
|
||||
HE_AUTH, // Proxy Authentication Required
|
||||
HE_CERTIFICATE_EXPIRED, // During SSL negotiation
|
||||
HE_STREAM, // Problem reading or writing to the document
|
||||
HE_CACHE, // Problem reading from cache
|
||||
HE_DEFAULT
|
||||
};
|
||||
|
||||
enum HttpHeader {
|
||||
HH_AGE,
|
||||
HH_CACHE_CONTROL,
|
||||
HH_CONNECTION,
|
||||
HH_CONTENT_DISPOSITION,
|
||||
HH_CONTENT_LENGTH,
|
||||
HH_CONTENT_RANGE,
|
||||
HH_CONTENT_TYPE,
|
||||
HH_COOKIE,
|
||||
HH_DATE,
|
||||
HH_ETAG,
|
||||
HH_EXPIRES,
|
||||
HH_HOST,
|
||||
HH_IF_MODIFIED_SINCE,
|
||||
HH_IF_NONE_MATCH,
|
||||
HH_KEEP_ALIVE,
|
||||
HH_LAST_MODIFIED,
|
||||
HH_LOCATION,
|
||||
HH_PROXY_AUTHENTICATE,
|
||||
HH_PROXY_AUTHORIZATION,
|
||||
HH_PROXY_CONNECTION,
|
||||
HH_RANGE,
|
||||
HH_SET_COOKIE,
|
||||
HH_TE,
|
||||
HH_TRAILERS,
|
||||
HH_TRANSFER_ENCODING,
|
||||
HH_UPGRADE,
|
||||
HH_USER_AGENT,
|
||||
HH_WWW_AUTHENTICATE,
|
||||
HH_LAST = HH_WWW_AUTHENTICATE
|
||||
};
|
||||
|
||||
const uint16_t HTTP_DEFAULT_PORT = 80;
|
||||
const uint16_t HTTP_SECURE_PORT = 443;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Utility Functions
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline HttpError mkerr(HttpError err, HttpError def_err = HE_DEFAULT) {
|
||||
return (err != HE_NONE) ? err : def_err;
|
||||
}
|
||||
|
||||
const char* ToString(HttpVersion version);
|
||||
bool FromString(HttpVersion& version, const std::string& str);
|
||||
|
||||
const char* ToString(HttpVerb verb);
|
||||
bool FromString(HttpVerb& verb, const std::string& str);
|
||||
|
||||
const char* ToString(HttpHeader header);
|
||||
bool FromString(HttpHeader& header, const std::string& str);
|
||||
|
||||
inline bool HttpCodeIsInformational(uint32_t code) {
|
||||
return ((code / 100) == 1);
|
||||
}
|
||||
inline bool HttpCodeIsSuccessful(uint32_t code) {
|
||||
return ((code / 100) == 2);
|
||||
}
|
||||
inline bool HttpCodeIsRedirection(uint32_t code) {
|
||||
return ((code / 100) == 3);
|
||||
}
|
||||
inline bool HttpCodeIsClientError(uint32_t code) {
|
||||
return ((code / 100) == 4);
|
||||
}
|
||||
inline bool HttpCodeIsServerError(uint32_t code) {
|
||||
return ((code / 100) == 5);
|
||||
}
|
||||
|
||||
bool HttpCodeHasBody(uint32_t code);
|
||||
bool HttpCodeIsCacheable(uint32_t code);
|
||||
bool HttpHeaderIsEndToEnd(HttpHeader header);
|
||||
bool HttpHeaderIsCollapsible(HttpHeader header);
|
||||
|
||||
struct HttpData;
|
||||
bool HttpShouldKeepAlive(const HttpData& data);
|
||||
|
||||
typedef std::pair<std::string, std::string> HttpAttribute;
|
||||
typedef std::vector<HttpAttribute> HttpAttributeList;
|
||||
void HttpComposeAttributes(const HttpAttributeList& attributes, char separator,
|
||||
std::string* composed);
|
||||
void HttpParseAttributes(const char * data, size_t len,
|
||||
HttpAttributeList& attributes);
|
||||
bool HttpHasAttribute(const HttpAttributeList& attributes,
|
||||
const std::string& name,
|
||||
std::string* value);
|
||||
bool HttpHasNthAttribute(HttpAttributeList& attributes,
|
||||
size_t index,
|
||||
std::string* name,
|
||||
std::string* value);
|
||||
|
||||
// Convert RFC1123 date (DoW, DD Mon YYYY HH:MM:SS TZ) to unix timestamp
|
||||
bool HttpDateToSeconds(const std::string& date, time_t* seconds);
|
||||
|
||||
inline uint16_t HttpDefaultPort(bool secure) {
|
||||
return secure ? HTTP_SECURE_PORT : HTTP_DEFAULT_PORT;
|
||||
}
|
||||
|
||||
// Returns the http server notation for a given address
|
||||
std::string HttpAddress(const SocketAddress& address, bool secure);
|
||||
|
||||
// functional for insensitive std::string compare
|
||||
struct iless {
|
||||
bool operator()(const std::string& lhs, const std::string& rhs) const {
|
||||
return (::_stricmp(lhs.c_str(), rhs.c_str()) < 0);
|
||||
}
|
||||
};
|
||||
|
||||
// put quotes around a string and escape any quotes inside it
|
||||
std::string quote(const std::string& str);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Url
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class CTYPE>
|
||||
class Url {
|
||||
public:
|
||||
typedef typename Traits<CTYPE>::string string;
|
||||
|
||||
// TODO: Implement Encode/Decode
|
||||
static int Encode(const CTYPE* source, CTYPE* destination, size_t len);
|
||||
static int Encode(const string& source, string& destination);
|
||||
static int Decode(const CTYPE* source, CTYPE* destination, size_t len);
|
||||
static int Decode(const string& source, string& destination);
|
||||
|
||||
Url(const string& url) { do_set_url(url.c_str(), url.size()); }
|
||||
Url(const string& path, const string& host, uint16_t port = HTTP_DEFAULT_PORT)
|
||||
: host_(host), port_(port), secure_(HTTP_SECURE_PORT == port) {
|
||||
set_full_path(path);
|
||||
}
|
||||
|
||||
bool valid() const { return !host_.empty(); }
|
||||
void clear() {
|
||||
host_.clear();
|
||||
port_ = HTTP_DEFAULT_PORT;
|
||||
secure_ = false;
|
||||
path_.assign(1, static_cast<CTYPE>('/'));
|
||||
query_.clear();
|
||||
}
|
||||
|
||||
void set_url(const string& val) {
|
||||
do_set_url(val.c_str(), val.size());
|
||||
}
|
||||
string url() const {
|
||||
string val; do_get_url(&val); return val;
|
||||
}
|
||||
|
||||
void set_address(const string& val) {
|
||||
do_set_address(val.c_str(), val.size());
|
||||
}
|
||||
string address() const {
|
||||
string val; do_get_address(&val); return val;
|
||||
}
|
||||
|
||||
void set_full_path(const string& val) {
|
||||
do_set_full_path(val.c_str(), val.size());
|
||||
}
|
||||
string full_path() const {
|
||||
string val; do_get_full_path(&val); return val;
|
||||
}
|
||||
|
||||
void set_host(const string& val) { host_ = val; }
|
||||
const string& host() const { return host_; }
|
||||
|
||||
void set_port(uint16_t val) { port_ = val; }
|
||||
uint16_t port() const { return port_; }
|
||||
|
||||
void set_secure(bool val) { secure_ = val; }
|
||||
bool secure() const { return secure_; }
|
||||
|
||||
void set_path(const string& val) {
|
||||
if (val.empty()) {
|
||||
path_.assign(1, static_cast<CTYPE>('/'));
|
||||
} else {
|
||||
RTC_DCHECK(val[0] == static_cast<CTYPE>('/'));
|
||||
path_ = val;
|
||||
}
|
||||
}
|
||||
const string& path() const { return path_; }
|
||||
|
||||
void set_query(const string& val) {
|
||||
RTC_DCHECK(val.empty() || (val[0] == static_cast<CTYPE>('?')));
|
||||
query_ = val;
|
||||
}
|
||||
const string& query() const { return query_; }
|
||||
|
||||
bool get_attribute(const string& name, string* value) const;
|
||||
|
||||
private:
|
||||
void do_set_url(const CTYPE* val, size_t len);
|
||||
void do_set_address(const CTYPE* val, size_t len);
|
||||
void do_set_full_path(const CTYPE* val, size_t len);
|
||||
|
||||
void do_get_url(string* val) const;
|
||||
void do_get_address(string* val) const;
|
||||
void do_get_full_path(string* val) const;
|
||||
|
||||
string host_, path_, query_;
|
||||
uint16_t port_;
|
||||
bool secure_;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// HttpData
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct HttpData {
|
||||
typedef std::multimap<std::string, std::string, iless> HeaderMap;
|
||||
typedef HeaderMap::const_iterator const_iterator;
|
||||
typedef HeaderMap::iterator iterator;
|
||||
|
||||
HttpVersion version;
|
||||
std::unique_ptr<StreamInterface> document;
|
||||
|
||||
HttpData();
|
||||
|
||||
enum HeaderCombine { HC_YES, HC_NO, HC_AUTO, HC_REPLACE, HC_NEW };
|
||||
void changeHeader(const std::string& name, const std::string& value,
|
||||
HeaderCombine combine);
|
||||
inline void addHeader(const std::string& name, const std::string& value,
|
||||
bool append = true) {
|
||||
changeHeader(name, value, append ? HC_AUTO : HC_NO);
|
||||
}
|
||||
inline void setHeader(const std::string& name, const std::string& value,
|
||||
bool overwrite = true) {
|
||||
changeHeader(name, value, overwrite ? HC_REPLACE : HC_NEW);
|
||||
}
|
||||
// Returns count of erased headers
|
||||
size_t clearHeader(const std::string& name);
|
||||
// Returns iterator to next header
|
||||
iterator clearHeader(iterator header);
|
||||
|
||||
// keep in mind, this may not do what you want in the face of multiple headers
|
||||
bool hasHeader(const std::string& name, std::string* value) const;
|
||||
|
||||
inline const_iterator begin() const {
|
||||
return headers_.begin();
|
||||
}
|
||||
inline const_iterator end() const {
|
||||
return headers_.end();
|
||||
}
|
||||
inline iterator begin() {
|
||||
return headers_.begin();
|
||||
}
|
||||
inline iterator end() {
|
||||
return headers_.end();
|
||||
}
|
||||
inline const_iterator begin(const std::string& name) const {
|
||||
return headers_.lower_bound(name);
|
||||
}
|
||||
inline const_iterator end(const std::string& name) const {
|
||||
return headers_.upper_bound(name);
|
||||
}
|
||||
inline iterator begin(const std::string& name) {
|
||||
return headers_.lower_bound(name);
|
||||
}
|
||||
inline iterator end(const std::string& name) {
|
||||
return headers_.upper_bound(name);
|
||||
}
|
||||
|
||||
// Convenience methods using HttpHeader
|
||||
inline void changeHeader(HttpHeader header, const std::string& value,
|
||||
HeaderCombine combine) {
|
||||
changeHeader(ToString(header), value, combine);
|
||||
}
|
||||
inline void addHeader(HttpHeader header, const std::string& value,
|
||||
bool append = true) {
|
||||
addHeader(ToString(header), value, append);
|
||||
}
|
||||
inline void setHeader(HttpHeader header, const std::string& value,
|
||||
bool overwrite = true) {
|
||||
setHeader(ToString(header), value, overwrite);
|
||||
}
|
||||
inline void clearHeader(HttpHeader header) {
|
||||
clearHeader(ToString(header));
|
||||
}
|
||||
inline bool hasHeader(HttpHeader header, std::string* value) const {
|
||||
return hasHeader(ToString(header), value);
|
||||
}
|
||||
inline const_iterator begin(HttpHeader header) const {
|
||||
return headers_.lower_bound(ToString(header));
|
||||
}
|
||||
inline const_iterator end(HttpHeader header) const {
|
||||
return headers_.upper_bound(ToString(header));
|
||||
}
|
||||
inline iterator begin(HttpHeader header) {
|
||||
return headers_.lower_bound(ToString(header));
|
||||
}
|
||||
inline iterator end(HttpHeader header) {
|
||||
return headers_.upper_bound(ToString(header));
|
||||
}
|
||||
|
||||
void setContent(const std::string& content_type, StreamInterface* document);
|
||||
void setDocumentAndLength(StreamInterface* document);
|
||||
|
||||
virtual size_t formatLeader(char* buffer, size_t size) const = 0;
|
||||
virtual HttpError parseLeader(const char* line, size_t len) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~HttpData();
|
||||
void clear(bool release_document);
|
||||
void copy(const HttpData& src);
|
||||
|
||||
private:
|
||||
HeaderMap headers_;
|
||||
};
|
||||
|
||||
struct HttpRequestData : public HttpData {
|
||||
HttpVerb verb;
|
||||
std::string path;
|
||||
|
||||
HttpRequestData() : verb(HV_GET) { }
|
||||
|
||||
void clear(bool release_document);
|
||||
void copy(const HttpRequestData& src);
|
||||
|
||||
size_t formatLeader(char* buffer, size_t size) const override;
|
||||
HttpError parseLeader(const char* line, size_t len) override;
|
||||
|
||||
bool getAbsoluteUri(std::string* uri) const;
|
||||
bool getRelativeUri(std::string* host, std::string* path) const;
|
||||
};
|
||||
|
||||
struct HttpResponseData : public HttpData {
|
||||
uint32_t scode;
|
||||
std::string message;
|
||||
|
||||
HttpResponseData() : scode(HC_INTERNAL_SERVER_ERROR) { }
|
||||
void clear(bool release_document);
|
||||
void copy(const HttpResponseData& src);
|
||||
|
||||
// Convenience methods
|
||||
void set_success(uint32_t scode = HC_OK);
|
||||
void set_success(const std::string& content_type,
|
||||
StreamInterface* document,
|
||||
uint32_t scode = HC_OK);
|
||||
void set_redirect(const std::string& location,
|
||||
uint32_t scode = HC_MOVED_TEMPORARILY);
|
||||
void set_error(uint32_t scode);
|
||||
|
||||
size_t formatLeader(char* buffer, size_t size) const override;
|
||||
HttpError parseLeader(const char* line, size_t len) override;
|
||||
};
|
||||
|
||||
struct HttpTransaction {
|
||||
HttpRequestData request;
|
||||
HttpResponseData response;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Http Authentication
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct HttpAuthContext {
|
||||
std::string auth_method;
|
||||
HttpAuthContext(const std::string& auth) : auth_method(auth) { }
|
||||
virtual ~HttpAuthContext() { }
|
||||
};
|
||||
|
||||
enum HttpAuthResult { HAR_RESPONSE, HAR_IGNORE, HAR_CREDENTIALS, HAR_ERROR };
|
||||
|
||||
// 'context' is used by this function to record information between calls.
|
||||
// Start by passing a null pointer, then pass the same pointer each additional
|
||||
// call. When the authentication attempt is finished, delete the context.
|
||||
HttpAuthResult HttpAuthenticate(
|
||||
const char * challenge, size_t len,
|
||||
const SocketAddress& server,
|
||||
const std::string& method, const std::string& uri,
|
||||
const std::string& username, const CryptString& password,
|
||||
HttpAuthContext *& context, std::string& response, std::string& auth_method);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // WEBRTC_BASE_HTTPCOMMON_H__
|
||||
#endif // WEBRTC_BASE_HTTPCOMMON_H_
|
||||
|
||||
@ -8,132 +8,12 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_BASE_HTTPSERVER_H__
|
||||
#define WEBRTC_BASE_HTTPSERVER_H__
|
||||
#ifndef WEBRTC_BASE_HTTPSERVER_H_
|
||||
#define WEBRTC_BASE_HTTPSERVER_H_
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
#include "webrtc/base/httpbase.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/httpserver.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
class AsyncSocket;
|
||||
class HttpServer;
|
||||
class SocketAddress;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// HttpServer
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
const int HTTP_INVALID_CONNECTION_ID = 0;
|
||||
|
||||
struct HttpServerTransaction : public HttpTransaction {
|
||||
public:
|
||||
HttpServerTransaction(int id) : connection_id_(id) { }
|
||||
int connection_id() const { return connection_id_; }
|
||||
|
||||
private:
|
||||
int connection_id_;
|
||||
};
|
||||
|
||||
class HttpServer {
|
||||
public:
|
||||
HttpServer();
|
||||
virtual ~HttpServer();
|
||||
|
||||
int HandleConnection(StreamInterface* stream);
|
||||
// Due to sigslot issues, we can't destroy some streams at an arbitrary time.
|
||||
sigslot::signal3<HttpServer*, int, StreamInterface*> SignalConnectionClosed;
|
||||
|
||||
// This signal occurs when the HTTP request headers have been received, but
|
||||
// before the request body is written to the request document. By default,
|
||||
// the request document is a MemoryStream. By handling this signal, the
|
||||
// document can be overridden, in which case the third signal argument should
|
||||
// be set to true. In the case where the request body should be ignored,
|
||||
// the document can be set to null. Note that the transaction object is still
|
||||
// owened by the HttpServer at this point.
|
||||
sigslot::signal3<HttpServer*, HttpServerTransaction*, bool*>
|
||||
SignalHttpRequestHeader;
|
||||
|
||||
// An HTTP request has been made, and is available in the transaction object.
|
||||
// Populate the transaction's response, and then return the object via the
|
||||
// Respond method. Note that during this time, ownership of the transaction
|
||||
// object is transferred, so it may be passed between threads, although
|
||||
// respond must be called on the server's active thread.
|
||||
sigslot::signal2<HttpServer*, HttpServerTransaction*> SignalHttpRequest;
|
||||
void Respond(HttpServerTransaction* transaction);
|
||||
|
||||
// If you want to know when a request completes, listen to this event.
|
||||
sigslot::signal3<HttpServer*, HttpServerTransaction*, int>
|
||||
SignalHttpRequestComplete;
|
||||
|
||||
// Stop processing the connection indicated by connection_id.
|
||||
// Unless force is true, the server will complete sending a response that is
|
||||
// in progress.
|
||||
void Close(int connection_id, bool force);
|
||||
void CloseAll(bool force);
|
||||
|
||||
// After calling CloseAll, this event is signalled to indicate that all
|
||||
// outstanding connections have closed.
|
||||
sigslot::signal1<HttpServer*> SignalCloseAllComplete;
|
||||
|
||||
private:
|
||||
class Connection : private IHttpNotify {
|
||||
public:
|
||||
Connection(int connection_id, HttpServer* server);
|
||||
~Connection() override;
|
||||
|
||||
void BeginProcess(StreamInterface* stream);
|
||||
StreamInterface* EndProcess();
|
||||
|
||||
void Respond(HttpServerTransaction* transaction);
|
||||
void InitiateClose(bool force);
|
||||
|
||||
// IHttpNotify Interface
|
||||
HttpError onHttpHeaderComplete(bool chunked, size_t& data_size) override;
|
||||
void onHttpComplete(HttpMode mode, HttpError err) override;
|
||||
void onHttpClosed(HttpError err) override;
|
||||
|
||||
int connection_id_;
|
||||
HttpServer* server_;
|
||||
HttpBase base_;
|
||||
HttpServerTransaction* current_;
|
||||
bool signalling_, close_;
|
||||
};
|
||||
|
||||
Connection* Find(int connection_id);
|
||||
void Remove(int connection_id);
|
||||
|
||||
friend class Connection;
|
||||
typedef std::map<int,Connection*> ConnectionMap;
|
||||
|
||||
ConnectionMap connections_;
|
||||
int next_connection_id_;
|
||||
bool closing_;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
class HttpListenServer : public HttpServer, public sigslot::has_slots<> {
|
||||
public:
|
||||
HttpListenServer();
|
||||
~HttpListenServer() override;
|
||||
|
||||
int Listen(const SocketAddress& address);
|
||||
bool GetAddress(SocketAddress* address) const;
|
||||
void StopListening();
|
||||
|
||||
private:
|
||||
void OnReadEvent(AsyncSocket* socket);
|
||||
void OnConnectionClosed(HttpServer* server, int connection_id,
|
||||
StreamInterface* stream);
|
||||
|
||||
std::unique_ptr<AsyncSocket> listener_;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // WEBRTC_BASE_HTTPSERVER_H__
|
||||
#endif // WEBRTC_BASE_HTTPSERVER_H_
|
||||
|
||||
@ -11,29 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_IFADDRS_ANDROID_H_
|
||||
#define WEBRTC_BASE_IFADDRS_ANDROID_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
|
||||
// Implementation of getifaddrs for Android.
|
||||
// Fills out a list of ifaddr structs (see below) which contain information
|
||||
// about every network interface available on the host.
|
||||
// See 'man getifaddrs' on Linux or OS X (nb: it is not a POSIX function).
|
||||
struct ifaddrs {
|
||||
struct ifaddrs* ifa_next;
|
||||
char* ifa_name;
|
||||
unsigned int ifa_flags;
|
||||
struct sockaddr* ifa_addr;
|
||||
struct sockaddr* ifa_netmask;
|
||||
// Real ifaddrs has broadcast, point to point and data members.
|
||||
// We don't need them (yet?).
|
||||
};
|
||||
|
||||
namespace rtc {
|
||||
|
||||
int getifaddrs(struct ifaddrs** result);
|
||||
void freeifaddrs(struct ifaddrs* addrs);
|
||||
|
||||
} // namespace rtc
|
||||
// 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/ifaddrs-android.h"
|
||||
|
||||
#endif // WEBRTC_BASE_IFADDRS_ANDROID_H_
|
||||
|
||||
@ -11,35 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_IFADDRS_CONVERTER_H_
|
||||
#define WEBRTC_BASE_IFADDRS_CONVERTER_H_
|
||||
|
||||
#if defined(WEBRTC_ANDROID)
|
||||
#include "webrtc/base/ifaddrs-android.h"
|
||||
#else
|
||||
#include <ifaddrs.h>
|
||||
#endif // WEBRTC_ANDROID
|
||||
|
||||
#include "webrtc/base/ipaddress.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
// This class converts native interface addresses to our internal IPAddress
|
||||
// class. Subclasses should override ConvertNativeToIPAttributes to implement
|
||||
// the different ways of retrieving IPv6 attributes for various POSIX platforms.
|
||||
class IfAddrsConverter {
|
||||
public:
|
||||
IfAddrsConverter();
|
||||
virtual ~IfAddrsConverter();
|
||||
virtual bool ConvertIfAddrsToIPAddress(const struct ifaddrs* interface,
|
||||
InterfaceAddress* ipaddress,
|
||||
IPAddress* mask);
|
||||
|
||||
protected:
|
||||
virtual bool ConvertNativeAttributesToIPAttributes(
|
||||
const struct ifaddrs* interface,
|
||||
int* ip_attributes);
|
||||
};
|
||||
|
||||
IfAddrsConverter* CreateIfAddrsConverter();
|
||||
|
||||
} // namespace rtc
|
||||
// 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/ifaddrs_converter.h"
|
||||
|
||||
#endif // WEBRTC_BASE_IFADDRS_CONVERTER_H_
|
||||
|
||||
@ -11,23 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_IGNORE_WUNDEF_H_
|
||||
#define WEBRTC_BASE_IGNORE_WUNDEF_H_
|
||||
|
||||
// If a header file uses #if on possibly undefined macros (and it's for some
|
||||
// reason not possible to just fix the header file), include it like this:
|
||||
//
|
||||
// RTC_PUSH_IGNORING_WUNDEF()
|
||||
// #include "misbehaving_header.h"
|
||||
// RTC_POP_IGNORING_WUNDEF()
|
||||
//
|
||||
// This will cause the compiler to not emit -Wundef warnings for that file.
|
||||
|
||||
#ifdef __clang__
|
||||
#define RTC_PUSH_IGNORING_WUNDEF() \
|
||||
_Pragma("clang diagnostic push") \
|
||||
_Pragma("clang diagnostic ignored \"-Wundef\"")
|
||||
#define RTC_POP_IGNORING_WUNDEF() _Pragma("clang diagnostic pop")
|
||||
#else
|
||||
#define RTC_PUSH_IGNORING_WUNDEF()
|
||||
#define RTC_POP_IGNORING_WUNDEF()
|
||||
#endif // __clang__
|
||||
// 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/ignore_wundef.h"
|
||||
|
||||
#endif // WEBRTC_BASE_IGNORE_WUNDEF_H_
|
||||
|
||||
@ -11,178 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_IPADDRESS_H_
|
||||
#define WEBRTC_BASE_IPADDRESS_H_
|
||||
|
||||
#if defined(WEBRTC_POSIX)
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#if defined(WEBRTC_WIN)
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/base/basictypes.h"
|
||||
#include "webrtc/base/byteorder.h"
|
||||
#if defined(WEBRTC_WIN)
|
||||
#include "webrtc/base/win32.h"
|
||||
#endif
|
||||
|
||||
namespace rtc {
|
||||
|
||||
enum IPv6AddressFlag {
|
||||
IPV6_ADDRESS_FLAG_NONE = 0x00,
|
||||
|
||||
// Temporary address is dynamic by nature and will not carry MAC
|
||||
// address.
|
||||
IPV6_ADDRESS_FLAG_TEMPORARY = 1 << 0,
|
||||
|
||||
// Temporary address could become deprecated once the preferred
|
||||
// lifetime is reached. It is still valid but just shouldn't be used
|
||||
// to create new connection.
|
||||
IPV6_ADDRESS_FLAG_DEPRECATED = 1 << 1,
|
||||
};
|
||||
|
||||
// Version-agnostic IP address class, wraps a union of in_addr and in6_addr.
|
||||
class IPAddress {
|
||||
public:
|
||||
IPAddress() : family_(AF_UNSPEC) {
|
||||
::memset(&u_, 0, sizeof(u_));
|
||||
}
|
||||
|
||||
explicit IPAddress(const in_addr& ip4) : family_(AF_INET) {
|
||||
memset(&u_, 0, sizeof(u_));
|
||||
u_.ip4 = ip4;
|
||||
}
|
||||
|
||||
explicit IPAddress(const in6_addr& ip6) : family_(AF_INET6) {
|
||||
u_.ip6 = ip6;
|
||||
}
|
||||
|
||||
explicit IPAddress(uint32_t ip_in_host_byte_order) : family_(AF_INET) {
|
||||
memset(&u_, 0, sizeof(u_));
|
||||
u_.ip4.s_addr = HostToNetwork32(ip_in_host_byte_order);
|
||||
}
|
||||
|
||||
IPAddress(const IPAddress& other) : family_(other.family_) {
|
||||
::memcpy(&u_, &other.u_, sizeof(u_));
|
||||
}
|
||||
|
||||
virtual ~IPAddress() {}
|
||||
|
||||
const IPAddress & operator=(const IPAddress& other) {
|
||||
family_ = other.family_;
|
||||
::memcpy(&u_, &other.u_, sizeof(u_));
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const IPAddress& other) const;
|
||||
bool operator!=(const IPAddress& other) const;
|
||||
bool operator <(const IPAddress& other) const;
|
||||
bool operator >(const IPAddress& other) const;
|
||||
friend std::ostream& operator<<(std::ostream& os, const IPAddress& addr);
|
||||
|
||||
int family() const { return family_; }
|
||||
in_addr ipv4_address() const;
|
||||
in6_addr ipv6_address() const;
|
||||
|
||||
// Returns the number of bytes needed to store the raw address.
|
||||
size_t Size() const;
|
||||
|
||||
// Wraps inet_ntop.
|
||||
std::string ToString() const;
|
||||
|
||||
// Same as ToString but anonymizes it by hiding the last part.
|
||||
std::string ToSensitiveString() const;
|
||||
|
||||
// Returns an unmapped address from a possibly-mapped address.
|
||||
// Returns the same address if this isn't a mapped address.
|
||||
IPAddress Normalized() const;
|
||||
|
||||
// Returns this address as an IPv6 address.
|
||||
// Maps v4 addresses (as ::ffff:a.b.c.d), returns v6 addresses unchanged.
|
||||
IPAddress AsIPv6Address() const;
|
||||
|
||||
// For socketaddress' benefit. Returns the IP in host byte order.
|
||||
uint32_t v4AddressAsHostOrderInteger() const;
|
||||
|
||||
// Whether this is an unspecified IP address.
|
||||
bool IsNil() const;
|
||||
|
||||
private:
|
||||
int family_;
|
||||
union {
|
||||
in_addr ip4;
|
||||
in6_addr ip6;
|
||||
} u_;
|
||||
};
|
||||
|
||||
// IP class which could represent IPv6 address flags which is only
|
||||
// meaningful in IPv6 case.
|
||||
class InterfaceAddress : public IPAddress {
|
||||
public:
|
||||
InterfaceAddress() : ipv6_flags_(IPV6_ADDRESS_FLAG_NONE) {}
|
||||
|
||||
InterfaceAddress(IPAddress ip)
|
||||
: IPAddress(ip), ipv6_flags_(IPV6_ADDRESS_FLAG_NONE) {}
|
||||
|
||||
InterfaceAddress(IPAddress addr, int ipv6_flags)
|
||||
: IPAddress(addr), ipv6_flags_(ipv6_flags) {}
|
||||
|
||||
InterfaceAddress(const in6_addr& ip6, int ipv6_flags)
|
||||
: IPAddress(ip6), ipv6_flags_(ipv6_flags) {}
|
||||
|
||||
const InterfaceAddress & operator=(const InterfaceAddress& other);
|
||||
|
||||
bool operator==(const InterfaceAddress& other) const;
|
||||
bool operator!=(const InterfaceAddress& other) const;
|
||||
|
||||
int ipv6_flags() const { return ipv6_flags_; }
|
||||
friend std::ostream& operator<<(std::ostream& os,
|
||||
const InterfaceAddress& addr);
|
||||
|
||||
private:
|
||||
int ipv6_flags_;
|
||||
};
|
||||
|
||||
bool IPFromAddrInfo(struct addrinfo* info, IPAddress* out);
|
||||
bool IPFromString(const std::string& str, IPAddress* out);
|
||||
bool IPFromString(const std::string& str, int flags,
|
||||
InterfaceAddress* out);
|
||||
bool IPIsAny(const IPAddress& ip);
|
||||
bool IPIsLoopback(const IPAddress& ip);
|
||||
bool IPIsPrivate(const IPAddress& ip);
|
||||
bool IPIsUnspec(const IPAddress& ip);
|
||||
size_t HashIP(const IPAddress& ip);
|
||||
|
||||
// These are only really applicable for IPv6 addresses.
|
||||
bool IPIs6Bone(const IPAddress& ip);
|
||||
bool IPIs6To4(const IPAddress& ip);
|
||||
bool IPIsLinkLocal(const IPAddress& ip);
|
||||
bool IPIsMacBased(const IPAddress& ip);
|
||||
bool IPIsSiteLocal(const IPAddress& ip);
|
||||
bool IPIsTeredo(const IPAddress& ip);
|
||||
bool IPIsULA(const IPAddress& ip);
|
||||
bool IPIsV4Compatibility(const IPAddress& ip);
|
||||
bool IPIsV4Mapped(const IPAddress& ip);
|
||||
|
||||
// Returns the precedence value for this IP as given in RFC3484.
|
||||
int IPAddressPrecedence(const IPAddress& ip);
|
||||
|
||||
// Returns 'ip' truncated to be 'length' bits long.
|
||||
IPAddress TruncateIP(const IPAddress& ip, int length);
|
||||
|
||||
IPAddress GetLoopbackIP(int family);
|
||||
IPAddress GetAnyIP(int family);
|
||||
|
||||
// Returns the number of contiguously set bits, counting from the MSB in network
|
||||
// byte order, in this IPAddress. Bits after the first 0 encountered are not
|
||||
// counted.
|
||||
int CountIPMaskBits(IPAddress mask);
|
||||
|
||||
} // namespace rtc
|
||||
// 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/ipaddress.h"
|
||||
|
||||
#endif // WEBRTC_BASE_IPADDRESS_H_
|
||||
|
||||
@ -11,81 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_JSON_H_
|
||||
#define WEBRTC_BASE_JSON_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#if !defined(WEBRTC_EXTERNAL_JSON)
|
||||
#include "json/json.h"
|
||||
#else
|
||||
#include "third_party/jsoncpp/json.h"
|
||||
#endif
|
||||
|
||||
namespace rtc {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// JSON Helpers
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Robust conversion operators, better than the ones in JsonCpp.
|
||||
bool GetIntFromJson(const Json::Value& in, int* out);
|
||||
bool GetUIntFromJson(const Json::Value& in, unsigned int* out);
|
||||
bool GetStringFromJson(const Json::Value& in, std::string* out);
|
||||
bool GetBoolFromJson(const Json::Value& in, bool* out);
|
||||
bool GetDoubleFromJson(const Json::Value& in, double* out);
|
||||
|
||||
// Pull values out of a JSON array.
|
||||
bool GetValueFromJsonArray(const Json::Value& in, size_t n,
|
||||
Json::Value* out);
|
||||
bool GetIntFromJsonArray(const Json::Value& in, size_t n,
|
||||
int* out);
|
||||
bool GetUIntFromJsonArray(const Json::Value& in, size_t n,
|
||||
unsigned int* out);
|
||||
bool GetStringFromJsonArray(const Json::Value& in, size_t n,
|
||||
std::string* out);
|
||||
bool GetBoolFromJsonArray(const Json::Value& in, size_t n,
|
||||
bool* out);
|
||||
bool GetDoubleFromJsonArray(const Json::Value& in, size_t n,
|
||||
double* out);
|
||||
|
||||
// Convert json arrays to std::vector
|
||||
bool JsonArrayToValueVector(const Json::Value& in,
|
||||
std::vector<Json::Value>* out);
|
||||
bool JsonArrayToIntVector(const Json::Value& in,
|
||||
std::vector<int>* out);
|
||||
bool JsonArrayToUIntVector(const Json::Value& in,
|
||||
std::vector<unsigned int>* out);
|
||||
bool JsonArrayToStringVector(const Json::Value& in,
|
||||
std::vector<std::string>* out);
|
||||
bool JsonArrayToBoolVector(const Json::Value& in,
|
||||
std::vector<bool>* out);
|
||||
bool JsonArrayToDoubleVector(const Json::Value& in,
|
||||
std::vector<double>* out);
|
||||
|
||||
// Convert std::vector to json array
|
||||
Json::Value ValueVectorToJsonArray(const std::vector<Json::Value>& in);
|
||||
Json::Value IntVectorToJsonArray(const std::vector<int>& in);
|
||||
Json::Value UIntVectorToJsonArray(const std::vector<unsigned int>& in);
|
||||
Json::Value StringVectorToJsonArray(const std::vector<std::string>& in);
|
||||
Json::Value BoolVectorToJsonArray(const std::vector<bool>& in);
|
||||
Json::Value DoubleVectorToJsonArray(const std::vector<double>& in);
|
||||
|
||||
// Pull values out of a JSON object.
|
||||
bool GetValueFromJsonObject(const Json::Value& in, const std::string& k,
|
||||
Json::Value* out);
|
||||
bool GetIntFromJsonObject(const Json::Value& in, const std::string& k,
|
||||
int* out);
|
||||
bool GetUIntFromJsonObject(const Json::Value& in, const std::string& k,
|
||||
unsigned int* out);
|
||||
bool GetStringFromJsonObject(const Json::Value& in, const std::string& k,
|
||||
std::string* out);
|
||||
bool GetBoolFromJsonObject(const Json::Value& in, const std::string& k,
|
||||
bool* out);
|
||||
bool GetDoubleFromJsonObject(const Json::Value& in, const std::string& k,
|
||||
double* out);
|
||||
|
||||
// Writes out a Json value as a string.
|
||||
std::string JsonValueToString(const Json::Value& json);
|
||||
|
||||
} // namespace rtc
|
||||
// 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/json.h"
|
||||
|
||||
#endif // WEBRTC_BASE_JSON_H_
|
||||
|
||||
@ -11,33 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_KEEP_REF_UNTIL_DONE_H_
|
||||
#define WEBRTC_BASE_KEEP_REF_UNTIL_DONE_H_
|
||||
|
||||
#include "webrtc/base/bind.h"
|
||||
#include "webrtc/base/callback.h"
|
||||
#include "webrtc/base/refcount.h"
|
||||
#include "webrtc/base/scoped_ref_ptr.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
namespace impl {
|
||||
template <class T>
|
||||
static inline void DoNothing(const scoped_refptr<T>& object) {}
|
||||
} // namespace impl
|
||||
|
||||
// KeepRefUntilDone keeps a reference to |object| until the returned
|
||||
// callback goes out of scope. If the returned callback is copied, the
|
||||
// reference will be released when the last callback goes out of scope.
|
||||
template <class ObjectT>
|
||||
static inline Callback0<void> KeepRefUntilDone(ObjectT* object) {
|
||||
return rtc::Bind(&impl::DoNothing<ObjectT>, scoped_refptr<ObjectT>(object));
|
||||
}
|
||||
|
||||
template <class ObjectT>
|
||||
static inline Callback0<void> KeepRefUntilDone(
|
||||
const scoped_refptr<ObjectT>& object) {
|
||||
return rtc::Bind(&impl::DoNothing<ObjectT>, object);
|
||||
}
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
// 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/keep_ref_until_done.h"
|
||||
|
||||
#endif // WEBRTC_BASE_KEEP_REF_UNTIL_DONE_H_
|
||||
|
||||
@ -11,47 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_LOCATION_H_
|
||||
#define WEBRTC_BASE_LOCATION_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "webrtc/base/stringize_macros.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
// Location provides basic info where of an object was constructed, or was
|
||||
// significantly brought to life.
|
||||
// This is a stripped down version of:
|
||||
// https://code.google.com/p/chromium/codesearch#chromium/src/base/location.h
|
||||
class Location {
|
||||
public:
|
||||
// Constructor should be called with a long-lived char*, such as __FILE__.
|
||||
// It assumes the provided value will persist as a global constant, and it
|
||||
// will not make a copy of it.
|
||||
//
|
||||
// TODO(deadbeef): Tracing is currently limited to 2 arguments, which is
|
||||
// why the file name and line number are combined into one argument.
|
||||
//
|
||||
// Once TracingV2 is available, separate the file name and line number.
|
||||
Location(const char* function_name, const char* file_and_line);
|
||||
Location();
|
||||
Location(const Location& other);
|
||||
Location& operator=(const Location& other);
|
||||
|
||||
const char* function_name() const { return function_name_; }
|
||||
const char* file_and_line() const { return file_and_line_; }
|
||||
|
||||
std::string ToString() const;
|
||||
|
||||
private:
|
||||
const char* function_name_;
|
||||
const char* file_and_line_;
|
||||
};
|
||||
|
||||
// Define a macro to record the current source location.
|
||||
#define RTC_FROM_HERE RTC_FROM_HERE_WITH_FUNCTION(__FUNCTION__)
|
||||
|
||||
#define RTC_FROM_HERE_WITH_FUNCTION(function_name) \
|
||||
::rtc::Location(function_name, __FILE__ ":" STRINGIZE(__LINE__))
|
||||
|
||||
} // namespace rtc
|
||||
// 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/location.h"
|
||||
|
||||
#endif // WEBRTC_BASE_LOCATION_H_
|
||||
|
||||
@ -46,325 +46,9 @@
|
||||
#ifndef WEBRTC_BASE_LOGGING_H_
|
||||
#define WEBRTC_BASE_LOGGING_H_
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <list>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#endif
|
||||
|
||||
#include "webrtc/base/basictypes.h"
|
||||
#include "webrtc/base/constructormagic.h"
|
||||
#include "webrtc/base/thread_annotations.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// ConstantLabel can be used to easily generate string names from constant
|
||||
// values. This can be useful for logging descriptive names of error messages.
|
||||
// Usage:
|
||||
// const ConstantLabel LIBRARY_ERRORS[] = {
|
||||
// KLABEL(SOME_ERROR),
|
||||
// KLABEL(SOME_OTHER_ERROR),
|
||||
// ...
|
||||
// LASTLABEL
|
||||
// }
|
||||
//
|
||||
// int err = LibraryFunc();
|
||||
// LOG(LS_ERROR) << "LibraryFunc returned: "
|
||||
// << ErrorName(err, LIBRARY_ERRORS);
|
||||
|
||||
struct ConstantLabel { int value; const char * label; };
|
||||
#define KLABEL(x) { x, #x }
|
||||
#define TLABEL(x, y) { x, y }
|
||||
#define LASTLABEL { 0, 0 }
|
||||
|
||||
const char* FindLabel(int value, const ConstantLabel entries[]);
|
||||
std::string ErrorName(int err, const ConstantLabel* err_table);
|
||||
|
||||
#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
|
||||
// Returns a UTF8 description from an OS X Status error.
|
||||
std::string DescriptionFromOSStatus(OSStatus err);
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Note that the non-standard LoggingSeverity aliases exist because they are
|
||||
// still in broad use. The meanings of the levels are:
|
||||
// LS_SENSITIVE: Information which should only be logged with the consent
|
||||
// of the user, due to privacy concerns.
|
||||
// LS_VERBOSE: This level is for data which we do not want to appear in the
|
||||
// normal debug log, but should appear in diagnostic logs.
|
||||
// LS_INFO: Chatty level used in debugging for all sorts of things, the default
|
||||
// in debug builds.
|
||||
// LS_WARNING: Something that may warrant investigation.
|
||||
// LS_ERROR: Something that should not have occurred.
|
||||
// LS_NONE: Don't log.
|
||||
enum LoggingSeverity {
|
||||
LS_SENSITIVE,
|
||||
LS_VERBOSE,
|
||||
LS_INFO,
|
||||
LS_WARNING,
|
||||
LS_ERROR,
|
||||
LS_NONE,
|
||||
INFO = LS_INFO,
|
||||
WARNING = LS_WARNING,
|
||||
LERROR = LS_ERROR
|
||||
};
|
||||
|
||||
// LogErrorContext assists in interpreting the meaning of an error value.
|
||||
enum LogErrorContext {
|
||||
ERRCTX_NONE,
|
||||
ERRCTX_ERRNO, // System-local errno
|
||||
ERRCTX_HRESULT, // Windows HRESULT
|
||||
ERRCTX_OSSTATUS, // MacOS OSStatus
|
||||
|
||||
// Abbreviations for LOG_E macro
|
||||
ERRCTX_EN = ERRCTX_ERRNO, // LOG_E(sev, EN, x)
|
||||
ERRCTX_HR = ERRCTX_HRESULT, // LOG_E(sev, HR, x)
|
||||
ERRCTX_OS = ERRCTX_OSSTATUS, // LOG_E(sev, OS, x)
|
||||
};
|
||||
|
||||
// Virtual sink interface that can receive log messages.
|
||||
class LogSink {
|
||||
public:
|
||||
LogSink() {}
|
||||
virtual ~LogSink() {}
|
||||
virtual void OnLogMessage(const std::string& message) = 0;
|
||||
};
|
||||
|
||||
class LogMessage {
|
||||
public:
|
||||
LogMessage(const char* file,
|
||||
int line,
|
||||
LoggingSeverity sev,
|
||||
LogErrorContext err_ctx = ERRCTX_NONE,
|
||||
int err = 0,
|
||||
const char* module = nullptr);
|
||||
|
||||
LogMessage(const char* file,
|
||||
int line,
|
||||
LoggingSeverity sev,
|
||||
const std::string& tag);
|
||||
|
||||
~LogMessage();
|
||||
|
||||
static inline bool Loggable(LoggingSeverity sev) { return (sev >= min_sev_); }
|
||||
std::ostream& stream() { return print_stream_; }
|
||||
|
||||
// Returns the time at which this function was called for the first time.
|
||||
// The time will be used as the logging start time.
|
||||
// If this is not called externally, the LogMessage ctor also calls it, in
|
||||
// which case the logging start time will be the time of the first LogMessage
|
||||
// instance is created.
|
||||
static int64_t LogStartTime();
|
||||
|
||||
// Returns the wall clock equivalent of |LogStartTime|, in seconds from the
|
||||
// epoch.
|
||||
static uint32_t WallClockStartTime();
|
||||
|
||||
// LogThreads: Display the thread identifier of the current thread
|
||||
static void LogThreads(bool on = true);
|
||||
|
||||
// LogTimestamps: Display the elapsed time of the program
|
||||
static void LogTimestamps(bool on = true);
|
||||
|
||||
// These are the available logging channels
|
||||
// Debug: Debug console on Windows, otherwise stderr
|
||||
static void LogToDebug(LoggingSeverity min_sev);
|
||||
static LoggingSeverity GetLogToDebug() { return dbg_sev_; }
|
||||
|
||||
// Sets whether logs will be directed to stderr in debug mode.
|
||||
static void SetLogToStderr(bool log_to_stderr);
|
||||
|
||||
// Stream: Any non-blocking stream interface. LogMessage takes ownership of
|
||||
// the stream. Multiple streams may be specified by using AddLogToStream.
|
||||
// LogToStream is retained for backwards compatibility; when invoked, it
|
||||
// will discard any previously set streams and install the specified stream.
|
||||
// GetLogToStream gets the severity for the specified stream, of if none
|
||||
// is specified, the minimum stream severity.
|
||||
// RemoveLogToStream removes the specified stream, without destroying it.
|
||||
static int GetLogToStream(LogSink* stream = nullptr);
|
||||
static void AddLogToStream(LogSink* stream, LoggingSeverity min_sev);
|
||||
static void RemoveLogToStream(LogSink* stream);
|
||||
|
||||
// Testing against MinLogSeverity allows code to avoid potentially expensive
|
||||
// logging operations by pre-checking the logging level.
|
||||
static int GetMinLogSeverity() { return min_sev_; }
|
||||
|
||||
// Parses the provided parameter stream to configure the options above.
|
||||
// Useful for configuring logging from the command line.
|
||||
static void ConfigureLogging(const char* params);
|
||||
|
||||
private:
|
||||
typedef std::pair<LogSink*, LoggingSeverity> StreamAndSeverity;
|
||||
typedef std::list<StreamAndSeverity> StreamList;
|
||||
|
||||
// Updates min_sev_ appropriately when debug sinks change.
|
||||
static void UpdateMinLogSeverity();
|
||||
|
||||
// These write out the actual log messages.
|
||||
static void OutputToDebug(const std::string& msg,
|
||||
LoggingSeverity severity,
|
||||
const std::string& tag);
|
||||
|
||||
// The ostream that buffers the formatted message before output
|
||||
std::ostringstream print_stream_;
|
||||
|
||||
// The severity level of this message
|
||||
LoggingSeverity severity_;
|
||||
|
||||
// The Android debug output tag.
|
||||
std::string tag_;
|
||||
|
||||
// String data generated in the constructor, that should be appended to
|
||||
// the message before output.
|
||||
std::string extra_;
|
||||
|
||||
// dbg_sev_ is the thresholds for those output targets
|
||||
// min_sev_ is the minimum (most verbose) of those levels, and is used
|
||||
// as a short-circuit in the logging macros to identify messages that won't
|
||||
// be logged.
|
||||
// ctx_sev_ is the minimum level at which file context is displayed
|
||||
static LoggingSeverity min_sev_, dbg_sev_, ctx_sev_;
|
||||
|
||||
// The output streams and their associated severities
|
||||
static StreamList streams_;
|
||||
|
||||
// Flags for formatting options
|
||||
static bool thread_, timestamp_;
|
||||
|
||||
// Determines if logs will be directed to stderr in debug mode.
|
||||
static bool log_to_stderr_;
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(LogMessage);
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Logging Helpers
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
class LogMultilineState {
|
||||
public:
|
||||
size_t unprintable_count_[2];
|
||||
LogMultilineState() {
|
||||
unprintable_count_[0] = unprintable_count_[1] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
// When possible, pass optional state variable to track various data across
|
||||
// multiple calls to LogMultiline. Otherwise, pass null.
|
||||
void LogMultiline(LoggingSeverity level, const char* label, bool input,
|
||||
const void* data, size_t len, bool hex_mode,
|
||||
LogMultilineState* state);
|
||||
|
||||
#ifndef LOG
|
||||
|
||||
// The following non-obvious technique for implementation of a
|
||||
// conditional log stream was stolen from google3/base/logging.h.
|
||||
|
||||
// This class is used to explicitly ignore values in the conditional
|
||||
// logging macros. This avoids compiler warnings like "value computed
|
||||
// is not used" and "statement has no effect".
|
||||
|
||||
class LogMessageVoidify {
|
||||
public:
|
||||
LogMessageVoidify() { }
|
||||
// This has to be an operator with a precedence lower than << but
|
||||
// higher than ?:
|
||||
void operator&(std::ostream&) { }
|
||||
};
|
||||
|
||||
#define LOG_SEVERITY_PRECONDITION(sev) \
|
||||
!(rtc::LogMessage::Loggable(sev)) \
|
||||
? (void) 0 \
|
||||
: rtc::LogMessageVoidify() &
|
||||
|
||||
#define LOG(sev) \
|
||||
LOG_SEVERITY_PRECONDITION(rtc::sev) \
|
||||
rtc::LogMessage(__FILE__, __LINE__, rtc::sev).stream()
|
||||
|
||||
// The _V version is for when a variable is passed in. It doesn't do the
|
||||
// namespace concatination.
|
||||
#define LOG_V(sev) \
|
||||
LOG_SEVERITY_PRECONDITION(sev) \
|
||||
rtc::LogMessage(__FILE__, __LINE__, sev).stream()
|
||||
|
||||
// The _F version prefixes the message with the current function name.
|
||||
#if (defined(__GNUC__) && !defined(NDEBUG)) || defined(WANT_PRETTY_LOG_F)
|
||||
#define LOG_F(sev) LOG(sev) << __PRETTY_FUNCTION__ << ": "
|
||||
#define LOG_T_F(sev) LOG(sev) << this << ": " << __PRETTY_FUNCTION__ << ": "
|
||||
#else
|
||||
#define LOG_F(sev) LOG(sev) << __FUNCTION__ << ": "
|
||||
#define LOG_T_F(sev) LOG(sev) << this << ": " << __FUNCTION__ << ": "
|
||||
#endif
|
||||
|
||||
#define LOG_CHECK_LEVEL(sev) \
|
||||
rtc::LogCheckLevel(rtc::sev)
|
||||
#define LOG_CHECK_LEVEL_V(sev) \
|
||||
rtc::LogCheckLevel(sev)
|
||||
|
||||
inline bool LogCheckLevel(LoggingSeverity sev) {
|
||||
return (LogMessage::GetMinLogSeverity() <= sev);
|
||||
}
|
||||
|
||||
#define LOG_E(sev, ctx, err, ...) \
|
||||
LOG_SEVERITY_PRECONDITION(rtc::sev) \
|
||||
rtc::LogMessage(__FILE__, __LINE__, rtc::sev, \
|
||||
rtc::ERRCTX_ ## ctx, err , ##__VA_ARGS__) \
|
||||
.stream()
|
||||
|
||||
#define LOG_T(sev) LOG(sev) << this << ": "
|
||||
|
||||
#define LOG_ERRNO_EX(sev, err) \
|
||||
LOG_E(sev, ERRNO, err)
|
||||
#define LOG_ERRNO(sev) \
|
||||
LOG_ERRNO_EX(sev, errno)
|
||||
|
||||
#if defined(WEBRTC_WIN)
|
||||
#define LOG_GLE_EX(sev, err) \
|
||||
LOG_E(sev, HRESULT, err)
|
||||
#define LOG_GLE(sev) \
|
||||
LOG_GLE_EX(sev, GetLastError())
|
||||
#define LOG_GLEM(sev, mod) \
|
||||
LOG_E(sev, HRESULT, GetLastError(), mod)
|
||||
#define LOG_ERR_EX(sev, err) \
|
||||
LOG_GLE_EX(sev, err)
|
||||
#define LOG_ERR(sev) \
|
||||
LOG_GLE(sev)
|
||||
#define LAST_SYSTEM_ERROR \
|
||||
(::GetLastError())
|
||||
#elif defined(__native_client__) && __native_client__
|
||||
#define LOG_ERR_EX(sev, err) \
|
||||
LOG(sev)
|
||||
#define LOG_ERR(sev) \
|
||||
LOG(sev)
|
||||
#define LAST_SYSTEM_ERROR \
|
||||
(0)
|
||||
#elif defined(WEBRTC_POSIX)
|
||||
#define LOG_ERR_EX(sev, err) \
|
||||
LOG_ERRNO_EX(sev, err)
|
||||
#define LOG_ERR(sev) \
|
||||
LOG_ERRNO(sev)
|
||||
#define LAST_SYSTEM_ERROR \
|
||||
(errno)
|
||||
#endif // WEBRTC_WIN
|
||||
|
||||
#define LOG_TAG(sev, tag) \
|
||||
LOG_SEVERITY_PRECONDITION(sev) \
|
||||
rtc::LogMessage(nullptr, 0, sev, tag).stream()
|
||||
|
||||
#define PLOG(sev, err) \
|
||||
LOG_ERR_EX(sev, err)
|
||||
|
||||
// TODO(?): Add an "assert" wrapper that logs in the same manner.
|
||||
|
||||
#endif // LOG
|
||||
|
||||
} // namespace rtc
|
||||
// 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/logging.h"
|
||||
|
||||
#endif // WEBRTC_BASE_LOGGING_H_
|
||||
|
||||
@ -8,61 +8,12 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_BASE_FILE_ROTATING_LOG_SINK_H_
|
||||
#define WEBRTC_BASE_FILE_ROTATING_LOG_SINK_H_
|
||||
#ifndef WEBRTC_BASE_LOGSINKS_H_
|
||||
#define WEBRTC_BASE_LOGSINKS_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "webrtc/base/constructormagic.h"
|
||||
#include "webrtc/base/filerotatingstream.h"
|
||||
#include "webrtc/base/logging.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/logsinks.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
// Log sink that uses a FileRotatingStream to write to disk.
|
||||
// Init() must be called before adding this sink.
|
||||
class FileRotatingLogSink : public LogSink {
|
||||
public:
|
||||
// |num_log_files| must be greater than 1 and |max_log_size| must be greater
|
||||
// than 0.
|
||||
FileRotatingLogSink(const std::string& log_dir_path,
|
||||
const std::string& log_prefix,
|
||||
size_t max_log_size,
|
||||
size_t num_log_files);
|
||||
~FileRotatingLogSink() override;
|
||||
|
||||
// Writes the message to the current file. It will spill over to the next
|
||||
// file if needed.
|
||||
void OnLogMessage(const std::string& message) override;
|
||||
|
||||
// Deletes any existing files in the directory and creates a new log file.
|
||||
virtual bool Init();
|
||||
|
||||
// Disables buffering on the underlying stream.
|
||||
bool DisableBuffering();
|
||||
|
||||
protected:
|
||||
explicit FileRotatingLogSink(FileRotatingStream* stream);
|
||||
|
||||
private:
|
||||
std::unique_ptr<FileRotatingStream> stream_;
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(FileRotatingLogSink);
|
||||
};
|
||||
|
||||
// Log sink that uses a CallSessionFileRotatingStream to write to disk.
|
||||
// Init() must be called before adding this sink.
|
||||
class CallSessionFileRotatingLogSink : public FileRotatingLogSink {
|
||||
public:
|
||||
CallSessionFileRotatingLogSink(const std::string& log_dir_path,
|
||||
size_t max_total_log_size);
|
||||
~CallSessionFileRotatingLogSink() override;
|
||||
|
||||
private:
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(CallSessionFileRotatingLogSink);
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // WEBRTC_BASE_FILE_ROTATING_LOG_SINK_H_
|
||||
#endif // WEBRTC_BASE_LOGSINKS_H_
|
||||
|
||||
@ -8,43 +8,12 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_BASE_MACUTILS_H__
|
||||
#define WEBRTC_BASE_MACUTILS_H__
|
||||
#ifndef WEBRTC_BASE_MACUTILS_H_
|
||||
#define WEBRTC_BASE_MACUTILS_H_
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <string>
|
||||
|
||||
namespace rtc {
|
||||
// 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/macutils.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Note that some of these functions work for both iOS and Mac OS X. The ones
|
||||
// that are specific to Mac are #ifdef'ed as such.
|
||||
|
||||
bool ToUtf8(const CFStringRef str16, std::string* str8);
|
||||
bool ToUtf16(const std::string& str8, CFStringRef* str16);
|
||||
|
||||
#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
|
||||
void DecodeFourChar(UInt32 fc, std::string* out);
|
||||
|
||||
enum MacOSVersionName {
|
||||
kMacOSUnknown, // ???
|
||||
kMacOSOlder, // 10.2-
|
||||
kMacOSPanther, // 10.3
|
||||
kMacOSTiger, // 10.4
|
||||
kMacOSLeopard, // 10.5
|
||||
kMacOSSnowLeopard, // 10.6
|
||||
kMacOSLion, // 10.7
|
||||
kMacOSMountainLion, // 10.8
|
||||
kMacOSMavericks, // 10.9
|
||||
kMacOSNewer, // 10.10+
|
||||
};
|
||||
|
||||
MacOSVersionName GetOSVersionName();
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // WEBRTC_BASE_MACUTILS_H__
|
||||
#endif // WEBRTC_BASE_MACUTILS_H_
|
||||
|
||||
@ -11,29 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_MATHUTILS_H_
|
||||
#define WEBRTC_BASE_MATHUTILS_H_
|
||||
|
||||
#include <math.h>
|
||||
#include <type_traits>
|
||||
|
||||
#include "webrtc/base/checks.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265359f
|
||||
#endif
|
||||
|
||||
// Given two numbers |x| and |y| such that x >= y, computes the difference
|
||||
// x - y without causing undefined behavior due to signed overflow.
|
||||
template <typename T>
|
||||
typename std::make_unsigned<T>::type unsigned_difference(T x, T y) {
|
||||
static_assert(
|
||||
std::is_signed<T>::value,
|
||||
"Function unsigned_difference is only meaningful for signed types.");
|
||||
RTC_DCHECK_GE(x, y);
|
||||
typedef typename std::make_unsigned<T>::type unsigned_type;
|
||||
// int -> unsigned conversion repeatedly adds UINT_MAX + 1 until the number
|
||||
// can be represented as an unsigned. Since we know that the actual
|
||||
// difference x - y can be represented as an unsigned, it is sufficient to
|
||||
// compute the difference modulo UINT_MAX + 1, i.e using unsigned arithmetic.
|
||||
return static_cast<unsigned_type>(x) - static_cast<unsigned_type>(y);
|
||||
}
|
||||
// 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/mathutils.h"
|
||||
|
||||
#endif // WEBRTC_BASE_MATHUTILS_H_
|
||||
|
||||
@ -23,22 +23,9 @@
|
||||
#ifndef WEBRTC_BASE_MD5_H_
|
||||
#define WEBRTC_BASE_MD5_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace rtc {
|
||||
|
||||
struct MD5Context {
|
||||
uint32_t buf[4];
|
||||
uint32_t bits[2];
|
||||
uint32_t in[16];
|
||||
};
|
||||
|
||||
void MD5Init(MD5Context* context);
|
||||
void MD5Update(MD5Context* context, const uint8_t* data, size_t len);
|
||||
void MD5Final(MD5Context* context, uint8_t digest[16]);
|
||||
void MD5Transform(uint32_t buf[4], const uint32_t in[16]);
|
||||
|
||||
} // namespace rtc
|
||||
// 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/md5.h"
|
||||
|
||||
#endif // WEBRTC_BASE_MD5_H_
|
||||
|
||||
@ -11,26 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_MD5DIGEST_H_
|
||||
#define WEBRTC_BASE_MD5DIGEST_H_
|
||||
|
||||
#include "webrtc/base/md5.h"
|
||||
#include "webrtc/base/messagedigest.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
// A simple wrapper for our MD5 implementation.
|
||||
class Md5Digest : public MessageDigest {
|
||||
public:
|
||||
enum { kSize = 16 };
|
||||
Md5Digest() {
|
||||
MD5Init(&ctx_);
|
||||
}
|
||||
size_t Size() const override;
|
||||
void Update(const void* buf, size_t len) override;
|
||||
size_t Finish(void* buf, size_t len) override;
|
||||
|
||||
private:
|
||||
MD5Context ctx_;
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
// 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/md5digest.h"
|
||||
|
||||
#endif // WEBRTC_BASE_MD5DIGEST_H_
|
||||
|
||||
@ -10,15 +10,9 @@
|
||||
#ifndef WEBRTC_BASE_MEMORY_USAGE_H_
|
||||
#define WEBRTC_BASE_MEMORY_USAGE_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace rtc {
|
||||
|
||||
// Returns current memory used by the process in bytes (working set size on
|
||||
// Windows and resident set size on other platforms).
|
||||
// Returns -1 on failure.
|
||||
int64_t GetProcessResidentSizeBytes();
|
||||
|
||||
} // namespace rtc
|
||||
// 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/memory_usage.h"
|
||||
|
||||
#endif // WEBRTC_BASE_MEMORY_USAGE_H_
|
||||
|
||||
@ -11,99 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_MESSAGEDIGEST_H_
|
||||
#define WEBRTC_BASE_MESSAGEDIGEST_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace rtc {
|
||||
|
||||
// Definitions for the digest algorithms.
|
||||
extern const char DIGEST_MD5[];
|
||||
extern const char DIGEST_SHA_1[];
|
||||
extern const char DIGEST_SHA_224[];
|
||||
extern const char DIGEST_SHA_256[];
|
||||
extern const char DIGEST_SHA_384[];
|
||||
extern const char DIGEST_SHA_512[];
|
||||
|
||||
// A general class for computing hashes.
|
||||
class MessageDigest {
|
||||
public:
|
||||
enum { kMaxSize = 64 }; // Maximum known size (SHA-512)
|
||||
virtual ~MessageDigest() {}
|
||||
// Returns the digest output size (e.g. 16 bytes for MD5).
|
||||
virtual size_t Size() const = 0;
|
||||
// Updates the digest with |len| bytes from |buf|.
|
||||
virtual void Update(const void* buf, size_t len) = 0;
|
||||
// Outputs the digest value to |buf| with length |len|.
|
||||
// Returns the number of bytes written, i.e., Size().
|
||||
virtual size_t Finish(void* buf, size_t len) = 0;
|
||||
};
|
||||
|
||||
// A factory class for creating digest objects.
|
||||
class MessageDigestFactory {
|
||||
public:
|
||||
static MessageDigest* Create(const std::string& alg);
|
||||
};
|
||||
|
||||
// A whitelist of approved digest algorithms from RFC 4572 (FIPS 180).
|
||||
bool IsFips180DigestAlgorithm(const std::string& alg);
|
||||
|
||||
// Functions to create hashes.
|
||||
|
||||
// Computes the hash of |in_len| bytes of |input|, using the |digest| hash
|
||||
// implementation, and outputs the hash to the buffer |output|, which is
|
||||
// |out_len| bytes long. Returns the number of bytes written to |output| if
|
||||
// successful, or 0 if |out_len| was too small.
|
||||
size_t ComputeDigest(MessageDigest* digest, const void* input, size_t in_len,
|
||||
void* output, size_t out_len);
|
||||
// Like the previous function, but creates a digest implementation based on
|
||||
// the desired digest name |alg|, e.g. DIGEST_SHA_1. Returns 0 if there is no
|
||||
// digest with the given name.
|
||||
size_t ComputeDigest(const std::string& alg, const void* input, size_t in_len,
|
||||
void* output, size_t out_len);
|
||||
// Computes the hash of |input| using the |digest| hash implementation, and
|
||||
// returns it as a hex-encoded string.
|
||||
std::string ComputeDigest(MessageDigest* digest, const std::string& input);
|
||||
// Like the previous function, but creates a digest implementation based on
|
||||
// the desired digest name |alg|, e.g. DIGEST_SHA_1. Returns empty string if
|
||||
// there is no digest with the given name.
|
||||
std::string ComputeDigest(const std::string& alg, const std::string& input);
|
||||
// Like the previous function, but returns an explicit result code.
|
||||
bool ComputeDigest(const std::string& alg, const std::string& input,
|
||||
std::string* output);
|
||||
|
||||
// Shorthand way to compute a hex-encoded hash using MD5.
|
||||
inline std::string MD5(const std::string& input) {
|
||||
return ComputeDigest(DIGEST_MD5, input);
|
||||
}
|
||||
|
||||
// Functions to compute RFC 2104 HMACs.
|
||||
|
||||
// Computes the HMAC of |in_len| bytes of |input|, using the |digest| hash
|
||||
// implementation and |key_len| bytes of |key| to key the HMAC, and outputs
|
||||
// the HMAC to the buffer |output|, which is |out_len| bytes long. Returns the
|
||||
// number of bytes written to |output| if successful, or 0 if |out_len| was too
|
||||
// small.
|
||||
size_t ComputeHmac(MessageDigest* digest, const void* key, size_t key_len,
|
||||
const void* input, size_t in_len,
|
||||
void* output, size_t out_len);
|
||||
// Like the previous function, but creates a digest implementation based on
|
||||
// the desired digest name |alg|, e.g. DIGEST_SHA_1. Returns 0 if there is no
|
||||
// digest with the given name.
|
||||
size_t ComputeHmac(const std::string& alg, const void* key, size_t key_len,
|
||||
const void* input, size_t in_len,
|
||||
void* output, size_t out_len);
|
||||
// Computes the HMAC of |input| using the |digest| hash implementation and |key|
|
||||
// to key the HMAC, and returns it as a hex-encoded string.
|
||||
std::string ComputeHmac(MessageDigest* digest, const std::string& key,
|
||||
const std::string& input);
|
||||
// Like the previous function, but creates a digest implementation based on
|
||||
// the desired digest name |alg|, e.g. DIGEST_SHA_1. Returns empty string if
|
||||
// there is no digest with the given name.
|
||||
std::string ComputeHmac(const std::string& alg, const std::string& key,
|
||||
const std::string& input);
|
||||
// Like the previous function, but returns an explicit result code.
|
||||
bool ComputeHmac(const std::string& alg, const std::string& key,
|
||||
const std::string& input, std::string* output);
|
||||
|
||||
} // namespace rtc
|
||||
// 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/messagedigest.h"
|
||||
|
||||
#endif // WEBRTC_BASE_MESSAGEDIGEST_H_
|
||||
|
||||
@ -11,65 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_MESSAGEHANDLER_H_
|
||||
#define WEBRTC_BASE_MESSAGEHANDLER_H_
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "webrtc/base/constructormagic.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
struct Message;
|
||||
|
||||
// Messages get dispatched to a MessageHandler
|
||||
|
||||
class MessageHandler {
|
||||
public:
|
||||
virtual ~MessageHandler();
|
||||
virtual void OnMessage(Message* msg) = 0;
|
||||
|
||||
protected:
|
||||
MessageHandler() {}
|
||||
|
||||
private:
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(MessageHandler);
|
||||
};
|
||||
|
||||
// Helper class to facilitate executing a functor on a thread.
|
||||
template <class ReturnT, class FunctorT>
|
||||
class FunctorMessageHandler : public MessageHandler {
|
||||
public:
|
||||
explicit FunctorMessageHandler(const FunctorT& functor)
|
||||
: functor_(functor) {}
|
||||
virtual void OnMessage(Message* msg) {
|
||||
result_ = functor_();
|
||||
}
|
||||
const ReturnT& result() const { return result_; }
|
||||
|
||||
// Returns moved result. Should not call result() or MoveResult() again
|
||||
// after this.
|
||||
ReturnT MoveResult() { return std::move(result_); }
|
||||
|
||||
private:
|
||||
FunctorT functor_;
|
||||
ReturnT result_;
|
||||
};
|
||||
|
||||
// Specialization for ReturnT of void.
|
||||
template <class FunctorT>
|
||||
class FunctorMessageHandler<void, FunctorT> : public MessageHandler {
|
||||
public:
|
||||
explicit FunctorMessageHandler(const FunctorT& functor)
|
||||
: functor_(functor) {}
|
||||
virtual void OnMessage(Message* msg) {
|
||||
functor_();
|
||||
}
|
||||
void result() const {}
|
||||
void MoveResult() {}
|
||||
|
||||
private:
|
||||
FunctorT functor_;
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
// 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/messagehandler.h"
|
||||
|
||||
#endif // WEBRTC_BASE_MESSAGEHANDLER_H_
|
||||
|
||||
@ -11,317 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_MESSAGEQUEUE_H_
|
||||
#define WEBRTC_BASE_MESSAGEQUEUE_H_
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <queue>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/base/basictypes.h"
|
||||
#include "webrtc/base/constructormagic.h"
|
||||
#include "webrtc/base/criticalsection.h"
|
||||
#include "webrtc/base/location.h"
|
||||
#include "webrtc/base/messagehandler.h"
|
||||
#include "webrtc/base/scoped_ref_ptr.h"
|
||||
#include "webrtc/base/sigslot.h"
|
||||
#include "webrtc/base/socketserver.h"
|
||||
#include "webrtc/base/timeutils.h"
|
||||
#include "webrtc/base/thread_annotations.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
struct Message;
|
||||
class MessageQueue;
|
||||
|
||||
// MessageQueueManager does cleanup of of message queues
|
||||
|
||||
class MessageQueueManager {
|
||||
public:
|
||||
static void Add(MessageQueue *message_queue);
|
||||
static void Remove(MessageQueue *message_queue);
|
||||
static void Clear(MessageHandler *handler);
|
||||
|
||||
// For testing purposes, we expose whether or not the MessageQueueManager
|
||||
// instance has been initialized. It has no other use relative to the rest of
|
||||
// the functions of this class, which auto-initialize the underlying
|
||||
// MessageQueueManager instance when necessary.
|
||||
static bool IsInitialized();
|
||||
|
||||
// Mainly for testing purposes, for use with a simulated clock.
|
||||
// Ensures that all message queues have processed delayed messages
|
||||
// up until the current point in time.
|
||||
static void ProcessAllMessageQueues();
|
||||
|
||||
private:
|
||||
static MessageQueueManager* Instance();
|
||||
|
||||
MessageQueueManager();
|
||||
~MessageQueueManager();
|
||||
|
||||
void AddInternal(MessageQueue *message_queue);
|
||||
void RemoveInternal(MessageQueue *message_queue);
|
||||
void ClearInternal(MessageHandler *handler);
|
||||
void ProcessAllMessageQueuesInternal();
|
||||
|
||||
static MessageQueueManager* instance_;
|
||||
// This list contains all live MessageQueues.
|
||||
std::vector<MessageQueue*> message_queues_ GUARDED_BY(crit_);
|
||||
|
||||
// Acquire this with DebugNonReentrantCritScope.
|
||||
CriticalSection crit_;
|
||||
bool locked_ GUARDED_BY(crit_);
|
||||
};
|
||||
|
||||
// Derive from this for specialized data
|
||||
// App manages lifetime, except when messages are purged
|
||||
|
||||
class MessageData {
|
||||
public:
|
||||
MessageData() {}
|
||||
virtual ~MessageData() {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class TypedMessageData : public MessageData {
|
||||
public:
|
||||
explicit TypedMessageData(const T& data) : data_(data) { }
|
||||
const T& data() const { return data_; }
|
||||
T& data() { return data_; }
|
||||
private:
|
||||
T data_;
|
||||
};
|
||||
|
||||
// Like TypedMessageData, but for pointers that require a delete.
|
||||
template <class T>
|
||||
class ScopedMessageData : public MessageData {
|
||||
public:
|
||||
explicit ScopedMessageData(std::unique_ptr<T> data)
|
||||
: data_(std::move(data)) {}
|
||||
// Deprecated.
|
||||
// TODO(deadbeef): Remove this once downstream applications stop using it.
|
||||
explicit ScopedMessageData(T* data) : data_(data) {}
|
||||
// Deprecated.
|
||||
// TODO(deadbeef): Returning a reference to a unique ptr? Why. Get rid of
|
||||
// this once downstream applications stop using it, then rename inner_data to
|
||||
// just data.
|
||||
const std::unique_ptr<T>& data() const { return data_; }
|
||||
std::unique_ptr<T>& data() { return data_; }
|
||||
|
||||
const T& inner_data() const { return *data_; }
|
||||
T& inner_data() { return *data_; }
|
||||
|
||||
private:
|
||||
std::unique_ptr<T> data_;
|
||||
};
|
||||
|
||||
// Like ScopedMessageData, but for reference counted pointers.
|
||||
template <class T>
|
||||
class ScopedRefMessageData : public MessageData {
|
||||
public:
|
||||
explicit ScopedRefMessageData(T* data) : data_(data) { }
|
||||
const scoped_refptr<T>& data() const { return data_; }
|
||||
scoped_refptr<T>& data() { return data_; }
|
||||
private:
|
||||
scoped_refptr<T> data_;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
inline MessageData* WrapMessageData(const T& data) {
|
||||
return new TypedMessageData<T>(data);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline const T& UseMessageData(MessageData* data) {
|
||||
return static_cast< TypedMessageData<T>* >(data)->data();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
class DisposeData : public MessageData {
|
||||
public:
|
||||
explicit DisposeData(T* data) : data_(data) { }
|
||||
virtual ~DisposeData() { delete data_; }
|
||||
private:
|
||||
T* data_;
|
||||
};
|
||||
|
||||
const uint32_t MQID_ANY = static_cast<uint32_t>(-1);
|
||||
const uint32_t MQID_DISPOSE = static_cast<uint32_t>(-2);
|
||||
|
||||
// No destructor
|
||||
|
||||
struct Message {
|
||||
Message()
|
||||
: phandler(nullptr), message_id(0), pdata(nullptr), ts_sensitive(0) {}
|
||||
inline bool Match(MessageHandler* handler, uint32_t id) const {
|
||||
return (handler == nullptr || handler == phandler) &&
|
||||
(id == MQID_ANY || id == message_id);
|
||||
}
|
||||
Location posted_from;
|
||||
MessageHandler *phandler;
|
||||
uint32_t message_id;
|
||||
MessageData *pdata;
|
||||
int64_t ts_sensitive;
|
||||
};
|
||||
|
||||
typedef std::list<Message> MessageList;
|
||||
|
||||
// DelayedMessage goes into a priority queue, sorted by trigger time. Messages
|
||||
// with the same trigger time are processed in num_ (FIFO) order.
|
||||
|
||||
class DelayedMessage {
|
||||
public:
|
||||
DelayedMessage(int64_t delay,
|
||||
int64_t trigger,
|
||||
uint32_t num,
|
||||
const Message& msg)
|
||||
: cmsDelay_(delay), msTrigger_(trigger), num_(num), msg_(msg) {}
|
||||
|
||||
bool operator< (const DelayedMessage& dmsg) const {
|
||||
return (dmsg.msTrigger_ < msTrigger_)
|
||||
|| ((dmsg.msTrigger_ == msTrigger_) && (dmsg.num_ < num_));
|
||||
}
|
||||
|
||||
int64_t cmsDelay_; // for debugging
|
||||
int64_t msTrigger_;
|
||||
uint32_t num_;
|
||||
Message msg_;
|
||||
};
|
||||
|
||||
class MessageQueue {
|
||||
public:
|
||||
static const int kForever = -1;
|
||||
|
||||
// Create a new MessageQueue and optionally assign it to the passed
|
||||
// SocketServer. Subclasses that override Clear should pass false for
|
||||
// init_queue and call DoInit() from their constructor to prevent races
|
||||
// with the MessageQueueManager using the object while the vtable is still
|
||||
// being created.
|
||||
MessageQueue(SocketServer* ss, bool init_queue);
|
||||
MessageQueue(std::unique_ptr<SocketServer> ss, bool init_queue);
|
||||
|
||||
// NOTE: SUBCLASSES OF MessageQueue THAT OVERRIDE Clear MUST CALL
|
||||
// DoDestroy() IN THEIR DESTRUCTORS! This is required to avoid a data race
|
||||
// between the destructor modifying the vtable, and the MessageQueueManager
|
||||
// calling Clear on the object from a different thread.
|
||||
virtual ~MessageQueue();
|
||||
|
||||
SocketServer* socketserver();
|
||||
|
||||
// Note: The behavior of MessageQueue has changed. When a MQ is stopped,
|
||||
// futher Posts and Sends will fail. However, any pending Sends and *ready*
|
||||
// Posts (as opposed to unexpired delayed Posts) will be delivered before
|
||||
// Get (or Peek) returns false. By guaranteeing delivery of those messages,
|
||||
// we eliminate the race condition when an MessageHandler and MessageQueue
|
||||
// may be destroyed independently of each other.
|
||||
virtual void Quit();
|
||||
virtual bool IsQuitting();
|
||||
virtual void Restart();
|
||||
// Not all message queues actually process messages (such as SignalThread).
|
||||
// In those cases, it's important to know, before posting, that it won't be
|
||||
// Processed. Normally, this would be true until IsQuitting() is true.
|
||||
virtual bool IsProcessingMessages();
|
||||
|
||||
// Get() will process I/O until:
|
||||
// 1) A message is available (returns true)
|
||||
// 2) cmsWait seconds have elapsed (returns false)
|
||||
// 3) Stop() is called (returns false)
|
||||
virtual bool Get(Message *pmsg, int cmsWait = kForever,
|
||||
bool process_io = true);
|
||||
virtual bool Peek(Message *pmsg, int cmsWait = 0);
|
||||
virtual void Post(const Location& posted_from,
|
||||
MessageHandler* phandler,
|
||||
uint32_t id = 0,
|
||||
MessageData* pdata = nullptr,
|
||||
bool time_sensitive = false);
|
||||
virtual void PostDelayed(const Location& posted_from,
|
||||
int cmsDelay,
|
||||
MessageHandler* phandler,
|
||||
uint32_t id = 0,
|
||||
MessageData* pdata = nullptr);
|
||||
virtual void PostAt(const Location& posted_from,
|
||||
int64_t tstamp,
|
||||
MessageHandler* phandler,
|
||||
uint32_t id = 0,
|
||||
MessageData* pdata = nullptr);
|
||||
// TODO(honghaiz): Remove this when all the dependencies are removed.
|
||||
virtual void PostAt(const Location& posted_from,
|
||||
uint32_t tstamp,
|
||||
MessageHandler* phandler,
|
||||
uint32_t id = 0,
|
||||
MessageData* pdata = nullptr);
|
||||
virtual void Clear(MessageHandler* phandler,
|
||||
uint32_t id = MQID_ANY,
|
||||
MessageList* removed = nullptr);
|
||||
virtual void Dispatch(Message *pmsg);
|
||||
virtual void ReceiveSends();
|
||||
|
||||
// Amount of time until the next message can be retrieved
|
||||
virtual int GetDelay();
|
||||
|
||||
bool empty() const { return size() == 0u; }
|
||||
size_t size() const {
|
||||
CritScope cs(&crit_); // msgq_.size() is not thread safe.
|
||||
return msgq_.size() + dmsgq_.size() + (fPeekKeep_ ? 1u : 0u);
|
||||
}
|
||||
|
||||
// Internally posts a message which causes the doomed object to be deleted
|
||||
template<class T> void Dispose(T* doomed) {
|
||||
if (doomed) {
|
||||
Post(RTC_FROM_HERE, nullptr, MQID_DISPOSE, new DisposeData<T>(doomed));
|
||||
}
|
||||
}
|
||||
|
||||
// When this signal is sent out, any references to this queue should
|
||||
// no longer be used.
|
||||
sigslot::signal0<> SignalQueueDestroyed;
|
||||
|
||||
protected:
|
||||
class PriorityQueue : public std::priority_queue<DelayedMessage> {
|
||||
public:
|
||||
container_type& container() { return c; }
|
||||
void reheap() { make_heap(c.begin(), c.end(), comp); }
|
||||
};
|
||||
|
||||
void DoDelayPost(const Location& posted_from,
|
||||
int64_t cmsDelay,
|
||||
int64_t tstamp,
|
||||
MessageHandler* phandler,
|
||||
uint32_t id,
|
||||
MessageData* pdata);
|
||||
|
||||
// Perform initialization, subclasses must call this from their constructor
|
||||
// if false was passed as init_queue to the MessageQueue constructor.
|
||||
void DoInit();
|
||||
|
||||
// Perform cleanup, subclasses that override Clear must call this from the
|
||||
// destructor.
|
||||
void DoDestroy();
|
||||
|
||||
void WakeUpSocketServer();
|
||||
|
||||
bool fPeekKeep_;
|
||||
Message msgPeek_;
|
||||
MessageList msgq_ GUARDED_BY(crit_);
|
||||
PriorityQueue dmsgq_ GUARDED_BY(crit_);
|
||||
uint32_t dmsgq_next_num_ GUARDED_BY(crit_);
|
||||
CriticalSection crit_;
|
||||
bool fInitialized_;
|
||||
bool fDestroyed_;
|
||||
|
||||
private:
|
||||
volatile int stop_;
|
||||
|
||||
// The SocketServer might not be owned by MessageQueue.
|
||||
SocketServer* const ss_;
|
||||
// Used if SocketServer ownership lies with |this|.
|
||||
std::unique_ptr<SocketServer> own_ss_;
|
||||
|
||||
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(MessageQueue);
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
// 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/messagequeue.h"
|
||||
|
||||
#endif // WEBRTC_BASE_MESSAGEQUEUE_H_
|
||||
|
||||
@ -11,125 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_MOD_OPS_H_
|
||||
#define WEBRTC_BASE_MOD_OPS_H_
|
||||
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
||||
#include "webrtc/base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
template <unsigned long M> // NOLINT
|
||||
inline unsigned long Add(unsigned long a, unsigned long b) { // NOLINT
|
||||
RTC_DCHECK_LT(a, M);
|
||||
unsigned long t = M - b % M; // NOLINT
|
||||
unsigned long res = a - t; // NOLINT
|
||||
if (t > a)
|
||||
return res + M;
|
||||
return res;
|
||||
}
|
||||
|
||||
template <unsigned long M> // NOLINT
|
||||
inline unsigned long Subtract(unsigned long a, unsigned long b) { // NOLINT
|
||||
RTC_DCHECK_LT(a, M);
|
||||
unsigned long sub = b % M; // NOLINT
|
||||
if (a < sub)
|
||||
return M - (sub - a);
|
||||
return a - sub;
|
||||
}
|
||||
|
||||
// Calculates the forward difference between two wrapping numbers.
|
||||
//
|
||||
// Example:
|
||||
// uint8_t x = 253;
|
||||
// uint8_t y = 2;
|
||||
//
|
||||
// ForwardDiff(x, y) == 5
|
||||
//
|
||||
// 252 253 254 255 0 1 2 3
|
||||
// #################################################
|
||||
// | | x | | | | | y | |
|
||||
// #################################################
|
||||
// |----->----->----->----->----->
|
||||
//
|
||||
// ForwardDiff(y, x) == 251
|
||||
//
|
||||
// 252 253 254 255 0 1 2 3
|
||||
// #################################################
|
||||
// | | x | | | | | y | |
|
||||
// #################################################
|
||||
// -->-----> |----->---
|
||||
//
|
||||
template <typename T, T M>
|
||||
inline T ForwardDiff(T a, T b) {
|
||||
static_assert(std::is_unsigned<T>::value,
|
||||
"Type must be an unsigned integer.");
|
||||
RTC_DCHECK_LT(a, M);
|
||||
RTC_DCHECK_LT(b, M);
|
||||
return a <= b ? b - a : M - (a - b);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T ForwardDiff(T a, T b) {
|
||||
static_assert(std::is_unsigned<T>::value,
|
||||
"Type must be an unsigned integer.");
|
||||
return b - a;
|
||||
}
|
||||
|
||||
// Calculates the reverse difference between two wrapping numbers.
|
||||
//
|
||||
// Example:
|
||||
// uint8_t x = 253;
|
||||
// uint8_t y = 2;
|
||||
//
|
||||
// ReverseDiff(y, x) == 5
|
||||
//
|
||||
// 252 253 254 255 0 1 2 3
|
||||
// #################################################
|
||||
// | | x | | | | | y | |
|
||||
// #################################################
|
||||
// <-----<-----<-----<-----<-----|
|
||||
//
|
||||
// ReverseDiff(x, y) == 251
|
||||
//
|
||||
// 252 253 254 255 0 1 2 3
|
||||
// #################################################
|
||||
// | | x | | | | | y | |
|
||||
// #################################################
|
||||
// ---<-----| |<-----<--
|
||||
//
|
||||
template <typename T, T M>
|
||||
inline T ReverseDiff(T a, T b) {
|
||||
static_assert(std::is_unsigned<T>::value,
|
||||
"Type must be an unsigned integer.");
|
||||
RTC_DCHECK_LT(a, M);
|
||||
RTC_DCHECK_LT(b, M);
|
||||
return b <= a ? a - b : M - (b - a);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T ReverseDiff(T a, T b) {
|
||||
static_assert(std::is_unsigned<T>::value,
|
||||
"Type must be an unsigned integer.");
|
||||
return a - b;
|
||||
}
|
||||
|
||||
// Calculates the minimum distance between to wrapping numbers.
|
||||
//
|
||||
// The minimum distance is defined as min(ForwardDiff(a, b), ReverseDiff(a, b))
|
||||
template <typename T, T M>
|
||||
inline T MinDiff(T a, T b) {
|
||||
static_assert(std::is_unsigned<T>::value,
|
||||
"Type must be an unsigned integer.");
|
||||
return std::min(ForwardDiff<T, M>(a, b), ReverseDiff<T, M>(a, b));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T MinDiff(T a, T b) {
|
||||
static_assert(std::is_unsigned<T>::value,
|
||||
"Type must be an unsigned integer.");
|
||||
return std::min(ForwardDiff(a, b), ReverseDiff(a, b));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
// 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/mod_ops.h"
|
||||
|
||||
#endif // WEBRTC_BASE_MOD_OPS_H_
|
||||
|
||||
@ -11,114 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_NATSERVER_H_
|
||||
#define WEBRTC_BASE_NATSERVER_H_
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
#include "webrtc/base/asyncudpsocket.h"
|
||||
#include "webrtc/base/constructormagic.h"
|
||||
#include "webrtc/base/socketaddresspair.h"
|
||||
#include "webrtc/base/thread.h"
|
||||
#include "webrtc/base/socketfactory.h"
|
||||
#include "webrtc/base/nattypes.h"
|
||||
#include "webrtc/base/proxyserver.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
// Change how routes (socketaddress pairs) are compared based on the type of
|
||||
// NAT. The NAT server maintains a hashtable of the routes that it knows
|
||||
// about. So these affect which routes are treated the same.
|
||||
struct RouteCmp {
|
||||
explicit RouteCmp(NAT* nat);
|
||||
size_t operator()(const SocketAddressPair& r) const;
|
||||
bool operator()(
|
||||
const SocketAddressPair& r1, const SocketAddressPair& r2) const;
|
||||
|
||||
bool symmetric;
|
||||
};
|
||||
|
||||
// Changes how addresses are compared based on the filtering rules of the NAT.
|
||||
struct AddrCmp {
|
||||
explicit AddrCmp(NAT* nat);
|
||||
size_t operator()(const SocketAddress& r) const;
|
||||
bool operator()(const SocketAddress& r1, const SocketAddress& r2) const;
|
||||
|
||||
bool use_ip;
|
||||
bool use_port;
|
||||
};
|
||||
|
||||
// Implements the NAT device. It listens for packets on the internal network,
|
||||
// translates them, and sends them out over the external network.
|
||||
//
|
||||
// TCP connections initiated from the internal side of the NAT server are
|
||||
// also supported, by making a connection to the NAT server's TCP address and
|
||||
// then sending the remote address in quasi-STUN format. The connection status
|
||||
// will be indicated back to the client as a 1 byte status code, where '0'
|
||||
// indicates success.
|
||||
|
||||
const int NAT_SERVER_UDP_PORT = 4237;
|
||||
const int NAT_SERVER_TCP_PORT = 4238;
|
||||
|
||||
class NATServer : public sigslot::has_slots<> {
|
||||
public:
|
||||
NATServer(
|
||||
NATType type, SocketFactory* internal,
|
||||
const SocketAddress& internal_udp_addr,
|
||||
const SocketAddress& internal_tcp_addr,
|
||||
SocketFactory* external, const SocketAddress& external_ip);
|
||||
~NATServer() override;
|
||||
|
||||
SocketAddress internal_udp_address() const {
|
||||
return udp_server_socket_->GetLocalAddress();
|
||||
}
|
||||
|
||||
SocketAddress internal_tcp_address() const {
|
||||
return tcp_proxy_server_->GetServerAddress();
|
||||
}
|
||||
|
||||
// Packets received on one of the networks.
|
||||
void OnInternalUDPPacket(AsyncPacketSocket* socket, const char* buf,
|
||||
size_t size, const SocketAddress& addr,
|
||||
const PacketTime& packet_time);
|
||||
void OnExternalUDPPacket(AsyncPacketSocket* socket, const char* buf,
|
||||
size_t size, const SocketAddress& remote_addr,
|
||||
const PacketTime& packet_time);
|
||||
|
||||
private:
|
||||
typedef std::set<SocketAddress, AddrCmp> AddressSet;
|
||||
|
||||
/* Records a translation and the associated external socket. */
|
||||
struct TransEntry {
|
||||
TransEntry(const SocketAddressPair& r, AsyncUDPSocket* s, NAT* nat);
|
||||
~TransEntry();
|
||||
|
||||
void WhitelistInsert(const SocketAddress& addr);
|
||||
bool WhitelistContains(const SocketAddress& ext_addr);
|
||||
|
||||
SocketAddressPair route;
|
||||
AsyncUDPSocket* socket;
|
||||
AddressSet* whitelist;
|
||||
CriticalSection crit_;
|
||||
};
|
||||
|
||||
typedef std::map<SocketAddressPair, TransEntry*, RouteCmp> InternalMap;
|
||||
typedef std::map<SocketAddress, TransEntry*> ExternalMap;
|
||||
|
||||
/* Creates a new entry that translates the given route. */
|
||||
void Translate(const SocketAddressPair& route);
|
||||
|
||||
/* Determines whether the NAT would filter out a packet from this address. */
|
||||
bool ShouldFilterOut(TransEntry* entry, const SocketAddress& ext_addr);
|
||||
|
||||
NAT* nat_;
|
||||
SocketFactory* external_;
|
||||
SocketAddress external_ip_;
|
||||
AsyncUDPSocket* udp_server_socket_;
|
||||
ProxyServer* tcp_proxy_server_;
|
||||
InternalMap* int_map_;
|
||||
ExternalMap* ext_map_;
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(NATServer);
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
// 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/natserver.h"
|
||||
|
||||
#endif // WEBRTC_BASE_NATSERVER_H_
|
||||
|
||||
@ -11,158 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_NATSOCKETFACTORY_H_
|
||||
#define WEBRTC_BASE_NATSOCKETFACTORY_H_
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
|
||||
#include "webrtc/base/constructormagic.h"
|
||||
#include "webrtc/base/natserver.h"
|
||||
#include "webrtc/base/socketaddress.h"
|
||||
#include "webrtc/base/socketserver.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
const size_t kNATEncodedIPv4AddressSize = 8U;
|
||||
const size_t kNATEncodedIPv6AddressSize = 20U;
|
||||
|
||||
// Used by the NAT socket implementation.
|
||||
class NATInternalSocketFactory {
|
||||
public:
|
||||
virtual ~NATInternalSocketFactory() {}
|
||||
virtual AsyncSocket* CreateInternalSocket(int family, int type,
|
||||
const SocketAddress& local_addr, SocketAddress* nat_addr) = 0;
|
||||
};
|
||||
|
||||
// Creates sockets that will send all traffic through a NAT, using an existing
|
||||
// NATServer instance running at nat_addr. The actual data is sent using sockets
|
||||
// from a socket factory, given to the constructor.
|
||||
class NATSocketFactory : public SocketFactory, public NATInternalSocketFactory {
|
||||
public:
|
||||
NATSocketFactory(SocketFactory* factory, const SocketAddress& nat_udp_addr,
|
||||
const SocketAddress& nat_tcp_addr);
|
||||
|
||||
// SocketFactory implementation
|
||||
Socket* CreateSocket(int type) override;
|
||||
Socket* CreateSocket(int family, int type) override;
|
||||
AsyncSocket* CreateAsyncSocket(int type) override;
|
||||
AsyncSocket* CreateAsyncSocket(int family, int type) override;
|
||||
|
||||
// NATInternalSocketFactory implementation
|
||||
AsyncSocket* CreateInternalSocket(int family,
|
||||
int type,
|
||||
const SocketAddress& local_addr,
|
||||
SocketAddress* nat_addr) override;
|
||||
|
||||
private:
|
||||
SocketFactory* factory_;
|
||||
SocketAddress nat_udp_addr_;
|
||||
SocketAddress nat_tcp_addr_;
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(NATSocketFactory);
|
||||
};
|
||||
|
||||
// Creates sockets that will send traffic through a NAT depending on what
|
||||
// address they bind to. This can be used to simulate a client on a NAT sending
|
||||
// to a client that is not behind a NAT.
|
||||
// Note that the internal addresses of clients must be unique. This is because
|
||||
// there is only one socketserver per thread, and the Bind() address is used to
|
||||
// figure out which NAT (if any) the socket should talk to.
|
||||
//
|
||||
// Example with 3 NATs (2 cascaded), and 3 clients.
|
||||
// ss->AddTranslator("1.2.3.4", "192.168.0.1", NAT_ADDR_RESTRICTED);
|
||||
// ss->AddTranslator("99.99.99.99", "10.0.0.1", NAT_SYMMETRIC)->
|
||||
// AddTranslator("10.0.0.2", "192.168.1.1", NAT_OPEN_CONE);
|
||||
// ss->GetTranslator("1.2.3.4")->AddClient("1.2.3.4", "192.168.0.2");
|
||||
// ss->GetTranslator("99.99.99.99")->AddClient("10.0.0.3");
|
||||
// ss->GetTranslator("99.99.99.99")->GetTranslator("10.0.0.2")->
|
||||
// AddClient("192.168.1.2");
|
||||
class NATSocketServer : public SocketServer, public NATInternalSocketFactory {
|
||||
public:
|
||||
class Translator;
|
||||
// holds a list of NATs
|
||||
class TranslatorMap : private std::map<SocketAddress, Translator*> {
|
||||
public:
|
||||
~TranslatorMap();
|
||||
Translator* Get(const SocketAddress& ext_ip);
|
||||
Translator* Add(const SocketAddress& ext_ip, Translator*);
|
||||
void Remove(const SocketAddress& ext_ip);
|
||||
Translator* FindClient(const SocketAddress& int_ip);
|
||||
};
|
||||
|
||||
// a specific NAT
|
||||
class Translator {
|
||||
public:
|
||||
Translator(NATSocketServer* server, NATType type,
|
||||
const SocketAddress& int_addr, SocketFactory* ext_factory,
|
||||
const SocketAddress& ext_addr);
|
||||
~Translator();
|
||||
|
||||
SocketFactory* internal_factory() { return internal_factory_.get(); }
|
||||
SocketAddress internal_udp_address() const {
|
||||
return nat_server_->internal_udp_address();
|
||||
}
|
||||
SocketAddress internal_tcp_address() const {
|
||||
return SocketAddress(); // nat_server_->internal_tcp_address();
|
||||
}
|
||||
|
||||
Translator* GetTranslator(const SocketAddress& ext_ip);
|
||||
Translator* AddTranslator(const SocketAddress& ext_ip,
|
||||
const SocketAddress& int_ip, NATType type);
|
||||
void RemoveTranslator(const SocketAddress& ext_ip);
|
||||
|
||||
bool AddClient(const SocketAddress& int_ip);
|
||||
void RemoveClient(const SocketAddress& int_ip);
|
||||
|
||||
// Looks for the specified client in this or a child NAT.
|
||||
Translator* FindClient(const SocketAddress& int_ip);
|
||||
|
||||
private:
|
||||
NATSocketServer* server_;
|
||||
std::unique_ptr<SocketFactory> internal_factory_;
|
||||
std::unique_ptr<NATServer> nat_server_;
|
||||
TranslatorMap nats_;
|
||||
std::set<SocketAddress> clients_;
|
||||
};
|
||||
|
||||
explicit NATSocketServer(SocketServer* ss);
|
||||
|
||||
SocketServer* socketserver() { return server_; }
|
||||
MessageQueue* queue() { return msg_queue_; }
|
||||
|
||||
Translator* GetTranslator(const SocketAddress& ext_ip);
|
||||
Translator* AddTranslator(const SocketAddress& ext_ip,
|
||||
const SocketAddress& int_ip, NATType type);
|
||||
void RemoveTranslator(const SocketAddress& ext_ip);
|
||||
|
||||
// SocketServer implementation
|
||||
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;
|
||||
|
||||
// NATInternalSocketFactory implementation
|
||||
AsyncSocket* CreateInternalSocket(int family,
|
||||
int type,
|
||||
const SocketAddress& local_addr,
|
||||
SocketAddress* nat_addr) override;
|
||||
|
||||
private:
|
||||
SocketServer* server_;
|
||||
MessageQueue* msg_queue_;
|
||||
TranslatorMap nats_;
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(NATSocketServer);
|
||||
};
|
||||
|
||||
// Free-standing NAT helper functions.
|
||||
size_t PackAddressForNAT(char* buf, size_t buf_size,
|
||||
const SocketAddress& remote_addr);
|
||||
size_t UnpackAddressFromNAT(const char* buf, size_t buf_size,
|
||||
SocketAddress* remote_addr);
|
||||
} // namespace rtc
|
||||
// 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/natsocketfactory.h"
|
||||
|
||||
#endif // WEBRTC_BASE_NATSOCKETFACTORY_H_
|
||||
|
||||
@ -8,40 +8,12 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_BASE_NATTYPE_H__
|
||||
#define WEBRTC_BASE_NATTYPE_H__
|
||||
#ifndef WEBRTC_BASE_NATTYPES_H_
|
||||
#define WEBRTC_BASE_NATTYPES_H_
|
||||
|
||||
namespace rtc {
|
||||
|
||||
/* Identifies each type of NAT that can be simulated. */
|
||||
enum NATType {
|
||||
NAT_OPEN_CONE,
|
||||
NAT_ADDR_RESTRICTED,
|
||||
NAT_PORT_RESTRICTED,
|
||||
NAT_SYMMETRIC
|
||||
};
|
||||
// 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/nattypes.h"
|
||||
|
||||
// Implements the rules for each specific type of NAT.
|
||||
class NAT {
|
||||
public:
|
||||
virtual ~NAT() { }
|
||||
|
||||
// Determines whether this NAT uses both source and destination address when
|
||||
// checking whether a mapping already exists.
|
||||
virtual bool IsSymmetric() = 0;
|
||||
|
||||
// Determines whether this NAT drops packets received from a different IP
|
||||
// the one last sent to.
|
||||
virtual bool FiltersIP() = 0;
|
||||
|
||||
// Determines whether this NAT drops packets received from a different port
|
||||
// the one last sent to.
|
||||
virtual bool FiltersPort() = 0;
|
||||
|
||||
// Returns an implementation of the given type of NAT.
|
||||
static NAT* Create(NATType type);
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // WEBRTC_BASE_NATTYPE_H__
|
||||
#endif // WEBRTC_BASE_NATTYPES_H_
|
||||
|
||||
@ -11,56 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_NETHELPERS_H_
|
||||
#define WEBRTC_BASE_NETHELPERS_H_
|
||||
|
||||
#if defined(WEBRTC_POSIX)
|
||||
#include <netdb.h>
|
||||
#include <stddef.h>
|
||||
#elif WEBRTC_WIN
|
||||
#include <winsock2.h> // NOLINT
|
||||
#endif
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "webrtc/base/asyncresolverinterface.h"
|
||||
#include "webrtc/base/signalthread.h"
|
||||
#include "webrtc/base/sigslot.h"
|
||||
#include "webrtc/base/socketaddress.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
class AsyncResolverTest;
|
||||
|
||||
// AsyncResolver will perform async DNS resolution, signaling the result on
|
||||
// the SignalDone from AsyncResolverInterface when the operation completes.
|
||||
class AsyncResolver : public SignalThread, public AsyncResolverInterface {
|
||||
public:
|
||||
AsyncResolver();
|
||||
~AsyncResolver() override;
|
||||
|
||||
void Start(const SocketAddress& addr) override;
|
||||
bool GetResolvedAddress(int family, SocketAddress* addr) const override;
|
||||
int GetError() const override;
|
||||
void Destroy(bool wait) override;
|
||||
|
||||
const std::vector<IPAddress>& addresses() const { return addresses_; }
|
||||
void set_error(int error) { error_ = error; }
|
||||
|
||||
protected:
|
||||
void DoWork() override;
|
||||
void OnWorkDone() override;
|
||||
|
||||
private:
|
||||
SocketAddress addr_;
|
||||
std::vector<IPAddress> addresses_;
|
||||
int error_;
|
||||
};
|
||||
|
||||
// rtc namespaced wrappers for inet_ntop and inet_pton so we can avoid
|
||||
// the windows-native versions of these.
|
||||
const char* inet_ntop(int af, const void *src, char* dst, socklen_t size);
|
||||
int inet_pton(int af, const char* src, void *dst);
|
||||
|
||||
bool HasIPv4Enabled();
|
||||
bool HasIPv6Enabled();
|
||||
} // namespace rtc
|
||||
// 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/nethelpers.h"
|
||||
|
||||
#endif // WEBRTC_BASE_NETHELPERS_H_
|
||||
|
||||
@ -11,424 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_NETWORK_H_
|
||||
#define WEBRTC_BASE_NETWORK_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/base/ipaddress.h"
|
||||
#include "webrtc/base/networkmonitor.h"
|
||||
#include "webrtc/base/messagehandler.h"
|
||||
#include "webrtc/base/sigslot.h"
|
||||
|
||||
#if defined(WEBRTC_POSIX)
|
||||
struct ifaddrs;
|
||||
#endif // defined(WEBRTC_POSIX)
|
||||
|
||||
namespace rtc {
|
||||
|
||||
extern const char kPublicIPv4Host[];
|
||||
extern const char kPublicIPv6Host[];
|
||||
|
||||
class IfAddrsConverter;
|
||||
class Network;
|
||||
class NetworkMonitorInterface;
|
||||
class Thread;
|
||||
|
||||
static const uint16_t kNetworkCostMax = 999;
|
||||
static const uint16_t kNetworkCostHigh = 900;
|
||||
static const uint16_t kNetworkCostUnknown = 50;
|
||||
static const uint16_t kNetworkCostLow = 10;
|
||||
static const uint16_t kNetworkCostMin = 0;
|
||||
|
||||
// By default, ignore loopback interfaces on the host.
|
||||
const int kDefaultNetworkIgnoreMask = ADAPTER_TYPE_LOOPBACK;
|
||||
|
||||
// Makes a string key for this network. Used in the network manager's maps.
|
||||
// Network objects are keyed on interface name, network prefix and the
|
||||
// length of that prefix.
|
||||
std::string MakeNetworkKey(const std::string& name, const IPAddress& prefix,
|
||||
int prefix_length);
|
||||
|
||||
class DefaultLocalAddressProvider {
|
||||
public:
|
||||
virtual ~DefaultLocalAddressProvider() = default;
|
||||
// The default local address is the local address used in multi-homed endpoint
|
||||
// when the any address (0.0.0.0 or ::) is used as the local address. It's
|
||||
// important to check the return value as a IP family may not be enabled.
|
||||
virtual bool GetDefaultLocalAddress(int family, IPAddress* ipaddr) const = 0;
|
||||
};
|
||||
|
||||
// Generic network manager interface. It provides list of local
|
||||
// networks.
|
||||
//
|
||||
// Every method of NetworkManager (including the destructor) must be called on
|
||||
// the same thread, except for the constructor which may be called on any
|
||||
// thread.
|
||||
//
|
||||
// This allows constructing a NetworkManager subclass on one thread and
|
||||
// passing it into an object that uses it on a different thread.
|
||||
class NetworkManager : public DefaultLocalAddressProvider {
|
||||
public:
|
||||
typedef std::vector<Network*> NetworkList;
|
||||
|
||||
// This enum indicates whether adapter enumeration is allowed.
|
||||
enum EnumerationPermission {
|
||||
ENUMERATION_ALLOWED, // Adapter enumeration is allowed. Getting 0 network
|
||||
// from GetNetworks means that there is no network
|
||||
// available.
|
||||
ENUMERATION_BLOCKED, // Adapter enumeration is disabled.
|
||||
// GetAnyAddressNetworks() should be used instead.
|
||||
};
|
||||
|
||||
NetworkManager();
|
||||
~NetworkManager() override;
|
||||
|
||||
// Called when network list is updated.
|
||||
sigslot::signal0<> SignalNetworksChanged;
|
||||
|
||||
// Indicates a failure when getting list of network interfaces.
|
||||
sigslot::signal0<> SignalError;
|
||||
|
||||
// This should be called on the NetworkManager's thread before the
|
||||
// NetworkManager is used. Subclasses may override this if necessary.
|
||||
virtual void Initialize() {}
|
||||
|
||||
// Start/Stop monitoring of network interfaces
|
||||
// list. SignalNetworksChanged or SignalError is emitted immediately
|
||||
// after StartUpdating() is called. After that SignalNetworksChanged
|
||||
// is emitted whenever list of networks changes.
|
||||
virtual void StartUpdating() = 0;
|
||||
virtual void StopUpdating() = 0;
|
||||
|
||||
// Returns the current list of networks available on this machine.
|
||||
// StartUpdating() must be called before this method is called.
|
||||
// It makes sure that repeated calls return the same object for a
|
||||
// given network, so that quality is tracked appropriately. Does not
|
||||
// include ignored networks.
|
||||
virtual void GetNetworks(NetworkList* networks) const = 0;
|
||||
|
||||
// return the current permission state of GetNetworks()
|
||||
virtual EnumerationPermission enumeration_permission() const;
|
||||
|
||||
// "AnyAddressNetwork" is a network which only contains single "any address"
|
||||
// IP address. (i.e. INADDR_ANY for IPv4 or in6addr_any for IPv6). This is
|
||||
// useful as binding to such interfaces allow default routing behavior like
|
||||
// http traffic.
|
||||
//
|
||||
// This method appends the "any address" networks to the list, such that this
|
||||
// can optionally be called after GetNetworks.
|
||||
//
|
||||
// TODO(guoweis): remove this body when chromium implements this.
|
||||
virtual void GetAnyAddressNetworks(NetworkList* networks) {}
|
||||
|
||||
// Dumps the current list of networks in the network manager.
|
||||
virtual void DumpNetworks() {}
|
||||
bool GetDefaultLocalAddress(int family, IPAddress* ipaddr) const override;
|
||||
|
||||
struct Stats {
|
||||
int ipv4_network_count;
|
||||
int ipv6_network_count;
|
||||
Stats() {
|
||||
ipv4_network_count = 0;
|
||||
ipv6_network_count = 0;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Base class for NetworkManager implementations.
|
||||
class NetworkManagerBase : public NetworkManager {
|
||||
public:
|
||||
NetworkManagerBase();
|
||||
~NetworkManagerBase() override;
|
||||
|
||||
void GetNetworks(NetworkList* networks) const override;
|
||||
void GetAnyAddressNetworks(NetworkList* networks) override;
|
||||
// Defaults to true.
|
||||
bool ipv6_enabled() const { return ipv6_enabled_; }
|
||||
void set_ipv6_enabled(bool enabled) { ipv6_enabled_ = enabled; }
|
||||
|
||||
void set_max_ipv6_networks(int networks) { max_ipv6_networks_ = networks; }
|
||||
int max_ipv6_networks() { return max_ipv6_networks_; }
|
||||
|
||||
EnumerationPermission enumeration_permission() const override;
|
||||
|
||||
bool GetDefaultLocalAddress(int family, IPAddress* ipaddr) const override;
|
||||
|
||||
protected:
|
||||
typedef std::map<std::string, Network*> NetworkMap;
|
||||
// Updates |networks_| with the networks listed in |list|. If
|
||||
// |network_map_| already has a Network object for a network listed
|
||||
// in the |list| then it is reused. Accept ownership of the Network
|
||||
// objects in the |list|. |changed| will be set to true if there is
|
||||
// any change in the network list.
|
||||
void MergeNetworkList(const NetworkList& list, bool* changed);
|
||||
|
||||
// |stats| will be populated even if |*changed| is false.
|
||||
void MergeNetworkList(const NetworkList& list,
|
||||
bool* changed,
|
||||
NetworkManager::Stats* stats);
|
||||
|
||||
void set_enumeration_permission(EnumerationPermission state) {
|
||||
enumeration_permission_ = state;
|
||||
}
|
||||
|
||||
void set_default_local_addresses(const IPAddress& ipv4,
|
||||
const IPAddress& ipv6);
|
||||
|
||||
private:
|
||||
friend class NetworkTest;
|
||||
|
||||
Network* GetNetworkFromAddress(const rtc::IPAddress& ip) const;
|
||||
|
||||
EnumerationPermission enumeration_permission_;
|
||||
|
||||
NetworkList networks_;
|
||||
int max_ipv6_networks_;
|
||||
|
||||
NetworkMap networks_map_;
|
||||
bool ipv6_enabled_;
|
||||
|
||||
std::unique_ptr<rtc::Network> ipv4_any_address_network_;
|
||||
std::unique_ptr<rtc::Network> ipv6_any_address_network_;
|
||||
|
||||
IPAddress default_local_ipv4_address_;
|
||||
IPAddress default_local_ipv6_address_;
|
||||
// We use 16 bits to save the bandwidth consumption when sending the network
|
||||
// id over the Internet. It is OK that the 16-bit integer overflows to get a
|
||||
// network id 0 because we only compare the network ids in the old and the new
|
||||
// best connections in the transport channel.
|
||||
uint16_t next_available_network_id_ = 1;
|
||||
};
|
||||
|
||||
// Basic implementation of the NetworkManager interface that gets list
|
||||
// of networks using OS APIs.
|
||||
class BasicNetworkManager : public NetworkManagerBase,
|
||||
public MessageHandler,
|
||||
public sigslot::has_slots<> {
|
||||
public:
|
||||
BasicNetworkManager();
|
||||
~BasicNetworkManager() override;
|
||||
|
||||
void StartUpdating() override;
|
||||
void StopUpdating() override;
|
||||
|
||||
void DumpNetworks() override;
|
||||
|
||||
// MessageHandler interface.
|
||||
void OnMessage(Message* msg) override;
|
||||
bool started() { return start_count_ > 0; }
|
||||
|
||||
// Sets the network ignore list, which is empty by default. Any network on the
|
||||
// ignore list will be filtered from network enumeration results.
|
||||
void set_network_ignore_list(const std::vector<std::string>& list) {
|
||||
network_ignore_list_ = list;
|
||||
}
|
||||
|
||||
#if defined(WEBRTC_LINUX)
|
||||
// Sets the flag for ignoring non-default routes.
|
||||
void set_ignore_non_default_routes(bool value) {
|
||||
ignore_non_default_routes_ = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
#if defined(WEBRTC_POSIX)
|
||||
// Separated from CreateNetworks for tests.
|
||||
void ConvertIfAddrs(ifaddrs* interfaces,
|
||||
IfAddrsConverter* converter,
|
||||
bool include_ignored,
|
||||
NetworkList* networks) const;
|
||||
#endif // defined(WEBRTC_POSIX)
|
||||
|
||||
// Creates a network object for each network available on the machine.
|
||||
bool CreateNetworks(bool include_ignored, NetworkList* networks) const;
|
||||
|
||||
// Determines if a network should be ignored. This should only be determined
|
||||
// based on the network's property instead of any individual IP.
|
||||
bool IsIgnoredNetwork(const Network& network) const;
|
||||
|
||||
// This function connects a UDP socket to a public address and returns the
|
||||
// local address associated it. Since it binds to the "any" address
|
||||
// internally, it returns the default local address on a multi-homed endpoint.
|
||||
IPAddress QueryDefaultLocalAddress(int family) const;
|
||||
|
||||
private:
|
||||
friend class NetworkTest;
|
||||
|
||||
// Creates a network monitor and listens for network updates.
|
||||
void StartNetworkMonitor();
|
||||
// Stops and removes the network monitor.
|
||||
void StopNetworkMonitor();
|
||||
// Called when it receives updates from the network monitor.
|
||||
void OnNetworksChanged();
|
||||
|
||||
// Updates the networks and reschedules the next update.
|
||||
void UpdateNetworksContinually();
|
||||
// Only updates the networks; does not reschedule the next update.
|
||||
void UpdateNetworksOnce();
|
||||
|
||||
AdapterType GetAdapterTypeFromName(const char* network_name) const;
|
||||
|
||||
Thread* thread_;
|
||||
bool sent_first_update_;
|
||||
int start_count_;
|
||||
std::vector<std::string> network_ignore_list_;
|
||||
bool ignore_non_default_routes_;
|
||||
std::unique_ptr<NetworkMonitorInterface> network_monitor_;
|
||||
};
|
||||
|
||||
// Represents a Unix-type network interface, with a name and single address.
|
||||
class Network {
|
||||
public:
|
||||
Network(const std::string& name,
|
||||
const std::string& description,
|
||||
const IPAddress& prefix,
|
||||
int prefix_length);
|
||||
|
||||
Network(const std::string& name,
|
||||
const std::string& description,
|
||||
const IPAddress& prefix,
|
||||
int prefix_length,
|
||||
AdapterType type);
|
||||
~Network();
|
||||
|
||||
sigslot::signal1<const Network*> SignalTypeChanged;
|
||||
|
||||
const DefaultLocalAddressProvider* default_local_address_provider() {
|
||||
return default_local_address_provider_;
|
||||
}
|
||||
void set_default_local_address_provider(
|
||||
const DefaultLocalAddressProvider* provider) {
|
||||
default_local_address_provider_ = provider;
|
||||
}
|
||||
|
||||
// Returns the name of the interface this network is associated wtih.
|
||||
const std::string& name() const { return name_; }
|
||||
|
||||
// Returns the OS-assigned name for this network. This is useful for
|
||||
// debugging but should not be sent over the wire (for privacy reasons).
|
||||
const std::string& description() const { return description_; }
|
||||
|
||||
// Returns the prefix for this network.
|
||||
const IPAddress& prefix() const { return prefix_; }
|
||||
// Returns the length, in bits, of this network's prefix.
|
||||
int prefix_length() const { return prefix_length_; }
|
||||
|
||||
// |key_| has unique value per network interface. Used in sorting network
|
||||
// interfaces. Key is derived from interface name and it's prefix.
|
||||
std::string key() const { return key_; }
|
||||
|
||||
// Returns the Network's current idea of the 'best' IP it has.
|
||||
// Or return an unset IP if this network has no active addresses.
|
||||
// Here is the rule on how we mark the IPv6 address as ignorable for WebRTC.
|
||||
// 1) return all global temporary dynamic and non-deprecrated ones.
|
||||
// 2) if #1 not available, return global ones.
|
||||
// 3) if #2 not available, use ULA ipv6 as last resort. (ULA stands
|
||||
// for unique local address, which is not route-able in open
|
||||
// internet but might be useful for a close WebRTC deployment.
|
||||
|
||||
// TODO(guoweis): rule #3 actually won't happen at current
|
||||
// implementation. The reason being that ULA address starting with
|
||||
// 0xfc 0r 0xfd will be grouped into its own Network. The result of
|
||||
// that is WebRTC will have one extra Network to generate candidates
|
||||
// but the lack of rule #3 shouldn't prevent turning on IPv6 since
|
||||
// ULA should only be tried in a close deployment anyway.
|
||||
|
||||
// Note that when not specifying any flag, it's treated as case global
|
||||
// IPv6 address
|
||||
IPAddress GetBestIP() const;
|
||||
|
||||
// Keep the original function here for now.
|
||||
// TODO(guoweis): Remove this when all callers are migrated to GetBestIP().
|
||||
IPAddress ip() const { return GetBestIP(); }
|
||||
|
||||
// Adds an active IP address to this network. Does not check for duplicates.
|
||||
void AddIP(const InterfaceAddress& ip) { ips_.push_back(ip); }
|
||||
|
||||
// Sets the network's IP address list. Returns true if new IP addresses were
|
||||
// detected. Passing true to already_changed skips this check.
|
||||
bool SetIPs(const std::vector<InterfaceAddress>& ips, bool already_changed);
|
||||
// Get the list of IP Addresses associated with this network.
|
||||
const std::vector<InterfaceAddress>& GetIPs() const { return ips_;}
|
||||
// Clear the network's list of addresses.
|
||||
void ClearIPs() { ips_.clear(); }
|
||||
|
||||
// Returns the scope-id of the network's address.
|
||||
// Should only be relevant for link-local IPv6 addresses.
|
||||
int scope_id() const { return scope_id_; }
|
||||
void set_scope_id(int id) { scope_id_ = id; }
|
||||
|
||||
// Indicates whether this network should be ignored, perhaps because
|
||||
// the IP is 0, or the interface is one we know is invalid.
|
||||
bool ignored() const { return ignored_; }
|
||||
void set_ignored(bool ignored) { ignored_ = ignored; }
|
||||
|
||||
AdapterType type() const { return type_; }
|
||||
void set_type(AdapterType type) {
|
||||
if (type_ == type) {
|
||||
return;
|
||||
}
|
||||
type_ = type;
|
||||
SignalTypeChanged(this);
|
||||
}
|
||||
|
||||
uint16_t GetCost() const {
|
||||
switch (type_) {
|
||||
case rtc::ADAPTER_TYPE_ETHERNET:
|
||||
case rtc::ADAPTER_TYPE_LOOPBACK:
|
||||
return kNetworkCostMin;
|
||||
case rtc::ADAPTER_TYPE_WIFI:
|
||||
case rtc::ADAPTER_TYPE_VPN:
|
||||
return kNetworkCostLow;
|
||||
case rtc::ADAPTER_TYPE_CELLULAR:
|
||||
return kNetworkCostHigh;
|
||||
default:
|
||||
return kNetworkCostUnknown;
|
||||
}
|
||||
}
|
||||
// A unique id assigned by the network manager, which may be signaled
|
||||
// to the remote side in the candidate.
|
||||
uint16_t id() const { return id_; }
|
||||
void set_id(uint16_t id) { id_ = id; }
|
||||
|
||||
int preference() const { return preference_; }
|
||||
void set_preference(int preference) { preference_ = preference; }
|
||||
|
||||
// When we enumerate networks and find a previously-seen network is missing,
|
||||
// we do not remove it (because it may be used elsewhere). Instead, we mark
|
||||
// it inactive, so that we can detect network changes properly.
|
||||
bool active() const { return active_; }
|
||||
void set_active(bool active) {
|
||||
if (active_ != active) {
|
||||
active_ = active;
|
||||
}
|
||||
}
|
||||
|
||||
// Debugging description of this network
|
||||
std::string ToString() const;
|
||||
|
||||
private:
|
||||
const DefaultLocalAddressProvider* default_local_address_provider_ = nullptr;
|
||||
std::string name_;
|
||||
std::string description_;
|
||||
IPAddress prefix_;
|
||||
int prefix_length_;
|
||||
std::string key_;
|
||||
std::vector<InterfaceAddress> ips_;
|
||||
int scope_id_;
|
||||
bool ignored_;
|
||||
AdapterType type_;
|
||||
int preference_;
|
||||
bool active_ = true;
|
||||
uint16_t id_ = 0;
|
||||
|
||||
friend class NetworkManager;
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
// 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/network.h"
|
||||
|
||||
#endif // WEBRTC_BASE_NETWORK_H_
|
||||
|
||||
@ -11,118 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_NETWORKMONITOR_H_
|
||||
#define WEBRTC_BASE_NETWORKMONITOR_H_
|
||||
|
||||
#include "webrtc/base/logging.h"
|
||||
#include "webrtc/base/sigslot.h"
|
||||
#include "webrtc/base/thread.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
class IPAddress;
|
||||
|
||||
enum class NetworkBindingResult {
|
||||
SUCCESS = 0, // No error
|
||||
FAILURE = -1, // Generic error
|
||||
NOT_IMPLEMENTED = -2,
|
||||
ADDRESS_NOT_FOUND = -3,
|
||||
NETWORK_CHANGED = -4
|
||||
};
|
||||
|
||||
enum AdapterType {
|
||||
// This enum resembles the one in Chromium net::ConnectionType.
|
||||
ADAPTER_TYPE_UNKNOWN = 0,
|
||||
ADAPTER_TYPE_ETHERNET = 1 << 0,
|
||||
ADAPTER_TYPE_WIFI = 1 << 1,
|
||||
ADAPTER_TYPE_CELLULAR = 1 << 2,
|
||||
ADAPTER_TYPE_VPN = 1 << 3,
|
||||
ADAPTER_TYPE_LOOPBACK = 1 << 4
|
||||
};
|
||||
|
||||
class NetworkBinderInterface {
|
||||
public:
|
||||
// Binds a socket to the network that is attached to |address| so that all
|
||||
// packets on the socket |socket_fd| will be sent via that network.
|
||||
// This is needed because some operating systems (like Android) require a
|
||||
// special bind call to put packets on a non-default network interface.
|
||||
virtual NetworkBindingResult BindSocketToNetwork(
|
||||
int socket_fd,
|
||||
const IPAddress& address) = 0;
|
||||
virtual ~NetworkBinderInterface() {}
|
||||
};
|
||||
|
||||
/*
|
||||
* Receives network-change events via |OnNetworksChanged| and signals the
|
||||
* networks changed event.
|
||||
*
|
||||
* Threading consideration:
|
||||
* It is expected that all upstream operations (from native to Java) are
|
||||
* performed from the worker thread. This includes creating, starting and
|
||||
* stopping the monitor. This avoids the potential race condition when creating
|
||||
* the singleton Java NetworkMonitor class. Downstream operations can be from
|
||||
* any thread, but this class will forward all the downstream operations onto
|
||||
* the worker thread.
|
||||
*
|
||||
* Memory consideration:
|
||||
* NetworkMonitor is owned by the caller (NetworkManager). The global network
|
||||
* monitor factory is owned by the factory itself but needs to be released from
|
||||
* the factory creator.
|
||||
*/
|
||||
// Generic network monitor interface. It starts and stops monitoring network
|
||||
// changes, and fires the SignalNetworksChanged event when networks change.
|
||||
class NetworkMonitorInterface {
|
||||
public:
|
||||
NetworkMonitorInterface();
|
||||
virtual ~NetworkMonitorInterface();
|
||||
|
||||
sigslot::signal0<> SignalNetworksChanged;
|
||||
|
||||
virtual void Start() = 0;
|
||||
virtual void Stop() = 0;
|
||||
|
||||
// Implementations should call this method on the base when networks change,
|
||||
// and the base will fire SignalNetworksChanged on the right thread.
|
||||
virtual void OnNetworksChanged() = 0;
|
||||
|
||||
virtual AdapterType GetAdapterType(const std::string& interface_name) = 0;
|
||||
};
|
||||
|
||||
class NetworkMonitorBase : public NetworkMonitorInterface,
|
||||
public MessageHandler,
|
||||
public sigslot::has_slots<> {
|
||||
public:
|
||||
NetworkMonitorBase();
|
||||
~NetworkMonitorBase() override;
|
||||
|
||||
void OnNetworksChanged() override;
|
||||
|
||||
void OnMessage(Message* msg) override;
|
||||
|
||||
protected:
|
||||
Thread* worker_thread() { return worker_thread_; }
|
||||
|
||||
private:
|
||||
Thread* worker_thread_;
|
||||
};
|
||||
|
||||
/*
|
||||
* NetworkMonitorFactory creates NetworkMonitors.
|
||||
*/
|
||||
class NetworkMonitorFactory {
|
||||
public:
|
||||
// This is not thread-safe; it should be called once (or once per audio/video
|
||||
// call) during the call initialization.
|
||||
static void SetFactory(NetworkMonitorFactory* factory);
|
||||
|
||||
static void ReleaseFactory(NetworkMonitorFactory* factory);
|
||||
static NetworkMonitorFactory* GetFactory();
|
||||
|
||||
virtual NetworkMonitorInterface* CreateNetworkMonitor() = 0;
|
||||
|
||||
virtual ~NetworkMonitorFactory();
|
||||
|
||||
protected:
|
||||
NetworkMonitorFactory();
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
// 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/networkmonitor.h"
|
||||
|
||||
#endif // WEBRTC_BASE_NETWORKMONITOR_H_
|
||||
|
||||
@ -11,43 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_NETWORKROUTE_H_
|
||||
#define WEBRTC_BASE_NETWORKROUTE_H_
|
||||
|
||||
// TODO(honghaiz): Make a directory that describes the interfaces and structs
|
||||
// the media code can rely on and the network code can implement, and both can
|
||||
// depend on that, but not depend on each other. Then, move this file to that
|
||||
// directory.
|
||||
namespace rtc {
|
||||
|
||||
struct NetworkRoute {
|
||||
bool connected;
|
||||
uint16_t local_network_id;
|
||||
uint16_t remote_network_id;
|
||||
int last_sent_packet_id; // Last packet id sent on the PREVIOUS route.
|
||||
|
||||
NetworkRoute()
|
||||
: connected(false),
|
||||
local_network_id(0),
|
||||
remote_network_id(0),
|
||||
last_sent_packet_id(-1) {}
|
||||
|
||||
// The route is connected if the local and remote network ids are provided.
|
||||
NetworkRoute(bool connected,
|
||||
uint16_t local_net_id,
|
||||
uint16_t remote_net_id,
|
||||
int last_packet_id)
|
||||
: connected(connected),
|
||||
local_network_id(local_net_id),
|
||||
remote_network_id(remote_net_id),
|
||||
last_sent_packet_id(last_packet_id) {}
|
||||
|
||||
// |last_sent_packet_id| does not affect the NetworkRoute comparison.
|
||||
bool operator==(const NetworkRoute& nr) const {
|
||||
return connected == nr.connected &&
|
||||
local_network_id == nr.local_network_id &&
|
||||
remote_network_id == nr.remote_network_id;
|
||||
}
|
||||
|
||||
bool operator!=(const NetworkRoute& nr) const { return !(*this == nr); }
|
||||
};
|
||||
} // namespace rtc
|
||||
// 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/networkroute.h"
|
||||
|
||||
#endif // WEBRTC_BASE_NETWORKROUTE_H_
|
||||
|
||||
@ -11,28 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_NULLSOCKETSERVER_H_
|
||||
#define WEBRTC_BASE_NULLSOCKETSERVER_H_
|
||||
|
||||
#include "webrtc/base/event.h"
|
||||
#include "webrtc/base/socketserver.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
class NullSocketServer : public SocketServer {
|
||||
public:
|
||||
NullSocketServer();
|
||||
~NullSocketServer() override;
|
||||
|
||||
bool Wait(int cms, bool process_io) override;
|
||||
void WakeUp() override;
|
||||
|
||||
Socket* CreateSocket(int type) override;
|
||||
Socket* CreateSocket(int family, int type) override;
|
||||
AsyncSocket* CreateAsyncSocket(int type) override;
|
||||
AsyncSocket* CreateAsyncSocket(int family, int type) override;
|
||||
|
||||
private:
|
||||
Event event_;
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
// 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/nullsocketserver.h"
|
||||
|
||||
#endif // WEBRTC_BASE_NULLSOCKETSERVER_H_
|
||||
|
||||
@ -11,38 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_NUMERICS_EXP_FILTER_H_
|
||||
#define WEBRTC_BASE_NUMERICS_EXP_FILTER_H_
|
||||
|
||||
namespace rtc {
|
||||
|
||||
// This class can be used, for example, for smoothing the result of bandwidth
|
||||
// estimation and packet loss estimation.
|
||||
|
||||
class ExpFilter {
|
||||
public:
|
||||
static const float kValueUndefined;
|
||||
|
||||
explicit ExpFilter(float alpha, float max = kValueUndefined) : max_(max) {
|
||||
Reset(alpha);
|
||||
}
|
||||
|
||||
// Resets the filter to its initial state, and resets filter factor base to
|
||||
// the given value |alpha|.
|
||||
void Reset(float alpha);
|
||||
|
||||
// Applies the filter with a given exponent on the provided sample:
|
||||
// y(k) = min(alpha_^ exp * y(k-1) + (1 - alpha_^ exp) * sample, max_).
|
||||
float Apply(float exp, float sample);
|
||||
|
||||
// Returns current filtered value.
|
||||
float filtered() const { return filtered_; }
|
||||
|
||||
// Changes the filter factor base to the given value |alpha|.
|
||||
void UpdateBase(float alpha);
|
||||
|
||||
private:
|
||||
float alpha_; // Filter factor base.
|
||||
float filtered_; // Current filter output.
|
||||
const float max_;
|
||||
};
|
||||
} // namespace rtc
|
||||
// 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/numerics/exp_filter.h"
|
||||
|
||||
#endif // WEBRTC_BASE_NUMERICS_EXP_FILTER_H_
|
||||
|
||||
@ -11,105 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_NUMERICS_PERCENTILE_FILTER_H_
|
||||
#define WEBRTC_BASE_NUMERICS_PERCENTILE_FILTER_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <iterator>
|
||||
#include <set>
|
||||
|
||||
#include "webrtc/base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Class to efficiently get the percentile value from a group of observations.
|
||||
// The percentile is the value below which a given percentage of the
|
||||
// observations fall.
|
||||
template <typename T>
|
||||
class PercentileFilter {
|
||||
public:
|
||||
// Construct filter. |percentile| should be between 0 and 1.
|
||||
explicit PercentileFilter(float percentile);
|
||||
|
||||
// Insert one observation. The complexity of this operation is logarithmic in
|
||||
// the size of the container.
|
||||
void Insert(const T& value);
|
||||
|
||||
// Remove one observation or return false if |value| doesn't exist in the
|
||||
// container. The complexity of this operation is logarithmic in the size of
|
||||
// the container.
|
||||
bool Erase(const T& value);
|
||||
|
||||
// Get the percentile value. The complexity of this operation is constant.
|
||||
T GetPercentileValue() const;
|
||||
|
||||
private:
|
||||
// Update iterator and index to point at target percentile value.
|
||||
void UpdatePercentileIterator();
|
||||
|
||||
const float percentile_;
|
||||
std::multiset<T> set_;
|
||||
// Maintain iterator and index of current target percentile value.
|
||||
typename std::multiset<T>::iterator percentile_it_;
|
||||
int64_t percentile_index_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
PercentileFilter<T>::PercentileFilter(float percentile)
|
||||
: percentile_(percentile),
|
||||
percentile_it_(set_.begin()),
|
||||
percentile_index_(0) {
|
||||
RTC_CHECK_GE(percentile, 0.0f);
|
||||
RTC_CHECK_LE(percentile, 1.0f);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void PercentileFilter<T>::Insert(const T& value) {
|
||||
// Insert element at the upper bound.
|
||||
set_.insert(value);
|
||||
if (set_.size() == 1u) {
|
||||
// First element inserted - initialize percentile iterator and index.
|
||||
percentile_it_ = set_.begin();
|
||||
percentile_index_ = 0;
|
||||
} else if (value < *percentile_it_) {
|
||||
// If new element is before us, increment |percentile_index_|.
|
||||
++percentile_index_;
|
||||
}
|
||||
UpdatePercentileIterator();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool PercentileFilter<T>::Erase(const T& value) {
|
||||
typename std::multiset<T>::const_iterator it = set_.lower_bound(value);
|
||||
// Ignore erase operation if the element is not present in the current set.
|
||||
if (it == set_.end() || *it != value)
|
||||
return false;
|
||||
if (it == percentile_it_) {
|
||||
// If same iterator, update to the following element. Index is not
|
||||
// affected.
|
||||
percentile_it_ = set_.erase(it);
|
||||
} else {
|
||||
set_.erase(it);
|
||||
// If erased element was before us, decrement |percentile_index_|.
|
||||
if (value <= *percentile_it_)
|
||||
--percentile_index_;
|
||||
}
|
||||
UpdatePercentileIterator();
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void PercentileFilter<T>::UpdatePercentileIterator() {
|
||||
if (set_.empty())
|
||||
return;
|
||||
const int64_t index = static_cast<int64_t>(percentile_ * (set_.size() - 1));
|
||||
std::advance(percentile_it_, index - percentile_index_);
|
||||
percentile_index_ = index;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T PercentileFilter<T>::GetPercentileValue() const {
|
||||
return set_.empty() ? 0 : *percentile_it_;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
// 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/numerics/percentile_filter.h"
|
||||
|
||||
#endif // WEBRTC_BASE_NUMERICS_PERCENTILE_FILTER_H_
|
||||
|
||||
@ -11,51 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_ONETIMEEVENT_H_
|
||||
#define WEBRTC_BASE_ONETIMEEVENT_H_
|
||||
|
||||
#include "webrtc/base/criticalsection.h"
|
||||
#include "webrtc/typedefs.h"
|
||||
|
||||
namespace webrtc {
|
||||
// Provides a simple way to perform an operation (such as logging) one
|
||||
// time in a certain scope.
|
||||
// Example:
|
||||
// OneTimeEvent firstFrame;
|
||||
// ...
|
||||
// if (firstFrame()) {
|
||||
// LOG(LS_INFO) << "This is the first frame".
|
||||
// }
|
||||
class OneTimeEvent {
|
||||
public:
|
||||
OneTimeEvent() {}
|
||||
bool operator()() {
|
||||
rtc::CritScope cs(&critsect_);
|
||||
if (happened_) {
|
||||
return false;
|
||||
}
|
||||
happened_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
bool happened_ = false;
|
||||
rtc::CriticalSection critsect_;
|
||||
};
|
||||
|
||||
// A non-thread-safe, ligher-weight version of the OneTimeEvent class.
|
||||
class ThreadUnsafeOneTimeEvent {
|
||||
public:
|
||||
ThreadUnsafeOneTimeEvent() {}
|
||||
bool operator()() {
|
||||
if (happened_) {
|
||||
return false;
|
||||
}
|
||||
happened_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
bool happened_ = false;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
// 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/onetimeevent.h"
|
||||
|
||||
#endif // WEBRTC_BASE_ONETIMEEVENT_H_
|
||||
|
||||
@ -11,10 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_OPENSSL_H_
|
||||
#define WEBRTC_BASE_OPENSSL_H_
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10000000L)
|
||||
#error OpenSSL is older than 1.0.0, which is the minimum supported version.
|
||||
#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/openssl.h"
|
||||
|
||||
#endif // WEBRTC_BASE_OPENSSL_H_
|
||||
|
||||
@ -8,105 +8,12 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_BASE_OPENSSLADAPTER_H__
|
||||
#define WEBRTC_BASE_OPENSSLADAPTER_H__
|
||||
#ifndef WEBRTC_BASE_OPENSSLADAPTER_H_
|
||||
#define WEBRTC_BASE_OPENSSLADAPTER_H_
|
||||
|
||||
#include <string>
|
||||
#include "webrtc/base/buffer.h"
|
||||
#include "webrtc/base/messagehandler.h"
|
||||
#include "webrtc/base/messagequeue.h"
|
||||
#include "webrtc/base/ssladapter.h"
|
||||
|
||||
typedef struct ssl_st SSL;
|
||||
typedef struct ssl_ctx_st SSL_CTX;
|
||||
typedef struct x509_store_ctx_st X509_STORE_CTX;
|
||||
// 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/openssladapter.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class OpenSSLAdapter : public SSLAdapter, public MessageHandler {
|
||||
public:
|
||||
static bool InitializeSSL(VerificationCallback callback);
|
||||
static bool InitializeSSLThread();
|
||||
static bool CleanupSSL();
|
||||
|
||||
OpenSSLAdapter(AsyncSocket* socket);
|
||||
~OpenSSLAdapter() override;
|
||||
|
||||
void SetMode(SSLMode mode) override;
|
||||
int StartSSL(const char* hostname, bool restartable) 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 Close() override;
|
||||
|
||||
// Note that the socket returns ST_CONNECTING while SSL is being negotiated.
|
||||
ConnState GetState() const override;
|
||||
|
||||
protected:
|
||||
void OnConnectEvent(AsyncSocket* socket) override;
|
||||
void OnReadEvent(AsyncSocket* socket) override;
|
||||
void OnWriteEvent(AsyncSocket* socket) override;
|
||||
void OnCloseEvent(AsyncSocket* socket, int err) override;
|
||||
|
||||
private:
|
||||
enum SSLState {
|
||||
SSL_NONE, SSL_WAIT, SSL_CONNECTING, SSL_CONNECTED, SSL_ERROR
|
||||
};
|
||||
|
||||
enum { MSG_TIMEOUT };
|
||||
|
||||
int BeginSSL();
|
||||
int ContinueSSL();
|
||||
void Error(const char* context, int err, bool signal = true);
|
||||
void Cleanup();
|
||||
|
||||
// Return value and arguments have the same meanings as for Send; |error| is
|
||||
// an output parameter filled with the result of SSL_get_error.
|
||||
int DoSslWrite(const void* pv, size_t cb, int* error);
|
||||
|
||||
void OnMessage(Message* msg) override;
|
||||
|
||||
static bool VerifyServerName(SSL* ssl, const char* host,
|
||||
bool ignore_bad_cert);
|
||||
bool SSLPostConnectionCheck(SSL* ssl, const char* host);
|
||||
#if !defined(NDEBUG)
|
||||
static void SSLInfoCallback(const SSL* s, int where, int ret);
|
||||
#endif
|
||||
static int SSLVerifyCallback(int ok, X509_STORE_CTX* store);
|
||||
static VerificationCallback custom_verify_callback_;
|
||||
friend class OpenSSLStreamAdapter; // for custom_verify_callback_;
|
||||
|
||||
static bool ConfigureTrustedRootCertificates(SSL_CTX* ctx);
|
||||
SSL_CTX* SetupSSLContext();
|
||||
|
||||
SSLState state_;
|
||||
bool ssl_read_needs_write_;
|
||||
bool ssl_write_needs_read_;
|
||||
// If true, socket will retain SSL configuration after Close.
|
||||
bool restartable_;
|
||||
|
||||
// This buffer is used if SSL_write fails with SSL_ERROR_WANT_WRITE, which
|
||||
// means we need to keep retrying with *the same exact data* until it
|
||||
// succeeds. Afterwards it will be cleared.
|
||||
Buffer pending_data_;
|
||||
|
||||
SSL* ssl_;
|
||||
SSL_CTX* ssl_ctx_;
|
||||
std::string ssl_host_name_;
|
||||
// Do DTLS or not
|
||||
SSLMode ssl_mode_;
|
||||
|
||||
bool custom_verification_succeeded_;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // WEBRTC_BASE_OPENSSLADAPTER_H__
|
||||
#endif // WEBRTC_BASE_OPENSSLADAPTER_H_
|
||||
|
||||
@ -11,40 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_OPENSSLDIGEST_H_
|
||||
#define WEBRTC_BASE_OPENSSLDIGEST_H_
|
||||
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#include "webrtc/base/messagedigest.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
// An implementation of the digest class that uses OpenSSL.
|
||||
class OpenSSLDigest : public MessageDigest {
|
||||
public:
|
||||
// Creates an OpenSSLDigest with |algorithm| as the hash algorithm.
|
||||
explicit OpenSSLDigest(const std::string& algorithm);
|
||||
~OpenSSLDigest() override;
|
||||
// Returns the digest output size (e.g. 16 bytes for MD5).
|
||||
size_t Size() const override;
|
||||
// Updates the digest with |len| bytes from |buf|.
|
||||
void Update(const void* buf, size_t len) override;
|
||||
// Outputs the digest value to |buf| with length |len|.
|
||||
size_t Finish(void* buf, size_t len) override;
|
||||
|
||||
// Helper function to look up a digest's EVP by name.
|
||||
static bool GetDigestEVP(const std::string &algorithm,
|
||||
const EVP_MD** md);
|
||||
// Helper function to look up a digest's name by EVP.
|
||||
static bool GetDigestName(const EVP_MD* md,
|
||||
std::string* algorithm);
|
||||
// Helper function to get the length of a digest.
|
||||
static bool GetDigestSize(const std::string &algorithm,
|
||||
size_t* len);
|
||||
|
||||
private:
|
||||
EVP_MD_CTX ctx_;
|
||||
const EVP_MD* md_;
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
// 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/openssldigest.h"
|
||||
|
||||
#endif // WEBRTC_BASE_OPENSSLDIGEST_H_
|
||||
|
||||
@ -11,137 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_OPENSSLIDENTITY_H_
|
||||
#define WEBRTC_BASE_OPENSSLIDENTITY_H_
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "webrtc/base/checks.h"
|
||||
#include "webrtc/base/constructormagic.h"
|
||||
#include "webrtc/base/sslidentity.h"
|
||||
|
||||
typedef struct ssl_ctx_st SSL_CTX;
|
||||
|
||||
namespace rtc {
|
||||
|
||||
// OpenSSLKeyPair encapsulates an OpenSSL EVP_PKEY* keypair object,
|
||||
// which is reference counted inside the OpenSSL library.
|
||||
class OpenSSLKeyPair {
|
||||
public:
|
||||
explicit OpenSSLKeyPair(EVP_PKEY* pkey) : pkey_(pkey) {
|
||||
RTC_DCHECK(pkey_ != nullptr);
|
||||
}
|
||||
|
||||
static OpenSSLKeyPair* Generate(const KeyParams& key_params);
|
||||
// Constructs a key pair from the private key PEM string. This must not result
|
||||
// in missing public key parameters. Returns null on error.
|
||||
static OpenSSLKeyPair* FromPrivateKeyPEMString(
|
||||
const std::string& pem_string);
|
||||
|
||||
virtual ~OpenSSLKeyPair();
|
||||
|
||||
virtual OpenSSLKeyPair* GetReference();
|
||||
|
||||
EVP_PKEY* pkey() const { return pkey_; }
|
||||
std::string PrivateKeyToPEMString() const;
|
||||
std::string PublicKeyToPEMString() const;
|
||||
bool operator==(const OpenSSLKeyPair& other) const;
|
||||
bool operator!=(const OpenSSLKeyPair& other) const;
|
||||
|
||||
private:
|
||||
void AddReference();
|
||||
|
||||
EVP_PKEY* pkey_;
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(OpenSSLKeyPair);
|
||||
};
|
||||
|
||||
// OpenSSLCertificate encapsulates an OpenSSL X509* certificate object,
|
||||
// which is also reference counted inside the OpenSSL library.
|
||||
class OpenSSLCertificate : public SSLCertificate {
|
||||
public:
|
||||
// Caller retains ownership of the X509 object.
|
||||
explicit OpenSSLCertificate(X509* x509) : x509_(x509) {
|
||||
AddReference();
|
||||
}
|
||||
|
||||
static OpenSSLCertificate* Generate(OpenSSLKeyPair* key_pair,
|
||||
const SSLIdentityParams& params);
|
||||
static OpenSSLCertificate* FromPEMString(const std::string& pem_string);
|
||||
|
||||
~OpenSSLCertificate() override;
|
||||
|
||||
OpenSSLCertificate* GetReference() const override;
|
||||
|
||||
X509* x509() const { return x509_; }
|
||||
|
||||
std::string ToPEMString() const override;
|
||||
void ToDER(Buffer* der_buffer) const override;
|
||||
bool operator==(const OpenSSLCertificate& other) const;
|
||||
bool operator!=(const OpenSSLCertificate& other) const;
|
||||
|
||||
// Compute the digest of the certificate given algorithm
|
||||
bool ComputeDigest(const std::string& algorithm,
|
||||
unsigned char* digest,
|
||||
size_t size,
|
||||
size_t* length) const override;
|
||||
|
||||
// Compute the digest of a certificate as an X509 *
|
||||
static bool ComputeDigest(const X509* x509,
|
||||
const std::string& algorithm,
|
||||
unsigned char* digest,
|
||||
size_t size,
|
||||
size_t* length);
|
||||
|
||||
bool GetSignatureDigestAlgorithm(std::string* algorithm) const override;
|
||||
std::unique_ptr<SSLCertChain> GetChain() const override;
|
||||
|
||||
int64_t CertificateExpirationTime() const override;
|
||||
|
||||
private:
|
||||
void AddReference() const;
|
||||
|
||||
X509* x509_;
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(OpenSSLCertificate);
|
||||
};
|
||||
|
||||
// Holds a keypair and certificate together, and a method to generate
|
||||
// them consistently.
|
||||
class OpenSSLIdentity : public SSLIdentity {
|
||||
public:
|
||||
static OpenSSLIdentity* GenerateWithExpiration(const std::string& common_name,
|
||||
const KeyParams& key_params,
|
||||
time_t certificate_lifetime);
|
||||
static OpenSSLIdentity* GenerateForTest(const SSLIdentityParams& params);
|
||||
static SSLIdentity* FromPEMStrings(const std::string& private_key,
|
||||
const std::string& certificate);
|
||||
~OpenSSLIdentity() override;
|
||||
|
||||
const OpenSSLCertificate& certificate() const override;
|
||||
OpenSSLIdentity* GetReference() const override;
|
||||
|
||||
// Configure an SSL context object to use our key and certificate.
|
||||
bool ConfigureIdentity(SSL_CTX* ctx);
|
||||
|
||||
std::string PrivateKeyToPEMString() const override;
|
||||
std::string PublicKeyToPEMString() const override;
|
||||
bool operator==(const OpenSSLIdentity& other) const;
|
||||
bool operator!=(const OpenSSLIdentity& other) const;
|
||||
|
||||
private:
|
||||
OpenSSLIdentity(OpenSSLKeyPair* key_pair, OpenSSLCertificate* certificate);
|
||||
|
||||
static OpenSSLIdentity* GenerateInternal(const SSLIdentityParams& params);
|
||||
|
||||
std::unique_ptr<OpenSSLKeyPair> key_pair_;
|
||||
std::unique_ptr<OpenSSLCertificate> certificate_;
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(OpenSSLIdentity);
|
||||
};
|
||||
|
||||
|
||||
} // namespace rtc
|
||||
// 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/opensslidentity.h"
|
||||
|
||||
#endif // WEBRTC_BASE_OPENSSLIDENTITY_H_
|
||||
|
||||
@ -8,219 +8,12 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_BASE_OPENSSLSTREAMADAPTER_H__
|
||||
#define WEBRTC_BASE_OPENSSLSTREAMADAPTER_H__
|
||||
#ifndef WEBRTC_BASE_OPENSSLSTREAMADAPTER_H_
|
||||
#define WEBRTC_BASE_OPENSSLSTREAMADAPTER_H_
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/base/buffer.h"
|
||||
#include "webrtc/base/sslstreamadapter.h"
|
||||
#include "webrtc/base/opensslidentity.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/opensslstreamadapter.h"
|
||||
|
||||
typedef struct ssl_st SSL;
|
||||
typedef struct ssl_ctx_st SSL_CTX;
|
||||
typedef struct ssl_cipher_st SSL_CIPHER;
|
||||
typedef struct x509_store_ctx_st X509_STORE_CTX;
|
||||
|
||||
namespace rtc {
|
||||
|
||||
// This class was written with OpenSSLAdapter (a socket adapter) as a
|
||||
// starting point. It has similar structure and functionality, but uses a
|
||||
// "peer-to-peer" mode, verifying the peer's certificate using a digest
|
||||
// sent over a secure signaling channel.
|
||||
//
|
||||
// Static methods to initialize and deinit the SSL library are in
|
||||
// OpenSSLAdapter. These should probably be moved out to a neutral class.
|
||||
//
|
||||
// In a few cases I have factored out some OpenSSLAdapter code into static
|
||||
// methods so it can be reused from this class. Eventually that code should
|
||||
// probably be moved to a common support class. Unfortunately there remain a
|
||||
// few duplicated sections of code. I have not done more restructuring because
|
||||
// I did not want to affect existing code that uses OpenSSLAdapter.
|
||||
//
|
||||
// This class does not support the SSL connection restart feature present in
|
||||
// OpenSSLAdapter. I am not entirely sure how the feature is useful and I am
|
||||
// not convinced that it works properly.
|
||||
//
|
||||
// This implementation is careful to disallow data exchange after an SSL error,
|
||||
// and it has an explicit SSL_CLOSED state. It should not be possible to send
|
||||
// any data in clear after one of the StartSSL methods has been called.
|
||||
|
||||
// Look in sslstreamadapter.h for documentation of the methods.
|
||||
|
||||
class OpenSSLIdentity;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class OpenSSLStreamAdapter : public SSLStreamAdapter {
|
||||
public:
|
||||
explicit OpenSSLStreamAdapter(StreamInterface* stream);
|
||||
~OpenSSLStreamAdapter() override;
|
||||
|
||||
void SetIdentity(SSLIdentity* identity) override;
|
||||
|
||||
// Default argument is for compatibility
|
||||
void SetServerRole(SSLRole role = SSL_SERVER) override;
|
||||
bool SetPeerCertificateDigest(
|
||||
const std::string& digest_alg,
|
||||
const unsigned char* digest_val,
|
||||
size_t digest_len,
|
||||
SSLPeerCertificateDigestError* error = nullptr) override;
|
||||
|
||||
std::unique_ptr<SSLCertificate> GetPeerCertificate() const override;
|
||||
|
||||
// Goes from state SSL_NONE to either SSL_CONNECTING or SSL_WAIT, depending
|
||||
// on whether the underlying stream is already open or not.
|
||||
int StartSSL() override;
|
||||
void SetMode(SSLMode mode) override;
|
||||
void SetMaxProtocolVersion(SSLProtocolVersion version) override;
|
||||
void SetInitialRetransmissionTimeout(int timeout_ms) override;
|
||||
|
||||
StreamResult Read(void* data,
|
||||
size_t data_len,
|
||||
size_t* read,
|
||||
int* error) override;
|
||||
StreamResult Write(const void* data,
|
||||
size_t data_len,
|
||||
size_t* written,
|
||||
int* error) override;
|
||||
void Close() override;
|
||||
StreamState GetState() const override;
|
||||
|
||||
// TODO(guoweis): Move this away from a static class method.
|
||||
static std::string SslCipherSuiteToName(int crypto_suite);
|
||||
|
||||
bool GetSslCipherSuite(int* cipher) override;
|
||||
|
||||
int GetSslVersion() const override;
|
||||
|
||||
// Key Extractor interface
|
||||
bool ExportKeyingMaterial(const std::string& label,
|
||||
const uint8_t* context,
|
||||
size_t context_len,
|
||||
bool use_context,
|
||||
uint8_t* result,
|
||||
size_t result_len) override;
|
||||
|
||||
// DTLS-SRTP interface
|
||||
bool SetDtlsSrtpCryptoSuites(const std::vector<int>& crypto_suites) override;
|
||||
bool GetDtlsSrtpCryptoSuite(int* crypto_suite) override;
|
||||
|
||||
bool IsTlsConnected() override;
|
||||
|
||||
// Capabilities interfaces.
|
||||
static bool IsBoringSsl();
|
||||
|
||||
static bool IsAcceptableCipher(int cipher, KeyType key_type);
|
||||
static bool IsAcceptableCipher(const std::string& cipher, KeyType key_type);
|
||||
|
||||
// Use our timeutils.h source of timing in BoringSSL, allowing us to test
|
||||
// using a fake clock.
|
||||
static void enable_time_callback_for_testing();
|
||||
|
||||
protected:
|
||||
void OnEvent(StreamInterface* stream, int events, int err) override;
|
||||
|
||||
private:
|
||||
enum SSLState {
|
||||
// Before calling one of the StartSSL methods, data flows
|
||||
// in clear text.
|
||||
SSL_NONE,
|
||||
SSL_WAIT, // waiting for the stream to open to start SSL negotiation
|
||||
SSL_CONNECTING, // SSL negotiation in progress
|
||||
SSL_CONNECTED, // SSL stream successfully established
|
||||
SSL_ERROR, // some SSL error occurred, stream is closed
|
||||
SSL_CLOSED // Clean close
|
||||
};
|
||||
|
||||
enum { MSG_TIMEOUT = MSG_MAX+1};
|
||||
|
||||
// The following three methods return 0 on success and a negative
|
||||
// error code on failure. The error code may be from OpenSSL or -1
|
||||
// on some other error cases, so it can't really be interpreted
|
||||
// unfortunately.
|
||||
|
||||
// Prepare SSL library, state is SSL_CONNECTING.
|
||||
int BeginSSL();
|
||||
// Perform SSL negotiation steps.
|
||||
int ContinueSSL();
|
||||
|
||||
// Error handler helper. signal is given as true for errors in
|
||||
// asynchronous contexts (when an error method was not returned
|
||||
// through some other method), and in that case an SE_CLOSE event is
|
||||
// raised on the stream with the specified error.
|
||||
// A 0 error means a graceful close, otherwise there is not really enough
|
||||
// context to interpret the error code.
|
||||
// |alert| indicates an alert description (one of the SSL_AD constants) to
|
||||
// send to the remote endpoint when closing the association. If 0, a normal
|
||||
// shutdown will be performed.
|
||||
void Error(const char* context, int err, uint8_t alert, bool signal);
|
||||
void Cleanup(uint8_t alert);
|
||||
|
||||
// Override MessageHandler
|
||||
void OnMessage(Message* msg) override;
|
||||
|
||||
// Flush the input buffers by reading left bytes (for DTLS)
|
||||
void FlushInput(unsigned int left);
|
||||
|
||||
// SSL library configuration
|
||||
SSL_CTX* SetupSSLContext();
|
||||
// Verify the peer certificate matches the signaled digest.
|
||||
bool VerifyPeerCertificate();
|
||||
// SSL certification verification error handler, called back from
|
||||
// the openssl library. Returns an int interpreted as a boolean in
|
||||
// the C style: zero means verification failure, non-zero means
|
||||
// passed.
|
||||
static int SSLVerifyCallback(int ok, X509_STORE_CTX* store);
|
||||
|
||||
bool waiting_to_verify_peer_certificate() const {
|
||||
return client_auth_enabled() && !peer_certificate_verified_;
|
||||
}
|
||||
|
||||
bool has_peer_certificate_digest() const {
|
||||
return !peer_certificate_digest_algorithm_.empty() &&
|
||||
!peer_certificate_digest_value_.empty();
|
||||
}
|
||||
|
||||
SSLState state_;
|
||||
SSLRole role_;
|
||||
int ssl_error_code_; // valid when state_ == SSL_ERROR or SSL_CLOSED
|
||||
// Whether the SSL negotiation is blocked on needing to read or
|
||||
// write to the wrapped stream.
|
||||
bool ssl_read_needs_write_;
|
||||
bool ssl_write_needs_read_;
|
||||
|
||||
SSL* ssl_;
|
||||
SSL_CTX* ssl_ctx_;
|
||||
|
||||
// Our key and certificate.
|
||||
std::unique_ptr<OpenSSLIdentity> identity_;
|
||||
// The certificate that the peer presented. Initially null, until the
|
||||
// connection is established.
|
||||
std::unique_ptr<OpenSSLCertificate> peer_certificate_;
|
||||
bool peer_certificate_verified_ = false;
|
||||
// The digest of the certificate that the peer must present.
|
||||
Buffer peer_certificate_digest_value_;
|
||||
std::string peer_certificate_digest_algorithm_;
|
||||
|
||||
// The DtlsSrtp ciphers
|
||||
std::string srtp_ciphers_;
|
||||
|
||||
// Do DTLS or not
|
||||
SSLMode ssl_mode_;
|
||||
|
||||
// Max. allowed protocol version
|
||||
SSLProtocolVersion ssl_max_version_;
|
||||
|
||||
// A 50-ms initial timeout ensures rapid setup on fast connections, but may
|
||||
// be too aggressive for low bandwidth links.
|
||||
int dtls_handshake_timeout_ms_ = 50;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // WEBRTC_BASE_OPENSSLSTREAMADAPTER_H__
|
||||
#endif // WEBRTC_BASE_OPENSSLSTREAMADAPTER_H_
|
||||
|
||||
@ -11,399 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_OPTIONAL_H_
|
||||
#define WEBRTC_BASE_OPTIONAL_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#ifdef UNIT_TEST
|
||||
#include <iomanip>
|
||||
#include <ostream>
|
||||
#endif // UNIT_TEST
|
||||
|
||||
#include "webrtc/base/array_view.h"
|
||||
#include "webrtc/base/checks.h"
|
||||
#include "webrtc/base/sanitizer.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
namespace optional_internal {
|
||||
|
||||
#if RTC_HAS_ASAN
|
||||
|
||||
// This is a non-inlined function. The optimizer can't see inside it. It
|
||||
// prevents the compiler from generating optimized code that reads value_ even
|
||||
// if it is unset. Although safe, this causes memory sanitizers to complain.
|
||||
void* FunctionThatDoesNothingImpl(void*);
|
||||
|
||||
template <typename T>
|
||||
inline T* FunctionThatDoesNothing(T* x) {
|
||||
return reinterpret_cast<T*>(
|
||||
FunctionThatDoesNothingImpl(reinterpret_cast<void*>(x)));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template <typename T>
|
||||
inline T* FunctionThatDoesNothing(T* x) { return x; }
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace optional_internal
|
||||
|
||||
// Simple std::optional-wannabe. It either contains a T or not.
|
||||
//
|
||||
// A moved-from Optional<T> may only be destroyed, and assigned to if T allows
|
||||
// being assigned to after having been moved from. Specifically, you may not
|
||||
// assume that it just doesn't contain a value anymore.
|
||||
//
|
||||
// Examples of good places to use Optional:
|
||||
//
|
||||
// - As a class or struct member, when the member doesn't always have a value:
|
||||
// struct Prisoner {
|
||||
// std::string name;
|
||||
// Optional<int> cell_number; // Empty if not currently incarcerated.
|
||||
// };
|
||||
//
|
||||
// - As a return value for functions that may fail to return a value on all
|
||||
// allowed inputs. For example, a function that searches an array might
|
||||
// return an Optional<size_t> (the index where it found the element, or
|
||||
// nothing if it didn't find it); and a function that parses numbers might
|
||||
// return Optional<double> (the parsed number, or nothing if parsing failed).
|
||||
//
|
||||
// Examples of bad places to use Optional:
|
||||
//
|
||||
// - As a return value for functions that may fail because of disallowed
|
||||
// inputs. For example, a string length function should not return
|
||||
// Optional<size_t> so that it can return nothing in case the caller passed
|
||||
// it a null pointer; the function should probably use RTC_[D]CHECK instead,
|
||||
// and return plain size_t.
|
||||
//
|
||||
// - As a return value for functions that may fail to return a value on all
|
||||
// allowed inputs, but need to tell the caller what went wrong. Returning
|
||||
// Optional<double> when parsing a single number as in the example above
|
||||
// might make sense, but any larger parse job is probably going to need to
|
||||
// tell the caller what the problem was, not just that there was one.
|
||||
//
|
||||
// - As a non-mutable function argument. When you want to pass a value of a
|
||||
// type T that can fail to be there, const T* is almost always both fastest
|
||||
// and cleanest. (If you're *sure* that the the caller will always already
|
||||
// have an Optional<T>, const Optional<T>& is slightly faster than const T*,
|
||||
// but this is a micro-optimization. In general, stick to const T*.)
|
||||
//
|
||||
// TODO(kwiberg): Get rid of this class when the standard library has
|
||||
// std::optional (and we're allowed to use it).
|
||||
template <typename T>
|
||||
class Optional final {
|
||||
public:
|
||||
// Construct an empty Optional.
|
||||
Optional() : has_value_(false), empty_('\0') {
|
||||
PoisonValue();
|
||||
}
|
||||
|
||||
// Construct an Optional that contains a value.
|
||||
explicit Optional(const T& value) : has_value_(true) {
|
||||
new (&value_) T(value);
|
||||
}
|
||||
explicit Optional(T&& value) : has_value_(true) {
|
||||
new (&value_) T(std::move(value));
|
||||
}
|
||||
|
||||
// Copy constructor: copies the value from m if it has one.
|
||||
Optional(const Optional& m) : has_value_(m.has_value_) {
|
||||
if (has_value_)
|
||||
new (&value_) T(m.value_);
|
||||
else
|
||||
PoisonValue();
|
||||
}
|
||||
|
||||
// Move constructor: if m has a value, moves the value from m, leaving m
|
||||
// still in a state where it has a value, but a moved-from one (the
|
||||
// properties of which depends on T; the only general guarantee is that we
|
||||
// can destroy m).
|
||||
Optional(Optional&& m) : has_value_(m.has_value_) {
|
||||
if (has_value_)
|
||||
new (&value_) T(std::move(m.value_));
|
||||
else
|
||||
PoisonValue();
|
||||
}
|
||||
|
||||
~Optional() {
|
||||
if (has_value_)
|
||||
value_.~T();
|
||||
else
|
||||
UnpoisonValue();
|
||||
}
|
||||
|
||||
// Copy assignment. Uses T's copy assignment if both sides have a value, T's
|
||||
// copy constructor if only the right-hand side has a value.
|
||||
Optional& operator=(const Optional& m) {
|
||||
if (m.has_value_) {
|
||||
if (has_value_) {
|
||||
value_ = m.value_; // T's copy assignment.
|
||||
} else {
|
||||
UnpoisonValue();
|
||||
new (&value_) T(m.value_); // T's copy constructor.
|
||||
has_value_ = true;
|
||||
}
|
||||
} else {
|
||||
reset();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Move assignment. Uses T's move assignment if both sides have a value, T's
|
||||
// move constructor if only the right-hand side has a value. The state of m
|
||||
// after it's been moved from is as for the move constructor.
|
||||
Optional& operator=(Optional&& m) {
|
||||
if (m.has_value_) {
|
||||
if (has_value_) {
|
||||
value_ = std::move(m.value_); // T's move assignment.
|
||||
} else {
|
||||
UnpoisonValue();
|
||||
new (&value_) T(std::move(m.value_)); // T's move constructor.
|
||||
has_value_ = true;
|
||||
}
|
||||
} else {
|
||||
reset();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Swap the values if both m1 and m2 have values; move the value if only one
|
||||
// of them has one.
|
||||
friend void swap(Optional& m1, Optional& m2) {
|
||||
if (m1.has_value_) {
|
||||
if (m2.has_value_) {
|
||||
// Both have values: swap.
|
||||
using std::swap;
|
||||
swap(m1.value_, m2.value_);
|
||||
} else {
|
||||
// Only m1 has a value: move it to m2.
|
||||
m2.UnpoisonValue();
|
||||
new (&m2.value_) T(std::move(m1.value_));
|
||||
m1.value_.~T(); // Destroy the moved-from value.
|
||||
m1.has_value_ = false;
|
||||
m2.has_value_ = true;
|
||||
m1.PoisonValue();
|
||||
}
|
||||
} else if (m2.has_value_) {
|
||||
// Only m2 has a value: move it to m1.
|
||||
m1.UnpoisonValue();
|
||||
new (&m1.value_) T(std::move(m2.value_));
|
||||
m2.value_.~T(); // Destroy the moved-from value.
|
||||
m1.has_value_ = true;
|
||||
m2.has_value_ = false;
|
||||
m2.PoisonValue();
|
||||
}
|
||||
}
|
||||
|
||||
// Destroy any contained value. Has no effect if we have no value.
|
||||
void reset() {
|
||||
if (!has_value_)
|
||||
return;
|
||||
value_.~T();
|
||||
has_value_ = false;
|
||||
PoisonValue();
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
void emplace(Args&&... args) {
|
||||
if (has_value_)
|
||||
value_.~T();
|
||||
else
|
||||
UnpoisonValue();
|
||||
new (&value_) T(std::forward<Args>(args)...);
|
||||
has_value_ = true;
|
||||
}
|
||||
|
||||
// Conversion to bool to test if we have a value.
|
||||
explicit operator bool() const { return has_value_; }
|
||||
bool has_value() const { return has_value_; }
|
||||
|
||||
// Dereferencing. Only allowed if we have a value.
|
||||
const T* operator->() const {
|
||||
RTC_DCHECK(has_value_);
|
||||
return &value_;
|
||||
}
|
||||
T* operator->() {
|
||||
RTC_DCHECK(has_value_);
|
||||
return &value_;
|
||||
}
|
||||
const T& operator*() const {
|
||||
RTC_DCHECK(has_value_);
|
||||
return value_;
|
||||
}
|
||||
T& operator*() {
|
||||
RTC_DCHECK(has_value_);
|
||||
return value_;
|
||||
}
|
||||
const T& value() const {
|
||||
RTC_DCHECK(has_value_);
|
||||
return value_;
|
||||
}
|
||||
T& value() {
|
||||
RTC_DCHECK(has_value_);
|
||||
return value_;
|
||||
}
|
||||
|
||||
// Dereference with a default value in case we don't have a value.
|
||||
const T& value_or(const T& default_val) const {
|
||||
// The no-op call prevents the compiler from generating optimized code that
|
||||
// reads value_ even if !has_value_, but only if FunctionThatDoesNothing is
|
||||
// not completely inlined; see its declaration.).
|
||||
return has_value_ ? *optional_internal::FunctionThatDoesNothing(&value_)
|
||||
: default_val;
|
||||
}
|
||||
|
||||
// Dereference and move value.
|
||||
T MoveValue() {
|
||||
RTC_DCHECK(has_value_);
|
||||
return std::move(value_);
|
||||
}
|
||||
|
||||
// Equality tests. Two Optionals are equal if they contain equivalent values,
|
||||
// or if they're both empty.
|
||||
friend bool operator==(const Optional& m1, const Optional& m2) {
|
||||
return m1.has_value_ && m2.has_value_ ? m1.value_ == m2.value_
|
||||
: m1.has_value_ == m2.has_value_;
|
||||
}
|
||||
friend bool operator==(const Optional& opt, const T& value) {
|
||||
return opt.has_value_ && opt.value_ == value;
|
||||
}
|
||||
friend bool operator==(const T& value, const Optional& opt) {
|
||||
return opt.has_value_ && value == opt.value_;
|
||||
}
|
||||
|
||||
friend bool operator!=(const Optional& m1, const Optional& m2) {
|
||||
return m1.has_value_ && m2.has_value_ ? m1.value_ != m2.value_
|
||||
: m1.has_value_ != m2.has_value_;
|
||||
}
|
||||
friend bool operator!=(const Optional& opt, const T& value) {
|
||||
return !opt.has_value_ || opt.value_ != value;
|
||||
}
|
||||
friend bool operator!=(const T& value, const Optional& opt) {
|
||||
return !opt.has_value_ || value != opt.value_;
|
||||
}
|
||||
|
||||
private:
|
||||
// Tell sanitizers that value_ shouldn't be touched.
|
||||
void PoisonValue() {
|
||||
rtc::AsanPoison(rtc::MakeArrayView(&value_, 1));
|
||||
rtc::MsanMarkUninitialized(rtc::MakeArrayView(&value_, 1));
|
||||
}
|
||||
|
||||
// Tell sanitizers that value_ is OK to touch again.
|
||||
void UnpoisonValue() {
|
||||
rtc::AsanUnpoison(rtc::MakeArrayView(&value_, 1));
|
||||
}
|
||||
|
||||
bool has_value_; // True iff value_ contains a live value.
|
||||
union {
|
||||
// empty_ exists only to make it possible to initialize the union, even when
|
||||
// it doesn't contain any data. If the union goes uninitialized, it may
|
||||
// trigger compiler warnings.
|
||||
char empty_;
|
||||
// By placing value_ in a union, we get to manage its construction and
|
||||
// destruction manually: the Optional constructors won't automatically
|
||||
// construct it, and the Optional destructor won't automatically destroy
|
||||
// it. Basically, this just allocates a properly sized and aligned block of
|
||||
// memory in which we can manually put a T with placement new.
|
||||
T value_;
|
||||
};
|
||||
};
|
||||
|
||||
#ifdef UNIT_TEST
|
||||
namespace optional_internal {
|
||||
|
||||
// Checks if there's a valid PrintTo(const T&, std::ostream*) call for T.
|
||||
template <typename T>
|
||||
struct HasPrintTo {
|
||||
private:
|
||||
struct No {};
|
||||
|
||||
template <typename T2>
|
||||
static auto Test(const T2& obj)
|
||||
-> decltype(PrintTo(obj, std::declval<std::ostream*>()));
|
||||
|
||||
template <typename>
|
||||
static No Test(...);
|
||||
|
||||
public:
|
||||
static constexpr bool value =
|
||||
!std::is_same<decltype(Test<T>(std::declval<const T&>())), No>::value;
|
||||
};
|
||||
|
||||
// Checks if there's a valid operator<<(std::ostream&, const T&) call for T.
|
||||
template <typename T>
|
||||
struct HasOstreamOperator {
|
||||
private:
|
||||
struct No {};
|
||||
|
||||
template <typename T2>
|
||||
static auto Test(const T2& obj)
|
||||
-> decltype(std::declval<std::ostream&>() << obj);
|
||||
|
||||
template <typename>
|
||||
static No Test(...);
|
||||
|
||||
public:
|
||||
static constexpr bool value =
|
||||
!std::is_same<decltype(Test<T>(std::declval<const T&>())), No>::value;
|
||||
};
|
||||
|
||||
// Prefer using PrintTo to print the object.
|
||||
template <typename T>
|
||||
typename std::enable_if<HasPrintTo<T>::value, void>::type OptionalPrintToHelper(
|
||||
const T& value,
|
||||
std::ostream* os) {
|
||||
PrintTo(value, os);
|
||||
}
|
||||
|
||||
// Fall back to operator<<(std::ostream&, ...) if it exists.
|
||||
template <typename T>
|
||||
typename std::enable_if<HasOstreamOperator<T>::value && !HasPrintTo<T>::value,
|
||||
void>::type
|
||||
OptionalPrintToHelper(const T& value, std::ostream* os) {
|
||||
*os << value;
|
||||
}
|
||||
|
||||
inline void OptionalPrintObjectBytes(const unsigned char* bytes,
|
||||
size_t size,
|
||||
std::ostream* os) {
|
||||
*os << "<optional with " << size << "-byte object [";
|
||||
for (size_t i = 0; i != size; ++i) {
|
||||
*os << (i == 0 ? "" : ((i & 1) ? "-" : " "));
|
||||
*os << std::hex << std::setw(2) << std::setfill('0')
|
||||
<< static_cast<int>(bytes[i]);
|
||||
}
|
||||
*os << "]>";
|
||||
}
|
||||
|
||||
// As a final back-up, just print the contents of the objcets byte-wise.
|
||||
template <typename T>
|
||||
typename std::enable_if<!HasOstreamOperator<T>::value && !HasPrintTo<T>::value,
|
||||
void>::type
|
||||
OptionalPrintToHelper(const T& value, std::ostream* os) {
|
||||
OptionalPrintObjectBytes(reinterpret_cast<const unsigned char*>(&value),
|
||||
sizeof(value), os);
|
||||
}
|
||||
|
||||
} // namespace optional_internal
|
||||
|
||||
// PrintTo is used by gtest to print out the results of tests. We want to ensure
|
||||
// the object contained in an Optional can be printed out if it's set, while
|
||||
// avoiding touching the object's storage if it is undefined.
|
||||
template <typename T>
|
||||
void PrintTo(const rtc::Optional<T>& opt, std::ostream* os) {
|
||||
if (opt) {
|
||||
optional_internal::OptionalPrintToHelper(*opt, os);
|
||||
} else {
|
||||
*os << "<empty optional>";
|
||||
}
|
||||
}
|
||||
|
||||
#endif // UNIT_TEST
|
||||
|
||||
} // namespace rtc
|
||||
// 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/optional.h"
|
||||
|
||||
#endif // WEBRTC_BASE_OPTIONAL_H_
|
||||
|
||||
@ -11,40 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_OPTIONSFILE_H_
|
||||
#define WEBRTC_BASE_OPTIONSFILE_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
namespace rtc {
|
||||
|
||||
// Implements storage of simple options in a text file on disk. This is
|
||||
// cross-platform, but it is intended mostly for Linux where there is no
|
||||
// first-class options storage system.
|
||||
class OptionsFile {
|
||||
public:
|
||||
OptionsFile(const std::string &path);
|
||||
~OptionsFile();
|
||||
|
||||
// Loads the file from disk, overwriting the in-memory values.
|
||||
bool Load();
|
||||
// Saves the contents in memory, overwriting the on-disk values.
|
||||
bool Save();
|
||||
|
||||
bool GetStringValue(const std::string& option, std::string* out_val) const;
|
||||
bool GetIntValue(const std::string& option, int* out_val) const;
|
||||
bool SetStringValue(const std::string& option, const std::string& val);
|
||||
bool SetIntValue(const std::string& option, int val);
|
||||
bool RemoveValue(const std::string& option);
|
||||
|
||||
private:
|
||||
typedef std::map<std::string, std::string> OptionsMap;
|
||||
|
||||
static bool IsLegalName(const std::string &name);
|
||||
static bool IsLegalValue(const std::string &value);
|
||||
|
||||
std::string path_;
|
||||
OptionsMap options_;
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
// 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/optionsfile.h"
|
||||
|
||||
#endif // WEBRTC_BASE_OPTIONSFILE_H_
|
||||
|
||||
@ -8,86 +8,12 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_BASE_PATHUTILS_H__
|
||||
#define WEBRTC_BASE_PATHUTILS_H__
|
||||
#ifndef WEBRTC_BASE_PATHUTILS_H_
|
||||
#define WEBRTC_BASE_PATHUTILS_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "webrtc/base/checks.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/pathutils.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Pathname - parsing of pathnames into components, and vice versa.
|
||||
//
|
||||
// To establish consistent terminology, a filename never contains a folder
|
||||
// component. A folder never contains a filename. A pathname may include
|
||||
// a folder and/or filename component. Here are some examples:
|
||||
//
|
||||
// pathname() /home/john/example.txt
|
||||
// folder() /home/john/
|
||||
// filename() example.txt
|
||||
// parent_folder() /home/
|
||||
// folder_name() john/
|
||||
// basename() example
|
||||
// extension() .txt
|
||||
//
|
||||
// Basename may begin, end, and/or include periods, but no folder delimiters.
|
||||
// If extension exists, it consists of a period followed by zero or more
|
||||
// non-period/non-delimiter characters, and basename is non-empty.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Pathname {
|
||||
public:
|
||||
// Folder delimiters are slash and backslash
|
||||
static bool IsFolderDelimiter(char ch);
|
||||
static char DefaultFolderDelimiter();
|
||||
|
||||
Pathname();
|
||||
Pathname(const Pathname&);
|
||||
Pathname(Pathname&&);
|
||||
Pathname(const std::string& pathname);
|
||||
Pathname(const std::string& folder, const std::string& filename);
|
||||
|
||||
Pathname& operator=(const Pathname&);
|
||||
Pathname& operator=(Pathname&&);
|
||||
|
||||
// Normalize changes all folder delimiters to folder_delimiter()
|
||||
void Normalize();
|
||||
|
||||
// Reset to the empty pathname
|
||||
void clear();
|
||||
|
||||
// Returns true if the pathname is empty. Note: this->pathname().empty()
|
||||
// is always false.
|
||||
bool empty() const;
|
||||
|
||||
// Returns the folder and filename components. If the pathname is empty,
|
||||
// returns a string representing the current directory (as a relative path,
|
||||
// i.e., ".").
|
||||
std::string pathname() const;
|
||||
void SetPathname(const std::string& pathname);
|
||||
void SetPathname(const std::string& folder, const std::string& filename);
|
||||
|
||||
std::string folder() const;
|
||||
std::string parent_folder() const;
|
||||
// SetFolder and AppendFolder will append a folder delimiter, if needed.
|
||||
void SetFolder(const std::string& folder);
|
||||
void AppendFolder(const std::string& folder);
|
||||
|
||||
bool SetBasename(const std::string& basename);
|
||||
|
||||
// SetExtension will prefix a period, if needed.
|
||||
bool SetExtension(const std::string& extension);
|
||||
|
||||
std::string filename() const;
|
||||
bool SetFilename(const std::string& filename);
|
||||
|
||||
private:
|
||||
std::string folder_, basename_, extension_;
|
||||
char folder_delimiter_;
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // WEBRTC_BASE_PATHUTILS_H__
|
||||
#endif // WEBRTC_BASE_PATHUTILS_H_
|
||||
|
||||
@ -8,263 +8,12 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_BASE_PHYSICALSOCKETSERVER_H__
|
||||
#define WEBRTC_BASE_PHYSICALSOCKETSERVER_H__
|
||||
#ifndef WEBRTC_BASE_PHYSICALSOCKETSERVER_H_
|
||||
#define WEBRTC_BASE_PHYSICALSOCKETSERVER_H_
|
||||
|
||||
#if defined(WEBRTC_POSIX) && defined(WEBRTC_LINUX)
|
||||
#include <sys/epoll.h>
|
||||
#define WEBRTC_USE_EPOLL 1
|
||||
#endif
|
||||
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#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/physicalsocketserver.h"
|
||||
|
||||
#include "webrtc/base/nethelpers.h"
|
||||
#include "webrtc/base/socketserver.h"
|
||||
#include "webrtc/base/criticalsection.h"
|
||||
|
||||
#if defined(WEBRTC_POSIX)
|
||||
typedef int SOCKET;
|
||||
#endif // WEBRTC_POSIX
|
||||
|
||||
namespace rtc {
|
||||
|
||||
// Event constants for the Dispatcher class.
|
||||
enum DispatcherEvent {
|
||||
DE_READ = 0x0001,
|
||||
DE_WRITE = 0x0002,
|
||||
DE_CONNECT = 0x0004,
|
||||
DE_CLOSE = 0x0008,
|
||||
DE_ACCEPT = 0x0010,
|
||||
};
|
||||
|
||||
class Signaler;
|
||||
#if defined(WEBRTC_POSIX)
|
||||
class PosixSignalDispatcher;
|
||||
#endif
|
||||
|
||||
class Dispatcher {
|
||||
public:
|
||||
virtual ~Dispatcher() {}
|
||||
virtual uint32_t GetRequestedEvents() = 0;
|
||||
virtual void OnPreEvent(uint32_t ff) = 0;
|
||||
virtual void OnEvent(uint32_t ff, int err) = 0;
|
||||
#if defined(WEBRTC_WIN)
|
||||
virtual WSAEVENT GetWSAEvent() = 0;
|
||||
virtual SOCKET GetSocket() = 0;
|
||||
virtual bool CheckSignalClose() = 0;
|
||||
#elif defined(WEBRTC_POSIX)
|
||||
virtual int GetDescriptor() = 0;
|
||||
virtual bool IsDescriptorClosed() = 0;
|
||||
#endif
|
||||
};
|
||||
|
||||
// A socket server that provides the real sockets of the underlying OS.
|
||||
class PhysicalSocketServer : public SocketServer {
|
||||
public:
|
||||
PhysicalSocketServer();
|
||||
~PhysicalSocketServer() override;
|
||||
|
||||
// SocketFactory:
|
||||
Socket* CreateSocket(int type) override;
|
||||
Socket* CreateSocket(int family, int type) override;
|
||||
|
||||
AsyncSocket* CreateAsyncSocket(int type) override;
|
||||
AsyncSocket* CreateAsyncSocket(int family, int type) override;
|
||||
|
||||
// Internal Factory for Accept (virtual so it can be overwritten in tests).
|
||||
virtual AsyncSocket* WrapSocket(SOCKET s);
|
||||
|
||||
// SocketServer:
|
||||
bool Wait(int cms, bool process_io) override;
|
||||
void WakeUp() override;
|
||||
|
||||
void Add(Dispatcher* dispatcher);
|
||||
void Remove(Dispatcher* dispatcher);
|
||||
void Update(Dispatcher* dispatcher);
|
||||
|
||||
#if defined(WEBRTC_POSIX)
|
||||
// Sets the function to be executed in response to the specified POSIX signal.
|
||||
// The function is executed from inside Wait() using the "self-pipe trick"--
|
||||
// regardless of which thread receives the signal--and hence can safely
|
||||
// manipulate user-level data structures.
|
||||
// "handler" may be SIG_IGN, SIG_DFL, or a user-specified function, just like
|
||||
// with signal(2).
|
||||
// Only one PhysicalSocketServer should have user-level signal handlers.
|
||||
// Dispatching signals on multiple PhysicalSocketServers is not reliable.
|
||||
// The signal mask is not modified. It is the caller's responsibily to
|
||||
// maintain it as desired.
|
||||
virtual bool SetPosixSignalHandler(int signum, void (*handler)(int));
|
||||
|
||||
protected:
|
||||
Dispatcher* signal_dispatcher();
|
||||
#endif
|
||||
|
||||
private:
|
||||
typedef std::set<Dispatcher*> DispatcherSet;
|
||||
|
||||
void AddRemovePendingDispatchers();
|
||||
|
||||
#if defined(WEBRTC_POSIX)
|
||||
bool WaitSelect(int cms, bool process_io);
|
||||
static bool InstallSignal(int signum, void (*handler)(int));
|
||||
|
||||
std::unique_ptr<PosixSignalDispatcher> signal_dispatcher_;
|
||||
#endif // WEBRTC_POSIX
|
||||
#if defined(WEBRTC_USE_EPOLL)
|
||||
void AddEpoll(Dispatcher* dispatcher);
|
||||
void RemoveEpoll(Dispatcher* dispatcher);
|
||||
void UpdateEpoll(Dispatcher* dispatcher);
|
||||
bool WaitEpoll(int cms);
|
||||
bool WaitPoll(int cms, Dispatcher* dispatcher);
|
||||
|
||||
int epoll_fd_ = INVALID_SOCKET;
|
||||
std::vector<struct epoll_event> epoll_events_;
|
||||
#endif // WEBRTC_USE_EPOLL
|
||||
DispatcherSet dispatchers_;
|
||||
DispatcherSet pending_add_dispatchers_;
|
||||
DispatcherSet pending_remove_dispatchers_;
|
||||
bool processing_dispatchers_ = false;
|
||||
Signaler* signal_wakeup_;
|
||||
CriticalSection crit_;
|
||||
bool fWait_;
|
||||
#if defined(WEBRTC_WIN)
|
||||
WSAEVENT socket_ev_;
|
||||
#endif
|
||||
};
|
||||
|
||||
class PhysicalSocket : public AsyncSocket, public sigslot::has_slots<> {
|
||||
public:
|
||||
PhysicalSocket(PhysicalSocketServer* ss, SOCKET s = INVALID_SOCKET);
|
||||
~PhysicalSocket() override;
|
||||
|
||||
// Creates the underlying OS socket (same as the "socket" function).
|
||||
virtual bool Create(int family, int type);
|
||||
|
||||
SocketAddress GetLocalAddress() const override;
|
||||
SocketAddress GetRemoteAddress() const override;
|
||||
|
||||
int Bind(const SocketAddress& bind_addr) override;
|
||||
int Connect(const SocketAddress& addr) 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;
|
||||
|
||||
int Send(const void* pv, size_t cb) override;
|
||||
int SendTo(const void* buffer,
|
||||
size_t length,
|
||||
const SocketAddress& addr) override;
|
||||
|
||||
int Recv(void* buffer, size_t length, int64_t* timestamp) override;
|
||||
int RecvFrom(void* buffer,
|
||||
size_t length,
|
||||
SocketAddress* out_addr,
|
||||
int64_t* timestamp) override;
|
||||
|
||||
int Listen(int backlog) override;
|
||||
AsyncSocket* Accept(SocketAddress* out_addr) override;
|
||||
|
||||
int Close() override;
|
||||
|
||||
SocketServer* socketserver() { return ss_; }
|
||||
|
||||
protected:
|
||||
int DoConnect(const SocketAddress& connect_addr);
|
||||
|
||||
// Make virtual so ::accept can be overwritten in tests.
|
||||
virtual SOCKET DoAccept(SOCKET socket, sockaddr* addr, socklen_t* addrlen);
|
||||
|
||||
// Make virtual so ::send can be overwritten in tests.
|
||||
virtual int DoSend(SOCKET socket, const char* buf, int len, int flags);
|
||||
|
||||
// Make virtual so ::sendto can be overwritten in tests.
|
||||
virtual int DoSendTo(SOCKET socket, const char* buf, int len, int flags,
|
||||
const struct sockaddr* dest_addr, socklen_t addrlen);
|
||||
|
||||
void OnResolveResult(AsyncResolverInterface* resolver);
|
||||
|
||||
void UpdateLastError();
|
||||
void MaybeRemapSendError();
|
||||
|
||||
uint8_t enabled_events() const { return enabled_events_; }
|
||||
virtual void SetEnabledEvents(uint8_t events);
|
||||
virtual void EnableEvents(uint8_t events);
|
||||
virtual void DisableEvents(uint8_t events);
|
||||
|
||||
static int TranslateOption(Option opt, int* slevel, int* sopt);
|
||||
|
||||
PhysicalSocketServer* ss_;
|
||||
SOCKET s_;
|
||||
bool udp_;
|
||||
CriticalSection crit_;
|
||||
int error_ GUARDED_BY(crit_);
|
||||
ConnState state_;
|
||||
AsyncResolver* resolver_;
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
std::string dbg_addr_;
|
||||
#endif
|
||||
|
||||
private:
|
||||
uint8_t enabled_events_ = 0;
|
||||
};
|
||||
|
||||
class SocketDispatcher : public Dispatcher, public PhysicalSocket {
|
||||
public:
|
||||
explicit SocketDispatcher(PhysicalSocketServer *ss);
|
||||
SocketDispatcher(SOCKET s, PhysicalSocketServer *ss);
|
||||
~SocketDispatcher() override;
|
||||
|
||||
bool Initialize();
|
||||
|
||||
virtual bool Create(int type);
|
||||
bool Create(int family, int type) override;
|
||||
|
||||
#if defined(WEBRTC_WIN)
|
||||
WSAEVENT GetWSAEvent() override;
|
||||
SOCKET GetSocket() override;
|
||||
bool CheckSignalClose() override;
|
||||
#elif defined(WEBRTC_POSIX)
|
||||
int GetDescriptor() override;
|
||||
bool IsDescriptorClosed() override;
|
||||
#endif
|
||||
|
||||
uint32_t GetRequestedEvents() override;
|
||||
void OnPreEvent(uint32_t ff) override;
|
||||
void OnEvent(uint32_t ff, int err) override;
|
||||
|
||||
int Close() override;
|
||||
|
||||
#if defined(WEBRTC_USE_EPOLL)
|
||||
protected:
|
||||
void StartBatchedEventUpdates();
|
||||
void FinishBatchedEventUpdates();
|
||||
|
||||
void SetEnabledEvents(uint8_t events) override;
|
||||
void EnableEvents(uint8_t events) override;
|
||||
void DisableEvents(uint8_t events) override;
|
||||
#endif
|
||||
|
||||
private:
|
||||
#if defined(WEBRTC_WIN)
|
||||
static int next_id_;
|
||||
int id_;
|
||||
bool signal_close_;
|
||||
int signal_err_;
|
||||
#endif // WEBRTC_WIN
|
||||
#if defined(WEBRTC_USE_EPOLL)
|
||||
void MaybeUpdateDispatcher(uint8_t old_events);
|
||||
|
||||
int saved_enabled_events_ = -1;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // WEBRTC_BASE_PHYSICALSOCKETSERVER_H__
|
||||
#endif // WEBRTC_BASE_PHYSICALSOCKETSERVER_H_
|
||||
|
||||
@ -11,46 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_PLATFORM_FILE_H_
|
||||
#define WEBRTC_BASE_PLATFORM_FILE_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
#if defined(WEBRTC_WIN)
|
||||
#include "webrtc/base/win32.h"
|
||||
#endif
|
||||
|
||||
namespace rtc {
|
||||
|
||||
#if defined(WEBRTC_WIN)
|
||||
typedef HANDLE PlatformFile;
|
||||
#elif defined(WEBRTC_POSIX)
|
||||
typedef int PlatformFile;
|
||||
#else
|
||||
#error Unsupported platform
|
||||
#endif
|
||||
|
||||
extern const PlatformFile kInvalidPlatformFileValue;
|
||||
|
||||
// Associates a standard FILE stream with an existing PlatformFile.
|
||||
// Note that after this function has returned a valid FILE stream,
|
||||
// the PlatformFile should no longer be used.
|
||||
FILE* FdopenPlatformFileForWriting(PlatformFile file);
|
||||
|
||||
// Closes a PlatformFile.
|
||||
// Don't use ClosePlatformFile to close a file opened with FdopenPlatformFile.
|
||||
// Use fclose instead.
|
||||
bool ClosePlatformFile(PlatformFile file);
|
||||
|
||||
// Removes a file in the filesystem.
|
||||
bool RemoveFile(const std::string& path);
|
||||
|
||||
// Opens a file for reading and writing. You might want to use base/file.h
|
||||
// instead.
|
||||
PlatformFile OpenPlatformFile(const std::string& path);
|
||||
|
||||
// Creates a new file for reading and writing. If the file already exists it
|
||||
// will be overwritten. You might want to use base/file.h instead.
|
||||
PlatformFile CreatePlatformFile(const std::string& path);
|
||||
|
||||
} // namespace rtc
|
||||
// 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/platform_file.h"
|
||||
|
||||
#endif // WEBRTC_BASE_PLATFORM_FILE_H_
|
||||
|
||||
@ -11,114 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_PLATFORM_THREAD_H_
|
||||
#define WEBRTC_BASE_PLATFORM_THREAD_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "webrtc/base/constructormagic.h"
|
||||
#include "webrtc/base/event.h"
|
||||
#include "webrtc/base/platform_thread_types.h"
|
||||
#include "webrtc/base/thread_checker.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
PlatformThreadId CurrentThreadId();
|
||||
PlatformThreadRef CurrentThreadRef();
|
||||
|
||||
// Compares two thread identifiers for equality.
|
||||
bool IsThreadRefEqual(const PlatformThreadRef& a, const PlatformThreadRef& b);
|
||||
|
||||
// Sets the current thread name.
|
||||
void SetCurrentThreadName(const char* name);
|
||||
|
||||
// Callback function that the spawned thread will enter once spawned.
|
||||
// A return value of false is interpreted as that the function has no
|
||||
// more work to do and that the thread can be released.
|
||||
typedef bool (*ThreadRunFunctionDeprecated)(void*);
|
||||
typedef void (*ThreadRunFunction)(void*);
|
||||
|
||||
enum ThreadPriority {
|
||||
#ifdef WEBRTC_WIN
|
||||
kLowPriority = THREAD_PRIORITY_BELOW_NORMAL,
|
||||
kNormalPriority = THREAD_PRIORITY_NORMAL,
|
||||
kHighPriority = THREAD_PRIORITY_ABOVE_NORMAL,
|
||||
kHighestPriority = THREAD_PRIORITY_HIGHEST,
|
||||
kRealtimePriority = THREAD_PRIORITY_TIME_CRITICAL
|
||||
#else
|
||||
kLowPriority = 1,
|
||||
kNormalPriority = 2,
|
||||
kHighPriority = 3,
|
||||
kHighestPriority = 4,
|
||||
kRealtimePriority = 5
|
||||
#endif
|
||||
};
|
||||
|
||||
// Represents a simple worker thread. The implementation must be assumed
|
||||
// to be single threaded, meaning that all methods of the class, must be
|
||||
// called from the same thread, including instantiation.
|
||||
class PlatformThread {
|
||||
public:
|
||||
PlatformThread(ThreadRunFunctionDeprecated func,
|
||||
void* obj,
|
||||
const char* thread_name);
|
||||
PlatformThread(ThreadRunFunction func,
|
||||
void* obj,
|
||||
const char* thread_name,
|
||||
ThreadPriority priority = kNormalPriority);
|
||||
virtual ~PlatformThread();
|
||||
|
||||
const std::string& name() const { return name_; }
|
||||
|
||||
// Spawns a thread and tries to set thread priority according to the priority
|
||||
// from when CreateThread was called.
|
||||
void Start();
|
||||
|
||||
bool IsRunning() const;
|
||||
|
||||
// Returns an identifier for the worker thread that can be used to do
|
||||
// thread checks.
|
||||
PlatformThreadRef GetThreadRef() const;
|
||||
|
||||
// Stops (joins) the spawned thread.
|
||||
void Stop();
|
||||
|
||||
// Set the priority of the thread. Must be called when thread is running.
|
||||
// TODO(tommi): Make private and only allow public support via ctor.
|
||||
bool SetPriority(ThreadPriority priority);
|
||||
|
||||
protected:
|
||||
#if defined(WEBRTC_WIN)
|
||||
// Exposed to derived classes to allow for special cases specific to Windows.
|
||||
bool QueueAPC(PAPCFUNC apc_function, ULONG_PTR data);
|
||||
#endif
|
||||
|
||||
private:
|
||||
void Run();
|
||||
|
||||
ThreadRunFunctionDeprecated const run_function_deprecated_ = nullptr;
|
||||
ThreadRunFunction const run_function_ = nullptr;
|
||||
const ThreadPriority priority_ = kNormalPriority;
|
||||
void* const obj_;
|
||||
// TODO(pbos): Make sure call sites use string literals and update to a const
|
||||
// char* instead of a std::string.
|
||||
const std::string name_;
|
||||
rtc::ThreadChecker thread_checker_;
|
||||
rtc::ThreadChecker spawned_thread_checker_;
|
||||
#if defined(WEBRTC_WIN)
|
||||
static DWORD WINAPI StartThread(void* param);
|
||||
|
||||
bool stop_ = false;
|
||||
HANDLE thread_ = nullptr;
|
||||
DWORD thread_id_ = 0;
|
||||
#else
|
||||
static void* StartThread(void* param);
|
||||
|
||||
// An atomic flag that we use to stop the thread. Only modified on the
|
||||
// controlling thread and checked on the worker thread.
|
||||
volatile int stop_flag_ = 0;
|
||||
pthread_t thread_ = 0;
|
||||
#endif // defined(WEBRTC_WIN)
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(PlatformThread);
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
// 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/platform_thread.h"
|
||||
|
||||
#endif // WEBRTC_BASE_PLATFORM_THREAD_H_
|
||||
|
||||
@ -11,22 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_PLATFORM_THREAD_TYPES_H_
|
||||
#define WEBRTC_BASE_PLATFORM_THREAD_TYPES_H_
|
||||
|
||||
#if defined(WEBRTC_WIN)
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#elif defined(WEBRTC_POSIX)
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
namespace rtc {
|
||||
#if defined(WEBRTC_WIN)
|
||||
typedef DWORD PlatformThreadId;
|
||||
typedef DWORD PlatformThreadRef;
|
||||
#elif defined(WEBRTC_POSIX)
|
||||
typedef pid_t PlatformThreadId;
|
||||
typedef pthread_t PlatformThreadRef;
|
||||
#endif
|
||||
} // namespace rtc
|
||||
// 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/platform_thread_types.h"
|
||||
|
||||
#endif // WEBRTC_BASE_PLATFORM_THREAD_TYPES_H_
|
||||
|
||||
@ -13,24 +13,9 @@
|
||||
#ifndef WEBRTC_BASE_PROTOBUF_UTILS_H_
|
||||
#define WEBRTC_BASE_PROTOBUF_UTILS_H_
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
using ProtoString = std::string;
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#if WEBRTC_ENABLE_PROTOBUF
|
||||
|
||||
#include "third_party/protobuf/src/google/protobuf/message_lite.h"
|
||||
#include "third_party/protobuf/src/google/protobuf/repeated_field.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
using google::protobuf::MessageLite;
|
||||
using google::protobuf::RepeatedPtrField;
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_ENABLE_PROTOBUF
|
||||
// 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/protobuf_utils.h"
|
||||
|
||||
#endif // WEBRTC_BASE_PROTOBUF_UTILS_H_
|
||||
|
||||
@ -8,36 +8,12 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_BASE_PROXYINFO_H__
|
||||
#define WEBRTC_BASE_PROXYINFO_H__
|
||||
#ifndef WEBRTC_BASE_PROXYINFO_H_
|
||||
#define WEBRTC_BASE_PROXYINFO_H_
|
||||
|
||||
#include <string>
|
||||
#include "webrtc/base/socketaddress.h"
|
||||
#include "webrtc/base/cryptstring.h"
|
||||
|
||||
namespace rtc {
|
||||
// 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/proxyinfo.h"
|
||||
|
||||
enum ProxyType {
|
||||
PROXY_NONE,
|
||||
PROXY_HTTPS,
|
||||
PROXY_SOCKS5,
|
||||
PROXY_UNKNOWN
|
||||
};
|
||||
const char * ProxyToString(ProxyType proxy);
|
||||
|
||||
struct ProxyInfo {
|
||||
ProxyType type;
|
||||
SocketAddress address;
|
||||
std::string autoconfig_url;
|
||||
bool autodetect;
|
||||
std::string bypass_list;
|
||||
std::string username;
|
||||
CryptString password;
|
||||
|
||||
ProxyInfo();
|
||||
~ProxyInfo();
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // WEBRTC_BASE_PROXYINFO_H__
|
||||
#endif // WEBRTC_BASE_PROXYINFO_H_
|
||||
|
||||
@ -11,90 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_PROXYSERVER_H_
|
||||
#define WEBRTC_BASE_PROXYSERVER_H_
|
||||
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include "webrtc/base/asyncsocket.h"
|
||||
#include "webrtc/base/constructormagic.h"
|
||||
#include "webrtc/base/socketadapters.h"
|
||||
#include "webrtc/base/socketaddress.h"
|
||||
#include "webrtc/base/stream.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
class SocketFactory;
|
||||
|
||||
// ProxyServer is a base class that allows for easy construction of proxy
|
||||
// servers. With its helper class ProxyBinding, it contains all the necessary
|
||||
// logic for receiving and bridging connections. The specific client-server
|
||||
// proxy protocol is implemented by an instance of the AsyncProxyServerSocket
|
||||
// class; children of ProxyServer implement WrapSocket appropriately to return
|
||||
// the correct protocol handler.
|
||||
|
||||
class ProxyBinding : public sigslot::has_slots<> {
|
||||
public:
|
||||
ProxyBinding(AsyncProxyServerSocket* in_socket, AsyncSocket* out_socket);
|
||||
~ProxyBinding() override;
|
||||
sigslot::signal1<ProxyBinding*> SignalDestroyed;
|
||||
|
||||
private:
|
||||
void OnConnectRequest(AsyncProxyServerSocket* socket,
|
||||
const SocketAddress& addr);
|
||||
void OnInternalRead(AsyncSocket* socket);
|
||||
void OnInternalWrite(AsyncSocket* socket);
|
||||
void OnInternalClose(AsyncSocket* socket, int err);
|
||||
void OnExternalConnect(AsyncSocket* socket);
|
||||
void OnExternalRead(AsyncSocket* socket);
|
||||
void OnExternalWrite(AsyncSocket* socket);
|
||||
void OnExternalClose(AsyncSocket* socket, int err);
|
||||
|
||||
static void Read(AsyncSocket* socket, FifoBuffer* buffer);
|
||||
static void Write(AsyncSocket* socket, FifoBuffer* buffer);
|
||||
void Destroy();
|
||||
|
||||
static const int kBufferSize = 4096;
|
||||
std::unique_ptr<AsyncProxyServerSocket> int_socket_;
|
||||
std::unique_ptr<AsyncSocket> ext_socket_;
|
||||
bool connected_;
|
||||
FifoBuffer out_buffer_;
|
||||
FifoBuffer in_buffer_;
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(ProxyBinding);
|
||||
};
|
||||
|
||||
class ProxyServer : public sigslot::has_slots<> {
|
||||
public:
|
||||
ProxyServer(SocketFactory* int_factory, const SocketAddress& int_addr,
|
||||
SocketFactory* ext_factory, const SocketAddress& ext_ip);
|
||||
~ProxyServer() override;
|
||||
|
||||
// Returns the address to which the proxy server is bound
|
||||
SocketAddress GetServerAddress();
|
||||
|
||||
protected:
|
||||
void OnAcceptEvent(AsyncSocket* socket);
|
||||
virtual AsyncProxyServerSocket* WrapSocket(AsyncSocket* socket) = 0;
|
||||
void OnBindingDestroyed(ProxyBinding* binding);
|
||||
|
||||
private:
|
||||
typedef std::list<ProxyBinding*> BindingList;
|
||||
SocketFactory* ext_factory_;
|
||||
SocketAddress ext_ip_;
|
||||
std::unique_ptr<AsyncSocket> server_socket_;
|
||||
BindingList bindings_;
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(ProxyServer);
|
||||
};
|
||||
|
||||
// SocksProxyServer is a simple extension of ProxyServer to implement SOCKS.
|
||||
class SocksProxyServer : public ProxyServer {
|
||||
public:
|
||||
SocksProxyServer(SocketFactory* int_factory, const SocketAddress& int_addr,
|
||||
SocketFactory* ext_factory, const SocketAddress& ext_ip)
|
||||
: ProxyServer(int_factory, int_addr, ext_factory, ext_ip) {
|
||||
}
|
||||
protected:
|
||||
AsyncProxyServerSocket* WrapSocket(AsyncSocket* socket) override;
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(SocksProxyServer);
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
// 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/proxyserver.h"
|
||||
|
||||
#endif // WEBRTC_BASE_PROXYSERVER_H_
|
||||
|
||||
@ -13,70 +13,9 @@
|
||||
#ifndef WEBRTC_BASE_PTR_UTIL_H_
|
||||
#define WEBRTC_BASE_PTR_UTIL_H_
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
namespace rtc {
|
||||
|
||||
// Helper to transfer ownership of a raw pointer to a std::unique_ptr<T>.
|
||||
// Note that std::unique_ptr<T> has very different semantics from
|
||||
// std::unique_ptr<T[]>: do not use this helper for array allocations.
|
||||
template <typename T>
|
||||
std::unique_ptr<T> WrapUnique(T* ptr) {
|
||||
return std::unique_ptr<T>(ptr);
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
template <typename T>
|
||||
struct MakeUniqueResult {
|
||||
using Scalar = std::unique_ptr<T>;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct MakeUniqueResult<T[]> {
|
||||
using Array = std::unique_ptr<T[]>;
|
||||
};
|
||||
|
||||
template <typename T, size_t N>
|
||||
struct MakeUniqueResult<T[N]> {
|
||||
using Invalid = void;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Helper to construct an object wrapped in a std::unique_ptr. This is an
|
||||
// implementation of C++14's std::make_unique that can be used in Chrome.
|
||||
//
|
||||
// MakeUnique<T>(args) should be preferred over WrapUnique(new T(args)): bare
|
||||
// calls to `new` should be treated with scrutiny.
|
||||
//
|
||||
// Usage:
|
||||
// // ptr is a std::unique_ptr<std::string>
|
||||
// auto ptr = MakeUnique<std::string>("hello world!");
|
||||
//
|
||||
// // arr is a std::unique_ptr<int[]>
|
||||
// auto arr = MakeUnique<int[]>(5);
|
||||
|
||||
// Overload for non-array types. Arguments are forwarded to T's constructor.
|
||||
template <typename T, typename... Args>
|
||||
typename internal::MakeUniqueResult<T>::Scalar MakeUnique(Args&&... args) {
|
||||
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
// Overload for array types of unknown bound, e.g. T[]. The array is allocated
|
||||
// with `new T[n]()` and value-initialized: note that this is distinct from
|
||||
// `new T[n]`, which default-initializes.
|
||||
template <typename T>
|
||||
typename internal::MakeUniqueResult<T>::Array MakeUnique(size_t size) {
|
||||
return std::unique_ptr<T>(new typename std::remove_extent<T>::type[size]());
|
||||
}
|
||||
|
||||
// Overload to reject array types of known bound, e.g. T[n].
|
||||
template <typename T, typename... Args>
|
||||
typename internal::MakeUniqueResult<T>::Invalid MakeUnique(Args&&... args) =
|
||||
delete;
|
||||
|
||||
} // namespace rtc
|
||||
// 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/ptr_util.h"
|
||||
|
||||
#endif // WEBRTC_BASE_PTR_UTIL_H_
|
||||
|
||||
@ -11,68 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_RACE_CHECKER_H_
|
||||
#define WEBRTC_BASE_RACE_CHECKER_H_
|
||||
|
||||
#include "webrtc/base/checks.h"
|
||||
#include "webrtc/base/platform_thread.h"
|
||||
#include "webrtc/base/thread_annotations.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
namespace internal {
|
||||
class RaceCheckerScope;
|
||||
} // namespace internal
|
||||
|
||||
// Best-effort race-checking implementation. This primitive uses no
|
||||
// synchronization at all to be as-fast-as-possible in the non-racy case.
|
||||
class LOCKABLE RaceChecker {
|
||||
public:
|
||||
friend class internal::RaceCheckerScope;
|
||||
RaceChecker();
|
||||
|
||||
private:
|
||||
bool Acquire() const EXCLUSIVE_LOCK_FUNCTION();
|
||||
void Release() const UNLOCK_FUNCTION();
|
||||
|
||||
// Volatile to prevent code being optimized away in Acquire()/Release().
|
||||
mutable volatile int access_count_ = 0;
|
||||
mutable volatile PlatformThreadRef accessing_thread_;
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
class SCOPED_LOCKABLE RaceCheckerScope {
|
||||
public:
|
||||
explicit RaceCheckerScope(const RaceChecker* race_checker)
|
||||
EXCLUSIVE_LOCK_FUNCTION(race_checker);
|
||||
|
||||
bool RaceDetected() const;
|
||||
~RaceCheckerScope() UNLOCK_FUNCTION();
|
||||
|
||||
private:
|
||||
const RaceChecker* const race_checker_;
|
||||
const bool race_check_ok_;
|
||||
};
|
||||
|
||||
class SCOPED_LOCKABLE RaceCheckerScopeDoNothing {
|
||||
public:
|
||||
explicit RaceCheckerScopeDoNothing(const RaceChecker* race_checker)
|
||||
EXCLUSIVE_LOCK_FUNCTION(race_checker) {}
|
||||
|
||||
~RaceCheckerScopeDoNothing() UNLOCK_FUNCTION() {}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace rtc
|
||||
|
||||
#define RTC_CHECK_RUNS_SERIALIZED(x) \
|
||||
rtc::internal::RaceCheckerScope race_checker(x); \
|
||||
RTC_CHECK(!race_checker.RaceDetected())
|
||||
|
||||
#if RTC_DCHECK_IS_ON
|
||||
#define RTC_DCHECK_RUNS_SERIALIZED(x) \
|
||||
rtc::internal::RaceCheckerScope race_checker(x); \
|
||||
RTC_DCHECK(!race_checker.RaceDetected())
|
||||
#else
|
||||
#define RTC_DCHECK_RUNS_SERIALIZED(x) \
|
||||
rtc::internal::RaceCheckerScopeDoNothing race_checker(x)
|
||||
#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/race_checker.h"
|
||||
|
||||
#endif // WEBRTC_BASE_RACE_CHECKER_H_
|
||||
|
||||
@ -11,83 +11,9 @@
|
||||
#ifndef WEBRTC_BASE_RANDOM_H_
|
||||
#define WEBRTC_BASE_RANDOM_H_
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "webrtc/typedefs.h"
|
||||
#include "webrtc/base/constructormagic.h"
|
||||
#include "webrtc/base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class Random {
|
||||
public:
|
||||
// TODO(tommi): Change this so that the seed can be initialized internally,
|
||||
// e.g. by offering two ways of constructing or offer a static method that
|
||||
// returns a seed that's suitable for initialization.
|
||||
// The problem now is that callers are calling clock_->TimeInMicroseconds()
|
||||
// which calls TickTime::Now().Ticks(), which can return a very low value on
|
||||
// Mac and can result in a seed of 0 after conversion to microseconds.
|
||||
// Besides the quality of the random seed being poor, this also requires
|
||||
// the client to take on extra dependencies to generate a seed.
|
||||
// If we go for a static seed generator in Random, we can use something from
|
||||
// webrtc/base and make sure that it works the same way across platforms.
|
||||
// See also discussion here: https://codereview.webrtc.org/1623543002/
|
||||
explicit Random(uint64_t seed);
|
||||
|
||||
// Return pseudo-random integer of the specified type.
|
||||
// We need to limit the size to 32 bits to keep the output close to uniform.
|
||||
template <typename T>
|
||||
T Rand() {
|
||||
static_assert(std::numeric_limits<T>::is_integer &&
|
||||
std::numeric_limits<T>::radix == 2 &&
|
||||
std::numeric_limits<T>::digits <= 32,
|
||||
"Rand is only supported for built-in integer types that are "
|
||||
"32 bits or smaller.");
|
||||
return static_cast<T>(NextOutput());
|
||||
}
|
||||
|
||||
// Uniformly distributed pseudo-random number in the interval [0, t].
|
||||
uint32_t Rand(uint32_t t);
|
||||
|
||||
// Uniformly distributed pseudo-random number in the interval [low, high].
|
||||
uint32_t Rand(uint32_t low, uint32_t high);
|
||||
|
||||
// Uniformly distributed pseudo-random number in the interval [low, high].
|
||||
int32_t Rand(int32_t low, int32_t high);
|
||||
|
||||
// Normal Distribution.
|
||||
double Gaussian(double mean, double standard_deviation);
|
||||
|
||||
// Exponential Distribution.
|
||||
double Exponential(double lambda);
|
||||
|
||||
private:
|
||||
// Outputs a nonzero 64-bit random number.
|
||||
uint64_t NextOutput() {
|
||||
state_ ^= state_ >> 12;
|
||||
state_ ^= state_ << 25;
|
||||
state_ ^= state_ >> 27;
|
||||
RTC_DCHECK(state_ != 0x0ULL);
|
||||
return state_ * 2685821657736338717ull;
|
||||
}
|
||||
|
||||
uint64_t state_;
|
||||
|
||||
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(Random);
|
||||
};
|
||||
|
||||
// Return pseudo-random number in the interval [0.0, 1.0).
|
||||
template <>
|
||||
float Random::Rand<float>();
|
||||
|
||||
// Return pseudo-random number in the interval [0.0, 1.0).
|
||||
template <>
|
||||
double Random::Rand<double>();
|
||||
|
||||
// Return pseudo-random boolean value.
|
||||
template <>
|
||||
bool Random::Rand<bool>();
|
||||
|
||||
} // namespace webrtc
|
||||
// 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/random.h"
|
||||
|
||||
#endif // WEBRTC_BASE_RANDOM_H_
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user