Backing out fix to bug 162572 to see if it fixes btek pageload numbers

This commit is contained in:
jkeiser@netscape.com
2002-09-16 19:45:59 +00:00
parent 0bbfc42dec
commit 66505be142
6 changed files with 452 additions and 944 deletions

View File

@@ -42,60 +42,94 @@
#include "nsReadableUtils.h" #include "nsReadableUtils.h"
#include "nsUnicharUtils.h" #include "nsUnicharUtils.h"
#include "nsCRT.h" #include "nsCRT.h"
#include "nsMemory.h"
nsHTMLValue::nsHTMLValue(nsHTMLUnit aUnit) nsHTMLValue::nsHTMLValue(nsHTMLUnit aUnit)
: mUnit(aUnit), mStorageFlags(HTMLSTORAGE_NORMAL) : mUnit(aUnit)
{ {
NS_ASSERTION(GetUnitClass() == HTMLUNIT_NOSTORE, "not a valueless unit"); NS_ASSERTION((aUnit <= eHTMLUnit_Empty), "not a valueless unit");
if (GetUnitClass() != HTMLUNIT_NOSTORE) { if (aUnit > eHTMLUnit_Empty) {
mUnit = eHTMLUnit_Null; mUnit = eHTMLUnit_Null;
} }
mValue.mString = nsnull; mValue.mString = nsnull;
} }
nsHTMLValue::nsHTMLValue(PRInt32 aValue, nsHTMLUnit aUnit) nsHTMLValue::nsHTMLValue(PRInt32 aValue, nsHTMLUnit aUnit)
: mUnit(aUnit), mStorageFlags(HTMLSTORAGE_NORMAL) : mUnit(aUnit)
{ {
NS_ASSERTION(GetUnitClass() == HTMLUNIT_INTEGER || NS_ASSERTION((eHTMLUnit_Integer == aUnit) ||
GetUnitClass() == HTMLUNIT_PIXEL, "unit not an integer unit"); (eHTMLUnit_Enumerated == aUnit) ||
if (GetUnitClass() == HTMLUNIT_INTEGER || (eHTMLUnit_Proportional == aUnit) ||
GetUnitClass() == HTMLUNIT_PIXEL) { (eHTMLUnit_Pixel == aUnit), "not an integer value");
if ((eHTMLUnit_Integer == aUnit) ||
(eHTMLUnit_Enumerated == aUnit) ||
(eHTMLUnit_Proportional == aUnit) ||
(eHTMLUnit_Pixel == aUnit)) {
mValue.mInt = aValue; mValue.mInt = aValue;
} else { }
else {
mUnit = eHTMLUnit_Null; mUnit = eHTMLUnit_Null;
mValue.mString = nsnull; mValue.mInt = 0;
} }
} }
nsHTMLValue::nsHTMLValue(float aValue) nsHTMLValue::nsHTMLValue(float aValue)
: mUnit(eHTMLUnit_Percent), mStorageFlags(HTMLSTORAGE_NORMAL) : mUnit(eHTMLUnit_Percent)
{ {
mValue.mFloat = aValue; mValue.mFloat = aValue;
} }
nsHTMLValue::nsHTMLValue(const nsAString& aValue, nsHTMLUnit aUnit) nsHTMLValue::nsHTMLValue(const nsAString& aValue, nsHTMLUnit aUnit)
: mUnit(aUnit), mStorageFlags(HTMLSTORAGE_NORMAL) : mUnit(aUnit)
{ {
SetStringValueInternal(aValue, aUnit); NS_ASSERTION((eHTMLUnit_String == aUnit) ||
(eHTMLUnit_ColorName == aUnit), "not a string value");
if ((eHTMLUnit_String == aUnit) ||
(eHTMLUnit_ColorName == aUnit)) {
mValue.mString = ToNewUnicode(aValue);
}
else {
mUnit = eHTMLUnit_Null;
mValue.mInt = 0;
}
} }
nsHTMLValue::nsHTMLValue(nsISupports* aValue) nsHTMLValue::nsHTMLValue(nsISupports* aValue)
: mUnit(eHTMLUnit_ISupports), mStorageFlags(HTMLSTORAGE_NORMAL) : mUnit(eHTMLUnit_ISupports)
{ {
mValue.mISupports = aValue; mValue.mISupports = aValue;
NS_IF_ADDREF(mValue.mISupports); NS_IF_ADDREF(mValue.mISupports);
} }
nsHTMLValue::nsHTMLValue(nscolor aValue) nsHTMLValue::nsHTMLValue(nscolor aValue)
: mUnit(eHTMLUnit_Color), mStorageFlags(HTMLSTORAGE_NORMAL) : mUnit(eHTMLUnit_Color)
{ {
mValue.mColor = aValue; mValue.mColor = aValue;
} }
nsHTMLValue::nsHTMLValue(const nsHTMLValue& aCopy) nsHTMLValue::nsHTMLValue(const nsHTMLValue& aCopy)
: mUnit(aCopy.mUnit)
{ {
InitializeFrom(aCopy); if ((eHTMLUnit_String == mUnit) || (eHTMLUnit_ColorName == mUnit)) {
if (nsnull != aCopy.mValue.mString) {
mValue.mString = nsCRT::strdup(aCopy.mValue.mString);
}
else {
mValue.mString = nsnull;
}
}
else if (eHTMLUnit_ISupports == mUnit) {
mValue.mISupports = aCopy.mValue.mISupports;
NS_IF_ADDREF(mValue.mISupports);
}
else if (eHTMLUnit_Color == mUnit){
mValue.mColor = aCopy.mValue.mColor;
}
else if (eHTMLUnit_Percent == mUnit) {
mValue.mFloat = aCopy.mValue.mFloat;
}
else {
mValue.mInt = aCopy.mValue.mInt;
}
} }
nsHTMLValue::~nsHTMLValue(void) nsHTMLValue::~nsHTMLValue(void)
@@ -106,81 +140,79 @@ nsHTMLValue::~nsHTMLValue(void)
nsHTMLValue& nsHTMLValue::operator=(const nsHTMLValue& aCopy) nsHTMLValue& nsHTMLValue::operator=(const nsHTMLValue& aCopy)
{ {
Reset(); Reset();
InitializeFrom(aCopy); mUnit = aCopy.mUnit;
if ((eHTMLUnit_String == mUnit) || (eHTMLUnit_ColorName == mUnit)) {
if (nsnull != aCopy.mValue.mString) {
mValue.mString = nsCRT::strdup(aCopy.mValue.mString);
}
}
else if (eHTMLUnit_ISupports == mUnit) {
mValue.mISupports = aCopy.mValue.mISupports;
NS_IF_ADDREF(mValue.mISupports);
}
else if (eHTMLUnit_Color == mUnit){
mValue.mColor = aCopy.mValue.mColor;
}
else if (eHTMLUnit_Percent == mUnit) {
mValue.mFloat = aCopy.mValue.mFloat;
}
else {
mValue.mInt = aCopy.mValue.mInt;
}
return *this; return *this;
} }
PRBool nsHTMLValue::operator==(const nsHTMLValue& aOther) const PRBool nsHTMLValue::operator==(const nsHTMLValue& aOther) const
{ {
if (mUnit != aOther.mUnit) { if (mUnit == aOther.mUnit) {
return PR_FALSE; if ((eHTMLUnit_String == mUnit) || (eHTMLUnit_ColorName == mUnit)) {
} if (nsnull == mValue.mString) {
// Call GetUnit() so that we turn StringWithLength into String if (nsnull == aOther.mValue.mString) {
PRUint32 unitClass = GetUnitClass();
switch (unitClass) {
case HTMLUNIT_NOSTORE:
return PR_TRUE; return PR_TRUE;
}
case HTMLUNIT_STRING: }
if (mValue.mString && aOther.mValue.mString) { else if (nsnull != aOther.mValue.mString) {
return GetDependentString().Equals(aOther.GetDependentString(), return nsDependentString(mValue.mString).Equals(nsDependentString(aOther.mValue.mString),
nsCaseInsensitiveStringComparator()); nsCaseInsensitiveStringComparator());
} }
// One of them is null. An == check will see if they are both null.
return mValue.mString == aOther.mValue.mString;
case HTMLUNIT_INTEGER:
case HTMLUNIT_PIXEL:
return mValue.mInt == aOther.mValue.mInt;
case HTMLUNIT_COLOR:
return mValue.mColor == aOther.mValue.mColor;
case HTMLUNIT_ISUPPORTS:
return mValue.mISupports == aOther.mValue.mISupports;
case HTMLUNIT_PERCENT:
return mValue.mFloat == aOther.mValue.mFloat;
default:
NS_WARNING("Unknown unit");
return PR_TRUE;
} }
else if (eHTMLUnit_ISupports == mUnit) {
return PRBool(mValue.mISupports == aOther.mValue.mISupports);
}
else if (eHTMLUnit_Color == mUnit){
return PRBool(mValue.mColor == aOther.mValue.mColor);
}
else if (eHTMLUnit_Percent == mUnit) {
return PRBool(mValue.mFloat == aOther.mValue.mFloat);
}
else {
return PRBool(mValue.mInt == aOther.mValue.mInt);
}
}
return PR_FALSE;
} }
PRUint32 nsHTMLValue::HashValue(void) const PRUint32 nsHTMLValue::HashValue(void) const
{ {
PRUint32 retval; return PRUint32(mUnit) ^
if (GetUnitClass() == HTMLUNIT_STRING) { ((((eHTMLUnit_String == mUnit) || (eHTMLUnit_ColorName == mUnit)) &&
if (mStorageFlags & HTMLSTORAGE_STRWITHLEN) { (nsnull != mValue.mString)) ?
retval = mValue.mString ? nsCheapStringBufferUtils::HashCode(mValue.mString) nsCRT::HashCode(mValue.mString) :
: 0; mValue.mInt);
} else {
retval = mValue.mString ? nsCRT::HashCode(mValue.mString) : 0;
}
} else {
retval = mValue.mInt;
}
return retval ^ PRUint32(mUnit);
} }
void nsHTMLValue::Reset(void) void nsHTMLValue::Reset(void)
{ {
if (GetUnitClass() == HTMLUNIT_STRING) { if ((eHTMLUnit_String == mUnit) || (eHTMLUnit_ColorName == mUnit)) {
if (mValue.mString) { if (nsnull != mValue.mString) {
if (mStorageFlags & HTMLSTORAGE_STRWITHLEN) { nsCRT::free(mValue.mString);
nsCheapStringBufferUtils::Free(mValue.mString);
} else {
nsMemory::Free(mValue.mString);
} }
} }
} else if (eHTMLUnit_ISupports == mUnit) {
else if (mUnit == eHTMLUnit_ISupports) {
NS_IF_RELEASE(mValue.mISupports); NS_IF_RELEASE(mValue.mISupports);
} }
mUnit = eHTMLUnit_Null; mUnit = eHTMLUnit_Null;
mStorageFlags = 0;
mValue.mString = nsnull; mValue.mString = nsnull;
} }
@@ -188,12 +220,14 @@ void nsHTMLValue::Reset(void)
void nsHTMLValue::SetIntValue(PRInt32 aValue, nsHTMLUnit aUnit) void nsHTMLValue::SetIntValue(PRInt32 aValue, nsHTMLUnit aUnit)
{ {
Reset(); Reset();
NS_ASSERTION((eHTMLUnit_Integer == aUnit) ||
(eHTMLUnit_Enumerated == aUnit) ||
(eHTMLUnit_Proportional == aUnit), "not an int value");
if ((eHTMLUnit_Integer == aUnit) ||
(eHTMLUnit_Enumerated == aUnit) ||
(eHTMLUnit_Proportional == aUnit)) {
mUnit = aUnit; mUnit = aUnit;
NS_ASSERTION(GetUnitClass() == HTMLUNIT_INTEGER, "not an int value");
if (GetUnitClass() == HTMLUNIT_INTEGER) {
mValue.mInt = aValue; mValue.mInt = aValue;
} else {
mUnit = eHTMLUnit_Null;
} }
} }
@@ -211,50 +245,14 @@ void nsHTMLValue::SetPercentValue(float aValue)
mValue.mFloat = aValue; mValue.mFloat = aValue;
} }
static inline PRBool
ShouldStoreLength(const nsAString& aStr, PRUint32 aLen)
{
// Always remember the length of the string if the length is greater than 30
if (aLen > 30) {
return PR_TRUE;
}
// Obviously never remember the length of the string if it is empty :)
if (aLen == 0) {
return PR_FALSE;
}
// Remember the length of the string if it has embedded nulls
nsAString::const_iterator begin, end;
return FindCharInReadable('\0', aStr.BeginReading(begin),
aStr.EndReading(end));
}
void nsHTMLValue::SetStringValueInternal(const nsAString& aValue,
nsHTMLUnit aUnit)
{
NS_ASSERTION(GetUnitClass() == HTMLUNIT_STRING, "unit not a string unit!");
if (GetUnitClass() == HTMLUNIT_STRING) {
// Remember the length of the string if necessary
PRUint32 len = aValue.Length();
if (ShouldStoreLength(aValue, len)) {
mStorageFlags = HTMLSTORAGE_STRWITHLEN;
nsCheapStringBufferUtils::CopyToBuffer(mValue.mString, aValue, len);
return;
}
// Else just store as a normal string
mValue.mString = ToNewUnicode(aValue);
} else {
mUnit = eHTMLUnit_Null;
mValue.mString = nsnull;
}
}
void nsHTMLValue::SetStringValue(const nsAString& aValue, void nsHTMLValue::SetStringValue(const nsAString& aValue,
nsHTMLUnit aUnit) nsHTMLUnit aUnit)
{ {
Reset(); Reset();
if ((eHTMLUnit_String == aUnit) || (eHTMLUnit_ColorName == aUnit)) {
mUnit = aUnit; mUnit = aUnit;
SetStringValueInternal(aValue, aUnit); mValue.mString = ToNewUnicode(aValue);
}
} }
void nsHTMLValue::SetISupportsValue(nsISupports* aValue) void nsHTMLValue::SetISupportsValue(nsISupports* aValue)
@@ -281,32 +279,29 @@ void nsHTMLValue::SetEmptyValue(void)
#ifdef DEBUG #ifdef DEBUG
void nsHTMLValue::AppendToString(nsAString& aBuffer) const void nsHTMLValue::AppendToString(nsAString& aBuffer) const
{ {
switch (GetUnitClass()) { if (eHTMLUnit_Null == mUnit) {
case HTMLUNIT_NOSTORE: return;
break; }
case HTMLUNIT_STRING:
if (mValue.mString) { if (eHTMLUnit_Empty == mUnit) {
}
else if ((eHTMLUnit_String == mUnit) || (eHTMLUnit_ColorName == mUnit)) {
if (nsnull != mValue.mString) {
aBuffer.Append(PRUnichar('"')); aBuffer.Append(PRUnichar('"'));
aBuffer.Append(GetDependentString()); aBuffer.Append(mValue.mString);
aBuffer.Append(PRUnichar('"')); aBuffer.Append(PRUnichar('"'));
} else { }
else {
aBuffer.Append(NS_LITERAL_STRING("null str")); aBuffer.Append(NS_LITERAL_STRING("null str"));
} }
break; }
case HTMLUNIT_INTEGER: else if (eHTMLUnit_ISupports == mUnit) {
case HTMLUNIT_PIXEL: aBuffer.Append(NS_LITERAL_STRING("0x"));
{
nsAutoString intStr; nsAutoString intStr;
intStr.AppendInt(mValue.mInt, 10); intStr.AppendInt(NS_PTR_TO_INT32(mValue.mISupports), 16);
intStr.Append(NS_LITERAL_STRING("[0x"));
intStr.AppendInt(mValue.mInt, 16);
intStr.Append(PRUnichar(']'));
aBuffer.Append(intStr); aBuffer.Append(intStr);
} }
break; else if (eHTMLUnit_Color == mUnit){
case HTMLUNIT_COLOR:
{
nsAutoString intStr; nsAutoString intStr;
intStr.Append(NS_LITERAL_STRING("(0x")); intStr.Append(NS_LITERAL_STRING("(0x"));
intStr.AppendInt(NS_GET_R(mValue.mColor), 16); intStr.AppendInt(NS_GET_R(mValue.mColor), 16);
@@ -320,33 +315,28 @@ void nsHTMLValue::AppendToString(nsAString& aBuffer) const
aBuffer.Append(intStr); aBuffer.Append(intStr);
} }
break; else if (eHTMLUnit_Percent == mUnit) {
case HTMLUNIT_ISUPPORTS:
{
aBuffer.Append(NS_LITERAL_STRING("0x"));
nsAutoString intStr;
intStr.AppendInt(NS_PTR_TO_INT32(mValue.mISupports), 16);
aBuffer.Append(intStr);
}
break;
case HTMLUNIT_PERCENT:
{
nsAutoString floatStr; nsAutoString floatStr;
floatStr.AppendFloat(mValue.mFloat * 100.0f); floatStr.AppendFloat(mValue.mFloat * 100.0f);
aBuffer.Append(floatStr); aBuffer.Append(floatStr);
} }
break; else {
default: nsAutoString intStr;
NS_ERROR("Unknown HTMLValue type!"); intStr.AppendInt(mValue.mInt, 10);
intStr.Append(NS_LITERAL_STRING("[0x"));
intStr.AppendInt(mValue.mInt, 16);
intStr.Append(PRUnichar(']'));
aBuffer.Append(intStr);
} }
//
// Append the type name for types that are ambiguous
//
switch (mUnit) { switch (mUnit) {
case eHTMLUnit_Null: aBuffer.Append(NS_LITERAL_STRING("null")); break; case eHTMLUnit_Null: break;
case eHTMLUnit_Empty: aBuffer.Append(NS_LITERAL_STRING("empty")); break; case eHTMLUnit_Empty: break;
case eHTMLUnit_String: break;
case eHTMLUnit_ColorName: break;
case eHTMLUnit_ISupports: aBuffer.Append(NS_LITERAL_STRING("ptr")); break; case eHTMLUnit_ISupports: aBuffer.Append(NS_LITERAL_STRING("ptr")); break;
case eHTMLUnit_Integer: break;
case eHTMLUnit_Enumerated: aBuffer.Append(NS_LITERAL_STRING("enum")); break; case eHTMLUnit_Enumerated: aBuffer.Append(NS_LITERAL_STRING("enum")); break;
case eHTMLUnit_Proportional: aBuffer.Append(NS_LITERAL_STRING("*")); break; case eHTMLUnit_Proportional: aBuffer.Append(NS_LITERAL_STRING("*")); break;
case eHTMLUnit_Color: aBuffer.Append(NS_LITERAL_STRING("rbga")); break; case eHTMLUnit_Color: aBuffer.Append(NS_LITERAL_STRING("rbga")); break;
@@ -356,49 +346,3 @@ void nsHTMLValue::AppendToString(nsAString& aBuffer) const
aBuffer.Append(PRUnichar(' ')); aBuffer.Append(PRUnichar(' '));
} }
#endif // DEBUG #endif // DEBUG
void
nsHTMLValue::InitializeFrom(const nsHTMLValue& aCopy)
{
mUnit = aCopy.mUnit;
mStorageFlags = aCopy.mStorageFlags;
switch (GetUnitClass()) {
case HTMLUNIT_NOSTORE:
mValue.mString = nsnull;
break;
case HTMLUNIT_STRING:
if (aCopy.mValue.mString) {
if (aCopy.mStorageFlags & HTMLSTORAGE_STRWITHLEN) {
// Clone the string = (PRUint32) + PRUnichar*len
nsCheapStringBufferUtils::Clone(mValue.mString, aCopy.mValue.mString);
} else {
mValue.mString = ToNewUnicode(nsDependentString(aCopy.mValue.mString));
}
} else {
mValue.mString = nsnull;
}
break;
case HTMLUNIT_INTEGER:
case HTMLUNIT_PIXEL:
mValue.mInt = aCopy.mValue.mInt;
break;
case HTMLUNIT_COLOR:
mValue.mColor = aCopy.mValue.mColor;
break;
case HTMLUNIT_ISUPPORTS:
mValue.mISupports = aCopy.mValue.mISupports;
NS_IF_ADDREF(mValue.mISupports);
break;
case HTMLUNIT_PERCENT:
mValue.mFloat = aCopy.mValue.mFloat;
break;
default:
NS_ERROR("Unknown HTMLValue type!");
}
}

View File

@@ -43,130 +43,20 @@
#include "nsString.h" #include "nsString.h"
#include "nsISupports.h" #include "nsISupports.h"
#include "nsReadableUtils.h"
#include "nsCRT.h"
class nsCheapStringBufferUtils {
public:
/**
* Get the string pointer
* @param aBuf the buffer
* @return a pointer to the string
*/
static const PRUnichar* StrPtr(const PRUnichar* aBuf) {
NS_ASSERTION(aBuf, "Cannot work on null buffer!");
return (const PRUnichar*)( ((const char*)aBuf) + sizeof(PRUint32) );
}
static PRUnichar* StrPtr(PRUnichar* aBuf) {
NS_ASSERTION(aBuf, "Cannot work on null buffer!");
return (PRUnichar*)( ((char*)aBuf) + sizeof(PRUint32) );
}
/**
* Get the string length
* @param aBuf the buffer
* @return the string length
*/
static PRUint32 Length(const PRUnichar* aBuf) {
NS_ASSERTION(aBuf, "Cannot work on null buffer!");
return *((PRUint32*)aBuf);
}
/**
* Get a DependentString from a buffer
*
* @param aBuf the buffer to get string from
* @return a DependentString representing this string
*/
static nsDependentSingleFragmentSubstring GetDependentString(const PRUnichar* aBuf) {
NS_ASSERTION(aBuf, "Cannot work on null buffer!");
const PRUnichar* buf = StrPtr(aBuf);
return Substring(buf, buf + Length(aBuf));
}
/**
* Construct from an AString
* @param aBuf the buffer to copy to
* @param aStr the string to construct from
* @param aLen the length of the string (passed for efficiency)
*/
static void CopyToBuffer(PRUnichar*& aBuf, const nsAString& aStr, PRUint32 aLen) {
NS_ASSERTION(aStr.Length() == aLen, "Wrong length passed in!");
aBuf = (PRUnichar*)nsMemory::Alloc(sizeof(PRUint32) +
aLen * sizeof(PRUnichar));
*((PRUint32*)aBuf) = aLen;
CopyUnicodeTo(aStr, 0, StrPtr(aBuf), aLen);
}
/**
* Construct from another nsCheapStringBuffer
* @param aBuf the buffer to put into
* @param aSrc the buffer to construct from
*/
static void Clone(PRUnichar*& aBuf, const PRUnichar* aSrc) {
NS_ASSERTION(aSrc, "Cannot work on null buffer!");
aBuf = (PRUnichar*)nsMemory::Clone(aSrc, sizeof(PRUint32) +
Length(aSrc) * sizeof(PRUnichar));
}
/**
* Free the memory for the buf
* @param aBuf the buffer to free
*/
static void Free(PRUnichar* aBuf) {
NS_ASSERTION(aBuf, "Cannot work on null buffer!");
nsMemory::Free(aBuf);
}
/**
* Get a hashcode for the buffer
* @param aBuf the buffer
* @return the hashcode
*/
static PRUint32 HashCode(const PRUnichar* aBuf) {
NS_ASSERTION(aBuf, "Cannot work on null buffer!");
return nsCRT::BufferHashCode((char*)StrPtr(aBuf),
Length(aBuf)*sizeof(PRUnichar));
}
};
//
// nsHTMLUnit is two bytes: the class of type, and a specifier to distinguish
// between different things stored as the same type. Doing
// mUnit & HTMLUNIT_CLASS_MASK should give you the class of type.
//
#define HTMLUNIT_NOSTORE 0x0000
#define HTMLUNIT_STRING 0x0100
#define HTMLUNIT_INTEGER 0x0200
#define HTMLUNIT_PIXEL 0x0400
#define HTMLUNIT_COLOR 0x0800
#define HTMLUNIT_ISUPPORTS 0x1000
#define HTMLUNIT_PERCENT 0x2000
#define HTMLUNIT_CLASS_MASK 0xff00
enum nsHTMLUnit { enum nsHTMLUnit {
// null, value is not specified: 0x0000 eHTMLUnit_Null = 0, // (n/a) null unit, value is not specified
eHTMLUnit_Null = HTMLUNIT_NOSTORE, eHTMLUnit_Empty = 1, // (n/a) empty unit, value is not specified
// empty, value is not specified: 0x0001 eHTMLUnit_String = 10, // (nsString) a string value
eHTMLUnit_Empty = HTMLUNIT_NOSTORE | 1, eHTMLUnit_ISupports = 20, // (nsISupports*) a ref counted interface
eHTMLUnit_Integer = 50, // (int) simple value
eHTMLUnit_Enumerated = 51, // (int) value has enumerated meaning
eHTMLUnit_Proportional = 52, // (int) value is a relative proportion of some whole
eHTMLUnit_Color = 80, // (color) an RGBA value
eHTMLUnit_ColorName = 81, // (nsString/color) a color name value
eHTMLUnit_Percent = 90, // (float) 1.0 == 100%) value is percentage of something
// a string value // Screen relative measure
eHTMLUnit_String = HTMLUNIT_STRING, eHTMLUnit_Pixel = 600 // (int) screen pixels
// a color name value
eHTMLUnit_ColorName = HTMLUNIT_STRING | 1,
// a simple int value
eHTMLUnit_Integer = HTMLUNIT_INTEGER,
// value has enumerated meaning
eHTMLUnit_Enumerated = HTMLUNIT_INTEGER | 1,
// value is a relative proportion of some whole
eHTMLUnit_Proportional = HTMLUNIT_INTEGER | 2,
// screen pixels (screen relative measure)
eHTMLUnit_Pixel = HTMLUNIT_PIXEL,
// an RGBA value
eHTMLUnit_Color = HTMLUNIT_COLOR,
// (nsISupports*) a ref counted interface
eHTMLUnit_ISupports = HTMLUNIT_ISUPPORTS,
// (1.0 == 100%) value is percentage of something
eHTMLUnit_Percent = HTMLUNIT_PERCENT
}; };
/** /**
@@ -191,12 +81,7 @@ public:
PRBool operator!=(const nsHTMLValue& aOther) const; PRBool operator!=(const nsHTMLValue& aOther) const;
PRUint32 HashValue(void) const; PRUint32 HashValue(void) const;
/** nsHTMLUnit GetUnit(void) const { return mUnit; }
* Get the unit of this HTMLValue
* @return the unit of this HTMLValue
*/
nsHTMLUnit GetUnit(void) const { return (nsHTMLUnit)mUnit; }
PRInt32 GetIntValue(void) const; PRInt32 GetIntValue(void) const;
PRInt32 GetPixelValue(void) const; PRInt32 GetPixelValue(void) const;
float GetPercentValue(void) const; float GetPercentValue(void) const;
@@ -204,9 +89,6 @@ public:
nsISupports* GetISupportsValue(void) const; nsISupports* GetISupportsValue(void) const;
nscolor GetColorValue(void) const; nscolor GetColorValue(void) const;
/**
* Reset the string to null type, freeing things in the process if necessary.
*/
void Reset(void); void Reset(void);
void SetIntValue(PRInt32 aValue, nsHTMLUnit aUnit); void SetIntValue(PRInt32 aValue, nsHTMLUnit aUnit);
void SetPixelValue(PRInt32 aValue); void SetPixelValue(PRInt32 aValue);
@@ -221,98 +103,34 @@ public:
#endif #endif
protected: protected:
/** nsHTMLUnit mUnit;
* The unit of the value
* @see nsHTMLUnit
*/
PRUint16 mUnit;
/** Flags indicating specifics of the storage format (HTMLSTORAGE_*) */
PRUint16 mStorageFlags;
/**
* The actual value. Please to not be adding more-than-4-byte things to this
* union.
*/
union { union {
/** Int. */
PRInt32 mInt; PRInt32 mInt;
/** Float. */
float mFloat; float mFloat;
/**
* String. Depending on mStorageFlags & HTMLSTORAGE_STRWITHLEN, this may be
* stored with the first 4 bytes being the length (this is done for
* embedded nulls and long strings).
*/
PRUnichar* mString; PRUnichar* mString;
/** ISupports. Strong reference. */
nsISupports* mISupports; nsISupports* mISupports;
/** Color. */
nscolor mColor; nscolor mColor;
} mValue; } mValue;
private:
/**
* Copy into this HTMLValue from aCopy. Please be aware that if this is an
* existing HTMLValue and you do not call Reset(), this will leak.
* @param aCopy the value to copy
*/
void InitializeFrom(const nsHTMLValue& aCopy);
/**
* Helper to set string value (checks for embedded nulls or length); verifies
* that aUnit is a string type as well.
* @param aValue the value to set
* @param aUnit the unit to set
*/
void SetStringValueInternal(const nsAString& aValue, nsHTMLUnit aUnit);
/**
* Get a DependentString from mValue.mString (if the string is stored with
* length, passes that information to the DependentString). Do not call this
* if mValue.mString is null.
*
* @return a DependentString representing this string
*/
nsDependentSingleFragmentSubstring GetDependentString() const;
/**
* Get the unit class (HTMLUNIT_*)
* @return the unit class
*/
PRUint32 GetUnitClass() const { return mUnit & HTMLUNIT_CLASS_MASK; }
}; };
/** Indicates that a string is stored as an nsCheapStringBuffer */
#define HTMLSTORAGE_NORMAL 0
#define HTMLSTORAGE_STRWITHLEN 1
inline nsDependentSingleFragmentSubstring nsHTMLValue::GetDependentString() const
{
NS_ASSERTION(GetUnitClass() == HTMLUNIT_STRING,
"Some dork called GetDependentString() on a non-string!");
NS_ASSERTION(mValue.mString, "buffer is null! This is bad.");
// If it is stored in string-with-length format, use the length properly
return (mStorageFlags & HTMLSTORAGE_STRWITHLEN) ?
nsCheapStringBufferUtils::GetDependentString(mValue.mString) :
Substring(mValue.mString,
mValue.mString
+ nsCharTraits<PRUnichar>::length(mValue.mString));
}
inline PRInt32 nsHTMLValue::GetIntValue(void) const inline PRInt32 nsHTMLValue::GetIntValue(void) const
{ {
NS_ASSERTION(GetUnitClass() == HTMLUNIT_STRING || NS_ASSERTION((mUnit == eHTMLUnit_String) ||
GetUnitClass() == HTMLUNIT_INTEGER, (mUnit == eHTMLUnit_Integer) ||
"not an int value"); (mUnit == eHTMLUnit_Enumerated) ||
PRUint32 unitClass = GetUnitClass(); (mUnit == eHTMLUnit_Proportional), "not an int value");
if (unitClass == HTMLUNIT_INTEGER) { if ((mUnit == eHTMLUnit_Integer) ||
(mUnit == eHTMLUnit_Enumerated) ||
(mUnit == eHTMLUnit_Proportional)) {
return mValue.mInt; return mValue.mInt;
} }
else if (mUnit == eHTMLUnit_String) {
if (unitClass == HTMLUNIT_STRING) {
if (mValue.mString) { if (mValue.mString) {
PRInt32 err=0; PRInt32 err=0;
// XXX this copies. new string APIs will make this better, right? nsAutoString str(mValue.mString); // XXX copy. new string APIs will make this better, right?
nsAutoString str(GetDependentString());
return str.ToInteger(&err); return str.ToInteger(&err);
} }
} }
return 0; return 0;
} }
@@ -336,12 +154,12 @@ inline float nsHTMLValue::GetPercentValue(void) const
inline nsAString& nsHTMLValue::GetStringValue(nsAString& aBuffer) const inline nsAString& nsHTMLValue::GetStringValue(nsAString& aBuffer) const
{ {
NS_ASSERTION(GetUnitClass() == HTMLUNIT_STRING || mUnit == eHTMLUnit_Null, NS_ASSERTION((mUnit == eHTMLUnit_String) || (mUnit == eHTMLUnit_ColorName) ||
"not a string value"); (mUnit == eHTMLUnit_Null), "not a string value");
if (GetUnitClass() == HTMLUNIT_STRING && mValue.mString) { aBuffer.SetLength(0);
aBuffer = GetDependentString(); if (((mUnit == eHTMLUnit_String) || (mUnit == eHTMLUnit_ColorName)) &&
} else { (nsnull != mValue.mString)) {
aBuffer.Truncate(); aBuffer.Append(mValue.mString);
} }
return aBuffer; return aBuffer;
} }

