зеркало из https://github.com/mozilla/gecko-dev.git
Bug 908413 - Make dom::MimeType a template to make it usable with nsCString r=hsivonen
Differential Revision: https://phabricator.services.mozilla.com/D5094 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
86eda77a20
Коммит
c4da49a35f
|
@ -2,26 +2,29 @@
|
|||
#include "nsUnicharUtils.h"
|
||||
|
||||
namespace {
|
||||
static inline bool IsHTTPTokenPoint(const char16_t c) {
|
||||
template<typename char_type>
|
||||
static inline bool IsHTTPTokenPoint(const char_type c) {
|
||||
return c == '!' || c == '#' || c == '$' || c == '%' || c == '&' ||
|
||||
c == '\'' || c == '*' || c == '+' || c == '-' || c == '.' ||
|
||||
c == '^' || c == '_' || c == '`' || c == '|' || c == '~' ||
|
||||
mozilla::IsAsciiAlphanumeric(c);
|
||||
}
|
||||
|
||||
static inline bool IsHTTPQuotedStringTokenPoint(const char16_t c) {
|
||||
return c == 0x9 || (c >= ' ' && c <= '~') || (c >= 0x80 && c <= 0xFF);
|
||||
template<typename char_type>
|
||||
static inline bool IsHTTPQuotedStringTokenPoint(const char_type c) {
|
||||
return c == 0x9 || (c >= ' ' && c <= '~') || mozilla::IsNonAsciiLatin1(c);
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ mozilla::UniquePtr<MimeType>
|
||||
MimeType::Parse(const nsAString& aMimeType)
|
||||
template<typename char_type>
|
||||
/* static */ mozilla::UniquePtr<TMimeType<char_type>>
|
||||
TMimeType<char_type>::Parse(const nsTSubstring<char_type>& aMimeType)
|
||||
{
|
||||
// See https://mimesniff.spec.whatwg.org/#parsing-a-mime-type
|
||||
|
||||
// Steps 1-2
|
||||
const char16_t* pos = aMimeType.BeginReading();
|
||||
const char16_t* end = aMimeType.EndReading();
|
||||
const char_type* pos = aMimeType.BeginReading();
|
||||
const char_type* end = aMimeType.EndReading();
|
||||
while (pos < end && mozilla::IsAsciiWhitespace(*pos)) {
|
||||
++pos;
|
||||
}
|
||||
|
@ -33,14 +36,14 @@ MimeType::Parse(const nsAString& aMimeType)
|
|||
}
|
||||
|
||||
// Steps 3-4
|
||||
const char16_t* typeStart = pos;
|
||||
const char_type* typeStart = pos;
|
||||
while (pos < end && *pos != '/') {
|
||||
if (!IsHTTPTokenPoint(*pos)) {
|
||||
return nullptr;
|
||||
}
|
||||
++pos;
|
||||
}
|
||||
const char16_t* typeEnd = pos;
|
||||
const char_type* typeEnd = pos;
|
||||
if (typeStart == typeEnd) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -54,8 +57,8 @@ MimeType::Parse(const nsAString& aMimeType)
|
|||
++pos;
|
||||
|
||||
// Step 7-9
|
||||
const char16_t* subtypeStart = pos;
|
||||
const char16_t* subtypeEnd = nullptr;
|
||||
const char_type* subtypeStart = pos;
|
||||
const char_type* subtypeEnd = nullptr;
|
||||
while (pos < end && *pos != ';') {
|
||||
if (!IsHTTPTokenPoint(*pos)) {
|
||||
// If we hit a whitespace, check that the rest of
|
||||
|
@ -84,15 +87,15 @@ MimeType::Parse(const nsAString& aMimeType)
|
|||
}
|
||||
|
||||
// Step 10
|
||||
nsString type;
|
||||
nsString subtype;
|
||||
for (const char16_t* c = typeStart; c < typeEnd; ++c) {
|
||||
nsTString<char_type> type;
|
||||
nsTString<char_type> subtype;
|
||||
for (const char_type* c = typeStart; c < typeEnd; ++c) {
|
||||
type.Append(ToLowerCaseASCII(*c));
|
||||
}
|
||||
for (const char16_t* c = subtypeStart; c < subtypeEnd; ++c) {
|
||||
for (const char_type* c = subtypeStart; c < subtypeEnd; ++c) {
|
||||
subtype.Append(ToLowerCaseASCII(*c));
|
||||
}
|
||||
mozilla::UniquePtr<MimeType> mimeType(mozilla::MakeUnique<MimeType>(type, subtype));
|
||||
mozilla::UniquePtr<TMimeType<char_type>> mimeType(mozilla::MakeUnique<TMimeType<char_type>>(type, subtype));
|
||||
|
||||
// Step 11
|
||||
while (pos < end) {
|
||||
|
@ -105,7 +108,7 @@ MimeType::Parse(const nsAString& aMimeType)
|
|||
}
|
||||
|
||||
// Steps 11.3 and 11.4
|
||||
nsString paramName;
|
||||
nsTString<char_type> paramName;
|
||||
bool paramNameHadInvalidChars = false;
|
||||
while (pos < end && *pos != ';' && *pos != '=') {
|
||||
if (!IsHTTPTokenPoint(*pos)) {
|
||||
|
@ -186,7 +189,7 @@ MimeType::Parse(const nsAString& aMimeType)
|
|||
|
||||
} else {
|
||||
|
||||
const char16_t* paramValueStart = pos;
|
||||
const char_type* paramValueStart = pos;
|
||||
|
||||
// Step 11.7.2.1
|
||||
while (pos < end && *pos != ';') {
|
||||
|
@ -200,13 +203,13 @@ MimeType::Parse(const nsAString& aMimeType)
|
|||
}
|
||||
|
||||
// Step 11.7.2.2
|
||||
const char16_t* paramValueEnd = pos - 1;
|
||||
const char_type* paramValueEnd = pos - 1;
|
||||
while (paramValueEnd >= paramValueStart &&
|
||||
mozilla::IsAsciiWhitespace(*paramValueEnd)) {
|
||||
--paramValueEnd;
|
||||
}
|
||||
|
||||
for (const char16_t* c = paramValueStart; c <= paramValueEnd; ++c) {
|
||||
for (const char_type* c = paramValueStart; c <= paramValueEnd; ++c) {
|
||||
paramValue.Append(*c);
|
||||
}
|
||||
}
|
||||
|
@ -224,8 +227,9 @@ MimeType::Parse(const nsAString& aMimeType)
|
|||
return mimeType;
|
||||
}
|
||||
|
||||
template<typename char_type>
|
||||
void
|
||||
MimeType::Serialize(nsAString& aOutput) const
|
||||
TMimeType<char_type>::Serialize(nsTSubstring<char_type>& aOutput) const
|
||||
{
|
||||
aOutput.Assign(mType);
|
||||
aOutput.AppendLiteral("/");
|
||||
|
@ -239,8 +243,8 @@ MimeType::Serialize(nsAString& aOutput) const
|
|||
aOutput.AppendLiteral("=");
|
||||
if (value.mRequiresQuoting) {
|
||||
aOutput.AppendLiteral("\"");
|
||||
const char16_t* vcur = value.BeginReading();
|
||||
const char16_t* vend = value.EndReading();
|
||||
const char_type* vcur = value.BeginReading();
|
||||
const char_type* vend = value.EndReading();
|
||||
while (vcur < vend) {
|
||||
if (*vcur == '"' || *vcur == '\\') {
|
||||
aOutput.AppendLiteral("\\");
|
||||
|
@ -254,3 +258,8 @@ MimeType::Serialize(nsAString& aOutput) const
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
template mozilla::UniquePtr<TMimeType<char16_t>> TMimeType<char16_t>::Parse(const nsTSubstring<char16_t>& aMimeType);
|
||||
template mozilla::UniquePtr<TMimeType<char>> TMimeType<char>::Parse(const nsTSubstring<char>& aMimeType);
|
||||
template void TMimeType<char16_t>::Serialize(nsTSubstring<char16_t>& aOutput) const;
|
||||
template void TMimeType<char>::Serialize(nsTSubstring<char>& aOutput) const;
|
||||
|
|
|
@ -12,10 +12,16 @@
|
|||
#include "nsDataHashtable.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
class MimeType final
|
||||
template<typename char_type> struct HashKeyType;
|
||||
template<> struct HashKeyType<char16_t> { typedef nsStringHashKey HashType; };
|
||||
template<> struct HashKeyType<char> { typedef nsCStringHashKey HashType; };
|
||||
|
||||
|
||||
template <typename char_type>
|
||||
class TMimeType final
|
||||
{
|
||||
private:
|
||||
class ParameterValue : public nsString
|
||||
class ParameterValue : public nsTString<char_type>
|
||||
{
|
||||
public:
|
||||
bool mRequiresQuoting;
|
||||
|
@ -25,18 +31,22 @@ private:
|
|||
{}
|
||||
};
|
||||
|
||||
nsString mType;
|
||||
nsString mSubtype;
|
||||
nsDataHashtable<nsStringHashKey, ParameterValue> mParameters;
|
||||
nsTArray<nsString> mParameterNames;
|
||||
nsTString<char_type> mType;
|
||||
nsTString<char_type> mSubtype;
|
||||
nsDataHashtable<typename HashKeyType<char_type>::HashType, ParameterValue> mParameters;
|
||||
nsTArray<nsTString<char_type>> mParameterNames;
|
||||
|
||||
public:
|
||||
MimeType(const nsAString& aType, const nsAString& aSubtype)
|
||||
TMimeType(const nsTSubstring<char_type>& aType, const nsTSubstring<char_type>& aSubtype)
|
||||
: mType(aType), mSubtype(aSubtype)
|
||||
{}
|
||||
|
||||
static mozilla::UniquePtr<MimeType> Parse(const nsAString& aStr);
|
||||
void Serialize(nsAString& aStr) const;
|
||||
static mozilla::UniquePtr<TMimeType<char_type>> Parse(const nsTSubstring<char_type>& aStr);
|
||||
|
||||
void Serialize(nsTSubstring<char_type>& aStr) const;
|
||||
};
|
||||
|
||||
using MimeType = TMimeType<char16_t>;
|
||||
using CMimeType = TMimeType<char>;
|
||||
|
||||
#endif // mozilla_dom_MimeType_h
|
||||
|
|
|
@ -212,6 +212,17 @@ TEST(MimeType, DuplicateParameter2)
|
|||
"Duplicate parameter #2";
|
||||
}
|
||||
|
||||
TEST(MimeType, CString)
|
||||
{
|
||||
const auto in = NS_LITERAL_CSTRING("text/html;charset=();charset=GBK");
|
||||
UniquePtr<CMimeType> parsed = CMimeType::Parse(in);
|
||||
ASSERT_TRUE(parsed) << "Parsing succeeded";
|
||||
nsCString out;
|
||||
parsed->Serialize(out);
|
||||
ASSERT_TRUE(out.Equals(NS_LITERAL_CSTRING("text/html;charset=\"()\""))) <<
|
||||
"Duplicate parameter #2";
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4819)
|
||||
|
|
|
@ -47,6 +47,15 @@ IsAscii(Char aChar)
|
|||
return uc < 0x80;
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
constexpr bool
|
||||
IsNonAsciiLatin1(Char aChar)
|
||||
{
|
||||
using UnsignedChar = typename detail::MakeUnsignedChar<Char>::Type;
|
||||
auto uc = static_cast<UnsignedChar>(aChar);
|
||||
return uc >= 0x80 && uc <= 0xFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true iff |aChar| matches Ascii Whitespace.
|
||||
*
|
||||
|
|
Загрузка…
Ссылка в новой задаче