Commit bc3c1476 authored by snej@chromium.org's avatar snej@chromium.org
Browse files

JavaScriptCore: Added variants of find/contains/add that allow a foreign key type to be used.

This will allow AtomicString-keyed maps to be queried by C string without
having to create a temporary AtomicString (see HTTPHeaderMap.)
The code for this is adapted from the equivalent in HashSet.h.

WebCore: Add convenience methods to Element and QualifiedName that take
char* instead of AtomicString, in preparation for removing the
implicit conversion between the two types (30187).
https://bugs.webkit.org/show_bug.cgi?id=31749

Reviewed by Darin Adler.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@51566 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 9c19a120
2009-12-01 Jens Alfke <snej@chromium.org>
Reviewed by Darin Adler.
Added variants of find/contains/add that allow a foreign key type to be used.
This will allow AtomicString-keyed maps to be queried by C string without
having to create a temporary AtomicString (see HTTPHeaderMap.)
The code for this is adapted from the equivalent in HashSet.h.
* wtf/HashMap.h:
(WTF::HashMap::find):
(WTF::HashMap::contains):
(WTF::HashMap::add):
* wtf/HashSet.h: Changed "method" to "function member" in a comment.
2009-12-01 Gustavo Noronha Silva <gustavo.noronha@collabora.co.uk>
Revert 51551 because it broke GTK+.
......
......@@ -83,6 +83,23 @@ namespace WTF {
MappedType take(const KeyType&); // efficient combination of get with remove
// An alternate version of find() that finds the object by hashing and comparing
// with some other type, to avoid the cost of type conversion. HashTranslator
// must have the following function members:
// static unsigned hash(const T&);
// static bool equal(const ValueType&, const T&);
template<typename T, typename HashTranslator> iterator find(const T&);
template<typename T, typename HashTranslator> const_iterator find(const T&) const;
template<typename T, typename HashTranslator> bool contains(const T&) const;
// An alternate version of add() that finds the object by hashing and comparing
// with some other type, to avoid the cost of type conversion if the object is already
// in the table. HashTranslator must have the following function members:
// static unsigned hash(const T&);
// static bool equal(const ValueType&, const T&);
// static translate(ValueType&, const T&, unsigned hashCode);
template<typename T, typename HashTranslator> pair<iterator, bool> add(const T&, const MappedType&);
private:
pair<iterator, bool> inlineAdd(const KeyType&, const MappedType&);
......@@ -107,6 +124,19 @@ namespace WTF {
}
};
template<typename ValueType, typename ValueTraits, typename T, typename Translator>
struct HashMapTranslatorAdapter {
typedef typename ValueType::first_type KeyType;
typedef typename ValueType::second_type MappedType;
static unsigned hash(const T& key) { return Translator::hash(key); }
static bool equal(const KeyType& a, const T& b) { return Translator::equal(a, b); }
static void translate(ValueType& location, const T& key, const MappedType&, unsigned hashCode)
{
Translator::translate(location.first, key, hashCode);
}
};
template<typename T, typename U, typename V, typename W, typename X>
inline void HashMap<T, U, V, W, X>::swap(HashMap& other)
{
......@@ -173,6 +203,33 @@ namespace WTF {
return m_impl.contains(key);
}
template<typename T, typename U, typename V, typename W, typename X>
template<typename TYPE, typename HashTranslator>
inline typename HashMap<T, U, V, W, X>::iterator
HashMap<T, U, V, W, X>::find(const TYPE& value)
{
typedef HashMapTranslatorAdapter<ValueType, ValueTraits, TYPE, HashTranslator> Adapter;
return m_impl.template find<TYPE, Adapter>(value);
}
template<typename T, typename U, typename V, typename W, typename X>
template<typename TYPE, typename HashTranslator>
inline typename HashMap<T, U, V, W, X>::const_iterator
HashMap<T, U, V, W, X>::find(const TYPE& value) const
{
typedef HashMapTranslatorAdapter<ValueType, ValueTraits, TYPE, HashTranslator> Adapter;
return m_impl.template find<TYPE, Adapter>(value);
}
template<typename T, typename U, typename V, typename W, typename X>
template<typename TYPE, typename HashTranslator>
inline bool
HashMap<T, U, V, W, X>::contains(const TYPE& value) const
{
typedef HashMapTranslatorAdapter<ValueType, ValueTraits, TYPE, HashTranslator> Adapter;
return m_impl.template contains<TYPE, Adapter>(value);
}
template<typename T, typename U, typename V, typename W, typename X>
inline pair<typename HashMap<T, U, V, W, X>::iterator, bool>
HashMap<T, U, V, W, X>::inlineAdd(const KeyType& key, const MappedType& mapped)
......@@ -193,6 +250,15 @@ namespace WTF {
return result;
}
template<typename T, typename U, typename V, typename W, typename X>
template<typename TYPE, typename HashTranslator>
pair<typename HashMap<T, U, V, W, X>::iterator, bool>
HashMap<T, U, V, W, X>::add(const TYPE& key, const MappedType& value)
{
typedef HashMapTranslatorAdapter<ValueType, ValueTraits, TYPE, HashTranslator> Adapter;
return m_impl.template addPassingHashCode<TYPE, MappedType, Adapter>(key, value);
}
template<typename T, typename U, typename V, typename W, typename X>
pair<typename HashMap<T, U, V, W, X>::iterator, bool>
HashMap<T, U, V, W, X>::add(const KeyType& key, const MappedType& mapped)
......
......@@ -81,7 +81,7 @@ namespace WTF {
// An alternate version of add() that finds the object by hashing and comparing
// with some other type, to avoid the cost of type conversion if the object is already
// in the table. HashTranslator must have the following methods:
// in the table. HashTranslator must have the following function members:
// static unsigned hash(const T&);
// static bool equal(const ValueType&, const T&);
// static translate(ValueType&, const T&, unsigned hashCode);
......
2009-12-01 Jens Alfke <snej@chromium.org>
Reviewed by Darin Adler.
Add convenience methods to Element and QualifiedName that take
char* instead of AtomicString, in preparation for removing the
implicit conversion between the two types (30187).
https://bugs.webkit.org/show_bug.cgi?id=31749
* dom/Element.cpp:
(WebCore::Element::setCStringAttribute): Equivalent to setAttribute.
* dom/Element.h:
* dom/QualifiedName.cpp:
(WebCore::QualifiedName::init): Shared impl of both constructors
(WebCore::QualifiedName::QualifiedName): New c'tor taking char*.
* dom/QualifiedName.h:
* platform/network/HTTPHeaderMap.cpp:
(WebCore::CaseFoldingCStringTranslator): Enables lookup by C string
(WebCore::HTTPHeaderMap::get): New variant that takes C string
(WebCore::HTTPHeaderMap::contains): New variant that takes C string
(WebCore::HTTPHeaderMap::add): New variant that takes C string
* platform/network/HTTPHeaderMap.h:
(WebCore::HTTPHeaderMap::get):
(WebCore::HTTPHeaderMap::add):
* platform/network/ResourceRequestBase.cpp:
(WebCore::ResourceRequestBase::httpHeaderField): New variant that takes C string
* platform/network/ResourceRequestBase.h:
(WebCore::ResourceRequestBase::setHTTPHeaderField): Use symbolic names for headers
* platform/network/ResourceResponseBase.cpp:
(WebCore::ResourceResponseBase::httpHeaderField): New variant that takes C string
* platform/network/ResourceResponseBase.h:
2009-12-01 Alexey Proskuryakov <ap@apple.com>
 
More Windows build fix.
......@@ -136,6 +136,12 @@ void Element::setAttribute(const QualifiedName& name, const AtomicString& value)
ExceptionCode ec;
setAttribute(name, value, ec);
}
void Element::setCStringAttribute(const QualifiedName& name, const char* cStringValue)
{
ExceptionCode ec;
setAttribute(name, AtomicString(cStringValue), ec);
}
void Element::setBooleanAttribute(const QualifiedName& name, bool b)
{
......
......@@ -167,6 +167,9 @@ public:
// convenience methods which ignore exceptions
void setAttribute(const QualifiedName&, const AtomicString& value);
void setBooleanAttribute(const QualifiedName& name, bool);
// Please don't use setCStringAttribute in performance-sensitive code;
// use a static AtomicString value instead to avoid the conversion overhead.
void setCStringAttribute(const QualifiedName&, const char* cStringValue);
virtual NamedNodeMap* attributes() const;
NamedNodeMap* attributes(bool readonly) const;
......
......@@ -51,7 +51,7 @@ struct QNameComponentsTranslator {
static QNameSet* gNameCache;
QualifiedName::QualifiedName(const AtomicString& p, const AtomicString& l, const AtomicString& n)
void QualifiedName::init(const AtomicString& p, const AtomicString& l, const AtomicString& n)
{
if (!gNameCache)
gNameCache = new QNameSet;
......@@ -62,6 +62,16 @@ QualifiedName::QualifiedName(const AtomicString& p, const AtomicString& l, const
m_impl->ref();
}
QualifiedName::QualifiedName(const AtomicString& p, const AtomicString& l, const AtomicString& n)
{
init(p, l, n);
}
QualifiedName::QualifiedName(const AtomicString& p, const char* l, const AtomicString& n)
{
init(p, AtomicString(l), n);
}
void QualifiedName::deref()
{
#ifdef QNAME_DEFAULT_CONSTRUCTOR
......
......@@ -57,6 +57,7 @@ public:
};
QualifiedName(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI);
QualifiedName(const AtomicString& prefix, const char* localName, const AtomicString& namespaceURI);
~QualifiedName() { deref(); }
#ifdef QNAME_DEFAULT_CONSTRUCTOR
QualifiedName() : m_impl(0) { }
......@@ -88,6 +89,7 @@ public:
static void init();
private:
void init(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI);
void ref() const { m_impl->ref(); }
void deref();
......
......@@ -59,5 +59,41 @@ void HTTPHeaderMap::adopt(auto_ptr<CrossThreadHTTPHeaderMapData> data)
set(header.first, header.second);
}
}
// Adapter that allows the HashMap to take C strings as keys.
struct CaseFoldingCStringTranslator {
static unsigned hash(const char* cString)
{
return CaseFoldingHash::hash(cString, strlen(cString));
}
static bool equal(const AtomicString& key, const char* cString)
{
return equalIgnoringCase(key, cString);
}
static void translate(AtomicString& location, const char* cString, unsigned /*hash*/)
{
location = AtomicString(cString);
}
};
String HTTPHeaderMap::get(const char* name) const
{
const_iterator i = find<const char*, CaseFoldingCStringTranslator>(name);
if (i == end())
return String();
return i->second;
}
bool HTTPHeaderMap::contains(const char* name) const
{
return find<const char*, CaseFoldingCStringTranslator>(name) != end();
}
pair<HTTPHeaderMap::iterator, bool> HTTPHeaderMap::add(const char* name, const String& value)
{
return HashMap<AtomicString, String, CaseFoldingHash>::add<const char*, CaseFoldingCStringTranslator>(name, value);
}
} // namespace WebCore
......@@ -45,6 +45,22 @@ namespace WebCore {
std::auto_ptr<CrossThreadHTTPHeaderMapData> copyData() const;
void adopt(std::auto_ptr<CrossThreadHTTPHeaderMapData>);
String get(const AtomicString& name) const
{
return HashMap<AtomicString, String, CaseFoldingHash>::get(name);
}
pair<iterator, bool> add(const AtomicString& name, const String& value)
{
return HashMap<AtomicString, String, CaseFoldingHash>::add(name, value);
}
// Alternate accessors that are faster than converting the char* to AtomicString first.
bool contains(const char*) const;
String get(const char*) const;
pair<iterator, bool> add(const char* name, const String& value);
};
} // namespace WebCore
......
......@@ -208,6 +208,13 @@ String ResourceRequestBase::httpHeaderField(const AtomicString& name) const
return m_httpHeaderFields.get(name);
}
String ResourceRequestBase::httpHeaderField(const char* name) const
{
updateResourceRequest();
return m_httpHeaderFields.get(name);
}
void ResourceRequestBase::setHTTPHeaderField(const AtomicString& name, const String& value)
{
updateResourceRequest();
......@@ -218,6 +225,11 @@ void ResourceRequestBase::setHTTPHeaderField(const AtomicString& name, const Str
m_platformRequestUpdated = false;
}
void ResourceRequestBase::setHTTPHeaderField(const char* name, const String& value)
{
setHTTPHeaderField(AtomicString(name), value);
}
void ResourceRequestBase::clearHTTPReferrer()
{
updateResourceRequest();
......
......@@ -79,7 +79,9 @@ namespace WebCore {
const HTTPHeaderMap& httpHeaderFields() const;
String httpHeaderField(const AtomicString& name) const;
String httpHeaderField(const char* name) const;
void setHTTPHeaderField(const AtomicString& name, const String& value);
void setHTTPHeaderField(const char* name, const String& value);
void addHTTPHeaderField(const AtomicString& name, const String& value);
void addHTTPHeaderFields(const HTTPHeaderMap& headerFields);
......
......@@ -239,6 +239,13 @@ String ResourceResponseBase::httpHeaderField(const AtomicString& name) const
return m_httpHeaderFields.get(name);
}
String ResourceResponseBase::httpHeaderField(const char* name) const
{
lazyInit();
return m_httpHeaderFields.get(name);
}
void ResourceResponseBase::setHTTPHeaderField(const AtomicString& name, const String& value)
{
lazyInit();
......
......@@ -71,6 +71,7 @@ public:
void setHTTPStatusText(const String&);
String httpHeaderField(const AtomicString& name) const;
String httpHeaderField(const char* name) const;
void setHTTPHeaderField(const AtomicString& name, const String& value);
const HTTPHeaderMap& httpHeaderFields() const;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment