--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -1486,29 +1486,28 @@ nsAccessible::GetAttributes(nsIPersisten
nsAccUtils::SetAccGroupAttrs(attributes, level, setSize, posInSet);
// Expose object attributes from ARIA attributes.
PRUint32 numAttrs = content->GetAttrCount();
for (PRUint32 count = 0; count < numAttrs; count ++) {
const nsAttrName *attr = content->GetAttrNameAt(count);
if (attr && attr->NamespaceEquals(kNameSpaceID_None)) {
nsIAtom *attrAtom = attr->Atom();
- const char *attrStr;
- attrAtom->GetUTF8String(&attrStr);
- if (PL_strncmp(attrStr, "aria-", 5))
+ nsDependentAtomString attrStr(attrAtom);
+ if (!StringBeginsWith(attrStr, NS_LITERAL_STRING("aria-")))
continue; // Not ARIA
PRUint8 attrFlags = nsAccUtils::GetAttributeCharacteristics(attrAtom);
if (attrFlags & ATTR_BYPASSOBJ)
continue; // No need to handle exposing as obj attribute here
if ((attrFlags & ATTR_VALTOKEN) &&
!nsAccUtils::HasDefinedARIAToken(content, attrAtom))
continue; // only expose token based attributes if they are defined
nsAutoString value;
if (content->GetAttr(kNameSpaceID_None, attrAtom, value)) {
- attributes->SetStringProperty(nsDependentCString(attrStr + 5), value, oldValueUnused);
+ attributes->SetStringProperty(NS_ConvertUTF16toUTF8(Substring(attrStr, 5)), value, oldValueUnused);
}
}
}
// If there is no aria-live attribute then expose default value of 'live'
// object attribute used for ARIA role of this accessible.
if (mRoleMapEntry) {
nsAutoString live;
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -1107,19 +1107,18 @@ nsDocAccessible::AttributeChangedImpl(ns
FireDelayedAccessibleEvent(sensitiveChangeEvent);
return;
}
// Check for namespaced ARIA attribute
if (aNameSpaceID == kNameSpaceID_None) {
// Check for hyphenated aria-foo property?
- const char* attributeName;
- aAttribute->GetUTF8String(&attributeName);
- if (!PL_strncmp("aria-", attributeName, 5)) {
+ if (StringBeginsWith(nsDependentAtomString(aAttribute),
+ NS_LITERAL_STRING("aria-"))) {
ARIAAttributeChanged(aContent, aAttribute);
}
}
if (aAttribute == nsAccessibilityAtoms::role ||
aAttribute == nsAccessibilityAtoms::href ||
aAttribute == nsAccessibilityAtoms::onclick) {
// Not worth the expense to ensure which namespace these are in
--- a/accessible/src/msaa/nsAccessNodeWrap.cpp
+++ b/accessible/src/msaa/nsAccessNodeWrap.cpp
@@ -244,22 +244,20 @@ STDMETHODIMP nsAccessNodeWrap::get_attri
if (numAttribs > aMaxAttribs)
numAttribs = aMaxAttribs;
*aNumAttribs = static_cast<unsigned short>(numAttribs);
for (PRUint32 index = 0; index < numAttribs; index++) {
aNameSpaceIDs[index] = 0; aAttribValues[index] = aAttribNames[index] = nsnull;
nsAutoString attributeValue;
- const char *pszAttributeName;
const nsAttrName* name = content->GetAttrNameAt(index);
aNameSpaceIDs[index] = static_cast<short>(name->NamespaceID());
- name->LocalName()->GetUTF8String(&pszAttributeName);
- aAttribNames[index] = ::SysAllocString(NS_ConvertUTF8toUTF16(pszAttributeName).get());
+ aAttribNames[index] = ::SysAllocString(name->LocalName()->GetUTF16String());
content->GetAttr(name->NamespaceID(), name->LocalName(), attributeValue);
aAttribValues[index] = ::SysAllocString(attributeValue.get());
}
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return S_OK;
}
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -1451,16 +1451,23 @@ public:
const nsAString &viewportInfo);
static nsIScriptContext* GetContextForEventHandlers(nsINode* aNode,
nsresult* aRv);
static JSContext *GetCurrentJSContext();
/**
+ * Case insensitive comparison between two strings. However it only ignores
+ * case for ASCII characters a-z.
+ */
+ static PRBool EqualsIgnoreASCIICase(const nsAString& aStr1,
+ const nsAString& aStr2);
+
+ /**
* Convert ASCII A-Z to a-z.
*/
static void ASCIIToLower(const nsAString& aSource, nsAString& aDest);
/**
* Convert ASCII a-z to A-Z.
*/
static void ASCIIToUpper(nsAString& aStr);
--- a/content/base/public/nsINodeInfo.h
+++ b/content/base/public/nsINodeInfo.h
@@ -265,19 +265,17 @@ public:
virtual PRBool NamespaceEquals(const nsAString& aNamespaceURI) const = 0;
PRBool QualifiedNameEquals(nsIAtom* aNameAtom) const
{
NS_PRECONDITION(aNameAtom, "Must have name atom");
if (!GetPrefixAtom())
return Equals(aNameAtom);
- const char* utf8;
- aNameAtom->GetUTF8String(&utf8);
- return QualifiedNameEqualsInternal(nsDependentCString(utf8));
+ return QualifiedNameEqualsInternal(nsAtomCString(aNameAtom));
}
PRBool QualifiedNameEquals(const nsACString& aQualifiedName) const
{
if (!GetPrefixAtom())
return mInner.mName->EqualsUTF8(aQualifiedName);
return QualifiedNameEqualsInternal(aQualifiedName);
--- a/content/base/src/nsAttrValue.cpp
+++ b/content/base/src/nsAttrValue.cpp
@@ -505,17 +505,17 @@ PRUint32
nsAttrValue::HashValue() const
{
switch(BaseType()) {
case eStringBase:
{
nsStringBuffer* str = static_cast<nsStringBuffer*>(GetPtr());
if (str) {
PRUint32 len = str->StorageSize()/sizeof(PRUnichar) - 1;
- return nsCRT::BufferHashCode(static_cast<PRUnichar*>(str->Data()), len);
+ return nsCRT::HashCode(static_cast<PRUnichar*>(str->Data()), len);
}
return 0;
}
case eOtherBase:
{
break;
}
@@ -771,36 +771,38 @@ nsAttrValue::Contains(nsIAtom* aValue, n
case eAtomBase:
{
nsIAtom* atom = GetAtomValue();
if (aCaseSensitive == eCaseMatters) {
return aValue == atom;
}
- const char *val1, *val2;
- aValue->GetUTF8String(&val1);
- atom->GetUTF8String(&val2);
-
- return nsCRT::strcasecmp(val1, val2) == 0;
+ // For performance reasons, don't do a full on unicode case insensitive
+ // string comparison. This is only used for quirks mode anyway.
+ return
+ nsContentUtils::EqualsIgnoreASCIICase(nsDependentAtomString(aValue),
+ nsDependentAtomString(atom));
}
default:
{
if (Type() == eAtomArray) {
nsCOMArray<nsIAtom>* array = GetAtomArrayValue();
if (aCaseSensitive == eCaseMatters) {
return array->IndexOf(aValue) >= 0;
}
- const char *val1, *val2;
- aValue->GetUTF8String(&val1);
+ nsDependentAtomString val1(aValue);
for (PRInt32 i = 0, count = array->Count(); i < count; ++i) {
- array->ObjectAt(i)->GetUTF8String(&val2);
- if (nsCRT::strcasecmp(val1, val2) == 0) {
+ // For performance reasons, don't do a full on unicode case
+ // insensitive string comparison. This is only used for quirks mode
+ // anyway.
+ if (nsContentUtils::EqualsIgnoreASCIICase(val1,
+ nsDependentAtomString(array->ObjectAt(i)))) {
return PR_TRUE;
}
}
}
}
}
return PR_FALSE;
--- a/content/base/src/nsContentSink.cpp
+++ b/content/base/src/nsContentSink.cpp
@@ -527,21 +527,19 @@ nsContentSink::ProcessHeaderData(nsIAtom
// so that it can process things like pragma: no-cache or other
// cache-control headers. Ideally this should also be the way for
// cookies to be set! But we'll worry about that in the next
// iteration
nsCOMPtr<nsIChannel> channel;
if (NS_SUCCEEDED(mParser->GetChannel(getter_AddRefs(channel)))) {
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
if (httpChannel) {
- const char* header;
- (void)aHeader->GetUTF8String(&header);
- (void)httpChannel->SetResponseHeader(nsDependentCString(header),
- NS_ConvertUTF16toUTF8(aValue),
- PR_TRUE);
+ httpChannel->SetResponseHeader(nsAtomCString(aHeader),
+ NS_ConvertUTF16toUTF8(aValue),
+ PR_TRUE);
}
}
}
return rv;
}
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -1892,20 +1892,17 @@ static inline void KeyAppendInt(PRInt32
aKey.Append(nsPrintfCString("%d", aInt));
}
static inline void KeyAppendAtom(nsIAtom* aAtom, nsACString& aKey)
{
NS_PRECONDITION(aAtom, "KeyAppendAtom: aAtom can not be null!\n");
- const char* atomString = nsnull;
- aAtom->GetUTF8String(&atomString);
-
- KeyAppendString(nsDependentCString(atomString), aKey);
+ KeyAppendString(nsAtomCString(aAtom), aKey);
}
static inline PRBool IsAutocompleteOff(nsIDOMElement* aElement)
{
nsAutoString autocomplete;
aElement->GetAttribute(NS_LITERAL_STRING("autocomplete"), autocomplete);
return autocomplete.LowerCaseEqualsLiteral("off");
}
@@ -3205,18 +3202,17 @@ nsAutoGCRoot::RemoveJSGCRoot(void* aPtr)
return NS_OK;
}
// static
PRBool
nsContentUtils::IsEventAttributeName(nsIAtom* aName, PRInt32 aType)
{
- const char* name;
- aName->GetUTF8String(&name);
+ const PRUnichar* name = aName->GetUTF16String();
if (name[0] != 'o' || name[1] != 'n')
return PR_FALSE;
EventNameMapping mapping;
return (sEventTable->Get(aName, &mapping) && mapping.mType & aType);
}
// static
@@ -4925,16 +4921,53 @@ nsContentUtils::ASCIIToUpper(nsAString&
PRUnichar c = *iter;
if (c >= 'a' && c <= 'z') {
*iter = c + ('A' - 'a');
}
++iter;
}
}
+PRBool
+nsContentUtils::EqualsIgnoreASCIICase(const nsAString& aStr1,
+ const nsAString& aStr2)
+{
+ PRUint32 len = aStr1.Length();
+ if (len != aStr2.Length()) {
+ return PR_FALSE;
+ }
+
+ const PRUnichar* str1 = aStr1.BeginReading();
+ const PRUnichar* str2 = aStr2.BeginReading();
+ const PRUnichar* end = str1 + len;
+
+ while (str1 < end) {
+ PRUnichar c1 = *str1++;
+ PRUnichar c2 = *str2++;
+
+ // First check if any bits other than the 0x0020 differs
+ if ((c1 ^ c2) & 0xffdf) {
+ return PR_FALSE;
+ }
+
+ // We know they only differ in the 0x0020 bit.
+ // Likely the two chars are the same, so check that first
+ if (c1 != c2) {
+ // They do differ, but since it's only in the 0x0020 bit, check if it's
+ // the same ascii char, but just differing in case
+ PRUnichar c1Upper = c1 & 0xffdf;
+ if (!('A' <= c1Upper && c1Upper <= 'Z')) {
+ return PR_FALSE;
+ }
+ }
+ }
+
+ return PR_TRUE;
+}
+
/* static */
void
nsAutoGCRoot::Shutdown()
{
NS_IF_RELEASE(sJSRuntimeService);
}
nsIAtom*
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -6713,19 +6713,17 @@ nsDocument::CreateElem(nsIAtom *aName, n
PRBool aDocumentDefaultType, nsIContent **aResult)
{
#ifdef DEBUG
nsAutoString qName;
if (aPrefix) {
aPrefix->ToString(qName);
qName.Append(':');
}
- const char *name;
- aName->GetUTF8String(&name);
- AppendUTF8toUTF16(name, qName);
+ qName.Append(nsAtomString(aName));
// Note: "a:b:c" is a valid name in non-namespaces XML, and
// nsDocument::CreateElement can call us with such a name and no prefix,
// which would cause an error if we just used PR_TRUE here.
PRBool nsAware = aPrefix != nsnull || aNamespaceID != GetDefaultNamespaceID();
NS_ASSERTION(NS_SUCCEEDED(nsContentUtils::CheckQName(qName, nsAware)),
"Don't pass invalid prefixes to nsDocument::CreateElem, "
"check caller.");
--- a/content/base/src/nsHTMLContentSerializer.cpp
+++ b/content/base/src/nsHTMLContentSerializer.cpp
@@ -64,18 +64,16 @@
#include "nsITextToSubURI.h"
#include "nsCRT.h"
#include "nsIParserService.h"
#include "nsContentUtils.h"
#include "nsLWBrkCIID.h"
#include "nsIScriptElement.h"
#include "nsAttrName.h"
-static const char kMozStr[] = "moz";
-
static const PRInt32 kLongLineLen = 128;
nsresult NS_NewHTMLContentSerializer(nsIContentSerializer** aSerializer)
{
nsHTMLContentSerializer* it = new nsHTMLContentSerializer();
if (!it) {
return NS_ERROR_OUT_OF_MEMORY;
}
@@ -118,20 +116,19 @@ nsHTMLContentSerializer::SerializeHTMLAt
for (PRInt32 index = count; index > 0;) {
--index;
const nsAttrName* name = aContent->GetAttrNameAt(index);
PRInt32 namespaceID = name->NamespaceID();
nsIAtom* attrName = name->LocalName();
// Filter out any attribute starting with [-|_]moz
- const char* sharedName;
- attrName->GetUTF8String(&sharedName);
- if ((('_' == *sharedName) || ('-' == *sharedName)) &&
- !nsCRT::strncmp(sharedName+1, kMozStr, PRUint32(sizeof(kMozStr)-1))) {
+ nsDependentAtomString attrNameStr(attrName);
+ if (StringBeginsWith(attrNameStr, NS_LITERAL_STRING("_moz")) ||
+ StringBeginsWith(attrNameStr, NS_LITERAL_STRING("-moz"))) {
continue;
}
aContent->GetAttr(namespaceID, attrName, valueStr);
//
// Filter out special case of <br type="_moz"> or <br _moz*>,
// used by the editor. Bug 16988. Yuck.
//
--- a/content/base/src/nsNodeInfo.cpp
+++ b/content/base/src/nsNodeInfo.cpp
@@ -252,35 +252,32 @@ nsNodeInfo::QualifiedNameEqualsInternal(
{
NS_PRECONDITION(mInner.mPrefix, "Must have prefix");
nsACString::const_iterator start;
aQualifiedName.BeginReading(start);
nsACString::const_iterator colon(start);
- const char* prefix;
- mInner.mPrefix->GetUTF8String(&prefix);
+ nsAtomCString prefix(mInner.mPrefix);
- PRUint32 len = strlen(prefix);
-
- if (len >= aQualifiedName.Length()) {
+ if (prefix.Length() >= aQualifiedName.Length()) {
return PR_FALSE;
}
- colon.advance(len);
+ colon.advance(prefix.Length());
// If the character at the prefix length index is not a colon,
// aQualifiedName is not equal to this string.
if (*colon != ':') {
return PR_FALSE;
}
// Compare the prefix to the string from the start to the colon
- if (!mInner.mPrefix->EqualsUTF8(Substring(start, colon)))
+ if (!prefix.Equals(Substring(start, colon)))
return PR_FALSE;
++colon; // Skip the ':'
nsACString::const_iterator end;
aQualifiedName.EndReading(end);
// Compare the local name to the string between the colon and the
--- a/content/base/src/nsXHTMLContentSerializer.cpp
+++ b/content/base/src/nsXHTMLContentSerializer.cpp
@@ -341,20 +341,19 @@ nsXHTMLContentSerializer::SerializeAttri
}
const nsAttrName* name = aContent->GetAttrNameAt(index);
PRInt32 namespaceID = name->NamespaceID();
nsIAtom* attrName = name->LocalName();
nsIAtom* attrPrefix = name->GetPrefix();
// Filter out any attribute starting with [-|_]moz
- const char* sharedName;
- attrName->GetUTF8String(&sharedName);
- if ((('_' == *sharedName) || ('-' == *sharedName)) &&
- !nsCRT::strncmp(sharedName+1, kMozStr, PRUint32(sizeof(kMozStr)-1))) {
+ nsDependentAtomString attrNameStr(attrName);
+ if (StringBeginsWith(attrNameStr, NS_LITERAL_STRING("_moz")) ||
+ StringBeginsWith(attrNameStr, NS_LITERAL_STRING("-moz"))) {
continue;
}
if (attrPrefix) {
attrPrefix->ToString(prefixStr);
}
else {
prefixStr.Truncate();
--- a/content/html/document/src/nsHTMLContentSink.cpp
+++ b/content/html/document/src/nsHTMLContentSink.cpp
@@ -937,23 +937,20 @@ SinkContext::CloseContainer(const nsHTML
if (mNotifyLevel >= mStackPos) {
// Check to see if new content has been added after our last
// notification
if (mStack[mStackPos].mNumFlushed < content->GetChildCount()) {
#ifdef NS_DEBUG
{
// Tracing code
- const char *tagStr;
- mStack[mStackPos].mContent->Tag()->GetUTF8String(&tagStr);
-
SINK_TRACE(gSinkLogModuleInfo, SINK_TRACE_REFLOW,
("SinkContext::CloseContainer: reflow on notifyImmediate "
"tag=%s newIndex=%d stackPos=%d",
- tagStr,
+ nsAtomCString(mStack[mStackPos].mContent->Tag()).get(),
mStack[mStackPos].mNumFlushed, mStackPos));
}
#endif
mSink->NotifyAppend(content, mStack[mStackPos].mNumFlushed);
mStack[mStackPos].mNumFlushed = content->GetChildCount();
}
// Indicate that notification has now happened at this level
@@ -1348,22 +1345,20 @@ SinkContext::FlushTags()
while (stackPos < mStackPos) {
content = mStack[stackPos].mContent;
childCount = content->GetChildCount();
if (!flushed && (mStack[stackPos].mNumFlushed < childCount)) {
#ifdef NS_DEBUG
{
// Tracing code
- const char* tagStr;
- mStack[stackPos].mContent->Tag()->GetUTF8String(&tagStr);
-
SINK_TRACE(gSinkLogModuleInfo, SINK_TRACE_REFLOW,
("SinkContext::FlushTags: tag=%s from newindex=%d at "
- "stackPos=%d", tagStr,
+ "stackPos=%d",
+ nsAtomCString(mStack[stackPos].mContent->Tag()).get(),
mStack[stackPos].mNumFlushed, stackPos));
}
#endif
if (mStack[stackPos].mInsertionPoint != -1) {
// We might have popped the child off our stack already
// but not notified on it yet, which is why we have to get it
// directly from its parent node.
--- a/content/smil/nsSMILCompositor.cpp
+++ b/content/smil/nsSMILCompositor.cpp
@@ -46,20 +46,18 @@ nsSMILCompositor::KeyEquals(KeyTypePoint
{
return aKey && aKey->Equals(mKey);
}
/*static*/ PLDHashNumber
nsSMILCompositor::HashKey(KeyTypePointer aKey)
{
// Combine the 3 values into one numeric value, which will be hashed
- const char *attrName = nsnull;
- aKey->mAttributeName->GetUTF8String(&attrName);
- return NS_PTR_TO_UINT32(aKey->mElement.get()) +
- HashString(attrName) +
+ return NS_PTR_TO_UINT32(aKey->mElement.get()) >> 4 +
+ NS_PTR_TO_INT32(aKey->mAttributeName.get()) +
(aKey->mIsCSS ? 1 : 0);
}
// Cycle-collection support
void
nsSMILCompositor::Traverse(nsCycleCollectionTraversalCallback* aCallback)
{
if (!mKey.mElement)
--- a/content/xslt/src/base/txStringUtils.h
+++ b/content/xslt/src/base/txStringUtils.h
@@ -44,20 +44,17 @@
#include "nsIAtom.h"
/**
* Check equality between a string and an atom containing ASCII.
*/
inline PRBool
TX_StringEqualsAtom(const nsASingleFragmentString& aString, nsIAtom* aAtom)
{
- const char* ASCIIAtom;
- aAtom->GetUTF8String(&ASCIIAtom);
-
- return aString.EqualsASCII(ASCIIAtom);
+ return aAtom->Equals(aString);
}
#ifndef TX_EXE
#include "nsUnicharUtils.h"
typedef nsCaseInsensitiveStringComparator txCaseInsensitiveStringComparator;
#define TX_ToLowerCase ToLowerCase
--- a/content/xslt/src/xpath/txXPCOMExtensionFunction.cpp
+++ b/content/xslt/src/xpath/txXPCOMExtensionFunction.cpp
@@ -207,20 +207,19 @@ LookupFunction(const char *aContractID,
NS_ENSURE_SUCCESS(rv, rv);
txInterfacesArrayHolder holder(iidArray, iidCount);
// Remove any minus signs and uppercase the following letter (so
// foo-bar becomes fooBar). Note that if there are any names that already
// have uppercase letters they might cause false matches (both fooBar and
// foo-bar matching fooBar).
- const char *name;
- aName->GetUTF8String(&name);
+ const PRUnichar *name = aName->GetUTF16String();
nsCAutoString methodName;
- char letter;
+ PRUnichar letter;
PRBool upperNext = PR_FALSE;
while ((letter = *name)) {
if (letter == '-') {
upperNext = PR_TRUE;
}
else {
methodName.Append(upperNext ? nsCRT::ToUpper(letter) : letter);
upperNext = PR_FALSE;
--- a/content/xul/document/src/nsXULDocument.cpp
+++ b/content/xul/document/src/nsXULDocument.cpp
@@ -1403,30 +1403,27 @@ nsXULDocument::Persist(nsIContent* aElem
if (NS_FAILED(rv)) return rv;
// No ID, so nothing to persist.
if (! element)
return NS_OK;
// Ick. Construct a property from the attribute. Punt on
// namespaces for now.
- const char* attrstr;
- rv = aAttribute->GetUTF8String(&attrstr);
- if (NS_FAILED(rv)) return rv;
-
// Don't bother with unreasonable attributes. We clamp long values,
// but truncating attribute names turns it into a different attribute
// so there's no point in persisting anything at all
- if (!attrstr || strlen(attrstr) > kMaxAttrNameLength) {
+ nsAtomCString attrstr(aAttribute);
+ if (attrstr.Length() > kMaxAttrNameLength) {
NS_WARNING("Can't persist, Attribute name too long");
return NS_ERROR_ILLEGAL_VALUE;
}
nsCOMPtr<nsIRDFResource> attr;
- rv = gRDFService->GetResource(nsDependentCString(attrstr),
+ rv = gRDFService->GetResource(attrstr,
getter_AddRefs(attr));
if (NS_FAILED(rv)) return rv;
// Turn the value into a literal
nsAutoString valuestr;
aElement->GetAttr(kNameSpaceID_None, aAttribute, valuestr);
// prevent over-long attributes that choke the parser (bug 319846)
--- a/content/xul/templates/src/nsXULContentBuilder.cpp
+++ b/content/xul/templates/src/nsXULContentBuilder.cpp
@@ -478,27 +478,24 @@ nsXULContentBuilder::BuildContentFromTem
nsresult rv;
#ifdef PR_LOGGING
if (PR_LOG_TEST(gXULTemplateLog, PR_LOG_DEBUG)) {
PR_LOG(gXULTemplateLog, PR_LOG_ALWAYS,
("nsXULContentBuilder::BuildContentFromTemplate (is unique: %d)",
aIsUnique));
- const char *tmpln, *resn, *realn;
- aTemplateNode->Tag()->GetUTF8String(&tmpln);
- aResourceNode->Tag()->GetUTF8String(&resn);
- aRealNode->Tag()->GetUTF8String(&realn);
-
nsAutoString id;
aChild->GetId(id);
PR_LOG(gXULTemplateLog, PR_LOG_ALWAYS,
("Tags: [Template: %s Resource: %s Real: %s] for id %s",
- tmpln, resn, realn, NS_ConvertUTF16toUTF8(id).get()));
+ nsAtomCString(aTemplateNode->Tag()).get(),
+ nsAtomCString(aResourceNode->Tag()).get(),
+ nsAtomCString(aRealNode->Tag()).get(), NS_ConvertUTF16toUTF8(id).get()));
}
#endif
// Iterate through all of the template children, constructing
// "real" content model nodes for each "template" child.
PRUint32 count = aTemplateNode->GetChildCount();
for (PRUint32 kid = 0; kid < count; kid++) {
@@ -557,21 +554,19 @@ nsXULContentBuilder::BuildContentFromTem
isUnique = PR_FALSE;
}
}
nsIAtom *tag = tmplKid->Tag();
#ifdef PR_LOGGING
if (PR_LOG_TEST(gXULTemplateLog, PR_LOG_DEBUG)) {
- const char *tagname;
- tag->GetUTF8String(&tagname);
PR_LOG(gXULTemplateLog, PR_LOG_DEBUG,
("xultemplate[%p] building %s %s %s",
- this, tagname,
+ this, nsAtomCString(tag).get(),
(isGenerationElement ? "[resource]" : ""),
(isUnique ? "[unique]" : "")));
}
#endif
// Set to PR_TRUE if the child we're trying to create now
// already existed in the content model.
PRBool realKidAlreadyExisted = PR_FALSE;
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -1922,37 +1922,35 @@ nsJSContext::ExecuteScript(void *aScript
// ScriptEvaluated needs to come after we pop the stack
ScriptEvaluated(PR_TRUE);
return rv;
}
-static inline const char *
-AtomToEventHandlerName(nsIAtom *aName)
+#ifdef DEBUG
+PRBool
+AtomIsEventHandlerName(nsIAtom *aName)
{
- const char *name;
-
- aName->GetUTF8String(&name);
-
-#ifdef DEBUG
- const char *cp;
- char c;
+ const PRUnichar *name = aName->GetUTF16String();
+
+ const PRUnichar *cp;
+ PRUnichar c;
for (cp = name; *cp != '\0'; ++cp)
{
c = *cp;
- NS_ASSERTION (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z'),
- "non-ASCII non-alphabetic event handler name");
+ if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z'))
+ return PR_FALSE;
}
+
+ return PR_TRUE;
+}
#endif
- return name;
-}
-
// Helper function to find the JSObject associated with a (presumably DOM)
// interface.
nsresult
nsJSContext::JSObjectFromInterface(nsISupports* aTarget, void *aScope, JSObject **aRet)
{
// It is legal to specify a null target.
if (!aTarget) {
*aRet = nsnull;
@@ -1987,49 +1985,48 @@ nsJSContext::CompileEventHandler(nsIAtom
const char** aArgNames,
const nsAString& aBody,
const char *aURL, PRUint32 aLineNo,
PRUint32 aVersion,
nsScriptObjectHolder &aHandler)
{
NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_NOT_INITIALIZED);
+ NS_PRECONDITION(AtomIsEventHandlerName(aName), "Bad event name");
NS_PRECONDITION(!::JS_IsExceptionPending(mContext),
"Why are we being called with a pending exception?");
if (!sSecurityManager) {
NS_ERROR("Huh, we need a script security manager to compile "
"an event handler!");
return NS_ERROR_UNEXPECTED;
}
// Don't compile if aVersion is unknown. Since the caller is responsible for
// parsing the version strings, we just check it isn't JSVERSION_UNKNOWN.
if ((JSVersion)aVersion == JSVERSION_UNKNOWN) {
return NS_ERROR_ILLEGAL_VALUE;
}
- const char *charName = AtomToEventHandlerName(aName);
-
#ifdef DEBUG
JSContext* top = nsContentUtils::GetCurrentJSContext();
NS_ASSERTION(mContext == top, "Context not properly pushed!");
#endif
// Event handlers are always shared, and must be bound before use.
// Therefore we never bother compiling with principals.
// (that probably means we should avoid JS_CompileUCFunctionForPrincipals!)
JSAutoRequest ar(mContext);
nsJSVersionSetter setVersion(mContext, aVersion);
JSFunction* fun =
::JS_CompileUCFunctionForPrincipals(mContext,
nsnull, nsnull,
- charName, aArgCount, aArgNames,
+ nsAtomCString(aName).get(), aArgCount, aArgNames,
(jschar*)PromiseFlatString(aBody).get(),
aBody.Length(),
aURL, aLineNo);
if (!fun) {
ReportPendingException();
return NS_ERROR_ILLEGAL_VALUE;
}
@@ -2201,17 +2198,17 @@ nsJSContext::CallEventHandler(nsISupport
nsresult
nsJSContext::BindCompiledEventHandler(nsISupports* aTarget, void *aScope,
nsIAtom *aName,
void *aHandler)
{
NS_ENSURE_ARG(aHandler);
NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_NOT_INITIALIZED);
- const char *charName = AtomToEventHandlerName(aName);
+ NS_PRECONDITION(AtomIsEventHandlerName(aName), "Bad event name");
nsresult rv;
// Get the jsobject associated with this target
JSObject *target = nsnull;
nsAutoGCRoot root(&target, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = JSObjectFromInterface(aTarget, aScope, &target);
NS_ENSURE_SUCCESS(rv, rv);
@@ -2235,17 +2232,17 @@ nsJSContext::BindCompiledEventHandler(ns
if (funobj) { // && ::JS_GetParent(mContext, funobj) != target) {
funobj = ::JS_CloneFunctionObject(mContext, funobj, target);
if (!funobj)
rv = NS_ERROR_OUT_OF_MEMORY;
}
if (NS_SUCCEEDED(rv) &&
// Make sure the flags here match those in nsEventReceiverSH::NewResolve
- !::JS_DefineProperty(mContext, target, charName,
+ !::JS_DefineProperty(mContext, target, nsAtomCString(aName).get(),
OBJECT_TO_JSVAL(funobj), nsnull, nsnull,
JSPROP_ENUMERATE | JSPROP_PERMANENT)) {
ReportPendingException();
rv = NS_ERROR_FAILURE;
}
// XXXmarkh - ideally we should assert that the wrapped native is now
// "long lived" - how to do that?
@@ -2257,29 +2254,29 @@ nsJSContext::BindCompiledEventHandler(ns
return rv;
}
nsresult
nsJSContext::GetBoundEventHandler(nsISupports* aTarget, void *aScope,
nsIAtom* aName,
nsScriptObjectHolder &aHandler)
{
+ NS_PRECONDITION(AtomIsEventHandlerName(aName), "Bad event name");
+
nsresult rv;
JSObject *obj = nsnull;
nsAutoGCRoot root(&obj, &rv);
NS_ENSURE_SUCCESS(rv, rv);
JSAutoRequest ar(mContext);
rv = JSObjectFromInterface(aTarget, aScope, &obj);
NS_ENSURE_SUCCESS(rv, rv);
- const char *charName = AtomToEventHandlerName(aName);
-
jsval funval;
if (!JS_LookupProperty(mContext, obj,
- charName, &funval))
+ nsAtomCString(aName).get(), &funval))
return NS_ERROR_FAILURE;
if (JS_TypeOfValue(mContext, funval) != JSTYPE_FUNCTION) {
NS_WARNING("Event handler object not a function");
aHandler.drop();
return NS_OK;
}
NS_ASSERTION(aHandler.getScriptTypeID()==JAVASCRIPT,
--- a/gfx/thebes/src/gfxWindowsFonts.cpp
+++ b/gfx/thebes/src/gfxWindowsFonts.cpp
@@ -1855,19 +1855,17 @@ gfxWindowsFontGroup::WhichPrefFontSuppor
nsAutoTArray<nsRefPtr<gfxFontEntry>, 15> fonts;
this->GetCJKPrefFonts(fonts);
selectedFont = WhichFontSupportsChar(fonts, aCh);
} else {
nsIAtom *langGroup = LangGroupFromUnicodeRange(unicodeRange);
if (langGroup) {
#ifdef PR_LOGGING
- const char *langGroupStr;
- langGroup->GetUTF8String(&langGroupStr);
- PR_LOG(gFontLog, PR_LOG_DEBUG, (" - Trying to find fonts for: %s", langGroupStr));
+ PR_LOG(gFontLog, PR_LOG_DEBUG, (" - Trying to find fonts for: %s", nsAtomCString(langGroup).get()));
#endif
nsAutoTArray<nsRefPtr<gfxFontEntry>, 5> fonts;
this->GetPrefFonts(langGroup, fonts);
selectedFont = WhichFontSupportsChar(fonts, aCh);
}
}
}
}
--- a/gfx/thebes/test/gfxFontSelectionTests.h
+++ b/gfx/thebes/test/gfxFontSelectionTests.h
@@ -104,25 +104,25 @@ SetupTests()
{
TestEntry *t;
/* some common styles */
gfxFontStyle style_western_normal_16 (FONT_STYLE_NORMAL,
NS_FONT_STRETCH_NORMAL,
400,
16.0,
- NS_NewPermanentAtom(NS_LITERAL_CSTRING("en")),
+ NS_NewPermanentAtom(NS_LITERAL_STRING("en")),
0.0,
PR_FALSE, PR_FALSE, PR_FALSE);
gfxFontStyle style_western_bold_16 (FONT_STYLE_NORMAL,
NS_FONT_STRETCH_NORMAL,
700,
16.0,
- NS_NewPermanentAtom(NS_LITERAL_CSTRING("en")),
+ NS_NewPermanentAtom(NS_LITERAL_STRING("en")),
0.0,
PR_FALSE, PR_FALSE, PR_FALSE);
/* Test 0 */
t = AddTest ("sans-serif",
style_western_normal_16,
S_ASCII,
"ABCD");
--- a/gfx/thebes/test/gfxTextRunPerfTest.cpp
+++ b/gfx/thebes/test/gfxTextRunPerfTest.cpp
@@ -88,17 +88,17 @@ const char* lastFamilies = nsnull;
void
RunTest (TestEntry *test, gfxContext *ctx) {
if (!lastFamilies || strcmp(lastFamilies, test->mFamilies)) {
gfxFontStyle style_western_normal_16 (FONT_STYLE_NORMAL,
NS_FONT_STRETCH_NORMAL,
400,
16.0,
- NS_NewPermanentAtom(NS_LITERAL_CSTRING("en")),
+ NS_NewPermanentAtom(NS_LITERAL_STRING("en")),
0.0,
PR_FALSE, PR_FALSE, PR_FALSE);
fontGroup = gfxPlatform::GetPlatform()->CreateFontGroup(NS_ConvertUTF8toUTF16(test->mFamilies), &style_western_normal_16, nsnull);
}
nsAutoPtr<gfxTextRun> textRun;
PRUint32 i;
--- a/gfx/thebes/test/gfxWordCacheTest.cpp
+++ b/gfx/thebes/test/gfxWordCacheTest.cpp
@@ -154,17 +154,17 @@ main (int argc, char **argv) {
gTextRuns = new FrameTextRunCache();
nsRefPtr<gfxContext> ctx = MakeContext();
{
gfxFontStyle style (FONT_STYLE_NORMAL,
NS_FONT_STRETCH_NORMAL,
139,
10.0,
- NS_NewPermanentAtom(NS_LITERAL_CSTRING("en")),
+ NS_NewPermanentAtom(NS_LITERAL_STRING("en")),
0.0,
PR_FALSE, PR_FALSE, PR_FALSE);
nsRefPtr<gfxFontGroup> fontGroup =
gfxPlatform::GetPlatform()->CreateFontGroup(NS_LITERAL_STRING("Geneva, MS Sans Serif, Helvetica,serif"), &style, nsnull);
gfxTextRunFactory::Parameters params = {
ctx, nsnull, nsnull, nsnull, 0, 60
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -426,23 +426,29 @@ nsPresContext::GetFontPreferences()
font.size-adjust.[generic].[langGroup] = "float" - settable by the user
font.minimum-size.[langGroup] = integer - settable by the user
*/
mDefaultVariableFont.size = CSSPixelsToAppUnits(16);
mDefaultFixedFont.size = CSSPixelsToAppUnits(13);
// the font prefs are based on langGroup, not actual language
- const char *langGroup = "x-western"; // Assume x-western is safe...
+ nsCAutoString langGroup;
if (mLanguage && mLangService) {
nsresult rv;
nsIAtom *group = mLangService->GetLanguageGroup(mLanguage, &rv);
if (NS_SUCCEEDED(rv) && group) {
- group->GetUTF8String(&langGroup);
+ group->ToUTF8String(langGroup);
}
+ else {
+ langGroup.AssignLiteral("x-western"); // Assume x-western is safe...
+ }
+ }
+ else {
+ langGroup.AssignLiteral("x-western"); // Assume x-western is safe...
}
nsCAutoString pref;
// get the current applicable font-size unit
enum {eUnit_unknown = -1, eUnit_px, eUnit_pt};
PRInt32 unit = eUnit_px;
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -6729,21 +6729,23 @@ nsFrame::GetBoxName(nsAutoString& aName)
}
#endif
#ifdef NS_DEBUG
static void
GetTagName(nsFrame* aFrame, nsIContent* aContent, PRIntn aResultSize,
char* aResult)
{
- const char *nameStr = "";
if (aContent) {
- aContent->Tag()->GetUTF8String(&nameStr);
- }
- PR_snprintf(aResult, aResultSize, "%s@%p", nameStr, aFrame);
+ PR_snprintf(aResult, aResultSize, "%s@%p",
+ nsAtomCString(aContent->Tag()).get(), aFrame);
+ }
+ else {
+ PR_snprintf(aResult, aResultSize, "@%p", aFrame);
+ }
}
void
nsFrame::Trace(const char* aMethod, PRBool aEnter)
{
if (NS_FRAME_LOG_TEST(gLogModule, NS_FRAME_TRACE_CALLS)) {
char tagbuf[40];
GetTagName(this, mContent, sizeof(tagbuf), tagbuf);
--- a/layout/generic/nsSelection.cpp
+++ b/layout/generic/nsSelection.cpp
@@ -4876,19 +4876,18 @@ nsTypedSelection::Collapse(nsINode* aPar
#ifdef DEBUG_SELECTION
if (aParentNode)
{
nsCOMPtr<nsIContent>content;
content = do_QueryInterface(aParentNode);
if (!content)
return NS_ERROR_FAILURE;
- const char *tagString;
- content->Tag()->GetUTF8String(&tagString);
- printf ("Sel. Collapse to %p %s %d\n", content.get(), tagString, aOffset);
+ printf ("Sel. Collapse to %p %s %d\n", content.get(),
+ nsAtomCString(content->Tag()).get(), aOffset);
}
else {
printf ("Sel. Collapse set to null parent.\n");
}
#endif
result = AddItem(range);
@@ -5269,19 +5268,18 @@ nsTypedSelection::Extend(nsINode* aParen
#endif
SetDirection(dir);
#ifdef DEBUG_SELECTION
if (aParentNode)
{
nsCOMPtr<nsIContent>content;
content = do_QueryInterface(aParentNode);
- const char *tagString;
- content->Tag()->GetUTF8String(&tagString);
- printf ("Sel. Extend to %p %s %d\n", content.get(), tagString, aOffset);
+ printf ("Sel. Extend to %p %s %d\n", content.get(),
+ nsAtomCString(content->Tag()).get(), aOffset);
}
else {
printf ("Sel. Extend set to null parent.\n");
}
#endif
return mFrameSelection->NotifySelectionListeners(GetType());
}
--- a/layout/generic/nsTextFrameThebes.cpp
+++ b/layout/generic/nsTextFrameThebes.cpp
@@ -2159,20 +2159,20 @@ static PRInt32 FindChar(const nsTextFrag
}
static PRBool IsChineseOrJapanese(nsIFrame* aFrame)
{
nsIAtom* language = aFrame->GetStyleVisibility()->mLanguage;
if (!language) {
return PR_FALSE;
}
- const char *lang;
- language->GetUTF8String(&lang);
- return (!strncmp(lang, "ja", 2) || !strncmp(lang, "zh", 2)) &&
- (lang[2] == '\0' || lang[2] == '-');
+ const PRUnichar *lang = language->GetUTF16String();
+ return (!nsCRT::strncmp(lang, NS_LITERAL_STRING("ja").get(), 2) ||
+ !nsCRT::strncmp(lang, NS_LITERAL_STRING("zh").get(), 2)) &&
+ (language->GetLength() == 2 || lang[2] == '-');
}
#ifdef DEBUG
static PRBool IsInBounds(const gfxSkipCharsIterator& aStart, PRInt32 aContentLength,
PRUint32 aOffset, PRUint32 aLength) {
if (aStart.GetSkippedOffset() > aOffset)
return PR_FALSE;
if (aContentLength == PR_INT32_MAX)
--- a/layout/style/nsCSSAnonBoxes.cpp
+++ b/layout/style/nsCSSAnonBoxes.cpp
@@ -73,14 +73,12 @@ PRBool nsCSSAnonBoxes::IsAnonBox(nsIAtom
return nsAtomListUtils::IsMember(aAtom, CSSAnonBoxes_info,
NS_ARRAY_LENGTH(CSSAnonBoxes_info));
}
#ifdef MOZ_XUL
/* static */ PRBool
nsCSSAnonBoxes::IsTreePseudoElement(nsIAtom* aPseudo)
{
- const char* str;
- aPseudo->GetUTF8String(&str);
- static const char moz_tree[] = ":-moz-tree-";
- return nsCRT::strncmp(str, moz_tree, PRInt32(sizeof(moz_tree)-1)) == 0;
+ return StringBeginsWith(nsDependentAtomString(aPseudo),
+ NS_LITERAL_STRING(":-moz-tree-"));
}
#endif
--- a/layout/style/nsCSSRuleProcessor.cpp
+++ b/layout/style/nsCSSRuleProcessor.cpp
@@ -191,21 +191,23 @@ RuleHash_CIMatchEntry(PLDHashTable *tabl
(key));
// Use our extra |getKey| callback to avoid code duplication.
nsIAtom *entry_atom = ToLocalOps(table->ops)->getKey(table, hdr);
// Check for case-sensitive match first.
if (match_atom == entry_atom)
return PR_TRUE;
- const char *match_str, *entry_str;
- match_atom->GetUTF8String(&match_str);
- entry_atom->GetUTF8String(&entry_str);
+ // Use EqualsIgnoreASCIICase instead of full on unicode case conversion
+ // in order to save on performance. This is only used in quirks mode
+ // anyway.
- return (nsCRT::strcasecmp(entry_str, match_str) == 0);
+ return
+ nsContentUtils::EqualsIgnoreASCIICase(nsDependentAtomString(entry_atom),
+ nsDependentAtomString(match_atom));
}
static PRBool
RuleHash_CSMatchEntry(PLDHashTable *table, const PLDHashEntryHdr *hdr,
const void *key)
{
nsIAtom *match_atom = const_cast<nsIAtom*>(static_cast<const nsIAtom*>
(key));
@@ -1829,23 +1831,23 @@ static PRBool SelectorMatches(RuleProces
if (isCaseSensitive) {
do {
if (IDList->mAtom != data.mContentID) {
return PR_FALSE;
}
IDList = IDList->mNext;
} while (IDList);
} else {
- const char* id1Str;
- data.mContentID->GetUTF8String(&id1Str);
- nsDependentCString id1(id1Str);
+ // Use EqualsIgnoreASCIICase instead of full on unicode case conversion
+ // in order to save on performance. This is only used in quirks mode
+ // anyway.
+ nsDependentAtomString id1Str(data.mContentID);
do {
- const char* id2Str;
- IDList->mAtom->GetUTF8String(&id2Str);
- if (!id1.Equals(id2Str, nsCaseInsensitiveCStringComparator())) {
+ if (!nsContentUtils::EqualsIgnoreASCIICase(id1Str,
+ nsDependentAtomString(IDList->mAtom))) {
return PR_FALSE;
}
IDList = IDList->mNext;
} while (IDList);
}
} else {
// Element has no id but we have an id selector
return PR_FALSE;
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -4289,20 +4289,19 @@ nsComputedDOMStyle::GetTransitionPropert
}
nsCSSProperty cssprop = transition->GetProperty();
if (cssprop == eCSSPropertyExtra_all_properties)
property->SetIdent(eCSSKeyword_all);
else if (cssprop == eCSSPropertyExtra_no_properties)
property->SetIdent(eCSSKeyword_none);
else if (cssprop == eCSSProperty_UNKNOWN)
{
- const char *str;
- transition->GetUnknownProperty()->GetUTF8String(&str);
nsAutoString escaped;
- nsStyleUtil::AppendEscapedCSSIdent(NS_ConvertUTF8toUTF16(str), escaped);
+ nsStyleUtil::AppendEscapedCSSIdent(
+ nsDependentAtomString(transition->GetUnknownProperty()), escaped);
property->SetString(escaped); // really want SetIdent
}
else
property->SetString(nsCSSProps::GetStringValue(cssprop));
} while (++i < display->mTransitionPropertyCount);
return CallQueryInterface(valueList, aValue);
}
--- a/parser/html/nsHtml5Atom.cpp
+++ b/parser/html/nsHtml5Atom.cpp
@@ -77,19 +77,26 @@ nsHtml5Atom::ToString(nsAString& aReturn
NS_IMETHODIMP
nsHtml5Atom::ToUTF8String(nsACString& aReturn)
{
NS_NOTREACHED("Should not attempt to convert to an UTF-8 string.");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
-nsHtml5Atom::GetUTF8String(const char **aReturn)
+nsHtml5Atom::GetUTF16String(const PRUnichar **aReturn)
{
- NS_NOTREACHED("Should not attempt to get a UTF-8 string from nsHtml5Atom");
+ NS_NOTREACHED("Should not attempt to get a UTF-16 string from nsHtml5Atom");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP_(PRUint32)
+nsHtml5Atom::GetLength()
+{
+ NS_NOTREACHED("Should not attempt to get a length from nsHtml5Atom");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP_(PRBool)
nsHtml5Atom::IsStaticAtom()
{
return PR_FALSE;
}
--- a/parser/htmlparser/src/nsHTMLTags.cpp
+++ b/parser/htmlparser/src/nsHTMLTags.cpp
@@ -363,31 +363,31 @@ nsHTMLTags::AddRefTable(void)
NS_INT32_TO_PTR(i + 1));
PL_HashTableAdd(gTagAtomTable, sTagAtomTable[i],
NS_INT32_TO_PTR(i + 1));
}
-#ifdef DEBUG
+#if defined(DEBUG) && defined(NS_STATIC_ATOM_USE_WIDE_STRINGS)
{
// let's verify that all names in the the table are lowercase...
for (i = 0; i < NS_HTML_TAG_MAX; ++i) {
- nsCAutoString temp1((char*)sTagAtoms_info[i].mStringBuffer->Data());
- nsCAutoString temp2((char*)sTagAtoms_info[i].mStringBuffer->Data());
+ nsAutoString temp1((PRUnichar*)sTagAtoms_info[i].mStringBuffer->Data());
+ nsAutoString temp2((PRUnichar*)sTagAtoms_info[i].mStringBuffer->Data());
ToLowerCase(temp1);
NS_ASSERTION(temp1.Equals(temp2), "upper case char in table");
}
// let's verify that all names in the unicode strings above are
// correct.
for (i = 0; i < NS_HTML_TAG_MAX; ++i) {
nsAutoString temp1(sTagUnicodeTable[i]);
- nsAutoString temp2; temp2.AssignWithConversion((char*)sTagAtoms_info[i].mStringBuffer->Data());
+ nsAutoString temp2((PRUnichar*)sTagAtoms_info[i].mStringBuffer->Data());
NS_ASSERTION(temp1.Equals(temp2), "Bad unicode tag name!");
}
// let's verify that NS_HTMLTAG_NAME_MAX_LENGTH is correct
PRUint32 maxTagNameLength = 0;
for (i = 0; i < NS_HTML_TAG_MAX; ++i) {
PRUint32 len = nsCRT::strlen(sTagUnicodeTable[i]);
maxTagNameLength = NS_MAX(len, maxTagNameLength);
--- a/rdf/base/src/nsRDFContentSink.cpp
+++ b/rdf/base/src/nsRDFContentSink.cpp
@@ -1021,21 +1021,18 @@ RDFContentSinkImpl::AddProperties(const
if (localName == kParseTypeAtom) {
if (nameSpaceURI.IsEmpty() ||
nameSpaceURI.EqualsLiteral(RDF_NAMESPACE_URI) ||
nameSpaceURI.EqualsLiteral(NC_NAMESPACE_URI)) {
continue;
}
}
- const char* attrName;
- localName->GetUTF8String(&attrName);
-
NS_ConvertUTF16toUTF8 propertyStr(nameSpaceURI);
- propertyStr.Append(attrName);
+ propertyStr.Append(nsAtomCString(localName));
// Add the assertion to RDF
nsCOMPtr<nsIRDFResource> property;
gRDFService->GetResource(propertyStr, getter_AddRefs(property));
nsCOMPtr<nsIRDFLiteral> target;
gRDFService->GetLiteral(aAttributes[1],
getter_AddRefs(target));
@@ -1153,21 +1150,18 @@ RDFContentSinkImpl::OpenObject(const PRU
else {
// heh, that's not *in* the RDF namespace: just treat it
// like a typed node
isaTypedNode = PR_TRUE;
}
}
if (isaTypedNode) {
- const char* attrName;
- localName->GetUTF8String(&attrName);
-
NS_ConvertUTF16toUTF8 typeStr(nameSpaceURI);
- typeStr.Append(attrName);
+ typeStr.Append(nsAtomCString(localName));
nsCOMPtr<nsIRDFResource> type;
nsresult rv = gRDFService->GetResource(typeStr, getter_AddRefs(type));
if (NS_FAILED(rv)) return rv;
rv = mDataSource->Assert(source, kRDF_type, type, PR_TRUE);
if (NS_FAILED(rv)) return rv;
@@ -1185,21 +1179,18 @@ RDFContentSinkImpl::OpenProperty(const P
// an "object" non-terminal is either a "description", a "typed
// node", or a "container", so this change the content sink's
// state appropriately.
nsCOMPtr<nsIAtom> localName;
const nsDependentSubstring& nameSpaceURI =
SplitExpatName(aName, getter_AddRefs(localName));
- const char* attrName;
- localName->GetUTF8String(&attrName);
-
NS_ConvertUTF16toUTF8 propertyStr(nameSpaceURI);
- propertyStr.Append(attrName);
+ propertyStr.Append(nsAtomCString(localName));
nsCOMPtr<nsIRDFResource> property;
rv = gRDFService->GetResource(propertyStr, getter_AddRefs(property));
if (NS_FAILED(rv)) return rv;
// See if they've specified a 'resource' attribute, in which case
// they mean *that* to be the object of this property.
nsCOMPtr<nsIRDFResource> target;
--- a/xpcom/ds/nsAtomService.cpp
+++ b/xpcom/ds/nsAtomService.cpp
@@ -54,17 +54,17 @@ nsAtomService::GetAtom(const nsAString&
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
nsresult
nsAtomService::GetPermanentAtom(const nsAString& aString, nsIAtom ** aResult)
{
- *aResult = NS_NewPermanentAtom(NS_ConvertUTF16toUTF8(aString));
+ *aResult = NS_NewPermanentAtom(aString);
if (!*aResult)
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP
@@ -76,15 +76,15 @@ nsAtomService::GetAtomUTF8(const char *a
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP
nsAtomService::GetPermanentAtomUTF8(const char *aValue, nsIAtom* *aResult)
{
- *aResult = NS_NewPermanentAtom(nsDependentCString(aValue));
+ *aResult = NS_NewPermanentAtom(NS_ConvertUTF8toUTF16(aValue));
if (!*aResult)
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
--- a/xpcom/ds/nsAtomTable.cpp
+++ b/xpcom/ds/nsAtomTable.cpp
@@ -148,17 +148,17 @@ struct AtomTableEntry : public PLDHashEn
NS_ASSERTION(keyHash > 1,
"GetAtomImpl() called on non-atom AtomTableEntry!");
return (AtomImpl*) (mBits & ~0x1);
}
// type-agnostic accessors
// get the string buffer
- inline const char* getAtomString() const {
+ inline const PRUnichar* getAtomString() const {
NS_ASSERTION(keyHash > 1,
"getAtomString() called on non-atom AtomTableEntry!");
return GetAtomImpl()->mString;
}
// get the string buffer
inline const char* getUTF8String() const {
@@ -195,56 +195,56 @@ struct AtomTableEntry : public PLDHashEn
}
};
static PLDHashNumber
AtomTableGetHash(PLDHashTable *table, const void *key)
{
const AtomTableEntry *e = static_cast<const AtomTableEntry*>(key);
- if (e->IsUTF16String()) {
- return nsCRT::HashCodeAsUTF8(e->getUTF16String(), e->getLength());;
+ if (e->IsUTF8String()) {
+ return nsCRT::HashCodeAsUTF16(e->getUTF8String(), e->getLength());;
}
- NS_ASSERTION(e->IsUTF8String(),
+ NS_ASSERTION(e->IsUTF16String(),
"AtomTableGetHash() called on non-string-key AtomTableEntry!");
- return nsCRT::HashCode(e->getUTF8String(), e->getLength());
+ return nsCRT::HashCode(e->getUTF16String(), e->getLength());
}
static PRBool
AtomTableMatchKey(PLDHashTable *table, const PLDHashEntryHdr *entry,
const void *key)
{
const AtomTableEntry *he = static_cast<const AtomTableEntry*>(entry);
const AtomTableEntry *strKey = static_cast<const AtomTableEntry*>(key);
- const char *atomString = he->getAtomString();
+ const PRUnichar *atomString = he->getAtomString();
- if (strKey->IsUTF16String()) {
+ if (strKey->IsUTF8String()) {
return
- CompareUTF8toUTF16(nsDependentCSubstring(atomString, atomString + he->getLength()),
- nsDependentSubstring(strKey->getUTF16String(),
- strKey->getUTF16String() + strKey->getLength())) == 0;
+ CompareUTF8toUTF16(nsDependentCSubstring(strKey->getUTF8String(),
+ strKey->getUTF8String() + strKey->getLength()),
+ nsDependentSubstring(atomString, atomString + he->getLength())) == 0;
}
PRUint32 length = he->getLength();
if (length != strKey->getLength()) {
return PR_FALSE;
}
- const char *str;
+ const PRUnichar *str;
- if (strKey->IsUTF8String()) {
- str = strKey->getUTF8String();
+ if (strKey->IsUTF16String()) {
+ str = strKey->getUTF16String();
} else {
str = strKey->getAtomString();
}
- return memcmp(atomString, str, length * sizeof(char)) == 0;
+ return memcmp(atomString, str, length * sizeof(PRUnichar)) == 0;
}
static void
AtomTableClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
{
AtomTableEntry *he = static_cast<AtomTableEntry*>(entry);
AtomImpl *atom = he->GetAtomImpl();
@@ -293,19 +293,19 @@ static PLDHashOperator
DumpAtomLeaks(PLDHashTable *table, PLDHashEntryHdr *he,
PRUint32 index, void *arg)
{
AtomTableEntry *entry = static_cast<AtomTableEntry*>(he);
AtomImpl* atom = entry->GetAtomImpl();
if (!atom->IsPermanent()) {
++*static_cast<PRUint32*>(arg);
- const char *str;
- atom->GetUTF8String(&str);
- fputs(str, stdout);
+ nsCAutoString str;
+ atom->ToUTF8String(str);
+ fputs(str.get(), stdout);
fputs("\n", stdout);
}
return PL_DHASH_NEXT;
}
#endif
static inline
void PromoteToPermanent(AtomImpl* aAtom)
@@ -338,35 +338,35 @@ NS_PurgeAtomTable()
}
#endif
PL_DHashTableFinish(&gAtomTable);
gAtomTable.entryCount = 0;
gAtomTable.ops = nsnull;
}
}
-AtomImpl::AtomImpl(const nsACString& aString)
+AtomImpl::AtomImpl(const nsAString& aString)
: mLength(aString.Length())
{
nsStringBuffer* buf = nsStringBuffer::FromString(aString);
if (buf) {
buf->AddRef();
- mString = static_cast<char*>(buf->Data());
+ mString = static_cast<PRUnichar*>(buf->Data());
}
else {
- buf = nsStringBuffer::Alloc((mLength + 1) * sizeof(char));
- mString = static_cast<char*>(buf->Data());
- memcpy(mString, aString.BeginReading(), mLength * sizeof(char));
+ buf = nsStringBuffer::Alloc((mLength + 1) * sizeof(PRUnichar));
+ mString = static_cast<PRUnichar*>(buf->Data());
+ CopyUnicodeTo(aString, 0, mString, mLength);
mString[mLength] = PRUnichar(0);
}
}
AtomImpl::AtomImpl(nsStringBuffer* aStringBuffer, PRUint32 aLength)
: mLength(aLength),
- mString(static_cast<char*>(aStringBuffer->Data()))
+ mString(static_cast<PRUnichar*>(aStringBuffer->Data()))
{
// Technically we could currently avoid doing this addref by instead making
// the static atom buffers have an initial refcount of 2.
aStringBuffer->AddRef();
}
AtomImpl::~AtomImpl()
{
@@ -425,47 +425,53 @@ void* PermanentAtomImpl::operator new (
// Just let the constructor overwrite the vtable pointer.
return aAtom;
}
NS_IMETHODIMP
AtomImpl::ToString(nsAString& aBuf)
{
- CopyUTF8toUTF16(nsDependentCString(mString, mLength), aBuf);
+ nsStringBuffer::FromData(mString)->ToString(mLength, aBuf);
return NS_OK;
}
NS_IMETHODIMP
AtomImpl::ToUTF8String(nsACString& aBuf)
{
- nsStringBuffer::FromData(mString)->ToString(mLength, aBuf);
+ CopyUTF16toUTF8(nsDependentString(mString, mLength), aBuf);
return NS_OK;
}
NS_IMETHODIMP
-AtomImpl::GetUTF8String(const char **aResult)
+AtomImpl::GetUTF16String(const PRUnichar **aResult)
{
NS_PRECONDITION(aResult, "null out param");
*aResult = mString;
return NS_OK;
}
+NS_IMETHODIMP_(PRUint32)
+AtomImpl::GetLength()
+{
+ return mLength;
+}
+
NS_IMETHODIMP
AtomImpl::EqualsUTF8(const nsACString& aString, PRBool* aResult)
{
- *aResult = aString.Equals(nsDependentCString(mString, mLength));
+ *aResult = CompareUTF8toUTF16(aString,
+ nsDependentString(mString, mLength)) == 0;
return NS_OK;
}
NS_IMETHODIMP
AtomImpl::Equals(const nsAString& aString, PRBool* aResult)
{
- *aResult = CompareUTF8toUTF16(nsDependentCString(mString, mLength),
- aString) == 0;
+ *aResult = aString.Equals(nsDependentString(mString, mLength));
return NS_OK;
}
NS_IMETHODIMP_(PRBool)
AtomImpl::IsStaticAtom()
{
return IsPermanent();
}
@@ -535,24 +541,25 @@ NS_RegisterStaticAtoms(const nsStaticAto
if (!gStaticAtomTable || !gStaticAtomTable->Init()) {
delete gStaticAtomTable;
gStaticAtomTable = nsnull;
return NS_ERROR_OUT_OF_MEMORY;
}
}
for (PRUint32 i=0; i<aAtomCount; i++) {
- NS_ASSERTION(nsCRT::IsAscii((char*)aAtoms[i].mStringBuffer->Data()),
+#ifdef NS_STATIC_ATOM_USE_WIDE_STRINGS
+ NS_ASSERTION(nsCRT::IsAscii((PRUnichar*)aAtoms[i].mStringBuffer->Data()),
"Static atoms must be ASCII!");
PRUint32 stringLen =
- aAtoms[i].mStringBuffer->StorageSize() / sizeof(char) - 1;
+ aAtoms[i].mStringBuffer->StorageSize() / sizeof(PRUnichar) - 1;
AtomTableEntry *he =
- GetAtomHashEntry((char*)aAtoms[i].mStringBuffer->Data(),
+ GetAtomHashEntry((PRUnichar*)aAtoms[i].mStringBuffer->Data(),
stringLen);
if (he->HasValue()) {
// there already is an atom with this name in the table.. but we
// still have to update mBits
if (!he->GetAtomImpl()->IsPermanent()) {
// since we wanted to create a static atom but there is
// already one there, we convert it to a non-refcounting
@@ -564,21 +571,35 @@ NS_RegisterStaticAtoms(const nsStaticAto
}
else {
AtomImpl* atom = new PermanentAtomImpl(aAtoms[i].mStringBuffer,
stringLen);
he->SetAtomImpl(atom);
*aAtoms[i].mAtom = atom;
if (!gStaticAtomTableSealed) {
- nsAutoString key;
- atom->ToString(key);
- gStaticAtomTable->Put(key, atom);
+ gStaticAtomTable->Put(nsAtomString(atom), atom);
}
}
+#else // NS_STATIC_ATOM_USE_WIDE_STRINGS
+ NS_ASSERTION(nsCRT::IsAscii((char*)aAtoms[i].mStringBuffer->Data()),
+ "Static atoms must be ASCII!");
+
+ PRUint32 stringLen = aAtoms[i].mStringBuffer->StorageSize() - 1;
+
+ NS_ConvertASCIItoUTF16 str((char*)aAtoms[i].mStringBuffer->Data(),
+ stringLen);
+ nsIAtom* atom = NS_NewPermanentAtom(str);
+ *aAtoms[i].mAtom = atom;
+
+ if (!gStaticAtomTableSealed) {
+ gStaticAtomTable->Put(str, atom);
+ }
+#endif
+
}
return NS_OK;
}
NS_COM nsIAtom*
NS_NewAtom(const char* aUTF8String)
{
return NS_NewAtom(nsDependentCString(aUTF8String));
@@ -589,23 +610,25 @@ NS_NewAtom(const nsACString& aUTF8String
{
AtomTableEntry *he = GetAtomHashEntry(aUTF8String.Data(),
aUTF8String.Length());
if (!he) {
return nsnull;
}
- NS_ASSERTION(!he->IsUTF8String() && !he->IsUTF16String(),
- "Atom hash entry is string? Should be atom!");
-
if (he->HasValue())
return he->GetAtom();
- AtomImpl* atom = new AtomImpl(aUTF8String);
+ // This results in an extra addref/release of the nsStringBuffer.
+ // Unfortunately there doesn't seem to be any APIs to avoid that.
+ nsString str;
+ CopyUTF8toUTF16(aUTF8String, str);
+ AtomImpl* atom = new AtomImpl(str);
+
he->SetAtomImpl(atom);
NS_ADDREF(atom);
return atom;
}
NS_COM nsIAtom*
NS_NewAtom(const PRUnichar* aUTF16String)
@@ -617,43 +640,38 @@ NS_COM nsIAtom*
NS_NewAtom(const nsAString& aUTF16String)
{
AtomTableEntry *he = GetAtomHashEntry(aUTF16String.Data(),
aUTF16String.Length());
if (he->HasValue())
return he->GetAtom();
- // This results in an extra addref/release of the nsStringBuffer.
- // Unfortunately there doesn't seem to be any APIs to avoid that.
- nsCString str;
- CopyUTF16toUTF8(aUTF16String, str);
- AtomImpl* atom = new AtomImpl(str);
-
+ AtomImpl* atom = new AtomImpl(aUTF16String);
he->SetAtomImpl(atom);
NS_ADDREF(atom);
return atom;
}
NS_COM nsIAtom*
-NS_NewPermanentAtom(const nsACString& aUTF8String)
+NS_NewPermanentAtom(const nsAString& aUTF16String)
{
- AtomTableEntry *he = GetAtomHashEntry(aUTF8String.Data(),
- aUTF8String.Length());
+ AtomTableEntry *he = GetAtomHashEntry(aUTF16String.Data(),
+ aUTF16String.Length());
if (he->HasValue()) {
AtomImpl* atom = he->GetAtomImpl();
if (!atom->IsPermanent()) {
PromoteToPermanent(atom);
}
return atom;
}
- AtomImpl* atom = new PermanentAtomImpl(aUTF8String);
+ AtomImpl* atom = new PermanentAtomImpl(aUTF16String);
he->SetAtomImpl(atom);
// No need to addref since permanent atoms aren't refcounted anyway
return atom;
}
NS_COM nsrefcnt
--- a/xpcom/ds/nsAtomTable.h
+++ b/xpcom/ds/nsAtomTable.h
@@ -43,29 +43,29 @@
/**
* Note that AtomImpl objects are sometimes converted into PermanentAtomImpl
* objects using placement new and just overwriting the vtable pointer.
*/
class AtomImpl : public nsIAtom {
public:
- AtomImpl(const nsACString& aString);
+ AtomImpl(const nsAString& aString);
// This is currently only used during startup when creating a permanent atom
// from NS_RegisterStaticAtoms
AtomImpl(nsStringBuffer* aData, PRUint32 aLength);
protected:
// This is only intended to be used when a normal atom is turned into a
// permanent one.
AtomImpl() {
// We can't really assert that mString is a valid nsStringBuffer string,
// so do the best we can do and check for some consistencies.
- NS_ASSERTION((mLength + 1) * sizeof(char) <=
+ NS_ASSERTION((mLength + 1) * sizeof(PRUnichar) <=
nsStringBuffer::FromData(mString)->StorageSize() &&
mString[mLength] == 0,
"Not initialized atom");
}
// We don't need a virtual destructor here because PermanentAtomImpl
// deletions aren't handled through Release().
~AtomImpl();
@@ -85,26 +85,26 @@ public:
// for |#ifdef NS_BUILD_REFCNT_LOGGING| access to reference count
nsrefcnt GetRefCount() { return mRefCnt; }
// The length of the string in the atom.
PRUint32 mLength;
// This always points to the data owned by a nsStringBuffer
- char* mString;
+ PRUnichar* mString;
};
/**
* A non-refcounted implementation of nsIAtom.
*/
class PermanentAtomImpl : public AtomImpl {
public:
- PermanentAtomImpl(const nsACString& aString)
+ PermanentAtomImpl(const nsAString& aString)
: AtomImpl(aString)
{}
PermanentAtomImpl(nsStringBuffer* aData, PRUint32 aLength)
: AtomImpl(aData, aLength)
{}
PermanentAtomImpl()
{}
--- a/xpcom/ds/nsCRT.cpp
+++ b/xpcom/ds/nsCRT.cpp
@@ -50,16 +50,17 @@
* routines, we simply return 0.
*/
#include "nsCRT.h"
#include "nsIServiceManager.h"
#include "nsCharTraits.h"
#include "prbit.h"
+#include "nsUTF8Utils.h"
#define ADD_TO_HASHVAL(hashval, c) \
hashval = PR_ROTATE_LEFT32(hashval, 4) ^ (c);
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
@@ -232,135 +233,54 @@ PRUint32 nsCRT::HashCode(const PRUnichar
while ( (c = *s++) )
ADD_TO_HASHVAL(h, c);
if ( resultingStrLen )
*resultingStrLen = (s-str)-1;
return h;
}
-PRUint32 nsCRT::HashCodeAsUTF8(const PRUnichar* start, PRUint32 length)
+PRUint32 nsCRT::HashCode(const PRUnichar* start, PRUint32 length)
{
PRUint32 h = 0;
const PRUnichar* s = start;
const PRUnichar* end = start + length;
- PRUint16 W1 = 0; // the first UTF-16 word in a two word tuple
- PRUint32 U = 0; // the current char as UCS-4
- int code_length = 0; // the number of bytes in the UTF-8 sequence for the current char
-
- PRUint16 W;
- while ( s < end )
- {
- W = *s++;
- /*
- * On the fly, decoding from UTF-16 (and/or UCS-2) into UTF-8 as per
- * http://www.ietf.org/rfc/rfc2781.txt
- * http://www.ietf.org/rfc/rfc3629.txt
- */
-
- if ( !W1 )
- {
- if ( !IS_SURROGATE(W) )
- {
- U = W;
- if ( W <= 0x007F )
- code_length = 1;
- else if ( W <= 0x07FF )
- code_length = 2;
- else
- code_length = 3;
- }
- else if ( NS_IS_HIGH_SURROGATE(W) && s < end)
- {
- W1 = W;
-
- continue;
- }
- else
- {
- // Treat broken characters as the Unicode replacement
- // character 0xFFFD
- U = 0xFFFD;
-
- code_length = 3;
-
- NS_WARNING("Got low surrogate but no previous high surrogate");
- }
- }
- else
- {
- // as required by the standard, this code is careful to
- // throw out illegal sequences
-
- if ( NS_IS_LOW_SURROGATE(W) )
- {
- U = SURROGATE_TO_UCS4(W1, W);
- NS_ASSERTION(IS_VALID_CHAR(U), "How did this happen?");
- code_length = 4;
- }
- else
- {
- // Treat broken characters as the Unicode replacement
- // character 0xFFFD
- U = 0xFFFD;
-
- code_length = 3;
-
- NS_WARNING("High surrogate not followed by low surrogate");
-
- // The pointer to the next character points to the second 16-bit
- // value, not beyond it, as per Unicode 5.0.0 Chapter 3 C10, only
- // the first code unit of an illegal sequence must be treated as
- // an illegally terminated code unit sequence (also Chapter 3
- // D91, "isolated [not paired and ill-formed] UTF-16 code units
- // in the range D800..DFFF are ill-formed").
- --s;
- }
-
- W1 = 0;
- }
-
-
- static const PRUint16 sBytePrefix[5] = { 0x0000, 0x0000, 0x00C0, 0x00E0, 0x00F0 };
- static const PRUint16 sShift[5] = { 0, 0, 6, 12, 18 };
-
- /*
- * Unlike the algorithm in
- * http://www.ietf.org/rfc/rfc3629.txt we must calculate the
- * bytes in left to right order so that our hash result
- * matches what the narrow version would calculate on an
- * already UTF-8 string.
- */
-
- // hash the first (and often, only, byte)
- ADD_TO_HASHVAL(h, (sBytePrefix[code_length] | (U>>sShift[code_length])));
-
- // an unrolled loop for hashing any remaining bytes in this
- // sequence
- switch ( code_length )
- { // falling through in each case
- case 4: ADD_TO_HASHVAL(h, (0x80 | ((U>>12) & 0x003F)));
- case 3: ADD_TO_HASHVAL(h, (0x80 | ((U>>6 ) & 0x003F)));
- case 2: ADD_TO_HASHVAL(h, (0x80 | ( U & 0x003F)));
- default: code_length = 0;
- break;
- }
- }
+ PRUnichar c;
+ while ( s < end ) {
+ c = *s++;
+ ADD_TO_HASHVAL(h, c);
+ }
return h;
}
-PRUint32 nsCRT::BufferHashCode(const PRUnichar* s, PRUint32 len)
+PRUint32 nsCRT::HashCodeAsUTF16(const char* start, PRUint32 length)
{
PRUint32 h = 0;
- const PRUnichar* done = s + len;
+ const char* s = start;
+ const char* end = start + length;
- while ( s < done )
- h = PR_ROTATE_LEFT32(h, 4) ^ PRUint16(*s++); // cast to unsigned to prevent possible sign extension
+ while ( s < end )
+ {
+ PRBool err;
+ PRUint32 ucs4 = UTF8CharEnumerator::NextChar(&s, end, &err);
+ if (err) {
+ return 0;
+ }
+
+ if (ucs4 < PLANE1_BASE) {
+ ADD_TO_HASHVAL(h, ucs4);
+ }
+ else {
+ ADD_TO_HASHVAL(h, H_SURROGATE(ucs4));
+ ADD_TO_HASHVAL(h, L_SURROGATE(ucs4));
+ }
+ }
+
return h;
}
// This should use NSPR but NSPR isn't exporting its PR_strtoll function
// Until then...
PRInt64 nsCRT::atoll(const char *str)
{
if (!str)
--- a/xpcom/ds/nsCRT.h
+++ b/xpcom/ds/nsCRT.h
@@ -231,25 +231,23 @@ public:
// Computes the hashcode for a length number of bytes of c-string data.
static PRUint32 HashCode(const char* start, PRUint32 length);
// Computes the hashcode for a ucs2 string, returns the string length
// as an added bonus.
static PRUint32 HashCode(const PRUnichar* str,
PRUint32* resultingStrLen = nsnull);
- // Computes a hashcode for a length number of UTF16
+ // Computes the hashcode for a buffer with a specified length.
+ static PRUint32 HashCode(const PRUnichar* str, PRUint32 strLen);
+
+ // Computes a hashcode for a length number of UTF8
// characters. Returns the same hash code as the HashCode method
- // taking a |char*| would if the string were converted to UTF8. This
- // hash function treats invalid UTF16 data as 0xFFFD (0xEFBFBD in
- // UTF-8).
- static PRUint32 HashCodeAsUTF8(const PRUnichar* start, PRUint32 length);
-
- // Computes the hashcode for a buffer with a specified length.
- static PRUint32 BufferHashCode(const PRUnichar* str, PRUint32 strLen);
+ // taking a |PRUnichar*| would if the string were converted to UTF16.
+ static PRUint32 HashCodeAsUTF16(const char* start, PRUint32 length);
// String to longlong
static PRInt64 atoll(const char *str);
static char ToUpper(char aChar) { return NS_ToUpper(aChar); }
static char ToLower(char aChar) { return NS_ToLower(aChar); }
static PRBool IsUpper(char aChar) { return NS_IsUpper(aChar); }
--- a/xpcom/ds/nsIAtom.idl
+++ b/xpcom/ds/nsIAtom.idl
@@ -43,29 +43,30 @@
%}
/*
* Should this really be scriptable? Using atoms from script or proxies
* could be dangerous since double-wrapping could lead to loss of
* pointer identity.
*/
-[scriptable, uuid(fbffe332-0856-421a-9b83-aaed0081fc40)]
+[scriptable, uuid(96c82146-56f3-4b43-817f-25d6db1ad8e8)]
interface nsIAtom : nsISupports
{
/**
* Get the Unicode or UTF8 value for the string
*/
AString toString();
AUTF8String toUTF8String();
/**
- * Return a pointer to a zero terminated UTF8 string.
+ * Return a pointer to a zero terminated UTF16 string.
*/
- [noscript] void getUTF8String([shared, retval] out string aResult);
+ [noscript] void getUTF16String([shared, retval] out wstring aResult);
+ [notxpcom] unsigned long getLength();
/**
* Compare the atom to a specific string value
* Note that this will NEVER return/throw an error condition.
*/
boolean equals(in AString aString);
boolean equalsUTF8(in AUTF8String aString);
@@ -78,16 +79,23 @@ interface nsIAtom : nsISupports
return result;
}
inline PRBool EqualsUTF8(const nsACString& s) {
PRBool result;
EqualsUTF8(s, &result);
return result;
}
+
+ inline const PRUnichar* GetUTF16String() {
+ const PRUnichar* result;
+ GetUTF16String(&result);
+ return result;
+ }
+
%}
/**
* Returns true if the atom is static and false otherwise.
*/
[noscript, notxpcom] boolean isStaticAtom();
};
@@ -118,32 +126,32 @@ extern NS_COM nsIAtom* NS_NewAtom(const
inline already_AddRefed<nsIAtom> do_GetAtom(const char* aUTF8String)
{ return NS_NewAtom(aUTF8String); }
/**
* Find an atom that matches the given UTF-8 string.
*/
extern NS_COM nsIAtom* NS_NewAtom(const nsACString& aUTF8String);
-extern NS_COM nsIAtom* NS_NewPermanentAtom(const nsACString& aUTF8String);
inline already_AddRefed<nsIAtom> do_GetAtom(const nsACString& aUTF8String)
{ return NS_NewAtom(aUTF8String); }
/**
* Find an atom that matches the given UTF-16 string.
* The string is assumed to be zero terminated.
*/
extern NS_COM nsIAtom* NS_NewAtom(const PRUnichar* aUTF16String);
inline already_AddRefed<nsIAtom> do_GetAtom(const PRUnichar* aUTF16String)
{ return NS_NewAtom(aUTF16String); }
/**
* Find an atom that matches the given UTF-16 string.
*/
extern NS_COM nsIAtom* NS_NewAtom(const nsAString& aUTF16String);
+extern NS_COM nsIAtom* NS_NewPermanentAtom(const nsAString& aUTF16String);
inline already_AddRefed<nsIAtom> do_GetAtom(const nsAString& aUTF16String)
{ return NS_NewAtom(aUTF16String); }
/**
* Return a count of the total number of atoms currently
* alive in the system.
*/
extern NS_COM nsrefcnt NS_GetNumberOfAtoms(void);
@@ -154,9 +162,36 @@ extern NS_COM nsrefcnt NS_GetNumberOfAto
*/
extern NS_COM nsIAtom* NS_GetStaticAtom(const nsAString& aUTF16String);
/**
* Seal the static atom table
*/
extern NS_COM void NS_SealStaticAtomTable();
+class nsAtomString : public nsString
+{
+public:
+ nsAtomString(nsIAtom* aAtom)
+ {
+ aAtom->ToString(*this);
+ }
+};
+
+class nsAtomCString : public nsCString
+{
+public:
+ nsAtomCString(nsIAtom* aAtom)
+ {
+ aAtom->ToUTF8String(*this);
+ }
+};
+
+class nsDependentAtomString : public nsDependentString
+{
+public:
+ nsDependentAtomString(nsIAtom* aAtom)
+ : nsDependentString(aAtom->GetUTF16String(), aAtom->GetLength())
+ {
+ }
+};
+
%}
--- a/xpcom/ds/nsStaticAtom.h
+++ b/xpcom/ds/nsStaticAtom.h
@@ -38,18 +38,28 @@
#ifndef nsStaticAtom_h__
#define nsStaticAtom_h__
#include "nsIAtom.h"
#include "nsStringBuffer.h"
#include "prlog.h"
+#if defined(HAVE_CPP_CHAR16_T)
+#define NS_STATIC_ATOM_USE_WIDE_STRINGS
+typedef char16_t nsStaticAtomStringType;
+#elif defined(HAVE_CPP_2BYTE_WCHAR_T)
+#define NS_STATIC_ATOM_USE_WIDE_STRINGS
+typedef wchar_t nsStaticAtomStringType;
+#else
+typedef char nsStaticAtomStringType;
+#endif
+
#define NS_STATIC_ATOM(buffer_name, atom_ptr) { (nsStringBuffer*) &buffer_name, atom_ptr }
-#define NS_STATIC_ATOM_BUFFER(buffer_name, str_data) static nsFakeStringBuffer< sizeof(str_data) > buffer_name = { 1, sizeof(str_data), str_data };
+#define NS_STATIC_ATOM_BUFFER(buffer_name, str_data) static nsFakeStringBuffer< sizeof(str_data) > buffer_name = { 1, sizeof(str_data) * sizeof(nsStaticAtomStringType), NS_L(str_data) };
/**
* Holds data used to initialize large number of atoms during startup. Use
* the above macros to initialize these structs. They should never be accessed
* directly other than from AtomTable.cpp
*/
struct nsStaticAtom {
nsStringBuffer* mStringBuffer;
@@ -58,17 +68,16 @@ struct nsStaticAtom {
/**
* This is a struct with the same binary layout as a nsStringBuffer.
*/
template <PRUint32 size>
struct nsFakeStringBuffer {
PRInt32 mRefCnt;
PRUint32 mSize;
- char mStringData[size];
+ nsStaticAtomStringType mStringData[size];
};
-// register your lookup function with the atom table. Your function
-// will be called when at atom is not found in the main atom table.
+// Register static atoms with the atom table
NS_COM nsresult
NS_RegisterStaticAtoms(const nsStaticAtom*, PRUint32 aAtomCount);
#endif
--- a/xpcom/tests/TestAtoms.cpp
+++ b/xpcom/tests/TestAtoms.cpp
@@ -76,19 +76,19 @@ int main(int argc, char** argv)
ids[i] = NS_NewAtom(strings[i]);
}
PRUnichar qqs[1]; qqs[0] = 0;
nsIAtom* qq = NS_NewAtom(qqs);
PRTime end1 = PR_Now();
// Now make sure we can find all the idents we just made
for (i = 0; i < count; i++) {
- const char *utf8String;
- ids[i]->GetUTF8String(&utf8String);
- nsIAtom* id = NS_NewAtom(utf8String);
+ const PRUnichar *utf16String;
+ ids[i]->GetUTF16String(&utf16String);
+ nsIAtom* id = NS_NewAtom(utf16String);
if (id != ids[i]) {
id->ToString(s1);
ids[i]->ToString(s2);
printf("find failed: id='%s' ids[%d]='%s'\n",
NS_LossyConvertUTF16toASCII(s1).get(), i, NS_LossyConvertUTF16toASCII(s2).get());
return -1;
}
NS_RELEASE(id);
--- a/xpcom/tests/TestPermanentAtoms.cpp
+++ b/xpcom/tests/TestPermanentAtoms.cpp
@@ -46,40 +46,38 @@
static void Assert(PRBool aCondition, const char* aStatement)
{
printf("%s: %s\n", aCondition?"PASS":"FAIL", aStatement);
}
static void AssertString(nsIAtom *aAtom, const nsACString& aString)
{
- const char *str;
- static_cast<AtomImpl*>(aAtom)->GetUTF8String(&str);
- Assert(nsDependentCString(str) == aString, "string is correct");
+ Assert(aAtom->EqualsUTF8(aString), "string is correct");
}
static void AssertPermanence(nsIAtom *aAtom, PRBool aPermanence)
{
Assert(static_cast<AtomImpl*>(aAtom)->IsPermanent() == aPermanence,
aPermanence ? "atom is permanent" : "atom is not permanent");
}
int main()
{
nsCOMPtr<nsIAtom> foo = do_GetAtom("foo");
AssertString(foo, NS_LITERAL_CSTRING("foo"));
AssertPermanence(foo, PR_FALSE);
- nsCOMPtr<nsIAtom> foop = do_GetPermanentAtom("foo");
+ nsCOMPtr<nsIAtom> foop = NS_NewPermanentAtom(NS_LITERAL_STRING("foo"));
AssertString(foop, NS_LITERAL_CSTRING("foo"));
AssertPermanence(foop, PR_TRUE);
Assert(foo == foop, "atoms are equal");
- nsCOMPtr<nsIAtom> barp = do_GetPermanentAtom("bar");
+ nsCOMPtr<nsIAtom> barp = NS_NewPermanentAtom(NS_LITERAL_STRING("bar"));
AssertString(barp, NS_LITERAL_CSTRING("bar"));
AssertPermanence(barp, PR_TRUE);
nsCOMPtr<nsIAtom> bar = do_GetAtom("bar");
AssertString(bar, NS_LITERAL_CSTRING("bar"));
AssertPermanence(bar, PR_TRUE);
Assert(bar == barp, "atoms are equal");
--- a/xpcom/tests/TestUTF.cpp
+++ b/xpcom/tests/TestUTF.cpp
@@ -135,32 +135,59 @@ test_malformed8()
if (CompareUTF8toUTF16(str8, EmptyString()) == 0)
return PR_FALSE;
}
return PR_TRUE;
}
+PRBool
+test_hashas16()
+{
+ for (unsigned int i = 0; i < NS_ARRAY_LENGTH(ValidStrings); ++i) {
+ nsDependentCString str8(ValidStrings[i].m8);
+ if (nsCRT::HashCode(ValidStrings[i].m16) !=
+ nsCRT::HashCodeAsUTF16(str8.get(), str8.Length()))
+ return PR_FALSE;
+ }
+
+ for (unsigned int i = 0; i < NS_ARRAY_LENGTH(Invalid8Strings); ++i) {
+ nsDependentCString str8(Invalid8Strings[i].m8);
+ if (nsCRT::HashCode(Invalid8Strings[i].m16) !=
+ nsCRT::HashCodeAsUTF16(str8.get(), str8.Length()))
+ return PR_FALSE;
+ }
+
+ for (unsigned int i = 0; i < NS_ARRAY_LENGTH(Malformed8Strings); ++i) {
+ nsDependentCString str8(Malformed8Strings[i]);
+ if (nsCRT::HashCodeAsUTF16(str8.get(), str8.Length()) != 0)
+ return PR_FALSE;
+ }
+
+ return PR_TRUE;
+}
+
typedef PRBool (*TestFunc)();
static const struct Test
{
const char* name;
TestFunc func;
}
tests[] =
{
{ "test_valid", test_valid },
{ "test_invalid16", test_invalid16 },
{ "test_invalid8", test_invalid8 },
#ifndef DEBUG
// Don't run this test in debug builds as that intentionally asserts
{ "test_malformed8", test_malformed8 },
#endif
+ { "test_hashas16", test_hashas16 },
{ nsnull, nsnull }
};
}
using namespace TestUTF;
int main(int argc, char **argv)