Modified: trunk/Source/WebCore/editing/MarkupAccumulator.cpp (163853 => 163854)
--- trunk/Source/WebCore/editing/MarkupAccumulator.cpp 2014-02-11 02:46:04 UTC (rev 163853)
+++ trunk/Source/WebCore/editing/MarkupAccumulator.cpp 2014-02-11 02:47:49 UTC (rev 163854)
@@ -46,58 +46,73 @@
using namespace HTMLNames;
-void MarkupAccumulator::appendCharactersReplacingEntities(StringBuilder& result, const String& source, unsigned offset, unsigned length, EntityMask entityMask)
+struct EntityDescription {
+ const char* characters;
+ unsigned char length;
+ unsigned char mask;
+};
+
+static const EntityDescription entitySubstitutionList[] = {
+ { "", 0 , 0 },
+ { "&", 5 , EntityAmp },
+ { "<", 4, EntityLt },
+ { ">", 4, EntityGt },
+ { """, 6, EntityQuot },
+ { " ", 6, EntityNbsp },
+};
+
+enum EntitySubstitutionIndex {
+ EntitySubstitutionNullIndex = 0,
+ EntitySubstitutionAmpIndex = 1,
+ EntitySubstitutionLtIndex = 2,
+ EntitySubstitutionGtIndex = 3,
+ EntitySubstitutionQuotIndex = 4,
+ EntitySubstitutionNbspIndex = 5,
+};
+
+static const unsigned maximumEscapedentityCharacter = noBreakSpace;
+static const uint8_t entityMap[maximumEscapedentityCharacter + 1] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ EntitySubstitutionQuotIndex, // '"'.
+ 0, 0, 0,
+ EntitySubstitutionAmpIndex, // '&'.
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ EntitySubstitutionLtIndex, // '<'.
+ 0,
+ EntitySubstitutionGtIndex, // '>'.
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ EntitySubstitutionNbspIndex // noBreakSpace.
+};
+
+template<typename CharacterType>
+static inline void appendCharactersReplacingEntitiesInternal(StringBuilder& result, const String& source, unsigned offset, unsigned length, EntityMask entityMask)
{
- DEFINE_STATIC_LOCAL(const String, ampReference, (ASCIILiteral("&")));
- DEFINE_STATIC_LOCAL(const String, ltReference, (ASCIILiteral("<")));
- DEFINE_STATIC_LOCAL(const String, gtReference, (ASCIILiteral(">")));
- DEFINE_STATIC_LOCAL(const String, quotReference, (ASCIILiteral(""")));
- DEFINE_STATIC_LOCAL(const String, nbspReference, (ASCIILiteral(" ")));
+ const CharacterType* text = source.characters<CharacterType>() + offset;
- static const EntityDescription entityMaps[] = {
- { '&', ampReference, EntityAmp },
- { '<', ltReference, EntityLt },
- { '>', gtReference, EntityGt },
- { '"', quotReference, EntityQuot },
- { noBreakSpace, nbspReference, EntityNbsp },
- };
+ size_t positionAfterLastEntity = 0;
+ for (size_t i = 0; i < length; ++i) {
+ CharacterType character = text[i];
+ uint8_t substitution = character < WTF_ARRAY_LENGTH(entityMap) ? entityMap[character] : static_cast<uint8_t>(EntitySubstitutionNullIndex);
+ if (UNLIKELY(substitution != EntitySubstitutionNullIndex) && entitySubstitutionList[substitution].mask & entityMask) {
+ result.append(text + positionAfterLastEntity, i - positionAfterLastEntity);
+ result.append(entitySubstitutionList[substitution].characters, entitySubstitutionList[substitution].length);
+ positionAfterLastEntity = i + 1;
+ }
+ }
+ result.append(text + positionAfterLastEntity, length - positionAfterLastEntity);
+}
+void MarkupAccumulator::appendCharactersReplacingEntities(StringBuilder& result, const String& source, unsigned offset, unsigned length, EntityMask entityMask)
+{
if (!(offset + length))
return;
ASSERT(offset + length <= source.length());
- if (source.is8Bit()) {
- const LChar* text = source.characters8() + offset;
-
- size_t positionAfterLastEntity = 0;
- for (size_t i = 0; i < length; ++i) {
- for (size_t entityIndex = 0; entityIndex < WTF_ARRAY_LENGTH(entityMaps); ++entityIndex) {
- if (text[i] == entityMaps[entityIndex].entity && entityMaps[entityIndex].mask & entityMask) {
- result.append(text + positionAfterLastEntity, i - positionAfterLastEntity);
- result.append(entityMaps[entityIndex].reference);
- positionAfterLastEntity = i + 1;
- break;
- }
- }
- }
- result.append(text + positionAfterLastEntity, length - positionAfterLastEntity);
- } else {
- const UChar* text = source.characters16() + offset;
-
- size_t positionAfterLastEntity = 0;
- for (size_t i = 0; i < length; ++i) {
- for (size_t entityIndex = 0; entityIndex < WTF_ARRAY_LENGTH(entityMaps); ++entityIndex) {
- if (text[i] == entityMaps[entityIndex].entity && entityMaps[entityIndex].mask & entityMask) {
- result.append(text + positionAfterLastEntity, i - positionAfterLastEntity);
- result.append(entityMaps[entityIndex].reference);
- positionAfterLastEntity = i + 1;
- break;
- }
- }
- }
- result.append(text + positionAfterLastEntity, length - positionAfterLastEntity);
- }
+ if (source.is8Bit())
+ appendCharactersReplacingEntitiesInternal<LChar>(result, source, offset, length, entityMask);
+ else
+ appendCharactersReplacingEntitiesInternal<UChar>(result, source, offset, length, entityMask);
}
MarkupAccumulator::MarkupAccumulator(Vector<Node*>* nodes, EAbsoluteURLs resolveUrlsMethod, const Range* range, EFragmentSerialization fragmentSerialization)