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
--- 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,