View File

@@ -43,130 +43,20 @@
#include "nsString.h" #include "nsString.h"
#include "nsISupports.h" #include "nsISupports.h"
#include "nsReadableUtils.h"
#include "nsCRT.h"
class nsCheapStringBufferUtils {
public:
/**
* Get the string pointer
* @param aBuf the buffer
* @return a pointer to the string
*/
static const PRUnichar* StrPtr(const PRUnichar* aBuf) {
NS_ASSERTION(aBuf, "Cannot work on null buffer!");
return (const PRUnichar*)( ((const char*)aBuf) + sizeof(PRUint32) );
}
static PRUnichar* StrPtr(PRUnichar* aBuf) {
NS_ASSERTION(aBuf, "Cannot work on null buffer!");
return (PRUnichar*)( ((char*)aBuf) + sizeof(PRUint32) );
}
/**
* Get the string length
* @param aBuf the buffer
* @return the string length
*/
static PRUint32 Length(const PRUnichar* aBuf) {
NS_ASSERTION(aBuf, "Cannot work on null buffer!");
return *((PRUint32*)aBuf);
}
/**
* Get a DependentString from a buffer
*
* @param aBuf the buffer to get string from
* @return a DependentString representing this string
*/
static nsDependentSingleFragmentSubstring GetDependentString(const PRUnichar* aBuf) {
NS_ASSERTION(aBuf, "Cannot work on null buffer!");
const PRUnichar* buf = StrPtr(aBuf);
return Substring(buf, buf + Length(aBuf));
}
/**
* Construct from an AString
* @param aBuf the buffer to copy to
* @param aStr the string to construct from
* @param aLen the length of the string (passed for efficiency)
*/
static void CopyToBuffer(PRUnichar*& aBuf, const nsAString& aStr, PRUint32 aLen) {
NS_ASSERTION(aStr.Length() == aLen, "Wrong length passed in!");
aBuf = (PRUnichar*)nsMemory::Alloc(sizeof(PRUint32) +
aLen * sizeof(PRUnichar));
*((PRUint32*)aBuf) = aLen;
CopyUnicodeTo(aStr, 0, StrPtr(aBuf), aLen);
}
/**
* Construct from another nsCheapStringBuffer
* @param aBuf the buffer to put into
* @param aSrc the buffer to construct from
*/
static void Clone(PRUnichar*& aBuf, const PRUnichar* aSrc) {
NS_ASSERTION(aSrc, "Cannot work on null buffer!");
aBuf = (PRUnichar*)nsMemory::Clone(aSrc, sizeof(PRUint32) +
Length(aSrc) * sizeof(PRUnichar));
}
/**
* Free the memory for the buf
* @param aBuf the buffer to free
*/
static void Free(PRUnichar* aBuf) {
NS_ASSERTION(aBuf, "Cannot work on null buffer!");
nsMemory::Free(aBuf);
}
/**
* Get a hashcode for the buffer
* @param aBuf the buffer
* @return the hashcode
*/
static PRUint32 HashCode(const PRUnichar* aBuf) {
NS_ASSERTION(aBuf, "Cannot work on null buffer!");
return nsCRT::BufferHashCode((char*)StrPtr(aBuf),
Length(aBuf)*sizeof(PRUnichar));
}
};
//
// nsHTMLUnit is two bytes: the class of type, and a specifier to distinguish
// between different things stored as the same type. Doing
// mUnit & HTMLUNIT_CLASS_MASK should give you the class of type.
//
#define HTMLUNIT_NOSTORE 0x0000
#define HTMLUNIT_STRING 0x0100
#define HTMLUNIT_INTEGER 0x0200
#define HTMLUNIT_PIXEL 0x0400
#define HTMLUNIT_COLOR 0x0800
#define HTMLUNIT_ISUPPORTS 0x1000
#define HTMLUNIT_PERCENT 0x2000
#define HTMLUNIT_CLASS_MASK 0xff00
enum nsHTMLUnit { enum nsHTMLUnit {
// null, value is not specified: 0x0000 eHTMLUnit_Null = 0, // (n/a) null unit, value is not specified
eHTMLUnit_Null = HTMLUNIT_NOSTORE, eHTMLUnit_Empty = 1, // (n/a) empty unit, value is not specified
// empty, value is not specified: 0x0001 eHTMLUnit_String = 10, // (nsString) a string value
eHTMLUnit_Empty = HTMLUNIT_NOSTORE | 1, eHTMLUnit_ISupports = 20, // (nsISupports*) a ref counted interface
eHTMLUnit_Integer = 50, // (int) simple value
eHTMLUnit_Enumerated = 51, // (int) value has enumerated meaning
eHTMLUnit_Proportional = 52, // (int) value is a relative proportion of some whole
eHTMLUnit_Color = 80, // (color) an RGBA value
eHTMLUnit_ColorName = 81, // (nsString/color) a color name value
eHTMLUnit_Percent = 90, // (float) 1.0 == 100%) value is percentage of something
// a string value // Screen relative measure
eHTMLUnit_String = HTMLUNIT_STRING, eHTMLUnit_Pixel = 600 // (int) screen pixels
// a color name value
eHTMLUnit_ColorName = HTMLUNIT_STRING | 1,
// a simple int value
eHTMLUnit_Integer = HTMLUNIT_INTEGER,
// value has enumerated meaning
eHTMLUnit_Enumerated = HTMLUNIT_INTEGER | 1,
// value is a relative proportion of some whole
eHTMLUnit_Proportional = HTMLUNIT_INTEGER | 2,
// screen pixels (screen relative measure)
eHTMLUnit_Pixel = HTMLUNIT_PIXEL,
// an RGBA value
eHTMLUnit_Color = HTMLUNIT_COLOR,
// (nsISupports*) a ref counted interface
eHTMLUnit_ISupports = HTMLUNIT_ISUPPORTS,
// (1.0 == 100%) value is percentage of something
eHTMLUnit_Percent = HTMLUNIT_PERCENT
}; };
/** /**
@@ -191,12 +81,7 @@ public:
PRBool operator!=(const nsHTMLValue& aOther) const; PRBool operator!=(const nsHTMLValue& aOther) const;
PRUint32 HashValue(void) const; PRUint32 HashValue(void) const;
/** nsHTMLUnit GetUnit(void) const { return mUnit; }
* Get the unit of this HTMLValue
* @return the unit of this HTMLValue
*/
nsHTMLUnit GetUnit(void) const { return (nsHTMLUnit)mUnit; }
PRInt32 GetIntValue(void) const; PRInt32 GetIntValue(void) const;
PRInt32 GetPixelValue(void) const; PRInt32 GetPixelValue(void) const;
float GetPercentValue(void) const; float GetPercentValue(void) const;
@@ -204,9 +89,6 @@ public:
nsISupports* GetISupportsValue(void) const; nsISupports* GetISupportsValue(void) const;
nscolor GetColorValue(void) const; nscolor GetColorValue(void) const;
/**
* Reset the string to null type, freeing things in the process if necessary.
*/
void Reset(void); void Reset(void);
void SetIntValue(PRInt32 aValue, nsHTMLUnit aUnit); void SetIntValue(PRInt32 aValue, nsHTMLUnit aUnit);
void SetPixelValue(PRInt32 aValue); void SetPixelValue(PRInt32 aValue);
@@ -221,98 +103,34 @@ public:
#endif #endif
protected: protected:
/** nsHTMLUnit mUnit;
* The unit of the value
* @see nsHTMLUnit
*/
PRUint16 mUnit;
/** Flags indicating specifics of the storage format (HTMLSTORAGE_*) */
PRUint16 mStorageFlags;
/**
* The actual value. Please to not be adding more-than-4-byte things to this
* union.
*/
union { union {
/** Int. */
PRInt32 mInt; PRInt32 mInt;
/** Float. */
float mFloat; float mFloat;
/**
* String. Depending on mStorageFlags & HTMLSTORAGE_STRWITHLEN, this may be
* stored with the first 4 bytes being the length (this is done for
* embedded nulls and long strings).
*/
PRUnichar* mString; PRUnichar* mString;
/** ISupports. Strong reference. */
nsISupports* mISupports; nsISupports* mISupports;
/** Color. */
nscolor mColor; nscolor mColor;
} mValue; } mValue;
private:
/**
* Copy into this HTMLValue from aCopy. Please be aware that if this is an
* existing HTMLValue and you do not call Reset(), this will leak.
* @param aCopy the value to copy
*/
void InitializeFrom(const nsHTMLValue& aCopy);
/**
* Helper to set string value (checks for embedded nulls or length); verifies
* that aUnit is a string type as well.
* @param aValue the value to set
* @param aUnit the unit to set
*/
void SetStringValueInternal(const nsAString& aValue, nsHTMLUnit aUnit);
/**
* Get a DependentString from mValue.mString (if the string is stored with
* length, passes that information to the DependentString). Do not call this
* if mValue.mString is null.
*
* @return a DependentString representing this string
*/
nsDependentSingleFragmentSubstring GetDependentString() const;
/**
* Get the unit class (HTMLUNIT_*)
* @return the unit class
*/
PRUint32 GetUnitClass() const { return mUnit & HTMLUNIT_CLASS_MASK; }
}; };
/** Indicates that a string is stored as an nsCheapStringBuffer */
#define HTMLSTORAGE_NORMAL 0
#define HTMLSTORAGE_STRWITHLEN 1
inline nsDependentSingleFragmentSubstring nsHTMLValue::GetDependentString() const
{
NS_ASSERTION(GetUnitClass() == HTMLUNIT_STRING,
"Some dork called GetDependentString() on a non-string!");
NS_ASSERTION(mValue.mString, "buffer is null! This is bad.");
// If it is stored in string-with-length format, use the length properly
return (mStorageFlags & HTMLSTORAGE_STRWITHLEN) ?
nsCheapStringBufferUtils::GetDependentString(mValue.mString) :
Substring(mValue.mString,
mValue.mString
+ nsCharTraits<PRUnichar>::length(mValue.mString));
}
inline PRInt32 nsHTMLValue::GetIntValue(void) const inline PRInt32 nsHTMLValue::GetIntValue(void) const
{ {
NS_ASSERTION(GetUnitClass() == HTMLUNIT_STRING || NS_ASSERTION((mUnit == eHTMLUnit_String) ||
GetUnitClass() == HTMLUNIT_INTEGER, (mUnit == eHTMLUnit_Integer) ||
"not an int value"); (mUnit == eHTMLUnit_Enumerated) ||
PRUint32 unitClass = GetUnitClass(); (mUnit == eHTMLUnit_Proportional), "not an int value");
if (unitClass == HTMLUNIT_INTEGER) { if ((mUnit == eHTMLUnit_Integer) ||
(mUnit == eHTMLUnit_Enumerated) ||
(mUnit == eHTMLUnit_Proportional)) {
return mValue.mInt; return mValue.mInt;
} }
else if (mUnit == eHTMLUnit_String) {
if (unitClass == HTMLUNIT_STRING) {
if (mValue.mString) { if (mValue.mString) {
PRInt32 err=0; PRInt32 err=0;
// XXX this copies. new string APIs will make this better, right? nsAutoString str(mValue.mString); // XXX copy. new string APIs will make this better, right?
nsAutoString str(GetDependentString());
return str.ToInteger(&err); return str.ToInteger(&err);
} }
} }
return 0; return 0;
} }
@@ -336,12 +154,12 @@ inline float nsHTMLValue::GetPercentValue(void) const
inline nsAString& nsHTMLValue::GetStringValue(nsAString& aBuffer) const inline nsAString& nsHTMLValue::GetStringValue(nsAString& aBuffer) const
{ {
NS_ASSERTION(GetUnitClass() == HTMLUNIT_STRING || mUnit == eHTMLUnit_Null, NS_ASSERTION((mUnit == eHTMLUnit_String) || (mUnit == eHTMLUnit_ColorName) ||
"not a string value"); (mUnit == eHTMLUnit_Null), "not a string value");
if (GetUnitClass() == HTMLUNIT_STRING && mValue.mString) { aBuffer.SetLength(0);
aBuffer = GetDependentString(); if (((mUnit == eHTMLUnit_String) || (mUnit == eHTMLUnit_ColorName)) &&
} else { (nsnull != mValue.mString)) {
aBuffer.Truncate(); aBuffer.Append(mValue.mString);
} }
return aBuffer; return aBuffer;
} }

