summaryrefslogtreecommitdiffstats
path: root/media/libcubeb/src/cubeb_utils.h
diff options
context:
space:
mode:
Diffstat (limited to 'media/libcubeb/src/cubeb_utils.h')
-rw-r--r--media/libcubeb/src/cubeb_utils.h148
1 files changed, 138 insertions, 10 deletions
diff --git a/media/libcubeb/src/cubeb_utils.h b/media/libcubeb/src/cubeb_utils.h
index d8e9928fe..df6751155 100644
--- a/media/libcubeb/src/cubeb_utils.h
+++ b/media/libcubeb/src/cubeb_utils.h
@@ -8,11 +8,16 @@
#if !defined(CUBEB_UTILS)
#define CUBEB_UTILS
+#include "cubeb/cubeb.h"
+
+#ifdef __cplusplus
+
#include <stdint.h>
#include <string.h>
#include <assert.h>
+#include <mutex>
#include <type_traits>
-#if defined(WIN32)
+#if defined(_WIN32)
#include "cubeb_utils_win.h"
#else
#include "cubeb_utils_unix.h"
@@ -23,6 +28,7 @@ template<typename T>
void PodCopy(T * destination, const T * source, size_t count)
{
static_assert(std::is_trivial<T>::value, "Requires trivial type");
+ assert(destination && source);
memcpy(destination, source, count * sizeof(T));
}
@@ -31,6 +37,7 @@ template<typename T>
void PodMove(T * destination, const T * source, size_t count)
{
static_assert(std::is_trivial<T>::value, "Requires trivial type");
+ assert(destination && source);
memmove(destination, source, count * sizeof(T));
}
@@ -39,9 +46,67 @@ template<typename T>
void PodZero(T * destination, size_t count)
{
static_assert(std::is_trivial<T>::value, "Requires trivial type");
+ assert(destination);
memset(destination, 0, count * sizeof(T));
}
+namespace {
+template<typename T, typename Trait>
+void Copy(T * destination, const T * source, size_t count, Trait)
+{
+ for (size_t i = 0; i < count; i++) {
+ destination[i] = source[i];
+ }
+}
+
+template<typename T>
+void Copy(T * destination, const T * source, size_t count, std::true_type)
+{
+ PodCopy(destination, source, count);
+}
+}
+
+/**
+ * This allows copying a number of elements from a `source` pointer to a
+ * `destination` pointer, using `memcpy` if it is safe to do so, or a loop that
+ * calls the constructors and destructors otherwise.
+ */
+template<typename T>
+void Copy(T * destination, const T * source, size_t count)
+{
+ assert(destination && source);
+ Copy(destination, source, count, typename std::is_trivial<T>::type());
+}
+
+namespace {
+template<typename T, typename Trait>
+void ConstructDefault(T * destination, size_t count, Trait)
+{
+ for (size_t i = 0; i < count; i++) {
+ destination[i] = T();
+ }
+}
+
+template<typename T>
+void ConstructDefault(T * destination,
+ size_t count, std::true_type)
+{
+ PodZero(destination, count);
+}
+}
+
+/**
+ * This allows zeroing (using memset) or default-constructing a number of
+ * elements calling the constructors and destructors if necessary.
+ */
+template<typename T>
+void ConstructDefault(T * destination, size_t count)
+{
+ assert(destination);
+ ConstructDefault(destination, count,
+ typename std::is_arithmetic<T>::type());
+}
+
template<typename T>
class auto_array
{
@@ -63,6 +128,11 @@ public:
return data_;
}
+ T * end() const
+ {
+ return data_ + length_;
+ }
+
const T& at(size_t index) const
{
assert(index < length_ && "out of range");
@@ -198,18 +268,76 @@ private:
size_t length_;
};
-struct auto_lock {
- explicit auto_lock(owned_critical_section & lock)
- : lock(lock)
- {
- lock.enter();
+struct auto_array_wrapper {
+ virtual void push(void * elements, size_t length) = 0;
+ virtual size_t length() = 0;
+ virtual void push_silence(size_t length) = 0;
+ virtual bool pop(size_t length) = 0;
+ virtual void * data() = 0;
+ virtual void * end() = 0;
+ virtual void clear() = 0;
+ virtual bool reserve(size_t capacity) = 0;
+ virtual void set_length(size_t length) = 0;
+ virtual ~auto_array_wrapper() {}
+};
+
+template <typename T>
+struct auto_array_wrapper_impl : public auto_array_wrapper {
+ auto_array_wrapper_impl() {}
+
+ explicit auto_array_wrapper_impl(uint32_t size)
+ : ar(size)
+ {}
+
+ void push(void * elements, size_t length) override {
+ ar.push(static_cast<T *>(elements), length);
}
- ~auto_lock()
- {
- lock.leave();
+
+ size_t length() override {
+ return ar.length();
+ }
+
+ void push_silence(size_t length) override {
+ ar.push_silence(length);
+ }
+
+ bool pop(size_t length) override {
+ return ar.pop(nullptr, length);
+ }
+
+ void * data() override {
+ return ar.data();
+ }
+
+ void * end() override {
+ return ar.end();
+ }
+
+ void clear() override {
+ ar.clear();
+ }
+
+ bool reserve(size_t capacity) override {
+ return ar.reserve(capacity);
}
+
+ void set_length(size_t length) override {
+ ar.set_length(length);
+ }
+
+ ~auto_array_wrapper_impl() {
+ ar.clear();
+ }
+
private:
- owned_critical_section & lock;
+ auto_array<T> ar;
};
+extern "C" {
+ size_t cubeb_sample_size(cubeb_sample_format format);
+}
+
+using auto_lock = std::lock_guard<owned_critical_section>;
+#endif // __cplusplus
+
#endif /* CUBEB_UTILS */