Log Message
Extend SortedArrayMap further to work on case-folded strings, use in MIMETypeRegistry https://bugs.webkit.org/show_bug.cgi?id=224968
Reviewed by Sam Weinig. Source/WebCore: Using fewer HashSet in MIMETypeRegistry saves code size and reduces memory use. * platform/MIMETypeRegistry.cpp: (WebCore::MIMETypeRegistry::supportedImageMIMETypes): Deleted. Replaced this function with a constexpr array, eliminating the use of HashSet. (WebCore::makeFixedVector): Added. Helper function used below for the repeated patttern of converting a constexpr array into a FixedVector<const char*>. (WebCore::supportedJavaScriptMIMETypes): Deleted. (WebCore::MIMETypeRegistry::supportedNonImageMIMETypes): Update since supportedJavaScriptMIMETypeArray is now an array, not a HashSet. (WebCore::MIMETypeRegistry::pdfMIMETypes): Rewrote to return a FixedVector<const char*> instead of a HashSet. The only caller makes an NSArray<NSString *>, so there is no need to involve a hash table or a WTF::String. (WebCore::MIMETypeRegistry::unsupportedTextMIMETypes): Ditto. (WebCore::commonMediaTypes): Deleted, merging into the function below. (WebCore::commonMimeTypesMap): Moved the commonMediaTypes data in here and use a constexpr array instead of an initializer_list. (WebCore::MIMETypeRegistry::isSupportedImageMIMEType): Use SortedArraySet instead of a HashSet for the core supported images types. Moved the code that checks this against defaultSupportedImageTypes here. (WebCore::MIMETypeRegistry::isSupportedJavaScriptMIMEType): Use SortedArraySet. (WebCore::MIMETypeRegistry::isUnsupportedTextMIMEType): Ditto. (WebCore::MIMETypeRegistry::isPDFMIMEType): Ditto. (WebCore::MIMETypeRegistry::isPostScriptMIMEType): Use equalLettersIgnoringASCIICase. For some reason this was the single case-sensitive function in this whole class! (WebCore::MIMETypeRegistry::isSystemPreviewMIMEType): Use SortedArraySet. (WebCore::MIMETypeRegistry::systemPreviewMIMETypes): Return a FixedVector. (WebCore::normalizedImageMIMEType): Renamed this from its old name, MIMETypeRegistry::normalizedMIMEType, to better reflect that it's only used in one place. Also added comments to clarify that it's CURL-only and suggest it be removed eventually. * platform/MIMETypeRegistry.h: Changed supportedImageMIMETypes, pdfMIMETypes, unsupportedTextMIMETypes, and systemPreviewMIMETypes to return FixedVector instead of HashSet. Also removed normalizedMIMEType. * svg/SVGTransformValue.h: Removed unneeded include of HashMap.h. * testing/TypeConversions.h: Ditto. Source/WebKit: * UIProcess/API/ios/WKWebViewIOS.mm: (-[WKWebView _isDisplayingPDF]): Updated since MIMETypeRegistry::pdfMIMETypes returns a different type. * UIProcess/Cocoa/WKWebViewContentProviderRegistry.mm: (-[WKWebViewContentProviderRegistry initWithConfiguration:]): Updated since MIMETypeRegistry::systemPreviewMIMETypes returns a different type. Source/WebKitLegacy/mac: * WebView/WebHTMLRepresentation.mm: (createNSArray): Renamed from newArrayWithStrings so this overloads the createNSArray function from VectorCocoa.h so we can use the two interchangably and handle both FixedVector and HashSet with the smae code. (+[WebHTMLRepresentation supportedMediaMIMETypes]): Updated for name change. (+[WebHTMLRepresentation supportedNonImageMIMETypes]): Ditto. (+[WebHTMLRepresentation supportedImageMIMETypes]): Ditto. (+[WebHTMLRepresentation unsupportedTextMIMETypes]): Ditto. Source/WTF: * wtf/ASCIICType.h: Make most functions constexpr. * wtf/Forward.h: Added FixedVector. * wtf/SortedArrayMap.h: Added SortedArraySet. Added ComparableCaseFoldingASCIILiteral and ComparableLettersLiteral, using a template shared with ComparableASCIILiteral. * wtf/StdLibExtras.h: Added isSortedConstExpr and allOfConstExpr. Tools: * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: Added SortedArrayMap.cpp, and removed references to non-existent FullscreenRemoveNodeBeforeEnter.h and FloatQuadTests.h. * TestWebKitAPI/Tests/WTF/SortedArrayMap.cpp: Added.
Modified Paths
- trunk/Source/WTF/ChangeLog
- trunk/Source/WTF/wtf/ASCIICType.h
- trunk/Source/WTF/wtf/Forward.h
- trunk/Source/WTF/wtf/SortedArrayMap.h
- trunk/Source/WTF/wtf/StdLibExtras.h
- trunk/Source/WebCore/ChangeLog
- trunk/Source/WebCore/platform/MIMETypeRegistry.cpp
- trunk/Source/WebCore/platform/MIMETypeRegistry.h
- trunk/Source/WebCore/svg/SVGTransformValue.h
- trunk/Source/WebCore/testing/TypeConversions.h
- trunk/Source/WebKit/ChangeLog
- trunk/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm
- trunk/Source/WebKit/UIProcess/Cocoa/WKWebViewContentProviderRegistry.mm
- trunk/Source/WebKitLegacy/mac/ChangeLog
- trunk/Source/WebKitLegacy/mac/WebView/WebHTMLRepresentation.mm
- trunk/Tools/ChangeLog
- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Added Paths
Diff
Modified: trunk/Source/WTF/ChangeLog (276779 => 276780)
--- trunk/Source/WTF/ChangeLog 2021-04-29 16:26:38 UTC (rev 276779)
+++ trunk/Source/WTF/ChangeLog 2021-04-29 16:39:55 UTC (rev 276780)
@@ -1,3 +1,19 @@
+2021-04-29 Darin Adler <[email protected]>
+
+ Extend SortedArrayMap further to work on case-folded strings, use in MIMETypeRegistry
+ https://bugs.webkit.org/show_bug.cgi?id=224968
+
+ Reviewed by Sam Weinig.
+
+ * wtf/ASCIICType.h: Make most functions constexpr.
+
+ * wtf/Forward.h: Added FixedVector.
+
+ * wtf/SortedArrayMap.h: Added SortedArraySet. Added ComparableCaseFoldingASCIILiteral
+ and ComparableLettersLiteral, using a template shared with ComparableASCIILiteral.
+
+ * wtf/StdLibExtras.h: Added isSortedConstExpr and allOfConstExpr.
+
2021-04-29 Ben Nham <[email protected]>
Unreviewed, reverting r276619.
Modified: trunk/Source/WTF/wtf/ASCIICType.h (276779 => 276780)
--- trunk/Source/WTF/wtf/ASCIICType.h 2021-04-29 16:26:38 UTC (rev 276779)
+++ trunk/Source/WTF/wtf/ASCIICType.h 2021-04-29 16:39:55 UTC (rev 276780)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007-2019 Apple Inc. All rights reserved.
+ * Copyright (C) 2007-2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -40,16 +40,17 @@
namespace WTF {
template<typename CharacterType> constexpr bool isASCII(CharacterType);
-template<typename CharacterType> bool isASCIIAlpha(CharacterType);
-template<typename CharacterType> bool isASCIIAlphanumeric(CharacterType);
-template<typename CharacterType> bool isASCIIBinaryDigit(CharacterType);
-template<typename CharacterType> bool isASCIIDigit(CharacterType);
-template<typename CharacterType> bool isASCIIHexDigit(CharacterType);
-template<typename CharacterType> bool isASCIILower(CharacterType);
-template<typename CharacterType> bool isASCIIOctalDigit(CharacterType);
-template<typename CharacterType> bool isASCIIPrintable(CharacterType);
-template<typename CharacterType> bool isASCIISpace(CharacterType);
-template<typename CharacterType> bool isASCIIUpper(CharacterType);
+template<typename CharacterType> constexpr bool isASCIIAlpha(CharacterType);
+template<typename CharacterType> constexpr bool isASCIIAlphanumeric(CharacterType);
+template<typename CharacterType> constexpr bool isASCIIBinaryDigit(CharacterType);
+template<typename CharacterType> constexpr bool isASCIIDigit(CharacterType);
+template<typename CharacterType> constexpr bool isASCIIDigitOrPunctuation(CharacterType);
+template<typename CharacterType> constexpr bool isASCIIHexDigit(CharacterType);
+template<typename CharacterType> constexpr bool isASCIILower(CharacterType);
+template<typename CharacterType> constexpr bool isASCIIOctalDigit(CharacterType);
+template<typename CharacterType> constexpr bool isASCIIPrintable(CharacterType);
+template<typename CharacterType> constexpr bool isASCIISpace(CharacterType);
+template<typename CharacterType> constexpr bool isASCIIUpper(CharacterType);
template<typename CharacterType> CharacterType toASCIILower(CharacterType);
template<typename CharacterType> CharacterType toASCIIUpper(CharacterType);
@@ -57,18 +58,18 @@
template<typename CharacterType> uint8_t toASCIIHexValue(CharacterType);
template<typename CharacterType> uint8_t toASCIIHexValue(CharacterType firstCharacter, CharacterType secondCharacter);
-char lowerNibbleToASCIIHexDigit(uint8_t);
-char upperNibbleToASCIIHexDigit(uint8_t);
-char lowerNibbleToLowercaseASCIIHexDigit(uint8_t);
-char upperNibbleToLowercaseASCIIHexDigit(uint8_t);
+constexpr char lowerNibbleToASCIIHexDigit(uint8_t);
+constexpr char upperNibbleToASCIIHexDigit(uint8_t);
+constexpr char lowerNibbleToLowercaseASCIIHexDigit(uint8_t);
+constexpr char upperNibbleToLowercaseASCIIHexDigit(uint8_t);
-template<typename CharacterType> bool isASCIIAlphaCaselessEqual(CharacterType, char expectedASCIILowercaseLetter);
+template<typename CharacterType> constexpr bool isASCIIAlphaCaselessEqual(CharacterType, char expectedASCIILowercaseLetter);
// The toASCIILowerUnchecked function can be used for comparing any input character
// to a lowercase English character. The isASCIIAlphaCaselessEqual function should
// be used for regular comparison of ASCII alpha characters, but switch statements
// in the CSS tokenizer, for example, instead make direct use toASCIILowerUnchecked.
-template<typename CharacterType> CharacterType toASCIILowerUnchecked(CharacterType);
+template<typename CharacterType> constexpr CharacterType toASCIILowerUnchecked(CharacterType);
extern WTF_EXPORT_PRIVATE const unsigned char asciiCaseFoldTable[256];
@@ -77,12 +78,12 @@
return !(character & ~0x7F);
}
-template<typename CharacterType> inline bool isASCIILower(CharacterType character)
+template<typename CharacterType> constexpr bool isASCIILower(CharacterType character)
{
return character >= 'a' && character <= 'z';
}
-template<typename CharacterType> inline CharacterType toASCIILowerUnchecked(CharacterType character)
+template<typename CharacterType> constexpr CharacterType toASCIILowerUnchecked(CharacterType character)
{
// This function can be used for comparing any input character
// to a lowercase English character. The isASCIIAlphaCaselessEqual
@@ -92,37 +93,37 @@
return character | 0x20;
}
-template<typename CharacterType> inline bool isASCIIAlpha(CharacterType character)
+template<typename CharacterType> constexpr bool isASCIIAlpha(CharacterType character)
{
return isASCIILower(toASCIILowerUnchecked(character));
}
-template<typename CharacterType> inline bool isASCIIDigit(CharacterType character)
+template<typename CharacterType> constexpr bool isASCIIDigit(CharacterType character)
{
return character >= '0' && character <= '9';
}
-template<typename CharacterType> inline bool isASCIIAlphanumeric(CharacterType character)
+template<typename CharacterType> constexpr bool isASCIIAlphanumeric(CharacterType character)
{
return isASCIIDigit(character) || isASCIIAlpha(character);
}
-template<typename CharacterType> inline bool isASCIIHexDigit(CharacterType character)
+template<typename CharacterType> constexpr bool isASCIIHexDigit(CharacterType character)
{
return isASCIIDigit(character) || (toASCIILowerUnchecked(character) >= 'a' && toASCIILowerUnchecked(character) <= 'f');
}
-template<typename CharacterType> inline bool isASCIIBinaryDigit(CharacterType character)
+template<typename CharacterType> constexpr bool isASCIIBinaryDigit(CharacterType character)
{
return character == '0' || character == '1';
}
-template<typename CharacterType> inline bool isASCIIOctalDigit(CharacterType character)
+template<typename CharacterType> constexpr bool isASCIIOctalDigit(CharacterType character)
{
return character >= '0' && character <= '7';
}
-template<typename CharacterType> inline bool isASCIIPrintable(CharacterType character)
+template<typename CharacterType> constexpr bool isASCIIPrintable(CharacterType character)
{
return character >= ' ' && character <= '~';
}
@@ -143,12 +144,12 @@
Because of those, we first check to quickly return false for non-control characters,
then check for space itself to quickly return true for that case, then do the rest.
*/
-template<typename CharacterType> inline bool isASCIISpace(CharacterType character)
+template<typename CharacterType> constexpr bool isASCIISpace(CharacterType character)
{
return character <= ' ' && (character == ' ' || (character <= 0xD && character >= 0x9));
}
-template<typename CharacterType> inline bool isASCIIUpper(CharacterType character)
+template<typename CharacterType> constexpr bool isASCIIUpper(CharacterType character)
{
return character >= 'A' && character <= 'Z';
}
@@ -184,31 +185,31 @@
return toASCIIHexValue(firstCharacter) << 4 | toASCIIHexValue(secondCharacter);
}
-inline char lowerNibbleToASCIIHexDigit(uint8_t value)
+constexpr char lowerNibbleToASCIIHexDigit(uint8_t value)
{
uint8_t nibble = value & 0xF;
return nibble + (nibble < 10 ? '0' : 'A' - 10);
}
-inline char upperNibbleToASCIIHexDigit(uint8_t value)
+constexpr char upperNibbleToASCIIHexDigit(uint8_t value)
{
uint8_t nibble = value >> 4;
return nibble + (nibble < 10 ? '0' : 'A' - 10);
}
-inline char lowerNibbleToLowercaseASCIIHexDigit(uint8_t value)
+constexpr char lowerNibbleToLowercaseASCIIHexDigit(uint8_t value)
{
uint8_t nibble = value & 0xF;
return nibble + (nibble < 10 ? '0' : 'a' - 10);
}
-inline char upperNibbleToLowercaseASCIIHexDigit(uint8_t value)
+constexpr char upperNibbleToLowercaseASCIIHexDigit(uint8_t value)
{
uint8_t nibble = value >> 4;
return nibble + (nibble < 10 ? '0' : 'a' - 10);
}
-template<typename CharacterType> inline bool isASCIIAlphaCaselessEqual(CharacterType inputCharacter, char expectedASCIILowercaseLetter)
+template<typename CharacterType> constexpr bool isASCIIAlphaCaselessEqual(CharacterType inputCharacter, char expectedASCIILowercaseLetter)
{
// Name of this argument says this must be a lowercase letter, but it can actually be:
// - a lowercase letter
@@ -225,9 +226,9 @@
return LIKELY(toASCIILowerUnchecked(inputCharacter) == expectedASCIILowercaseLetter);
}
-template<typename CharacterType> inline bool isASCIIDigitOrPunctuation(CharacterType charCode)
+template<typename CharacterType> constexpr bool isASCIIDigitOrPunctuation(CharacterType character)
{
- return (charCode >= '!' && charCode <= '@') || (charCode >= '[' && charCode <= '`') || (charCode >= '{' && charCode <= '~');
+ return (character >= '!' && character <= '@') || (character >= '[' && character <= '`') || (character >= '{' && character <= '~');
}
}
Modified: trunk/Source/WTF/wtf/Forward.h (276779 => 276780)
--- trunk/Source/WTF/wtf/Forward.h 2021-04-29 16:26:38 UTC (rev 276779)
+++ trunk/Source/WTF/wtf/Forward.h 2021-04-29 16:39:55 UTC (rev 276780)
@@ -62,6 +62,7 @@
template<typename> struct DefaultRefDerefTraits;
template<typename> class CompletionHandler;
+template<typename> class FixedVector;
template<typename> class Function;
template<typename, typename = AnyThreadsAccessTraits> class LazyNeverDestroyed;
template<typename, typename = AnyThreadsAccessTraits> class NeverDestroyed;
@@ -118,6 +119,7 @@
using WTF::BinarySemaphore;
using WTF::CString;
using WTF::CompletionHandler;
+using WTF::FixedVector;
using WTF::Function;
using WTF::FunctionDispatcher;
using WTF::HashCountedSet;
Modified: trunk/Source/WTF/wtf/SortedArrayMap.h (276779 => 276780)
--- trunk/Source/WTF/wtf/SortedArrayMap.h 2021-04-29 16:26:38 UTC (rev 276779)
+++ trunk/Source/WTF/wtf/SortedArrayMap.h 2021-04-29 16:39:55 UTC (rev 276780)
@@ -52,39 +52,69 @@
const ArrayType& m_array;
};
+template<typename ArrayType> class SortedArraySet {
+public:
+ constexpr SortedArraySet(const ArrayType&);
+ template<typename KeyArgument> bool contains(const KeyArgument&) const;
+
+private:
+ const ArrayType& m_array;
+};
+
struct ComparableStringView {
StringView string;
};
-struct ComparableASCIILiteral {
- const char* literal;
- template<std::size_t size> constexpr ComparableASCIILiteral(const char (&characters)[size]) : literal { characters } { }
+// NoUppercaseLettersOptimized means no characters with the 0x20 bit set.
+// That means the strings can't include control characters, uppercase letters, or any of @[\]_.
+enum class ASCIISubset { All, NoUppercaseLetters, NoUppercaseLettersOptimized };
+
+template<ASCIISubset> struct ComparableASCIISubsetLiteral {
+ ASCIILiteral literal;
+ template<std::size_t size> constexpr ComparableASCIISubsetLiteral(const char (&characters)[size]);
static Optional<ComparableStringView> parse(StringView string) { return { { string } }; }
};
-constexpr bool operator==(ComparableASCIILiteral, ComparableASCIILiteral);
-constexpr bool operator<(ComparableASCIILiteral, ComparableASCIILiteral);
+using ComparableASCIILiteral = ComparableASCIISubsetLiteral<ASCIISubset::All>;
+using ComparableCaseFoldingASCIILiteral = ComparableASCIISubsetLiteral<ASCIISubset::NoUppercaseLetters>;
+using ComparableLettersLiteral = ComparableASCIISubsetLiteral<ASCIISubset::NoUppercaseLettersOptimized>;
+template<ASCIISubset subset> constexpr bool operator==(ComparableASCIISubsetLiteral<subset>, ComparableASCIISubsetLiteral<subset>);
+template<ASCIISubset subset> constexpr bool operator<(ComparableASCIISubsetLiteral<subset>, ComparableASCIISubsetLiteral<subset>);
+
bool operator==(ComparableStringView, ComparableASCIILiteral);
+bool operator==(ComparableStringView, ComparableCaseFoldingASCIILiteral);
+bool operator==(ComparableStringView, ComparableLettersLiteral);
bool operator<(ComparableStringView, ComparableASCIILiteral);
-bool operator!=(ComparableStringView, ComparableASCIILiteral);
-bool operator==(ComparableASCIILiteral, ComparableStringView);
+bool operator<(ComparableStringView, ComparableCaseFoldingASCIILiteral);
+bool operator<(ComparableStringView, ComparableLettersLiteral);
-// FIXME: Use std::is_sorted instead of this and remove it, once we require C++20.
-template<typename Iterator, typename Predicate> constexpr bool isSortedConstExpr(Iterator begin, Iterator end, Predicate predicate)
+template<typename OtherType> bool operator==(OtherType, ComparableStringView);
+template<typename OtherType> bool operator!=(ComparableStringView, OtherType);
+
+template<ASCIISubset subset> constexpr bool isInSubset(char character)
{
- if (begin == end)
+ if (!(character && isASCII(character)))
+ return false;
+ switch (subset) {
+ case ASCIISubset::All:
return true;
- auto current = begin;
- auto previous = current;
- while (++current != end) {
- if (!predicate(*previous, *current))
- return false;
- previous = current;
+ case ASCIISubset::NoUppercaseLetters:
+ return !isASCIIUpper(character);
+ case ASCIISubset::NoUppercaseLettersOptimized:
+ return character == toASCIILowerUnchecked(character);
}
- return true;
}
+template<ASCIISubset subset> template<std::size_t size> constexpr ComparableASCIISubsetLiteral<subset>::ComparableASCIISubsetLiteral(const char (&characters)[size])
+ : literal { ASCIILiteral::fromLiteralUnsafe(characters) }
+{
+ ASSERT_UNDER_CONSTEXPR_CONTEXT(allOfConstExpr(&characters[0], &characters[size - 1], [] (char character) {
+ return isInSubset<subset>(character);
+ }));
+ ASSERT_UNDER_CONSTEXPR_CONTEXT(!characters[size - 1]);
+}
+
template<typename ArrayType> constexpr SortedArrayMap<ArrayType>::SortedArrayMap(const ArrayType& array)
: m_array { array }
{
@@ -112,6 +142,23 @@
return result ? *result : defaultValue;
}
+template<typename ArrayType> constexpr SortedArraySet<ArrayType>::SortedArraySet(const ArrayType& array)
+ : m_array { array }
+{
+ ASSERT_UNDER_CONSTEXPR_CONTEXT(isSortedConstExpr(std::begin(array), std::end(array)));
+}
+
+template<typename ArrayType> template<typename KeyArgument> inline bool SortedArraySet<ArrayType>::contains(const KeyArgument& key) const
+{
+ using ElementType = typename std::remove_extent_t<ArrayType>;
+ auto parsedKey = ElementType::parse(key);
+ // FIXME: We should enhance tryBinarySearch so it can deduce ElementType.
+ // FIXME: If the array's size is small enough, should do linear search since it is more efficient than binary search.
+ return parsedKey && tryBinarySearch<ElementType>(m_array, std::size(m_array), *parsedKey, [] (auto* element) {
+ return *element;
+ });
+}
+
constexpr int strcmpConstExpr(const char* a, const char* b)
{
while (*a == *b && *a && *b) {
@@ -121,16 +168,35 @@
return *a == *b ? 0 : *a < *b ? -1 : 1;
}
-constexpr bool operator==(ComparableASCIILiteral a, ComparableASCIILiteral b)
+template<typename CharacterType> inline bool lessThanASCIICaseFolding(const CharacterType* characters, unsigned length, const char* literalWithNoUppercase)
{
- return !strcmpConstExpr(a.literal, b.literal);
+ for (unsigned i = 0; i < length; ++i) {
+ if (!literalWithNoUppercase[i])
+ return false;
+ auto character = toASCIILower(characters[i]);
+ if (character != literalWithNoUppercase[i])
+ return character < literalWithNoUppercase[i];
+ }
+ return true;
}
-constexpr bool operator<(ComparableASCIILiteral a, ComparableASCIILiteral b)
+inline bool lessThanASCIICaseFolding(StringView string, const char* literalWithNoUppercase)
{
- return strcmpConstExpr(a.literal, b.literal) < 0;
+ if (string.is8Bit())
+ return lessThanASCIICaseFolding(string.characters8(), string.length(), literalWithNoUppercase);
+ return lessThanASCIICaseFolding(string.characters16(), string.length(), literalWithNoUppercase);
}
+template<ASCIISubset subset> constexpr bool operator==(ComparableASCIISubsetLiteral<subset> a, ComparableASCIISubsetLiteral<subset> b)
+{
+ return !strcmpConstExpr(a.literal.characters(), b.literal.characters());
+}
+
+template<ASCIISubset subset> constexpr bool operator<(ComparableASCIISubsetLiteral<subset> a, ComparableASCIISubsetLiteral<subset> b)
+{
+ return strcmpConstExpr(a.literal.characters(), b.literal.characters()) < 0;
+}
+
inline bool operator==(ComparableStringView a, ComparableASCIILiteral b)
{
return a.string == b.literal;
@@ -138,20 +204,45 @@
inline bool operator<(ComparableStringView a, ComparableASCIILiteral b)
{
- return codePointCompare(a.string, b.literal) < 0;
+ return codePointCompare(a.string, b.literal.characters()) < 0;
}
-inline bool operator!=(ComparableStringView a, ComparableASCIILiteral b)
+inline bool operator==(ComparableStringView a, ComparableLettersLiteral b)
{
- return !(a == b);
+ return equalLettersIgnoringASCIICaseCommonWithoutLength(a.string, b.literal);
}
-inline bool operator==(ComparableASCIILiteral a, ComparableStringView b)
+inline bool operator<(ComparableStringView a, ComparableLettersLiteral b)
{
+ return lessThanASCIICaseFolding(a.string, b.literal);
+}
+
+inline bool operator==(ComparableStringView a, ComparableCaseFoldingASCIILiteral b)
+{
+ return equalIgnoringASCIICase(a.string, b.literal);
+}
+
+inline bool operator<(ComparableStringView a, ComparableCaseFoldingASCIILiteral b)
+{
+ return lessThanASCIICaseFolding(a.string, b.literal);
+}
+
+template<typename OtherType> inline bool operator==(OtherType a, ComparableStringView b)
+{
return b == a;
}
+template<typename OtherType> inline bool operator!=(ComparableStringView a, OtherType b)
+{
+ return !(a == b);
}
+}
+
+using WTF::ASCIISubset;
using WTF::ComparableASCIILiteral;
+using WTF::ComparableASCIISubsetLiteral;
+using WTF::ComparableCaseFoldingASCIILiteral;
+using WTF::ComparableLettersLiteral;
using WTF::SortedArrayMap;
+using WTF::SortedArraySet;
Modified: trunk/Source/WTF/wtf/StdLibExtras.h (276779 => 276780)
--- trunk/Source/WTF/wtf/StdLibExtras.h 2021-04-29 16:26:38 UTC (rev 276779)
+++ trunk/Source/WTF/wtf/StdLibExtras.h 2021-04-29 16:39:55 UTC (rev 276780)
@@ -527,6 +527,37 @@
return constructFixedSizeArrayWithArgumentsImpl<ResultType>(tuple, std::forward<Args>(args)...);
}
+// FIXME: Use std::is_sorted instead of this and remove it, once we require C++20.
+template<typename Iterator, typename Predicate> constexpr bool isSortedConstExpr(Iterator first, Iterator last, Predicate predicate)
+{
+ if (first == last)
+ return true;
+ auto current = first;
+ auto previous = current;
+ while (++current != last) {
+ if (!predicate(*previous, *current))
+ return false;
+ previous = current;
+ }
+ return true;
+}
+
+// FIXME: Use std::is_sorted instead of this and remove it, once we require C++20.
+template<typename Iterator> constexpr bool isSortedConstExpr(Iterator first, Iterator last)
+{
+ return isSortedConstExpr(first, last, [] (auto& a, auto& b) { return a < b; });
+}
+
+// FIXME: Use std::all_of instead of this and remove it, once we require C++20.
+template<typename Iterator, typename Predicate> constexpr bool allOfConstExpr(Iterator first, Iterator last, Predicate predicate)
+{
+ for (; first != last; ++first) {
+ if (!predicate(*first))
+ return false;
+ }
+ return true;
+}
+
} // namespace WTF
#define WTFMove(value) std::move<WTF::CheckMoveParameter>(value)
Modified: trunk/Source/WebCore/ChangeLog (276779 => 276780)
--- trunk/Source/WebCore/ChangeLog 2021-04-29 16:26:38 UTC (rev 276779)
+++ trunk/Source/WebCore/ChangeLog 2021-04-29 16:39:55 UTC (rev 276780)
@@ -1,3 +1,49 @@
+2021-04-29 Darin Adler <[email protected]>
+
+ Extend SortedArrayMap further to work on case-folded strings, use in MIMETypeRegistry
+ https://bugs.webkit.org/show_bug.cgi?id=224968
+
+ Reviewed by Sam Weinig.
+
+ Using fewer HashSet in MIMETypeRegistry saves code size and reduces memory use.
+
+ * platform/MIMETypeRegistry.cpp:
+ (WebCore::MIMETypeRegistry::supportedImageMIMETypes): Deleted. Replaced
+ this function with a constexpr array, eliminating the use of HashSet.
+ (WebCore::makeFixedVector): Added. Helper function used below for the repeated patttern
+ of converting a constexpr array into a FixedVector<const char*>.
+ (WebCore::supportedJavaScriptMIMETypes): Deleted.
+ (WebCore::MIMETypeRegistry::supportedNonImageMIMETypes): Update since
+ supportedJavaScriptMIMETypeArray is now an array, not a HashSet.
+ (WebCore::MIMETypeRegistry::pdfMIMETypes): Rewrote to return a FixedVector<const char*>
+ instead of a HashSet. The only caller makes an NSArray<NSString *>, so there is no need
+ to involve a hash table or a WTF::String.
+ (WebCore::MIMETypeRegistry::unsupportedTextMIMETypes): Ditto.
+ (WebCore::commonMediaTypes): Deleted, merging into the function below.
+ (WebCore::commonMimeTypesMap): Moved the commonMediaTypes data in here
+ and use a constexpr array instead of an initializer_list.
+ (WebCore::MIMETypeRegistry::isSupportedImageMIMEType): Use SortedArraySet
+ instead of a HashSet for the core supported images types. Moved the code
+ that checks this against defaultSupportedImageTypes here.
+ (WebCore::MIMETypeRegistry::isSupportedJavaScriptMIMEType): Use SortedArraySet.
+ (WebCore::MIMETypeRegistry::isUnsupportedTextMIMEType): Ditto.
+ (WebCore::MIMETypeRegistry::isPDFMIMEType): Ditto.
+ (WebCore::MIMETypeRegistry::isPostScriptMIMEType): Use equalLettersIgnoringASCIICase.
+ For some reason this was the single case-sensitive function in this whole class!
+ (WebCore::MIMETypeRegistry::isSystemPreviewMIMEType): Use SortedArraySet.
+ (WebCore::MIMETypeRegistry::systemPreviewMIMETypes): Return a FixedVector.
+ (WebCore::normalizedImageMIMEType): Renamed this from its old name,
+ MIMETypeRegistry::normalizedMIMEType, to better reflect that it's only used in
+ one place. Also added comments to clarify that it's CURL-only and suggest it be
+ removed eventually.
+
+ * platform/MIMETypeRegistry.h: Changed supportedImageMIMETypes, pdfMIMETypes,
+ unsupportedTextMIMETypes, and systemPreviewMIMETypes to return FixedVector instead
+ of HashSet. Also removed normalizedMIMEType.
+
+ * svg/SVGTransformValue.h: Removed unneeded include of HashMap.h.
+ * testing/TypeConversions.h: Ditto.
+
2021-04-29 Sam Weinig <[email protected]>
Add support for CanvasRenderingContext2DSettings
Modified: trunk/Source/WebCore/platform/MIMETypeRegistry.cpp (276779 => 276780)
--- trunk/Source/WebCore/platform/MIMETypeRegistry.cpp 2021-04-29 16:26:38 UTC (rev 276779)
+++ trunk/Source/WebCore/platform/MIMETypeRegistry.cpp 2021-04-29 16:39:55 UTC (rev 276780)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006-2019 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2021 Apple Inc. All rights reserved.
* Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
*
* Redistribution and use in source and binary forms, with or without
@@ -29,10 +29,13 @@
#include "MediaPlayer.h"
#include "ThreadGlobalData.h"
+#include <wtf/FixedVector.h>
#include <wtf/HashMap.h>
#include <wtf/MainThread.h>
#include <wtf/NeverDestroyed.h>
+#include <wtf/SortedArrayMap.h>
#include <wtf/StdLibExtras.h>
+#include <wtf/Vector.h>
#if USE(CG)
#include "ImageSourceCG.h"
@@ -64,110 +67,101 @@
namespace WebCore {
-const HashSet<String, ASCIICaseInsensitiveHash>& MIMETypeRegistry::supportedImageMIMETypes()
-{
- static NeverDestroyed<HashSet<String, ASCIICaseInsensitiveHash>> supportedImageMIMETypes = std::initializer_list<String> {
-#if USE(CG)
- // This represents the subset of allowed image UTIs for which CoreServices has a corresponding MIME type.
- "image/tiff"_s,
- "image/gif"_s,
- "image/jpeg"_s,
- "image/vnd.microsoft.icon"_s,
- "image/jp2"_s,
- "image/apng"_s,
- "image/png"_s,
- "image/bmp"_s,
+static String normalizedImageMIMEType(const String&);
- "image/x-icon"_s, // Favicons don't have a MIME type in the registry either.
- "image/pjpeg"_s, // We only get one MIME type per UTI, hence our need to add these manually
-#if HAVE(WEBP)
- "image/webp"_s,
-#endif
+// On iOS, we include malformed image MIME types for compatibility with Mail.
+// These were removed for <rdar://problem/6564538> Re-enable UTI code in WebCore now that
+// MobileCoreServices exists. But Mail relies on at least image/tif reported as being
+// supported (should be image/tiff). This can be removed when Mail addresses:
+// <rdar://problem/7879510> Mail should use standard image mimetypes
+// and we fix sniffing so that it corrects items such as image/jpg -> image/jpeg.
+constexpr ComparableCaseFoldingASCIILiteral supportedImageMIMETypeArray[] = {
#if PLATFORM(IOS_FAMILY)
- // Add malformed image mimetype for compatibility with Mail and to handle malformed mimetypes from the net
- // These were removed for <rdar://problem/6564538> Re-enable UTI code in WebCore now that MobileCoreServices exists
- // But Mail relies on at least image/tif reported as being supported (should be image/tiff).
- // This can be removed when Mail addresses:
- // <rdar://problem/7879510> Mail should use standard image mimetypes
- // and we fix sniffing so that it corrects items such as image/jpg -> image/jpeg.
-
- // JPEG (image/jpeg)
- "image/jpg"_s,
- "image/jp_"_s,
- "image/jpe_"_s,
- "application/jpg"_s,
- "application/x-jpg"_s,
- "image/pipeg"_s,
- "image/vnd.switfview-jpeg"_s,
- "image/x-xbitmap"_s,
-
- // GIF (image/gif)
- "image/gi_"_s,
-
- // PNG (image/png)
- "application/png"_s,
- "application/x-png"_s,
-
- // TIFF (image/tiff)
- "image/x-tif"_s,
- "image/tif"_s,
- "image/x-tiff"_s,
- "application/tif"_s,
- "application/x-tif"_s,
- "application/tiff"_s,
- "application/x-tiff"_s,
-
- // BMP (image/bmp, image/x-bitmap)
- "image/x-bmp"_s,
- "image/x-win-bitmap"_s,
- "image/x-windows-bmp"_s,
- "image/ms-bmp"_s,
- "image/x-ms-bmp"_s,
- "application/bmp"_s,
- "application/x-bmp"_s,
- "application/x-win-bitmap"_s,
+ "application/bmp",
+ "application/jpg",
+ "application/png",
+ "application/tif",
+ "application/tiff",
+ "application/x-bmp",
+ "application/x-jpg",
+ "application/x-png",
+ "application/x-tif",
+ "application/x-tiff",
+ "application/x-win-bitmap",
#endif
-#else
- // assume that all implementations at least support the following standard
- // image types:
- "image/jpeg"_s,
- "image/png"_s,
- "image/gif"_s,
- "image/bmp"_s,
- "image/vnd.microsoft.icon"_s, // ico
- "image/x-icon"_s, // ico
- "image/x-xbitmap"_s, // xbm
-#if ENABLE(APNG)
- "image/apng"_s,
+#if USE(CG) || ENABLE(APNG)
+ "image/apng",
#endif
#if USE(AVIF)
- "image/avif"_s,
+ "image/avif",
#endif
-#if USE(OPENJPEG)
- "image/jp2"_s,
- "image/jpeg2000"_s,
+ "image/bmp",
+#if PLATFORM(IOS_FAMILY)
+ "image/gi_",
#endif
-#if USE(WEBP)
- "image/webp"_s,
+ "image/gif",
+#if USE(CG) || USE(OPENJPEG)
+ "image/jp2",
#endif
+#if PLATFORM(IOS_FAMILY)
+ "image/jp_",
+ "image/jpe_",
#endif
- };
-
+ "image/jpeg",
+#if !USE(CG) && USE(OPENJPEG)
+ "image/jpeg2000",
+#endif
+#if PLATFORM(IOS_FAMILY)
+ "image/ms-bmp",
+ "image/pipeg",
+#endif
#if USE(CG)
-#ifndef NDEBUG
- // Esnure supportedImageMIMETypes() is in sync with defaultSupportedImageTypes().
- static std::once_flag onceFlag;
- std::call_once(onceFlag, [] {
- for (auto& imageType : defaultSupportedImageTypes()) {
- auto mimeType = MIMETypeForImageType(imageType);
- ASSERT_IMPLIES(!mimeType.isEmpty(), supportedImageMIMETypes.get().contains(mimeType));
- }
- });
+ "image/pjpeg",
#endif
+ "image/png",
+#if PLATFORM(IOS_FAMILY)
+ "image/tif",
#endif
- return supportedImageMIMETypes;
+#if USE(CG)
+ "image/tiff",
+#endif
+ "image/vnd.microsoft.icon",
+#if PLATFORM(IOS_FAMILY)
+ "image/vnd.switfview-jpeg",
+#endif
+#if (USE(CG) && HAVE(WEBP)) || (!USE(CG) && USE(WEBP))
+ "image/webp",
+#endif
+#if PLATFORM(IOS_FAMILY)
+ "image/x-bmp",
+#endif
+ "image/x-icon",
+#if PLATFORM(IOS_FAMILY)
+ "image/x-ms-bmp",
+ "image/x-tif",
+ "image/x-tiff",
+ "image/x-win-bitmap",
+ "image/x-windows-bmp",
+#endif
+#if PLATFORM(IOS_FAMILY) || !USE(CG)
+ "image/x-xbitmap",
+#endif
+};
+
+template<ASCIISubset subset, unsigned size> static FixedVector<const char*> makeFixedVector(const ComparableASCIISubsetLiteral<subset> (&array)[size])
+{
+ FixedVector<const char*> result(std::size(array));
+ std::transform(std::begin(array), std::end(array), result.begin(), [] (auto literal) {
+ return literal.literal;
+ });
+ return result;
}
+FixedVector<const char*> MIMETypeRegistry::supportedImageMIMETypes()
+{
+ return makeFixedVector(supportedImageMIMETypeArray);
+}
+
HashSet<String, ASCIICaseInsensitiveHash>& MIMETypeRegistry::additionalSupportedImageMIMETypes()
{
static NeverDestroyed<HashSet<String, ASCIICaseInsensitiveHash>> additionalSupportedImageMIMETypes;
@@ -174,29 +168,25 @@
return additionalSupportedImageMIMETypes;
}
-static const HashSet<String, ASCIICaseInsensitiveHash>& supportedJavaScriptMIMETypes()
-{
- static NeverDestroyed<HashSet<String, ASCIICaseInsensitiveHash>> supportedJavaScriptMIMETypes = std::initializer_list<String> {
- // https://html.spec.whatwg.org/multipage/scripting.html#_javascript_-mime-type
- "text/_javascript_"_s,
- "text/ecmascript"_s,
- "application/_javascript_"_s,
- "application/ecmascript"_s,
- "application/x-_javascript_"_s,
- "application/x-ecmascript"_s,
- "text/_javascript_1.0"_s,
- "text/_javascript_1.1"_s,
- "text/_javascript_1.2"_s,
- "text/_javascript_1.3"_s,
- "text/_javascript_1.4"_s,
- "text/_javascript_1.5"_s,
- "text/jscript"_s,
- "text/livescript"_s,
- "text/x-_javascript_"_s,
- "text/x-ecmascript"_s,
- };
- return supportedJavaScriptMIMETypes;
-}
+// https://html.spec.whatwg.org/multipage/scripting.html#_javascript_-mime-type
+constexpr ComparableLettersLiteral supportedJavaScriptMIMETypeArray[] = {
+ "application/ecmascript",
+ "application/_javascript_",
+ "application/x-ecmascript",
+ "application/x-_javascript_",
+ "text/ecmascript",
+ "text/_javascript_",
+ "text/_javascript_1.0",
+ "text/_javascript_1.1",
+ "text/_javascript_1.2",
+ "text/_javascript_1.3",
+ "text/_javascript_1.4",
+ "text/_javascript_1.5",
+ "text/jscript",
+ "text/livescript",
+ "text/x-ecmascript",
+ "text/x-_javascript_",
+};
HashSet<String, ASCIICaseInsensitiveHash>& MIMETypeRegistry::supportedNonImageMIMETypes()
{
@@ -223,7 +213,8 @@
// Note: Adding a new type here will probably render it as HTML.
// This can result in cross-site scripting vulnerabilities.
};
- supportedNonImageMIMETypes.add(supportedJavaScriptMIMETypes().begin(), supportedJavaScriptMIMETypes().end());
+ for (auto& type : supportedJavaScriptMIMETypeArray)
+ supportedNonImageMIMETypes.add(type.literal);
#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
ArchiveFactory::registerKnownArchiveMIMETypes(supportedNonImageMIMETypes);
#endif
@@ -244,131 +235,129 @@
return supportedMediaMIMETypes;
}
-const HashSet<String, ASCIICaseInsensitiveHash>& MIMETypeRegistry::pdfMIMETypes()
+constexpr ComparableLettersLiteral pdfMIMETypeArray[] = {
+ "application/pdf",
+ "text/pdf",
+};
+
+FixedVector<const char*> MIMETypeRegistry::pdfMIMETypes()
{
- static NeverDestroyed<HashSet<String, ASCIICaseInsensitiveHash>> pdfMIMETypes = std::initializer_list<String> {
- "application/pdf"_s,
- "text/pdf"_s,
- };
- return pdfMIMETypes;
+ return makeFixedVector(pdfMIMETypeArray);
}
-const HashSet<String, ASCIICaseInsensitiveHash>& MIMETypeRegistry::unsupportedTextMIMETypes()
-{
- static NeverDestroyed<HashSet<String, ASCIICaseInsensitiveHash>> unsupportedTextMIMETypes = std::initializer_list<String> {
- "text/calendar"_s,
- "text/x-calendar"_s,
- "text/x-vcalendar"_s,
- "text/vcalendar"_s,
- "text/vcard"_s,
- "text/x-vcard"_s,
- "text/directory"_s,
- "text/ldif"_s,
- "text/qif"_s,
- "text/x-qif"_s,
- "text/x-csv"_s,
- "text/x-vcf"_s,
+constexpr ComparableLettersLiteral unsupportedTextMIMETypeArray[] = {
+ "text/calendar",
+ "text/directory",
+ "text/ldif",
+ "text/qif",
#if !PLATFORM(IOS_FAMILY)
- "text/rtf"_s,
-#else
- "text/vnd.sun.j2me.app-descriptor"_s,
+ "text/rtf",
#endif
- };
- return unsupportedTextMIMETypes;
+ "text/vcalendar",
+ "text/vcard",
+#if PLATFORM(IOS_FAMILY)
+ "text/vnd.sun.j2me.app-descriptor",
+#endif
+ "text/x-calendar",
+ "text/x-csv",
+ "text/x-qif",
+ "text/x-vcalendar",
+ "text/x-vcard",
+ "text/x-vcf",
+};
+
+FixedVector<const char*> MIMETypeRegistry::unsupportedTextMIMETypes()
+{
+ return makeFixedVector(unsupportedTextMIMETypeArray);
}
-const std::initializer_list<TypeExtensionPair>& commonMediaTypes()
+static const HashMap<String, Vector<String>, ASCIICaseInsensitiveHash>& commonMimeTypesMap()
{
- // A table of common media MIME types and file extensions used when a platform's
- // specific MIME type lookup doesn't have a match for a media file extension.
- static std::initializer_list<TypeExtensionPair> commonMediaTypes = {
- // Ogg
- { "application/ogg"_s, "ogx"_s },
- { "audio/ogg"_s, "ogg"_s },
- { "audio/ogg"_s, "oga"_s },
- { "video/ogg"_s, "ogv"_s },
+ ASSERT(isMainThread());
+ static NeverDestroyed<HashMap<String, Vector<String>, ASCIICaseInsensitiveHash>> mimeTypesMap = [] {
+ HashMap<String, Vector<String>, ASCIICaseInsensitiveHash> map;
+ // A table of common media MIME types and file extensions used when a platform's
+ // specific MIME type lookup doesn't have a match for a media file extension.
+ static constexpr TypeExtensionPair commonMediaTypes[] = {
+ // Ogg
+ { "application/ogg"_s, "ogx"_s },
+ { "audio/ogg"_s, "ogg"_s },
+ { "audio/ogg"_s, "oga"_s },
+ { "video/ogg"_s, "ogv"_s },
- // Annodex
- { "application/annodex"_s, "anx"_s },
- { "audio/annodex"_s, "axa"_s },
- { "video/annodex"_s, "axv"_s },
- { "audio/speex"_s, "spx"_s },
+ // Annodex
+ { "application/annodex"_s, "anx"_s },
+ { "audio/annodex"_s, "axa"_s },
+ { "video/annodex"_s, "axv"_s },
+ { "audio/speex"_s, "spx"_s },
- // WebM
- { "video/webm"_s, "webm"_s },
- { "audio/webm"_s, "webm"_s },
+ // WebM
+ { "video/webm"_s, "webm"_s },
+ { "audio/webm"_s, "webm"_s },
- // MPEG
- { "audio/mpeg"_s, "m1a"_s },
- { "audio/mpeg"_s, "m2a"_s },
- { "audio/mpeg"_s, "m1s"_s },
- { "audio/mpeg"_s, "mpa"_s },
- { "video/mpeg"_s, "mpg"_s },
- { "video/mpeg"_s, "m15"_s },
- { "video/mpeg"_s, "m1s"_s },
- { "video/mpeg"_s, "m1v"_s },
- { "video/mpeg"_s, "m75"_s },
- { "video/mpeg"_s, "mpa"_s },
- { "video/mpeg"_s, "mpeg"_s },
- { "video/mpeg"_s, "mpm"_s },
- { "video/mpeg"_s, "mpv"_s },
+ // MPEG
+ { "audio/mpeg"_s, "m1a"_s },
+ { "audio/mpeg"_s, "m2a"_s },
+ { "audio/mpeg"_s, "m1s"_s },
+ { "audio/mpeg"_s, "mpa"_s },
+ { "video/mpeg"_s, "mpg"_s },
+ { "video/mpeg"_s, "m15"_s },
+ { "video/mpeg"_s, "m1s"_s },
+ { "video/mpeg"_s, "m1v"_s },
+ { "video/mpeg"_s, "m75"_s },
+ { "video/mpeg"_s, "mpa"_s },
+ { "video/mpeg"_s, "mpeg"_s },
+ { "video/mpeg"_s, "mpm"_s },
+ { "video/mpeg"_s, "mpv"_s },
- // MPEG playlist
- { "application/vnd.apple.mpegurl"_s, "m3u8"_s },
- { "application/mpegurl"_s, "m3u8"_s },
- { "application/x-mpegurl"_s, "m3u8"_s },
- { "audio/mpegurl"_s, "m3url"_s },
- { "audio/x-mpegurl"_s, "m3url"_s },
- { "audio/mpegurl"_s, "m3u"_s },
- { "audio/x-mpegurl"_s, "m3u"_s },
+ // MPEG playlist
+ { "application/vnd.apple.mpegurl"_s, "m3u8"_s },
+ { "application/mpegurl"_s, "m3u8"_s },
+ { "application/x-mpegurl"_s, "m3u8"_s },
+ { "audio/mpegurl"_s, "m3url"_s },
+ { "audio/x-mpegurl"_s, "m3url"_s },
+ { "audio/mpegurl"_s, "m3u"_s },
+ { "audio/x-mpegurl"_s, "m3u"_s },
- // MPEG-4
- { "video/x-m4v"_s, "m4v"_s },
- { "audio/x-m4a"_s, "m4a"_s },
- { "audio/x-m4b"_s, "m4b"_s },
- { "audio/x-m4p"_s, "m4p"_s },
- { "audio/mp4"_s, "m4a"_s },
+ // MPEG-4
+ { "video/x-m4v"_s, "m4v"_s },
+ { "audio/x-m4a"_s, "m4a"_s },
+ { "audio/x-m4b"_s, "m4b"_s },
+ { "audio/x-m4p"_s, "m4p"_s },
+ { "audio/mp4"_s, "m4a"_s },
- // MP3
- { "audio/mp3"_s, "mp3"_s },
- { "audio/x-mp3"_s, "mp3"_s },
- { "audio/x-mpeg"_s, "mp3"_s },
+ // MP3
+ { "audio/mp3"_s, "mp3"_s },
+ { "audio/x-mp3"_s, "mp3"_s },
+ { "audio/x-mpeg"_s, "mp3"_s },
- // MPEG-2
- { "video/x-mpeg2"_s, "mp2"_s },
- { "video/mpeg2"_s, "vob"_s },
- { "video/mpeg2"_s, "mod"_s },
- { "video/m2ts"_s, "m2ts"_s },
- { "video/x-m2ts"_s, "m2t"_s },
- { "video/x-m2ts"_s, "ts"_s },
+ // MPEG-2
+ { "video/x-mpeg2"_s, "mp2"_s },
+ { "video/mpeg2"_s, "vob"_s },
+ { "video/mpeg2"_s, "mod"_s },
+ { "video/m2ts"_s, "m2ts"_s },
+ { "video/x-m2ts"_s, "m2t"_s },
+ { "video/x-m2ts"_s, "ts"_s },
- // 3GP/3GP2
- { "audio/3gpp"_s, "3gpp"_s },
- { "audio/3gpp2"_s, "3g2"_s },
- { "application/x-mpeg"_s, "amc"_s },
+ // 3GP/3GP2
+ { "audio/3gpp"_s, "3gpp"_s },
+ { "audio/3gpp2"_s, "3g2"_s },
+ { "application/x-mpeg"_s, "amc"_s },
- // AAC
- { "audio/aac"_s, "aac"_s },
- { "audio/aac"_s, "adts"_s },
- { "audio/x-aac"_s, "m4r"_s },
+ // AAC
+ { "audio/aac"_s, "aac"_s },
+ { "audio/aac"_s, "adts"_s },
+ { "audio/x-aac"_s, "m4r"_s },
- // CoreAudio File
- { "audio/x-caf"_s, "caf"_s },
- { "audio/x-gsm"_s, "gsm"_s },
+ // CoreAudio File
+ { "audio/x-caf"_s, "caf"_s },
+ { "audio/x-gsm"_s, "gsm"_s },
- // ADPCM
- { "audio/x-wav"_s, "wav"_s },
- { "audio/vnd.wave"_s, "wav"_s },
- };
- return commonMediaTypes;
-}
-
-static const HashMap<String, Vector<String>, ASCIICaseInsensitiveHash>& commonMimeTypesMap()
-{
- ASSERT(isMainThread());
- static NeverDestroyed<HashMap<String, Vector<String>, ASCIICaseInsensitiveHash>> mimeTypesMap = [] {
- HashMap<String, Vector<String>, ASCIICaseInsensitiveHash> map;
- for (auto& pair : commonMediaTypes()) {
+ // ADPCM
+ { "audio/x-wav"_s, "wav"_s },
+ { "audio/vnd.wave"_s, "wav"_s },
+ };
+ for (auto& pair : commonMediaTypes) {
ASCIILiteral type = pair.type;
ASCIILiteral extension = pair.extension;
map.ensure(extension, [type, extension] {
@@ -418,8 +407,20 @@
{
if (mimeType.isEmpty())
return false;
- String normalizedMIMEType = MIMETypeRegistry::normalizedMIMEType(mimeType);
- return supportedImageMIMETypes().contains(normalizedMIMEType) || additionalSupportedImageMIMETypes().contains(normalizedMIMEType);
+ static constexpr SortedArraySet supportedImageMIMETypeSet { supportedImageMIMETypeArray };
+#if USE(CG) && ASSERT_ENABLED
+ // Esnure supportedImageMIMETypeArray matches defaultSupportedImageTypes().
+ static std::once_flag onceFlag;
+ std::call_once(onceFlag, [] {
+ for (auto& imageType : defaultSupportedImageTypes()) {
+ auto mimeType = MIMETypeForImageType(imageType);
+ ASSERT_IMPLIES(!mimeType.isEmpty(), supportedImageMIMETypeSet.contains(mimeType));
+ }
+ });
+#endif
+ if (supportedImageMIMETypeSet.contains(mimeType))
+ return true;
+ return additionalSupportedImageMIMETypes().contains(normalizedImageMIMEType(mimeType));
}
bool MIMETypeRegistry::isSupportedImageVideoOrSVGMIMEType(const String& mimeType)
@@ -486,18 +487,8 @@
bool MIMETypeRegistry::isSupportedJavaScriptMIMEType(const String& mimeType)
{
- if (mimeType.isEmpty())
- return false;
-
- if (!isMainThread()) {
- bool isSupported = false;
- callOnMainThreadAndWait([&isSupported, mimeType = mimeType.isolatedCopy()] {
- isSupported = isSupportedJavaScriptMIMEType(mimeType);
- });
- return isSupported;
- }
-
- return supportedJavaScriptMIMETypes().contains(mimeType);
+ static constexpr SortedArraySet supportedJavaScriptMIMETypes { supportedJavaScriptMIMETypeArray };
+ return supportedJavaScriptMIMETypes.contains(mimeType);
}
bool MIMETypeRegistry::isSupportedStyleSheetMIMEType(const String& mimeType)
@@ -577,9 +568,8 @@
bool MIMETypeRegistry::isUnsupportedTextMIMEType(const String& mimeType)
{
- if (mimeType.isEmpty())
- return false;
- return unsupportedTextMIMETypes().contains(mimeType);
+ static constexpr SortedArraySet unsupportedTextMIMETypes { unsupportedTextMIMETypeArray };
+ return unsupportedTextMIMETypes.contains(mimeType);
}
bool MIMETypeRegistry::isTextMIMEType(const String& mimeType)
@@ -641,14 +631,13 @@
bool MIMETypeRegistry::isPDFMIMEType(const String& mimeType)
{
- if (mimeType.isEmpty())
- return false;
- return pdfMIMETypes().contains(mimeType);
+ static constexpr SortedArraySet set { pdfMIMETypeArray };
+ return set.contains(mimeType);
}
bool MIMETypeRegistry::isPostScriptMIMEType(const String& mimeType)
{
- return mimeType == "application/postscript";
+ return equalLettersIgnoringASCIICase(mimeType, "application/postscript");
}
bool MIMETypeRegistry::isPDFOrPostScriptMIMEType(const String& mimeType)
@@ -681,104 +670,85 @@
return defaultMIMEType;
}
-const HashSet<String, ASCIICaseInsensitiveHash>& MIMETypeRegistry::systemPreviewMIMETypes()
+constexpr ComparableLettersLiteral systemPreviewMIMETypeArray[] = {
+ "model/usd", // Unofficial, but supported because we documented this.
+ "model/vnd.pixar.usd", // Unofficial, but supported because we documented this.
+ "model/vnd.reality",
+ "model/vnd.usdz+zip", // The official type: https://www.iana.org/assignments/media-types/model/vnd.usdz+zip
+};
+
+FixedVector<const char*> MIMETypeRegistry::systemPreviewMIMETypes()
{
- static NeverDestroyed<HashSet<String, ASCIICaseInsensitiveHash>> systemPreviewMIMETypes = std::initializer_list<String> {
- // The official type: https://www.iana.org/assignments/media-types/model/vnd.usdz+zip
- "model/vnd.usdz+zip"_s,
- // Unofficial, but supported because we documented them.
- "model/usd"_s,
- "model/vnd.pixar.usd"_s,
- // Reality files.
- "model/vnd.reality"_s,
- };
- return systemPreviewMIMETypes;
+ return makeFixedVector(systemPreviewMIMETypeArray);
}
bool MIMETypeRegistry::isSystemPreviewMIMEType(const String& mimeType)
{
- if (mimeType.isEmpty())
- return false;
- return systemPreviewMIMETypes().contains(mimeType);
+ static constexpr SortedArraySet systemPreviewMIMETypeSet { systemPreviewMIMETypeArray };
+ return systemPreviewMIMETypeSet.contains(mimeType);
}
-#if !USE(CURL)
-
-// FIXME: Not sure why it makes sense to have a cross-platform function when only CURL has the concept
-// of a "normalized" MIME type.
-String MIMETypeRegistry::normalizedMIMEType(const String& mimeType)
+// FIXME: Not great that CURL needs this concept; other platforms do not.
+static String normalizedImageMIMEType(const String& mimeType)
{
+#if USE(CURL)
return mimeType;
-}
-
#else
-
-String MIMETypeRegistry::normalizedMIMEType(const String& mimeType)
-{
- static const auto mimeTypeAssociationMap = makeNeverDestroyed([] {
- static const std::pair<ASCIILiteral, ASCIILiteral> mimeTypeAssociations[] = {
- { "image/x-ms-bmp"_s, "image/bmp"_s },
- { "image/x-windows-bmp"_s, "image/bmp"_s },
- { "image/x-bmp"_s, "image/bmp"_s },
- { "image/x-bitmap"_s, "image/bmp"_s },
- { "image/x-ms-bitmap"_s, "image/bmp"_s },
- { "image/jpg"_s, "image/jpeg"_s },
- { "image/pjpeg"_s, "image/jpeg"_s },
- { "image/x-png"_s, "image/png"_s },
- { "image/vnd.rim.png"_s, "image/png"_s },
- { "image/ico"_s, "image/vnd.microsoft.icon"_s },
- { "image/icon"_s, "image/vnd.microsoft.icon"_s },
- { "text/ico"_s, "image/vnd.microsoft.icon"_s },
- { "application/ico"_s, "image/vnd.microsoft.icon"_s },
- { "image/x-icon"_s, "image/vnd.microsoft.icon"_s },
- { "audio/vnd.qcelp"_s, "audio/qcelp"_s },
- { "audio/qcp"_s, "audio/qcelp"_s },
- { "audio/vnd.qcp"_s, "audio/qcelp"_s },
- { "audio/wav"_s, "audio/x-wav"_s },
- { "audio/vnd.wave"_s, "audio/x-wav"_s },
- { "audio/mid"_s, "audio/midi"_s },
- { "audio/sp-midi"_s, "audio/midi"_s },
- { "audio/x-mid"_s, "audio/midi"_s },
- { "audio/x-midi"_s, "audio/midi"_s },
- { "audio/x-mpeg"_s, "audio/mpeg"_s },
- { "audio/mp3"_s, "audio/mpeg"_s },
- { "audio/x-mp3"_s, "audio/mpeg"_s },
- { "audio/mpeg3"_s, "audio/mpeg"_s },
- { "audio/x-mpeg3"_s, "audio/mpeg"_s },
- { "audio/mpg3"_s, "audio/mpeg"_s },
- { "audio/mpg"_s, "audio/mpeg"_s },
- { "audio/x-mpg"_s, "audio/mpeg"_s },
- { "audio/m4a"_s, "audio/mp4"_s },
- { "audio/x-m4a"_s, "audio/mp4"_s },
- { "audio/x-mp4"_s, "audio/mp4"_s },
- { "audio/x-aac"_s, "audio/aac"_s },
- { "audio/x-amr"_s, "audio/amr"_s },
- { "audio/mpegurl"_s, "audio/x-mpegurl"_s },
- { "audio/flac"_s, "audio/x-flac"_s },
- { "video/3gp"_s, "video/3gpp"_s },
- { "video/avi"_s, "video/x-msvideo"_s },
- { "video/x-m4v"_s, "video/mp4"_s },
- { "video/x-quicktime"_s, "video/quicktime"_s },
- { "application/java"_s, "application/java-archive"_s },
- { "application/x-java-archive"_s, "application/java-archive"_s },
- { "application/x-zip-compressed"_s, "application/zip"_s },
- { "text/cache-manifest"_s, "text/plain"_s },
- };
-
- HashMap<String, String, ASCIICaseInsensitiveHash> map;
- for (auto& pair : mimeTypeAssociations)
- map.add(pair.first, pair.second);
- return map;
- }());
-
- auto it = mimeTypeAssociationMap.get().find(mimeType);
- if (it != mimeTypeAssociationMap.get().end())
- return it->value;
- return mimeType;
+ // FIXME: Since this is only used in isSupportedImageMIMEType, we should consider removing the non-image types below.
+ static constexpr std::pair<ComparableLettersLiteral, ASCIILiteral> mimeTypeAssociationArray[] = {
+ { "application/ico", "image/vnd.microsoft.icon"_s },
+ { "application/java", "application/java-archive"_s },
+ { "application/x-java-archive", "application/java-archive"_s },
+ { "application/x-zip-compressed", "application/zip"_s },
+ { "audio/flac", "audio/x-flac"_s },
+ { "audio/m4a", "audio/mp4"_s },
+ { "audio/mid", "audio/midi"_s },
+ { "audio/mp3", "audio/mpeg"_s },
+ { "audio/mpeg3", "audio/mpeg"_s },
+ { "audio/mpegurl", "audio/x-mpegurl"_s },
+ { "audio/mpg", "audio/mpeg"_s },
+ { "audio/mpg3", "audio/mpeg"_s },
+ { "audio/qcp", "audio/qcelp"_s },
+ { "audio/sp-midi", "audio/midi"_s },
+ { "audio/vnd.qcelp", "audio/qcelp"_s },
+ { "audio/vnd.qcp", "audio/qcelp"_s },
+ { "audio/vnd.wave", "audio/x-wav"_s },
+ { "audio/wav", "audio/x-wav"_s },
+ { "audio/x-aac", "audio/aac"_s },
+ { "audio/x-amr", "audio/amr"_s },
+ { "audio/x-m4a", "audio/mp4"_s },
+ { "audio/x-mid", "audio/midi"_s },
+ { "audio/x-midi", "audio/midi"_s },
+ { "audio/x-mp3", "audio/mpeg"_s },
+ { "audio/x-mp4", "audio/mp4"_s },
+ { "audio/x-mpeg", "audio/mpeg"_s },
+ { "audio/x-mpeg3", "audio/mpeg"_s },
+ { "audio/x-mpg", "audio/mpeg"_s },
+ { "image/ico", "image/vnd.microsoft.icon"_s },
+ { "image/icon", "image/vnd.microsoft.icon"_s },
+ { "image/jpg", "image/jpeg"_s },
+ { "image/pjpeg", "image/jpeg"_s },
+ { "image/vnd.rim.png", "image/png"_s },
+ { "image/x-bitmap", "image/bmp"_s },
+ { "image/x-bmp", "image/bmp"_s },
+ { "image/x-icon", "image/vnd.microsoft.icon"_s },
+ { "image/x-ms-bitmap", "image/bmp"_s },
+ { "image/x-ms-bmp", "image/bmp"_s },
+ { "image/x-png", "image/png"_s },
+ { "image/x-windows-bmp", "image/bmp"_s },
+ { "text/cache-manifest", "text/plain"_s },
+ { "text/ico", "image/vnd.microsoft.icon"_s },
+ { "video/3gp", "video/3gpp"_s },
+ { "video/avi", "video/x-msvideo"_s },
+ { "video/x-m4v", "video/mp4"_s },
+ { "video/x-quicktime", "video/quicktime"_s },
+ };
+ static constexpr SortedArrayMap associationMap { mimeTypeAssociationArray };
+ auto normalizedType = associationMap.tryGet(mimeType);
+ return normalizedType ? *normalizedType : mimeType;
+#endif
}
-#endif
-
String MIMETypeRegistry::appendFileExtensionIfNecessary(const String& filename, const String& mimeType)
{
if (filename.isEmpty() || filename.contains('.') || equalIgnoringASCIICase(mimeType, defaultMIMEType()))
Modified: trunk/Source/WebCore/platform/MIMETypeRegistry.h (276779 => 276780)
--- trunk/Source/WebCore/platform/MIMETypeRegistry.h 2021-04-29 16:26:38 UTC (rev 276779)
+++ trunk/Source/WebCore/platform/MIMETypeRegistry.h 2021-04-29 16:39:55 UTC (rev 276780)
@@ -26,7 +26,6 @@
#pragma once
#include <wtf/HashSet.h>
-#include <wtf/Vector.h>
#include <wtf/text/StringHash.h>
namespace WebCore {
@@ -128,18 +127,14 @@
// makes this test is after many other tests are done on the MIME type.
WEBCORE_EXPORT static bool isTextMIMEType(const String& mimeType);
- // FIXME: Would be nice to find a way to avoid exposing these sets, even worse exposing non-const references.
- WEBCORE_EXPORT static const HashSet<String, ASCIICaseInsensitiveHash>& supportedImageMIMETypes();
+ WEBCORE_EXPORT static FixedVector<const char*> supportedImageMIMETypes();
static HashSet<String, ASCIICaseInsensitiveHash>& additionalSupportedImageMIMETypes();
WEBCORE_EXPORT static HashSet<String, ASCIICaseInsensitiveHash>& supportedNonImageMIMETypes();
WEBCORE_EXPORT static const HashSet<String, ASCIICaseInsensitiveHash>& supportedMediaMIMETypes();
- WEBCORE_EXPORT static const HashSet<String, ASCIICaseInsensitiveHash>& pdfMIMETypes();
- WEBCORE_EXPORT static const HashSet<String, ASCIICaseInsensitiveHash>& unsupportedTextMIMETypes();
- WEBCORE_EXPORT static const HashSet<String, ASCIICaseInsensitiveHash>& systemPreviewMIMETypes();
+ WEBCORE_EXPORT static FixedVector<const char*> pdfMIMETypes();
+ WEBCORE_EXPORT static FixedVector<const char*> unsupportedTextMIMETypes();
+ WEBCORE_EXPORT static FixedVector<const char*> systemPreviewMIMETypes();
- // FIXME: Unclear what the concept of a normalized MIME type is; currently it's a platform-specific notion.
- static String normalizedMIMEType(const String&);
-
WEBCORE_EXPORT static String appendFileExtensionIfNecessary(const String& filename, const String& mimeType);
WEBCORE_EXPORT static String preferredImageMIMETypeForEncoding(const Vector<String>& mimeTypes, const Vector<String>& extensions);
Modified: trunk/Source/WebCore/svg/SVGTransformValue.h (276779 => 276780)
--- trunk/Source/WebCore/svg/SVGTransformValue.h 2021-04-29 16:26:38 UTC (rev 276779)
+++ trunk/Source/WebCore/svg/SVGTransformValue.h 2021-04-29 16:39:55 UTC (rev 276780)
@@ -25,7 +25,6 @@
#include "FloatPoint.h"
#include "FloatSize.h"
#include "SVGMatrix.h"
-#include <wtf/HashMap.h>
#include <wtf/NeverDestroyed.h>
#include <wtf/text/StringBuilder.h>
Modified: trunk/Source/WebCore/testing/TypeConversions.h (276779 => 276780)
--- trunk/Source/WebCore/testing/TypeConversions.h 2021-04-29 16:26:38 UTC (rev 276779)
+++ trunk/Source/WebCore/testing/TypeConversions.h 2021-04-29 16:39:55 UTC (rev 276780)
@@ -27,7 +27,6 @@
#include "Node.h"
#include <wtf/FastMalloc.h>
-#include <wtf/HashMap.h>
#include <wtf/RefCounted.h>
#include <wtf/Variant.h>
#include <wtf/Vector.h>
Modified: trunk/Source/WebKit/ChangeLog (276779 => 276780)
--- trunk/Source/WebKit/ChangeLog 2021-04-29 16:26:38 UTC (rev 276779)
+++ trunk/Source/WebKit/ChangeLog 2021-04-29 16:39:55 UTC (rev 276780)
@@ -1,3 +1,17 @@
+2021-04-29 Darin Adler <[email protected]>
+
+ Extend SortedArrayMap further to work on case-folded strings, use in MIMETypeRegistry
+ https://bugs.webkit.org/show_bug.cgi?id=224968
+
+ Reviewed by Sam Weinig.
+
+ * UIProcess/API/ios/WKWebViewIOS.mm:
+ (-[WKWebView _isDisplayingPDF]): Updated since MIMETypeRegistry::pdfMIMETypes
+ returns a different type.
+ * UIProcess/Cocoa/WKWebViewContentProviderRegistry.mm:
+ (-[WKWebViewContentProviderRegistry initWithConfiguration:]): Updated since
+ MIMETypeRegistry::systemPreviewMIMETypes returns a different type.
+
2021-04-29 Ben Nham <[email protected]>
Unreviewed, reverting r276619.
Modified: trunk/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm (276779 => 276780)
--- trunk/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm 2021-04-29 16:26:38 UTC (rev 276779)
+++ trunk/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm 2021-04-29 16:39:55 UTC (rev 276780)
@@ -2700,8 +2700,8 @@
- (BOOL)_isDisplayingPDF
{
- for (auto& mimeType : WebCore::MIMETypeRegistry::pdfMIMETypes()) {
- Class providerClass = [[_configuration _contentProviderRegistry] providerForMIMEType:mimeType];
+ for (auto& type : WebCore::MIMETypeRegistry::pdfMIMETypes()) {
+ Class providerClass = [[_configuration _contentProviderRegistry] providerForMIMEType:@(type)];
if ([_customContentView isKindOfClass:providerClass])
return YES;
}
Modified: trunk/Source/WebKit/UIProcess/Cocoa/WKWebViewContentProviderRegistry.mm (276779 => 276780)
--- trunk/Source/WebKit/UIProcess/Cocoa/WKWebViewContentProviderRegistry.mm 2021-04-29 16:26:38 UTC (rev 276779)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WKWebViewContentProviderRegistry.mm 2021-04-29 16:39:55 UTC (rev 276780)
@@ -34,10 +34,10 @@
#import "WKWebViewInternal.h"
#import "WebPageProxy.h"
#import <WebCore/MIMETypeRegistry.h>
+#import <wtf/FixedVector.h>
#import <wtf/HashCountedSet.h>
#import <wtf/HashMap.h>
#import <wtf/text/StringHash.h>
-#import <wtf/text/WTFString.h>
@implementation WKWebViewContentProviderRegistry {
HashMap<String, Class <WKWebViewContentProvider>, ASCIICaseInsensitiveHash> _contentProviderForMIMEType;
@@ -50,14 +50,14 @@
return nil;
#if ENABLE(WKPDFVIEW)
- for (auto& mimeType : WebCore::MIMETypeRegistry::pdfMIMETypes())
- [self registerProvider:[WKPDFView class] forMIMEType:mimeType];
+ for (auto& type : WebCore::MIMETypeRegistry::pdfMIMETypes())
+ [self registerProvider:[WKPDFView class] forMIMEType:@(type)];
#endif
#if USE(SYSTEM_PREVIEW)
if (configuration._systemPreviewEnabled) {
- for (auto& mimeType : WebCore::MIMETypeRegistry::systemPreviewMIMETypes())
- [self registerProvider:[WKSystemPreviewView class] forMIMEType:mimeType];
+ for (auto& type : WebCore::MIMETypeRegistry::systemPreviewMIMETypes())
+ [self registerProvider:[WKSystemPreviewView class] forMIMEType:@(type)];
}
#endif
Modified: trunk/Source/WebKitLegacy/mac/ChangeLog (276779 => 276780)
--- trunk/Source/WebKitLegacy/mac/ChangeLog 2021-04-29 16:26:38 UTC (rev 276779)
+++ trunk/Source/WebKitLegacy/mac/ChangeLog 2021-04-29 16:39:55 UTC (rev 276780)
@@ -1,3 +1,19 @@
+2021-04-29 Darin Adler <[email protected]>
+
+ Extend SortedArrayMap further to work on case-folded strings, use in MIMETypeRegistry
+ https://bugs.webkit.org/show_bug.cgi?id=224968
+
+ Reviewed by Sam Weinig.
+
+ * WebView/WebHTMLRepresentation.mm:
+ (createNSArray): Renamed from newArrayWithStrings so this overloads the createNSArray
+ function from VectorCocoa.h so we can use the two interchangably and handle both FixedVector
+ and HashSet with the smae code.
+ (+[WebHTMLRepresentation supportedMediaMIMETypes]): Updated for name change.
+ (+[WebHTMLRepresentation supportedNonImageMIMETypes]): Ditto.
+ (+[WebHTMLRepresentation supportedImageMIMETypes]): Ditto.
+ (+[WebHTMLRepresentation unsupportedTextMIMETypes]): Ditto.
+
2021-04-28 Alex Christensen <[email protected]>
Remove support for NPAPI plugins in WebView
Modified: trunk/Source/WebKitLegacy/mac/WebView/WebHTMLRepresentation.mm (276779 => 276780)
--- trunk/Source/WebKitLegacy/mac/WebView/WebHTMLRepresentation.mm 2021-04-29 16:26:38 UTC (rev 276779)
+++ trunk/Source/WebKitLegacy/mac/WebView/WebHTMLRepresentation.mm 2021-04-29 16:39:55 UTC (rev 276780)
@@ -63,6 +63,7 @@
#import <WebCore/TextResourceDecoder.h>
#import <WebKitLegacy/DOMHTMLInputElement.h>
#import <wtf/Assertions.h>
+#import <wtf/FixedVector.h>
#import <wtf/NeverDestroyed.h>
#import <wtf/StdLibExtras.h>
#import <wtf/cocoa/VectorCocoa.h>
@@ -89,7 +90,7 @@
@implementation WebHTMLRepresentation
-static RetainPtr<NSArray> newArrayWithStrings(const HashSet<String, ASCIICaseInsensitiveHash>& set)
+static RetainPtr<NSArray> createNSArray(const HashSet<String, ASCIICaseInsensitiveHash>& set)
{
auto vector = copyToVectorOf<NSString *>(set);
return adoptNS([[NSArray alloc] initWithObjects:vector.data() count:vector.size()]);
@@ -104,25 +105,25 @@
+ (NSArray *)supportedMediaMIMETypes
{
- static NeverDestroyed<RetainPtr<NSArray>> staticSupportedMediaMIMETypes = newArrayWithStrings(MIMETypeRegistry::supportedMediaMIMETypes());
+ static NeverDestroyed<RetainPtr<NSArray>> staticSupportedMediaMIMETypes = createNSArray(MIMETypeRegistry::supportedMediaMIMETypes());
return staticSupportedMediaMIMETypes.get().get();
}
+ (NSArray *)supportedNonImageMIMETypes
{
- static NeverDestroyed<RetainPtr<NSArray>> staticSupportedNonImageMIMETypes = newArrayWithStrings(MIMETypeRegistry::supportedNonImageMIMETypes());
+ static NeverDestroyed<RetainPtr<NSArray>> staticSupportedNonImageMIMETypes = createNSArray(MIMETypeRegistry::supportedNonImageMIMETypes());
return staticSupportedNonImageMIMETypes.get().get();
}
+ (NSArray *)supportedImageMIMETypes
{
- static NeverDestroyed<RetainPtr<NSArray>> staticSupportedImageMIMETypes = newArrayWithStrings(MIMETypeRegistry::supportedImageMIMETypes());
+ static NeverDestroyed<RetainPtr<NSArray>> staticSupportedImageMIMETypes = createNSArray(MIMETypeRegistry::supportedImageMIMETypes());
return staticSupportedImageMIMETypes.get().get();
}
+ (NSArray *)unsupportedTextMIMETypes
{
- static NeverDestroyed<RetainPtr<NSArray>> staticUnsupportedTextMIMETypes = newArrayWithStrings(MIMETypeRegistry::unsupportedTextMIMETypes());
+ static NeverDestroyed<RetainPtr<NSArray>> staticUnsupportedTextMIMETypes = createNSArray(MIMETypeRegistry::unsupportedTextMIMETypes());
return staticUnsupportedTextMIMETypes.get().get();
}
Modified: trunk/Tools/ChangeLog (276779 => 276780)
--- trunk/Tools/ChangeLog 2021-04-29 16:26:38 UTC (rev 276779)
+++ trunk/Tools/ChangeLog 2021-04-29 16:39:55 UTC (rev 276780)
@@ -1,3 +1,15 @@
+2021-04-29 Darin Adler <[email protected]>
+
+ Extend SortedArrayMap further to work on case-folded strings, use in MIMETypeRegistry
+ https://bugs.webkit.org/show_bug.cgi?id=224968
+
+ Reviewed by Sam Weinig.
+
+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: Added SortedArrayMap.cpp,
+ and removed references to non-existent FullscreenRemoveNodeBeforeEnter.h and
+ FloatQuadTests.h.
+ * TestWebKitAPI/Tests/WTF/SortedArrayMap.cpp: Added.
+
2021-04-29 Roy Reapor <[email protected]>
[webkitcorepy] Allow user to specify interpreter used by autoinstall.py to install imported dependencies
Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (276779 => 276780)
--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2021-04-29 16:26:38 UTC (rev 276779)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2021-04-29 16:39:55 UTC (rev 276780)
@@ -869,6 +869,7 @@
93F56DA91E5F919D003EDE84 /* WKWebViewSnapshot.mm in Sources */ = {isa = PBXBuildFile; fileRef = 93F56DA81E5F9181003EDE84 /* WKWebViewSnapshot.mm */; };
93F7E86F14DC8E5C00C84A99 /* NewFirstVisuallyNonEmptyLayoutFrames_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93F7E86E14DC8E5B00C84A99 /* NewFirstVisuallyNonEmptyLayoutFrames_Bundle.cpp */; };
95095F20262FFFA50000D920 /* SampledPageTopColor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95095F1F262FFFA50000D920 /* SampledPageTopColor.mm */; };
+ 93FCDB34263631560046DD7D /* SortedArrayMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93FCDB33263631560046DD7D /* SortedArrayMap.cpp */; };
950E4CC1252E75240071659F /* iOSStylusSupport.mm in Sources */ = {isa = PBXBuildFile; fileRef = 950E4CC0252E75230071659F /* iOSStylusSupport.mm */; };
953ABB3525C0D682004C8B73 /* PageExtendedBackgroundColor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 953ABB3425C0D681004C8B73 /* PageExtendedBackgroundColor.mm */; };
95A524952581A10D00461FE9 /* WKWebViewThemeColor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95A524942581A10D00461FE9 /* WKWebViewThemeColor.mm */; };
@@ -1340,7 +1341,6 @@
dstPath = TestWebKitAPI.resources;
dstSubfolderSpec = 7;
files = (
- 498D030A26376B34009CBFAD /* resourceLoadStatisticsMissingUniqueIndex.db in Copy Resources */,
55A817FF2181021A0004A39A /* 100x100-red.tga in Copy Resources */,
1A9E52C913E65EF4006917F5 /* 18-characters.html in Copy Resources */,
55A81800218102210004A39A /* 400x400-green.png in Copy Resources */,
@@ -1652,6 +1652,7 @@
F41AB9A91EF4696B0083FA08 /* prevent-start.html in Copy Resources */,
F6FDDDD614241C6F004F1729 /* push-state.html in Copy Resources */,
A12DDC001E8373E700CF6CAE /* rendered-image-excluding-overflow.html in Copy Resources */,
+ 498D030A26376B34009CBFAD /* resourceLoadStatisticsMissingUniqueIndex.db in Copy Resources */,
F46849C01EEF5EF300B937FE /* rich-and-plain-text.html in Copy Resources */,
1CE6FAC32320267C00E48F6E /* rich-color-filtered.html in Copy Resources */,
2E92B8F7216490D4005B64F0 /* rich-text-attributes.html in Copy Resources */,
@@ -2564,6 +2565,7 @@
93F7E86B14DC8E4D00C84A99 /* NewFirstVisuallyNonEmptyLayoutFrames.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NewFirstVisuallyNonEmptyLayoutFrames.cpp; sourceTree = "<group>"; };
93F7E86E14DC8E5B00C84A99 /* NewFirstVisuallyNonEmptyLayoutFrames_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NewFirstVisuallyNonEmptyLayoutFrames_Bundle.cpp; sourceTree = "<group>"; };
95095F1F262FFFA50000D920 /* SampledPageTopColor.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SampledPageTopColor.mm; sourceTree = "<group>"; };
+ 93FCDB33263631560046DD7D /* SortedArrayMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SortedArrayMap.cpp; sourceTree = "<group>"; };
950E4CC0252E75230071659F /* iOSStylusSupport.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = iOSStylusSupport.mm; sourceTree = "<group>"; };
953ABB3425C0D681004C8B73 /* PageExtendedBackgroundColor.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PageExtendedBackgroundColor.mm; sourceTree = "<group>"; };
95A524942581A10D00461FE9 /* WKWebViewThemeColor.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKWebViewThemeColor.mm; sourceTree = "<group>"; };
@@ -2872,7 +2874,6 @@
CDCFA7A91E45122F00C2433D /* SampleMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SampleMap.cpp; sourceTree = "<group>"; };
CDCFFEC022E268D500DF4223 /* NoPauseWhenSwitchingTabs.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = NoPauseWhenSwitchingTabs.mm; sourceTree = "<group>"; };
CDD68F0C22C18317000CF0AE /* WKWebViewCloseAllMediaPresentations.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKWebViewCloseAllMediaPresentations.mm; sourceTree = "<group>"; };
- CDDC7C6725FFF6D000224278 /* FullscreenRemoveNodeBeforeEnter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FullscreenRemoveNodeBeforeEnter.h; sourceTree = "<group>"; };
CDDC7C6825FFF6D000224278 /* FullscreenRemoveNodeBeforeEnter.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = FullscreenRemoveNodeBeforeEnter.mm; sourceTree = "<group>"; };
CDE195B21CFE0ADE0053D256 /* FullscreenTopContentInset.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = FullscreenTopContentInset.html; sourceTree = "<group>"; };
CDE195B31CFE0ADE0053D256 /* TopContentInset.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TopContentInset.mm; sourceTree = "<group>"; };
@@ -3050,7 +3051,6 @@
F4A32ECA1F0642F40047C544 /* contenteditable-in-iframe.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "contenteditable-in-iframe.html"; sourceTree = "<group>"; };
F4A9202E1FEE34C800F59590 /* apple-data-url.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "apple-data-url.html"; sourceTree = "<group>"; };
F4AB57891F65164B00DB0DA1 /* custom-draggable-div.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "custom-draggable-div.html"; sourceTree = "<group>"; };
- F4AD183625ED791500B1A19F /* FloatQuadTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FloatQuadTests.h; sourceTree = "<group>"; };
F4AD183725ED791500B1A19F /* FloatQuadTests.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FloatQuadTests.cpp; sourceTree = "<group>"; };
F4B0167F25AE02D600E445C4 /* DisableSpellcheckPlugIn.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = DisableSpellcheckPlugIn.mm; sourceTree = "<group>"; };
F4B0168225AE060F00E445C4 /* DisableSpellcheck.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = DisableSpellcheck.mm; sourceTree = "<group>"; };
@@ -3416,7 +3416,6 @@
CDCF78A7244A2EDB00480311 /* FullscreenAlert.mm */,
CD78E11A1DB7EA360014A2DE /* FullscreenDelegate.mm */,
3F1B52681D3D7129008D60C4 /* FullscreenLayoutConstraints.mm */,
- CDDC7C6725FFF6D000224278 /* FullscreenRemoveNodeBeforeEnter.h */,
CDDC7C6825FFF6D000224278 /* FullscreenRemoveNodeBeforeEnter.mm */,
631EFFF51E7B5E8D00D2EBB8 /* Geolocation.mm */,
07E1F6A01FFC3A080096C7EC /* GetDisplayMedia.mm */,
@@ -3676,7 +3675,6 @@
7A32D7491F02151500162C44 /* FileMonitor.cpp */,
7A909A701D877475007E10F8 /* FloatPointTests.cpp */,
F4AD183725ED791500B1A19F /* FloatQuadTests.cpp */,
- F4AD183625ED791500B1A19F /* FloatQuadTests.h */,
7A909A711D877475007E10F8 /* FloatRectTests.cpp */,
7A909A721D877475007E10F8 /* FloatSizeTests.cpp */,
8E4A85361E1D1AA100F53B0F /* GridPosition.cpp */,
@@ -3881,7 +3879,6 @@
A16F66B81C40E9E100BD4D24 /* Resources */ = {
isa = PBXGroup;
children = (
- 498D030926376B2C009CBFAD /* resourceLoadStatisticsMissingUniqueIndex.db */,
55A817FE218101DF0004A39A /* 100x100-red.tga */,
55A817FD218101DF0004A39A /* 400x400-green.png */,
F4CFCDD9249FC9D900527482 /* Ahem.ttf */,
@@ -4071,6 +4068,7 @@
F41AB9941EF4692C0083FA08 /* prevent-operation.html */,
F41AB99A1EF4692C0083FA08 /* prevent-start.html */,
A12DDBFF1E8373C100CF6CAE /* rendered-image-excluding-overflow.html */,
+ 498D030926376B2C009CBFAD /* resourceLoadStatisticsMissingUniqueIndex.db */,
F46849BF1EEF5EDC00B937FE /* rich-and-plain-text.html */,
1CE6FAC12320264F00E48F6E /* rich-color-filtered.html */,
2E92B8F6216490C3005B64F0 /* rich-text-attributes.html */,
@@ -4450,6 +4448,7 @@
0BCD85691485C98B00EA2003 /* SetForScope.cpp */,
CD5393C91757BAC400C07123 /* SHA1.cpp */,
E3953F951F2CF32100A76A2E /* Signals.cpp */,
+ 93FCDB33263631560046DD7D /* SortedArrayMap.cpp */,
FE2BCDC62470FC7000DEC33B /* StdLibExtras.cpp */,
81B50192140F232300D9EB58 /* StringBuilder.cpp */,
7CD4C26C1E2C0E6E00929470 /* StringConcatenate.cpp */,
@@ -5203,6 +5202,7 @@
7C83DF3D1D0A590C00FEBCF3 /* SetForScope.cpp in Sources */,
7C83DF2A1D0A590C00FEBCF3 /* SHA1.cpp in Sources */,
E373D7911F2CF35200C6FAAF /* Signals.cpp in Sources */,
+ 93FCDB34263631560046DD7D /* SortedArrayMap.cpp in Sources */,
FE2BCDC72470FDA300DEC33B /* StdLibExtras.cpp in Sources */,
7C83DF321D0A590C00FEBCF3 /* StringBuilder.cpp in Sources */,
7CD4C26E1E2C0E6E00929470 /* StringConcatenate.cpp in Sources */,
Added: trunk/Tools/TestWebKitAPI/Tests/WTF/SortedArrayMap.cpp (0 => 276780)
--- trunk/Tools/TestWebKitAPI/Tests/WTF/SortedArrayMap.cpp (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/SortedArrayMap.cpp 2021-04-29 16:39:55 UTC (rev 276780)
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include <wtf/SortedArrayMap.h>
+
+TEST(WTF, SortedArraySet)
+{
+ static constexpr ComparableCaseFoldingASCIILiteral caseFoldingArray[] = {
+ "_",
+ "a",
+ "c",
+ "delightful",
+ "q",
+ "q_",
+ "r/y",
+ "s-z",
+ };
+ static constexpr SortedArraySet caseFoldingSet { caseFoldingArray };
+
+ static constexpr ComparableLettersLiteral lettersArray[] = {
+ "a",
+ "c",
+ "delightful",
+ "q",
+ "r/y",
+ "s-z",
+ };
+ static constexpr SortedArraySet lettersSet { lettersArray };
+
+ static constexpr ComparableLettersLiteral scriptTypesArray[] = {
+ "application/ecmascript",
+ "application/_javascript_",
+ "application/x-ecmascript",
+ "application/x-_javascript_",
+ "text/ecmascript",
+ "text/_javascript_",
+ "text/_javascript_1.0",
+ "text/_javascript_1.1",
+ "text/_javascript_1.2",
+ "text/_javascript_1.3",
+ "text/_javascript_1.4",
+ "text/_javascript_1.5",
+ "text/jscript",
+ "text/livescript",
+ "text/x-ecmascript",
+ "text/x-_javascript_",
+ };
+ static constexpr SortedArraySet scriptTypesSet { scriptTypesArray };
+
+ EXPECT_FALSE(caseFoldingSet.contains(""));
+ EXPECT_TRUE(caseFoldingSet.contains("_"));
+ EXPECT_TRUE(caseFoldingSet.contains("c"));
+ EXPECT_TRUE(caseFoldingSet.contains("delightful"));
+ EXPECT_FALSE(caseFoldingSet.contains("d"));
+ EXPECT_TRUE(caseFoldingSet.contains("q_"));
+ EXPECT_FALSE(caseFoldingSet.contains("q__"));
+
+ EXPECT_FALSE(lettersSet.contains(""));
+ EXPECT_FALSE(lettersSet.contains("_"));
+ EXPECT_TRUE(lettersSet.contains("c"));
+ EXPECT_TRUE(lettersSet.contains("delightful"));
+ EXPECT_FALSE(lettersSet.contains("d"));
+ EXPECT_FALSE(lettersSet.contains("q_"));
+ EXPECT_FALSE(lettersSet.contains("q__"));
+
+ ASSERT_TRUE(scriptTypesSet.contains("text/_javascript_"));
+ ASSERT_TRUE(scriptTypesSet.contains("TEXT/_javascript_"));
+ ASSERT_TRUE(scriptTypesSet.contains("application/_javascript_"));
+ ASSERT_TRUE(scriptTypesSet.contains("application/ecmascript"));
+ ASSERT_TRUE(scriptTypesSet.contains("application/x-_javascript_"));
+ ASSERT_TRUE(scriptTypesSet.contains("application/x-ecmascript"));
+ ASSERT_FALSE(scriptTypesSet.contains("text/plain"));
+ ASSERT_FALSE(scriptTypesSet.contains("application/json"));
+ ASSERT_FALSE(scriptTypesSet.contains("foo/_javascript_"));
+}
_______________________________________________ webkit-changes mailing list [email protected] https://lists.webkit.org/mailman/listinfo/webkit-changes
