static inline bool matchesCSSPropertyNamePrefix(const StringImpl& propertyName, const char (&prefix)[prefixCStringLength]) { size_t prefixLength = prefixCStringLength - 1; ASSERT(toASCIILower(propertyName[0]) == prefix[0]); const size_t offset = 1; #ifndef NDEBUG for (size_t i = 0; i < prefixLength; ++i) ASSERT(isASCIILower(prefix[i])); ASSERT(!prefix[prefixLength]); ASSERT(propertyName.length()); #endif // The prefix within the property name must be followed by a capital letter. // Other characters in the prefix within the property name must be lowercase. if (propertyName.length() < (prefixLength + 1)) return false; for (size_t i = offset; i < prefixLength; ++i) { if (propertyName[i] != prefix[i]) return false; } if (!isASCIIUpper(propertyName[prefixLength])) return false; return true; }
static bool isValidPropertyName(const String& name) { unsigned length = name.length(); for (unsigned i = 0; i < length; ++i) { if (name[i] == '-' && (i + 1 < length) && isASCIILower(name[i + 1])) return false; } return true; }
static bool isValidPropertyName(const String& name) { const UChar* characters = name.characters(); unsigned length = name.length(); for (unsigned i = 0; i < length; ++i) { if (characters[i] == '-' && (i + 1 < length) && isASCIILower(characters[i + 1])) return false; } return true; }
static DateTimeFormat::FieldType mapCharacterToFieldType(const UChar ch) { if (isASCIIUpper(ch)) return upperCaseToFieldTypeMap[ch - 'A']; if (isASCIILower(ch)) return lowerCaseToFieldTypeMap[ch - 'a']; return DateTimeFormat::FieldTypeLiteral; }
static bool lowerCaseEqualsASCII(const char* begin, const char* end, const char* str) { while (begin != end && *str) { ASSERT(isASCIILower(*str)); if (toASCIILower(*begin++) != *str++) return false; } // Both strings are equal (ignoring case) if and only if all of the characters were equal, // and the end of both has been reached. return begin == end && !*str; }
static bool propertyNameMatchesAttributeName(const CharType1* propertyName, const CharType2* attributeName, unsigned propertyLength, unsigned attributeLength) { unsigned a = 5; unsigned p = 0; bool wordBoundary = false; while (a < attributeLength && p < propertyLength) { if (attributeName[a] == '-' && a + 1 < attributeLength && isASCIILower(attributeName[a + 1])) { wordBoundary = true; } else { if ((wordBoundary ? toASCIIUpper(attributeName[a]) : attributeName[a]) != propertyName[p]) return false; p++; wordBoundary = false; } a++; } return (a == attributeLength && p == propertyLength); }
static String convertAttributeNameToPropertyName(const String& name) { StringBuilder stringBuilder; unsigned length = name.length(); for (unsigned i = 5; i < length; ++i) { UChar character = name[i]; if (character != '-') stringBuilder.append(character); else { if ((i + 1 < length) && isASCIILower(name[i + 1])) { stringBuilder.append(toASCIIUpper(name[i + 1])); ++i; } else stringBuilder.append(character); } } return stringBuilder.toString(); }
static String convertAttributeNameToPropertyName(const String& name) { Vector<UChar> newStringBuffer; const UChar* characters = name.characters(); unsigned length = name.length(); for (unsigned i = 5; i < length; ++i) { if (characters[i] != '-') newStringBuffer.append(characters[i]); else { if ((i + 1 < length) && isASCIILower(characters[i + 1])) { newStringBuffer.append(toASCIIUpper(characters[i + 1])); ++i; } else newStringBuffer.append(characters[i]); } } return String::adopt(newStringBuffer); }
// Check for a CSS prefix. // Passed prefix is all lowercase. // First character of the prefix within the property name may be upper or lowercase. // Other characters in the prefix within the property name must be lowercase. // The prefix within the property name must be followed by a capital letter. static bool hasCSSPropertyNamePrefix(const Identifier& propertyName, const char* prefix) { #ifndef NDEBUG ASSERT(*prefix); for (const char* p = prefix; *p; ++p) ASSERT(isASCIILower(*p)); ASSERT(propertyName.size()); #endif if (toASCIILower(propertyName.data()[0]) != prefix[0]) return false; unsigned length = propertyName.size(); for (unsigned i = 1; i < length; ++i) { if (!prefix[i]) return isASCIIUpper(propertyName.data()[i]); if (propertyName.data()[i] != prefix[i]) return false; } return false; }
bool StringImpl::isLower() { // Do a faster loop for the case where all the characters are ASCII. bool allLower = true; UChar ored = 0; for (unsigned i = 0; i < m_length; i++) { UChar c = m_data[i]; allLower = allLower && isASCIILower(c); ored |= c; } if (!(ored & ~0x7F)) return allLower; // Do a slower check for cases that include non-ASCII characters. allLower = true; unsigned i = 0; while (i < m_length) { UChar32 character; U16_NEXT(m_data, i, m_length, character) allLower = allLower && Unicode::isLower(character); } return allLower; }
static const QuotesForLanguage* quotesForLanguage(const String& language) { // Table of quotes from http://www.whatwg.org/specs/web-apps/current-work/multipage/rendering.html#quotes static const QuotesForLanguage quoteTable[] = { { "af", 0x201c, 0x201d, 0x2018, 0x2019 }, { "agq", 0x201e, 0x201d, 0x201a, 0x2019 }, { "ak", 0x201c, 0x201d, 0x2018, 0x2019 }, { "am", 0x00ab, 0x00bb, 0x2039, 0x203a }, { "ar", 0x201d, 0x201c, 0x2019, 0x2018 }, { "asa", 0x201c, 0x201d, 0x2018, 0x2019 }, { "az-cyrl", 0x00ab, 0x00bb, 0x2039, 0x203a }, { "bas", 0x00ab, 0x00bb, 0x201e, 0x201c }, { "bem", 0x201c, 0x201d, 0x2018, 0x2019 }, { "bez", 0x201c, 0x201d, 0x2018, 0x2019 }, { "bg", 0x201e, 0x201c, 0x201a, 0x2018 }, { "bm", 0x00ab, 0x00bb, 0x201c, 0x201d }, { "bn", 0x201c, 0x201d, 0x2018, 0x2019 }, { "br", 0x00ab, 0x00bb, 0x2039, 0x203a }, { "brx", 0x201c, 0x201d, 0x2018, 0x2019 }, { "bs-cyrl", 0x201e, 0x201c, 0x201a, 0x2018 }, { "ca", 0x201c, 0x201d, 0x00ab, 0x00bb }, { "cgg", 0x201c, 0x201d, 0x2018, 0x2019 }, { "chr", 0x201c, 0x201d, 0x2018, 0x2019 }, { "cs", 0x201e, 0x201c, 0x201a, 0x2018 }, { "da", 0x201c, 0x201d, 0x2018, 0x2019 }, { "dav", 0x201c, 0x201d, 0x2018, 0x2019 }, { "de", 0x201e, 0x201c, 0x201a, 0x2018 }, { "de-ch", 0x00ab, 0x00bb, 0x2039, 0x203a }, { "dje", 0x201c, 0x201d, 0x2018, 0x2019 }, { "dua", 0x00ab, 0x00bb, 0x2018, 0x2019 }, { "dyo", 0x00ab, 0x00bb, 0x201c, 0x201d }, { "dz", 0x201c, 0x201d, 0x2018, 0x2019 }, { "ebu", 0x201c, 0x201d, 0x2018, 0x2019 }, { "ee", 0x201c, 0x201d, 0x2018, 0x2019 }, { "el", 0x00ab, 0x00bb, 0x201c, 0x201d }, { "en", 0x201c, 0x201d, 0x2018, 0x2019 }, { "en-gb", 0x201c, 0x201d, 0x2018, 0x2019 }, { "es", 0x201c, 0x201d, 0x00ab, 0x00bb }, { "et", 0x201e, 0x201c, 0x201a, 0x2018 }, { "eu", 0x201c, 0x201d, 0x00ab, 0x00bb }, { "ewo", 0x00ab, 0x00bb, 0x201c, 0x201d }, { "fa", 0x00ab, 0x00bb, 0x2039, 0x203a }, { "ff", 0x201e, 0x201d, 0x201a, 0x2019 }, { "fi", 0x201d, 0x201d, 0x2019, 0x2019 }, { "fr", 0x00ab, 0x00bb, 0x00ab, 0x00bb }, { "fr-ca", 0x00ab, 0x00bb, 0x2039, 0x203a }, { "fr-ch", 0x00ab, 0x00bb, 0x2039, 0x203a }, { "gsw", 0x00ab, 0x00bb, 0x2039, 0x203a }, { "gu", 0x201c, 0x201d, 0x2018, 0x2019 }, { "guz", 0x201c, 0x201d, 0x2018, 0x2019 }, { "ha", 0x201c, 0x201d, 0x2018, 0x2019 }, { "he", 0x0022, 0x0022, 0x0027, 0x0027 }, { "hi", 0x201c, 0x201d, 0x2018, 0x2019 }, { "hr", 0x201e, 0x201c, 0x201a, 0x2018 }, { "hu", 0x201e, 0x201d, 0x00bb, 0x00ab }, { "id", 0x201c, 0x201d, 0x2018, 0x2019 }, { "ig", 0x201c, 0x201d, 0x2018, 0x2019 }, { "it", 0x00ab, 0x00bb, 0x201c, 0x201d }, { "ja", 0x300c, 0x300d, 0x300e, 0x300f }, { "jgo", 0x00ab, 0x00bb, 0x2039, 0x203a }, { "jmc", 0x201c, 0x201d, 0x2018, 0x2019 }, { "kab", 0x00ab, 0x00bb, 0x201c, 0x201d }, { "kam", 0x201c, 0x201d, 0x2018, 0x2019 }, { "kde", 0x201c, 0x201d, 0x2018, 0x2019 }, { "kea", 0x201c, 0x201d, 0x2018, 0x2019 }, { "khq", 0x201c, 0x201d, 0x2018, 0x2019 }, { "ki", 0x201c, 0x201d, 0x2018, 0x2019 }, { "kkj", 0x00ab, 0x00bb, 0x2039, 0x203a }, { "kln", 0x201c, 0x201d, 0x2018, 0x2019 }, { "km", 0x201c, 0x201d, 0x2018, 0x2019 }, { "kn", 0x201c, 0x201d, 0x2018, 0x2019 }, { "ko", 0x201c, 0x201d, 0x2018, 0x2019 }, { "ksb", 0x201c, 0x201d, 0x2018, 0x2019 }, { "ksf", 0x00ab, 0x00bb, 0x2018, 0x2019 }, { "lag", 0x201d, 0x201d, 0x2019, 0x2019 }, { "lg", 0x201c, 0x201d, 0x2018, 0x2019 }, { "ln", 0x201c, 0x201d, 0x2018, 0x2019 }, { "lo", 0x201c, 0x201d, 0x2018, 0x2019 }, { "lt", 0x201e, 0x201c, 0x201e, 0x201c }, { "lu", 0x201c, 0x201d, 0x2018, 0x2019 }, { "luo", 0x201c, 0x201d, 0x2018, 0x2019 }, { "luy", 0x201e, 0x201c, 0x201a, 0x2018 }, { "lv", 0x201c, 0x201d, 0x2018, 0x2019 }, { "mas", 0x201c, 0x201d, 0x2018, 0x2019 }, { "mer", 0x201c, 0x201d, 0x2018, 0x2019 }, { "mfe", 0x201c, 0x201d, 0x2018, 0x2019 }, { "mg", 0x00ab, 0x00bb, 0x201c, 0x201d }, { "mgo", 0x201c, 0x201d, 0x2018, 0x2019 }, { "mk", 0x201e, 0x201c, 0x201a, 0x2018 }, { "ml", 0x201c, 0x201d, 0x2018, 0x2019 }, { "mr", 0x201c, 0x201d, 0x2018, 0x2019 }, { "ms", 0x201c, 0x201d, 0x2018, 0x2019 }, { "mua", 0x00ab, 0x00bb, 0x201c, 0x201d }, { "my", 0x201c, 0x201d, 0x2018, 0x2019 }, { "naq", 0x201c, 0x201d, 0x2018, 0x2019 }, { "nb", 0x00ab, 0x00bb, 0x2018, 0x2019 }, { "nd", 0x201c, 0x201d, 0x2018, 0x2019 }, { "nl", 0x201c, 0x201d, 0x2018, 0x2019 }, { "nmg", 0x201e, 0x201d, 0x00ab, 0x00bb }, { "nn", 0x00ab, 0x00bb, 0x2018, 0x2019 }, { "nnh", 0x00ab, 0x00bb, 0x201c, 0x201d }, { "nus", 0x201c, 0x201d, 0x2018, 0x2019 }, { "nyn", 0x201c, 0x201d, 0x2018, 0x2019 }, { "pl", 0x201e, 0x201d, 0x00ab, 0x00bb }, { "pt", 0x201c, 0x201d, 0x2018, 0x2019 }, { "pt-pt", 0x00ab, 0x00bb, 0x201c, 0x201d }, { "rn", 0x201d, 0x201d, 0x2019, 0x2019 }, { "ro", 0x201e, 0x201d, 0x00ab, 0x00bb }, { "rof", 0x201c, 0x201d, 0x2018, 0x2019 }, { "ru", 0x00ab, 0x00bb, 0x201e, 0x201c }, { "rw", 0x00ab, 0x00bb, 0x2018, 0x2019 }, { "rwk", 0x201c, 0x201d, 0x2018, 0x2019 }, { "saq", 0x201c, 0x201d, 0x2018, 0x2019 }, { "sbp", 0x201c, 0x201d, 0x2018, 0x2019 }, { "seh", 0x201c, 0x201d, 0x2018, 0x2019 }, { "ses", 0x201c, 0x201d, 0x2018, 0x2019 }, { "sg", 0x00ab, 0x00bb, 0x201c, 0x201d }, { "shi", 0x00ab, 0x00bb, 0x201e, 0x201d }, { "shi-tfng", 0x00ab, 0x00bb, 0x201e, 0x201d }, { "si", 0x201c, 0x201d, 0x2018, 0x2019 }, { "sk", 0x201e, 0x201c, 0x201a, 0x2018 }, { "sl", 0x201e, 0x201c, 0x201a, 0x2018 }, { "sn", 0x201d, 0x201d, 0x2019, 0x2019 }, { "so", 0x201c, 0x201d, 0x2018, 0x2019 }, { "sq", 0x201e, 0x201c, 0x201a, 0x2018 }, { "sr", 0x201e, 0x201c, 0x201a, 0x2018 }, { "sr-latn", 0x201e, 0x201c, 0x201a, 0x2018 }, { "sv", 0x201d, 0x201d, 0x2019, 0x2019 }, { "sw", 0x201c, 0x201d, 0x2018, 0x2019 }, { "swc", 0x201c, 0x201d, 0x2018, 0x2019 }, { "ta", 0x201c, 0x201d, 0x2018, 0x2019 }, { "te", 0x201c, 0x201d, 0x2018, 0x2019 }, { "teo", 0x201c, 0x201d, 0x2018, 0x2019 }, { "th", 0x201c, 0x201d, 0x2018, 0x2019 }, { "ti-er", 0x2018, 0x2019, 0x201c, 0x201d }, { "to", 0x201c, 0x201d, 0x2018, 0x2019 }, { "tr", 0x201c, 0x201d, 0x2018, 0x2019 }, { "twq", 0x201c, 0x201d, 0x2018, 0x2019 }, { "tzm", 0x201c, 0x201d, 0x2018, 0x2019 }, { "uk", 0x00ab, 0x00bb, 0x201e, 0x201c }, { "ur", 0x201d, 0x201c, 0x2019, 0x2018 }, { "vai", 0x201c, 0x201d, 0x2018, 0x2019 }, { "vai-latn", 0x201c, 0x201d, 0x2018, 0x2019 }, { "vi", 0x201c, 0x201d, 0x2018, 0x2019 }, { "vun", 0x201c, 0x201d, 0x2018, 0x2019 }, { "xh", 0x2018, 0x2019, 0x201c, 0x201d }, { "xog", 0x201c, 0x201d, 0x2018, 0x2019 }, { "yav", 0x00ab, 0x00bb, 0x00ab, 0x00bb }, { "yo", 0x201c, 0x201d, 0x2018, 0x2019 }, { "zh", 0x201c, 0x201d, 0x2018, 0x2019 }, { "zh-hant", 0x300c, 0x300d, 0x300e, 0x300f }, { "zu", 0x201c, 0x201d, 0x2018, 0x2019 }, }; const unsigned maxLanguageLength = 8; #if !ASSERT_DISABLED // One time check that the table meets the constraints that the code below relies on. static bool didOneTimeCheck = false; if (!didOneTimeCheck) { didOneTimeCheck = true; checkNumberOfDistinctQuoteCharacters(quotationMark); checkNumberOfDistinctQuoteCharacters(apostrophe); for (unsigned i = 0; i < WTF_ARRAY_LENGTH(quoteTable); ++i) { ASSERT(strlen(quoteTable[i].language) <= maxLanguageLength); if (i) ASSERT(strcmp(quoteTable[i - 1].language, quoteTable[i].language) < 0); for (unsigned j = 0; UChar character = quoteTable[i].language[j]; ++j) ASSERT(isASCIILower(character) || character == '-'); checkNumberOfDistinctQuoteCharacters(quoteTable[i].open1); checkNumberOfDistinctQuoteCharacters(quoteTable[i].close1); checkNumberOfDistinctQuoteCharacters(quoteTable[i].open2); checkNumberOfDistinctQuoteCharacters(quoteTable[i].close2); } } #endif unsigned length = language.length(); if (!length || length > maxLanguageLength) return 0; char languageKeyBuffer[maxLanguageLength + 1]; for (unsigned i = 0; i < length; ++i) { UChar character = toASCIILower(language[i]); if (!(isASCIILower(character) || character == '-')) return 0; languageKeyBuffer[i] = static_cast<char>(character); } languageKeyBuffer[length] = 0; QuotesForLanguage languageKey = { languageKeyBuffer, 0, 0, 0, 0 }; return static_cast<const QuotesForLanguage*>(bsearch(&languageKey, quoteTable, WTF_ARRAY_LENGTH(quoteTable), sizeof(quoteTable[0]), quoteTableLanguageComparisonFunction)); }