Made nsIProperties scriptable. Bug #21982

This commit is contained in:
warren%netscape.com 2000-01-05 09:29:25 +00:00
parent 5370d83dc2
commit 06918ca494
15 changed files with 56 additions and 518 deletions

View File

@ -24,7 +24,7 @@
#include "nsID.h"
#include "nsString2.h"
#include "nsIProperties.h"
#include "nsIPersistentProperties.h"
#include "nsIStringBundle.h"
#include "nscore.h"
#include "nsILocale.h"

View File

@ -22,7 +22,7 @@
#define NS_IMPL_IDS
#include "nsIProperties.h"
#include "nsIPersistentProperties.h"
#include "nsIStringBundle.h"
#include "nsIEventQueueService.h"
#include "nsILocale.h"

View File

@ -23,7 +23,7 @@
#ifndef nsURLProperties_h__
#define nsURLProperties_h__
#include "nsIProperties.h"
#include "nsIPersistentProperties.h"
#include "nsString.h"
class nsURLProperties {

View File

@ -22,7 +22,7 @@
#include "nsIEntityConverter.h"
#include "nsIFactory.h"
#include "nsIProperties.h"
#include "nsIPersistentProperties.h"
nsresult NS_NewEntityConverter(nsISupports** oResult);

View File

@ -28,7 +28,7 @@
#include "nsISaveAsCharset.h"
#include "nsIUnicodeEncoder.h"
#include "nsUnicharUtilCIID.h"
#include "nsIProperties.h"
#include "nsIPersistentProperties.h"
#include "nsIURL.h"
#include "nsNetUtil.h"
#include "nsCOMPtr.h"

View File

@ -45,7 +45,7 @@
//#include "nsEscape.h"
#include "nsIEventQueueService.h"
#include "nsIProperties.h"
#include "nsIPersistentProperties.h"
#include "nsIServiceManager.h"
#include "nsIURL.h"
#include "nsIIOService.h"

View File

@ -26,6 +26,7 @@
#include "nsObserverService.h"
#include "nsObserver.h"
#include "nsProperties.h"
#include "nsPersistentProperties.h"
#include "nsScriptableInputStream.h"
#include "nsAllocator.h"

View File

@ -8,7 +8,7 @@ nsHashtableEnumerator.h
nsIArena.h
nsIByteBuffer.h
nsIObserverList.h
nsIProperties.h
nsIPersistentProperties.h
nsISimpleEnumerator.h
nsISizeOfHandler.h
nsIUnicharBuffer.h

View File

@ -3,4 +3,8 @@ nsICollection.idl
nsIEnumerator.idl
nsIObserver.idl
nsIObserverService.idl
nsIProperties.idl
nsIStopwatch.idl
nsIProperties.idl
nsIStopwatch.idl
nsISupportsArray.idl

View File

@ -48,6 +48,7 @@ CPPSRCS = \
nsObserverList.cpp \
nsObserverService.cpp \
nsProperties.cpp \
nsPersistentProperties.cpp \
nsQuickSort.cpp \
nsSizeOfHandler.cpp \
nsStr.cpp \
@ -74,7 +75,7 @@ EXPORTS = \
nsIArena.h \
nsIByteBuffer.h \
nsIObserverList.h \
nsIProperties.h \
nsIPersistentProperties.h \
nsISimpleEnumerator.h \
nsISizeOfHandler.h \
nsIUnicharBuffer.h \
@ -100,6 +101,7 @@ XPIDLSRCS = \
nsIEnumerator.idl \
nsIObserver.idl \
nsIObserverService.idl \
nsIProperties.idl \
nsISupportsArray.idl \
nsISupportsPrimitives.idl \
$(NULL)

View File

@ -39,7 +39,7 @@ EXPORTS = \
nsIArena.h \
nsIByteBuffer.h \
nsIObserverList.h \
nsIProperties.h \
nsIPersistentProperties.h \
nsISimpleEnumerator.h \
nsISizeOfHandler.h \
nsIUnicharBuffer.h \
@ -66,6 +66,7 @@ XPIDLSRCS = \
.\nsIEnumerator.idl \
.\nsIObserver.idl \
.\nsIObserverService.idl \
.\nsIProperties.idl \
.\nsISupportsArray.idl \
.\nsISupportsPrimitives.idl \
$(NULL)
@ -100,6 +101,7 @@ CPP_OBJS = \
.\$(OBJDIR)\nsObserverList.obj \
.\$(OBJDIR)\nsObserverService.obj \
.\$(OBJDIR)\nsProperties.obj \
.\$(OBJDIR)\nsPersistentProperties.obj \
.\$(OBJDIR)\nsQuickSort.obj \
.\$(OBJDIR)\nsSizeOfHandler.obj \
.\$(OBJDIR)\nsStr.obj \

View File

@ -18,14 +18,13 @@
* Rights Reserved.
*
* Contributor(s):
* Pierre Phaneuf <pp@ludusdesign.com>
*/
#define NS_IMPL_IDS
#include "nsProperties.h"
#include <iostream.h>
//#include <iostream.h>
////////////////////////////////////////////////////////////////////////////////
@ -38,15 +37,15 @@ NS_METHOD
nsProperties::Create(nsISupports *outer, REFNSIID aIID, void **aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
NS_ENSURE_PROPER_AGGREGATION(outer, aIID);
NS_ENSURE_PROPER_AGGREGATION(outer, aIID);
nsProperties* props = new nsProperties(outer);
if (props == NULL)
return NS_ERROR_OUT_OF_MEMORY;
nsresult rv = props->AggregatedQueryInterface(aIID, aResult);
if (NS_FAILED(rv))
delete props;
if (NS_FAILED(rv))
delete props;
return rv;
}
@ -70,21 +69,21 @@ nsProperties::AggregatedQueryInterface(const nsIID& aIID, void** aInstancePtr)
{
NS_ENSURE_ARG_POINTER(aInstancePtr);
if (aIID.Equals(NS_GET_IID(nsISupports)))
*aInstancePtr = GetInner();
else if (aIID.Equals(NS_GET_IID(nsIProperties)))
*aInstancePtr = NS_STATIC_CAST(nsIProperties*, this);
else {
*aInstancePtr = nsnull;
return NS_NOINTERFACE;
if (aIID.Equals(NS_GET_IID(nsISupports)))
*aInstancePtr = GetInner();
else if (aIID.Equals(NS_GET_IID(nsIProperties)))
*aInstancePtr = NS_STATIC_CAST(nsIProperties*, this);
else {
*aInstancePtr = nsnull;
return NS_NOINTERFACE;
}
NS_ADDREF((nsISupports*)*aInstancePtr);
NS_ADDREF((nsISupports*)*aInstancePtr);
return NS_OK;
}
NS_IMETHODIMP
nsProperties::DefineProperty(const char* prop, nsISupports* initialValue)
nsProperties::Define(const char* prop, nsISupports* initialValue)
{
nsStringKey key(prop);
if (Exists(&key))
@ -97,7 +96,7 @@ nsProperties::DefineProperty(const char* prop, nsISupports* initialValue)
}
NS_IMETHODIMP
nsProperties::UndefineProperty(const char* prop)
nsProperties::Undefine(const char* prop)
{
nsStringKey key(prop);
if (!Exists(&key))
@ -109,448 +108,47 @@ nsProperties::UndefineProperty(const char* prop)
}
NS_IMETHODIMP
nsProperties::GetProperty(const char* prop, nsISupports* *result)
nsProperties::Get(const char* prop, const nsIID & uuid, void* *result)
{
nsresult rv;
nsStringKey key(prop);
if (!Exists(&key))
return NS_ERROR_FAILURE;
nsISupports* value = (nsISupports*)Get(&key);
NS_IF_ADDREF(value);
*result = value;
return NS_OK;
nsISupports* value = (nsISupports*)nsHashtable::Get(&key);
if (value) {
rv = value->QueryInterface(uuid, result);
}
else {
rv = NS_ERROR_FAILURE;
}
return rv;
}
NS_IMETHODIMP
nsProperties::SetProperty(const char* prop, nsISupports* value)
nsProperties::Set(const char* prop, nsISupports* value)
{
nsStringKey key(prop);
if (!Exists(&key))
return NS_ERROR_FAILURE;
nsISupports* prevValue = (nsISupports*)Put(&key, value);
NS_IF_RELEASE(prevValue);
NS_RELEASE(prevValue);
NS_IF_ADDREF(value);
return NS_OK;
}
NS_IMETHODIMP
nsProperties::HasProperty(const char* prop, nsISupports* expectedValue)
nsProperties::Has(const char* prop, const nsIID & uuid,
nsISupports* expectedValue, PRBool *result)
{
nsISupports* value;
nsresult rv = GetProperty(prop, &value);
if (NS_FAILED(rv)) return rv;
rv = (value == expectedValue) ? NS_OK : NS_ERROR_FAILURE;
NS_IF_RELEASE(value);
return rv;
}
////////////////////////////////////////////////////////////////////////////////
nsresult
NS_NewIProperties(nsIProperties* *result)
{
return nsProperties::Create(NULL, NS_GET_IID(nsIProperties), (void**)result);
}
////////////////////////////////////////////////////////////////////////////////
// Persistent Properties (should go in a separate file)
////////////////////////////////////////////////////////////////////////////////
#include "nsID.h"
#include "nsCRT.h"
#include "nsIInputStream.h"
#include "nsIProperties.h"
#include "nsIUnicharInputStream.h"
#include "nsProperties.h"
#include "pratom.h"
static PLHashNumber
HashKey(const PRUnichar *aString)
{
return (PLHashNumber) nsCRT::HashValue(aString);
}
static PRIntn
CompareKeys(const PRUnichar *aStr1, const PRUnichar *aStr2)
{
return nsCRT::strcmp(aStr1, aStr2) == 0;
}
nsPersistentProperties::nsPersistentProperties()
{
NS_INIT_REFCNT();
mIn = nsnull;
mSubclass = NS_STATIC_CAST(nsIPersistentProperties*, this);
mTable = PL_NewHashTable(8, (PLHashFunction) HashKey,
(PLHashComparator) CompareKeys,
(PLHashComparator) nsnull, nsnull, nsnull);
}
PR_STATIC_CALLBACK(PRIntn)
FreeHashEntries(PLHashEntry* he, PRIntn i, void* arg)
{
nsCRT::free((PRUnichar*)he->key);
nsCRT::free((PRUnichar*)he->value);
return HT_ENUMERATE_REMOVE;
}
nsPersistentProperties::~nsPersistentProperties()
{
if (mTable) {
// Free the PRUnicode* pointers contained in the hash table entries
PL_HashTableEnumerateEntries(mTable, FreeHashEntries, 0);
PL_HashTableDestroy(mTable);
mTable = nsnull;
}
}
NS_METHOD
nsPersistentProperties::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsPersistentProperties* props = new nsPersistentProperties();
if (props == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(props);
nsresult rv = props->QueryInterface(aIID, aResult);
NS_RELEASE(props);
return rv;
}
NS_IMPL_ISUPPORTS2(nsPersistentProperties, nsIPersistentProperties, nsIProperties)
NS_IMETHODIMP
nsPersistentProperties::Load(nsIInputStream *aIn)
{
PRInt32 c;
nsresult ret;
nsAutoString uesc("x-u-escaped");
ret = NS_NewConverterStream(&mIn, nsnull, aIn, 0, &uesc);
if (ret != NS_OK) {
#ifdef NS_DEBUG
cout << "NS_NewConverterStream failed" << endl;
#endif
return NS_ERROR_FAILURE;
}
c = Read();
while (1) {
c = SkipWhiteSpace(c);
if (c < 0) {
break;
}
else if ((c == '#') || (c == '!')) {
c = SkipLine(c);
continue;
}
else {
nsAutoString key("");
while ((c >= 0) && (c != '=') && (c != ':')) {
key.Append((PRUnichar) c);
c = Read();
}
if (c < 0) {
break;
}
char *trimThese = " \t";
key.Trim(trimThese, PR_FALSE, PR_TRUE);
c = Read();
nsAutoString value("");
while ((c >= 0) && (c != '\r') && (c != '\n')) {
if (c == '\\') {
c = Read();
if ((c == '\r') || (c == '\n')) {
c = SkipWhiteSpace(c);
}
else {
value.Append('\\');
}
nsCOMPtr<nsISupports> value;
nsresult rv = Get(prop, uuid, getter_AddRefs(value));
if (NS_SUCCEEDED(rv)) {
if (value == expectedValue) {
*result = PR_TRUE;
return NS_OK;
}
value.Append((PRUnichar) c);
c = Read();
}
value.Trim(trimThese, PR_TRUE, PR_TRUE);
nsAutoString oldValue("");
mSubclass->SetStringProperty(key, value, oldValue);
}
}
mIn->Close();
NS_RELEASE(mIn);
NS_ASSERTION(!mIn, "unexpected remaining reference");
return NS_OK;
}
NS_IMETHODIMP
nsPersistentProperties::SetStringProperty(const nsString& aKey, nsString& aNewValue,
nsString& aOldValue)
{
// XXX The ToNewCString() calls allocate memory using "new" so this code
// causes a memory leak...
#if 0
cout << "will add " << aKey.ToNewCString() << "=" << aNewValue.ToNewCString() << endl;
#endif
if (!mTable) {
return NS_ERROR_FAILURE;
}
const PRUnichar *key = aKey.GetUnicode(); // returns internal pointer (not a copy)
PRUint32 len;
PRUint32 hashValue = nsCRT::HashValue(key, &len);
PLHashEntry **hep = PL_HashTableRawLookup(mTable, hashValue, key);
PLHashEntry *he = *hep;
if (he) {
// XXX should we copy the old value to aOldValue, and then remove it?
#ifdef NS_DEBUG
char buf[128];
aKey.ToCString(buf, sizeof(buf));
printf("warning: property %s already exists\n", buf);
#endif
*result = PR_FALSE;
return NS_OK;
}
PL_HashTableRawAdd(mTable, hep, hashValue, aKey.ToNewUnicode(),
aNewValue.ToNewUnicode());
return NS_OK;
}
NS_IMETHODIMP
nsPersistentProperties::Save(nsIOutputStream* aOut, const nsString& aHeader)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsPersistentProperties::Subclass(nsIPersistentProperties* aSubclass)
{
if (aSubclass) {
mSubclass = aSubclass;
}
return NS_OK;
}
NS_IMETHODIMP
nsPersistentProperties::GetStringProperty(const nsString& aKey, nsString& aValue)
{
if (!mTable)
return NS_ERROR_FAILURE;
const PRUnichar *key = aKey.GetUnicode();
if (!mTable) {
return NS_ERROR_FAILURE;
}
PRUint32 len;
PRUint32 hashValue = nsCRT::HashValue(key, &len);
PLHashEntry **hep = PL_HashTableRawLookup(mTable, hashValue, key);
PLHashEntry *he = *hep;
if (he) {
aValue = (const PRUnichar*)he->value;
return NS_OK;
}
return NS_ERROR_FAILURE;
}
PR_STATIC_CALLBACK(PRIntn)
AddElemToArray(PLHashEntry* he, PRIntn i, void* arg)
{
nsISupportsArray *propArray = (nsISupportsArray *) arg;
nsString* keyStr = new nsString((PRUnichar*) he->key);
nsString* valueStr = new nsString((PRUnichar*) he->value);
nsPropertyElement *element = new nsPropertyElement();
if (!element)
return HT_ENUMERATE_STOP;
NS_ADDREF(element);
element->SetKey(keyStr);
element->SetValue(valueStr);
propArray->InsertElementAt(element, i);
return HT_ENUMERATE_NEXT;
}
NS_IMETHODIMP
nsPersistentProperties::EnumerateProperties(nsIBidirectionalEnumerator** aResult)
{
if (!mTable)
return NS_ERROR_FAILURE;
nsISupportsArray* propArray;
nsresult rv = NS_NewISupportsArray(&propArray);
if (rv != NS_OK)
return rv;
// Step through hash entries populating a transient array
PRIntn n = PL_HashTableEnumerateEntries(mTable, AddElemToArray, (void *)propArray);
if ( n < (PRIntn) mTable->nentries )
return NS_ERROR_OUT_OF_MEMORY;
// Convert array into enumerator
rv = NS_NewISupportsArrayEnumerator(propArray, aResult);
if (rv != NS_OK)
return rv;
return NS_OK;
}
PRInt32
nsPersistentProperties::Read()
{
PRUnichar c;
PRUint32 nRead;
nsresult ret;
ret = mIn->Read(&c, 0, 1, &nRead);
if (ret == NS_OK && nRead == 1) {
return c;
}
return -1;
}
#define IS_WHITE_SPACE(c) \
(((c) == ' ') || ((c) == '\t') || ((c) == '\r') || ((c) == '\n'))
PRInt32
nsPersistentProperties::SkipWhiteSpace(PRInt32 c)
{
while ((c >= 0) && IS_WHITE_SPACE(c)) {
c = Read();
}
return c;
}
PRInt32
nsPersistentProperties::SkipLine(PRInt32 c)
{
while ((c >= 0) && (c != '\r') && (c != '\n')) {
c = Read();
}
if (c == '\r') {
c = Read();
}
if (c == '\n') {
c = Read();
}
return c;
}
////////////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsPersistentProperties::DefineProperty(const char* prop, nsISupports* initialValue)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsPersistentProperties::UndefineProperty(const char* prop)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsPersistentProperties::GetProperty(const char* prop, nsISupports* *result)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsPersistentProperties::SetProperty(const char* prop, nsISupports* value)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsPersistentProperties::HasProperty(const char* prop, nsISupports* value)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
////////////////////////////////////////////////////////////////////////////////
// PropertyElement
////////////////////////////////////////////////////////////////////////////////
nsPropertyElement::nsPropertyElement()
{
NS_INIT_REFCNT();
mKey = nsnull;
mValue = nsnull;
}
nsPropertyElement::~nsPropertyElement()
{
if (mKey)
delete mKey;
if (mValue)
delete mValue;
}
NS_METHOD
nsPropertyElement::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsPropertyElement* propElem = new nsPropertyElement();
if (propElem == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(propElem);
nsresult rv = propElem->QueryInterface(aIID, aResult);
NS_RELEASE(propElem);
return rv;
}
NS_IMPL_ISUPPORTS1(nsPropertyElement, nsIPropertyElement)
NS_IMETHODIMP
nsPropertyElement::GetKey(nsString** aReturnKey)
{
if (aReturnKey)
{
*aReturnKey = mKey;
return NS_OK;
}
return NS_ERROR_INVALID_POINTER;
}
NS_IMETHODIMP
nsPropertyElement::GetValue(nsString** aReturnValue)
{
if (aReturnValue)
{
*aReturnValue = mValue;
return NS_OK;
}
return NS_ERROR_INVALID_POINTER;
}
NS_IMETHODIMP
nsPropertyElement::SetKey(nsString* aKey)
{
mKey = aKey;
return NS_OK;
}
NS_IMETHODIMP
nsPropertyElement::SetValue(nsString* aValue)
{
mValue = aValue;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -33,15 +33,8 @@ class nsProperties : public nsIProperties, public nsHashtable {
public:
NS_DECL_AGGREGATED
NS_DECL_NSIPROPERTIES
// nsIProperties methods:
NS_IMETHOD DefineProperty(const char* prop, nsISupports* initialValue);
NS_IMETHOD UndefineProperty(const char* prop);
NS_IMETHOD GetProperty(const char* prop, nsISupports* *result);
NS_IMETHOD SetProperty(const char* prop, nsISupports* value);
NS_IMETHOD HasProperty(const char* prop, nsISupports* value);
// nsProperties methods:
nsProperties(nsISupports* outer);
virtual ~nsProperties();
@ -52,66 +45,4 @@ public:
};
class nsPersistentProperties : public nsIPersistentProperties
{
public:
nsPersistentProperties();
virtual ~nsPersistentProperties();
NS_DECL_ISUPPORTS
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
// nsIProperties methods:
NS_IMETHOD DefineProperty(const char* prop, nsISupports* initialValue);
NS_IMETHOD UndefineProperty(const char* prop);
NS_IMETHOD GetProperty(const char* prop, nsISupports* *result);
NS_IMETHOD SetProperty(const char* prop, nsISupports* value);
NS_IMETHOD HasProperty(const char* prop, nsISupports* value);
// nsIPersistentProperties methods:
NS_IMETHOD Load(nsIInputStream* aIn);
NS_IMETHOD Save(nsIOutputStream* aOut, const nsString& aHeader);
NS_IMETHOD Subclass(nsIPersistentProperties* aSubclass);
NS_IMETHOD EnumerateProperties(nsIBidirectionalEnumerator* *aResult);
// XXX these 2 methods will be subsumed by the ones from
// nsIProperties once we figure this all out
NS_IMETHOD GetStringProperty(const nsString& aKey, nsString& aValue);
NS_IMETHOD SetStringProperty(const nsString& aKey, nsString& aNewValue,
nsString& aOldValue);
// nsPersistentProperties methods:
PRInt32 Read();
PRInt32 SkipLine(PRInt32 c);
PRInt32 SkipWhiteSpace(PRInt32 c);
nsIUnicharInputStream* mIn;
nsIPersistentProperties* mSubclass;
struct PLHashTable* mTable;
};
class nsPropertyElement : public nsIPropertyElement
{
public:
nsPropertyElement();
virtual ~nsPropertyElement();
NS_DECL_ISUPPORTS
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
// nsIPropertyElement methods:
NS_IMETHOD GetKey(nsString** aReturnKey);
NS_IMETHOD GetValue(nsString** aReturnValue);
NS_IMETHOD SetKey(nsString* aKey);
NS_IMETHOD SetValue(nsString* aValue);
protected:
nsString* mKey;
nsString* mValue;
};
#endif /* nsProperties_h___ */

View File

@ -24,7 +24,7 @@
#define NS_IMPL_IDS
#include "nsIEventQueueService.h"
#include "nsIProperties.h"
#include "nsIPersistentProperties.h"
#include "nsIServiceManager.h"
#include "nsIURL.h"
#include "nsIIOService.h"

View File

@ -53,7 +53,7 @@
#include "nsIEventQueueService.h"
#include "nsIServiceManager.h"
#include "nsIComponentManager.h"
#include "nsIProperties.h"
#include "nsIPersistentProperties.h"
#include "nsIEnumerator.h"
#include "nsIZipReader.h"