--- a/dom/media/DecoderDoctorDiagnostics.cpp
+++ b/dom/media/DecoderDoctorDiagnostics.cpp
@@ -12,16 +12,17 @@
#include "nsContentUtils.h"
#include "nsGkAtoms.h"
#include "nsIDocument.h"
#include "nsIObserverService.h"
#include "nsIScriptError.h"
#include "nsITimer.h"
#include "nsIWeakReference.h"
#include "nsPluginHost.h"
+#include "VideoUtils.h"
static mozilla::LazyLogModule sDecoderDoctorLog("DecoderDoctor");
#define DD_LOG(level, arg, ...) MOZ_LOG(sDecoderDoctorLog, level, (arg, ##__VA_ARGS__))
#define DD_DEBUG(arg, ...) DD_LOG(mozilla::LogLevel::Debug, arg, ##__VA_ARGS__)
#define DD_INFO(arg, ...) DD_LOG(mozilla::LogLevel::Info, arg, ##__VA_ARGS__)
#define DD_WARN(arg, ...) DD_LOG(mozilla::LogLevel::Warning, arg, ##__VA_ARGS__)
namespace mozilla {
@@ -237,129 +238,16 @@ DecoderDoctorDocumentWatcher::EnsureTime
if (NS_WARN_IF(NS_FAILED(
mTimer->InitWithCallback(
this, sAnalysisPeriod_ms, nsITimer::TYPE_ONE_SHOT)))) {
mTimer = nullptr;
}
}
}
-template <typename String>
-class StringListRange
-{
- typedef typename String::char_type CharType;
- typedef const CharType* Pointer;
-
-public:
- // Iterator into range, trims items and skips empty items.
- class Iterator
- {
- public:
- bool operator!=(const Iterator& a) const
- {
- return mStart != a.mStart || mEnd != a.mEnd;
- }
- Iterator& operator++()
- {
- SearchItemAt(mComma + 1);
- return *this;
- }
- typedef decltype(Substring(Pointer(), Pointer())) DereferencedType;
- DereferencedType operator*()
- {
- return Substring(mStart, mEnd);
- }
- private:
- friend class StringListRange;
- Iterator(const CharType* aRangeStart, uint32_t aLength)
- : mRangeEnd(aRangeStart + aLength)
- {
- SearchItemAt(aRangeStart);
- }
- void SearchItemAt(Pointer start)
- {
- // First, skip leading whitespace.
- for (Pointer p = start; ; ++p) {
- if (p >= mRangeEnd) {
- mStart = mEnd = mComma = mRangeEnd;
- return;
- }
- auto c = *p;
- if (c == CharType(',')) {
- // Comma -> Empty item -> Skip.
- } else if (c != CharType(' ')) {
- mStart = p;
- break;
- }
- }
- // Find comma, recording start of trailing space.
- Pointer trailingWhitespace = nullptr;
- for (Pointer p = mStart + 1; ; ++p) {
- if (p >= mRangeEnd) {
- mEnd = trailingWhitespace ? trailingWhitespace : p;
- mComma = p;
- return;
- }
- auto c = *p;
- if (c == CharType(',')) {
- mEnd = trailingWhitespace ? trailingWhitespace : p;
- mComma = p;
- return;
- }
- if (c == CharType(' ')) {
- // Found a whitespace -> Record as trailing if not first one.
- if (!trailingWhitespace) {
- trailingWhitespace = p;
- }
- } else {
- // Found a non-whitespace -> Reset trailing whitespace if needed.
- if (trailingWhitespace) {
- trailingWhitespace = nullptr;
- }
- }
- }
- }
- const Pointer mRangeEnd;
- Pointer mStart;
- Pointer mEnd;
- Pointer mComma;
- };
-
- explicit StringListRange(const String& aList) : mList(aList) {}
- Iterator begin()
- {
- return Iterator(mList.Data(), mList.Length());
- }
- Iterator end()
- {
- return Iterator(mList.Data() + mList.Length(), 0);
- }
-private:
- const String& mList;
-};
-
-template <typename String>
-StringListRange<String>
-MakeStringListRange(const String& aList)
-{
- return StringListRange<String>(aList);
-}
-
-template <typename ListString, typename ItemString>
-static bool
-StringListContains(const ListString& aList, const ItemString& aItem)
-{
- for (const auto& listItem : MakeStringListRange(aList)) {
- if (listItem.Equals(aItem)) {
- return true;
- }
- }
- return false;
-}
-
static const NotificationAndReportStringId sMediaWidevineNoWMFNoSilverlight =
{ dom::DecoderDoctorNotificationType::Platform_decoder_not_found,
"MediaWidevineNoWMFNoSilverlight" };
static const NotificationAndReportStringId sMediaWMFNeeded =
{ dom::DecoderDoctorNotificationType::Platform_decoder_not_found,
"MediaWMFNeeded" };
static const NotificationAndReportStringId sMediaPlatformDecoderNotFound =
{ dom::DecoderDoctorNotificationType::Platform_decoder_not_found,
new file mode 100644
--- /dev/null
+++ b/dom/media/gtest/TestVideoUtils.cpp
@@ -0,0 +1,80 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "gtest/gtest.h"
+#include "nsString.h"
+#include "VideoUtils.h"
+
+using namespace mozilla;
+
+TEST(StringListRange, MakeStringListRange)
+{
+ static const struct
+ {
+ const char* mList;
+ const char* mExpected;
+ } tests[] =
+ {
+ { "", "" },
+ { " ", "" },
+ { ",", "" },
+ { " , ", "" },
+ { "a", "a|" },
+ { " a ", "a|" },
+ { "aa,bb", "aa|bb|" },
+ { " a a , b b ", "a a|b b|" },
+ { " , ,a 1,, ,b 2,", "a 1|b 2|" }
+ };
+
+ for (const auto& test : tests) {
+ nsCString list(test.mList);
+ nsCString out;
+ for (const auto& item : MakeStringListRange(list)) {
+ out += item;
+ out += "|";
+ }
+ EXPECT_STREQ(test.mExpected, out.Data());
+ }
+}
+
+TEST(StringListRange, StringListContains)
+{
+ static const struct
+ {
+ const char* mList;
+ const char* mItemToSearch;
+ bool mExpected;
+ } tests[] =
+ {
+ { "", "", false },
+ { "", "a", false },
+ { " ", "a", false },
+ { ",", "a", false },
+ { " , ", "", false },
+ { " , ", "a", false },
+ { "a", "a", true },
+ { "a", "b", false },
+ { " a ", "a", true },
+ { "aa,bb", "aa", true },
+ { "aa,bb", "bb", true },
+ { "aa,bb", "cc", false },
+ { "aa,bb", " aa ", false },
+ { " a a , b b ", "a a", true },
+ { " , ,a 1,, ,b 2,", "a 1", true },
+ { " , ,a 1,, ,b 2,", "b 2", true },
+ { " , ,a 1,, ,b 2,", "", false },
+ { " , ,a 1,, ,b 2,", " ", false },
+ { " , ,a 1,, ,b 2,", "A 1", false },
+ { " , ,A 1,, ,b 2,", "a 1", false }
+ };
+
+ for (const auto& test : tests) {
+ nsCString list(test.mList);
+ nsCString itemToSearch(test.mItemToSearch);
+ EXPECT_EQ(test.mExpected, StringListContains(list, itemToSearch))
+ << "trying to find \"" << itemToSearch.Data()
+ << "\" in \"" << list.Data() << "\"";
+ }
+}