View File

@@ -42,60 +42,94 @@
#include "nsReadableUtils.h" #include "nsReadableUtils.h"
#include "nsUnicharUtils.h" #include "nsUnicharUtils.h"
#include "nsCRT.h" #include "nsCRT.h"
#include "nsMemory.h"
nsHTMLValue::nsHTMLValue(nsHTMLUnit aUnit) nsHTMLValue::nsHTMLValue(nsHTMLUnit aUnit)
: mUnit(aUnit), mStorageFlags(HTMLSTORAGE_NORMAL) : mUnit(aUnit)
{ {
NS_ASSERTION(GetUnitClass() == HTMLUNIT_NOSTORE, "not a valueless unit"); NS_ASSERTION((aUnit <= eHTMLUnit_Empty), "not a valueless unit");
if (GetUnitClass() != HTMLUNIT_NOSTORE) { if (aUnit > eHTMLUnit_Empty) {
mUnit = eHTMLUnit_Null; mUnit = eHTMLUnit_Null;
} }
mValue.mString = nsnull; mValue.mString = nsnull;
} }
nsHTMLValue::nsHTMLValue(PRInt32 aValue, nsHTMLUnit aUnit) nsHTMLValue::nsHTMLValue(PRInt32 aValue, nsHTMLUnit aUnit)
: mUnit(aUnit), mStorageFlags(HTMLSTORAGE_NORMAL) : mUnit(aUnit)
{ {
NS_ASSERTION(GetUnitClass() == HTMLUNIT_INTEGER || NS_ASSERTION((eHTMLUnit_Integer == aUnit) ||
GetUnitClass() == HTMLUNIT_PIXEL, "unit not an integer unit"); (eHTMLUnit_Enumerated == aUnit) ||
if (GetUnitClass() == HTMLUNIT_INTEGER || (eHTMLUnit_Proportional == aUnit) ||
GetUnitClass() == HTMLUNIT_PIXEL) { (eHTMLUnit_Pixel == aUnit), "not an integer value");
if ((eHTMLUnit_Integer == aUnit) ||
(eHTMLUnit_Enumerated == aUnit) ||
(eHTMLUnit_Proportional == aUnit) ||
(eHTMLUnit_Pixel == aUnit)) {
mValue.mInt = aValue; mValue.mInt = aValue;
} else { }
else {
mUnit = eHTMLUnit_Null; mUnit = eHTMLUnit_Null;
mValue.mString = nsnull; mValue.mInt = 0;
} }
} }
nsHTMLValue::nsHTMLValue(float aValue) nsHTMLValue::nsHTMLValue(float aValue)
: mUnit(eHTMLUnit_Percent), mStorageFlags(HTMLSTORAGE_NORMAL) : mUnit(eHTMLUnit_Percent)
{ {
mValue.mFloat = aValue; mValue.mFloat = aValue;
} }
nsHTMLValue::nsHTMLValue(const nsAString& aValue, nsHTMLUnit aUnit) nsHTMLValue::nsHTMLValue(const nsAString& aValue, nsHTMLUnit aUnit)
: mUnit(aUnit), mStorageFlags(HTMLSTORAGE_NORMAL) : mUnit(aUnit)
{ {
SetStringValueInternal(aValue, aUnit); NS_ASSERTION((eHTMLUnit_String == aUnit) ||
(eHTMLUnit_ColorName == aUnit), "not a string value");
if ((eHTMLUnit_String == aUnit) ||
(eHTMLUnit_ColorName == aUnit)) {
mValue.mString = ToNewUnicode(aValue);
}
else {
mUnit = eHTMLUnit_Null;
mValue.mInt = 0;
}
} }
nsHTMLValue::nsHTMLValue(nsISupports* aValue) nsHTMLValue::nsHTMLValue(nsISupports* aValue)
: mUnit(eHTMLUnit_ISupports), mStorageFlags(HTMLSTORAGE_NORMAL) : mUnit(eHTMLUnit_ISupports)
{ {
mValue.mISupports = aValue; mValue.mISupports = aValue;
NS_IF_ADDREF(mValue.mISupports); NS_IF_ADDREF(mValue.mISupports);
} }
nsHTMLValue::nsHTMLValue(nscolor aValue) nsHTMLValue::nsHTMLValue(nscolor aValue)
: mUnit(eHTMLUnit_Color), mStorageFlags(HTMLSTORAGE_NORMAL) : mUnit(eHTMLUnit_Color)
{ {
mValue.mColor = aValue; mValue.mColor = aValue;
} }
nsHTMLValue::nsHTMLValue(const nsHTMLValue& aCopy) nsHTMLValue::nsHTMLValue(const nsHTMLValue& aCopy)
: mUnit(aCopy.mUnit)
{ {
InitializeFrom(aCopy); if ((eHTMLUnit_String == mUnit) || (eHTMLUnit_ColorName == mUnit)) {
if (nsnull != aCopy.mValue.mString) {
mValue.mString = nsCRT::strdup(aCopy.mValue.mString);
}
else {
mValue.mString = nsnull;
}
}
else if (eHTMLUnit_ISupports == mUnit) {
mValue.mISupports = aCopy.mValue.mISupports;
NS_IF_ADDREF(mValue.mISupports);
}
else if (eHTMLUnit_Color == mUnit){
mValue.mColor = aCopy.mValue.mColor;
}
else if (eHTMLUnit_Percent == mUnit) {
mValue.mFloat = aCopy.mValue.mFloat;
}
else {
mValue.mInt = aCopy.mValue.mInt;
}
} }
nsHTMLValue::~nsHTMLValue(void) nsHTMLValue::~nsHTMLValue(void)
@@ -106,81 +140,79 @@ nsHTMLValue::~nsHTMLValue(void)
nsHTMLValue& nsHTMLValue::operator=(const nsHTMLValue& aCopy) nsHTMLValue& nsHTMLValue::operator=(const nsHTMLValue& aCopy)
{ {
Reset(); Reset();
InitializeFrom(aCopy); mUnit = aCopy.mUnit;
if ((eHTMLUnit_String == mUnit) || (eHTMLUnit_ColorName == mUnit)) {
if (nsnull != aCopy.mValue.mString) {
mValue.mString = nsCRT::strdup(aCopy.mValue.mString);
}
}
else if (eHTMLUnit_ISupports == mUnit) {
mValue.mISupports = aCopy.mValue.mISupports;
NS_IF_ADDREF(mValue.mISupports);
}
else if (eHTMLUnit_Color == mUnit){
mValue.mColor = aCopy.mValue.mColor;
}
else if (eHTMLUnit_Percent == mUnit) {
mValue.mFloat = aCopy.mValue.mFloat;
}
else {
mValue.mInt = aCopy.mValue.mInt;
}
return *this; return *this;
} }
PRBool nsHTMLValue::operator==(const nsHTMLValue& aOther) const PRBool nsHTMLValue::operator==(const nsHTMLValue& aOther) const
{ {
if (mUnit != aOther.mUnit) { if (mUnit == aOther.mUnit) {
return PR_FALSE; if ((eHTMLUnit_String == mUnit) || (eHTMLUnit_ColorName == mUnit)) {
} if (nsnull == mValue.mString) {
// Call GetUnit() so that we turn StringWithLength into String if (nsnull == aOther.mValue.mString) {
PRUint32 unitClass = GetUnitClass();
switch (unitClass) {
case HTMLUNIT_NOSTORE:
return PR_TRUE; return PR_TRUE;
}
case HTMLUNIT_STRING: }
if (mValue.mString && aOther.mValue.mString) { else if (nsnull != aOther.mValue.mString) {
return GetDependentString().Equals(aOther.GetDependentString(), return nsDependentString(mValue.mString).Equals(nsDependentString(aOther.mValue.mString),
nsCaseInsensitiveStringComparator()); nsCaseInsensitiveStringComparator());
} }
// One of them is null. An == check will see if they are both null.
return mValue.mString == aOther.mValue.mString;
case HTMLUNIT_INTEGER:
case HTMLUNIT_PIXEL:
return mValue.mInt == aOther.mValue.mInt;
case HTMLUNIT_COLOR:
return mValue.mColor == aOther.mValue.mColor;
case HTMLUNIT_ISUPPORTS:
return mValue.mISupports == aOther.mValue.mISupports;
case HTMLUNIT_PERCENT:
return mValue.mFloat == aOther.mValue.mFloat;
default:
NS_WARNING("Unknown unit");
return PR_TRUE;
} }
else if (eHTMLUnit_ISupports == mUnit) {
return PRBool(mValue.mISupports == aOther.mValue.mISupports);
}
else if (eHTMLUnit_Color == mUnit){
return PRBool(mValue.mColor == aOther.mValue.mColor);
}
else if (eHTMLUnit_Percent == mUnit) {
return PRBool(mValue.mFloat == aOther.mValue.mFloat);
}
else {
return PRBool(mValue.mInt == aOther.mValue.mInt);
}
}
return PR_FALSE;
} }
PRUint32 nsHTMLValue::HashValue(void) const PRUint32 nsHTMLValue::HashValue(void) const
{ {
PRUint32 retval; return PRUint32(mUnit) ^
if (GetUnitClass() == HTMLUNIT_STRING) { ((((eHTMLUnit_String == mUnit) || (eHTMLUnit_ColorName == mUnit)) &&
if (mStorageFlags & HTMLSTORAGE_STRWITHLEN) { (nsnull != mValue.mString)) ?
retval = mValue.mString ? nsCheapStringBufferUtils::HashCode(mValue.mString) nsCRT::HashCode(mValue.mString) :
: 0; mValue.mInt);
} else {
retval = mValue.mString ? nsCRT::HashCode(mValue.mString) : 0;
}
} else {
retval = mValue.mInt;
}
return retval ^ PRUint32(mUnit);
} }
void nsHTMLValue::Reset(void) void nsHTMLValue::Reset(void)
{ {
if (GetUnitClass() == HTMLUNIT_STRING) { if ((eHTMLUnit_String == mUnit) || (eHTMLUnit_ColorName == mUnit)) {
if (mValue.mString) { if (nsnull != mValue.mString) {
if (mStorageFlags & HTMLSTORAGE_STRWITHLEN) { nsCRT::free(mValue.mString);
nsCheapStringBufferUtils::Free(mValue.mString);
} else {
nsMemory::Free(mValue.mString);
} }
} }
} else if (eHTMLUnit_ISupports == mUnit) {
else if (mUnit == eHTMLUnit_ISupports) {
NS_IF_RELEASE(mValue.mISupports); NS_IF_RELEASE(mValue.mISupports);
} }
mUnit = eHTMLUnit_Null; mUnit = eHTMLUnit_Null;
mStorageFlags = 0;
mValue.mString = nsnull; mValue.mString = nsnull;
} }
@@ -188,12 +220,14 @@ void nsHTMLValue::Reset(void)
void nsHTMLValue::SetIntValue(PRInt32 aValue, nsHTMLUnit aUnit) void nsHTMLValue::SetIntValue(PRInt32 aValue, nsHTMLUnit aUnit)
{ {
Reset(); Reset();
NS_ASSERTION((eHTMLUnit_Integer == aUnit) ||
(eHTMLUnit_Enumerated == aUnit) ||
(eHTMLUnit_Proportional == aUnit), "not an int value");
if ((eHTMLUnit_Integer == aUnit) ||
(eHTMLUnit_Enumerated == aUnit) ||
(eHTMLUnit_Proportional == aUnit)) {
mUnit = aUnit; mUnit = aUnit;
NS_ASSERTION(GetUnitClass() == HTMLUNIT_INTEGER, "not an int value");
if (GetUnitClass() == HTMLUNIT_INTEGER) {
mValue.mInt = aValue; mValue.mInt = aValue;
} else {
mUnit = eHTMLUnit_Null;
} }
} }
@@ -211,50 +245,14 @@ void nsHTMLValue::SetPercentValue(float aValue)
mValue.mFloat = aValue; mValue.mFloat = aValue;
} }
static inline PRBool
ShouldStoreLength(const nsAString& aStr, PRUint32 aLen)
{
// Always remember the length of the string if the length is greater than 30
if (aLen > 30) {
return PR_TRUE;
}
// Obviously never remember the length of the string if it is empty :)
if (aLen == 0) {
return PR_FALSE;
}
// Remember the length of the string if it has embedded nulls
nsAString::const_iterator begin, end;
return FindCharInReadable('\0', aStr.BeginReading(begin),
aStr.EndReading(end));
}
void nsHTMLValue::SetStringValueInternal(const nsAString& aValue,
nsHTMLUnit aUnit)
{
NS_ASSERTION(GetUnitClass() == HTMLUNIT_STRING, "unit not a string unit!");
if (GetUnitClass() == HTMLUNIT_STRING) {
// Remember the length of the string if necessary
PRUint32 len = aValue.Length();
if (ShouldStoreLength(aValue, len)) {
mStorageFlags = HTMLSTORAGE_STRWITHLEN;
nsCheapStringBufferUtils::CopyToBuffer(mValue.mString, aValue, len);
return;
}
// Else just store as a normal string
mValue.mString = ToNewUnicode(aValue);
} else {
mUnit = eHTMLUnit_Null;
mValue.mString = nsnull;
}
}
void nsHTMLValue::SetStringValue(const nsAString& aValue, void nsHTMLValue::SetStringValue(const nsAString& aValue,
nsHTMLUnit aUnit) nsHTMLUnit aUnit)
{ {
Reset(); Reset();
if ((eHTMLUnit_String == aUnit) || (eHTMLUnit_ColorName == aUnit)) {
mUnit = aUnit; mUnit = aUnit;
SetStringValueInternal(aValue, aUnit); mValue.mString = ToNewUnicode(aValue);
}
} }
void nsHTMLValue::SetISupportsValue(nsISupports* aValue) void nsHTMLValue::SetISupportsValue(nsISupports* aValue)
@@ -281,32 +279,29 @@ void nsHTMLValue::SetEmptyValue(void)
#ifdef DEBUG #ifdef DEBUG
void nsHTMLValue::AppendToString(nsAString& aBuffer) const void nsHTMLValue::AppendToString(nsAString& aBuffer) const
{ {
switch (GetUnitClass()) { if (eHTMLUnit_Null == mUnit) {
case HTMLUNIT_NOSTORE: return;
break; }
case HTMLUNIT_STRING:
if (mValue.mString) { if (eHTMLUnit_Empty == mUnit) {
}
else if ((eHTMLUnit_String == mUnit) || (eHTMLUnit_ColorName == mUnit)) {
if (nsnull != mValue.mString) {
aBuffer.Append(PRUnichar('"')); aBuffer.Append(PRUnichar('"'));
aBuffer.Append(GetDependentString()); aBuffer.Append(mValue.mString);
aBuffer.Append(PRUnichar('"')); aBuffer.Append(PRUnichar('"'));
} else { }
else {
aBuffer.Append(NS_LITERAL_STRING("null str")); aBuffer.Append(NS_LITERAL_STRING("null str"));
} }
break; }
case HTMLUNIT_INTEGER: else if (eHTMLUnit_ISupports == mUnit) {
case HTMLUNIT_PIXEL: aBuffer.Append(NS_LITERAL_STRING("0x"));
{
nsAutoString intStr; nsAutoString intStr;
intStr.AppendInt(mValue.mInt, 10); intStr.AppendInt(NS_PTR_TO_INT32(mValue.mISupports), 16);
intStr.Append(NS_LITERAL_STRING("[0x"));
intStr.AppendInt(mValue.mInt, 16);
intStr.Append(PRUnichar(']'));
aBuffer.Append(intStr); aBuffer.Append(intStr);
} }
break; else if (eHTMLUnit_Color == mUnit){
case HTMLUNIT_COLOR:
{
nsAutoString intStr; nsAutoString intStr;
intStr.Append(NS_LITERAL_STRING("(0x")); intStr.Append(NS_LITERAL_STRING("(0x"));
intStr.AppendInt(NS_GET_R(mValue.mColor), 16); intStr.AppendInt(NS_GET_R(mValue.mColor), 16);
@@ -320,33 +315,28 @@ void nsHTMLValue::AppendToString(nsAString& aBuffer) const
aBuffer.Append(intStr); aBuffer.Append(intStr);
} }
break; else if (eHTMLUnit_Percent == mUnit) {
case HTMLUNIT_ISUPPORTS:
{
aBuffer.Append(NS_LITERAL_STRING("0x"));
nsAutoString intStr;
intStr.AppendInt(NS_PTR_TO_INT32(mValue.mISupports), 16);
aBuffer.Append(intStr);
}
break;
case HTMLUNIT_PERCENT:
{
nsAutoString floatStr; nsAutoString floatStr;
floatStr.AppendFloat(mValue.mFloat * 100.0f); floatStr.AppendFloat(mValue.mFloat * 100.0f);
aBuffer.Append(floatStr); aBuffer.Append(floatStr);
} }
break; else {
default: nsAutoString intStr;
NS_ERROR("Unknown HTMLValue type!"); intStr.AppendInt(mValue.mInt, 10);
intStr.Append(NS_LITERAL_STRING("[0x"));
intStr.AppendInt(mValue.mInt, 16);
intStr.Append(PRUnichar(']'));
aBuffer.Append(intStr);
} }
//
// Append the type name for types that are ambiguous
//
switch (mUnit) { switch (mUnit) {
case eHTMLUnit_Null: aBuffer.Append(NS_LITERAL_STRING("null")); break; case eHTMLUnit_Null: break;
case eHTMLUnit_Empty: aBuffer.Append(NS_LITERAL_STRING("empty")); break; case eHTMLUnit_Empty: break;
case eHTMLUnit_String: break;
case eHTMLUnit_ColorName: break;
case eHTMLUnit_ISupports: aBuffer.Append(NS_LITERAL_STRING("ptr")); break; case eHTMLUnit_ISupports: aBuffer.Append(NS_LITERAL_STRING("ptr")); break;
case eHTMLUnit_Integer: break;
case eHTMLUnit_Enumerated: aBuffer.Append(NS_LITERAL_STRING("enum")); break; case eHTMLUnit_Enumerated: aBuffer.Append(NS_LITERAL_STRING("enum")); break;
case eHTMLUnit_Proportional: aBuffer.Append(NS_LITERAL_STRING("*")); break; case eHTMLUnit_Proportional: aBuffer.Append(NS_LITERAL_STRING("*")); break;
case eHTMLUnit_Color: aBuffer.Append(NS_LITERAL_STRING("rbga")); break; case eHTMLUnit_Color: aBuffer.Append(NS_LITERAL_STRING("rbga")); break;
@@ -356,49 +346,3 @@ void nsHTMLValue::AppendToString(nsAString& aBuffer) const
aBuffer.Append(PRUnichar(' ')); aBuffer.Append(PRUnichar(' '));
} }
#endif // DEBUG #endif // DEBUG
void
nsHTMLValue::InitializeFrom(const nsHTMLValue& aCopy)
{
mUnit = aCopy.mUnit;
mStorageFlags = aCopy.mStorageFlags;
switch (GetUnitClass()) {
case HTMLUNIT_NOSTORE:
mValue.mString = nsnull;
break;
case HTMLUNIT_STRING:
if (aCopy.mValue.mString) {
if (aCopy.mStorageFlags & HTMLSTORAGE_STRWITHLEN) {
// Clone the string = (PRUint32) + PRUnichar*len
nsCheapStringBufferUtils::Clone(mValue.mString, aCopy.mValue.mString);
} else {
mValue.mString = ToNewUnicode(nsDependentString(aCopy.mValue.mString));
}
} else {
mValue.mString = nsnull;
}
break;
case HTMLUNIT_INTEGER:
case HTMLUNIT_PIXEL:
mValue.mInt = aCopy.mValue.mInt;
break;
case HTMLUNIT_COLOR:
mValue.mColor = aCopy.mValue.mColor;
break;
case HTMLUNIT_ISUPPORTS:
mValue.mISupports = aCopy.mValue.mISupports;
NS_IF_ADDREF(mValue.mISupports);
break;
case HTMLUNIT_PERCENT:
mValue.mFloat = aCopy.mValue.mFloat;
break;
default:
NS_ERROR("Unknown HTMLValue type!");
}
}

View File

@@ -1649,49 +1649,41 @@ nsCSSFrameConstructor::CreateInputFrame(nsIPresShell *aPresShell,
nsIFrame *&aFrame, nsIFrame *&aFrame,
nsIStyleContext *aStyleContext) nsIStyleContext *aStyleContext)
{ {
nsCOMPtr<nsIFormControl> control = do_QueryInterface(aContent); // Figure out which type of input frame to create
NS_ASSERTION(control, "input is not an nsIFormControl!"); nsAutoString val;
if (NS_OK == aContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::type, val)) {
PRInt32 type; if (val.EqualsIgnoreCase("submit") ||
control->GetType(&type); val.EqualsIgnoreCase("reset") ||
switch (type) { val.EqualsIgnoreCase("button")) {
case NS_FORM_INPUT_SUBMIT:
case NS_FORM_INPUT_RESET:
case NS_FORM_INPUT_BUTTON:
if (UseXBLForms()) if (UseXBLForms())
return NS_OK; return NS_OK;
return ConstructButtonControlFrame(aPresShell, aPresContext, aFrame); return ConstructButtonControlFrame(aPresShell, aPresContext, aFrame);
}
case NS_FORM_INPUT_CHECKBOX: else if (val.EqualsIgnoreCase("checkbox")) {
if (UseXBLForms()) if (UseXBLForms())
return NS_OK; return NS_OK;
return ConstructCheckboxControlFrame(aPresShell, aPresContext, aFrame, aContent, aStyleContext); return ConstructCheckboxControlFrame(aPresShell, aPresContext, aFrame, aContent, aStyleContext);
}
case NS_FORM_INPUT_RADIO: else if (val.EqualsIgnoreCase("file")) {
return NS_NewFileControlFrame(aPresShell, &aFrame);
}
else if (val.EqualsIgnoreCase("hidden")) {
return NS_OK;
}
else if (val.EqualsIgnoreCase("image")) {
return NS_NewImageControlFrame(aPresShell, &aFrame);
}
else if (val.EqualsIgnoreCase("radio")) {
if (UseXBLForms()) if (UseXBLForms())
return NS_OK; return NS_OK;
return ConstructRadioControlFrame(aPresShell, aPresContext, aFrame, aContent, aStyleContext); return ConstructRadioControlFrame(aPresShell, aPresContext, aFrame, aContent, aStyleContext);
case NS_FORM_INPUT_FILE:
return NS_NewFileControlFrame(aPresShell, &aFrame);
case NS_FORM_INPUT_HIDDEN:
return NS_OK;
case NS_FORM_INPUT_IMAGE:
return NS_NewImageControlFrame(aPresShell, &aFrame);
case NS_FORM_INPUT_TEXT:
case NS_FORM_INPUT_PASSWORD:
return ConstructTextControlFrame(aPresShell, aPresContext,
aFrame, aContent);
default:
NS_ASSERTION(0, "Unknown input type!");
return NS_ERROR_INVALID_ARG;
} }
} }
// "password", "text", and all others
return ConstructTextControlFrame(aPresShell, aPresContext, aFrame, aContent);
}
static PRBool static PRBool
IsOnlyWhiteSpace(nsIContent* aContent) IsOnlyWhiteSpace(nsIContent* aContent)
{ {

View File

@@ -1649,49 +1649,41 @@ nsCSSFrameConstructor::CreateInputFrame(nsIPresShell *aPresShell,
nsIFrame *&aFrame, nsIFrame *&aFrame,
nsIStyleContext *aStyleContext) nsIStyleContext *aStyleContext)
{ {
nsCOMPtr<nsIFormControl> control = do_QueryInterface(aContent); // Figure out which type of input frame to create
NS_ASSERTION(control, "input is not an nsIFormControl!"); nsAutoString val;
if (NS_OK == aContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::type, val)) {
PRInt32 type; if (val.EqualsIgnoreCase("submit") ||
control->GetType(&type); val.EqualsIgnoreCase("reset") ||
switch (type) { val.EqualsIgnoreCase("button")) {
case NS_FORM_INPUT_SUBMIT:
case NS_FORM_INPUT_RESET:
case NS_FORM_INPUT_BUTTON:
if (UseXBLForms()) if (UseXBLForms())
return NS_OK; return NS_OK;
return ConstructButtonControlFrame(aPresShell, aPresContext, aFrame); return ConstructButtonControlFrame(aPresShell, aPresContext, aFrame);
}
case NS_FORM_INPUT_CHECKBOX: else if (val.EqualsIgnoreCase("checkbox")) {
if (UseXBLForms()) if (UseXBLForms())
return NS_OK; return NS_OK;
return ConstructCheckboxControlFrame(aPresShell, aPresContext, aFrame, aContent, aStyleContext); return ConstructCheckboxControlFrame(aPresShell, aPresContext, aFrame, aContent, aStyleContext);
}
case NS_FORM_INPUT_RADIO: else if (val.EqualsIgnoreCase("file")) {
return NS_NewFileControlFrame(aPresShell, &aFrame);
}
else if (val.EqualsIgnoreCase("hidden")) {
return NS_OK;
}
else if (val.EqualsIgnoreCase("image")) {
return NS_NewImageControlFrame(aPresShell, &aFrame);
}
else if (val.EqualsIgnoreCase("radio")) {
if (UseXBLForms()) if (UseXBLForms())
return NS_OK; return NS_OK;
return ConstructRadioControlFrame(aPresShell, aPresContext, aFrame, aContent, aStyleContext); return ConstructRadioControlFrame(aPresShell, aPresContext, aFrame, aContent, aStyleContext);
case NS_FORM_INPUT_FILE:
return NS_NewFileControlFrame(aPresShell, &aFrame);
case NS_FORM_INPUT_HIDDEN:
return NS_OK;
case NS_FORM_INPUT_IMAGE:
return NS_NewImageControlFrame(aPresShell, &aFrame);
case NS_FORM_INPUT_TEXT:
case NS_FORM_INPUT_PASSWORD:
return ConstructTextControlFrame(aPresShell, aPresContext,
aFrame, aContent);
default:
NS_ASSERTION(0, "Unknown input type!");
return NS_ERROR_INVALID_ARG;
} }
} }
// "password", "text", and all others
return ConstructTextControlFrame(aPresShell, aPresContext, aFrame, aContent);
}
static PRBool static PRBool
IsOnlyWhiteSpace(nsIContent* aContent) IsOnlyWhiteSpace(nsIContent* aContent)
{ {