Bug 1329568 - Simple IsMediaMIMEType checker for strings - r=jya
☠☠ backed out by 4caa61eee820 ☠ ☠
authorGerald Squelart <gsquelart@mozilla.com>
Sun, 01 Jan 2017 08:46:34 +1100
changeset 374174 99758b5f7918a50d35bdecbe339371072df325ad
parent 374173 2ce9dcf0c27412fbb5cff17f9f6e13fe36d4bdda
child 374175 7c62078beb88dce045784041fe78b1265c1545dc
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjya
bugs1329568
milestone53.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1329568 - Simple IsMediaMIMEType checker for strings - r=jya Inside dom/media, we really only deal with audio and video MIME types. IsMediaMIMEType will help check for that. Note that 'application' is an acceptable MIME major type, as some A/V contents do use it! E.g.: "application/ogg". IsMediaMIMEType is constexpr to allow its use in static_assert's, so we will be able to verify string literals at compile time. MozReview-Commit-ID: InBicRRUeiP
dom/media/VideoUtils.h
--- a/dom/media/VideoUtils.h
+++ b/dom/media/VideoUtils.h
@@ -357,16 +357,86 @@ CreateTrackInfoWithMIMEType(const nsACSt
 
 // Try and create a TrackInfo with a given codec MIME type, and optional extra
 // parameters from a content type (its MIME type and codecs are ignored).
 UniquePtr<TrackInfo>
 CreateTrackInfoWithMIMETypeAndContentTypeExtraParameters(
   const nsACString& aCodecMIMEType,
   const MediaContentType& aContentType);
 
+namespace detail {
+
+// aString should start with aMajor + '/'.
+constexpr bool
+StartsWithMIMETypeMajor(const char* aString,
+                        const char* aMajor, size_t aMajorRemaining)
+{
+  return (aMajorRemaining == 0 && *aString == '/')
+         || (*aString == *aMajor
+             && StartsWithMIMETypeMajor(aString + 1,
+                                        aMajor + 1, aMajorRemaining - 1));
+}
+
+// aString should only contain [a-z0-9\-\.] and a final '\0'.
+constexpr bool
+EndsWithMIMESubtype(const char* aString, size_t aRemaining)
+{
+  return aRemaining == 0
+         || (((*aString >= 'a' && *aString <= 'z')
+              || (*aString >= '0' && *aString <= '9')
+              || *aString == '-'
+              || *aString == '.')
+             && EndsWithMIMESubtype(aString + 1, aRemaining - 1));
+}
+
+// Simple MIME-type literal string checker with a given (major) type.
+// Only accepts "{aMajor}/[a-z0-9\-\.]+".
+template <size_t MajorLengthPlus1>
+constexpr bool
+IsMIMETypeWithMajor(const char* aString, size_t aLength,
+                    const char (&aMajor)[MajorLengthPlus1])
+{
+  return aLength > MajorLengthPlus1 // Major + '/' + at least 1 char
+         && StartsWithMIMETypeMajor(aString, aMajor, MajorLengthPlus1 - 1)
+         && EndsWithMIMESubtype(aString + MajorLengthPlus1,
+                                aLength - MajorLengthPlus1);
+}
+
+} // namespace detail
+
+// Simple MIME-type string checker.
+// Only accepts lowercase "{application,audio,video}/[a-z0-9\-\.]+".
+// Add more if necessary.
+constexpr bool
+IsMediaMIMEType(const char* aString, size_t aLength)
+{
+  return detail::IsMIMETypeWithMajor(aString, aLength, "application")
+         || detail::IsMIMETypeWithMajor(aString, aLength, "audio")
+         || detail::IsMIMETypeWithMajor(aString, aLength, "video");
+}
+
+// Simple MIME-type string literal checker.
+// Only accepts lowercase "{application,audio,video}/[a-z0-9\-\.]+".
+// Add more if necessary.
+template <size_t LengthPlus1>
+constexpr bool
+IsMediaMIMEType(const char (&aString)[LengthPlus1])
+{
+  return IsMediaMIMEType(aString, LengthPlus1 - 1);
+}
+
+// Simple MIME-type string checker.
+// Only accepts lowercase "{application,audio,video}/[a-z0-9\-\.]+".
+// Add more if necessary.
+inline bool
+IsMediaMIMEType(const nsACString& aString)
+{
+  return IsMediaMIMEType(aString.Data(), aString.Length());
+}
+
 enum class StringListRangeEmptyItems
 {
   // Skip all empty items (empty string will process nothing)
   // E.g.: "a,,b" -> ["a", "b"], "" -> nothing
   Skip,
   // Process all, except if string is empty
   // E.g.: "a,,b" -> ["a", "", "b"], "" -> nothing
   ProcessEmptyItems,