Compare commits

..

2 Commits

Author SHA1 Message Date
fur%netscape.com
1c43d4984f This is a copy of regalloc_code2_BRANCH from Netscape's private repository,
as it existed in January of 1998.


git-svn-id: svn://10.0.0.236/branches/regalloc_code2_BRANCH@22571 18797224-902f-48f8-a5cc-f745e15eee43
1999-03-02 16:12:08 +00:00
(no author)
cfe021ff88 This commit was manufactured by cvs2svn to create branch
'regalloc_code2_BRANCH'.

git-svn-id: svn://10.0.0.236/branches/regalloc_code2_BRANCH@22567 18797224-902f-48f8-a5cc-f745e15eee43
1999-03-02 15:57:58 +00:00
300 changed files with 5202 additions and 75968 deletions

View File

@@ -1,107 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsIServiceManager.h"
#include "nsIComponentManager.h"
#include "nsIGenericFactory.h"
#include "nsIChromeRegistry.h"
#include "nscore.h"
#include "rdf.h"
static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
static NS_DEFINE_CID(kGenericFactoryCID, NS_GENERICFACTORY_CID);
static NS_DEFINE_CID(kChromeRegistryCID, NS_CHROMEREGISTRY_CID);
static NS_IMETHODIMP
NS_ConstructChromeRegistry(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
nsresult rv;
NS_ASSERTION(aOuter == nsnull, "no aggregation");
nsIChromeRegistry* chromeRegistry;
rv = NS_NewChromeRegistry(&chromeRegistry);
if (NS_FAILED(rv)) {
NS_ERROR("Unable to construct chrome registry");
return rv;
}
rv = chromeRegistry->QueryInterface(aIID, aResult);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to find correct interface");
NS_RELEASE(chromeRegistry);
return rv;
}
extern "C" PR_IMPLEMENT(nsresult)
NSGetFactory(nsISupports* aServMgr,
const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFactory **aFactory)
{
nsresult rv;
NS_ASSERTION(aFactory != nsnull, "bad factory pointer");
NS_ASSERTION(aClass.Equals(kChromeRegistryCID), "incorrectly registered");
NS_WITH_SERVICE1(nsIComponentManager, compMgr,
aServMgr, kComponentManagerCID, &rv);
if (NS_FAILED(rv)) return rv;
nsIGenericFactory* factory;
rv = compMgr->CreateInstance(kGenericFactoryCID, nsnull, nsIGenericFactory::GetIID(),
(void**)&factory);
if (NS_FAILED(rv)) return rv;
rv = factory->SetConstructor(NS_ConstructChromeRegistry);
if (NS_FAILED(rv)) {
delete factory;
return rv;
}
NS_ADDREF(factory);
*aFactory = factory;
return NS_OK;
}
extern "C" PR_IMPLEMENT(nsresult)
NSRegisterSelf(nsISupports* aServMgr , const char* aPath)
{
nsresult rv;
NS_WITH_SERVICE1(nsIComponentManager, compMgr,
aServMgr, kComponentManagerCID, &rv);
if (NS_FAILED(rv)) return rv;
rv = compMgr->RegisterComponent(kChromeRegistryCID,
"Chrome Registry",
NS_RDF_DATASOURCE_PROGID_PREFIX "chrome",
aPath,
PR_TRUE, PR_TRUE);
return rv;
}
extern "C" PR_IMPLEMENT(nsresult)
NSUnregisterSelf(nsISupports* aServMgr, const char* aPath)
{
nsresult rv;
NS_WITH_SERVICE1(nsIComponentManager, compMgr,
aServMgr, kComponentManagerCID, &rv);
if (NS_FAILED(rv)) return rv;
rv = compMgr->UnregisterComponent(kChromeRegistryCID, aPath);
return rv;
}

View File

@@ -1,601 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsCOMPtr.h"
#include "nsFileSpec.h"
#include "nsSpecialSystemDirectory.h"
#include "nsIChromeRegistry.h"
#include "nsIRDFObserver.h"
#include "nsCRT.h"
#include "rdf.h"
#include "nsIServiceManager.h"
#include "nsIRDFService.h"
#include "nsRDFCID.h"
#include "nsIRDFResource.h"
#include "nsIRDFDataSource.h"
#include "nsHashtable.h"
#include "nsString.h"
#include "nsXPIDLString.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIRDFResourceIID, NS_IRDFRESOURCE_IID);
static NS_DEFINE_IID(kIRDFLiteralIID, NS_IRDFLITERAL_IID);
static NS_DEFINE_IID(kIRDFServiceIID, NS_IRDFSERVICE_IID);
static NS_DEFINE_IID(kIRDFDataSourceIID, NS_IRDFDATASOURCE_IID);
static NS_DEFINE_CID(kRDFXMLDataSourceCID, NS_RDFXMLDATASOURCE_CID);
static NS_DEFINE_IID(kIRDFIntIID, NS_IRDFINT_IID);
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
#define CHROME_NAMESPACE_URI "http://chrome.mozilla.org/rdf#"
DEFINE_RDF_VOCAB(CHROME_NAMESPACE_URI, CHROME, chrome);
DEFINE_RDF_VOCAB(CHROME_NAMESPACE_URI, CHROME, skin);
DEFINE_RDF_VOCAB(CHROME_NAMESPACE_URI, CHROME, content);
DEFINE_RDF_VOCAB(CHROME_NAMESPACE_URI, CHROME, locale);
DEFINE_RDF_VOCAB(CHROME_NAMESPACE_URI, CHROME, platform);
DEFINE_RDF_VOCAB(CHROME_NAMESPACE_URI, CHROME, behavior);
DEFINE_RDF_VOCAB(CHROME_NAMESPACE_URI, CHROME, base);
DEFINE_RDF_VOCAB(CHROME_NAMESPACE_URI, CHROME, main);
DEFINE_RDF_VOCAB(CHROME_NAMESPACE_URI, CHROME, archive);
DEFINE_RDF_VOCAB(RDF_NAMESPACE_URI, RDF, Description);
////////////////////////////////////////////////////////////////////////////////
class nsChromeRegistry : public nsIChromeRegistry, public nsIRDFDataSource {
public:
NS_DECL_ISUPPORTS
// nsIChromeRegistry methods:
NS_IMETHOD InitRegistry();
NS_IMETHOD ConvertChromeURL(nsIURL* aChromeURL);
// nsIRDFDataSource methods
NS_IMETHOD Init(const char* uri) ; // Called to init the data source.
NS_IMETHOD GetURI(char** uri);
NS_IMETHOD GetSource(nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
nsIRDFResource** source /* out */) ;
NS_IMETHOD GetSources(nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
nsISimpleEnumerator** sources /* out */) ;
NS_IMETHOD GetTarget(nsIRDFResource* source,
nsIRDFResource* property,
PRBool tv,
nsIRDFNode** target /* out */) ;
NS_IMETHOD GetTargets(nsIRDFResource* source,
nsIRDFResource* property,
PRBool tv,
nsISimpleEnumerator** targets /* out */) ;
NS_IMETHOD Assert(nsIRDFResource* source,
nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv) ;
NS_IMETHOD Unassert(nsIRDFResource* source,
nsIRDFResource* property,
nsIRDFNode* target) ;
NS_IMETHOD HasAssertion(nsIRDFResource* source,
nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
PRBool* hasAssertion /* out */) ;
NS_IMETHOD AddObserver(nsIRDFObserver* n) ;
NS_IMETHOD RemoveObserver(nsIRDFObserver* n) ;
NS_IMETHOD ArcLabelsIn(nsIRDFNode* node,
nsISimpleEnumerator** labels /* out */) ;
NS_IMETHOD ArcLabelsOut(nsIRDFResource* source,
nsISimpleEnumerator** labels /* out */) ;
NS_IMETHOD GetAllResources(nsISimpleEnumerator** aResult) ;
NS_IMETHOD Flush(void) ;
NS_IMETHOD GetAllCommands(nsIRDFResource* source,
nsIEnumerator/*<nsIRDFResource>*/** commands) ;
NS_IMETHOD IsCommandEnabled(nsISupportsArray/*<nsIRDFResource>*/* aSources,
nsIRDFResource* aCommand,
nsISupportsArray/*<nsIRDFResource>*/* aArguments,
PRBool* retVal) ;
NS_IMETHOD DoCommand(nsISupportsArray/*<nsIRDFResource>*/* aSources,
nsIRDFResource* aCommand,
nsISupportsArray/*<nsIRDFResource>*/* aArguments) ;
// nsChromeRegistry methods:
nsChromeRegistry();
virtual ~nsChromeRegistry();
static PRUint32 gRefCnt;
static nsIRDFService* gRDFService;
static nsIRDFResource* kCHROME_chrome;
static nsIRDFResource* kCHROME_skin;
static nsIRDFResource* kCHROME_content;
static nsIRDFResource* kCHROME_platform;
static nsIRDFResource* kCHROME_locale;
static nsIRDFResource* kCHROME_behavior;
static nsIRDFResource* kCHROME_base;
static nsIRDFResource* kCHROME_main;
static nsIRDFResource* kCHROME_archive;
static nsIRDFDataSource* mInner;
protected:
nsresult GetProviderTypeResource(const nsString& aChromeType, nsIRDFResource** aResult);
nsresult GetChromeResource(nsString& aResult, nsIRDFResource* aChromeResource,
nsIRDFResource* aProperty);
};
PRUint32 nsChromeRegistry::gRefCnt ;
nsIRDFService* nsChromeRegistry::gRDFService = nsnull;
nsIRDFResource* nsChromeRegistry::kCHROME_chrome = nsnull;
nsIRDFResource* nsChromeRegistry::kCHROME_skin = nsnull;
nsIRDFResource* nsChromeRegistry::kCHROME_content = nsnull;
nsIRDFResource* nsChromeRegistry::kCHROME_locale = nsnull;
nsIRDFResource* nsChromeRegistry::kCHROME_behavior = nsnull;
nsIRDFResource* nsChromeRegistry::kCHROME_platform = nsnull;
nsIRDFResource* nsChromeRegistry::kCHROME_base = nsnull;
nsIRDFResource* nsChromeRegistry::kCHROME_main = nsnull;
nsIRDFResource* nsChromeRegistry::kCHROME_archive = nsnull;
nsIRDFDataSource* nsChromeRegistry::mInner = nsnull;
////////////////////////////////////////////////////////////////////////////////
nsChromeRegistry::nsChromeRegistry()
{
NS_INIT_REFCNT();
}
nsChromeRegistry::~nsChromeRegistry()
{
--gRefCnt;
if (gRefCnt == 0) {
// Release our inner data source
NS_IF_RELEASE(mInner);
// release all the properties:
NS_IF_RELEASE(kCHROME_chrome);
NS_IF_RELEASE(kCHROME_skin);
NS_IF_RELEASE(kCHROME_content);
NS_IF_RELEASE(kCHROME_platform);
NS_IF_RELEASE(kCHROME_locale);
NS_IF_RELEASE(kCHROME_behavior);
NS_IF_RELEASE(kCHROME_base);
NS_IF_RELEASE(kCHROME_main);
NS_IF_RELEASE(kCHROME_archive);
if (gRDFService) {
nsServiceManager::ReleaseService(kRDFServiceCID, gRDFService);
gRDFService = nsnull;
}
}
}
NS_IMPL_ADDREF(nsChromeRegistry)
NS_IMPL_RELEASE(nsChromeRegistry)
NS_IMETHODIMP
nsChromeRegistry::QueryInterface(REFNSIID aIID, void** aResult)
{
NS_PRECONDITION(aResult != nsnull, "null ptr");
if (! aResult)
return NS_ERROR_NULL_POINTER;
if (aIID.Equals(nsIChromeRegistry::GetIID()) ||
aIID.Equals(kISupportsIID)) {
*aResult = NS_STATIC_CAST(nsIChromeRegistry*, this);
NS_ADDREF(this);
return NS_OK;
}
if (aIID.Equals(kIRDFDataSourceIID)) {
*aResult = NS_STATIC_CAST(nsIRDFDataSource*, this);
NS_ADDREF(this);
return NS_OK;
}
return NS_NOINTERFACE;
}
////////////////////////////////////////////////////////////////////////////////
// nsIChromeRegistry methods:
NS_IMETHODIMP
nsChromeRegistry::ConvertChromeURL(nsIURL* aChromeURL)
{
nsresult rv = NS_OK;
// Retrieve the resource for this chrome element.
const char* host;
if (NS_FAILED(rv = aChromeURL->GetHost(&host))) {
NS_ERROR("Unable to retrieve the host for a chrome URL.");
return rv;
}
nsAutoString hostStr(host);
// Construct a chrome URL and use it to look up a resource.
nsAutoString windowType = nsAutoString("chrome://") + hostStr + "/";
// Find out the provider type of the URL
const char* file;
aChromeURL->GetFile(&file);
nsAutoString restOfURL(file);
// Find the second slash.
nsAutoString providerType("content");
nsAutoString path("");
PRInt32 slashIndex = -1;
if (restOfURL.Length() > 1)
{
// There is something to the right of that slash. A provider type must have
// been specified.
slashIndex = restOfURL.Find('/', 1);
if (slashIndex == -1)
slashIndex = restOfURL.Length();
restOfURL.Mid(providerType, 1, slashIndex - 1);
if (slashIndex < restOfURL.Length()-1)
{
// There are some extra subdirectories to remember.
restOfURL.Right(path, restOfURL.Length()-slashIndex-1);
}
}
windowType += providerType + "/";
// We have the resource URI that we wish to retrieve. Fetch it.
nsCOMPtr<nsIRDFResource> chromeResource;
if (NS_FAILED(rv = GetProviderTypeResource(windowType, getter_AddRefs(chromeResource)))) {
NS_ERROR("Unable to retrieve the resource corresponding to the chrome skin or content.");
return rv;
}
nsString chromeBase;
if (NS_FAILED(rv = GetChromeResource(chromeBase, chromeResource, kCHROME_base))) {
NS_ERROR("Unable to retrieve codebase for chrome entry.");
return rv;
}
// Make sure base ends in a slash
PRInt32 length = chromeBase.Length();
if (length > 0)
{
PRUnichar c = chromeBase.CharAt(length-1);
if (c != '/')
chromeBase += "/"; // Ensure that a slash is present.
}
// Check to see if we should append the "main" entry in the registry.
// Only do this when the user doesn't have anything following "skin"
// or "content" in the specified URL.
if (path == "")
{
PRInt32 length = restOfURL.Length();
if (length > 0)
{
PRUnichar c = restOfURL.CharAt(length-1);
if (c != '/')
restOfURL += "/"; // Ensure that a slash is present.
}
// Append the "main" entry.
nsString mainFile;
if (NS_FAILED(rv = GetChromeResource(mainFile, chromeResource, kCHROME_main))) {
NS_ERROR("Unable to retrieve the main file registry entry for a chrome URL.");
return rv;
}
chromeBase += mainFile;
}
else
{
// XXX Just append the rest of the URL to base to get the actual URL to look up.
chromeBase += path;
}
char* finalDecision = chromeBase.ToNewCString();
aChromeURL->SetSpec(finalDecision);
delete []finalDecision;
return NS_OK;
}
NS_IMETHODIMP
nsChromeRegistry::InitRegistry()
{
if (mInner == nsnull)
return Init("rdf:chrome");
else return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsIRDFObserver methods:
////////////////////////////////////////////////////////////////////////////////
nsresult
nsChromeRegistry::GetProviderTypeResource(const nsString& aChromeType,
nsIRDFResource** aResult)
{
nsresult rv = NS_OK;
char* url = aChromeType.ToNewCString();
if (NS_FAILED(rv = gRDFService->GetResource(url, aResult))) {
NS_ERROR("Unable to retrieve a resource for this provider type.");
*aResult = nsnull;
delete []url;
return rv;
}
delete []url;
return NS_OK;
}
nsresult
nsChromeRegistry::GetChromeResource(nsString& aResult,
nsIRDFResource* aChromeResource,
nsIRDFResource* aProperty)
{
nsresult rv = NS_OK;
if (mInner == nsnull)
return NS_ERROR_FAILURE; // Must have a DB to attempt this operation.
nsCOMPtr<nsIRDFNode> chromeBase;
if (NS_FAILED(rv = GetTarget(aChromeResource, aProperty, PR_TRUE, getter_AddRefs(chromeBase)))) {
NS_ERROR("Unable to obtain a base resource.");
return rv;
}
if (chromeBase == nsnull)
return NS_OK;
nsCOMPtr<nsIRDFResource> resource;
nsCOMPtr<nsIRDFLiteral> literal;
if (NS_SUCCEEDED(rv = chromeBase->QueryInterface(kIRDFResourceIID,
(void**) getter_AddRefs(resource)))) {
nsXPIDLCString uri;
resource->GetValue( getter_Copies(uri) );
aResult = uri;
}
else if (NS_SUCCEEDED(rv = chromeBase->QueryInterface(kIRDFLiteralIID,
(void**) getter_AddRefs(literal)))) {
nsXPIDLString s;
literal->GetValue( getter_Copies(s) );
aResult = s;
}
else {
// This should _never_ happen.
NS_ERROR("uh, this isn't a resource or a literal!");
return NS_ERROR_UNEXPECTED;
}
return NS_OK;
}
nsresult
NS_NewChromeRegistry(nsIChromeRegistry** aResult)
{
NS_PRECONDITION(aResult != nsnull, "null ptr");
if (! aResult)
return NS_ERROR_NULL_POINTER;
nsChromeRegistry* chromeRegistry = new nsChromeRegistry();
if (chromeRegistry == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(chromeRegistry);
*aResult = chromeRegistry;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsIRDFDataSource methods
NS_IMETHODIMP
nsChromeRegistry::Init(const char* uri)
{
// We're going to be init'ed with the "rdf:chrome" URI.
// We want to use the location of the registry source instead.
nsresult rv = NS_OK;
gRefCnt++;
if (gRefCnt == 1) {
rv = nsServiceManager::GetService(kRDFServiceCID,
kIRDFServiceIID,
(nsISupports**)&gRDFService);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get RDF service");
if (NS_FAILED(rv)) return rv;
// get all the properties we'll need:
rv = gRDFService->GetResource(kURICHROME_chrome, &kCHROME_chrome);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get resource");
if (NS_FAILED(rv)) return rv;
rv = gRDFService->GetResource(kURICHROME_skin, &kCHROME_skin);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get resource");
if (NS_FAILED(rv)) return rv;
rv = gRDFService->GetResource(kURICHROME_content, &kCHROME_content);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get resource");
if (NS_FAILED(rv)) return rv;
rv = gRDFService->GetResource(kURICHROME_content, &kCHROME_platform);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get resource");
if (NS_FAILED(rv)) return rv;
rv = gRDFService->GetResource(kURICHROME_content, &kCHROME_locale);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get resource");
if (NS_FAILED(rv)) return rv;
rv = gRDFService->GetResource(kURICHROME_content, &kCHROME_behavior);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get resource");
if (NS_FAILED(rv)) return rv;
rv = gRDFService->GetResource(kURICHROME_base, &kCHROME_base);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get resource");
if (NS_FAILED(rv)) return rv;
rv = gRDFService->GetResource(kURICHROME_main, &kCHROME_main);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get resource");
if (NS_FAILED(rv)) return rv;
rv = gRDFService->GetResource(kURICHROME_archive, &kCHROME_archive);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get resource");
if (NS_FAILED(rv)) return rv;
// Retrieve the mInner data source.
nsSpecialSystemDirectory chromeFile(nsSpecialSystemDirectory::OS_CurrentProcessDirectory);
chromeFile += "chrome";
chromeFile += "registry.rdf";
nsFileURL chromeURL(chromeFile);
const char* innerURI = chromeURL.GetAsString();
// Try to create the new data source.
if (NS_FAILED(rv = gRDFService->GetDataSource(innerURI, &mInner)))
return rv;
}
return rv;
}
NS_IMETHODIMP
nsChromeRegistry::GetURI(char** uri)
{
return mInner->GetURI(uri);
}
NS_IMETHODIMP
nsChromeRegistry::GetSource(nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
nsIRDFResource** source /* out */)
{
return mInner->GetSource(property, target, tv, source);
}
NS_IMETHODIMP
nsChromeRegistry::GetSources(nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
nsISimpleEnumerator** sources /* out */)
{
return mInner->GetSources(property, target, tv, sources);
}
NS_IMETHODIMP
nsChromeRegistry::GetTarget(nsIRDFResource* source,
nsIRDFResource* property,
PRBool tv,
nsIRDFNode** target /* out */)
{
return mInner->GetTarget(source, property, tv, target);
}
NS_IMETHODIMP
nsChromeRegistry::GetTargets(nsIRDFResource* source,
nsIRDFResource* property,
PRBool tv,
nsISimpleEnumerator** targets /* out */)
{
return mInner->GetTargets(source, property, tv, targets);
}
NS_IMETHODIMP
nsChromeRegistry::Assert(nsIRDFResource* source,
nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv)
{
return mInner->Assert(source, property, target, tv);
}
NS_IMETHODIMP
nsChromeRegistry::Unassert(nsIRDFResource* source,
nsIRDFResource* property,
nsIRDFNode* target)
{
return mInner->Unassert(source, property, target);
}
NS_IMETHODIMP
nsChromeRegistry::HasAssertion(nsIRDFResource* source,
nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
PRBool* hasAssertion /* out */)
{
return mInner->HasAssertion(source, property, target, tv, hasAssertion);
}
NS_IMETHODIMP nsChromeRegistry::AddObserver(nsIRDFObserver* n)
{
return mInner->AddObserver(n);
}
NS_IMETHODIMP nsChromeRegistry::RemoveObserver(nsIRDFObserver* n)
{
return mInner->RemoveObserver(n);
}
NS_IMETHODIMP nsChromeRegistry::ArcLabelsIn(nsIRDFNode* node,
nsISimpleEnumerator** labels /* out */)
{
return mInner->ArcLabelsIn(node, labels);
}
NS_IMETHODIMP nsChromeRegistry::ArcLabelsOut(nsIRDFResource* source,
nsISimpleEnumerator** labels /* out */)
{
return mInner->ArcLabelsOut(source, labels);
}
NS_IMETHODIMP nsChromeRegistry::GetAllResources(nsISimpleEnumerator** aCursor)
{
return mInner->GetAllResources(aCursor);
}
NS_IMETHODIMP
nsChromeRegistry::Flush(void)
{
return mInner->Flush();
}
NS_IMETHODIMP
nsChromeRegistry::GetAllCommands(nsIRDFResource* source,
nsIEnumerator/*<nsIRDFResource>*/** commands)
{
return mInner->GetAllCommands(source, commands);
}
NS_IMETHODIMP
nsChromeRegistry::IsCommandEnabled(nsISupportsArray/*<nsIRDFResource>*/* aSources,
nsIRDFResource* aCommand,
nsISupportsArray/*<nsIRDFResource>*/* aArguments,
PRBool* retVal)
{
return mInner->IsCommandEnabled(aSources, aCommand, aArguments, retVal);
}
NS_IMETHODIMP
nsChromeRegistry::DoCommand(nsISupportsArray/*<nsIRDFResource>*/* aSources,
nsIRDFResource* aCommand,
nsISupportsArray/*<nsIRDFResource>*/* aArguments)
{
return mInner->DoCommand(aSources, aCommand, aArguments);
}

View File

@@ -1,305 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
/*
Helper class to implement the nsIDOMNodeList interface.
XXX It's probably wrong in some sense, as it uses the "naked"
content interface to look for kids. (I assume in general this is
bad because there may be pseudo-elements created for presentation
that aren't visible to the DOM.)
*/
#include "nsDOMCID.h"
#include "nsIDOMNode.h"
#include "nsIDOMHTMLCollection.h"
#include "nsIDOMScriptObjectFactory.h"
#include "nsIScriptGlobalObject.h"
#include "nsIServiceManager.h"
#include "nsISupportsArray.h"
#include "nsRDFDOMNodeList.h"
////////////////////////////////////////////////////////////////////////
// GUID definitions
static NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_IID);
static NS_DEFINE_IID(kIDOMNodeListIID, NS_IDOMNODELIST_IID);
static NS_DEFINE_IID(kIDOMScriptObjectFactoryIID, NS_IDOM_SCRIPT_OBJECT_FACTORY_IID);
static NS_DEFINE_CID(kDOMScriptObjectFactoryCID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
////////////////////////////////////////////////////////////////////////
//
class RDFHTMLCollectionImpl : public nsIDOMHTMLCollection
{
private:
nsRDFDOMNodeList* mOuter;
public:
RDFHTMLCollectionImpl(nsRDFDOMNodeList* aOuter);
virtual ~RDFHTMLCollectionImpl();
// nsISupports interface
NS_IMETHOD_(nsrefcnt) AddRef(void);
NS_IMETHOD_(nsrefcnt) Release(void);
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aResult);
// nsIDOMHTMLCollection interface
NS_DECL_IDOMHTMLCOLLECTION
};
RDFHTMLCollectionImpl::RDFHTMLCollectionImpl(nsRDFDOMNodeList* aOuter)
: mOuter(aOuter)
{
}
RDFHTMLCollectionImpl::~RDFHTMLCollectionImpl(void)
{
}
NS_IMETHODIMP_(nsrefcnt)
RDFHTMLCollectionImpl::AddRef(void)
{
return mOuter->AddRef();
}
NS_IMETHODIMP_(nsrefcnt)
RDFHTMLCollectionImpl::Release(void)
{
return mOuter->Release();
}
NS_IMETHODIMP
RDFHTMLCollectionImpl::QueryInterface(REFNSIID aIID, void** aResult)
{
NS_PRECONDITION(aResult != nsnull, "null ptr");
if (! aResult)
return NS_ERROR_NULL_POINTER;
if (aIID.Equals(nsIDOMHTMLCollection::GetIID())) {
*aResult = NS_STATIC_CAST(nsIDOMHTMLCollection*, this);
NS_ADDREF(this);
return NS_OK;
}
else {
return mOuter->QueryInterface(aIID, aResult);
}
}
NS_IMETHODIMP
RDFHTMLCollectionImpl::GetLength(PRUint32* aLength)
{
return mOuter->GetLength(aLength);
}
NS_IMETHODIMP
RDFHTMLCollectionImpl::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
{
return mOuter->Item(aIndex, aReturn);
}
NS_IMETHODIMP
RDFHTMLCollectionImpl::NamedItem(const nsString& aName, nsIDOMNode** aReturn)
{
NS_NOTYETIMPLEMENTED("write me!");
return NS_ERROR_NOT_IMPLEMENTED;
}
////////////////////////////////////////////////////////////////////////
// ctors & dtors
nsRDFDOMNodeList::nsRDFDOMNodeList(void)
: mInner(nsnull),
mElements(nsnull),
mScriptObject(nsnull)
{
NS_INIT_REFCNT();
}
nsRDFDOMNodeList::~nsRDFDOMNodeList(void)
{
NS_IF_RELEASE(mElements);
delete mInner;
}
nsresult
nsRDFDOMNodeList::Create(nsRDFDOMNodeList** aResult)
{
NS_PRECONDITION(aResult != nsnull, "null ptr");
if (! aResult)
return NS_ERROR_NULL_POINTER;
nsRDFDOMNodeList* list = new nsRDFDOMNodeList();
if (! list)
return NS_ERROR_OUT_OF_MEMORY;
nsresult rv;
if (NS_FAILED(rv = list->Init())) {
delete list;
return rv;
}
NS_ADDREF(list);
*aResult = list;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
// nsISupports interface
NS_IMPL_ADDREF(nsRDFDOMNodeList);
NS_IMPL_RELEASE(nsRDFDOMNodeList);
nsresult
nsRDFDOMNodeList::QueryInterface(REFNSIID aIID, void** aResult)
{
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
NS_PRECONDITION(aResult != nsnull, "null ptr");
if (! aResult)
return NS_ERROR_NULL_POINTER;
if (aIID.Equals(nsIDOMNodeList::GetIID()) ||
aIID.Equals(kISupportsIID)) {
*aResult = NS_STATIC_CAST(nsIDOMNodeList*, this);
NS_ADDREF(this);
return NS_OK;
}
else if (aIID.Equals(kIScriptObjectOwnerIID)) {
*aResult = NS_STATIC_CAST(nsIScriptObjectOwner*, this);
NS_ADDREF(this);
return NS_OK;
}
else if (aIID.Equals(nsIDOMHTMLCollection::GetIID())) {
// Aggregate this interface
if (! mInner) {
if (! (mInner = new RDFHTMLCollectionImpl(this)))
return NS_ERROR_OUT_OF_MEMORY;
}
return mInner->QueryInterface(aIID, aResult);
}
return NS_NOINTERFACE;
}
////////////////////////////////////////////////////////////////////////
// nsIDOMNodeList interface
NS_IMETHODIMP
nsRDFDOMNodeList::GetLength(PRUint32* aLength)
{
NS_ASSERTION(aLength != nsnull, "null ptr");
if (! aLength)
return NS_ERROR_NULL_POINTER;
*aLength = mElements->Count();
return NS_OK;
}
NS_IMETHODIMP
nsRDFDOMNodeList::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
{
NS_PRECONDITION(aReturn != nsnull, "null ptr");
if (! aReturn)
return NS_ERROR_NULL_POINTER;
NS_PRECONDITION(aIndex < (PRUint32) mElements->Count(), "invalid arg");
if (aIndex >= (PRUint32) mElements->Count())
return NS_ERROR_INVALID_ARG;
// Cast is okay because we're in a closed system.
*aReturn = (nsIDOMNode*) mElements->ElementAt(aIndex);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
// nsIScriptObjectOwner interface
NS_IMETHODIMP
nsRDFDOMNodeList::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
{
nsresult rv = NS_OK;
nsIScriptGlobalObject* global = aContext->GetGlobalObject();
if (nsnull == mScriptObject) {
nsIDOMScriptObjectFactory *factory;
if (NS_SUCCEEDED(rv = nsServiceManager::GetService(kDOMScriptObjectFactoryCID,
kIDOMScriptObjectFactoryIID,
(nsISupports **)&factory))) {
rv = factory->NewScriptHTMLCollection(aContext,
(nsISupports*)(nsIDOMNodeList*)this,
global,
(void**)&mScriptObject);
nsServiceManager::ReleaseService(kDOMScriptObjectFactoryCID, factory);
}
}
*aScriptObject = mScriptObject;
NS_RELEASE(global);
return rv;
}
NS_IMETHODIMP
nsRDFDOMNodeList::SetScriptObject(void* aScriptObject)
{
mScriptObject = aScriptObject;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
// Implementation methods
nsresult
nsRDFDOMNodeList::Init(void)
{
nsresult rv;
if (NS_FAILED(rv = NS_NewISupportsArray(&mElements))) {
NS_ERROR("unable to create elements array");
return rv;
}
return NS_OK;
}
nsresult
nsRDFDOMNodeList::AppendNode(nsIDOMNode* aNode)
{
NS_PRECONDITION(aNode != nsnull, "null ptr");
if (! aNode)
return NS_ERROR_NULL_POINTER;
return mElements->AppendElement(aNode);
}

View File

@@ -1,58 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
#ifndef nsRDFDOMNodeList_h__
#define nsRDFDOMNodeList_h__
#include "nsIDOMNodeList.h"
#include "nsIScriptObjectOwner.h"
class nsIDOMNode;
class nsISupportsArray;
class nsRDFDOMNodeList : public nsIDOMNodeList,
public nsIScriptObjectOwner
{
private:
nsISupports* mInner;
nsISupportsArray* mElements;
void* mScriptObject;
nsRDFDOMNodeList(void);
nsresult Init(void);
public:
static nsresult Create(nsRDFDOMNodeList** aResult);
virtual ~nsRDFDOMNodeList(void);
// nsISupports interface
NS_DECL_ISUPPORTS
// nsIDOMNodeList interface
NS_DECL_IDOMNODELIST
// nsIScriptObjectOwner interface
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
NS_IMETHOD SetScriptObject(void* aScriptObject);
// Implementation methods
nsresult AppendNode(nsIDOMNode* aNode);
};
#endif // nsRDFDOMNodeList_h__

View File

@@ -1,646 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
/*
A helper class used to implement attributes.
*/
/*
* Notes
*
* A lot of these methods delegate back to the original content node
* that created them. This is so that we can lazily produce attribute
* values from the RDF graph as they're asked for.
*
*/
#include "nsCOMPtr.h"
#include "nsDOMCID.h"
#include "nsIContent.h"
#include "nsICSSParser.h"
#include "nsIDOMElement.h"
#include "nsIDOMScriptObjectFactory.h"
#include "nsINameSpaceManager.h"
#include "nsIServiceManager.h"
#include "nsIURL.h"
#include "nsXULAttributes.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_CID(kDOMScriptObjectFactoryCID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
////////////////////////////////////////////////////////////////////////
// nsXULAttribute
nsXULAttribute::nsXULAttribute(nsIContent* aContent,
PRInt32 aNameSpaceID,
nsIAtom* aName,
const nsString& aValue)
: mNameSpaceID(aNameSpaceID),
mName(aName),
mValue(aValue),
mContent(aContent),
mScriptObject(nsnull)
{
NS_INIT_REFCNT();
NS_IF_ADDREF(aName);
}
nsXULAttribute::~nsXULAttribute()
{
NS_IF_RELEASE(mName);
}
nsresult
NS_NewXULAttribute(nsXULAttribute** aResult,
nsIContent* aContent,
PRInt32 aNameSpaceID,
nsIAtom* aName,
const nsString& aValue)
{
NS_PRECONDITION(aResult != nsnull, "null ptr");
if (! aResult)
return NS_ERROR_NULL_POINTER;
if (! (*aResult = new nsXULAttribute(aContent, aNameSpaceID, aName, aValue)))
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aResult);
return NS_OK;
}
// nsISupports interface
NS_IMPL_ADDREF(nsXULAttribute);
NS_IMPL_RELEASE(nsXULAttribute);
NS_IMETHODIMP
nsXULAttribute::QueryInterface(REFNSIID aIID, void** aResult)
{
NS_PRECONDITION(aResult != nsnull, "null ptr");
if (! aResult)
return NS_ERROR_NULL_POINTER;
if (aIID.Equals(nsIDOMAttr::GetIID()) ||
aIID.Equals(nsIDOMNode::GetIID()) ||
aIID.Equals(kISupportsIID)) {
*aResult = NS_STATIC_CAST(nsIDOMAttr*, this);
NS_ADDREF(this);
return NS_OK;
}
else if (aIID.Equals(nsIScriptObjectOwner::GetIID())) {
*aResult = NS_STATIC_CAST(nsIScriptObjectOwner*, this);
NS_ADDREF(this);
return NS_OK;
}
else {
*aResult = nsnull;
return NS_NOINTERFACE;
}
}
// nsIDOMNode interface
NS_IMETHODIMP
nsXULAttribute::GetNodeName(nsString& aNodeName)
{
aNodeName.SetString(mName->GetUnicode());
return NS_OK;
}
NS_IMETHODIMP
nsXULAttribute::GetNodeValue(nsString& aNodeValue)
{
aNodeValue=mValue;
return NS_OK;
}
NS_IMETHODIMP
nsXULAttribute::SetNodeValue(const nsString& aNodeValue)
{
return SetValue(aNodeValue);
}
NS_IMETHODIMP
nsXULAttribute::GetNodeType(PRUint16* aNodeType)
{
*aNodeType = (PRUint16)nsIDOMNode::ATTRIBUTE_NODE;
return NS_OK;
}
NS_IMETHODIMP
nsXULAttribute::GetParentNode(nsIDOMNode** aParentNode)
{
*aParentNode = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsXULAttribute::GetChildNodes(nsIDOMNodeList** aChildNodes)
{
NS_NOTYETIMPLEMENTED("write me");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsXULAttribute::GetFirstChild(nsIDOMNode** aFirstChild)
{
NS_NOTYETIMPLEMENTED("write me");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsXULAttribute::GetLastChild(nsIDOMNode** aLastChild)
{
NS_NOTYETIMPLEMENTED("write me");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsXULAttribute::GetPreviousSibling(nsIDOMNode** aPreviousSibling)
{
*aPreviousSibling = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsXULAttribute::GetNextSibling(nsIDOMNode** aNextSibling)
{
*aNextSibling = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsXULAttribute::GetAttributes(nsIDOMNamedNodeMap** aAttributes)
{
*aAttributes = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsXULAttribute::GetOwnerDocument(nsIDOMDocument** aOwnerDocument)
{
NS_NOTYETIMPLEMENTED("write me");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsXULAttribute::InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, nsIDOMNode** aReturn)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsXULAttribute::ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsXULAttribute::RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsXULAttribute::AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsXULAttribute::HasChildNodes(PRBool* aReturn)
{
NS_NOTYETIMPLEMENTED("write me");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsXULAttribute::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
{
NS_NOTYETIMPLEMENTED("write me");
return NS_ERROR_NOT_IMPLEMENTED;
}
// nsIDOMAttr interface
NS_IMETHODIMP
nsXULAttribute::GetName(nsString& aName)
{
aName.SetString(mName->GetUnicode());
return NS_OK;
}
NS_IMETHODIMP
nsXULAttribute::GetSpecified(PRBool* aSpecified)
{
// XXX this'll break when we make Clone() work
*aSpecified = PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP
nsXULAttribute::GetValue(nsString& aValue)
{
aValue=mValue;
return NS_OK;
}
NS_IMETHODIMP
nsXULAttribute::SetValue(const nsString& aValue)
{
nsCOMPtr<nsIDOMElement> element( do_QueryInterface(mContent) );
if (element) {
nsAutoString qualifiedName;
GetQualifiedName(qualifiedName);
return element->SetAttribute(qualifiedName, aValue);
}
else {
return NS_ERROR_FAILURE;
}
}
// nsIScriptObjectOwner interface
NS_IMETHODIMP
nsXULAttribute::GetScriptObject(nsIScriptContext* aContext, void** aScriptObject)
{
nsresult rv = NS_OK;
if (! mScriptObject) {
nsIDOMScriptObjectFactory *factory;
rv = nsServiceManager::GetService(kDOMScriptObjectFactoryCID,
nsIDOMScriptObjectFactory::GetIID(),
(nsISupports **)&factory);
if (NS_FAILED(rv))
return rv;
rv = factory->NewScriptAttr(aContext,
(nsISupports*)(nsIDOMAttr*) this,
(nsISupports*) mContent,
(void**) &mScriptObject);
nsServiceManager::ReleaseService(kDOMScriptObjectFactoryCID, factory);
}
*aScriptObject = mScriptObject;
return rv;
}
NS_IMETHODIMP
nsXULAttribute::SetScriptObject(void *aScriptObject)
{
mScriptObject = aScriptObject;
return NS_OK;
}
// Implementation methods
void
nsXULAttribute::GetQualifiedName(nsString& aQualifiedName)
{
aQualifiedName.Truncate();
if ((mNameSpaceID != kNameSpaceID_None) &&
(mNameSpaceID != kNameSpaceID_Unknown)) {
nsresult rv;
nsIAtom* prefix;
rv = mContent->GetNameSpacePrefixFromId(mNameSpaceID, prefix);
if (NS_SUCCEEDED(rv) && (prefix != nsnull)) {
aQualifiedName.Append(prefix->GetUnicode());
aQualifiedName.Append(':');
NS_RELEASE(prefix);
}
}
aQualifiedName.Append(mName->GetUnicode());
}
////////////////////////////////////////////////////////////////////////
// nsXULAttributes
nsXULAttributes::nsXULAttributes(nsIContent* aContent)
: mContent(aContent),
mClassList(nsnull),
mStyleRule(nsnull),
mScriptObject(nsnull)
{
NS_INIT_REFCNT();
}
nsXULAttributes::~nsXULAttributes()
{
PRInt32 count = mAttributes.Count();
PRInt32 index;
for (index = 0; index < count; index++) {
nsXULAttribute* attr = (nsXULAttribute*)mAttributes.ElementAt(index);
NS_RELEASE(attr);
}
}
nsresult
NS_NewXULAttributes(nsXULAttributes** aResult, nsIContent* aContent)
{
NS_PRECONDITION(aResult != nsnull, "null ptr");
if (! aResult)
return NS_ERROR_NULL_POINTER;
if (! (*aResult = new nsXULAttributes(aContent)))
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aResult);
return NS_OK;
}
// nsISupports interface
NS_IMPL_ADDREF(nsXULAttributes);
NS_IMPL_RELEASE(nsXULAttributes);
NS_IMETHODIMP
nsXULAttributes::QueryInterface(REFNSIID aIID, void** aResult)
{
NS_PRECONDITION(aResult != nsnull, "null ptr");
if (! aResult)
return NS_ERROR_NULL_POINTER;
if (aIID.Equals(nsIDOMNamedNodeMap::GetIID()) ||
aIID.Equals(kISupportsIID)) {
*aResult = NS_STATIC_CAST(nsIDOMNamedNodeMap*, this);
NS_ADDREF(this);
return NS_OK;
}
else if (aIID.Equals(nsIScriptObjectOwner::GetIID())) {
*aResult = NS_STATIC_CAST(nsIScriptObjectOwner*, this);
NS_ADDREF(this);
return NS_OK;
}
else {
*aResult = nsnull;
return NS_NOINTERFACE;
}
}
// nsIDOMNamedNodeMap interface
NS_IMETHODIMP
nsXULAttributes::GetLength(PRUint32* aLength)
{
NS_PRECONDITION(aLength != nsnull, "null ptr");
if (! aLength)
return NS_ERROR_NULL_POINTER;
*aLength = mAttributes.Count();
return NS_OK;
}
NS_IMETHODIMP
nsXULAttributes::GetNamedItem(const nsString& aName, nsIDOMNode** aReturn)
{
NS_PRECONDITION(aReturn != nsnull, "null ptr");
if (! aReturn)
return NS_ERROR_NULL_POINTER;
nsresult rv;
*aReturn = nsnull;
PRInt32 nameSpaceID;
nsIAtom* name;
if (NS_FAILED(rv = mContent->ParseAttributeString(aName, name, nameSpaceID)))
return rv;
// XXX doing this instead of calling mContent->GetAttribute() will
// make it a lot harder to lazily instantiate properties from the
// graph. The problem is, how else do we get the named item?
for (PRInt32 i = mAttributes.Count() - 1; i >= 0; --i) {
nsXULAttribute* attr = (nsXULAttribute*) mAttributes[i];
if (((nameSpaceID == attr->mNameSpaceID) ||
(nameSpaceID == kNameSpaceID_Unknown) ||
(nameSpaceID == kNameSpaceID_None)) &&
(name == attr->mName)) {
NS_ADDREF(attr);
*aReturn = attr;
break;
}
}
NS_RELEASE(name);
return NS_OK;
}
NS_IMETHODIMP
nsXULAttributes::SetNamedItem(nsIDOMNode* aArg, nsIDOMNode** aReturn)
{
NS_NOTYETIMPLEMENTED("write me");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsXULAttributes::RemoveNamedItem(const nsString& aName, nsIDOMNode** aReturn)
{
nsCOMPtr<nsIDOMElement> element( do_QueryInterface(mContent) );
if (element) {
return element->RemoveAttribute(aName);
*aReturn = nsnull; // XXX should be the element we just removed
return NS_OK;
}
else {
return NS_ERROR_FAILURE;
}
}
NS_IMETHODIMP
nsXULAttributes::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
{
*aReturn = (nsXULAttribute*) mAttributes[aIndex];
NS_IF_ADDREF(*aReturn);
return NS_OK;
}
// nsIScriptObjectOwner interface
NS_IMETHODIMP
nsXULAttributes::GetScriptObject(nsIScriptContext* aContext, void** aScriptObject)
{
nsresult rv = NS_OK;
if (! mScriptObject) {
nsIDOMScriptObjectFactory *factory;
rv = nsServiceManager::GetService(kDOMScriptObjectFactoryCID,
nsIDOMScriptObjectFactory::GetIID(),
(nsISupports **)&factory);
if (NS_FAILED(rv))
return rv;
rv = factory->NewScriptNamedNodeMap(aContext,
(nsISupports*)(nsIDOMNamedNodeMap*) this,
(nsISupports*) mContent,
(void**) &mScriptObject);
nsServiceManager::ReleaseService(kDOMScriptObjectFactoryCID, factory);
}
*aScriptObject = mScriptObject;
return rv;
}
NS_IMETHODIMP
nsXULAttributes::SetScriptObject(void *aScriptObject)
{
mScriptObject = aScriptObject;
return NS_OK;
}
// Implementation methods
nsresult
nsXULAttributes::GetClasses(nsVoidArray& aArray) const
{
aArray.Clear();
const nsClassList* classList = mClassList;
while (nsnull != classList) {
aArray.AppendElement(classList->mAtom); // NOTE atom is not addrefed
classList = classList->mNext;
}
return NS_OK;
}
nsresult
nsXULAttributes::HasClass(nsIAtom* aClass) const
{
const nsClassList* classList = mClassList;
while (nsnull != classList) {
if (classList->mAtom == aClass) {
return NS_OK;
}
classList = classList->mNext;
}
return NS_COMFALSE;
}
nsresult nsXULAttributes::UpdateClassList(const nsString& aValue)
{
if (mClassList != nsnull)
{
delete mClassList;
mClassList = nsnull;
}
if (aValue != "")
ParseClasses(aValue, &mClassList);
return NS_OK;
}
nsresult nsXULAttributes::UpdateStyleRule(nsIURL* aDocURL, const nsString& aValue)
{
if (aValue == "")
{
// XXX: Removing the rule. Is this sufficient?
NS_IF_RELEASE(mStyleRule);
mStyleRule = nsnull;
return NS_OK;
}
nsICSSParser* css;
nsresult result = NS_NewCSSParser(&css);
if (NS_OK != result) {
return result;
}
nsIStyleRule* rule;
result = css->ParseDeclarations(aValue, aDocURL, rule);
//NS_IF_RELEASE(docURL);
if ((NS_OK == result) && (nsnull != rule)) {
mStyleRule = rule; //Addrefed already during parse, so don't need to addref again.
//result = SetHTMLAttribute(aAttribute, nsHTMLValue(rule), aNotify);
}
//else {
// result = SetHTMLAttribute(aAttribute, nsHTMLValue(aValue), aNotify);
//}
NS_RELEASE(css);
return NS_OK;
}
nsresult nsXULAttributes::GetInlineStyleRule(nsIStyleRule*& aRule)
{
nsresult result = NS_ERROR_NULL_POINTER;
if (mStyleRule != nsnull)
{
aRule = mStyleRule;
NS_ADDREF(aRule);
result = NS_OK;
}
return result;
}
void
nsXULAttributes::ParseClasses(const nsString& aClassString, nsClassList** aClassList)
{
static const PRUnichar kNullCh = PRUnichar('\0');
NS_ASSERTION(nsnull == *aClassList, "non null start list");
nsAutoString classStr(aClassString); // copy to work buffer
classStr.Append(kNullCh); // put an extra null at the end
PRUnichar* start = (PRUnichar*)(const PRUnichar*)classStr.GetUnicode();
PRUnichar* end = start;
while (kNullCh != *start) {
while ((kNullCh != *start) && nsString::IsSpace(*start)) { // skip leading space
start++;
}
end = start;
while ((kNullCh != *end) && (PR_FALSE == nsString::IsSpace(*end))) { // look for space or end
end++;
}
*end = kNullCh; // end string here
if (start < end) {
*aClassList = new nsClassList(NS_NewAtom(start));
aClassList = &((*aClassList)->mNext);
}
start = ++end;
}
}

View File

@@ -1,180 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
/*
A set of helper classes used to implement attributes.
*/
#ifndef nsXULAttributes_h__
#define nsXULAttributes_h__
#include "nsIDOMAttr.h"
#include "nsIDOMNamedNodeMap.h"
#include "nsIScriptObjectOwner.h"
#include "nsIStyleRule.h"
#include "nsString.h"
#include "nsIAtom.h"
#include "nsVoidArray.h"
class nsIURL;
struct nsClassList {
nsClassList(nsIAtom* aAtom)
: mAtom(aAtom),
mNext(nsnull)
{
}
nsClassList(const nsClassList& aCopy)
: mAtom(aCopy.mAtom),
mNext(nsnull)
{
NS_ADDREF(mAtom);
if (nsnull != aCopy.mNext) {
mNext = new nsClassList(*(aCopy.mNext));
}
}
~nsClassList(void)
{
NS_RELEASE(mAtom);
if (nsnull != mNext) {
delete mNext;
}
}
nsIAtom* mAtom;
nsClassList* mNext;
};
////////////////////////////////////////////////////////////////////////
class nsXULAttribute : public nsIDOMAttr,
public nsIScriptObjectOwner
{
private:
nsXULAttribute(nsIContent* aContent,
PRInt32 aNameSpaceID,
nsIAtom* aName,
const nsString& aValue);
virtual ~nsXULAttribute();
friend nsresult
NS_NewXULAttribute(nsXULAttribute** aResult,
nsIContent* aContent,
PRInt32 aNameSpaceID,
nsIAtom* aName,
const nsString& aValue);
public:
// nsISupports interface
NS_DECL_ISUPPORTS
// nsIDOMNode interface
NS_DECL_IDOMNODE
// nsIDOMAttr interface
NS_DECL_IDOMATTR
// nsIScriptObjectOwner interface
NS_IMETHOD GetScriptObject(nsIScriptContext* aContext, void** aScriptObject);
NS_IMETHOD SetScriptObject(void *aScriptObject);
// Implementation methods
void GetQualifiedName(nsString& aAttributeName);
PRInt32 GetNameSpaceID();
nsIAtom* GetName();
const nsString& GetValue();
// Publicly exposed to make life easier. This is a private class
// anyway.
PRInt32 mNameSpaceID;
nsIAtom* mName;
nsString mValue;
private:
nsIContent* mContent;
void* mScriptObject;
};
nsresult
NS_NewXULAttribute(nsXULAttribute** aResult,
nsIContent* aContent,
PRInt32 aNameSpaceID,
nsIAtom* aName,
const nsString& aValue);
////////////////////////////////////////////////////////////////////////
class nsXULAttributes : public nsIDOMNamedNodeMap,
public nsIScriptObjectOwner
{
public:
// nsISupports interface
NS_DECL_ISUPPORTS
// nsIDOMNamedNodeMap interface
NS_DECL_IDOMNAMEDNODEMAP
// nsIScriptObjectOwner interface
NS_IMETHOD GetScriptObject(nsIScriptContext* aContext, void** aScriptObject);
NS_IMETHOD SetScriptObject(void *aScriptObject);
// Implementation methods
// VoidArray Helpers
PRInt32 Count() { return mAttributes.Count(); };
nsXULAttribute* ElementAt(PRInt32 i) { return (nsXULAttribute*)mAttributes.ElementAt(i); };
void AppendElement(nsXULAttribute* aElement) { mAttributes.AppendElement((void*)aElement); };
void RemoveElementAt(PRInt32 index) { mAttributes.RemoveElementAt(index); };
// Style Helpers
nsresult GetClasses(nsVoidArray& aArray) const;
nsresult HasClass(nsIAtom* aClass) const;
nsresult UpdateClassList(const nsString& aValue);
nsresult UpdateStyleRule(nsIURL* aDocURL, const nsString& aValue);
nsresult GetInlineStyleRule(nsIStyleRule*& aRule);
private:
friend nsresult
NS_NewXULAttributes(nsXULAttributes** aResult, nsIContent* aContent);
nsXULAttributes(nsIContent* aContent);
virtual ~nsXULAttributes();
static void
ParseClasses(const nsString& aClassString, nsClassList** aClassList);
nsIContent* mContent;
nsClassList* mClassList;
nsIStyleRule* mStyleRule;
nsVoidArray mAttributes;
void* mScriptObject;
};
nsresult
NS_NewXULAttributes(nsXULAttributes** aResult, nsIContent* aContent);
#endif // nsXULAttributes_h__

File diff suppressed because it is too large Load Diff

View File

@@ -1,71 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
#ifndef nsXULElement_h__
#define nsXULElement_h__
#include "nsIDOMXULElement.h"
class nsXULElement : public nsISupports
{
protected:
nsIDOMXULElement* mOuter;
nsXULElement(nsIDOMXULElement* aOuter) : mOuter(aOuter) {}
public:
virtual ~nsXULElement() {};
// nsISupports interface. Subclasses should use the
// NS_DECL/IMPL_ISUPPORTS_INHERITED macros to implement the
// nsISupports interface.
NS_IMETHOD_(nsrefcnt) AddRef() {
return mOuter->AddRef();
}
NS_IMETHOD_(nsrefcnt) Release() {
return mOuter->Release();
}
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aResult) {
return mOuter->QueryInterface(aIID, aResult);
}
};
#define NS_IMPL_XULELEMENT_ISUPPORTS \
NS_IMETHOD_(nsrefcnt) AddRef() { \
return mOuter->AddRef(); \
} \
\
NS_IMETHOD_(nsrefcnt) Release() { \
return mOuter->Release(); \
} \
\
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aResult) { \
if (aIID.Equals(GetDOMIID())) { \
*aResult = this; \
NS_ADDREF(this); \
return NS_OK; \
} \
else { \
return mOuter->QueryInterface(aIID, aResult); \
} \
}
#endif // nsXULElement_h__

View File

@@ -1,55 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
#include "nsCOMPtr.h"
#include "nsIRDFCompositeDataSource.h"
#include "nsIServiceManager.h"
#include "nsRDFCID.h"
#include "nsXULTreeElement.h"
NS_IMPL_ISUPPORTS_INHERITED(nsXULTreeElement, nsXULElement, nsIDOMXULTreeElement);
NS_IMETHODIMP
nsXULTreeElement::GetDatabase(nsIRDFCompositeDataSource** aDatabase)
{
NS_PRECONDITION(aDatabase != nsnull, "null ptr");
if (! aDatabase)
return NS_ERROR_NULL_POINTER;
NS_IF_ADDREF(mDatabase);
*aDatabase = mDatabase;
return NS_OK;
}
NS_IMETHODIMP
nsXULTreeElement::SetDatabase(nsIRDFCompositeDataSource* aDatabase)
{
// XXX maybe someday you'll be allowed to change it.
NS_PRECONDITION(mDatabase == nsnull, "already initialized");
if (mDatabase)
return NS_ERROR_ALREADY_INITIALIZED;
mDatabase = aDatabase;
NS_IF_ADDREF(aDatabase);
// XXX reconstruct the entire tree now!
return NS_OK;
}

View File

@@ -1,60 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
#ifndef nsXULTreeElement_h__
#define nsXULTreeElement_h__
#include "nsXULElement.h"
#include "nsIDOMXULTreeElement.h"
#include "nsIRDFCompositeDataSource.h"
class nsXULTreeElement : public nsXULElement,
public nsIDOMXULTreeElement
{
private:
nsIRDFCompositeDataSource* mDatabase;
public:
nsXULTreeElement(nsIDOMXULElement* aOuter)
: nsXULElement(aOuter),
mDatabase(nsnull)
{
}
NS_DECL_ISUPPORTS_INHERITED
// nsIDOMNode interface
NS_FORWARD_IDOMNODE(mOuter->);
// nsIDOMElement interface
NS_FORWARD_IDOMELEMENT(mOuter->);
// nsIDOMXULElement interface
NS_FORWARD_IDOMXULELEMENT(mOuter->);
// nsIDOMXULTreeElement interface
NS_DECL_IDOMXULTREEELEMENT
virtual const nsIID& GetDOMIID() {
return nsIDOMXULTreeElement::GetIID();
}
};
#endif // nsXULTreeElement_h__

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +0,0 @@
interface XULDocument : Document {
/* IID: { 0x17ddd8c0, 0xc5f8, 0x11d2, \
{ 0xa6, 0xae, 0x0, 0x10, 0x4b, 0xde, 0x60, 0x48 } } */
Element getElementById(in DOMString id);
NodeList getElementsByAttribute(in DOMString name, in DOMString value);
};

View File

@@ -1,12 +0,0 @@
interface XULElement : Element {
/* IID: { 0x574ed81, 0xc088, 0x11d2, \
{ 0x96, 0xed, 0x0, 0x10, 0x4b, 0x7b, 0x7d, 0xeb } } */
readonly attribute xpidl nsIRDFResource resource;
void addBroadcastListener(in DOMString attr, in Element element);
void removeBroadcastListener(in DOMString attr, in Element element);
void doCommand();
NodeList getElementsByAttribute(in DOMString name, in DOMString value);
};

View File

@@ -1,5 +0,0 @@
interface XULTreeElement : XULElement {
/* IID: { 0xa6cf90ec, 0x15b3, 0x11d2, \
{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} } */
attribute xpidl nsIRDFCompositeDataSource database;
};

View File

@@ -1,60 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/* AUTO-GENERATED. DO NOT EDIT!!! */
#ifndef nsIDOMXULDocument_h__
#define nsIDOMXULDocument_h__
#include "nsISupports.h"
#include "nsString.h"
#include "nsIScriptContext.h"
#include "nsIDOMDocument.h"
class nsIDOMElement;
class nsIDOMNodeList;
#define NS_IDOMXULDOCUMENT_IID \
{ 0x17ddd8c0, 0xc5f8, 0x11d2, \
{ 0xa6, 0xae, 0x0, 0x10, 0x4b, 0xde, 0x60, 0x48 } }
class nsIDOMXULDocument : public nsIDOMDocument {
public:
static const nsIID& GetIID() { static nsIID iid = NS_IDOMXULDOCUMENT_IID; return iid; }
NS_IMETHOD GetElementById(const nsString& aId, nsIDOMElement** aReturn)=0;
NS_IMETHOD GetElementsByAttribute(const nsString& aName, const nsString& aValue, nsIDOMNodeList** aReturn)=0;
};
#define NS_DECL_IDOMXULDOCUMENT \
NS_IMETHOD GetElementById(const nsString& aId, nsIDOMElement** aReturn); \
NS_IMETHOD GetElementsByAttribute(const nsString& aName, const nsString& aValue, nsIDOMNodeList** aReturn); \
#define NS_FORWARD_IDOMXULDOCUMENT(_to) \
NS_IMETHOD GetElementById(const nsString& aId, nsIDOMElement** aReturn) { return _to GetElementById(aId, aReturn); } \
NS_IMETHOD GetElementsByAttribute(const nsString& aName, const nsString& aValue, nsIDOMNodeList** aReturn) { return _to GetElementsByAttribute(aName, aValue, aReturn); } \
extern "C" NS_DOM nsresult NS_InitXULDocumentClass(nsIScriptContext *aContext, void **aPrototype);
extern "C" NS_DOM nsresult NS_NewScriptXULDocument(nsIScriptContext *aContext, nsISupports *aSupports, nsISupports *aParent, void **aReturn);
#endif // nsIDOMXULDocument_h__

View File

@@ -1,73 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/* AUTO-GENERATED. DO NOT EDIT!!! */
#ifndef nsIDOMXULElement_h__
#define nsIDOMXULElement_h__
#include "nsISupports.h"
#include "nsString.h"
#include "nsIScriptContext.h"
#include "nsIDOMElement.h"
class nsIDOMElement;
class nsIRDFResource;
class nsIDOMNodeList;
#define NS_IDOMXULELEMENT_IID \
{ 0x574ed81, 0xc088, 0x11d2, \
{ 0x96, 0xed, 0x0, 0x10, 0x4b, 0x7b, 0x7d, 0xeb } }
class nsIDOMXULElement : public nsIDOMElement {
public:
static const nsIID& GetIID() { static nsIID iid = NS_IDOMXULELEMENT_IID; return iid; }
NS_IMETHOD GetResource(nsIRDFResource** aResource)=0;
NS_IMETHOD AddBroadcastListener(const nsString& aAttr, nsIDOMElement* aElement)=0;
NS_IMETHOD RemoveBroadcastListener(const nsString& aAttr, nsIDOMElement* aElement)=0;
NS_IMETHOD DoCommand()=0;
NS_IMETHOD GetElementsByAttribute(const nsString& aName, const nsString& aValue, nsIDOMNodeList** aReturn)=0;
};
#define NS_DECL_IDOMXULELEMENT \
NS_IMETHOD GetResource(nsIRDFResource** aResource); \
NS_IMETHOD AddBroadcastListener(const nsString& aAttr, nsIDOMElement* aElement); \
NS_IMETHOD RemoveBroadcastListener(const nsString& aAttr, nsIDOMElement* aElement); \
NS_IMETHOD DoCommand(); \
NS_IMETHOD GetElementsByAttribute(const nsString& aName, const nsString& aValue, nsIDOMNodeList** aReturn); \
#define NS_FORWARD_IDOMXULELEMENT(_to) \
NS_IMETHOD GetResource(nsIRDFResource** aResource) { return _to GetResource(aResource); } \
NS_IMETHOD AddBroadcastListener(const nsString& aAttr, nsIDOMElement* aElement) { return _to AddBroadcastListener(aAttr, aElement); } \
NS_IMETHOD RemoveBroadcastListener(const nsString& aAttr, nsIDOMElement* aElement) { return _to RemoveBroadcastListener(aAttr, aElement); } \
NS_IMETHOD DoCommand() { return _to DoCommand(); } \
NS_IMETHOD GetElementsByAttribute(const nsString& aName, const nsString& aValue, nsIDOMNodeList** aReturn) { return _to GetElementsByAttribute(aName, aValue, aReturn); } \
extern "C" NS_DOM nsresult NS_InitXULElementClass(nsIScriptContext *aContext, void **aPrototype);
extern "C" NS_DOM nsresult NS_NewScriptXULElement(nsIScriptContext *aContext, nsISupports *aSupports, nsISupports *aParent, void **aReturn);
#endif // nsIDOMXULElement_h__

View File

@@ -1,58 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/* AUTO-GENERATED. DO NOT EDIT!!! */
#ifndef nsIDOMXULTreeElement_h__
#define nsIDOMXULTreeElement_h__
#include "nsISupports.h"
#include "nsString.h"
#include "nsIScriptContext.h"
#include "nsIDOMXULElement.h"
class nsIRDFCompositeDataSource;
#define NS_IDOMXULTREEELEMENT_IID \
{ 0xa6cf90ec, 0x15b3, 0x11d2, \
{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} }
class nsIDOMXULTreeElement : public nsIDOMXULElement {
public:
static const nsIID& GetIID() { static nsIID iid = NS_IDOMXULTREEELEMENT_IID; return iid; }
NS_IMETHOD GetDatabase(nsIRDFCompositeDataSource** aDatabase)=0;
NS_IMETHOD SetDatabase(nsIRDFCompositeDataSource* aDatabase)=0;
};
#define NS_DECL_IDOMXULTREEELEMENT \
NS_IMETHOD GetDatabase(nsIRDFCompositeDataSource** aDatabase); \
NS_IMETHOD SetDatabase(nsIRDFCompositeDataSource* aDatabase); \
#define NS_FORWARD_IDOMXULTREEELEMENT(_to) \
NS_IMETHOD GetDatabase(nsIRDFCompositeDataSource** aDatabase) { return _to GetDatabase(aDatabase); } \
NS_IMETHOD SetDatabase(nsIRDFCompositeDataSource* aDatabase) { return _to SetDatabase(aDatabase); } \
extern "C" NS_DOM nsresult NS_InitXULTreeElementClass(nsIScriptContext *aContext, void **aPrototype);
extern "C" NS_DOM nsresult NS_NewScriptXULTreeElement(nsIScriptContext *aContext, nsISupports *aSupports, nsISupports *aParent, void **aReturn);
#endif // nsIDOMXULTreeElement_h__

View File

@@ -1,356 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/* AUTO-GENERATED. DO NOT EDIT!!! */
#include "jsapi.h"
#include "nsJSUtils.h"
#include "nscore.h"
#include "nsIScriptContext.h"
#include "nsIJSScriptObject.h"
#include "nsIScriptObjectOwner.h"
#include "nsIScriptGlobalObject.h"
#include "nsIPtr.h"
#include "nsString.h"
#include "nsIDOMElement.h"
#include "nsIDOMXULDocument.h"
#include "nsIDOMNodeList.h"
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
static NS_DEFINE_IID(kIJSScriptObjectIID, NS_IJSSCRIPTOBJECT_IID);
static NS_DEFINE_IID(kIScriptGlobalObjectIID, NS_ISCRIPTGLOBALOBJECT_IID);
static NS_DEFINE_IID(kIElementIID, NS_IDOMELEMENT_IID);
static NS_DEFINE_IID(kIXULDocumentIID, NS_IDOMXULDOCUMENT_IID);
static NS_DEFINE_IID(kINodeListIID, NS_IDOMNODELIST_IID);
NS_DEF_PTR(nsIDOMElement);
NS_DEF_PTR(nsIDOMXULDocument);
NS_DEF_PTR(nsIDOMNodeList);
/***********************************************************************/
//
// XULDocument Properties Getter
//
PR_STATIC_CALLBACK(JSBool)
GetXULDocumentProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
nsIDOMXULDocument *a = (nsIDOMXULDocument*)JS_GetPrivate(cx, obj);
// If there's no private data, this must be the prototype, so ignore
if (nsnull == a) {
return JS_TRUE;
}
if (JSVAL_IS_INT(id)) {
switch(JSVAL_TO_INT(id)) {
case 0:
default:
return nsJSUtils::nsCallJSScriptObjectGetProperty(a, cx, id, vp);
}
}
else {
return nsJSUtils::nsCallJSScriptObjectGetProperty(a, cx, id, vp);
}
return PR_TRUE;
}
/***********************************************************************/
//
// XULDocument Properties Setter
//
PR_STATIC_CALLBACK(JSBool)
SetXULDocumentProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
nsIDOMXULDocument *a = (nsIDOMXULDocument*)JS_GetPrivate(cx, obj);
// If there's no private data, this must be the prototype, so ignore
if (nsnull == a) {
return JS_TRUE;
}
if (JSVAL_IS_INT(id)) {
switch(JSVAL_TO_INT(id)) {
case 0:
default:
return nsJSUtils::nsCallJSScriptObjectSetProperty(a, cx, id, vp);
}
}
else {
return nsJSUtils::nsCallJSScriptObjectSetProperty(a, cx, id, vp);
}
return PR_TRUE;
}
//
// XULDocument finalizer
//
PR_STATIC_CALLBACK(void)
FinalizeXULDocument(JSContext *cx, JSObject *obj)
{
nsJSUtils::nsGenericFinalize(cx, obj);
}
//
// XULDocument enumerate
//
PR_STATIC_CALLBACK(JSBool)
EnumerateXULDocument(JSContext *cx, JSObject *obj)
{
return nsJSUtils::nsGenericEnumerate(cx, obj);
}
//
// XULDocument resolve
//
PR_STATIC_CALLBACK(JSBool)
ResolveXULDocument(JSContext *cx, JSObject *obj, jsval id)
{
return nsJSUtils::nsGenericResolve(cx, obj, id);
}
//
// Native method GetElementById
//
PR_STATIC_CALLBACK(JSBool)
XULDocumentGetElementById(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsIDOMXULDocument *nativeThis = (nsIDOMXULDocument*)JS_GetPrivate(cx, obj);
JSBool rBool = JS_FALSE;
nsIDOMElement* nativeRet;
nsAutoString b0;
*rval = JSVAL_NULL;
// If there's no private data, this must be the prototype, so ignore
if (nsnull == nativeThis) {
return JS_TRUE;
}
if (argc >= 1) {
nsJSUtils::nsConvertJSValToString(b0, cx, argv[0]);
if (NS_OK != nativeThis->GetElementById(b0, &nativeRet)) {
return JS_FALSE;
}
nsJSUtils::nsConvertObjectToJSVal(nativeRet, cx, rval);
}
else {
JS_ReportError(cx, "Function getElementById requires 1 parameters");
return JS_FALSE;
}
return JS_TRUE;
}
//
// Native method GetElementsByAttribute
//
PR_STATIC_CALLBACK(JSBool)
XULDocumentGetElementsByAttribute(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsIDOMXULDocument *nativeThis = (nsIDOMXULDocument*)JS_GetPrivate(cx, obj);
JSBool rBool = JS_FALSE;
nsIDOMNodeList* nativeRet;
nsAutoString b0;
nsAutoString b1;
*rval = JSVAL_NULL;
// If there's no private data, this must be the prototype, so ignore
if (nsnull == nativeThis) {
return JS_TRUE;
}
if (argc >= 2) {
nsJSUtils::nsConvertJSValToString(b0, cx, argv[0]);
nsJSUtils::nsConvertJSValToString(b1, cx, argv[1]);
if (NS_OK != nativeThis->GetElementsByAttribute(b0, b1, &nativeRet)) {
return JS_FALSE;
}
nsJSUtils::nsConvertObjectToJSVal(nativeRet, cx, rval);
}
else {
JS_ReportError(cx, "Function getElementsByAttribute requires 2 parameters");
return JS_FALSE;
}
return JS_TRUE;
}
/***********************************************************************/
//
// class for XULDocument
//
JSClass XULDocumentClass = {
"XULDocument",
JSCLASS_HAS_PRIVATE,
JS_PropertyStub,
JS_PropertyStub,
GetXULDocumentProperty,
SetXULDocumentProperty,
EnumerateXULDocument,
ResolveXULDocument,
JS_ConvertStub,
FinalizeXULDocument
};
//
// XULDocument class properties
//
static JSPropertySpec XULDocumentProperties[] =
{
{0}
};
//
// XULDocument class methods
//
static JSFunctionSpec XULDocumentMethods[] =
{
{"getElementById", XULDocumentGetElementById, 1},
{"getElementsByAttribute", XULDocumentGetElementsByAttribute, 2},
{0}
};
//
// XULDocument constructor
//
PR_STATIC_CALLBACK(JSBool)
XULDocument(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
return JS_FALSE;
}
//
// XULDocument class initialization
//
extern "C" NS_DOM nsresult NS_InitXULDocumentClass(nsIScriptContext *aContext, void **aPrototype)
{
JSContext *jscontext = (JSContext *)aContext->GetNativeContext();
JSObject *proto = nsnull;
JSObject *constructor = nsnull;
JSObject *parent_proto = nsnull;
JSObject *global = JS_GetGlobalObject(jscontext);
jsval vp;
if ((PR_TRUE != JS_LookupProperty(jscontext, global, "XULDocument", &vp)) ||
!JSVAL_IS_OBJECT(vp) ||
((constructor = JSVAL_TO_OBJECT(vp)) == nsnull) ||
(PR_TRUE != JS_LookupProperty(jscontext, JSVAL_TO_OBJECT(vp), "prototype", &vp)) ||
!JSVAL_IS_OBJECT(vp)) {
if (NS_OK != NS_InitDocumentClass(aContext, (void **)&parent_proto)) {
return NS_ERROR_FAILURE;
}
proto = JS_InitClass(jscontext, // context
global, // global object
parent_proto, // parent proto
&XULDocumentClass, // JSClass
XULDocument, // JSNative ctor
0, // ctor args
XULDocumentProperties, // proto props
XULDocumentMethods, // proto funcs
nsnull, // ctor props (static)
nsnull); // ctor funcs (static)
if (nsnull == proto) {
return NS_ERROR_FAILURE;
}
}
else if ((nsnull != constructor) && JSVAL_IS_OBJECT(vp)) {
proto = JSVAL_TO_OBJECT(vp);
}
else {
return NS_ERROR_FAILURE;
}
if (aPrototype) {
*aPrototype = proto;
}
return NS_OK;
}
//
// Method for creating a new XULDocument JavaScript object
//
extern "C" NS_DOM nsresult NS_NewScriptXULDocument(nsIScriptContext *aContext, nsISupports *aSupports, nsISupports *aParent, void **aReturn)
{
NS_PRECONDITION(nsnull != aContext && nsnull != aSupports && nsnull != aReturn, "null argument to NS_NewScriptXULDocument");
JSObject *proto;
JSObject *parent;
nsIScriptObjectOwner *owner;
JSContext *jscontext = (JSContext *)aContext->GetNativeContext();
nsresult result = NS_OK;
nsIDOMXULDocument *aXULDocument;
if (nsnull == aParent) {
parent = nsnull;
}
else if (NS_OK == aParent->QueryInterface(kIScriptObjectOwnerIID, (void**)&owner)) {
if (NS_OK != owner->GetScriptObject(aContext, (void **)&parent)) {
NS_RELEASE(owner);
return NS_ERROR_FAILURE;
}
NS_RELEASE(owner);
}
else {
return NS_ERROR_FAILURE;
}
if (NS_OK != NS_InitXULDocumentClass(aContext, (void **)&proto)) {
return NS_ERROR_FAILURE;
}
result = aSupports->QueryInterface(kIXULDocumentIID, (void **)&aXULDocument);
if (NS_OK != result) {
return result;
}
// create a js object for this class
*aReturn = JS_NewObject(jscontext, &XULDocumentClass, proto, parent);
if (nsnull != *aReturn) {
// connect the native object to the js object
JS_SetPrivate(jscontext, (JSObject *)*aReturn, aXULDocument);
}
else {
NS_RELEASE(aXULDocument);
return NS_ERROR_FAILURE;
}
return NS_OK;
}

View File

@@ -1,469 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/* AUTO-GENERATED. DO NOT EDIT!!! */
#include "jsapi.h"
#include "nsJSUtils.h"
#include "nscore.h"
#include "nsIScriptContext.h"
#include "nsIJSScriptObject.h"
#include "nsIScriptObjectOwner.h"
#include "nsIScriptGlobalObject.h"
#include "nsIPtr.h"
#include "nsString.h"
#include "nsIDOMElement.h"
#include "nsIDOMXULElement.h"
#include "nsIRDFResource.h"
#include "nsIDOMNodeList.h"
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
static NS_DEFINE_IID(kIJSScriptObjectIID, NS_IJSSCRIPTOBJECT_IID);
static NS_DEFINE_IID(kIScriptGlobalObjectIID, NS_ISCRIPTGLOBALOBJECT_IID);
static NS_DEFINE_IID(kIElementIID, NS_IDOMELEMENT_IID);
static NS_DEFINE_IID(kIXULElementIID, NS_IDOMXULELEMENT_IID);
static NS_DEFINE_IID(kIRDFResourceIID, NS_IRDFRESOURCE_IID);
static NS_DEFINE_IID(kINodeListIID, NS_IDOMNODELIST_IID);
NS_DEF_PTR(nsIDOMElement);
NS_DEF_PTR(nsIDOMXULElement);
NS_DEF_PTR(nsIRDFResource);
NS_DEF_PTR(nsIDOMNodeList);
//
// XULElement property ids
//
enum XULElement_slots {
XULELEMENT_RESOURCE = -1
};
/***********************************************************************/
//
// XULElement Properties Getter
//
PR_STATIC_CALLBACK(JSBool)
GetXULElementProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
nsIDOMXULElement *a = (nsIDOMXULElement*)JS_GetPrivate(cx, obj);
// If there's no private data, this must be the prototype, so ignore
if (nsnull == a) {
return JS_TRUE;
}
if (JSVAL_IS_INT(id)) {
switch(JSVAL_TO_INT(id)) {
case XULELEMENT_RESOURCE:
{
nsIRDFResource* prop;
if (NS_OK == a->GetResource(&prop)) {
// get the js object
#ifdef XPIDL_JS_STUBS
*vp = OBJECT_TO_JSVAL(nsIRDFResource::GetJSObject(cx, prop));
#else
nsJSUtils::nsConvertXPCObjectToJSVal(prop, nsIRDFResource::GetIID(), cx, vp);
#endif
}
else {
return JS_FALSE;
}
break;
}
default:
return nsJSUtils::nsCallJSScriptObjectGetProperty(a, cx, id, vp);
}
}
else {
return nsJSUtils::nsCallJSScriptObjectGetProperty(a, cx, id, vp);
}
return PR_TRUE;
}
/***********************************************************************/
//
// XULElement Properties Setter
//
PR_STATIC_CALLBACK(JSBool)
SetXULElementProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
nsIDOMXULElement *a = (nsIDOMXULElement*)JS_GetPrivate(cx, obj);
// If there's no private data, this must be the prototype, so ignore
if (nsnull == a) {
return JS_TRUE;
}
if (JSVAL_IS_INT(id)) {
switch(JSVAL_TO_INT(id)) {
case 0:
default:
return nsJSUtils::nsCallJSScriptObjectSetProperty(a, cx, id, vp);
}
}
else {
return nsJSUtils::nsCallJSScriptObjectSetProperty(a, cx, id, vp);
}
return PR_TRUE;
}
//
// XULElement finalizer
//
PR_STATIC_CALLBACK(void)
FinalizeXULElement(JSContext *cx, JSObject *obj)
{
nsJSUtils::nsGenericFinalize(cx, obj);
}
//
// XULElement enumerate
//
PR_STATIC_CALLBACK(JSBool)
EnumerateXULElement(JSContext *cx, JSObject *obj)
{
return nsJSUtils::nsGenericEnumerate(cx, obj);
}
//
// XULElement resolve
//
PR_STATIC_CALLBACK(JSBool)
ResolveXULElement(JSContext *cx, JSObject *obj, jsval id)
{
return nsJSUtils::nsGenericResolve(cx, obj, id);
}
//
// Native method AddBroadcastListener
//
PR_STATIC_CALLBACK(JSBool)
XULElementAddBroadcastListener(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsIDOMXULElement *nativeThis = (nsIDOMXULElement*)JS_GetPrivate(cx, obj);
JSBool rBool = JS_FALSE;
nsAutoString b0;
nsIDOMElementPtr b1;
*rval = JSVAL_NULL;
// If there's no private data, this must be the prototype, so ignore
if (nsnull == nativeThis) {
return JS_TRUE;
}
if (argc >= 2) {
nsJSUtils::nsConvertJSValToString(b0, cx, argv[0]);
if (JS_FALSE == nsJSUtils::nsConvertJSValToObject((nsISupports **)&b1,
kIElementIID,
"Element",
cx,
argv[1])) {
return JS_FALSE;
}
if (NS_OK != nativeThis->AddBroadcastListener(b0, b1)) {
return JS_FALSE;
}
*rval = JSVAL_VOID;
}
else {
JS_ReportError(cx, "Function addBroadcastListener requires 2 parameters");
return JS_FALSE;
}
return JS_TRUE;
}
//
// Native method RemoveBroadcastListener
//
PR_STATIC_CALLBACK(JSBool)
XULElementRemoveBroadcastListener(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsIDOMXULElement *nativeThis = (nsIDOMXULElement*)JS_GetPrivate(cx, obj);
JSBool rBool = JS_FALSE;
nsAutoString b0;
nsIDOMElementPtr b1;
*rval = JSVAL_NULL;
// If there's no private data, this must be the prototype, so ignore
if (nsnull == nativeThis) {
return JS_TRUE;
}
if (argc >= 2) {
nsJSUtils::nsConvertJSValToString(b0, cx, argv[0]);
if (JS_FALSE == nsJSUtils::nsConvertJSValToObject((nsISupports **)&b1,
kIElementIID,
"Element",
cx,
argv[1])) {
return JS_FALSE;
}
if (NS_OK != nativeThis->RemoveBroadcastListener(b0, b1)) {
return JS_FALSE;
}
*rval = JSVAL_VOID;
}
else {
JS_ReportError(cx, "Function removeBroadcastListener requires 2 parameters");
return JS_FALSE;
}
return JS_TRUE;
}
//
// Native method DoCommand
//
PR_STATIC_CALLBACK(JSBool)
XULElementDoCommand(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsIDOMXULElement *nativeThis = (nsIDOMXULElement*)JS_GetPrivate(cx, obj);
JSBool rBool = JS_FALSE;
*rval = JSVAL_NULL;
// If there's no private data, this must be the prototype, so ignore
if (nsnull == nativeThis) {
return JS_TRUE;
}
if (argc >= 0) {
if (NS_OK != nativeThis->DoCommand()) {
return JS_FALSE;
}
*rval = JSVAL_VOID;
}
else {
JS_ReportError(cx, "Function doCommand requires 0 parameters");
return JS_FALSE;
}
return JS_TRUE;
}
//
// Native method GetElementsByAttribute
//
PR_STATIC_CALLBACK(JSBool)
XULElementGetElementsByAttribute(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsIDOMXULElement *nativeThis = (nsIDOMXULElement*)JS_GetPrivate(cx, obj);
JSBool rBool = JS_FALSE;
nsIDOMNodeList* nativeRet;
nsAutoString b0;
nsAutoString b1;
*rval = JSVAL_NULL;
// If there's no private data, this must be the prototype, so ignore
if (nsnull == nativeThis) {
return JS_TRUE;
}
if (argc >= 2) {
nsJSUtils::nsConvertJSValToString(b0, cx, argv[0]);
nsJSUtils::nsConvertJSValToString(b1, cx, argv[1]);
if (NS_OK != nativeThis->GetElementsByAttribute(b0, b1, &nativeRet)) {
return JS_FALSE;
}
nsJSUtils::nsConvertObjectToJSVal(nativeRet, cx, rval);
}
else {
JS_ReportError(cx, "Function getElementsByAttribute requires 2 parameters");
return JS_FALSE;
}
return JS_TRUE;
}
/***********************************************************************/
//
// class for XULElement
//
JSClass XULElementClass = {
"XULElement",
JSCLASS_HAS_PRIVATE,
JS_PropertyStub,
JS_PropertyStub,
GetXULElementProperty,
SetXULElementProperty,
EnumerateXULElement,
ResolveXULElement,
JS_ConvertStub,
FinalizeXULElement
};
//
// XULElement class properties
//
static JSPropertySpec XULElementProperties[] =
{
{"resource", XULELEMENT_RESOURCE, JSPROP_ENUMERATE | JSPROP_READONLY},
{0}
};
//
// XULElement class methods
//
static JSFunctionSpec XULElementMethods[] =
{
{"addBroadcastListener", XULElementAddBroadcastListener, 2},
{"removeBroadcastListener", XULElementRemoveBroadcastListener, 2},
{"doCommand", XULElementDoCommand, 0},
{"getElementsByAttribute", XULElementGetElementsByAttribute, 2},
{0}
};
//
// XULElement constructor
//
PR_STATIC_CALLBACK(JSBool)
XULElement(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
return JS_FALSE;
}
//
// XULElement class initialization
//
extern "C" NS_DOM nsresult NS_InitXULElementClass(nsIScriptContext *aContext, void **aPrototype)
{
JSContext *jscontext = (JSContext *)aContext->GetNativeContext();
JSObject *proto = nsnull;
JSObject *constructor = nsnull;
JSObject *parent_proto = nsnull;
JSObject *global = JS_GetGlobalObject(jscontext);
jsval vp;
if ((PR_TRUE != JS_LookupProperty(jscontext, global, "XULElement", &vp)) ||
!JSVAL_IS_OBJECT(vp) ||
((constructor = JSVAL_TO_OBJECT(vp)) == nsnull) ||
(PR_TRUE != JS_LookupProperty(jscontext, JSVAL_TO_OBJECT(vp), "prototype", &vp)) ||
!JSVAL_IS_OBJECT(vp)) {
if (NS_OK != NS_InitElementClass(aContext, (void **)&parent_proto)) {
return NS_ERROR_FAILURE;
}
proto = JS_InitClass(jscontext, // context
global, // global object
parent_proto, // parent proto
&XULElementClass, // JSClass
XULElement, // JSNative ctor
0, // ctor args
XULElementProperties, // proto props
XULElementMethods, // proto funcs
nsnull, // ctor props (static)
nsnull); // ctor funcs (static)
if (nsnull == proto) {
return NS_ERROR_FAILURE;
}
}
else if ((nsnull != constructor) && JSVAL_IS_OBJECT(vp)) {
proto = JSVAL_TO_OBJECT(vp);
}
else {
return NS_ERROR_FAILURE;
}
if (aPrototype) {
*aPrototype = proto;
}
return NS_OK;
}
//
// Method for creating a new XULElement JavaScript object
//
extern "C" NS_DOM nsresult NS_NewScriptXULElement(nsIScriptContext *aContext, nsISupports *aSupports, nsISupports *aParent, void **aReturn)
{
NS_PRECONDITION(nsnull != aContext && nsnull != aSupports && nsnull != aReturn, "null argument to NS_NewScriptXULElement");
JSObject *proto;
JSObject *parent;
nsIScriptObjectOwner *owner;
JSContext *jscontext = (JSContext *)aContext->GetNativeContext();
nsresult result = NS_OK;
nsIDOMXULElement *aXULElement;
if (nsnull == aParent) {
parent = nsnull;
}
else if (NS_OK == aParent->QueryInterface(kIScriptObjectOwnerIID, (void**)&owner)) {
if (NS_OK != owner->GetScriptObject(aContext, (void **)&parent)) {
NS_RELEASE(owner);
return NS_ERROR_FAILURE;
}
NS_RELEASE(owner);
}
else {
return NS_ERROR_FAILURE;
}
if (NS_OK != NS_InitXULElementClass(aContext, (void **)&proto)) {
return NS_ERROR_FAILURE;
}
result = aSupports->QueryInterface(kIXULElementIID, (void **)&aXULElement);
if (NS_OK != result) {
return result;
}
// create a js object for this class
*aReturn = JS_NewObject(jscontext, &XULElementClass, proto, parent);
if (nsnull != *aReturn) {
// connect the native object to the js object
JS_SetPrivate(jscontext, (JSObject *)*aReturn, aXULElement);
}
else {
NS_RELEASE(aXULElement);
return NS_ERROR_FAILURE;
}
return NS_OK;
}

View File

@@ -1,308 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/* AUTO-GENERATED. DO NOT EDIT!!! */
#include "jsapi.h"
#include "nsJSUtils.h"
#include "nscore.h"
#include "nsIScriptContext.h"
#include "nsIJSScriptObject.h"
#include "nsIScriptObjectOwner.h"
#include "nsIScriptGlobalObject.h"
#include "nsIPtr.h"
#include "nsString.h"
#include "nsIRDFCompositeDataSource.h"
#include "nsIDOMXULTreeElement.h"
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
static NS_DEFINE_IID(kIJSScriptObjectIID, NS_IJSSCRIPTOBJECT_IID);
static NS_DEFINE_IID(kIScriptGlobalObjectIID, NS_ISCRIPTGLOBALOBJECT_IID);
static NS_DEFINE_IID(kIRDFCompositeDataSourceIID, NS_IRDFCOMPOSITEDATASOURCE_IID);
static NS_DEFINE_IID(kIXULTreeElementIID, NS_IDOMXULTREEELEMENT_IID);
NS_DEF_PTR(nsIRDFCompositeDataSource);
NS_DEF_PTR(nsIDOMXULTreeElement);
//
// XULTreeElement property ids
//
enum XULTreeElement_slots {
XULTREEELEMENT_DATABASE = -1
};
/***********************************************************************/
//
// XULTreeElement Properties Getter
//
PR_STATIC_CALLBACK(JSBool)
GetXULTreeElementProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
nsIDOMXULTreeElement *a = (nsIDOMXULTreeElement*)JS_GetPrivate(cx, obj);
// If there's no private data, this must be the prototype, so ignore
if (nsnull == a) {
return JS_TRUE;
}
if (JSVAL_IS_INT(id)) {
switch(JSVAL_TO_INT(id)) {
case XULTREEELEMENT_DATABASE:
{
nsIRDFCompositeDataSource* prop;
if (NS_OK == a->GetDatabase(&prop)) {
// get the js object
#ifdef XPIDL_JS_STUBS
*vp = OBJECT_TO_JSVAL(nsIRDFCompositeDataSource::GetJSObject(cx, prop));
#else
nsJSUtils::nsConvertXPCObjectToJSVal(prop, nsIRDFCompositeDataSource::GetIID(), cx, vp);
#endif
}
else {
return JS_FALSE;
}
break;
}
default:
return nsJSUtils::nsCallJSScriptObjectGetProperty(a, cx, id, vp);
}
}
else {
return nsJSUtils::nsCallJSScriptObjectGetProperty(a, cx, id, vp);
}
return PR_TRUE;
}
/***********************************************************************/
//
// XULTreeElement Properties Setter
//
PR_STATIC_CALLBACK(JSBool)
SetXULTreeElementProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
nsIDOMXULTreeElement *a = (nsIDOMXULTreeElement*)JS_GetPrivate(cx, obj);
// If there's no private data, this must be the prototype, so ignore
if (nsnull == a) {
return JS_TRUE;
}
if (JSVAL_IS_INT(id)) {
switch(JSVAL_TO_INT(id)) {
case XULTREEELEMENT_DATABASE:
{
nsIRDFCompositeDataSource* prop;
if (PR_FALSE == nsJSUtils::nsConvertJSValToObject((nsISupports **)&prop,
kIRDFCompositeDataSourceIID, "RDFCompositeDataSource",
cx, *vp)) {
return JS_FALSE;
}
a->SetDatabase(prop);
break;
}
default:
return nsJSUtils::nsCallJSScriptObjectSetProperty(a, cx, id, vp);
}
}
else {
return nsJSUtils::nsCallJSScriptObjectSetProperty(a, cx, id, vp);
}
return PR_TRUE;
}
//
// XULTreeElement finalizer
//
PR_STATIC_CALLBACK(void)
FinalizeXULTreeElement(JSContext *cx, JSObject *obj)
{
nsJSUtils::nsGenericFinalize(cx, obj);
}
//
// XULTreeElement enumerate
//
PR_STATIC_CALLBACK(JSBool)
EnumerateXULTreeElement(JSContext *cx, JSObject *obj)
{
return nsJSUtils::nsGenericEnumerate(cx, obj);
}
//
// XULTreeElement resolve
//
PR_STATIC_CALLBACK(JSBool)
ResolveXULTreeElement(JSContext *cx, JSObject *obj, jsval id)
{
return nsJSUtils::nsGenericResolve(cx, obj, id);
}
/***********************************************************************/
//
// class for XULTreeElement
//
JSClass XULTreeElementClass = {
"XULTreeElement",
JSCLASS_HAS_PRIVATE,
JS_PropertyStub,
JS_PropertyStub,
GetXULTreeElementProperty,
SetXULTreeElementProperty,
EnumerateXULTreeElement,
ResolveXULTreeElement,
JS_ConvertStub,
FinalizeXULTreeElement
};
//
// XULTreeElement class properties
//
static JSPropertySpec XULTreeElementProperties[] =
{
{"database", XULTREEELEMENT_DATABASE, JSPROP_ENUMERATE},
{0}
};
//
// XULTreeElement class methods
//
static JSFunctionSpec XULTreeElementMethods[] =
{
{0}
};
//
// XULTreeElement constructor
//
PR_STATIC_CALLBACK(JSBool)
XULTreeElement(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
return JS_FALSE;
}
//
// XULTreeElement class initialization
//
extern "C" NS_DOM nsresult NS_InitXULTreeElementClass(nsIScriptContext *aContext, void **aPrototype)
{
JSContext *jscontext = (JSContext *)aContext->GetNativeContext();
JSObject *proto = nsnull;
JSObject *constructor = nsnull;
JSObject *parent_proto = nsnull;
JSObject *global = JS_GetGlobalObject(jscontext);
jsval vp;
if ((PR_TRUE != JS_LookupProperty(jscontext, global, "XULTreeElement", &vp)) ||
!JSVAL_IS_OBJECT(vp) ||
((constructor = JSVAL_TO_OBJECT(vp)) == nsnull) ||
(PR_TRUE != JS_LookupProperty(jscontext, JSVAL_TO_OBJECT(vp), "prototype", &vp)) ||
!JSVAL_IS_OBJECT(vp)) {
if (NS_OK != NS_InitXULElementClass(aContext, (void **)&parent_proto)) {
return NS_ERROR_FAILURE;
}
proto = JS_InitClass(jscontext, // context
global, // global object
parent_proto, // parent proto
&XULTreeElementClass, // JSClass
XULTreeElement, // JSNative ctor
0, // ctor args
XULTreeElementProperties, // proto props
XULTreeElementMethods, // proto funcs
nsnull, // ctor props (static)
nsnull); // ctor funcs (static)
if (nsnull == proto) {
return NS_ERROR_FAILURE;
}
}
else if ((nsnull != constructor) && JSVAL_IS_OBJECT(vp)) {
proto = JSVAL_TO_OBJECT(vp);
}
else {
return NS_ERROR_FAILURE;
}
if (aPrototype) {
*aPrototype = proto;
}
return NS_OK;
}
//
// Method for creating a new XULTreeElement JavaScript object
//
extern "C" NS_DOM nsresult NS_NewScriptXULTreeElement(nsIScriptContext *aContext, nsISupports *aSupports, nsISupports *aParent, void **aReturn)
{
NS_PRECONDITION(nsnull != aContext && nsnull != aSupports && nsnull != aReturn, "null argument to NS_NewScriptXULTreeElement");
JSObject *proto;
JSObject *parent;
nsIScriptObjectOwner *owner;
JSContext *jscontext = (JSContext *)aContext->GetNativeContext();
nsresult result = NS_OK;
nsIDOMXULTreeElement *aXULTreeElement;
if (nsnull == aParent) {
parent = nsnull;
}
else if (NS_OK == aParent->QueryInterface(kIScriptObjectOwnerIID, (void**)&owner)) {
if (NS_OK != owner->GetScriptObject(aContext, (void **)&parent)) {
NS_RELEASE(owner);
return NS_ERROR_FAILURE;
}
NS_RELEASE(owner);
}
else {
return NS_ERROR_FAILURE;
}
if (NS_OK != NS_InitXULTreeElementClass(aContext, (void **)&proto)) {
return NS_ERROR_FAILURE;
}
result = aSupports->QueryInterface(kIXULTreeElementIID, (void **)&aXULTreeElement);
if (NS_OK != result) {
return result;
}
// create a js object for this class
*aReturn = JS_NewObject(jscontext, &XULTreeElementClass, proto, parent);
if (nsnull != *aReturn) {
// connect the native object to the js object
JS_SetPrivate(jscontext, (JSObject *)*aReturn, aXULTreeElement);
}
else {
NS_RELEASE(aXULTreeElement);
return NS_ERROR_FAILURE;
}
return NS_OK;
}

View File

@@ -0,0 +1,134 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "Fundamentals.h"
#include "BitSet.h"
// Return the next bit after index set to true or -1 if none.
//
Int32 BitSet::nextOne(Int32 pos) const
{
++pos;
if (pos < 0 || Uint32(pos) >= universeSize)
return -1;
Uint32 offset = getWordOffset(pos);
Uint8 index = getBitOffset(pos);
Word* ptr = &word[offset];
Word currentWord = *ptr++ >> index;
if (currentWord != Word(0)) {
while ((currentWord & Word(1)) == 0) {
++index;
currentWord >>= 1;
}
return (offset << nBitsInWordLog2) + index;
}
Word* limit = &word[getSizeInWords(universeSize)];
while (ptr < limit) {
++offset;
currentWord = *ptr++;
if (currentWord != Word(0)) {
index = 0;
while ((currentWord & Word(1)) == 0) {
++index;
currentWord >>= 1;
}
return (offset << nBitsInWordLog2) + index;
}
}
return -1;
}
// Return the next bit after index set to false or -1 if none.
//
Int32 BitSet::nextZero(Int32 pos) const
{
++pos;
if (pos < 0 || Uint32(pos) >= universeSize)
return -1;
Uint32 offset = getWordOffset(pos);
Uint8 index = getBitOffset(pos);
Word* ptr = &word[offset];
Word currentWord = *ptr++ >> index;
if (currentWord != Word(~0)) {
for (; index < nBitsInWord; ++index) {
if ((currentWord & Word(1)) == 0) {
Int32 ret = (offset << nBitsInWordLog2) + index;
return (Uint32(ret) < universeSize) ? ret : -1;
}
currentWord >>= 1;
}
}
Word* limit = &word[getSizeInWords(universeSize)];
while (ptr < limit) {
++offset;
currentWord = *ptr++;
if (currentWord != Word(~0)) {
for (index = 0; index < nBitsInWord; ++index) {
if ((currentWord & Word(1)) == 0) {
Int32 ret = (offset << nBitsInWordLog2) + index;
return (Uint32(ret) < universeSize) ? ret : -1;
}
currentWord >>= 1;
}
}
}
return -1;
}
#ifdef DEBUG_LOG
// Print the set.
//
void BitSet::printPretty(LogModuleObject log)
{
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("[ "));
for (Int32 i = firstOne(); i != -1; i = nextOne(i)) {
Int32 currentBit = i;
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%d", currentBit));
Int32 nextBit = nextOne(currentBit);
if (nextBit != currentBit + 1) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (" "));
continue;
}
while ((nextBit != -1) && (nextBit == (currentBit + 1))) {
currentBit = nextBit;
nextBit = nextOne(nextBit);
}
if (currentBit > (i+1))
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("-%d ", currentBit));
else
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (" %d ", currentBit));
i = currentBit;
}
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("]\n"));
}
#endif // DEBUG_LOG

View File

@@ -0,0 +1,195 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _BITSET_H_
#define _BITSET_H_
#include "Fundamentals.h"
#include "LogModule.h"
#include "Pool.h"
#include <string.h>
//------------------------------------------------------------------------------
// BitSet -
class BitSet
{
private:
#if (PR_BITS_PER_WORD == 64)
typedef Uint64 Word;
#elif (PR_BITS_PER_WORD == 32)
typedef Uint32 Word;
#endif
static const nBitsInWord = PR_BITS_PER_WORD;
static const nBytesInWord = PR_BYTES_PER_WORD;
static const nBitsInWordLog2 = PR_BITS_PER_WORD_LOG2;
static const nBytesInWordLog2 = PR_BYTES_PER_WORD_LOG2;
// Return the number of Word need to store the universe.
static Uint32 getSizeInWords(Uint32 sizeOfUniverse) {return (sizeOfUniverse + (nBitsInWord - 1)) >> nBitsInWordLog2;}
// Return the given element offset in its containing Word.
static Uint32 getBitOffset(Uint32 element) {return element & (nBitsInWord - 1);}
// Return the Word offset for the given element int the universe.
static Uint32 getWordOffset(Uint32 element) {return element >> nBitsInWordLog2;}
// Return the mask for the given bit index.
static Word getMask(Uint8 index) {return Word(1) << index;}
private:
Uint32 universeSize; // Size of the universe
Word* word; // universe memory.
private:
// No copy constructor.
BitSet(const BitSet&);
// Check if the given set's universe is of the same size than this universe.
void checkUniverseCompatibility(const BitSet& set) const {assert(set.universeSize == universeSize);}
// Check if pos is valid for this set's universe.
void checkMember(Int32 pos) const {assert(pos >=0 && Uint32(pos) < universeSize);}
public:
// Create a bitset of universeSize bits.
BitSet(Pool& pool, Uint32 universeSize) : universeSize(universeSize) {word = new(pool) Word[getSizeInWords(universeSize)]; clear();}
// Return the size of this bitset.
Uint32 getSize() const {return universeSize;}
// Clear the bitset.
void clear() {memset(word, 0x00, getSizeInWords(universeSize) << nBytesInWordLog2);}
// Clear the bit at index.
void clear(Uint32 index) {checkMember(index); word[getWordOffset(index)] &= ~getMask(index);}
// Set the bitset.
void set() {memset(word, 0xFF, getSizeInWords(universeSize) << nBytesInWordLog2);}
// Set the bit at index.
void set(Uint32 index) {checkMember(index); word[getWordOffset(index)] |= getMask(index);}
// Return true if the bit at index is set.
bool test(Uint32 index) const {checkMember(index); return (word[getWordOffset(index)] & getMask(index)) != 0;}
// Union with the given bitset.
inline void or(const BitSet& set);
// Intersection with the given bitset.
inline void and(const BitSet& set);
// Difference with the given bitset.
inline void difference(const BitSet& set);
// Copy set.
inline BitSet& operator = (const BitSet& set);
// Return true if the bitset are identical.
friend bool operator == (const BitSet& set1, const BitSet& set2);
// Return true if the bitset are different.
friend bool operator != (const BitSet& set1, const BitSet& set2);
// Logical operators.
BitSet& operator |= (const BitSet& set) {or(set); return *this;}
BitSet& operator &= (const BitSet& set) {and(set); return *this;}
BitSet& operator -= (const BitSet& set) {difference(set); return *this;}
// Return the first bit at set to true or -1 if none.
Int32 firstOne() const {return nextOne(-1);}
// Return the next bit after index set to true or -1 if none.
Int32 nextOne(Int32 pos) const;
// Return the first bit at set to false or -1 if none.
Int32 firstZero() const {return nextZero(-1);}
// Return the next bit after index set to false or -1 if none.
Int32 nextZero(Int32 pos) const;
// Iterator to conform with the set API.
typedef Int32 iterator;
// Return true if the walk is ordered.
static bool isOrdered() {return true;}
// Return the iterator for the first element of this set.
iterator begin() const {return firstOne();}
// Return the next iterator.
iterator advance(iterator pos) const {return nextOne(pos);}
// Return true if the iterator is at the end of the set.
bool done(iterator pos) const {return pos == -1;}
// Return the element corresponding to the given iterator.
Uint32 get(iterator pos) const {return pos;}
#ifdef DEBUG_LOG
// Print the set.
void printPretty(LogModuleObject log);
#endif // DEBUG_LOG
};
// Union with the given bitset.
//
inline void BitSet::or(const BitSet& set)
{
checkUniverseCompatibility(set);
Word* src = set.word;
Word* dst = word;
Word* limit = &src[getSizeInWords(universeSize)];
while (src < limit)
*dst++ |= *src++;
}
// Intersection with the given bitset.
//
inline void BitSet::and(const BitSet& set)
{
checkUniverseCompatibility(set);
Word* src = set.word;
Word* dst = word;
Word* limit = &src[getSizeInWords(universeSize)];
while (src < limit)
*dst++ &= *src++;
}
// Difference with the given bitset.
//
inline void BitSet::difference(const BitSet& set)
{
checkUniverseCompatibility(set);
Word* src = set.word;
Word* dst = word;
Word* limit = &src[getSizeInWords(universeSize)];
while (src < limit)
*dst++ &= ~*src++;
}
// Copy the given set into this set.
//
inline BitSet& BitSet::operator = (const BitSet& set)
{
checkUniverseCompatibility(set);
if (this != &set)
memcpy(word, set.word, getSizeInWords(universeSize) << nBytesInWordLog2);
return *this;
}
// Return true if the given set is identical to this set.
inline bool operator == (const BitSet& set1, const BitSet& set2)
{
set1.checkUniverseCompatibility(set2);
if (&set1 == &set2)
return true;
return memcmp(set1.word, set2.word, BitSet::getSizeInWords(set1.universeSize) << BitSet::nBytesInWordLog2) == 0;
}
inline bool operator != (const BitSet& set1, const BitSet& set2) {return !(set1 == set2);}
#endif // _BITSET_H

View File

@@ -0,0 +1,159 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _COALESCING_H_
#define _COALESCING_H_
#include "Fundamentals.h"
#include "Pool.h"
#include "RegisterPressure.h"
#include "InterferenceGraph.h"
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "Instruction.h"
#include "SparseSet.h"
#include "RegisterAllocator.h"
#include "RegisterAllocatorTools.h"
#if 1
// Performing an ultra conservative coalescing meens that when we look at
// candidates (source,destination) for coalescing we need to make sure
// that the combined interference of the source and destination register
// will not exceed the total number of register available for the register
// class.
#define ULTRA_CONSERVATIVE_COALESCING
#else
// If we are not doing an ultra conservative coalescing we have to make sure
// that the total number of neighbor whose degree is greater than the total
// number of register is not greater than the total number of register.
#undef ULTRA_CONSERVATIVE_COALESCING
#endif
template <class RegisterPressure>
struct Coalescing
{
static bool coalesce(RegisterAllocator& registerAllocator);
};
template <class RegisterPressure>
bool Coalescing<RegisterPressure>::coalesce(RegisterAllocator& registerAllocator)
{
Pool& pool = registerAllocator.pool;
// Initialize the lookup table
//
Uint32 rangeCount = registerAllocator.rangeCount;
RegisterName* newRange = new RegisterName[2 * rangeCount];
RegisterName* coalescedRange = &newRange[rangeCount];
RegisterName* name2range = registerAllocator.name2range;
init(coalescedRange, rangeCount);
SparseSet interferences(pool, rangeCount);
InterferenceGraph<RegisterPressure>& iGraph = registerAllocator.iGraph;
bool removedInstructions = false;
ControlGraph& controlGraph = registerAllocator.controlGraph;
ControlNode** nodes = controlGraph.lndList;
Uint32 nNodes = controlGraph.nNodes;
// Walk the nodes in the loop nesting depth list.
for (Int32 n = nNodes - 1; n >= 0; n--) {
InstructionList& instructions = nodes[n]->getInstructions();
InstructionList::iterator it = instructions.begin();
while (!instructions.done(it)) {
Instruction& instruction = instructions.get(it);
it = instructions.advance(it);
if ((instruction.getFlags() & ifCopy) != 0) {
assert(instruction.getInstructionUseBegin() != instruction.getInstructionUseEnd() && instruction.getInstructionUseBegin()[0].isRegister());
assert(instruction.getInstructionDefineBegin() != instruction.getInstructionDefineEnd() && instruction.getInstructionDefineBegin()[0].isRegister());
RegisterName source = findRoot(name2range[instruction.getInstructionUseBegin()[0].getRegisterName()], coalescedRange);
RegisterName destination = findRoot(name2range[instruction.getInstructionDefineBegin()[0].getRegisterName()], coalescedRange);
if (source == destination) {
instruction.remove();
} else if (!iGraph.interfere(source, destination)) {
InterferenceVector* sourceVector = iGraph.getInterferenceVector(source);
InterferenceVector* destinationVector = iGraph.getInterferenceVector(destination);
#ifdef ULTRA_CONSERVATIVE_COALESCING
interferences.clear();
InterferenceVector* vector;
for (vector = sourceVector; vector != NULL; vector = vector->next) {
RegisterName* neighbors = vector->neighbors;
for (Uint32 i = 0; i < vector->count; i++)
interferences.set(findRoot(neighbors[i], coalescedRange));
}
for (vector = destinationVector; vector != NULL; vector = vector->next) {
RegisterName* neighbors = vector->neighbors;
for (Uint32 i = 0; i < vector->count; i++)
interferences.set(findRoot(neighbors[i], coalescedRange));
}
Uint32 count = interferences.getSize();
#else // ULTRA_CONSERVATIVE_COALESCING
trespass("not implemented");
Uint32 count = 0;
#endif // ULTRA_CONSERVATIVE_COALESCING
if (count < 6 /* FIX: should get the number from the class */) {
// Update the interferences vector.
if (sourceVector == NULL) {
iGraph.setInterferenceVector(source, destinationVector);
sourceVector = destinationVector;
} else if (destinationVector == NULL)
iGraph.setInterferenceVector(destination, sourceVector);
else {
InterferenceVector* last = NULL;
for (InterferenceVector* v = sourceVector; v != NULL; v = v->next)
last = v;
assert(last);
last->next = destinationVector;
iGraph.setInterferenceVector(destination, sourceVector);
}
// Update the interference matrix.
for (InterferenceVector* v = sourceVector; v != NULL; v = v->next) {
RegisterName* neighbors = v->neighbors;
for (Uint32 i = 0; i < v->count; i++) {
RegisterName neighbor = findRoot(neighbors[i], coalescedRange);
iGraph.setInterference(neighbor, source);
iGraph.setInterference(neighbor, destination);
}
}
instruction.remove();
coalescedRange[source] = destination;
removedInstructions = true;
}
}
}
}
}
registerAllocator.rangeCount = compress(registerAllocator.name2range, coalescedRange, registerAllocator.nameCount, rangeCount);
delete newRange;
return removedInstructions;
}
#endif // _COALESCING_H_

View File

@@ -0,0 +1,283 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef NEW_LAURENTM_CODE
#include "Coloring.h"
#include "VirtualRegister.h"
#include "FastBitSet.h"
#include "FastBitMatrix.h"
#include "CpuInfo.h"
bool Coloring::
assignRegisters(FastBitMatrix& interferenceMatrix)
{
PRUint32 *stackPtr = new(pool) PRUint32[vRegManager.count()];
return select(interferenceMatrix, stackPtr, simplify(interferenceMatrix, stackPtr));
}
PRInt32 Coloring::
getLowestSpillCostRegister(FastBitSet& bitset)
{
PRInt32 lowest = bitset.firstOne();
if (lowest != -1)
{
Flt32 cost = vRegManager.getVirtualRegister(lowest).spillInfo.spillCost;
for (PRInt32 r = bitset.nextOne(lowest); r != -1; r = bitset.nextOne(r))
{
VirtualRegister& vReg = vRegManager.getVirtualRegister(r);
if (!vReg.spillInfo.infiniteSpillCost && (vReg.spillInfo.spillCost < cost))
{
cost = vReg.spillInfo.spillCost;
lowest = r;
}
}
}
return lowest;
}
PRUint32* Coloring::
simplify(FastBitMatrix interferenceMatrix, PRUint32* stackPtr)
{
// first we construct the sets low and high. low contains all nodes of degree
// inferior to the number of register available on the processor. All the
// nodes with an high degree and a finite spill cost are placed in high.
// Nodes of high degree and infinite spill cost are not included in either sets.
PRUint32 nRegisters = vRegManager.count();
FastBitSet low(pool, nRegisters);
FastBitSet high(pool, nRegisters);
FastBitSet stack(pool, nRegisters);
for (VirtualRegisterManager::iterator i = vRegManager.begin(); !vRegManager.done(i); i = vRegManager.advance(i))
{
VirtualRegister& vReg = vRegManager.getVirtualRegister(i);
if (vReg.getClass() == vrcStackSlot)
{
stack.set(i);
vReg.colorRegister(nRegisters);
}
else
{
if (vReg.colorInfo.interferenceDegree < NUMBER_OF_REGISTERS)
low.set(i);
else // if (!vReg.spillInfo.infiniteSpillCost)
high.set(i);
// Set coloring info.
vReg.spillInfo.willSpill = false;
switch(vReg.getClass())
{
case vrcInteger:
vReg.colorRegister(LAST_GREGISTER + 1);
break;
case vrcFloatingPoint:
case vrcFixedPoint:
vReg.colorRegister(LAST_FPREGISTER + 1);
break;
default:
PR_ASSERT(false); // Cannot happen.
}
}
}
// push the stack registers
PRInt32 j;
for (j = stack.firstOne(); j != -1; j = stack.nextOne(j))
*stackPtr++ = j;
// simplify
while (true)
{
PRInt32 r;
while ((r = getLowestSpillCostRegister(low)) != -1)
{
VirtualRegister& vReg = vRegManager.getVirtualRegister(r);
/* update low and high */
FastBitSet inter(interferenceMatrix.getRow(r), nRegisters);
for (j = inter.firstOne(); j != -1; j = inter.nextOne(j))
{
VirtualRegister& neighbor = vRegManager.getVirtualRegister(j);
// if the new interference degree of one of his neighbor becomes
// NUMBER_OF_REGISTERS - 1 then it is added to the set 'low'.
PRUint32 maxInterference = 0;
switch (neighbor.getClass())
{
case vrcInteger:
maxInterference = NUMBER_OF_GREGISTERS;
break;
case vrcFloatingPoint:
case vrcFixedPoint:
maxInterference = NUMBER_OF_FPREGISTERS;
break;
default:
PR_ASSERT(false);
}
if ((vRegManager.getVirtualRegister(j).colorInfo.interferenceDegree-- == maxInterference))
{
high.clear(j);
low.set(j);
}
vReg.colorInfo.interferenceDegree--;
interferenceMatrix.clear(r, j);
interferenceMatrix.clear(j, r);
}
low.clear(r);
// Push this register.
*stackPtr++ = r;
}
if ((r = getLowestSpillCostRegister(high)) != -1)
{
high.clear(r);
low.set(r);
}
else
break;
}
return stackPtr;
}
bool Coloring::
select(FastBitMatrix& interferenceMatrix, PRUint32* stackBase, PRUint32* stackPtr)
{
PRUint32 nRegisters = vRegManager.count();
FastBitSet usedRegisters(NUMBER_OF_REGISTERS + 1); // usedRegisters if used for both GR & FPR.
FastBitSet preColoredRegisters(NUMBER_OF_REGISTERS + 1);
FastBitSet usedStack(nRegisters + 1);
bool success = true;
Int32 lastUsedSSR = -1;
// select
while (stackPtr != stackBase)
{
// Pop one register.
PRUint32 r = *--stackPtr;
VirtualRegister& vReg = vRegManager.getVirtualRegister(r);
FastBitSet neighbors(interferenceMatrix.getRow(r), nRegisters);
if (vReg.getClass() == vrcStackSlot)
// Stack slots coloring.
{
usedStack.clear();
for (PRInt32 i = neighbors.firstOne(); i != -1; i = neighbors.nextOne(i))
usedStack.set(vRegManager.getVirtualRegister(i).getColor());
Int32 color = usedStack.firstZero();
vReg.colorRegister(color);
if (color > lastUsedSSR)
lastUsedSSR = color;
}
else
// Integer & Floating point register coloring.
{
usedRegisters.clear();
preColoredRegisters.clear();
for (PRInt32 i = neighbors.firstOne(); i != -1; i = neighbors.nextOne(i))
{
VirtualRegister& nvReg = vRegManager.getVirtualRegister(i);
usedRegisters.set(nvReg.getColor());
if (nvReg.isPreColored())
preColoredRegisters.set(nvReg.getPreColor());
}
if (vReg.hasSpecialInterference)
usedRegisters |= vReg.specialInterference;
PRInt8 c = -1;
PRInt8 maxColor = 0;
PRInt8 firstColor = 0;
switch (vReg.getClass())
{
case vrcInteger:
firstColor = FIRST_GREGISTER;
maxColor = LAST_GREGISTER;
break;
case vrcFloatingPoint:
case vrcFixedPoint:
firstColor = FIRST_FPREGISTER;
maxColor = LAST_FPREGISTER;
break;
default:
PR_ASSERT(false);
}
if (vReg.isPreColored())
{
c = vReg.getPreColor();
if (usedRegisters.test(c))
c = -1;
}
else
{
for (c = usedRegisters.nextZero(firstColor - 1); (c >= 0) && (c <= maxColor) && (preColoredRegisters.test(c));
c = usedRegisters.nextZero(c)) {}
}
if ((c >= 0) && (c <= maxColor))
{
vReg.colorRegister(c);
}
else
{
VirtualRegister& stackRegister = vRegManager.newVirtualRegister(vrcStackSlot);
vReg.equivalentRegister[vrcStackSlot] = &stackRegister;
vReg.spillInfo.willSpill = true;
success = false;
}
}
}
#ifdef DEBUG
if (success)
{
for (VirtualRegisterManager::iterator i = vRegManager.begin(); !vRegManager.done(i); i = vRegManager.advance(i))
{
VirtualRegister& vReg = vRegManager.getVirtualRegister(i);
switch (vReg.getClass())
{
case vrcInteger:
if (vReg.getColor() > LAST_GREGISTER)
PR_ASSERT(false);
break;
case vrcFloatingPoint:
case vrcFixedPoint:
#if NUMBER_OF_FPREGISTERS != 0
if (vReg.getColor() > LAST_FPREGISTER)
PR_ASSERT(false);
#endif
break;
default:
break;
}
}
}
#endif
vRegManager.nUsedStackSlots = lastUsedSSR + 1;
return success;
}
#endif // NEW_LAURENTM_CODE

View File

@@ -0,0 +1,284 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "Fundamentals.h"
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "Instruction.h"
#include "RegisterAllocator.h"
#include "VirtualRegister.h"
#include "InterferenceGraph.h"
#include "SparseSet.h"
#include "Spilling.h"
#include "Splits.h"
UT_EXTERN_LOG_MODULE(RegAlloc);
template <class RegisterPressure>
class Coloring
{
private:
static RegisterName* simplify(RegisterAllocator& registerAllocator, RegisterName* coloringStack);
static bool select(RegisterAllocator& registerAllocator, RegisterName* coloringStack, RegisterName* coloringStackPtr);
public:
static bool color(RegisterAllocator& registerAllocator);
static void finalColoring(RegisterAllocator& registerAllocator);
};
template <class RegisterPressure>
void Coloring<RegisterPressure>::finalColoring(RegisterAllocator& registerAllocator)
{
RegisterName* color = registerAllocator.color;
RegisterName* name2range = registerAllocator.name2range;
ControlGraph& controlGraph = registerAllocator.controlGraph;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
for (Uint32 n = 0; n < nNodes; n++) {
InstructionList& instructions = nodes[n]->getInstructions();
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
usePtr->setRegisterName(color[name2range[usePtr->getRegisterName()]]);
#ifdef DEBUG
RegisterID rid = usePtr->getRegisterID();
setColoredRegister(rid);
usePtr->setRegisterID(rid);
#endif // DEBUG
}
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister()) {
definePtr->setRegisterName(color[name2range[definePtr->getRegisterName()]]);
#ifdef DEBUG
RegisterID rid = definePtr->getRegisterID();
setColoredRegister(rid);
definePtr->setRegisterID(rid);
#endif // DEBUG
}
}
}
}
template <class RegisterPressure>
bool Coloring<RegisterPressure>::select(RegisterAllocator& registerAllocator, RegisterName* coloringStack, RegisterName* coloringStackPtr)
{
Uint32 rangeCount = registerAllocator.rangeCount;
RegisterName* color = new RegisterName[rangeCount];
registerAllocator.color = color;
for (Uint32 r = 1; r < rangeCount; r++)
color[r] = RegisterName(6); // FIX;
// Color the preColored registers.
//
VirtualRegisterManager& vrManager = registerAllocator.vrManager;
RegisterName* name2range = registerAllocator.name2range;
PreColoredRegister* machineEnd = vrManager.getMachineRegistersEnd();
for (PreColoredRegister* machinePtr = vrManager.getMachineRegistersBegin(); machinePtr < machineEnd; machinePtr++)
if (machinePtr->id != invalidID) {
color[name2range[getName(machinePtr->id)]] = machinePtr->color;
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\twill preColor range %d as %d\n", name2range[getName(machinePtr->id)], machinePtr->color));
}
SpillCost* cost = registerAllocator.spillCost;
Pool& pool = registerAllocator.pool;
SparseSet& spill = *new(pool) SparseSet(pool, rangeCount);
registerAllocator.willSpill = &spill;
SparseSet neighborColors(pool, 6); // FIX
InterferenceGraph<RegisterPressure>& iGraph = registerAllocator.iGraph;
bool coloringFailed = false;
while (coloringStackPtr > coloringStack) {
RegisterName range = *--coloringStackPtr;
if (!cost[range].infinite && cost[range].cost < 0) {
coloringFailed = true;
spill.set(range);
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tfailed to color %d, will spill.\n", range));
} else {
neighborColors.clear();
for (InterferenceVector* vector = iGraph.getInterferenceVector(range); vector != NULL; vector = vector->next)
for (Int32 i = vector->count - 1; i >= 0; --i) {
RegisterName neighborColor = color[vector->neighbors[i]];
if (neighborColor < 6) // FIX
neighborColors.set(neighborColor);
}
if (neighborColors.getSize() == 6) { // FIX
coloringFailed = true;
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tfailed to color %d, ", range));
if (!Splits<RegisterPressure>::findSplit(registerAllocator, color, range)) {
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("will spill.\n"));
spill.set(range);
} else
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("will split.\n"));
} else {
for (Uint32 i = 0; i < 6; i++) // FIX
if (!neighborColors.test(i)) {
fprintf(stdout, "\twill color %d as %d\n", range, i);
color[range] = RegisterName(i);
break;
}
}
}
}
#ifdef DEBUG_LOG
if (coloringFailed) {
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("Coloring failed:\n"));
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\twill spill: "));
spill.printPretty(UT_LOG_MODULE(RegAlloc));
} else {
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("Coloring succeeded:\n"));
for (Uint32 i = 1; i < rangeCount; i++)
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\trange %d colored as %d\n", i, color[i]));
}
#endif
return !coloringFailed;
}
template <class RegisterPressure>
RegisterName* Coloring<RegisterPressure>::simplify(RegisterAllocator& registerAllocator, RegisterName* coloringStack)
{
InterferenceGraph<RegisterPressure>& iGraph = registerAllocator.iGraph;
SpillCost* spillCost = registerAllocator.spillCost;
Uint32 rangeCount = registerAllocator.rangeCount;
Uint32* degree = new Uint32[rangeCount];
for (RegisterName i = RegisterName(1); i < rangeCount; i = RegisterName(i + 1)) {
InterferenceVector* vector = iGraph.getInterferenceVector(i);
degree[i] = (vector != NULL) ? vector->count : 0;
}
Pool& pool = registerAllocator.pool;
SparseSet low(pool, rangeCount);
SparseSet high(pool, rangeCount);
SparseSet highInfinite(pool, rangeCount);
SparseSet preColored(pool, rangeCount);
// Get the precolored registers.
//
VirtualRegisterManager& vrManager = registerAllocator.vrManager;
RegisterName* name2range = registerAllocator.name2range;
PreColoredRegister* machineEnd = vrManager.getMachineRegistersEnd();
for (PreColoredRegister* machinePtr = vrManager.getMachineRegistersBegin(); machinePtr < machineEnd; machinePtr++)
if (machinePtr->id != invalidID)
preColored.set(name2range[getName(machinePtr->id)]);
// Insert the live ranges in the sets.
//
for (Uint32 range = 1; range < rangeCount; range++)
if (!preColored.test(range))
if (degree[range] < 6) // FIX
low.set(range);
else if (!spillCost[range].infinite)
high.set(range);
else
highInfinite.set(range);
#ifdef DEBUG_LOG
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("Coloring sets:\n\tlow = "));
low.printPretty(UT_LOG_MODULE(RegAlloc));
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\thigh = "));
high.printPretty(UT_LOG_MODULE(RegAlloc));
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\thighInfinite = "));
highInfinite.printPretty(UT_LOG_MODULE(RegAlloc));
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tpreColored = "));
preColored.printPretty(UT_LOG_MODULE(RegAlloc));
#endif // DEBUG_LOG
RegisterName* coloringStackPtr = coloringStack;
while (low.getSize() != 0 || high.getSize() != 0) {
while (low.getSize() != 0) {
RegisterName range = RegisterName(low.getOne());
low.clear(range);
*coloringStackPtr++ = range;
for (InterferenceVector* vector = iGraph.getInterferenceVector(range); vector != NULL; vector = vector->next)
for (Int32 i = (vector->count - 1); i >= 0; --i) {
RegisterName neighbor = vector->neighbors[i];
degree[neighbor]--;
if (degree[neighbor] < 6) // FIX
if (high.test(neighbor)) {
high.clear(neighbor);
low.set(neighbor);
} else if (highInfinite.test(neighbor)) {
highInfinite.clear(neighbor);
low.set(neighbor);
}
}
}
if (high.getSize() != 0) {
RegisterName best = RegisterName(high.getOne());
double bestCost = spillCost[best].cost;
double bestDegree = degree[best];
// Choose the next best candidate.
//
for (SparseSet::iterator i = high.begin(); !high.done(i); i = high.advance(i)) {
RegisterName range = RegisterName(high.get(i));
double thisCost = spillCost[range].cost;
double thisDegree = degree[range];
if (thisCost * bestDegree < bestCost * thisDegree) {
best = range;
bestCost = thisCost;
bestDegree = thisDegree;
}
}
high.clear(best);
low.set(best);
}
}
assert(highInfinite.getSize() == 0);
delete degree;
#ifdef DEBUG_LOG
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("Coloring stack:\n\t"));
for (RegisterName* sp = coloringStack; sp < coloringStackPtr; ++sp)
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("%d ", *sp));
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\n"));
#endif // DEBUG_LOG
return coloringStackPtr;
}
template <class RegisterPressure>
bool Coloring<RegisterPressure>::color(RegisterAllocator& registerAllocator)
{
RegisterName* coloringStack = new RegisterName[registerAllocator.rangeCount];
return select(registerAllocator, coloringStack, simplify(registerAllocator, coloringStack));
}

View File

@@ -0,0 +1,212 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "Fundamentals.h"
#include <string.h>
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "DominatorGraph.h"
DominatorGraph::DominatorGraph(ControlGraph& controlGraph) : controlGraph(controlGraph)
{
Uint32 nNodes = controlGraph.nNodes;
GtoV = new Uint32[nNodes + 1];
VtoG = new Uint32[nNodes + 1];
Uint32 v = 1;
for (Uint32 n = 0; n < nNodes; n++) {
VtoG[v] = n;
GtoV[n] = v++;
}
// Initialize all the 1-based arrays.
//
parent = new Uint32[v];
semi = new Uint32[v];
vertex = new Uint32[v];
label = new Uint32[v];
size = new Uint32[v];
ancestor = new Uint32[v];
child = new Uint32[v];
dom = new Uint32[v];
bucket = new DGLinkedList*[v];
memset(semi, '\0', v * sizeof(Uint32));
memset(bucket, '\0', v * sizeof(DGLinkedList*));
vCount = v;
build();
delete parent;
delete semi;
delete vertex;
delete label;
delete size;
delete ancestor;
delete child;
delete dom;
delete bucket;
}
Uint32 DominatorGraph::DFS(Uint32 vx, Uint32 n)
{
semi[vx] = ++n;
vertex[n] = label[vx] = vx;
ancestor[vx] = child[vx] = 0;
size[vx] = 1;
ControlNode& node = *controlGraph.dfsList[VtoG[vx]];
ControlEdge* successorEnd = node.getSuccessorsEnd();
for (ControlEdge* successorPtr = node.getSuccessorsBegin(); successorPtr < successorEnd; successorPtr++) {
Uint32 w = GtoV[successorPtr->getTarget().dfsNum];
if (semi[w] == 0) {
parent[w] = vx;
n = DFS(w, n);
}
}
return n;
}
void DominatorGraph::LINK(Uint32 vx, Uint32 w)
{
Uint32 s = w;
while (semi[label[w]] < semi[label[child[s]]]) {
if (size[s] + size[child[child[s]]] >= (size[child[s]] << 1)) {
ancestor[child[s]] = s;
child[s] = child[child[s]];
} else {
size[child[s]] = size[s];
s = ancestor[s] = child[s];
}
}
label[s] = label[w];
size[vx] += size[w];
if(size[vx] < (size[w] << 1)) {
Uint32 t = s;
s = child[vx];
child[vx] = t;
}
while( s != 0 ) {
ancestor[s] = vx;
s = child[s];
}
}
void DominatorGraph::COMPRESS(Uint32 vx)
{
if(ancestor[ancestor[vx]] != 0) {
COMPRESS(ancestor[vx]);
if(semi[label[ancestor[vx]]] < semi[label[vx]])
label[vx] = label[ancestor[vx]];
ancestor[vx] = ancestor[ancestor[vx]];
}
}
Uint32 DominatorGraph::EVAL(Uint32 vx)
{
if(ancestor[vx] == 0)
return label[vx];
COMPRESS(vx);
return (semi[label[ancestor[vx]]] >= semi[label[vx]]) ? label[vx] : label[ancestor[vx]];
}
void DominatorGraph::build()
{
Uint32 n = DFS(GtoV[0], 0);
size[0] = label[0] = semi[0];
for (Uint32 i = n; i >= 2; i--) {
Uint32 w = vertex[i];
ControlNode& node = *controlGraph.dfsList[VtoG[w]];
const DoublyLinkedList<ControlEdge>& predecessors = node.getPredecessors();
for (DoublyLinkedList<ControlEdge>::iterator p = predecessors.begin(); !predecessors.done(p); p = predecessors.advance(p)) {
Uint32 vx = GtoV[predecessors.get(p).getSource().dfsNum];
Uint32 u = EVAL(vx);
if(semi[u] < semi[w])
semi[w] = semi[u];
}
DGLinkedList* elem = new DGLinkedList();
elem->next = bucket[vertex[semi[w]]];
elem->index = w;
bucket[vertex[semi[w]]] = elem;
LINK(parent[w], w);
elem = bucket[parent[w]];
while(elem != NULL) {
Uint32 vx = elem->index;
Uint32 u = EVAL(vx);
dom[vx] = (semi[u] < semi[vx]) ? u : parent[w];
elem = elem->next;
}
}
memset(size, '\0', n * sizeof(Uint32));
Pool& pool = controlGraph.pool;
nodes = new(pool) DGNode[n];
for(Uint32 j = 2; j <= n; j++) {
Uint32 w = vertex[j];
Uint32 d = dom[w];
if(d != vertex[semi[w]]) {
d = dom[d];
dom[w] = d;
}
size[d]++;
}
dom[GtoV[0]] = 0;
for (Uint32 k = 1; k <= n; k++) {
DGNode& node = nodes[VtoG[k]];
Uint32 count = size[k];
node.successorsEnd = node.successorsBegin = (count) ? new(pool) Uint32[count] : (Uint32*) 0;
}
for (Uint32 l = 2; l <= n; l++)
*(nodes[VtoG[dom[l]]].successorsEnd)++ = VtoG[l];
}
#ifdef DEBUG_LOG
void DominatorGraph::printPretty(LogModuleObject log)
{
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Dominator Graph:\n"));
Uint32 nNodes = controlGraph.nNodes;
for (Uint32 i = 0; i < nNodes; i++) {
DGNode& node = nodes[i];
if (node.successorsBegin != node.successorsEnd) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\tN%d dominates ", i));
for (Uint32* successorsPtr = node.successorsBegin; successorsPtr < node.successorsEnd; successorsPtr++)
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("N%d ", *successorsPtr));
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
}
}
}
#endif // DEBUG_LOG

View File

@@ -0,0 +1,80 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _DOMINATOR_GRAPH_H_
#define _DOMINATOR_GRAPH_H_
#include "LogModule.h"
class ControlGraph;
struct DGNode
{
Uint32* successorsBegin;
Uint32* successorsEnd;
};
struct DGLinkedList
{
DGLinkedList* next;
Uint32 index;
};
class DominatorGraph
{
private:
ControlGraph& controlGraph;
Uint32 vCount;
Uint32* VtoG;
Uint32* GtoV;
Uint32* parent;
Uint32* semi;
Uint32* vertex;
Uint32* label;
Uint32* size;
Uint32* ancestor;
Uint32* child;
Uint32* dom;
DGLinkedList** bucket;
DGNode* nodes;
private:
void build();
Uint32 DFS(Uint32 vx, Uint32 n);
void LINK(Uint32 vx, Uint32 w);
void COMPRESS(Uint32 vx);
Uint32 EVAL(Uint32 vx);
public:
DominatorGraph(ControlGraph& controlGraph);
Uint32* getSuccessorsBegin(Uint32 n) const {return nodes[n].successorsBegin;}
Uint32* getSuccessorsEnd(Uint32 n) const {return nodes[n].successorsEnd;}
#ifdef DEBUG_LOG
void printPretty(LogModuleObject log);
#endif // DEBUG_LOG
};
#endif // _DOMINATOR_GRAPH_H_

View File

@@ -1,5 +1,5 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
@@ -16,16 +16,5 @@
* Reserved.
*/
/*
The RDF data source observer interface. Data source observers are
notified when the contents of the graph change.
*/
#ifndef nsIRDFObserver_h__
#define nsIRDFObserver_h__
#include "nsRDFInterfaces.h"
#endif /* nsIRDFObserver_h__ */
#include "Fundamentals.h"
#include "HashSet.h"

View File

@@ -0,0 +1,97 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _HASH_SET_H_
#define _HASH_SET_H_
#include "Fundamentals.h"
#include "Pool.h"
#include <string.h>
struct HashSetElement
{
Uint32 index;
HashSetElement* next;
};
class HashSet
{
private:
static const hashSize = 64;
// Return the hash code for the given element index.
static Uint32 getHashCode(Uint32 index) {return index & (hashSize - 1);} // Could be better !
private:
Pool& allocationPool;
HashSetElement** bucket;
HashSetElement* free;
private:
// No copy constructor.
HashSet(const HashSet&);
// No copy operator.
void operator = (const HashSet&);
public:
// Create a new HashSet.
inline HashSet(Pool& pool, Uint32 universeSize);
// Clear the hashset.
void clear();
// Clear the element for the given index.
void clear(Uint32 index);
// Set the element for the given index.
void set(Uint32 index);
// Return true if the element at index is a member.
bool test(Uint32 index) const;
// Union with the given hashset.
inline void or(const HashSet& set);
// Intersection with the given hashset.
inline void and(const HashSet& set);
// Difference with the given hashset.
inline void difference(const HashSet& set);
// Logical operators.
HashSet& operator |= (const HashSet& set) {or(set); return *this;}
HashSet& operator &= (const HashSet& set) {and(set); return *this;}
HashSet& operator -= (const HashSet& set) {difference(set); return *this;}
// Iterator to conform with the set API.
typedef HashSetElement* iterator;
// Return the iterator for the first element of this set.
iterator begin() const;
// Return the next iterator.
iterator advance(iterator pos) const;
// Return true if the iterator is at the end of the set.
bool done(iterator pos) const {return pos == NULL;}
};
inline HashSet::HashSet(Pool& pool, Uint32 /*universeSize*/)
: allocationPool(pool), free(NULL)
{
bucket = new(pool) HashSetElement*[hashSize];
memset(bucket, '\0', sizeof(HashSetElement*));
}
#endif // _HASH_SET_H_

View File

@@ -0,0 +1,213 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _INDEXED_POOL_H_
#define _INDEXED_POOL_H_
#include "Fundamentals.h"
#include <string.h>
#include <stdlib.h>
//------------------------------------------------------------------------------
// IndexedPool<IndexedObjectSubclass> is an indexed pool of objects. The
// template parameter 'IndexedObjectSubclass' must be a subclass of the struct
// IndexedObject.
//
// When the indexed pool is ask to allocate and initialize a new object (using
// the operator new(anIndexedPool) it will zero the memory used to store the
// object and initialize the field 'index' of this object to its position in
// the pool.
//
// An object allocated by the indexed pool can be freed by calling the method
// IndexedPool::release(IndexedElement& objectIndex).
//
// example:
//
// IndexedPool<IndexedElement> elementPool;
//
// IndexedElement& element1 = *new(elementPool) IndexedElement();
// IndexedElement& element2 = *new(elementPool) IndexedElement();
//
// indexedPool.release(element1);
// IndexedElement& element3 = *new(elementPool) IndexedElement();
//
// At this point element1 is no longer a valid object, element2 is at
// index 2 and element3 is at index 1.
//
//------------------------------------------------------------------------------
// IndexedObject -
//
template<class Object>
struct IndexedObject
{
Uint32 index; // Index in the pool.
Object* next; // Used to link IndexedObject together.
Uint32 getIndex() {return index;}
};
//------------------------------------------------------------------------------
// IndexedPool<IndexedObject> -
//
template <class IndexedObject>
class IndexedPool
{
private:
static const blockSize = 4; // Size of one block.
Uint32 nBlocks; // Number of blocks in the pool.
IndexedObject** block; // Array of block pointers.
IndexedObject* freeObjects; // Chained list of free IndexedObjects.
Uint32 nextIndex; // Index of the next free object in the last block.
private:
void allocateAnotherBlock();
IndexedObject& newObject();
public:
IndexedPool() : nBlocks(0), block(NULL), freeObjects(NULL), nextIndex(1) {}
~IndexedPool();
IndexedObject& get(Uint32 index) const;
void release(IndexedObject& object);
void setSize(Uint32 size) {assert(size < nextIndex); nextIndex = size;}
// Return the universe size.
Uint32 getSize() {return nextIndex;}
friend void* operator new(size_t, IndexedPool<IndexedObject>& pool); // Needs to call newObject().
};
// Free all the memory allocated for this object.
//
template <class IndexedObject>
IndexedPool<IndexedObject>::~IndexedPool()
{
for (Uint32 n = 0; n < nBlocks; n++)
free(&((IndexedObject **) &block[n][n*blockSize])[-(n + 1)]);
}
// Release the given. This object will be iserted in the chained
// list of free IndexedObjects. To minimize the fragmentation the chained list
// is ordered by ascending indexes.
//
template <class IndexedObject>
void IndexedPool<IndexedObject>::release(IndexedObject& object)
{
Uint32 index = object.index;
IndexedObject* list = freeObjects;
assert(&object == &get(index)); // Make sure that object is owned by this pool.
if (list == NULL) { // The list is empty.
freeObjects = &object;
object.next = NULL;
} else { // The list contains at least 1 element.
if (index < list->index) { // insert as first element.
freeObjects = &object;
object.next = list;
} else { // Find this object's place.
while ((list->next) != NULL && (list->next->index < index))
list = list->next;
object.next = list->next;
list->next = &object;
}
}
#ifdef DEBUG
// Sanity check to be sure that the list is correctly ordered.
for (IndexedObject* obj = freeObjects; obj != NULL; obj = obj->next)
if (obj->next != NULL)
assert(obj->index < obj->next->index);
#endif
}
// Create a new block of IndexedObjects. We will allocate the memory to
// store IndexedPool::blockSize IndexedObject and the new Array of block
// pointers.
// The newly created IndexedObjects will not be initialized.
//
template <class IndexedObject>
void IndexedPool<IndexedObject>::allocateAnotherBlock()
{
void* memory = (void *) malloc((nBlocks + 1) * sizeof(Uint32) + blockSize * sizeof(IndexedObject));
memcpy(memory, block, nBlocks * sizeof(Uint32));
block = (IndexedObject **) memory;
IndexedObject* objects = (IndexedObject *) &block[nBlocks + 1];
block[nBlocks] = &objects[-(nBlocks * blockSize)];
nBlocks++;
}
// Return the IndexedObject at the position 'index' in the pool.
//
template <class IndexedObject>
IndexedObject& IndexedPool<IndexedObject>::get(Uint32 index) const
{
Uint32 blockIndex = index / blockSize;
assert(blockIndex < nBlocks);
return block[blockIndex][index];
}
// Return the reference of an unused object in the pool.
//
template <class IndexedObject>
IndexedObject& IndexedPool<IndexedObject>::newObject()
{
if (freeObjects != NULL) {
IndexedObject& newObject = *freeObjects;
freeObjects = newObject.next;
return newObject;
}
Uint32 nextIndex = this->nextIndex++;
Uint32 blockIndex = nextIndex / blockSize;
while (blockIndex >= nBlocks)
allocateAnotherBlock();
IndexedObject& newObject = block[blockIndex][nextIndex];
newObject.index = nextIndex;
return newObject;
}
// Return the address of the next unsused object in the given
// indexed pool. The field index of the newly allocated object
// will be initialized to the corresponding index of this object
// in the pool.
//
template <class IndexedObject>
void* operator new(size_t size, IndexedPool<IndexedObject>& pool)
{
assert(size == sizeof(IndexedObject));
return (void *) &pool.newObject();
}
#endif // _INDEXED_POOL_H_

View File

@@ -0,0 +1,258 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _INTERFERENCE_GRAPH_H_
#define _INTERFERENCE_GRAPH_H_
#include "Fundamentals.h"
#include "ControlGraph.h"
#include "Primitives.h"
#include "Instruction.h"
#include "VirtualRegister.h"
#include "RegisterPressure.h"
#include "SparseSet.h"
#include <string.h>
struct InterferenceVector
{
Uint32 count;
InterferenceVector* next;
RegisterName* neighbors;
InterferenceVector() : count(0), next(NULL) {}
};
class RegisterAllocator;
template <class RegisterPressure>
class InterferenceGraph
{
private:
RegisterAllocator& registerAllocator;
RegisterPressure::Set* interferences;
InterferenceVector** vector;
Uint32* offset;
Uint32 rangeCount;
private:
// No copy constructor.
InterferenceGraph(const InterferenceGraph&);
// No copy operator.
void operator = (const InterferenceGraph&);
// Check if reg is a member of the universe.
void checkMember(RegisterName name) {assert(name < rangeCount);}
// Return the edge index for the interference between name1 and name2.
Uint32 getEdgeIndex(RegisterName name1, RegisterName name2);
public:
InterferenceGraph(RegisterAllocator& registerAllocator) : registerAllocator(registerAllocator) {}
// Calculate the interferences.
void build();
// Return true if reg1 and reg2 interfere.
bool interfere(RegisterName name1, RegisterName name2);
// Return the interference vector for the given register or NULL if there is none.
InterferenceVector* getInterferenceVector(RegisterName name) {return vector[name];}
// Set the interference between name1 and name2.
void setInterference(RegisterName name1, RegisterName name2);
// Set the interference vector for the given register.
void setInterferenceVector(RegisterName name, InterferenceVector* v) {vector[name] = v;}
#ifdef DEBUG_LOG
// Print the interferences.
void printPretty(LogModuleObject log);
#endif // DEBUG_LOG
};
template <class RegisterPressure>
void InterferenceGraph<RegisterPressure>::build()
{
Pool& pool = registerAllocator.pool;
Uint32 rangeCount = registerAllocator.rangeCount;
this->rangeCount = rangeCount;
// Initialize the structures.
//
offset = new(pool) Uint32[rangeCount + 1];
vector = new(pool) InterferenceVector*[rangeCount];
memset(vector, '\0', sizeof(InterferenceVector*) * rangeCount);
Uint32 o = 0;
offset[0] = 0;
for (Uint32 i = 1; i <= rangeCount; ++i) {
offset[i] = o;
o += i;
}
interferences = new(pool) RegisterPressure::Set(pool, (rangeCount * rangeCount) / 2);
ControlGraph& controlGraph = registerAllocator.controlGraph;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
RegisterName* name2range = registerAllocator.name2range;
LivenessInfo<RegisterPressure> liveness = Liveness<RegisterPressure>::analysis(controlGraph, rangeCount, name2range);
registerAllocator.liveness = liveness;
SparseSet currentLive(pool, rangeCount);
for (Uint32 n = 0; n < nNodes; n++) {
ControlNode& node = *nodes[n];
currentLive = liveness.liveOut[n];
InstructionList& instructions = node.getInstructions();
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useBegin = instruction.getInstructionUseBegin();
InstructionUse* useEnd = instruction.getInstructionUseEnd();
InstructionUse* usePtr;
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
InstructionDefine* definePtr;
// Handle the copy instruction to avoid unnecessary interference between the 2 registers.
if ((instruction.getFlags() & ifCopy) != 0) {
assert(useBegin != useEnd && useBegin[0].isRegister());
currentLive.clear(name2range[useBegin[0].getRegisterName()]);
}
// Create the interferences.
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister()) {
RegisterName define = name2range[definePtr->getRegisterName()];
for (SparseSet::iterator e = currentLive.begin(); !currentLive.done(e); e = currentLive.advance(e)) {
RegisterName live = RegisterName(currentLive.get(e));
if ((live != define) && !interfere(live, define) && registerAllocator.canInterfere(live, define)) {
if (vector[define] == NULL)
vector[define] = new(pool) InterferenceVector();
vector[define]->count++;
if (vector[live] == NULL)
vector[live] = new(pool) InterferenceVector();
vector[live]->count++;
setInterference(live, define);
}
}
}
// Now update the liveness.
//
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
currentLive.clear(name2range[definePtr->getRegisterName()]);
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister())
currentLive.set(name2range[usePtr->getRegisterName()]);
}
}
// Allocate the memory to store the interferences.
//
for (Uint32 e = 0; e < rangeCount; e++)
if (vector[e] != NULL) {
InterferenceVector& v = *vector[e];
v.neighbors = new(pool) RegisterName[v.count];
v.count = 0;
}
// Initialize the edges.
//
if (RegisterPressure::Set::isOrdered()) {
RegisterName name1 = RegisterName(0);
for (RegisterPressure::Set::iterator i = interferences->begin(); !interferences->done(i); i = interferences->advance(i)) {
Uint32 interferenceIndex = interferences->get(i);
while(interferenceIndex >= offset[name1 + 1])
name1 = RegisterName(name1 + 1);
assert((interferenceIndex >= offset[name1]) && (interferenceIndex < offset[name1 + 1]));
RegisterName name2 = RegisterName(interferenceIndex - offset[name1]);
assert(interfere(name1, name2));
InterferenceVector& vector1 = *vector[name1];
vector1.neighbors[vector1.count++] = name2;
InterferenceVector& vector2 = *vector[name2];
vector2.neighbors[vector2.count++] = name1;
}
} else {
trespass("not Implemented"); // FIX: need one more pass to initialize the vectors.
}
}
template <class RegisterPressure>
Uint32 InterferenceGraph<RegisterPressure>::getEdgeIndex(RegisterName name1, RegisterName name2)
{
checkMember(name1); checkMember(name2);
assert(name1 != name2); // This is not possible.
return (name1 < name2) ? offset[name2] + name1 : offset[name1] + name2;
}
template <class RegisterPressure>
void InterferenceGraph<RegisterPressure>::setInterference(RegisterName name1, RegisterName name2)
{
interferences->set(getEdgeIndex(name1, name2));
}
template <class RegisterPressure>
bool InterferenceGraph<RegisterPressure>::interfere(RegisterName name1, RegisterName name2)
{
return interferences->test(getEdgeIndex(name1, name2));
}
#ifdef DEBUG_LOG
template <class RegisterPressure>
void InterferenceGraph<RegisterPressure>::printPretty(LogModuleObject log)
{
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Interference Vectors:\n"));
for (Uint32 i = 1; i < rangeCount; i++) {
if (vector[i] != NULL) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\tvr%d: (", i));
for (InterferenceVector* v = vector[i]; v != NULL; v = v->next)
for (Uint32 j = 0; j < v->count; j++) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%d", v->neighbors[j]));
if (v->next != NULL || j != (v->count - 1))
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (","));
}
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (")\n"));
}
}
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Interference Matrix:\n"));
for (RegisterName name1 = RegisterName(1); name1 < rangeCount; name1 = RegisterName(name1 + 1)) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\t%d:\t", name1));
for (RegisterName name2 = RegisterName(1); name2 < rangeCount; name2 = RegisterName(name2 + 1))
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%c", ((name1 != name2) && interfere(name1, name2)) ? '1' : '0'));
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
}
}
#endif // DEBUG_LOG
#endif // _INTERFERENCE_GRAPH_H_

View File

@@ -0,0 +1,87 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _LIVE_RANGE_H_
#define _LIVE_RANGE_H_
#include "Fundamentals.h"
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "Primitives.h"
#include "Instruction.h"
#include "RegisterAllocator.h"
#include "RegisterAllocatorTools.h"
template <class RegisterPressure>
struct LiveRange
{
static void build(RegisterAllocator& registerAllocator);
};
template <class RegisterPressure>
void LiveRange<RegisterPressure>::build(RegisterAllocator& registerAllocator)
{
// Intialize the lookup table.
//
Uint32 nameCount = registerAllocator.nameCount;
RegisterName* nameTable = new(registerAllocator.pool) RegisterName[2*nameCount];
RegisterName* rangeName = &nameTable[nameCount];
init(rangeName, nameCount);
// Walk the graph.
//
ControlGraph& controlGraph = registerAllocator.controlGraph;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
SparseSet destination(registerAllocator.pool, nameCount);
for (Uint32 n = 0; n < nNodes; n++) {
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
destination.clear();
for (InstructionList::iterator i = phiNodes.begin(); !phiNodes.done(i); i = phiNodes.advance(i)) {
Instruction& phiNode = phiNodes.get(i);
assert(phiNode.getInstructionDefineBegin() != phiNode.getInstructionDefineEnd() && phiNode.getInstructionDefineBegin()[0].isRegister());
destination.set(findRoot(phiNode.getInstructionDefineBegin()[0].getRegisterName(), rangeName));
}
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
Instruction& phiNode = phiNodes.get(p);
assert(phiNode.getInstructionDefineBegin() != phiNode.getInstructionDefineEnd() && phiNode.getInstructionDefineBegin()[0].isRegister());
RegisterName destinationName = phiNode.getInstructionDefineBegin()[0].getRegisterName();
RegisterName destinationRoot = findRoot(destinationName, rangeName);
InstructionUse* useEnd = phiNode.getInstructionUseEnd();
for (InstructionUse* usePtr = phiNode.getInstructionUseBegin(); usePtr < useEnd; usePtr++) {
assert(usePtr->isRegister());
RegisterName sourceName = usePtr->getRegisterName();
RegisterName sourceRoot = findRoot(sourceName, rangeName);
if (sourceRoot != destinationRoot && !destination.test(sourceRoot))
rangeName[sourceRoot] = destinationRoot;
}
}
}
registerAllocator.rangeCount = compress(registerAllocator.name2range, rangeName, nameCount, nameCount);
}
#endif // _LIVE_RANGE_H_

View File

@@ -0,0 +1,163 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _LIVE_RANGE_GRAPH_
#define _LIVE_RANGE_GRAPH_
#include "Fundamentals.h"
#include "Pool.h"
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "Instruction.h"
#include "RegisterTypes.h"
class RegisterAllocator;
template <class RegisterPressure>
class LiveRangeGraph
{
private:
RegisterAllocator& registerAllocator;
RegisterPressure::Set* edges;
Uint32 rangeCount;
public:
//
//
LiveRangeGraph(RegisterAllocator& registerAllocator) : registerAllocator(registerAllocator) {}
//
//
void build();
//
//
void addEdge(RegisterName name1, RegisterName name2);
//
//
bool haveEdge(RegisterName name1, RegisterName name2);
#ifdef DEBUG_LOG
//
//
void printPretty(LogModuleObject log);
#endif // DEBUG_LOG
};
template <class RegisterPressure>
void LiveRangeGraph<RegisterPressure>::build()
{
Pool& pool = registerAllocator.pool;
Uint32 rangeCount = registerAllocator.rangeCount;
this->rangeCount = rangeCount;
edges = new(pool) RegisterPressure::Set(pool, rangeCount * rangeCount);
ControlGraph& controlGraph = registerAllocator.controlGraph;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
RegisterName* name2range = registerAllocator.name2range;
LivenessInfo<RegisterPressure>& liveness = registerAllocator.liveness;
SparseSet currentLive(pool, rangeCount);
for (Uint32 n = 0; n < nNodes; n++) {
ControlNode& node = *nodes[n];
currentLive = liveness.liveOut[n];
InstructionList& instructions = node.getInstructions();
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useBegin = instruction.getInstructionUseBegin();
InstructionUse* useEnd = instruction.getInstructionUseEnd();
InstructionUse* usePtr;
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
InstructionDefine* definePtr;
if ((instruction.getFlags() & ifCopy) != 0) {
assert(useBegin != useEnd && useBegin[0].isRegister());
currentLive.clear(name2range[useBegin[0].getRegisterName()]);
}
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister()) {
RegisterName define = name2range[definePtr->getRegisterName()];
for (SparseSet::iterator l = currentLive.begin(); !currentLive.done(l); l = currentLive.advance(l)) {
RegisterName live = RegisterName(currentLive.get(l));
if (define != live && registerAllocator.canInterfere(define, live))
addEdge(define, live);
}
}
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
currentLive.clear(name2range[definePtr->getRegisterName()]);
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister())
currentLive.set(name2range[usePtr->getRegisterName()]);
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
RegisterName use = name2range[usePtr->getRegisterName()];
for (SparseSet::iterator l = currentLive.begin(); !currentLive.done(l); l = currentLive.advance(l)) {
RegisterName live = RegisterName(currentLive.get(l));
if (use != live && registerAllocator.canInterfere(use, live))
addEdge(use, live);
}
}
}
}
}
template <class RegisterPressure>
void LiveRangeGraph<RegisterPressure>::addEdge(RegisterName name1, RegisterName name2)
{
assert(name1 != name2);
edges->set(name1 * rangeCount + name2);
}
template <class RegisterPressure>
bool LiveRangeGraph<RegisterPressure>::haveEdge(RegisterName name1, RegisterName name2)
{
assert(name1 != name2);
return edges->test(name1 * rangeCount + name2);
}
#ifdef DEBUG_LOG
template <class RegisterPressure>
void LiveRangeGraph<RegisterPressure>::printPretty(LogModuleObject log)
{
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Live ranges graph:\n"));
for (RegisterName name1 = RegisterName(1); name1 < rangeCount; name1 = RegisterName(name1 + 1)) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\t%d:\t", name1));
for (RegisterName name2 = RegisterName(1); name2 < rangeCount; name2 = RegisterName(name2 + 1))
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%c", ((name1 != name2) && haveEdge(name1, name2)) ? '1' : '0'));
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
}
}
#endif // DEBUG_LOG
#endif // _LIVE_RANGE_GRAPH_

View File

@@ -16,11 +16,6 @@
* Reserved.
*/
#ifndef nsIRDFResource_h__
#define nsIRDFResource_h__
#include "nsRDFInterfaces.h"
#endif // nsIRDFResource_h__
#include "Fundamentals.h"
#include "Liveness.h"

View File

@@ -0,0 +1,301 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _LIVENESS_H_
#define _LIVENESS_H_
#include "Fundamentals.h"
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "Instruction.h"
#include "RegisterTypes.h"
// ----------------------------------------------------------------------------
// LivenessInfo -
template <class RegisterPressure>
struct LivenessInfo
{
RegisterPressure::Set* liveIn;
RegisterPressure::Set* liveOut;
DEBUG_LOG_ONLY(Uint32 size);
#ifdef DEBUG_LOG
void printPretty(LogModuleObject log);
#endif // DEBUG_LOG
};
// ----------------------------------------------------------------------------
// Liveness
//
// The liveness is defined by the following data-flow equations:
//
// LiveIn(n) = LocalLive(n) U (LiveOut(n) - Killed(n)).
// LiveOut(n) = U LiveIn(s) (s a successor of n).
//
// where LocalLive(n) is the set of used registers in the block n, Killed(n)
// is the set of defined registers in the block n, LiveIn(n) is the set of
// live registers at the begining of the block n and LiveOut(n) is the set
// of live registers at the end of the block n.
//
//
// We will compute the liveness analysis in two stages:
//
// 1- Build LocalLive(n) (wich is an approximation of LiveIn(n)) and Killed(n)
// for each block n.
// 2- Perform a backward data-flow analysis to propagate the liveness information
// through the entire control-flow graph.
//
template <class RegisterPressure>
struct Liveness
{
static LivenessInfo<RegisterPressure> analysis(ControlGraph& controlGraph, Uint32 rangeCount, const RegisterName* name2range);
static LivenessInfo<RegisterPressure> analysis(ControlGraph& controlGraph, Uint32 nameCount);
};
template <class RegisterPressure>
LivenessInfo<RegisterPressure> Liveness<RegisterPressure>::analysis(ControlGraph& controlGraph, Uint32 rangeCount, const RegisterName* name2range)
{
Pool& pool = controlGraph.pool;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
// Allocate the temporary sets.
RegisterPressure::Set* killed = new(pool) RegisterPressure::Set[nNodes](pool, rangeCount);
// Allocate the globals sets.
RegisterPressure::Set* liveIn = new(pool) RegisterPressure::Set[nNodes](pool, rangeCount);
RegisterPressure::Set* liveOut = new(pool) RegisterPressure::Set[nNodes](pool, rangeCount);
// First stage of the liveness analysis: Compute the sets LocalLive(stored in LiveIn) and Killed.
//
for (Uint32 n = 0; n < (nNodes - 1); n++) {
ControlNode& node = *nodes[n];
RegisterPressure::Set& currentLocalLive = liveIn[n];
RegisterPressure::Set& currentKilled = killed[n];
// Find the instructions contributions to the sets LocalLive and Killed.
//
InstructionList& instructions = node.getInstructions();
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
Instruction& instruction = instructions.get(i);
// If a VirtualRegister is 'used' before being 'defined' then we add it to set LocalLive.
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
Uint32 index = name2range[usePtr->getRegisterName()];
if (!currentKilled.test(index))
currentLocalLive.set(index);
}
// If a Virtualregister is 'defined' then we add it to the set Killed.
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
currentKilled.set(name2range[definePtr->getRegisterName()]);
}
}
// Second stage of the liveness analysis: We propagate the LiveIn & LiveOut through the entire
// control-flow graph.
//
RegisterPressure::Set temp(pool, rangeCount);
bool changed;
do {
changed = false;
// For all nodes is this graph except the endNode.
for (Int32 n = (nNodes - 2); n >= 0; n--) {
ControlNode& node = *nodes[n];
RegisterPressure::Set& currentLiveIn = liveIn[n];
RegisterPressure::Set& currentLiveOut = liveOut[n];
// Compute temp = Union of LiveIn(s) (s a successor of this node) | usedByPhiNodes(n).
// temp will be the new LiveOut(n).
Uint32 nSuccessors = node.nSuccessors();
if (nSuccessors != 0) {
temp = liveIn[node.nthSuccessor(0).getTarget().dfsNum];
for (Uint32 s = 1; s < nSuccessors; s++)
temp |= liveIn[node.nthSuccessor(s).getTarget().dfsNum];
} else
temp.clear();
// If temp and LiveOut(n) differ then set LiveOut(n) = temp and recalculate the
// new LiveIn(n).
if (currentLiveOut != temp) {
currentLiveOut = temp;
temp -= killed[n]; // FIX: could be optimized with one call to unionDiff !
temp |= currentLiveIn;
if (currentLiveIn != temp) {
currentLiveIn = temp;
changed = true;
}
}
}
} while(changed);
LivenessInfo<RegisterPressure> liveness;
liveness.liveIn = liveIn;
liveness.liveOut = liveOut;
DEBUG_LOG_ONLY(liveness.size = nNodes);
return liveness;
}
template <class RegisterPressure>
LivenessInfo<RegisterPressure> Liveness<RegisterPressure>::analysis(ControlGraph& controlGraph, Uint32 nameCount)
{
Pool& pool = controlGraph.pool;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
// Allocate the temporary sets.
RegisterPressure::Set* killed = new(pool) RegisterPressure::Set[nNodes](pool, nameCount);
RegisterPressure::Set* usedByPhiNodes = NULL;
// Allocate the globals sets.
RegisterPressure::Set* liveIn = new(pool) RegisterPressure::Set[nNodes](pool, nameCount);
RegisterPressure::Set* liveOut = new(pool) RegisterPressure::Set[nNodes](pool, nameCount);
// First stage of the liveness analysis: Compute the sets LocalLive(stored in LiveIn) and Killed.
//
for (Uint32 n = 0; n < (nNodes - 1); n++) {
ControlNode& node = *nodes[n];
RegisterPressure::Set& currentLocalLive = liveIn[n];
RegisterPressure::Set& currentKilled = killed[n];
InstructionList& phiNodes = node.getPhiNodeInstructions();
if ((usedByPhiNodes == NULL) && !phiNodes.empty())
usedByPhiNodes = new(pool) RegisterPressure::Set[nNodes](pool, nameCount);
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
Instruction& phiNode = phiNodes.get(p);
InstructionDefine& define = phiNode.getInstructionDefineBegin()[0];
currentKilled.set(define.getRegisterName());
typedef DoublyLinkedList<ControlEdge> ControlEdgeList;
const ControlEdgeList& predecessors = node.getPredecessors();
ControlEdgeList::iterator p = predecessors.begin();
InstructionUse* useEnd = phiNode.getInstructionUseEnd();
for (InstructionUse* usePtr = phiNode.getInstructionUseBegin(); usePtr < useEnd; usePtr++, p = predecessors.advance(p))
if (usePtr->isRegister())
usedByPhiNodes[predecessors.get(p).getSource().dfsNum].set(usePtr->getRegisterName());
}
// Find the instructions contributions to the sets LocalLive and Killed.
//
InstructionList& instructions = node.getInstructions();
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
Instruction& instruction = instructions.get(i);
// If a VirtualRegister is 'used' before being 'defined' then we add it to set LocalLive.
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
Uint32 index = usePtr->getRegisterName();
if (!currentKilled.test(index))
currentLocalLive.set(index);
}
// If a Virtualregister is 'defined' then we add it to the set Killed.
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
currentKilled.set(definePtr->getRegisterName());
}
}
// Second stage of the liveness analysis: We propagate the LiveIn & LiveOut through the entire
// control-flow graph.
//
RegisterPressure::Set temp(pool, nameCount);
bool changed;
do {
changed = false;
// For all nodes is this graph except the endNode.
for (Int32 n = (nNodes - 2); n >= 0; n--) {
ControlNode& node = *nodes[n];
RegisterPressure::Set& currentLiveIn = liveIn[n];
RegisterPressure::Set& currentLiveOut = liveOut[n];
// Compute temp = Union of LiveIn(s) (s a successor of this node) | usedByPhiNodes(n).
// temp will be the new LiveOut(n).
Uint32 nSuccessors = node.nSuccessors();
if (nSuccessors != 0) {
temp = liveIn[node.nthSuccessor(0).getTarget().dfsNum];
for (Uint32 s = 1; s < nSuccessors; s++)
temp |= liveIn[node.nthSuccessor(s).getTarget().dfsNum];
} else
temp.clear();
// Insert the phiNodes contribution.
if (usedByPhiNodes != NULL)
temp |= usedByPhiNodes[n];
// If temp and LiveOut(n) differ then set LiveOut(n) = temp and recalculate the
// new LiveIn(n).
if (currentLiveOut != temp) {
currentLiveOut = temp;
temp -= killed[n]; // FIX: could be optimized with one call to unionDiff !
temp |= currentLiveIn;
if (currentLiveIn != temp) {
currentLiveIn = temp;
changed = true;
}
}
}
} while(changed);
LivenessInfo<RegisterPressure> liveness;
liveness.liveIn = liveIn;
liveness.liveOut = liveOut;
DEBUG_LOG_ONLY(liveness.size = nNodes);
return liveness;
}
#ifdef DEBUG_LOG
template <class RegisterPressure>
void LivenessInfo<RegisterPressure>::printPretty(LogModuleObject log)
{
for (Uint32 n = 0; n < size; n++) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Node N%d:\n\tliveIn = ", n));
liveIn[n].printPretty(log);
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\tliveOut = "));
liveOut[n].printPretty(log);
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
}
}
#endif // DEBUG_LOG
#endif // _LIVENESS_H_

View File

@@ -0,0 +1,40 @@
#! gmake
DEPTH = ../..
MODULE_NAME = RegisterAllocator
include $(DEPTH)/config/config.mk
INCLUDES += \
-I$(DEPTH)/Utilities/General \
-I$(DEPTH)/Utilities/zlib \
-I$(DEPTH)/Runtime/ClassReader \
-I$(DEPTH)/Runtime/NativeMethods \
-I$(DEPTH)/Runtime/System \
-I$(DEPTH)/Runtime/ClassInfo \
-I$(DEPTH)/Runtime/FileReader \
-I$(DEPTH)/Compiler/PrimitiveGraph \
-I$(DEPTH)/Compiler/FrontEnd \
-I$(DEPTH)/Compiler/Optimizer \
-I$(DEPTH)/Compiler/CodeGenerator \
-I$(DEPTH)/Compiler/CodeGenerator/md \
-I$(DEPTH)/Compiler/CodeGenerator/md/$(CPU_ARCH) \
-I$(DEPTH)/Compiler/RegisterAllocator \
-I$(DEPTH)/Driver/StandAloneJava \
-I$(DEPTH)/Debugger \
$(NULL)
CXXSRCS = \
RegisterAllocator.cpp \
RegisterAllocatorTools.cpp \
DominatorGraph.cpp \
VirtualRegister.cpp \
BitSet.cpp \
SparseSet.cpp \
$(NULL)
include $(DEPTH)/config/rules.mk
libs:: $(MODULE)

View File

@@ -0,0 +1,392 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _PHI_NODE_REMOVER_H_
#define _PHI_NODE_REMOVER_H_
#include "Fundamentals.h"
#include "Pool.h"
#include "ControlGraph.h"
#include "DominatorGraph.h"
#include "VirtualRegister.h"
#include "RegisterPressure.h"
#include "Liveness.h"
#include "Instruction.h"
#include "InstructionEmitter.h"
#include "SparseSet.h"
#include <string.h>
//------------------------------------------------------------------------------
// RegisterNameNode -
struct RegisterNameNode
{
RegisterNameNode* next;
RegisterName newName;
Uint32 nextPushed;
};
//------------------------------------------------------------------------------
// CopyData -
struct CopyData
{
RegisterName source;
RegisterClassKind classKind;
Uint32 useCount;
bool isLiveOut;
RegisterName sourceNameToUse;
RegisterName temporaryName;
RegisterNameNode* newName;
};
//------------------------------------------------------------------------------
// PhiNodeRemover<RegisterPressure> -
template <class RegisterPressure>
struct PhiNodeRemover
{
// Replace the phi nodes by copy instructions.
static void replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter);
};
// Split some of the critical edges and return true if there are still some
// in the graph after that.
//
static bool splitCriticalEdges(ControlGraph& /*cg*/)
{
// FIX: not implemented.
return true;
}
inline void pushName(Pool& pool, RegisterNameNode** stack, SparseSet& pushed, Uint32* nodeListPointer, RegisterName oldName, RegisterName newName)
{
RegisterNameNode& newNode = *new(pool) RegisterNameNode();
if (pushed.test(oldName))
(*stack)->newName = newName;
else {
newNode.newName = newName;
newNode.nextPushed = *nodeListPointer;
*nodeListPointer = oldName;
newNode.next = *stack;
*stack = &newNode;
pushed.set(oldName);
}
}
template <class RegisterPressure>
void PhiNodeRemover<RegisterPressure>::replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter)
{
Pool& pool = controlGraph.pool;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
// Initialize the local variables.
//
// When we insert the copies we will also need to create new VirtualRegisters for
// the insertion of temporaries. The maximum number of temporary register will not
// exceed the number of phiNodes in the primitive graph.
Uint32 nameCount = vrManager.getSize();
Uint32 maxNameCount = nameCount;
for (Uint32 n = 0; n < nNodes; n++)
maxNameCount += nodes[n]->getPhiNodes().length();
// If the CFG contains some critical edges (backward edge which source has more than one
// outgoing edge and destination has more than one incomimg edge) then we need the liveness
// information to be able to insert temporary copies.
RegisterPressure::Set* liveOut = NULL;
if (splitCriticalEdges(controlGraph))
liveOut = Liveness<LowRegisterPressure>::analysis(controlGraph, nameCount).liveOut;
DominatorGraph dGraph(controlGraph);
SparseSet pushed(pool, maxNameCount);
SparseSet destinationList(pool, maxNameCount);
SparseSet workList(pool, maxNameCount);
CopyData* copyStats = new(pool) CopyData[maxNameCount];
memset(copyStats, '\0', maxNameCount*sizeof(CopyData));
struct NodeStack {
Uint32* next;
Uint32* limit;
Uint32 pushedList;
};
// Allocate the node stack and initialize the node stack pointer.
NodeStack* nodeStack = new(pool) NodeStack[nNodes + 1];
NodeStack* nodeStackPtr = nodeStack;
// We start by the begin node.
Uint32 startNode = 0;
Uint32* next = &startNode;
Uint32* limit = &startNode + 1;
while (true) {
if (next == limit) {
// If there are no more node in the sibling, we have to pop the current
// frame from the stack and update the copyStats of the pushed nodes.
//
if (nodeStackPtr == nodeStack)
// We are at the bottom of the stack and there are no more nodes
// to look at. We are done !
break;
--nodeStackPtr;
// We are done with all the children of this node in the dominator tree.
// We need to update the copy information of all the new names pushed
// during the walk over this node.
Uint32 pushedList = nodeStackPtr->pushedList;
while (pushedList != 0) {
Uint32 nextName = copyStats[pushedList].newName->nextPushed;
copyStats[pushedList].newName = copyStats[pushedList].newName->next;
pushedList = nextName;
}
// restore the previous frame.
next = nodeStackPtr->next;
limit = nodeStackPtr->limit;
} else {
Uint32 currentNode = *next++;
Uint32 pushedList = 0;
// Initialize the sets.
pushed.clear();
destinationList.clear();
// STEP1:
// Walk the instruction list and to replace all the instruction uses with their new name.
// If the instruction is a phi node and its defined register is alive at the end of this
// block then we push the defined register into the stack.
//
ControlNode& node = *nodes[currentNode];
RegisterPressure::Set* currentLiveOut = (liveOut != NULL) ? &liveOut[currentNode] : (RegisterPressure::Set*) 0;
InstructionList& phiNodes = node.getPhiNodeInstructions();
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
Instruction& phiNode = phiNodes.get(p);
InstructionUse* useEnd = phiNode.getInstructionUseEnd();
for (InstructionUse* usePtr = phiNode.getInstructionUseBegin(); usePtr < useEnd; usePtr++) {
assert(usePtr->isRegister());
RegisterName name = usePtr->getRegisterName();
if (copyStats[name].newName != NULL && copyStats[name].newName->newName != name)
usePtr->setRegisterName(copyStats[name].newName->newName);
}
if (currentLiveOut != NULL) {
// This is a phi node and we have to push its defined name if it is live
// at the end of the node. We only need to do this if the CFG has critical edges.
assert(phiNode.getInstructionDefineBegin() != phiNode.getInstructionDefineEnd() && phiNode.getInstructionDefineBegin()[0].isRegister());
RegisterName name = phiNode.getInstructionDefineBegin()[0].getRegisterName();
if (currentLiveOut->test(name))
pushName(pool, &(copyStats[name].newName), pushed, &pushedList, name, name);
}
}
InstructionList& instructions = node.getInstructions();
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
RegisterName name = usePtr->getRegisterName();
if (copyStats[name].newName != NULL && copyStats[name].newName->newName != name)
usePtr->setRegisterName(copyStats[name].newName->newName);
}
}
// STEP2:
// Look at this node's successors' phiNodes. We keep track of the number of time
// a VR will be used by another copy instruction and insert each definition into the
// destinationList. This is the only pass over this node's successors as we will
// get all the information we need in the CopyData structures.
//
ControlEdge* successorEdgeEnd = node.getSuccessorsEnd();
for (ControlEdge* successorEdgePtr = node.getSuccessorsBegin(); successorEdgePtr < successorEdgeEnd; successorEdgePtr++) {
Uint32 useIndex = successorEdgePtr->getIndex();
ControlNode& successor = successorEdgePtr->getTarget();
// Look at its phi nodes. The phi nodes are at the top of the instruction list. We exit
// as soon as we find an instruction which is not a phi node
InstructionList& phiNodes = successor.getPhiNodeInstructions();
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
Instruction& phiNode = phiNodes.get(p);
assert((phiNode.getInstructionUseBegin() + useIndex) < phiNode.getInstructionUseEnd());
assert(phiNode.getInstructionDefineBegin() != phiNode.getInstructionDefineEnd());
InstructionUse& source = phiNode.getInstructionUseBegin()[useIndex];
InstructionDefine& destination = phiNode.getInstructionDefineBegin()[0];
assert(source.isRegister() && destination.isRegister());
RegisterName sourceName = source.getRegisterName();
RegisterName destinationName = destination.getRegisterName();
// Get the correct name for the source.
if (copyStats[sourceName].newName != NULL)
sourceName = copyStats[sourceName].newName->newName;
// Update the CopyData structures.
if ((sourceName != rnInvalid) && (sourceName != destinationName)) {
copyStats[destinationName].source = sourceName;
copyStats[destinationName].classKind = destination.getRegisterClass();
copyStats[destinationName].isLiveOut = (currentLiveOut != NULL) ? currentLiveOut->test(destinationName) : false;
copyStats[destinationName].sourceNameToUse = destinationName;
copyStats[sourceName].sourceNameToUse = sourceName;
copyStats[sourceName].useCount++;
destinationList.set(destinationName);
}
}
}
// STEP3:
// Insert into the worklist only the destination registers that will be not used in
// another copy instruction in this block.
//
assert(workList.getSize() == 0);
for (SparseSet::iterator d = destinationList.begin(); !destinationList.done(d); d = destinationList.advance(d)) {
Uint32 dest = destinationList.get(d);
if (copyStats[dest].useCount == 0)
workList.set(dest);
}
// STEP4:
// Insert the copy instructions.
//
Uint32 destinationListSize = destinationList.getSize();
InstructionList::iterator endOfTheNode = instructions.end();
// Find the right place to insert the copy instructions.
if (destinationListSize != 0)
while (instructions.get(endOfTheNode).getFlags() & ifControl)
endOfTheNode = instructions.retreat(endOfTheNode);
while (destinationListSize != 0) {
while(workList.getSize()) {
RegisterName destinationName = RegisterName(workList.getOne());
RegisterName sourceName = copyStats[destinationName].source;
workList.clear(destinationName);
if (copyStats[destinationName].isLiveOut && !copyStats[destinationName].temporaryName) {
// Lost copy problem.
copyStats[destinationName].isLiveOut = false;
RegisterName sourceName = destinationName;
RegisterClassKind classKind = copyStats[sourceName].classKind;
RegisterName destinationName = getName(vrManager.newVirtualRegister(classKind));
assert(destinationName < maxNameCount);
copyStats[destinationName].classKind = classKind;
copyStats[sourceName].useCount = 0;
// We need to insert a copy to a temporary register to keep the
// source register valid at the end of the node defining it.
// This copy will be inserted right after the phi node defining it.
RegisterName from = copyStats[sourceName].sourceNameToUse;
Instruction* definingPhiNode = vrManager.getVirtualRegister(from).getDefiningInstruction();
assert(definingPhiNode && (definingPhiNode->getFlags() & ifPhiNode) != 0);
RegisterID fromID = buildRegisterID(from, classKind);
RegisterID toID = buildRegisterID(destinationName, classKind);
Instruction& copy = emitter.newCopy(*definingPhiNode->getPrimitive(), fromID, toID);
vrManager.getVirtualRegister(destinationName).setDefiningInstruction(copy);
definingPhiNode->getPrimitive()->getContainer()->getInstructions().addFirst(copy);
copyStats[sourceName].temporaryName = destinationName;
copyStats[sourceName].sourceNameToUse = destinationName;
pushName(pool, &(copyStats[sourceName].newName), pushed, &pushedList, sourceName, destinationName);
}
// Insert the copy instruction at the end of the current node.
RegisterName from = copyStats[sourceName].sourceNameToUse;
RegisterClassKind classKind = copyStats[destinationName].classKind;
RegisterID fromID = buildRegisterID(from, classKind);
RegisterID toID = buildRegisterID(destinationName, classKind);
Instruction& copy = emitter.newCopy(*vrManager.getVirtualRegister(from).getDefiningInstruction()->getPrimitive(), fromID, toID);
instructions.insertAfter(copy, endOfTheNode);
endOfTheNode = instructions.advance(endOfTheNode);
copyStats[sourceName].useCount = 0;
if (destinationList.test(sourceName) && copyStats[sourceName].isLiveOut)
pushName(pool, &(copyStats[sourceName].newName), pushed, &pushedList, sourceName, destinationName);
copyStats[sourceName].isLiveOut = false;
copyStats[sourceName].sourceNameToUse = destinationName;
if (destinationList.test(sourceName))
workList.set(sourceName);
destinationList.clear(destinationName);
}
destinationListSize = destinationList.getSize();
if (destinationListSize != 0) {
RegisterName sourceName = RegisterName(destinationList.getOne());
RegisterName destinationName;
if (!copyStats[sourceName].temporaryName) {
// Cycle problem.
RegisterClassKind classKind = copyStats[sourceName].classKind;
destinationName = getName(vrManager.newVirtualRegister(classKind));
assert(destinationName < maxNameCount);
copyStats[destinationName].classKind = classKind;
copyStats[sourceName].temporaryName = destinationName;
// Insert the copy instruction at the end of the current node.
RegisterName from = copyStats[sourceName].sourceNameToUse;
RegisterID fromID = buildRegisterID(from, classKind);
RegisterID toID = buildRegisterID(destinationName, classKind);
Instruction& copy = emitter.newCopy(*vrManager.getVirtualRegister(from).getDefiningInstruction()->getPrimitive(), fromID, toID);
vrManager.getVirtualRegister(destinationName).setDefiningInstruction(copy);
instructions.insertAfter(copy, endOfTheNode);
endOfTheNode = instructions.advance(endOfTheNode);
} else
destinationName = copyStats[sourceName].temporaryName;
copyStats[sourceName].useCount = 0;
copyStats[sourceName].isLiveOut = false;
copyStats[sourceName].sourceNameToUse = destinationName;
pushName(pool, &(copyStats[sourceName].newName), pushed, &pushedList, sourceName, destinationName);
workList.set(sourceName);
}
}
nodeStackPtr->pushedList = pushedList;
nodeStackPtr->next = next;
nodeStackPtr->limit = limit;
++nodeStackPtr;
next = dGraph.getSuccessorsBegin(currentNode);
limit = dGraph.getSuccessorsEnd(currentNode);
}
}
}
#endif // _PHI_NODE_REMOVER_H_

View File

@@ -0,0 +1,155 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "Fundamentals.h"
#include "LogModule.h"
#include "RegisterAllocator.h"
#include "RegisterPressure.h"
#include "RegisterAllocatorTools.h"
#include "PhiNodeRemover.h"
#include "LiveRange.h"
#include "Liveness.h"
#include "InterferenceGraph.h"
#include "LiveRangeGraph.h"
#include "Coalescing.h"
#include "Spilling.h"
#include "Coloring.h"
#include "Splits.h"
class Pool;
class ControlGraph;
class VirtualRegisterManager;
class InstructionEmitter;
UT_DEFINE_LOG_MODULE(RegAlloc);
void RegisterAllocator::allocateRegisters(Pool& pool, ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter)
{
// Insert the phi node instructions. We want to do this to have a single defined register per instruction.
// If we keep the PhiNode (as a DataNode) and a PhiNode is of DoubleWordKind then we have to execute
// some special code for the high word annotation.
//
RegisterAllocatorTools::insertPhiNodeInstructions(controlGraph, emitter);
// Perform some tests on the instruction graph.
//
DEBUG_ONLY(RegisterAllocatorTools::testTheInstructionGraph(controlGraph, vrManager));
// Replace the phi node instructions by their equivalent copy instructions.
//
PhiNodeRemover<LowRegisterPressure>::replacePhiNodes(controlGraph, vrManager, emitter);
// Do the register allocation.
//
RegisterAllocator registerAllocator(pool, controlGraph, vrManager, emitter);
registerAllocator.doGraphColoring();
}
void RegisterAllocator::doGraphColoring()
{
// Initialize the liverange map.
//
initLiveRanges();
// Build the live ranges. We do this to compress the number of RegisterNames
// used in the insterference graph.
//
LiveRange<LowRegisterPressure>::build(*this);
// Remove unnecessary copies.
//
RegisterAllocatorTools::removeUnnecessaryCopies(*this);
for (Uint8 loop = 0; loop < 10; loop++) {
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("********* RegisterAllocator loop %d *********\n", loop));
while(true) {
// Build the interference graph.
//
iGraph.build();
// Coalesce the copy instructions.
//
if (!Coalescing<LowRegisterPressure>::coalesce(*this))
break;
}
// Print the interference graph.
//
DEBUG_LOG_ONLY(iGraph.printPretty(UT_LOG_MODULE(RegAlloc)));
// Calculate the spill costs.
//
Spilling<LowRegisterPressure>::calculateSpillCosts(*this);
DEBUG_LOG_ONLY(RegisterAllocatorTools::printSpillCosts(*this));
// Calculate the split costs.
//
Splits<LowRegisterPressure>::calculateSplitCosts(*this);
DEBUG_LOG_ONLY(RegisterAllocatorTools::printSplitCosts(*this));
// Build the live range graph.
//
lGraph.build();
DEBUG_LOG_ONLY(lGraph.printPretty(UT_LOG_MODULE(RegAlloc)));
// Color the graph. If it succeeds then we're done with the
// register allocation.
//
if (Coloring<LowRegisterPressure>::color(*this)) {
// Write the final colors in the instruction graph.
//
Coloring<LowRegisterPressure>::finalColoring(*this);
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("********** RegisterAllocator done **********\n"));
DEBUG_LOG_ONLY(RegisterAllocatorTools::printInstructions(*this));
return;
}
// We need to spill some registers.
//
Spilling<LowRegisterPressure>::insertSpillCode(*this);
// Insert the split instructions.
//
Splits<LowRegisterPressure>::insertSplitCode(*this);
// Update the live ranges.
//
// FIX
}
#ifdef DEBUG_LOG
RegisterAllocatorTools::updateInstructionGraph(*this);
RegisterAllocatorTools::printInstructions(*this);
#endif
fprintf(stderr, "!!! Coloring failed after 10 loops !!!\n");
abort();
}
void RegisterAllocator::initLiveRanges()
{
Uint32 count = this->nameCount;
RegisterName* name2range = new(pool) RegisterName[nameCount];
for (RegisterName r = RegisterName(1); r < count; r = RegisterName(r + 1))
name2range[r] = r;
this->name2range = name2range;
rangeCount = count;
}

View File

@@ -0,0 +1,88 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _REGISTER_ALLOCATOR_H_
#define _REGISTER_ALLOCATOR_H_
class Pool;
class ControlGraph;
class InstructionEmitter;
struct SpillCost;
struct SplitCost;
#include "Liveness.h"
#include "VirtualRegister.h"
#include "RegisterPressure.h" // This should included by Backend.cpp
#include "InterferenceGraph.h"
#include "LiveRangeGraph.h"
//template <class RegisterPressure>
class RegisterAllocator
{
public:
Pool& pool; //
ControlGraph& controlGraph; //
VirtualRegisterManager& vrManager; //
InstructionEmitter& emitter; //
RegisterName* name2range; //
RegisterName* color; //
SpillCost* spillCost; //
SparseSet* willSpill; //
SplitCost* splitCost; //
NameLinkedList** splitAround; //
InterferenceGraph<LowRegisterPressure> iGraph; //
LiveRangeGraph<LowRegisterPressure> lGraph; //
LivenessInfo<LowRegisterPressure> liveness; //
Uint32 nameCount; //
Uint32 rangeCount; //
bool splitFound; //
private:
//
//
void doGraphColoring();
public:
//
//
inline RegisterAllocator(Pool& pool, ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter);
//
//
bool canInterfere(RegisterName /*name1*/, RegisterName /*name2*/) const {return true;}
//
//
void initLiveRanges();
//
//
static void allocateRegisters(Pool& pool, ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter);
};
//
//
inline RegisterAllocator::RegisterAllocator(Pool& pool, ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter)
: pool(pool), controlGraph(controlGraph), vrManager(vrManager), emitter(emitter), iGraph(*this), lGraph(*this), nameCount(vrManager.getSize()) {}
#endif // _REGISTER_ALLOCATOR_H_

View File

@@ -0,0 +1,355 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "Fundamentals.h"
#include "LogModule.h"
#include "RegisterAllocatorTools.h"
#include "Pool.h"
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "Primitives.h"
#include "InstructionEmitter.h"
#include "Instruction.h"
#include "RegisterAllocator.h"
#include "Spilling.h"
#include "Splits.h"
#include "BitSet.h"
UT_EXTERN_LOG_MODULE(RegAlloc);
#ifdef DEBUG
void RegisterAllocatorTools::testTheInstructionGraph(ControlGraph& controlGraph, VirtualRegisterManager& vrManager)
{
// Test the declared VirtualRegisters. The register allocator tries to condense the register universe.
// Any gap in the VirtualRegister names will be a loss of efficiency !!!!
Uint32 nameCount = vrManager.getSize();
BitSet registerSeen(controlGraph.pool, nameCount);
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
for (Uint32 n = 0; n < nNodes; n++) {
InstructionList& instructions = nodes[n]->getInstructions();
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister())
registerSeen.set(usePtr->getRegisterName());
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
registerSeen.set(definePtr->getRegisterName());
}
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
Instruction& instruction = phiNodes.get(p);
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister())
registerSeen.set(usePtr->getRegisterName());
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
registerSeen.set(definePtr->getRegisterName());
}
}
bool renameRegisters = false;
for (BitSet::iterator i = registerSeen.nextZero(0); !registerSeen.done(i); i = registerSeen.nextZero(i)) {
renameRegisters = true;
fprintf(stderr,
"WARNING: The VirtualRegister vr%d has been allocated during CodeGeneration but\n"
" is never used nor defined by any instruction in the instruction graph\n"
" PLEASE FIX \n",
i);
}
if (renameRegisters) {
Instruction** definingInstruction = new Instruction*[nameCount];
memset(definingInstruction, '\0', nameCount * sizeof(Instruction*));
RegisterName* newName = new RegisterName[nameCount];
memset(newName, '\0', nameCount * sizeof(RegisterName));
RegisterName nextName = RegisterName(1);
for (Uint32 n = 0; n < nNodes; n++) {
InstructionList& instructions = nodes[n]->getInstructions();
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
RegisterName name = usePtr->getRegisterName();
if (newName[name] == rnInvalid) {
newName[name] = nextName;
definingInstruction[nextName] = vrManager.getVirtualRegister(name).getDefiningInstruction();
nextName = RegisterName(nextName + 1);
}
usePtr->setRegisterName(newName[name]);
}
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister()) {
RegisterName name = definePtr->getRegisterName();
if (newName[name] == rnInvalid) {
newName[name] = nextName;
definingInstruction[nextName] = vrManager.getVirtualRegister(name).getDefiningInstruction();
nextName = RegisterName(nextName + 1);
}
definePtr->setRegisterName(newName[name]);
}
}
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
Instruction& instruction = phiNodes.get(p);
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
RegisterName name = usePtr->getRegisterName();
if (newName[name] == rnInvalid) {
newName[name] = nextName;
definingInstruction[nextName] = vrManager.getVirtualRegister(name).getDefiningInstruction();
nextName = RegisterName(nextName + 1);
}
usePtr->setRegisterName(newName[name]);
}
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister()) {
RegisterName name = definePtr->getRegisterName();
if (newName[name] == rnInvalid) {
newName[name] = nextName;
definingInstruction[nextName] = vrManager.getVirtualRegister(name).getDefiningInstruction();
nextName = RegisterName(nextName + 1);
}
definePtr->setRegisterName(newName[name]);
}
}
}
vrManager.setSize(nextName);
for (RegisterName r = RegisterName(1); r < nextName; r = RegisterName(r + 1))
vrManager.getVirtualRegister(r).definingInstruction = definingInstruction[r];
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("RegisterMap:\n"));
for (Uint32 i = 1; i < nameCount; i++)
if (newName[i] != 0)
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tvr%d becomes vr%d.\n", i, newName[i]));
else
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tvr%d is dead.\n", i));
delete newName;
delete definingInstruction;
}
}
#endif // DEBUG
void RegisterAllocatorTools::removeUnnecessaryCopies(RegisterAllocator& registerAllocator)
{
ControlGraph& controlGraph = registerAllocator.controlGraph;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
RegisterName* name2range = registerAllocator.name2range;
for (Uint32 n = 0; n < nNodes; n++) {
InstructionList& instructions = nodes[n]->getInstructions();
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i);) {
Instruction& instruction = instructions.get(i);
i = instructions.advance(i);
if (instruction.getFlags() & ifCopy) {
assert(instruction.getInstructionUseBegin() != instruction.getInstructionUseEnd() && instruction.getInstructionUseBegin()[0].isRegister());
assert(instruction.getInstructionDefineBegin() != instruction.getInstructionDefineEnd() && instruction.getInstructionDefineBegin()[0].isRegister());
RegisterName source = name2range[instruction.getInstructionUseBegin()[0].getRegisterName()];
RegisterName destination = name2range[instruction.getInstructionDefineBegin()[0].getRegisterName()];
if (source == destination)
instruction.remove();
}
}
}
}
void RegisterAllocatorTools::updateInstructionGraph(RegisterAllocator& registerAllocator)
{
ControlGraph& controlGraph = registerAllocator.controlGraph;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
RegisterName* name2range = registerAllocator.name2range;
for (Uint32 n = 0; n < nNodes; n++) {
InstructionList& instructions = nodes[n]->getInstructions();
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister())
usePtr->setRegisterName(name2range[usePtr->getRegisterName()]);
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
definePtr->setRegisterName(name2range[definePtr->getRegisterName()]);
}
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
Instruction& instruction = phiNodes.get(p);
InstructionUse* useEnd = instruction.getInstructionUseEnd();
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
if (usePtr->isRegister())
usePtr->setRegisterName(name2range[usePtr->getRegisterName()]);
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
definePtr->setRegisterName(name2range[definePtr->getRegisterName()]);
}
}
}
void RegisterAllocatorTools::insertPhiNodeInstructions(ControlGraph& controlGraph, InstructionEmitter& emitter)
{
Pool& pool = controlGraph.pool;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
for (Uint32 n = 0; n < nNodes; n++) {
ControlNode& node = *nodes[n];
DoublyLinkedList<PhiNode>& phiNodes = node.getPhiNodes();
if (!phiNodes.empty()) {
// Set the index of the incoming edges.
Uint32 index = 0;
const DoublyLinkedList<ControlEdge>& predecessors = node.getPredecessors();
for (DoublyLinkedList<ControlEdge>::iterator p = predecessors.begin(); !predecessors.done(p); p = predecessors.advance(p))
predecessors.get(p).setIndex(index++);
// Insert the phi node instruction in the instruction list.
for (DoublyLinkedList<PhiNode>::iterator i = phiNodes.begin(); !phiNodes.done(i); i = phiNodes.advance(i)) {
PhiNode& phiNode = phiNodes.get(i);
ValueKind kind = phiNode.getKind();
if (!isStorableKind(kind))
continue;
RegisterClassKind classKind = rckGeneral; // FIX: get class kind from phi node kind.
Uint32 nInputs = phiNode.nInputs();
PhiNodeInstruction& phiNodeInstruction = *new(pool) PhiNodeInstruction(&phiNode, pool, nInputs);
emitter.defineProducer(phiNode, phiNodeInstruction, 0, classKind, drLow);
for (Uint32 whichInput = 0; whichInput < nInputs; whichInput++)
emitter.useProducer(phiNode.nthInputVariable(whichInput), phiNodeInstruction, whichInput, classKind, drLow);
node.addPhiNodeInstruction(phiNodeInstruction);
if (isDoublewordKind(kind)) {
PhiNodeInstruction& phiNodeInstruction = *new(pool) PhiNodeInstruction(&phiNode, pool, nInputs);
emitter.defineProducer(phiNode, phiNodeInstruction, 0, classKind, drHigh);
for (Uint32 whichInput = 0; whichInput < nInputs; whichInput++)
emitter.useProducer(phiNode.nthInputVariable(whichInput), phiNodeInstruction, whichInput, classKind, drHigh);
node.addPhiNodeInstruction(phiNodeInstruction);
}
}
}
}
}
#ifdef DEBUG_LOG
void RegisterAllocatorTools::printSpillCosts(RegisterAllocator& registerAllocator)
{
LogModuleObject log = UT_LOG_MODULE(RegAlloc);
Uint32 rangeCount = registerAllocator.rangeCount;
SpillCost* cost = registerAllocator.spillCost;
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Spill costs:\n"));
for (Uint32 i = 1; i < rangeCount; i++) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\trange %d : ", i));
if (cost[i].infinite)
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("infinite\n"));
else
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%f\n", cost[i].cost));
}
}
void RegisterAllocatorTools::printSplitCosts(RegisterAllocator& registerAllocator)
{
LogModuleObject log = UT_LOG_MODULE(RegAlloc);
Uint32 rangeCount = registerAllocator.rangeCount;
SplitCost* cost = registerAllocator.splitCost;
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Split costs:\n"));
for (Uint32 i = 1; i < rangeCount; i++) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\trange %d : loads = %f stores = %f\n", i, cost[i].loads, cost[i].stores));
}
}
void RegisterAllocatorTools::printInstructions(RegisterAllocator& registerAllocator)
{
LogModuleObject log = UT_LOG_MODULE(RegAlloc);
ControlNode** nodes = registerAllocator.controlGraph.dfsList;
Uint32 nNodes = registerAllocator.controlGraph.nNodes;
for (Uint32 n = 0; n < nNodes; n++) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("N%d:\n", n));
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
InstructionList& instructions = nodes[n]->getInstructions();
if (!phiNodes.empty()) {
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (" PhiNodes:\n", n));
for(InstructionList::iterator i = phiNodes.begin(); !phiNodes.done(i); i = phiNodes.advance(i)) {
phiNodes.get(i).printPretty(log);
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
}
if (!instructions.empty())
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (" Instructions:\n", n));
}
for(InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
instructions.get(i).printPretty(log);
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
}
}
}
#endif // DEBUG_LOG

View File

@@ -0,0 +1,117 @@
// -*- mode:C++; tab-width:4; truncate-lines:t -*-
//
// CONFIDENTIAL AND PROPRIETARY SOURCE CODE OF
// NETSCAPE COMMUNICATIONS CORPORATION
// Copyright © 1996, 1997 Netscape Communications Corporation. All Rights
// Reserved. Use of this Source Code is subject to the terms of the
// applicable license agreement from Netscape Communications Corporation.
// The copyright notice(s) in this Source Code does not indicate actual or
// intended publication of this Source Code.
//
// $Id: RegisterAllocatorTools.h,v 1.1.2.1 1999-03-02 16:12:05 fur%netscape.com Exp $
//
#ifndef _REGISTER_ALLOCATOR_TOOLS_H_
#define _REGISTER_ALLOCATOR_TOOLS_H_
#include "LogModule.h"
#include "RegisterTypes.h"
#include <string.h>
class RegisterAllocator;
class ControlGraph;
class InstructionEmitter;
class VirtualRegisterManager;
struct RegisterAllocatorTools
{
//
//
static void insertPhiNodeInstructions(ControlGraph& controlGraph, InstructionEmitter& emitter);
//
//
static void updateInstructionGraph(RegisterAllocator& registerAllocator);
//
//
static void removeUnnecessaryCopies(RegisterAllocator& registerAllocator);
#ifdef DEBUG
//
//
static void testTheInstructionGraph(ControlGraph& controlGraph, VirtualRegisterManager& vrManager);
#endif // DEBUG
#ifdef DEBUG_LOG
//
//
static void printInstructions(RegisterAllocator& registerAllocator);
//
//
static void printSpillCosts(RegisterAllocator& registerAllocator);
//
//
static void printSplitCosts(RegisterAllocator& registerAllocator);
#endif // DEBUG_LOG
};
//
// FIX: this should go in a class (LookupTable ?)
//
inline RegisterName findRoot(RegisterName name, RegisterName* table)
{
RegisterName* stack = table;
RegisterName* stackPtr = stack;
RegisterName newName;
while((newName = table[name]) != name) {
*--stackPtr = name;
name = newName;
}
while (stackPtr != stack)
table[*stackPtr++] = name;
return name;
}
inline void init(RegisterName* table, Uint32 nameCount)
{
for (RegisterName r = RegisterName(0); r < nameCount; r = RegisterName(r + 1))
table[r] = r;
}
inline Uint32 compress(RegisterName* name2range, RegisterName* table, Uint32 nameCount, Uint32 tableSize)
{
RegisterName* liveRange = new RegisterName[tableSize];
memset(liveRange, '\0', tableSize * sizeof(RegisterName));
// Update the lookup table.
for (RegisterName r = RegisterName(1); r < tableSize; r = RegisterName(r + 1))
findRoot(r, table);
// Count the liveranges.
Uint32 liveRangeCount = 1;
for (RegisterName s = RegisterName(1); s < tableSize; s = RegisterName(s + 1))
if (table[s] == s)
liveRange[s] = RegisterName(liveRangeCount++);
for (RegisterName t = RegisterName(1); t < nameCount; t = RegisterName(t + 1))
name2range[t] = liveRange[table[name2range[t]]];
return liveRangeCount;
}
inline double doLog10(Uint32 power)
{
double log = 1.0;
while (power--)
log *= 10.0;
return log;
}
#endif // _REGISTER_ALLOCATOR_TOOLS_H_

View File

@@ -0,0 +1,38 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _REGISTER_ASSIGNER_H_
#define _REGISTER_ASSIGNER_H_
#include "Fundamentals.h"
#include "VirtualRegister.h"
class FastBitMatrix;
class RegisterAssigner
{
protected:
VirtualRegisterManager& vRegManager;
public:
RegisterAssigner(VirtualRegisterManager& vrMan) : vRegManager(vrMan) {}
virtual bool assignRegisters(FastBitMatrix& interferenceMatrix) = 0;
};
#endif /* _REGISTER_ASSIGNER_H_ */

View File

@@ -16,16 +16,10 @@
* Reserved.
*/
/*
#ifndef _REGISTER_CLASS_H_
#define _REGISTER_CLASS_H_
RDF node interfaces, including nsIRDFNode, nsIRDFResource, and
nsIRDFLiteral. Nodes are the elements that appear in RDF graphs.
#include "Fundamentals.h"
#include "RegisterTypes.h"
*/
#ifndef nsIRDFNode_h__
#define nsIRDFNode_h__
#include "nsRDFInterfaces.h"
#endif // nsIRDFNode_h__
#endif // _REGISTER_CLASS_H_

View File

@@ -16,19 +16,22 @@
* Reserved.
*/
/*
#ifndef _REGISTER_PRESSURE_H_
#define _REGISTER_PRESSURE_H_
The RDF service interface. This is a singleton object, and should be
obtained from the <tt>nsServiceManager</tt>.
#include "BitSet.h"
#include "HashSet.h"
*/
struct LowRegisterPressure
{
typedef BitSet Set;
static const bool setIsOrdered = true;
};
#ifndef nsIRDFService_h__
#define nsIRDFService_h__
struct HighRegisterPressure
{
typedef HashSet Set;
static const bool setIsOrdered = false;
};
#include "nsRDFInterfaces.h"
extern nsresult
NS_NewRDFService(nsIRDFService** result);
#endif // nsIRDFService_h__
#endif // _REGISTER_PRESSURE_H_

View File

@@ -0,0 +1,104 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _REGISTER_TYPES_H_
#define _REGISTER_TYPES_H_
#include "Fundamentals.h"
//------------------------------------------------------------------------------
// RegisterName -
//
enum RegisterName {
rnInvalid = 0,
};
//------------------------------------------------------------------------------
// RegisterClassKind -
//
enum RegisterClassKind {
rckInvalid = 0,
rckGeneral,
rckStackSlot,
nRegisterClassKind
};
//------------------------------------------------------------------------------
// RegisterID -
//
enum RegisterID {
invalidID = 0
};
//------------------------------------------------------------------------------
// RegisterKind -
//
enum RegisterKind {
rkCallerSave = 0,
rkCalleeSave,
};
struct NameLinkedList {
RegisterName name;
NameLinkedList* next;
};
#ifdef DEBUG
const registerNameMask = 0x03ffffff;
const coloredRegisterMask = 0x04000000;
const machineRegisterMask = 0x08000000;
const registerClassMask = 0xf0000000;
const registerNameShift = 0;
const coloredRegisterShift = 26;
const machineRegisterShift = 27;
const registerClassShift = 28;
#else // DEBUG
const registerNameMask = 0x0fffffff;
const registerClassMask = 0xf0000000;
const registerNameShift = 0;
const registerClassShift = 28;
#endif // DEBUG
inline RegisterClassKind getClass(RegisterID registerID) {return RegisterClassKind((registerID & registerClassMask) >> registerClassShift);}
inline RegisterName getName(RegisterID registerID) {return RegisterName((registerID & registerNameMask) >> registerNameShift);}
inline void setClass(RegisterID& registerID, RegisterClassKind classKind) {registerID = RegisterID((registerID & ~registerClassMask) | ((classKind << registerClassShift) & registerClassMask));}
inline void setName(RegisterID& registerID, RegisterName name) {assert((name & ~registerNameMask) == 0); registerID = RegisterID((registerID & ~registerNameMask) | ((name << registerNameShift) & registerNameMask));}
inline RegisterID buildRegisterID(RegisterName name, RegisterClassKind classKind) {return RegisterID(((classKind << registerClassShift) & registerClassMask) | ((name << registerNameShift) & registerNameMask));}
#ifdef DEBUG
inline bool isMachineRegister(RegisterID rid) {return (rid & machineRegisterMask) != 0;}
inline void setMachineRegister(RegisterID& rid) {rid = RegisterID(rid | machineRegisterMask);}
inline bool isColoredRegister(RegisterID rid) {return (rid & coloredRegisterMask) != 0;}
inline void setColoredRegister(RegisterID& rid) {rid = RegisterID(rid | coloredRegisterMask);}
#endif // DEBUG
#endif // _REGISTER_TYPES_H_

View File

@@ -0,0 +1,32 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "Fundamentals.h"
#include "SSATools.h"
#include "ControlGraph.h"
#include "VirtualRegister.h"
#include "Liveness.h"
void replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager)
{
if (!controlGraph.hasBackEdges)
return;
Liveness liveness(controlGraph.pool);
liveness.buildLivenessAnalysis(controlGraph, vrManager);
}

View File

@@ -16,16 +16,14 @@
* Reserved.
*/
/*
#ifndef _SSA_TOOLS_H_
#define _SSA_TOOLS_H_
The RDF data source interface. An RDF data source presents a
graph-like interface to a back-end service.
#include "Fundamentals.h"
*/
class ControlGraph;
class VirtualRegisterManager;
#ifndef nsIRDFDataSource_h__
#define nsIRDFDataSource_h__
extern void replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager);
#include "nsRDFInterfaces.h"
#endif /* nsIRDFDataSource_h__ */
#endif // _SSA_TOOLS_H_

View File

@@ -0,0 +1,37 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "Fundamentals.h"
#include "SparseSet.h"
#include "BitSet.h"
#include "Pool.h"
#ifdef DEBUG_LOG
// Print the set.
//
void SparseSet::printPretty(LogModuleObject log)
{
Pool pool;
BitSet set(pool, universeSize);
for (Uint32 i = 0; i < count; i++)
set.set(node[i].element);
set.printPretty(log);
}
#endif // DEBUG_LOG

View File

@@ -0,0 +1,168 @@
// -*- mode:C++; tab-width:4; truncate-lines:t -*-
//
// CONFIDENTIAL AND PROPRIETARY SOURCE CODE OF
// NETSCAPE COMMUNICATIONS CORPORATION
// Copyright © 1996, 1997 Netscape Communications Corporation. All Rights
// Reserved. Use of this Source Code is subject to the terms of the
// applicable license agreement from Netscape Communications Corporation.
// The copyright notice(s) in this Source Code does not indicate actual or
// intended publication of this Source Code.
//
// $Id: SparseSet.h,v 1.1.2.1 1999-03-02 16:12:07 fur%netscape.com Exp $
//
#ifndef _SPARSE_SET_H_
#define _SPARSE_SET_H_
#include "Fundamentals.h"
#include "Pool.h"
#include "LogModule.h"
#include "BitSet.h"
class SparseSet
{
private:
struct Node {
Uint32 element;
Uint32 stackIndex;
};
Node* node;
Uint32 count;
Uint32 universeSize;
private:
// No copy constructor.
SparseSet(const SparseSet&);
// Check if the given set's universe is of the same size than this universe.
void checkUniverseCompatibility(const SparseSet& set) const {assert(set.universeSize == universeSize);}
// Check if pos is valid for this set's universe.
void checkMember(Int32 pos) const {assert(pos >=0 && Uint32(pos) < universeSize);}
public:
SparseSet(Pool& pool, Uint32 universeSize) : universeSize(universeSize) {node = new(pool) Node[universeSize]; clear();}
// Clear the sparse set.
void clear() {count = 0;}
// Clear the element at index.
inline void clear(Uint32 index);
// Set the element at index.
inline void set(Uint32 index);
// Return true if the element at index is set.
inline bool test(Uint32 index) const;
// Union with the given sparse set.
inline void or(const SparseSet& set);
// Intersection with the given sparse set.
inline void and(const SparseSet& set);
// Difference with the given sparse set.
inline void difference(const SparseSet& set);
// Copy set.
inline SparseSet& operator = (const SparseSet& set);
inline SparseSet& operator = (const BitSet& set);
// Return true if the sparse sets are identical.
friend bool operator == (const SparseSet& set1, const SparseSet& set2);
// Return true if the sparse sets are different.
friend bool operator != (const SparseSet& set1, const SparseSet& set2);
// Logical operators.
SparseSet& operator |= (const SparseSet& set) {or(set); return *this;}
SparseSet& operator &= (const SparseSet& set) {and(set); return *this;}
SparseSet& operator -= (const SparseSet& set) {difference(set); return *this;}
// Iterator to conform with the set API.
typedef Int32 iterator;
// Return the iterator for the first element of this set.
iterator begin() const {return count - 1;}
// Return the next iterator.
iterator advance(iterator pos) const {return --pos;}
// Return true if the iterator is at the end of the set.
bool done(iterator pos) const {return pos < 0;}
// Return the element for the given iterator;
Uint32 get(iterator pos) const {return node[pos].element;}
// Return one element of this set.
Uint32 getOne() const {assert(count > 0); return node[0].element;}
// Return the size of this set.
Uint32 getSize() const {return count;}
#ifdef DEBUG_LOG
// Print the set.
void printPretty(LogModuleObject log);
#endif // DEBUG_LOG
};
inline void SparseSet::clear(Uint32 element)
{
checkMember(element);
Uint32 count = this->count;
Node* node = this->node;
Uint32 stackIndex = node[element].stackIndex;
if ((stackIndex < count) && (node[stackIndex].element == element)) {
Uint32 stackTop = node[count - 1].element;
node[stackIndex].element = stackTop;
node[stackTop].stackIndex = stackIndex;
this->count = count - 1;
}
}
inline void SparseSet::set(Uint32 element)
{
checkMember(element);
Uint32 count = this->count;
Node* node = this->node;
Uint32 stackIndex = node[element].stackIndex;
if ((stackIndex >= count) || (node[stackIndex].element != element)) {
node[count].element = element;
node[element].stackIndex = count;
this->count = count + 1;
}
}
inline bool SparseSet::test(Uint32 element) const
{
checkMember(element);
Node* node = this->node;
Uint32 stackIndex = node[element].stackIndex;
return ((stackIndex < count) && (node[stackIndex].element == element));
}
inline SparseSet& SparseSet::operator = (const SparseSet& set)
{
checkUniverseCompatibility(set);
Uint32 sourceCount = set.getSize();
Node* node = this->node;
memcpy(node, set.node, sourceCount * sizeof(Node));
for (Uint32 i = 0; i < sourceCount; i++) {
Uint32 element = node[i].element;
node[element].stackIndex = i;
}
count = sourceCount;
return *this;
}
inline SparseSet& SparseSet::operator = (const BitSet& set)
{
// FIX: there's room for optimization here.
assert(universeSize == set.getSize());
clear();
for (Int32 i = set.firstOne(); i != -1; i = set.nextOne(i))
this->set(i);
return *this;
}
#endif // _SPARSE_SET_H_

View File

@@ -0,0 +1,270 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef NEW_LAURENTM_CODE
#define INCLUDE_EMITTER
#include "CpuInfo.h"
#include "Fundamentals.h"
#include "ControlNodes.h"
#include "Instruction.h"
#include "InstructionEmitter.h"
#include "Spilling.h"
void Spilling::
insertSpillCode(ControlNode** dfsList, Uint32 nNodes)
{
PRUint32 nVirtualRegisters = vRegManager.count();
FastBitSet currentLive(vRegManager.pool, nVirtualRegisters);
FastBitSet usedInThisInstruction(vRegManager.pool, nVirtualRegisters);
RegisterFifo grNeedLoad(nVirtualRegisters);
RegisterFifo fpNeedLoad(nVirtualRegisters);
for (PRInt32 n = nNodes - 1; n >= 0; n--)
{
PR_ASSERT(grNeedLoad.empty() & fpNeedLoad.empty());
ControlNode& node = *dfsList[n];
currentLive = node.liveAtEnd;
PRUint32 nGeneralAlive = 0;
PRUint32 nFloatingPointAlive = 0;
// Get the number of registers alive at the end of this node.
for (PRInt32 j = currentLive.firstOne(); j != -1; j = currentLive.nextOne(j))
{
VirtualRegister& vReg = vRegManager.getVirtualRegister(j);
if (vReg.spillInfo.willSpill)
{
currentLive.clear(j);
}
else
{
switch (vReg.getClass())
{
case vrcInteger:
nGeneralAlive++;
break;
case vrcFloatingPoint:
case vrcFixedPoint:
nFloatingPointAlive++;
break;
default:
break;
}
}
}
// if(node.dfsNum == 8) printf("\n________Begin Node %d________\n", node.dfsNum);
InstructionList& instructions = node.getInstructions();
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i))
{
Instruction& instruction = instructions.get(i);
InstructionUse* useBegin = instruction.getInstructionUseBegin();
InstructionUse* useEnd = instruction.getInstructionUseEnd();
InstructionUse* usePtr;
InstructionDefine* defBegin = instruction.getInstructionDefineBegin();
InstructionDefine* defEnd = instruction.getInstructionDefineEnd();
InstructionDefine* defPtr;
// if(node.dfsNum == 8) { printf("\n");
// instruction.printPretty(stdout);
// printf("\n"); }
// Handle definitions
for (defPtr = defBegin; defPtr < defEnd; defPtr++)
if (defPtr->isVirtualRegister())
{
VirtualRegister& vReg = defPtr->getVirtualRegister();
currentLive.clear(vReg.getRegisterIndex());
switch (vReg.getClass())
{
case vrcInteger:
nGeneralAlive--;
break;
case vrcFloatingPoint:
case vrcFixedPoint:
nFloatingPointAlive--;
break;
default:
break;
}
}
// Check for deaths
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isVirtualRegister())
{
VirtualRegister& vReg = usePtr->getVirtualRegister();
if (!currentLive.test(vReg.getRegisterIndex()))
// This is the last use of this register.
{
currentLive.set(vReg.getRegisterIndex());
switch (vReg.getClass())
{
case vrcInteger:
nGeneralAlive++;
while (/*(nGeneralAlive > NUMBER_OF_GREGISTERS) &&*/ !grNeedLoad.empty())
{
PRUint32 toLoad = grNeedLoad.get();
currentLive.clear(toLoad);
nGeneralAlive--;
VirtualRegister& nReg = vRegManager.getVirtualRegister(toLoad);
Instruction& lastUsingInstruction = *nReg.spillInfo.lastUsingInstruction;
emitter.emitLoadAfter(*lastUsingInstruction.getPrimitive(), lastUsingInstruction.getLinks().prev,
nReg.getAlias(), *nReg.equivalentRegister[vrcStackSlot]);
nReg.releaseSelf();
}
break;
case vrcFloatingPoint:
case vrcFixedPoint:
nFloatingPointAlive++;
while (/*(nFloatingPointAlive > NUMBER_OF_FPREGISTERS) &&*/ !fpNeedLoad.empty())
{
PRUint32 toLoad = fpNeedLoad.get();
currentLive.clear(toLoad);
nFloatingPointAlive--;
VirtualRegister& nReg = vRegManager.getVirtualRegister(toLoad);
Instruction& lastUsingInstruction = *nReg.spillInfo.lastUsingInstruction;
emitter.emitLoadAfter(*lastUsingInstruction.getPrimitive(), lastUsingInstruction.getLinks().prev,
nReg.getAlias(), *nReg.equivalentRegister[vrcStackSlot]);
nReg.releaseSelf();
}
break;
default:
break;
}
}
}
// Handle uses
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isVirtualRegister())
{
VirtualRegister& vReg = usePtr->getVirtualRegister();
PRUint32 registerIndex = vReg.getRegisterIndex();
if (vReg.spillInfo.willSpill) {
#if defined(GENERATE_FOR_X86)
if (!instruction.switchUseToSpill((usePtr - useBegin), *vReg.equivalentRegister[vrcStackSlot]))
#endif
{
switch (vReg.getClass())
{
case vrcInteger:
if (!grNeedLoad.test(registerIndex))
{
grNeedLoad.put(registerIndex);
VirtualRegister& alias = vRegManager.newVirtualRegister(vrcInteger);
if (vReg.isPreColored())
alias.preColorRegister(vReg.getPreColor());
/* if (vReg.hasSpecialInterference) {
alias.specialInterference.sizeTo(NUMBER_OF_REGISTERS);
alias.specialInterference = vReg.specialInterference;
alias.hasSpecialInterference = true;
} */
vReg.setAlias(alias);
vReg.retainSelf();
}
break;
case vrcFloatingPoint:
case vrcFixedPoint:
if (!fpNeedLoad.test(registerIndex))
{
fpNeedLoad.put(registerIndex);
VirtualRegister& alias = vRegManager.newVirtualRegister(vReg.getClass());
if (vReg.isPreColored())
alias.preColorRegister(vReg.getPreColor());
/*if (vReg.hasSpecialInterference) {
alias.specialInterference.sizeTo(NUMBER_OF_REGISTERS);
alias.specialInterference = vReg.specialInterference;
alias.hasSpecialInterference = true;
} */
vReg.setAlias(alias);
vReg.retainSelf();
}
break;
default:
break;
}
usePtr->getVirtualRegisterPtr().initialize(vReg.getAlias());
usedInThisInstruction.set(registerIndex);
vReg.spillInfo.lastUsingInstruction = &instruction;
}
currentLive.clear(registerIndex);
} else { // will not spill
currentLive.set(registerIndex);
}
}
// Handle definitions
for (defPtr = defBegin; defPtr < defEnd; defPtr++)
if (defPtr->isVirtualRegister())
{
VirtualRegister& vReg = defPtr->getVirtualRegister();
if (vReg.spillInfo.willSpill)
#if defined(GENERATE_FOR_X86)
if (!instruction.switchDefineToSpill((defPtr - defBegin), *vReg.equivalentRegister[vrcStackSlot]))
#endif
{
if (usedInThisInstruction.test(vReg.getRegisterIndex()))
// this virtualRegister was used in this instruction and is also defined. We need to move
// this virtual register to its alias first and then save it to memory.
{
emitter.emitStoreAfter(*instruction.getPrimitive(), &instruction.getLinks(),
vReg.getAlias(), *vReg.equivalentRegister[vrcStackSlot]);
defPtr->getVirtualRegisterPtr().initialize(vReg.getAlias());
}
else
{
emitter.emitStoreAfter(*instruction.getPrimitive(), &instruction.getLinks(),
vReg, *vReg.equivalentRegister[vrcStackSlot]);
}
}
}
}
while (!grNeedLoad.empty())
{
PRUint32 nl = grNeedLoad.get();
VirtualRegister& nlReg = vRegManager.getVirtualRegister(nl);
Instruction& lastUse = *nlReg.spillInfo.lastUsingInstruction;
emitter.emitLoadAfter(*lastUse.getPrimitive(), lastUse.getLinks().prev,
nlReg.getAlias(), *nlReg.equivalentRegister[vrcStackSlot]);
nlReg.releaseSelf();
}
while (!fpNeedLoad.empty())
{
PRUint32 nl = fpNeedLoad.get();
VirtualRegister& nlReg = vRegManager.getVirtualRegister(nl);
Instruction& lastUse = *nlReg.spillInfo.lastUsingInstruction;
emitter.emitLoadAfter(*lastUse.getPrimitive(), lastUse.getLinks().prev,
nlReg.getAlias(), *nlReg.equivalentRegister[vrcStackSlot]);
nlReg.releaseSelf();
}
// if(node.dfsNum == 8) printf("\n________End Node %d________\n", node.dfsNum);
}
}
#endif

View File

@@ -0,0 +1,269 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _SPILLING_H_
#define _SPILLING_H_
#include "Fundamentals.h"
#include <string.h>
#include "RegisterAllocator.h"
#include "RegisterAllocatorTools.h"
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "Instruction.h"
#include "SparseSet.h"
template <class RegisterPressure>
class Spilling
{
private:
static void insertStoreAfter(Instruction& instruction, RegisterName name);
static void insertLoadBefore(Instruction& instruction, RegisterName name);
public:
static void calculateSpillCosts(RegisterAllocator& registerAllocator);
static void insertSpillCode(RegisterAllocator& registerAllocator);
};
struct SpillCost
{
double loads;
double stores;
double copies;
double cost;
bool infinite;
};
template <class RegisterPressure>
void Spilling<RegisterPressure>::insertSpillCode(RegisterAllocator& registerAllocator)
{
Uint32 rangeCount = registerAllocator.rangeCount;
RegisterName* name2range = registerAllocator.name2range;
Pool& pool = registerAllocator.pool;
SparseSet currentLive(pool, rangeCount);
SparseSet needLoad(pool, rangeCount);
SparseSet mustSpill(pool, rangeCount);
SparseSet& willSpill = *registerAllocator.willSpill;
ControlGraph& controlGraph = registerAllocator.controlGraph;
RegisterPressure::Set* liveOut = registerAllocator.liveness.liveOut;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
for (Uint32 n = 0; n < nNodes; n++) {
needLoad.clear();
currentLive = liveOut[n];
mustSpill = currentLive;
InstructionList& instructions = nodes[n]->getInstructions();
for (InstructionList::iterator i = instructions.end(); !instructions.done(i);) {
Instruction& instruction = instructions.get(i);
i = instructions.retreat(i);
InstructionUse* useBegin = instruction.getInstructionUseBegin();
InstructionUse* useEnd = instruction.getInstructionUseEnd();
InstructionUse* usePtr;
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
InstructionDefine* definePtr;
bool foundLiveDefine = false;
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister()) {
if (currentLive.test(name2range[definePtr->getRegisterName()])) {
foundLiveDefine = true;
break;
}
} else {
foundLiveDefine = true;
break;
}
if (defineBegin != defineEnd && !foundLiveDefine) {
fprintf(stderr, "!!! Removed instruction because it was only defining unused registers !!!\n");
instruction.remove();
}
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister()) {
RegisterName range = name2range[definePtr->getRegisterName()];
#ifdef DEBUG
if (needLoad.test(range))
if (!mustSpill.test(range) && registerAllocator.spillCost[range].infinite && willSpill.test(range)) {
fprintf(stderr, "Tried to spill a register with infinite spill cost\n");
abort();
}
#endif // DEBUG
if (willSpill.test(range))
insertStoreAfter(instruction, range);
needLoad.clear(range);
}
if (instruction.getFlags() & ifCopy)
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
RegisterName range = name2range[usePtr->getRegisterName()];
if (!currentLive.test(range))
for (SparseSet::iterator r = needLoad.begin(); !needLoad.done(r); r = needLoad.advance(r)) {
RegisterName load = RegisterName(needLoad.get(r));
if (willSpill.test(load))
insertLoadBefore(instruction, load);
mustSpill.set(load);
}
needLoad.clear();
}
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
currentLive.clear(name2range[definePtr->getRegisterName()]);
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
RegisterName range = name2range[usePtr->getRegisterName()];
currentLive.set(range);
needLoad.set(range);
}
}
for (SparseSet::iterator l = needLoad.begin(); !needLoad.done(l); l = needLoad.advance(l)) {
RegisterName load = RegisterName(needLoad.get(l));
if (willSpill.test(load))
insertLoadBefore(instructions.first(), load);
}
}
}
template <class RegisterPressure>
void Spilling<RegisterPressure>::insertLoadBefore(Instruction& /*instruction*/, RegisterName name)
{
fprintf(stdout, "will insert load for range %d\n", name);
}
template <class RegisterPressure>
void Spilling<RegisterPressure>::insertStoreAfter(Instruction& /*instruction*/, RegisterName name)
{
fprintf(stdout, "will insert store for range %d\n", name);
}
template <class RegisterPressure>
void Spilling<RegisterPressure>::calculateSpillCosts(RegisterAllocator& registerAllocator)
{
Uint32 rangeCount = registerAllocator.rangeCount;
RegisterName* name2range = registerAllocator.name2range;
Pool& pool = registerAllocator.pool;
SparseSet live(pool, rangeCount);
SparseSet needLoad(pool, rangeCount);
SparseSet mustSpill(pool, rangeCount);
SparseSet alreadyStored(pool, rangeCount); // FIX: should get this from previous spilling.
SpillCost* cost = new SpillCost[rangeCount];
memset(cost, '\0', rangeCount * sizeof(SpillCost));
ControlGraph& controlGraph = registerAllocator.controlGraph;
RegisterPressure::Set* liveOut = registerAllocator.liveness.liveOut;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
for (Uint32 n = 0; n < nNodes; n++) {
ControlNode& node = *nodes[n];
double weight = doLog10(node.loopDepth);
needLoad.clear();
live = liveOut[n];
mustSpill = live;
InstructionList& instructions = nodes[n]->getInstructions();
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useBegin = instruction.getInstructionUseBegin();
InstructionUse* useEnd = instruction.getInstructionUseEnd();
InstructionUse* usePtr;
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
InstructionDefine* definePtr;
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister()) {
RegisterName range = name2range[definePtr->getRegisterName()];
if (needLoad.test(range))
if (!mustSpill.test(range))
cost[range].infinite = true;
if ((false /* !rematerializable(range) */ || !needLoad.test(range)) && !alreadyStored.test(range))
cost[range].stores += weight;
needLoad.clear(range);
}
if (instruction.getFlags() & ifCopy)
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister())
if (!live.test(name2range[usePtr->getRegisterName()])) {
for (SparseSet::iterator l = needLoad.begin(); !needLoad.done(l); l = needLoad.advance(l)) {
Uint32 range = needLoad.get(l);
cost[range].loads += weight;
mustSpill.set(range);
}
needLoad.clear();
}
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
live.clear(name2range[definePtr->getRegisterName()]);
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
RegisterName range = name2range[usePtr->getRegisterName()];
live.set(range);
needLoad.set(range);
}
if (instruction.getFlags() & ifCopy) {
assert(useBegin != useEnd && useBegin[0].isRegister());
assert(defineBegin != defineEnd && defineBegin[0].isRegister());
RegisterName source = name2range[useBegin[0].getRegisterName()];
RegisterName destination = name2range[defineBegin[0].getRegisterName()];
cost[source].copies += weight;
cost[destination].copies += weight;
}
}
for (SparseSet::iterator s = needLoad.begin(); !needLoad.done(s); s = needLoad.advance(s))
cost[needLoad.get(s)].loads += weight;
}
for (Uint32 r = 0; r < rangeCount; r++) {
SpillCost& c = cost[r];
c.cost = 2 * (c.loads + c.stores) - c.copies;
}
registerAllocator.spillCost = cost;
}
#endif // _SPILLING_H_

View File

@@ -0,0 +1,239 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _SPLITS_H_
#define _SPLITS_H_
#include "Fundamentals.h"
#include <string.h>
#include "Pool.h"
#include "ControlGraph.h"
#include "ControlNodes.h"
#include "Instruction.h"
#include "RegisterAllocator.h"
#include "RegisterAllocatorTools.h"
UT_EXTERN_LOG_MODULE(RegAlloc);
template <class RegisterPressure>
struct Splits
{
static void calculateSplitCosts(RegisterAllocator& registerAllocator);
static bool findSplit(RegisterAllocator& registerAllocator, RegisterName* color, RegisterName range);
static void insertSplitCode(RegisterAllocator& registerAllocator);
};
struct SplitCost
{
double loads;
double stores;
};
template <class RegisterPressure>
void Splits<RegisterPressure>::insertSplitCode(RegisterAllocator& /*registerAllocator*/)
{
// FIX
}
template <class RegisterPressure>
bool Splits<RegisterPressure>::findSplit(RegisterAllocator& registerAllocator, RegisterName* color, RegisterName range)
{
Pool& pool = registerAllocator.pool;
NameLinkedList** neighborsWithColor = new(pool) NameLinkedList*[6]; // FIX
memset(neighborsWithColor, '\0', 6 * sizeof(NameLinkedList*));
InterferenceGraph<RegisterPressure>& iGraph = registerAllocator.iGraph;
for (InterferenceVector* vector = iGraph.getInterferenceVector(range); vector != NULL; vector = vector->next)
for (Int32 i = vector->count - 1; i >=0; --i) {
RegisterName neighbor = vector->neighbors[i];
RegisterName c = color[neighbor];
if (c < 6) { // FIX
NameLinkedList* node = new(pool) NameLinkedList();
node->name = neighbor;
node->next = neighborsWithColor[c];
neighborsWithColor[c] = node;
}
}
bool splitAroundName = true;
LiveRangeGraph<RegisterPressure>& lGraph = registerAllocator.lGraph;
RegisterName bestColor = RegisterName(6); // FIX
double bestCost = registerAllocator.spillCost[range].cost;
SplitCost* splitCost = registerAllocator.splitCost;
for (RegisterName i = RegisterName(0); i < 6; i = RegisterName(i + 1)) { // FIX
double splitAroundNameCost = 0.0;
bool canSplitAroundName = true;
SplitCost& sCost = splitCost[range];
double addedCost = 2.0 * (sCost.stores + sCost.loads);
for (NameLinkedList* node = neighborsWithColor[i]; node != NULL; node = node->next) {
RegisterName neighbor = node->name;
if (lGraph.haveEdge(neighbor, range)) {
canSplitAroundName = false;
break;
} else
splitAroundNameCost += addedCost;
}
if (canSplitAroundName && splitAroundNameCost < bestCost) {
bestCost = splitAroundNameCost;
bestColor = i;
splitAroundName = true;
}
double splitAroundColorCost = 0.0;
bool canSplitAroundColor = true;
for (NameLinkedList* node = neighborsWithColor[i]; node != NULL; node = node->next) {
RegisterName neighbor = node->name;
if (lGraph.haveEdge(range, neighbor)) {
canSplitAroundColor = false;
break;
} else {
SplitCost& sCost = splitCost[neighbor];
double addedCost = 2.0 * (sCost.stores + sCost.loads);
splitAroundColorCost += addedCost;
}
}
if (canSplitAroundColor && splitAroundColorCost < bestCost) {
bestCost = splitAroundColorCost;
bestColor = i;
splitAroundName = false;
}
}
if (bestColor < RegisterName(6)) {
color[range] = bestColor;
registerAllocator.splitFound = true;
NameLinkedList** splitAround = registerAllocator.splitAround;
if (splitAroundName)
for (NameLinkedList* node = neighborsWithColor[bestColor]; node != NULL; node = node->next) {
NameLinkedList* newNode = new(pool) NameLinkedList();
newNode->name = node->name;
newNode->next = splitAround[range];
splitAround[range] = newNode;
}
else
for (NameLinkedList* node = neighborsWithColor[bestColor]; node != NULL; node = node->next) {
NameLinkedList* newNode = new(pool) NameLinkedList();
RegisterName neighbor = node->name;
newNode->name = range;
newNode->next = splitAround[neighbor];
splitAround[neighbor] = newNode;
}
trespass("Found a split");
return true;
}
return false;
}
template <class RegisterPressure>
void Splits<RegisterPressure>::calculateSplitCosts(RegisterAllocator& registerAllocator)
{
Pool& pool = registerAllocator.pool;
Uint32 rangeCount = registerAllocator.rangeCount;
RegisterName* name2range = registerAllocator.name2range;
SplitCost* splitCost = new(pool) SplitCost[rangeCount];
memset(splitCost, '\0', rangeCount * sizeof(SplitCost));
SparseSet live(pool, rangeCount);
RegisterPressure::Set* liveIn = registerAllocator.liveness.liveIn;
RegisterPressure::Set* liveOut = registerAllocator.liveness.liveOut;
ControlGraph& controlGraph = registerAllocator.controlGraph;
ControlNode** nodes = controlGraph.dfsList;
Uint32 nNodes = controlGraph.nNodes;
for (Uint32 n = 0; n < nNodes; n++) {
ControlNode& node = *nodes[n];
double weight = doLog10(node.loopDepth);
live = liveOut[n];
ControlEdge* successorsEnd = node.getSuccessorsEnd();
for (ControlEdge* successorsPtr = node.getSuccessorsBegin(); successorsPtr < successorsEnd; successorsPtr++) {
ControlNode& successor = successorsPtr->getTarget();
if (successor.getControlKind() != ckEnd) {
RegisterPressure::Set& successorLiveIn = liveIn[successor.dfsNum];
for (SparseSet::iterator i = live.begin(); !live.done(i); i = live.advance(i)) {
RegisterName name = RegisterName(live.get(i));
if (!successorLiveIn.test(name))
splitCost[name].loads += doLog10(successor.loopDepth);
}
}
}
InstructionList& instructions = node.getInstructions();
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) {
Instruction& instruction = instructions.get(i);
InstructionUse* useBegin = instruction.getInstructionUseBegin();
InstructionUse* useEnd = instruction.getInstructionUseEnd();
InstructionUse* usePtr;
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
InstructionDefine* definePtr;
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
splitCost[name2range[definePtr->getRegisterName()]].stores += weight;
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister()) {
RegisterName range = name2range[usePtr->getRegisterName()];
if (!live.test(range)) {
if (&instruction != &instructions.last())
splitCost[range].loads += weight;
else {
ControlEdge* successorsEnd = node.getSuccessorsEnd();
for (ControlEdge* successorsPtr = node.getSuccessorsBegin(); successorsPtr < successorsEnd; successorsPtr++)
splitCost[range].loads += doLog10(successorsPtr->getTarget().loopDepth);
}
}
}
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
if (definePtr->isRegister())
live.clear(name2range[definePtr->getRegisterName()]);
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
if (usePtr->isRegister())
live.set(name2range[usePtr->getRegisterName()]);
}
}
NameLinkedList** splitAround = new(pool) NameLinkedList*[rangeCount];
memset(splitAround, '\0', rangeCount * sizeof(NameLinkedList*));
registerAllocator.splitAround = splitAround;
registerAllocator.splitCost = splitCost;
registerAllocator.splitFound = false;
}
#endif // _SPLITS_H_

View File

@@ -0,0 +1,186 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "Fundamentals.h"
#include "HashTable.h"
#include "Timer.h"
#include "Pool.h"
static Pool pool; // Pool for the Timer class.
static HashTable<TimerEntry*> timerEntries(pool); // Timers hashtable.
const nTimersInABlock = 128; // Number of timers in a block.
static PRTime *timers = new(pool) PRTime[nTimersInABlock]; // A block of timers.
static Uint8 nextTimer = 0; // nextAvailableTimer.
//
// Calibrate the call to PR_Now().
//
static PRTime calibrate()
{
PRTime t = PR_Now();
PRTime& a = *new(pool) PRTime();
// Call 10 times the PR_Now() function.
a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now();
a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now();
t = (PR_Now() - t + 9) / 10;
return t;
}
static PRTime adjust = calibrate();
//
// Return the named timer..
//
TimerEntry& Timer::getTimerEntry(const char* name)
{
if (!timerEntries.exists(name)) {
TimerEntry* newEntry = new(pool) TimerEntry();
newEntry->accumulator = 0;
newEntry->running = false;
timerEntries.add(name, newEntry);
}
return *timerEntries[name];
}
//
// Return a reference to a new timer.
//
PRTime& Timer::getNewTimer()
{
if (nextTimer >= nTimersInABlock) {
timers = new(pool) PRTime[nTimersInABlock];
nextTimer = 0;
}
return timers[nextTimer++];
}
static Uint32 timersAreFrozen = 0;
//
// Start the named timer.
//
void Timer::start(const char* name)
{
if (timersAreFrozen)
return;
freezeTimers();
TimerEntry& timer = getTimerEntry(name);
PR_ASSERT(!timer.running);
timer.accumulator = 0;
timer.running = true;
timer.done = false;
unfreezeTimers();
}
//
// Stop the named timer.
//
void Timer::stop(const char* name)
{
if (timersAreFrozen)
return;
freezeTimers();
TimerEntry& timer = getTimerEntry(name);
PR_ASSERT(timer.running);
timer.running = false;
timer.done = true;
unfreezeTimers();
}
//
// Freeze all the running timers.
//
void Timer::freezeTimers()
{
PRTime when = PR_Now() - adjust;
if (timersAreFrozen == 0) {
Vector<TimerEntry*> entries = timerEntries;
Uint32 count = entries.size();
for (Uint32 i = 0; i < count; i++) {
TimerEntry& entry = *entries[i];
if (entry.running) {
entry.accumulator += (when - *entry.startTime);
}
}
}
timersAreFrozen++;
}
//
// Unfreeze all the running timers.
//
void Timer::unfreezeTimers()
{
PR_ASSERT(timersAreFrozen != 0);
timersAreFrozen--;
if (timersAreFrozen == 0) {
Vector<TimerEntry *> entries = timerEntries;
Uint32 count = entries.size();
PRTime& newStart = getNewTimer();
for (Uint32 i = 0; i < count; i++) {
TimerEntry& entry = *entries[i];
if (entry.running) {
entry.startTime = &newStart;
}
}
newStart = PR_Now();
}
}
//
// Print the named timer in the file f.
//
void Timer::print(FILE* f, const char *name)
{
if (timersAreFrozen)
return;
freezeTimers();
TimerEntry& timer = getTimerEntry(name);
PR_ASSERT(timer.done);
PRTime elapsed = timer.accumulator;
if (elapsed >> 32) {
fprintf(f, "[timer %s out of range]\n", name);
} else {
fprintf(f, "[%dus in %s]\n", Uint32(elapsed), name);
}
fflush(f);
unfreezeTimers();
}

View File

@@ -0,0 +1,80 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _TIMER_H_
#define _TIMER_H_
#include "Fundamentals.h"
#include "HashTable.h"
#include "prtime.h"
//
// Naming convention:
// As the class Timer contains only static methods, the timer's name should start with the
// module name. Otherwise starting 2 timers with the same name will assert.
//
#ifndef NO_TIMER
struct TimerEntry
{
PRTime *startTime; // Current time when we start the timer.
PRTime accumulator; // Time spent in this timer.
bool running; // True if the timer is running.
bool done; // True if the timer was running and was stopped.
};
class Timer
{
private:
// Return the named timer.
static TimerEntry& getTimerEntry(const char* name);
// Return a reference to a new Timer.
static PRTime& getNewTimer();
public:
// Start the timer.
static void start(const char* name);
// Stop the timer.
static void stop(const char* name);
// Freeze all the running timers.
static void freezeTimers();
// Unfreeze all the running timers.
static void unfreezeTimers();
// Print the timer.
static void print(FILE* f, const char *name);
};
inline void startTimer(const char* name) {Timer::start(name);}
inline void stopTimer(const char* name) {Timer::stop(name); Timer::print(stdout, name);}
#define START_TIMER_SAFE Timer::freezeTimers();
#define END_TIMER_SAFE Timer::unfreezeTimers();
#define TIMER_SAFE(x) START_TIMER_SAFE x; END_TIMER_SAFE
#else /* NO_TIMER */
inline void startTimer(const char* /*name*/) {}
inline void stopTimer(const char* /*name*/) {}
#define START_TIMER_SAFE
#define END_TIMER_SAFE
#define TIMER_SAFE(x) x;
#endif /* NO_TIMER */
#endif /* _TIMER_H_ */

View File

@@ -16,24 +16,25 @@
* Reserved.
*/
#ifndef nsILocalStore_h__
#define nsILocalStore_h__
#include "Fundamentals.h"
#include "VirtualRegister.h"
#include "Instruction.h"
#include "nsISupports.h"
//------------------------------------------------------------------------------
// VirtualRegister -
// {DF71C6F1-EC53-11d2-BDCA-000064657374}
#define NS_ILOCALSTORE_IID \
{ 0xdf71c6f1, 0xec53, 0x11d2, { 0xbd, 0xca, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }
#ifdef MANUAL_TEMPLATES
template class IndexedPool<VirtualRegister>;
#endif
class nsILocalStore : public nsISupports
// Set the defining instruction.
//
void VirtualRegister::setDefiningInstruction(Instruction& instruction)
{
public:
static const nsIID& GetIID() { static nsIID iid = NS_ILOCALSTORE_IID; return iid; }
};
if (definingInstruction != NULL) {
if ((instruction.getFlags() & ifCopy) && (definingInstruction->getFlags() & ifPhiNode))
return;
}
definingInstruction = &instruction;
}
PR_EXTERN(nsresult)
NS_NewLocalStore(nsILocalStore** aResult);
#endif // nsILocalStore_h__

View File

@@ -0,0 +1,116 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _VIRTUAL_REGISTER_H_
#define _VIRTUAL_REGISTER_H_
#include "Fundamentals.h"
#include "IndexedPool.h"
#include <string.h>
#include "RegisterTypes.h"
#include "RegisterClass.h"
//------------------------------------------------------------------------------
// VirtualRegister - 24b
class Instruction;
class VirtualRegister : public IndexedObject<VirtualRegister>
{
public:
Instruction* definingInstruction; // Instruction defining this VR.
// Initialize a VR of the given classKind.
VirtualRegister(RegisterClassKind /*classKind*/) : definingInstruction(NULL) {}
// Return the defining instruction for this VR.
Instruction* getDefiningInstruction() const {return definingInstruction;}
// Set the defining instruction.
void setDefiningInstruction(Instruction& insn);
};
// Return true if the VirtualRegisters are equals. The only way 2 VRs can be equal is if
// they have the same index. If they have the same index then they are at the same
// address in the indexed pool.
//
inline bool operator == (const VirtualRegister& regA, const VirtualRegister& regB) {return &regA == &regB;}
//------------------------------------------------------------------------------
// VirtualRegisterManager -
struct PreColoredRegister
{
RegisterID id;
RegisterName color;
};
class VirtualRegisterManager
{
private:
IndexedPool<VirtualRegister> registerPool;
PreColoredRegister machineRegister[6];
public:
VirtualRegisterManager()
{
for (Uint32 i = 0; i < 6; i++)
machineRegister[i].id = invalidID;
}
// Return the VirtualRegister at the given index.
VirtualRegister& getVirtualRegister(RegisterName name) const {return registerPool.get(name);}
// Return a new VirtualRegister.
RegisterID newVirtualRegister(RegisterClassKind classKind)
{
VirtualRegister& vReg = *new(registerPool) VirtualRegister(classKind);
RegisterID rid;
setName(rid, RegisterName(vReg.getIndex()));
setClass(rid, classKind);
return rid;
}
RegisterID newMachineRegister(RegisterName name, RegisterClassKind classKind)
{
RegisterID rid = machineRegister[name].id;
if (rid == invalidID) {
rid = newVirtualRegister(classKind);
DEBUG_ONLY(setMachineRegister(rid));
machineRegister[name].id = rid;
machineRegister[name].color = name;
}
return rid;
}
PreColoredRegister* getMachineRegistersBegin() const {return (PreColoredRegister*) machineRegister;} // FIX
PreColoredRegister* getMachineRegistersEnd() const {return (PreColoredRegister*) &machineRegister[6];} // FIX
// Return the VirtualRegister universe size.
Uint32 getSize() {return registerPool.getSize();}
void setSize(Uint32 size) {registerPool.setSize(size);}
};
#endif // _VIRTUAL_REGISTER_H_

View File

@@ -1,37 +0,0 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH = ..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = base util content datasource chrome build
ifdef MOZ_BRPROF
DIRS += brprof
endif
ifdef ENABLE_TESTS
DIRS += tests
endif
include $(topsrcdir)/config/config.mk
include $(topsrcdir)/config/rules.mk

View File

@@ -1,33 +0,0 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH = ../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = public src
ifdef USE_XPIDL
DIRS += idl
endif
include $(topsrcdir)/config/config.mk
include $(topsrcdir)/config/rules.mk

View File

@@ -1,45 +0,0 @@
#!gmake
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
IDLSRCS = \
nsRDFInterfaces.idl \
# nsIRDFArcsInCursor.idl \
# nsIRDFArcsOutCursor.idl \
# nsIRDFAssertionCursor.idl \
# nsIRDFCursor.idl \
# nsIRDFDataSource.idl \
# nsIRDFLiteral.idl \
# nsIRDFNode.idl \
# nsIRDFObserver.idl \
# nsIRDFResoruce.idl \
# nsIRDFResourceCursor.idl \
$(NULL)
# for testing purposes
#EXPORTS = $(IDLSRCS:.idl=.h)
# to build in the static methods
#CPPSRCS = $(IDLSRCS:.idl=.cpp)
#LIBRARY_NAME = rdfidl
include $(topsrcdir)/config/rules.mk

View File

@@ -1,43 +0,0 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH=..\..\..
MODULE=rdf
GARBAGE= nsRDFInterfaces.h \
nsRDFInterfaces.cpp \
$(NULL)
include <$(DEPTH)\config\rules.mak>
XPIDL=$(DIST)\bin\xpidl.exe
XPIDL_INCLUDES= -I $(DEPTH)\xpcom\idl \
$(NULL)
nsRDFInterfaces.h: nsRDFInterfaces.idl
@echo +++ make: generating XPIDL headers
$(XPIDL) -m header $(XPIDL_INCLUDES) $**
nsRDFInterfaces.xpt: nsRDFInterfaces.idl
@echo +++ make: generating XPIDL typelib
$(XPIDL) -m typelib $(XPIDL_INCLUDES) $**
export:: nsRDFInterfaces.h nsRDFInterfaces.xpt
$(MAKE_INSTALL) nsRDFInterfaces.h $(DEPTH)\rdf\base\public
$(MAKE_INSTALL) nsRDFInterfaces.xpt $(DEPTH)\rdf\build

View File

@@ -1,393 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
This file contains _all_ of the interface definitions, lumped into
one big happy file. It's done this way to circumvent problems with
forward declarations in the current version of `xpidl'.
*/
#include "nsIEnumerator.idl"
#include "nsISimpleEnumerator.idl"
#include "nsISupports.idl"
#include "nsISupportsArray.idl"
%{C++
#include "nscore.h" // for PRUnichar
%}
// An nsIRDFNode object is an abstract placeholder for a node in the
// RDF data model. Its concreted implementations (e.g., nsIRDFResource
// or nsIRDFLiteral) are the actual objects that populate the graph.
[scriptable, uuid(0F78DA50-8321-11d2-8EAC-00805F29F370)]
interface nsIRDFNode : nsISupports {
// Determine if two nodes are identical
boolean EqualsNode(in nsIRDFNode aNode);
};
// An nsIRDFResource is an object that has unique identity in the
// RDF data model. The object's identity is determined by its URI.
[scriptable, uuid(E0C493D1-9542-11d2-8EB8-00805F29F370)]
interface nsIRDFResource : nsIRDFNode {
// The single-byte string value of the resource
readonly attribute string Value;
// This method is called by the nsIRDFService after constructing
// a resource object to initialize it's URI. You would not normally
// call this method directly
void Init(in string uri);
// Determine if two resources are identical.
boolean EqualsResource(in nsIRDFResource aResource);
// Determine if the resource has the given URI.
boolean EqualsString(in string aURI);
};
// A literal node in the graph, whose value is a string.
[scriptable, uuid(E0C493D2-9542-11d2-8EB8-00805F29F370)]
interface nsIRDFLiteral : nsIRDFNode {
// The Unicode string value of the literal.
readonly attribute wstring Value;
// Determine if two literals are identical.
boolean EqualsLiteral(in nsIRDFLiteral aLiteral);
};
// A literal node in the graph, whose value is a date
[scriptable, uuid(E13A24E1-C77A-11d2-80BE-006097B76B8E)]
interface nsIRDFDate : nsIRDFNode {
// The date value of the literal
readonly attribute long long Value;
// Determine if the date is equal to another
//
// XXX Is this really necessary?
boolean EqualsDate(in nsIRDFDate aDate);
};
// A literal node in the graph, whose value is an integer
[scriptable, uuid(E13A24E3-C77A-11d2-80BE-006097B76B8E)]
interface nsIRDFInt : nsIRDFNode {
// The integer value of the literal
readonly attribute long Value;
// Determine if the integer is equal to another
//
// XXX Is this really necessary?
boolean EqualsInt(in nsIRDFInt aInt);
};
interface nsIRDFDataSource;
// An nsIRDFObserver object is an observer that will be notified
// when assertions are made or removed from a datasource
[scriptable, uuid(3CC75360-484A-11D2-BC16-00805F912FE7)]
interface nsIRDFObserver : nsISupports {
// This method is called whenever a new assertion is made
// in the data source
void OnAssert(in nsIRDFResource aSource,
in nsIRDFResource aLabel,
in nsIRDFNode aTarget);
// This method is called whenever an assertion is removed
// from the data source
void OnUnassert(in nsIRDFResource aSource,
in nsIRDFResource aLabel,
in nsIRDFNode aTarget);
};
[scriptable, uuid(0F78DA58-8321-11d2-8EAC-00805F29F370)]
interface nsIRDFDataSource : nsISupports {
// Specify the URI for the data source: this is the prefix
// that will be used to register the data source in the
// data source registry.
void Init(in string uri);
// The URI of the data source.
readonly attribute string URI;
// Find an RDF resource that points to a given node over the
// specified arc & truth value
//
// @return NS_RDF_NO_VALUE if there is no source that leads
// to the target with the specified property.
nsIRDFResource GetSource(in nsIRDFResource aProperty,
in nsIRDFNode aTarget,
in boolean aTruthValue);
// Find all RDF resources that point to a given node over the
// specified arc & truth value
//
// @return NS_OK unless a catastrophic error occurs. If the
// method returns NS_OK, you may assume that nsISimpleEnumerator points
// to a valid (but possibly empty) cursor.
nsISimpleEnumerator GetSources(in nsIRDFResource aProperty,
in nsIRDFNode aTarget,
in boolean aTruthValue);
// Find a child of that is related to the source by the given arc
// arc and truth value
//
// @return NS_RDF_NO_VALUE if there is no target accessable from the
// source via the specified property.
nsIRDFNode GetTarget(in nsIRDFResource aSource,
in nsIRDFResource aProperty,
in boolean aTruthValue);
// Find all children of that are related to the source by the given arc
// arc and truth value.
//
// @return NS_OK unless a catastrophic error occurs. If the
// method returns NS_OK, you may assume that nsISimpleEnumerator points
// to a valid (but possibly empty) cursor.
nsISimpleEnumerator GetTargets(in nsIRDFResource aSource,
in nsIRDFResource aProperty,
in boolean aTruthValue);
// Add an assertion to the graph.
void Assert(in nsIRDFResource aSource,
in nsIRDFResource aProperty,
in nsIRDFNode aTarget,
in boolean aTruthValue);
// Remove an assertion from the graph.
void Unassert(in nsIRDFResource aSource,
in nsIRDFResource aProperty,
in nsIRDFNode aTarget);
// Query whether an assertion exists in this graph.
boolean HasAssertion(in nsIRDFResource aSource,
in nsIRDFResource aProperty,
in nsIRDFNode aTarget,
in boolean aTruthValue);
// Add an observer to this data source.
void AddObserver(in nsIRDFObserver aObserver);
// Remove an observer from this data source
void RemoveObserver(in nsIRDFObserver aObserver);
// Get a cursor to iterate over all the arcs that point into a node.
//
// @return NS_OK unless a catastrophic error occurs. If the method
// returns NS_OK, you may assume that labels points to a valid (but
// possible empty) nsISimpleEnumerator object.
nsISimpleEnumerator ArcLabelsIn(in nsIRDFNode aNode);
// Get a cursor to iterate over all the arcs that originate in
// a resource.
//
// @return NS_OK unless a catastrophic error occurs. If the method
// returns NS_OK, you may assume that labels points to a valid (but
// possible empty) nsISimpleEnumerator object.
nsISimpleEnumerator ArcLabelsOut(in nsIRDFResource aSource);
// Retrieve all of the resources that the data source currently
// refers to.
nsISimpleEnumerator GetAllResources();
// Request that a data source write it's contents out to
// permanent storage if applicable.
void Flush();
// Returns the set of all commands defined for a given source.
nsIEnumerator GetAllCommands(in nsIRDFResource aSource);
// Returns whether a given command is enabled for a set of sources.
boolean IsCommandEnabled(in nsISupportsArray aSources,
in nsIRDFResource aCommand,
in nsISupportsArray aArguments);
// Perform the specified command on set of sources.
void DoCommand(in nsISupportsArray aSources,
in nsIRDFResource aCommand,
in nsISupportsArray aArguments);
};
// An nsIRDFCompositeDataSource composes individual data sources, providing
// the illusion of a single, coherent RDF graph.
[scriptable, uuid(96343820-307C-11D2-BC15-00805F912FE7)]
interface nsIRDFCompositeDataSource : nsIRDFDataSource {
// Add a datasource the the database.
void AddDataSource(in nsIRDFDataSource aDataSource);
// Remove a datasource from the database
void RemoveDataSource(in nsIRDFDataSource aDataSource);
};
// The RDF service interface. This is a singleton object, and should be
// obtained from the <tt>nsServiceManager</tt>.
[scriptable, uuid(BFD05261-834C-11d2-8EAC-00805F29F370)]
interface nsIRDFService : nsISupports {
// Construct an RDF resource from a single-byte URI. <tt>nsIRDFSerivce</tt>
// caches resources that are in-use, so multiple calls to <tt>GetResource()</tt>
// for the same <tt>uri</tt> will return identical pointers. FindResource
// is used to find out whether there already exists a resource corresponding to that url.
nsIRDFResource GetResource(in string aURI);
// Construct an RDF resource from a Unicode URI. This is provided
// as a convenience method, allowing automatic, in-line C++
// conversion from <tt>nsString</tt> objects. The <tt>uri</tt> will
// be converted to a single-byte representation internally.
nsIRDFResource GetUnicodeResource(in wstring aURI);
// Construct an RDF literal from a Unicode string.
nsIRDFLiteral GetLiteral(in wstring aValue);
// Construct an RDF literal from a PRTime.
nsIRDFDate GetDateLiteral(in long long aValue);
// Construct an RDF literal from an int.
nsIRDFInt GetIntLiteral(in long aValue);
// Registers a resource with the RDF system, making it unique w.r.t.
// GetResource.
//
// An implementation of nsIRDFResource should call this in its
// Init() method if it wishes the resource to be globally unique
// (which is usually the case).
//
// NOTE that the resource will <i>not</i> be ref-counted by the
// RDF service: the assumption is that the resource implementation
// will call nsIRDFService::UnregisterResource() when the last
// reference to the resource is released.
//
// NOTE that the nsIRDFService implementation may choose to
// maintain a reference to the resource's URI; therefore, the
// resource implementation should ensure that the resource's URI
// (accessable via nsIRDFResource::GetValue(const char* *aURI)) is
// valid before calling RegisterResource(). Furthermore, the
// resource implementation should ensure that this pointer
// <i>remains</i> valid for the lifetime of the resource. (The
// implementation of the resource cache in nsIRDFService uses the
// URI maintained "internally" in the resource as a key into the
// cache rather than copying the resource URI itself.)
void RegisterResource(in nsIRDFResource aResource, in boolean aReplace);
// Called to notify the resource manager that a resource is no
// longer in use. This method should only be called from the
// destructor of a "custom" resource implementation to notify the
// RDF service that the last reference to the resource has been
// released, so the resource is no longer valid.
//
// NOTE. As mentioned in nsIRDFResourceFactory::CreateResource(),
// the RDF service will use the result of
// nsIRDFResource::GetValue() as a key into its cache. For this
// reason, you must always un-cache the resource <b>before</b>
// releasing the storage for the <tt>const char*</tt> URI.
void UnregisterResource(in nsIRDFResource aResource);
// Register a <i>named data source</i>. The RDF service will call
// <tt>nsIRDFDataSource::GetURI()</tt> to determine the URI under
// which to register the data source.
//
// Note that the data source will <i>not</i> be refcounted by the
// RDF service! The assumption is that an RDF data source
// registers with the service once it is initialized (via
// <tt>nsIRDFDataSource::Init()</tt>), and unregisters when the
// last reference to the data source is released.
void RegisterDataSource(in nsIRDFDataSource aDataSource,
in boolean aReplace);
// Unregister a <i>named data source</i>. The RDF service will call
// <tt>nsIRDFDataSource::GetURI()</tt> to determine the URI under which the
// data source was registered.
void UnregisterDataSource(in nsIRDFDataSource aDataSource);
// Get the <i>named data source</i> corresponding to the URI. If a data
// source has been registered via <tt>RegisterDataSource()</tt>, that
// data source will be returned.
//
// If no data source is currently
// registered for the specified URI, and a data source <i>constructor</i>
// function has been registered via <tt>RegisterDatasourceConstructor()</tt>,
// the RDF service will call the constructor to attempt to construct a
// new data source. If construction is successful, the data source will
// be initialized via <tt>nsIRDFDataSource::Init()</tt>.
nsIRDFDataSource GetDataSource(in string aURI);
};
// A wrapper for manipulating RDF containers
[scriptable, uuid(D4214E90-FB94-11D2-BDD8-00104BDE6048)]
interface nsIRDFContainer : nsISupports {
// Initialize the container wrapper to the specified resource
// using the specified datasource for context.
void Init(in nsIRDFDataSource aDataSource, in nsIRDFResource aContainer);
// Return the number of elements in the container. Note that this
// may not always be accurate due to aggregation.
long GetCount();
// Return an enumerator that can be used to enumerate the contents
// of the container in ascending order.
nsISimpleEnumerator GetElements();
// Append an element to the container, assigning it the next
// available ordinal.
void AppendElement(in nsIRDFNode aElement);
// Remove the first occurence of the specified element from the
// container.
void RemoveElement(in nsIRDFNode aElement, in boolean aRenumber);
void InsertElementAt(in nsIRDFNode aElement, in long aIndex, in boolean aRenumber);
long IndexOf(in nsIRDFNode aElement);
};
// Container utilities
[scriptable, uuid(D4214E91-FB94-11D2-BDD8-00104BDE6048)]
interface nsIRDFContainerUtils : nsISupports {
// Returns 'true' if the property is an RDF ordinal property.
boolean IsOrdinalProperty(in nsIRDFResource aProperty);
// Convert the specified index to an ordinal property.
nsIRDFResource IndexToOrdinalResource(in long aIndex);
// Convert the specified ordinal property into an index
long OrdinalResourceToIndex(in nsIRDFResource aOrdinal);
// Return 'true' if the specified resource is a container
boolean IsContainer(in nsIRDFDataSource aDataSource, in nsIRDFResource aResource);
// Return 'true' if the specified resource is a bag
boolean IsBag(in nsIRDFDataSource aDataSource, in nsIRDFResource aResource);
// Return 'true' if the specified resource is a sequence
boolean IsSeq(in nsIRDFDataSource aDataSource, in nsIRDFResource aResource);
// Return 'true' if the specified resource is an alternation
boolean IsAlt(in nsIRDFDataSource aDataSource, in nsIRDFResource aResource);
// Decorates the specified resource appropriately to make it
// usable as an empty bag in the specified data source.
nsIRDFContainer MakeBag(in nsIRDFDataSource aDataSource, in nsIRDFResource aResource);
// Decorates the specified resource appropriately to make it
// usable as an empty sequence in the specified data source.
nsIRDFContainer MakeSeq(in nsIRDFDataSource aDataSource, in nsIRDFResource aResource);
// Decorates the specified resource appropriately to make it
// usable as an empty alternation in the specified data source.
nsIRDFContainer MakeAlt(in nsIRDFDataSource aDataSource, in nsIRDFResource aResource);
};

View File

@@ -1,27 +0,0 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH=..\..
MODULE = rdf
DIRS=\
public \
src \
$(NULL)
include <$(DEPTH)\config\rules.mak>

View File

@@ -1,14 +0,0 @@
rdf.h
nsIRDFCompositeDataSource.h
nsIRDFContainer.h
nsIRDFContainerUtils.h
nsIRDFContentSink.h
nsIRDFDataSource.h
nsIRDFNode.h
nsIRDFObserver.h
nsIRDFResource.h
nsIRDFResourceFactory.h
nsIRDFService.h
nsIRDFXMLDataSource.h
nsIRDFXMLSource.h
nsRDFInterfaces.h

View File

@@ -1,48 +0,0 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH=../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = rdf
EXPORTS = \
rdf.h \
nsIRDFCompositeDataSource.h \
nsIRDFContainer.h \
nsIRDFContainerUtils.h \
nsIRDFContentSink.h \
nsIRDFDataSource.h \
nsIRDFNode.h \
nsIRDFObserver.h \
nsIRDFResource.h \
nsIRDFResourceFactory.h \
nsIRDFService.h \
nsIRDFXMLDataSource.h \
nsIRDFXMLSource.h \
nsRDFInterfaces.h \
$(NULL)
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
include $(topsrcdir)/config/config.mk
include $(topsrcdir)/config/rules.mk

View File

@@ -1,42 +0,0 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
MODULE=rdf
DEPTH=..\..\..
EXPORTS=\
rdf.h \
nsIRDFCompositeDataSource.h \
nsIRDFContainer.h \
nsIRDFContainerUtils.h \
nsIRDFContentSink.h \
nsIRDFDataSource.h \
nsIRDFNode.h \
nsIRDFObserver.h \
nsIRDFResource.h \
nsIRDFResourceFactory.h \
nsIRDFService.h \
nsIRDFXMLDataSource.h \
nsIRDFXMLSource.h \
nsRDFInterfaces.h \
$(NULL)
include <$(DEPTH)/config/rules.mak>

View File

@@ -1,66 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
RDF composite data source interface. A composite data source
aggregates individual RDF data sources.
*/
#ifndef nsIRDFCompositeDataSource_h__
#define nsIRDFCompositeDataSource_h__
#if 1 //defined(USE_XPIDL_INTERFACES)
#include "nsRDFInterfaces.h"
#else
#include "nsISupports.h"
#include "nsIRDFDataSource.h"
class nsIRDFDataSource;
// 96343820-307c-11d2-bc15-00805f912fe7
#define NS_IRDFCOMPOSITEDATASOURCE_IID \
{ 0x96343820, 0x307c, 0x11d2, { 0xb, 0x15, 0x00, 0x80, 0x5f, 0x91, 0x2f, 0xe7 } }
/**
* An <tt>nsIRDFCompositeDataSource</tt> composes individual data sources, providing
* the illusion of a single, coherent RDF graph.
*/
class nsIRDFCompositeDataSource : public nsIRDFDataSource {
public:
static const nsIID& GetIID() { static nsIID iid = NS_IRDFCOMPOSITEDATASOURCE_IID; return iid; }
/**
* Add a datasource the the database.
*/
NS_IMETHOD AddDataSource(nsIRDFDataSource* source) = 0;
/**
* Remove a datasource from the database
*/
NS_IMETHOD RemoveDataSource(nsIRDFDataSource* source) = 0;
};
#endif
extern nsresult
NS_NewRDFCompositeDataSource(nsIRDFCompositeDataSource** result);
#endif /* nsIRDFCompositeDataSource_h__ */

View File

@@ -1,47 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
#ifndef nsIRDFContainer_h__
#define nsIRDFContainer_h__
#include "nsRDFInterfaces.h"
PR_EXTERN(nsresult)
NS_NewRDFContainer(nsIRDFContainer** aResult);
PR_EXTERN(nsresult)
NS_NewRDFContainer(nsIRDFDataSource* aDataSource,
nsIRDFResource* aResource,
nsIRDFContainer** aResult);
/**
* Create a cursor on a container that enumerates its contents in
* order
*/
PR_EXTERN(nsresult)
NS_NewContainerEnumerator(nsIRDFDataSource* aDataSource,
nsIRDFResource* aContainer,
nsISimpleEnumerator** aResult);
#endif // nsIRDFContainer_h__

View File

@@ -1,29 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
#ifndef nsIRDFContainerUtils_h__
#define nsIRDFContainerUtils_h__
#include "nsRDFInterfaces.h"
extern nsresult
NS_NewRDFContainerUtils(nsIRDFContainerUtils** aResult);
#endif // nsIRDFContainerUtils_h__

View File

@@ -1,72 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
/*
An RDF-specific content sink. The content sink is targeted by the
parser for building the RDF content model.
*/
#ifndef nsIRDFContentSink_h___
#define nsIRDFContentSink_h___
#include "nsIXMLContentSink.h"
class nsIDocument;
class nsIRDFXMLDataSource;
class nsINameSpaceManager;
class nsIURL;
// {751843E2-8309-11d2-8EAC-00805F29F370}
#define NS_IRDFCONTENTSINK_IID \
{ 0x751843e2, 0x8309, 0x11d2, { 0x8e, 0xac, 0x0, 0x80, 0x5f, 0x29, 0xf3, 0x70 } }
/**
* This interface represents a content sink for RDF files.
*/
class nsIRDFContentSink : public nsIXMLContentSink {
public:
static const nsIID& GetIID() { static nsIID iid = NS_IRDFCONTENTSINK_IID; return iid; }
/**
* Initialize the content sink.
*/
NS_IMETHOD Init(nsIURL* aURL, nsINameSpaceManager* aNameSpaceManager) = 0;
/**
* Set the content sink's RDF Data source
*/
NS_IMETHOD SetDataSource(nsIRDFXMLDataSource* aDataSource) = 0;
/**
* Retrieve the content sink's RDF data source.
*/
NS_IMETHOD GetDataSource(nsIRDFXMLDataSource*& rDataSource) = 0;
};
/**
* This constructs a content sink that can be used without a
* document, say, to create a stand-alone in-memory graph.
*/
nsresult
NS_NewRDFContentSink(nsIRDFContentSink** aResult);
#endif // nsIRDFContentSink_h___

View File

@@ -1,77 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
The RDF resource factory interface. A resource factory produces
nsIRDFResource objects for a specified URI prefix.
*/
#ifndef nsIRDFResourceFactory_h__
#define nsIRDFResourceFactory_h__
#if 0 // obsolete
#include "nsISupports.h"
class nsIRDFResource;
// {8CE57A20-A02C-11d2-8EBF-00805F29F370}
#define NS_IRDFRESOURCEFACTORY_IID \
{ 0x8ce57a20, 0xa02c, 0x11d2, { 0x8e, 0xbf, 0x0, 0x80, 0x5f, 0x29, 0xf3, 0x70 } }
/**
* A resource factory can be registered with <tt>nsIRDFService</tt> to produce
* resources with a certain <i>URI prefix</i>. The resource factory will be called
* upon to create a new resource, which the resource manager will cache.
*
* @see nsIRDFService::RegisterResourceFactory
* @see nsIRDFService::UnRegisterResourceFactory
*/
class nsIRDFResourceFactory : public nsISupports
{
public:
static const nsIID& GetIID() { static nsIID iid = NS_IRDFRESOURCEFACTORY_IID; return iid; }
/**
* This method is called by the RDF service to create a new
* resource.
*
* NOTE. After constructing a new resource via a call to
* nsIRDFResourceFactory::CreateResource(), the implementation of
* the RDF service calls nsIRDFResource::GetValue() on the
* resulting resource. The resulting <tt>const char*</tt> is used
* as a key for the resource cache. (The assumption is that the
* custom resource implementation needs to store this information,
* anyway.)
*
* This has important implications for a custom resource's
* destructor; namely, that you must call
* nsIRDFService::UnCacheResource() <b>before</b> releasing the
* storage for the resource's URI. See
* nsIRDFService::UnCacheResource() for more information.
*/
NS_IMETHOD CreateResource(const char* aURI, nsIRDFResource** aResult) = 0;
};
#endif
#endif // nsIRDFResourceFactory_h__

View File

@@ -1,60 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsIRDFTree_h__
#define nsIRDFTree_h__
#include "nscore.h"
#include "nsISupports.h"
#include "prtypes.h"
#include "rdf.h" // for error codes
/*
An interface for presenting a tree view of an rdf datasource (or
database).
Any datasource can also support nsIRDFTree. The interface is purely
syntactic sugar for traversing simple tree where the child relation
corresponds to the property type nc:child (nc = http://home.netscape.com/NC-rdf#).
Each leaf is assumed to have a certain predefined set of properties
such as creationDate, size, lastModificationDate, lastVisitDate, etc.
This interface is substantially less general than nsIRDFDataSource,
but is adequate for bookmarks, the file system, history and a few
other very commonly used data sources.
*/
// {7D7EEBD1-AA41-11d2-80B7-006097B76B8E}
#define NS_IRDFTREE_IID \
{ 0x7d7eebd1, 0xaa41, 0x11d2, { 0x80, 0xb7, 0x0, 0x60, 0x97, 0xb7, 0x6b, 0x8e } };
class nsIRDFTree : public nsISupports {
public:
NS_IMETHOD ListChildren (nsIRDFResource* folder, nsVoidArray** result);
// XXX should define something called nsResourceArray and use that
NS_IMETHOD IsFolder (nsIRDFResource* node, PRBool* result);
NS_IMETHOD GetProperty (nsIRDFResource* node, nsIRDFResource* property,
nsIRDFNode** result);
}
#endif

View File

@@ -1,200 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
This interface encapsulates information about an RDF/XML file,
including the root resource, CSS style sheets, and named data
sources.
This file also includes an observer interface for nsIRDFXMLDataSource
objects.
*/
#ifndef nsIRDFXMLDataSource_h__
#define nsIRDFXMLDataSource_h__
#include "nsIRDFDataSource.h"
class nsIAtom;
class nsIOutputStream;
class nsIURL;
class nsString;
// {EB1A5D30-AB33-11d2-8EC6-00805F29F370}
#define NS_IRDFXMLDOCUMENTOBSERVER_IID \
{ 0xeb1a5d30, 0xab33, 0x11d2, { 0x8e, 0xc6, 0x0, 0x80, 0x5f, 0x29, 0xf3, 0x70 } }
class nsIRDFXMLDataSource;
class nsIRDFXMLDataSourceObserver : public nsISupports
{
public:
static const nsIID& GetIID() { static nsIID iid = NS_IRDFXMLDOCUMENTOBSERVER_IID; return iid; }
/**
* Called when the RDF/XML document begins to load.
*/
NS_IMETHOD OnBeginLoad(nsIRDFXMLDataSource* aStream) = 0;
/**
* Called when the RDF/XML document load is interrupted for some reason.
*/
NS_IMETHOD OnInterrupt(nsIRDFXMLDataSource* aStream) = 0;
/**
* Called when an interrupted RDF/XML document load is resumed.
*/
NS_IMETHOD OnResume(nsIRDFXMLDataSource* aStream) = 0;
/**
* Called whtn the RDF/XML document load is complete.
*/
NS_IMETHOD OnEndLoad(nsIRDFXMLDataSource* aStream) = 0;
/**
* Called when the root resource of the RDF/XML document is found
*/
NS_IMETHOD OnRootResourceFound(nsIRDFXMLDataSource* aStream, nsIRDFResource* aResource) = 0;
/**
* Called when a CSS style sheet is included (via XML processing
* instruction) to the document.
*/
NS_IMETHOD OnCSSStyleSheetAdded(nsIRDFXMLDataSource* aStream, nsIURL* aCSSStyleSheetURL) = 0;
/**
* Called when a named data source is included (via XML processing
* instruction) to the document.
*/
NS_IMETHOD OnNamedDataSourceAdded(nsIRDFXMLDataSource* aStream, const char* aNamedDataSourceURI) = 0;
};
// {EB1A5D31-AB33-11d2-8EC6-00805F29F370}
#define NS_IRDFXMLDATASOURCE_IID \
{ 0xeb1a5d31, 0xab33, 0x11d2, { 0x8e, 0xc6, 0x0, 0x80, 0x5f, 0x29, 0xf3, 0x70 } }
class nsIRDFXMLDataSource : public nsIRDFDataSource
{
public:
static const nsIID& GetIID() { static nsIID iid = NS_IRDFXMLDATASOURCE_IID; return iid; }
/**
* Sets the RDF/XML stream to load either synchronously or
* asynchronously when nsIRDFDataSource::Init() is called.
* By default, the stream will load <em>asynchronously</em>.
*/
NS_IMETHOD SetSynchronous(PRBool aIsSynchronous) = 0;
/**
* Sets the RDF/XML stream's read-only status. By default,
* the stream will be read/write if the URL on which
* nsIRDFDataSource::Init() is called is writable.
*/
NS_IMETHOD SetReadOnly(PRBool aIsReadOnly) = 0;
/**
* Notify the document that the load is beginning.
*/
NS_IMETHOD BeginLoad(void) = 0;
/**
* Notify the document that the load is being interrupted.
*/
NS_IMETHOD Interrupt(void) = 0;
/**
* Notify the document that an interrupted load is being resumed.
*/
NS_IMETHOD Resume(void) = 0;
/**
* Notify the document that the load is ending.
*/
NS_IMETHOD EndLoad(void) = 0;
/**
* Set the root resource for the document.
*/
NS_IMETHOD SetRootResource(nsIRDFResource* aResource) = 0;
/**
* Retrieve the root resource for the document.
*/
NS_IMETHOD GetRootResource(nsIRDFResource** aResource) = 0;
/**
* Add a CSS style sheet to the document.
* @param aStyleSheetURL An nsIURL object that is the URL of the style
* sheet to add to the document.
*/
NS_IMETHOD AddCSSStyleSheetURL(nsIURL* aStyleSheetURL) = 0;
/**
* Get the set of style sheets that have been included in the
* document.
* @param aStyleSheetURLs (out) A pointer to an array of pointers to nsIURL objects.
* @param aCount (out) The number of nsIURL objects returned.
*/
NS_IMETHOD GetCSSStyleSheetURLs(nsIURL*** aStyleSheetURLs, PRInt32* aCount) = 0;
/**
* Add a named data source to the document.
* @param aNamedDataSoruceURI A URI identifying the data source.
*/
NS_IMETHOD AddNamedDataSourceURI(const char* aNamedDataSourceURI) = 0;
/**
* Get the set of named data sources that have been included in
* the document
* @param aNamedDataSourceURIs (out) A pointer to an array of C-style character
* strings.
* @param aCount (out) The number of named data sources in the array.
*/
NS_IMETHOD GetNamedDataSourceURIs(const char* const** aNamedDataSourceURIs, PRInt32* aCount) = 0;
/**
* Add a new namespace declaration to the RDF/XML document.
*/
NS_IMETHOD AddNameSpace(nsIAtom* aPrefix, const nsString& aURI) = 0;
/**
* Add an observer to the document. The observer will be notified of
* RDF/XML events via the nsIRDFXMLDataSourceObserver interface. Note that
* the observer is <em>not</em> reference counted.
*/
NS_IMETHOD AddXMLStreamObserver(nsIRDFXMLDataSourceObserver* aObserver) = 0;
/**
* Remove an observer from the document.
*/
NS_IMETHOD RemoveXMLStreamObserver(nsIRDFXMLDataSourceObserver* aObserver) = 0;
};
// Two different kinds of XML data sources exist for RDF: serialized RDF and XUL.
// These are the methods that make these data sources.
extern nsresult
NS_NewRDFXMLDataSource(nsIRDFXMLDataSource** result);
extern nsresult
NS_NewXULDataSource(nsIRDFXMLDataSource** result);
#endif // nsIRDFXMLDataSource_h__

View File

@@ -1,165 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
This interface encapsulates information about an RDF/XML file,
including the root resource, CSS style sheets, and named data
sources.
This file also includes an observer interface for nsIRDFXMLDocument
objects.
*/
#ifndef nsIRDFXMLDocument_h__
#define nsIRDFXMLDocument_h__
#include "nsISupports.h"
class nsIOutputStream;
class nsIURL;
// {EB1A5D30-AB33-11d2-8EC6-00805F29F370}
#define NS_IRDFXMLDOCUMENTOBSERVER_IID \
{ 0xeb1a5d30, 0xab33, 0x11d2, { 0x8e, 0xc6, 0x0, 0x80, 0x5f, 0x29, 0xf3, 0x70 } }
class nsIRDFXMLDocumentObserver : public nsISupports
{
public:
/**
* Called when the RDF/XML document begins to load.
*/
NS_IMETHOD OnBeginLoad(void) = 0;
/**
* Called when the RDF/XML document load is interrupted for some reason.
*/
NS_IMETHOD OnInterrupt(void) = 0;
/**
* Called when an interrupted RDF/XML document load is resumed.
*/
NS_IMETHOD OnResume(void) = 0;
/**
* Called whtn the RDF/XML document load is complete.
*/
NS_IMETHOD OnEndLoad(void) = 0;
/**
* Called when the root resource of the RDF/XML document is found
*/
NS_IMETHOD OnRootResourceFound(nsIRDFResource* aResource) = 0;
/**
* Called when a CSS style sheet is included (via XML processing
* instruction) to the document.
*/
NS_IMETHOD OnCSSStyleSheetAdded(nsIURL* aCSSStyleSheetURL) = 0;
/**
* Called when a named data source is included (via XML processing
* instruction) to the document.
*/
NS_IMETHOD OnNamedDataSourceAdded(const char* aNamedDataSourceURI) = 0;
};
// {EB1A5D31-AB33-11d2-8EC6-00805F29F370}
#define NS_IRDFXMLDOCUMENT_IID \
{ 0xeb1a5d31, 0xab33, 0x11d2, { 0x8e, 0xc6, 0x0, 0x80, 0x5f, 0x29, 0xf3, 0x70 } }
class nsIRDFXMLDocument : public nsISupports
{
public:
/**
* Notify the document that the load is beginning.
*/
NS_IMETHOD BeginLoad(void) = 0;
/**
* Notify the document that the load is being interrupted.
*/
NS_IMETHOD Interrupt(void) = 0;
/**
* Notify the document that an interrupted load is being resumed.
*/
NS_IMETHOD Resume(void) = 0;
/**
* Notify the document that the load is ending.
*/
NS_IMETHOD EndLoad(void) = 0;
/**
* Set the root resource for the document.
*/
NS_IMETHOD SetRootResource(nsIRDFResource* aResource) = 0;
/**
* Retrieve the root resource for the document.
*/
NS_IMETHOD GetRootResource(nsIRDFResource** aResource) = 0;
/**
* Add a CSS style sheet to the document.
* @param aStyleSheetURL An nsIURL object that is the URL of the style
* sheet to add to the document.
*/
NS_IMETHOD AddCSSStyleSheetURL(nsIURL* aStyleSheetURL) = 0;
/**
* Get the set of style sheets that have been included in the
* document.
* @param aStyleSheetURLs (out) A pointer to an array of pointers to nsIURL objects.
* @param aCount (out) The number of nsIURL objects returned.
*/
NS_IMETHOD GetCSSStyleSheetURLs(nsIURL*** aStyleSheetURLs, PRInt32* aCount) = 0;
/**
* Add a named data source to the document.
* @param aNamedDataSoruceURI A URI identifying the data source.
*/
NS_IMETHOD AddNamedDataSourceURI(const char* aNamedDataSourceURI) = 0;
/**
* Get the set of named data sources that have been included in
* the document
* @param aNamedDataSourceURIs (out) A pointer to an array of C-style character
* strings.
* @param aCount (out) The number of named data sources in the array.
*/
NS_IMETHOD GetNamedDataSourceURIs(const char* const** aNamedDataSourceURIs, PRInt32* aCount) = 0;
/**
* Add an observer to the document. The observer will be notified of
* RDF/XML events via the nsIRDFXMLDocumentObserver interface. Note that
* the observer is <em>not</em> reference counted.
*/
NS_IMETHOD AddDocumentObserver(nsIRDFXMLDocumentObserver* aObserver) = 0;
/**
* Remove an observer from the document.
*/
NS_IMETHOD RemoveDocumentObserver(nsIRDFXMLDocumentObserver* aObserver) = 0;
};
#endif // nsIRDFXMLDocument_h__

View File

@@ -1,44 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
The RDF/XML source interface. An RDF/XML source is capable of
producing serialized RDF/XML to an output stream.
*/
#ifndef nsIRDFXMLSource_h__
#define nsIRDFXMLSource_h__
class nsIOutputStream;
// {4DA56F10-99FE-11d2-8EBB-00805F29F370}
#define NS_IRDFXMLSOURCE_IID \
{ 0x4da56f10, 0x99fe, 0x11d2, { 0x8e, 0xbb, 0x0, 0x80, 0x5f, 0x29, 0xf3, 0x70 } }
class nsIRDFXMLSource : public nsISupports
{
public:
static const nsIID& GetIID() { static nsIID iid = NS_IRDFXMLSOURCE_IID; return iid; }
NS_IMETHOD Serialize(nsIOutputStream* aStream) = 0;
};
#endif // nsIRDFXMLSource_h__

View File

@@ -1,400 +0,0 @@
/*
* DO NOT EDIT. THIS FILE IS GENERATED FROM nsRDFInterfaces.idl
*/
#ifndef __gen_nsRDFInterfaces_h__
#define __gen_nsRDFInterfaces_h__
#include "nsISupports.h" /* interface nsISupports */
#include "nsISupportsArray.h" /* interface nsISupportsArray */
#include "nsICollection.h" /* interface nsICollection */
#include "nsIEnumerator.h" /* interface nsIEnumerator */
#include "nsrootidl.h" /* interface nsrootidl */
#include "nsISimpleEnumerator.h" /* interface nsISimpleEnumerator */
#ifdef XPIDL_JS_STUBS
#include "jsapi.h"
#endif
#include "nscore.h" // for PRUnichar
/* starting interface: nsIRDFNode */
/* {0F78DA50-8321-11d2-8EAC-00805F29F370} */
#define NS_IRDFNODE_IID_STR "0F78DA50-8321-11d2-8EAC-00805F29F370"
#define NS_IRDFNODE_IID \
{0x0F78DA50, 0x8321, 0x11d2, \
{ 0x8E, 0xAC, 0x00, 0x80, 0x5F, 0x29, 0xF3, 0x70 }}
class nsIRDFNode : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IRDFNODE_IID)
/* boolean EqualsNode (in nsIRDFNode aNode); */
NS_IMETHOD EqualsNode(nsIRDFNode *aNode, PRBool *_retval) = 0;
#ifdef XPIDL_JS_STUBS
static NS_EXPORT_(JSObject *) InitJSClass(JSContext *cx);
static NS_EXPORT_(JSObject *) GetJSObject(JSContext *cx, nsIRDFNode *priv);
#endif
};
/* starting interface: nsIRDFResource */
/* {E0C493D1-9542-11d2-8EB8-00805F29F370} */
#define NS_IRDFRESOURCE_IID_STR "E0C493D1-9542-11d2-8EB8-00805F29F370"
#define NS_IRDFRESOURCE_IID \
{0xE0C493D1, 0x9542, 0x11d2, \
{ 0x8E, 0xB8, 0x00, 0x80, 0x5F, 0x29, 0xF3, 0x70 }}
class nsIRDFResource : public nsIRDFNode {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IRDFRESOURCE_IID)
/* readonly attribute string Value; */
NS_IMETHOD GetValue(char * *aValue) = 0;
/* void Init (in string uri); */
NS_IMETHOD Init(const char *uri) = 0;
/* boolean EqualsResource (in nsIRDFResource aResource); */
NS_IMETHOD EqualsResource(nsIRDFResource *aResource, PRBool *_retval) = 0;
/* boolean EqualsString (in string aURI); */
NS_IMETHOD EqualsString(const char *aURI, PRBool *_retval) = 0;
#ifdef XPIDL_JS_STUBS
static NS_EXPORT_(JSObject *) InitJSClass(JSContext *cx);
static NS_EXPORT_(JSObject *) GetJSObject(JSContext *cx, nsIRDFResource *priv);
#endif
};
/* starting interface: nsIRDFLiteral */
/* {E0C493D2-9542-11d2-8EB8-00805F29F370} */
#define NS_IRDFLITERAL_IID_STR "E0C493D2-9542-11d2-8EB8-00805F29F370"
#define NS_IRDFLITERAL_IID \
{0xE0C493D2, 0x9542, 0x11d2, \
{ 0x8E, 0xB8, 0x00, 0x80, 0x5F, 0x29, 0xF3, 0x70 }}
class nsIRDFLiteral : public nsIRDFNode {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IRDFLITERAL_IID)
/* readonly attribute wstring Value; */
NS_IMETHOD GetValue(PRUnichar * *aValue) = 0;
/* boolean EqualsLiteral (in nsIRDFLiteral aLiteral); */
NS_IMETHOD EqualsLiteral(nsIRDFLiteral *aLiteral, PRBool *_retval) = 0;
#ifdef XPIDL_JS_STUBS
static NS_EXPORT_(JSObject *) InitJSClass(JSContext *cx);
static NS_EXPORT_(JSObject *) GetJSObject(JSContext *cx, nsIRDFLiteral *priv);
#endif
};
/* starting interface: nsIRDFDate */
/* {E13A24E1-C77A-11d2-80BE-006097B76B8E} */
#define NS_IRDFDATE_IID_STR "E13A24E1-C77A-11d2-80BE-006097B76B8E"
#define NS_IRDFDATE_IID \
{0xE13A24E1, 0xC77A, 0x11d2, \
{ 0x80, 0xBE, 0x00, 0x60, 0x97, 0xB7, 0x6B, 0x8E }}
class nsIRDFDate : public nsIRDFNode {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IRDFDATE_IID)
/* readonly attribute long long Value; */
NS_IMETHOD GetValue(PRInt64 *aValue) = 0;
/* boolean EqualsDate (in nsIRDFDate aDate); */
NS_IMETHOD EqualsDate(nsIRDFDate *aDate, PRBool *_retval) = 0;
#ifdef XPIDL_JS_STUBS
static NS_EXPORT_(JSObject *) InitJSClass(JSContext *cx);
static NS_EXPORT_(JSObject *) GetJSObject(JSContext *cx, nsIRDFDate *priv);
#endif
};
/* starting interface: nsIRDFInt */
/* {E13A24E3-C77A-11d2-80BE-006097B76B8E} */
#define NS_IRDFINT_IID_STR "E13A24E3-C77A-11d2-80BE-006097B76B8E"
#define NS_IRDFINT_IID \
{0xE13A24E3, 0xC77A, 0x11d2, \
{ 0x80, 0xBE, 0x00, 0x60, 0x97, 0xB7, 0x6B, 0x8E }}
class nsIRDFInt : public nsIRDFNode {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IRDFINT_IID)
/* readonly attribute long Value; */
NS_IMETHOD GetValue(PRInt32 *aValue) = 0;
/* boolean EqualsInt (in nsIRDFInt aInt); */
NS_IMETHOD EqualsInt(nsIRDFInt *aInt, PRBool *_retval) = 0;
#ifdef XPIDL_JS_STUBS
static NS_EXPORT_(JSObject *) InitJSClass(JSContext *cx);
static NS_EXPORT_(JSObject *) GetJSObject(JSContext *cx, nsIRDFInt *priv);
#endif
};
class nsIRDFDataSource; /* forward decl */
/* starting interface: nsIRDFObserver */
/* {3CC75360-484A-11D2-BC16-00805F912FE7} */
#define NS_IRDFOBSERVER_IID_STR "3CC75360-484A-11D2-BC16-00805F912FE7"
#define NS_IRDFOBSERVER_IID \
{0x3CC75360, 0x484A, 0x11D2, \
{ 0xBC, 0x16, 0x00, 0x80, 0x5F, 0x91, 0x2F, 0xE7 }}
class nsIRDFObserver : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IRDFOBSERVER_IID)
/* void OnAssert (in nsIRDFResource aSource, in nsIRDFResource aLabel, in nsIRDFNode aTarget); */
NS_IMETHOD OnAssert(nsIRDFResource *aSource, nsIRDFResource *aLabel, nsIRDFNode *aTarget) = 0;
/* void OnUnassert (in nsIRDFResource aSource, in nsIRDFResource aLabel, in nsIRDFNode aTarget); */
NS_IMETHOD OnUnassert(nsIRDFResource *aSource, nsIRDFResource *aLabel, nsIRDFNode *aTarget) = 0;
#ifdef XPIDL_JS_STUBS
static NS_EXPORT_(JSObject *) InitJSClass(JSContext *cx);
static NS_EXPORT_(JSObject *) GetJSObject(JSContext *cx, nsIRDFObserver *priv);
#endif
};
/* starting interface: nsIRDFDataSource */
/* {0F78DA58-8321-11d2-8EAC-00805F29F370} */
#define NS_IRDFDATASOURCE_IID_STR "0F78DA58-8321-11d2-8EAC-00805F29F370"
#define NS_IRDFDATASOURCE_IID \
{0x0F78DA58, 0x8321, 0x11d2, \
{ 0x8E, 0xAC, 0x00, 0x80, 0x5F, 0x29, 0xF3, 0x70 }}
class nsIRDFDataSource : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IRDFDATASOURCE_IID)
/* void Init (in string uri); */
NS_IMETHOD Init(const char *uri) = 0;
/* readonly attribute string URI; */
NS_IMETHOD GetURI(char * *aURI) = 0;
/* nsIRDFResource GetSource (in nsIRDFResource aProperty, in nsIRDFNode aTarget, in boolean aTruthValue); */
NS_IMETHOD GetSource(nsIRDFResource *aProperty, nsIRDFNode *aTarget, PRBool aTruthValue, nsIRDFResource **_retval) = 0;
/* nsISimpleEnumerator GetSources (in nsIRDFResource aProperty, in nsIRDFNode aTarget, in boolean aTruthValue); */
NS_IMETHOD GetSources(nsIRDFResource *aProperty, nsIRDFNode *aTarget, PRBool aTruthValue, nsISimpleEnumerator **_retval) = 0;
/* nsIRDFNode GetTarget (in nsIRDFResource aSource, in nsIRDFResource aProperty, in boolean aTruthValue); */
NS_IMETHOD GetTarget(nsIRDFResource *aSource, nsIRDFResource *aProperty, PRBool aTruthValue, nsIRDFNode **_retval) = 0;
/* nsISimpleEnumerator GetTargets (in nsIRDFResource aSource, in nsIRDFResource aProperty, in boolean aTruthValue); */
NS_IMETHOD GetTargets(nsIRDFResource *aSource, nsIRDFResource *aProperty, PRBool aTruthValue, nsISimpleEnumerator **_retval) = 0;
/* void Assert (in nsIRDFResource aSource, in nsIRDFResource aProperty, in nsIRDFNode aTarget, in boolean aTruthValue); */
NS_IMETHOD Assert(nsIRDFResource *aSource, nsIRDFResource *aProperty, nsIRDFNode *aTarget, PRBool aTruthValue) = 0;
/* void Unassert (in nsIRDFResource aSource, in nsIRDFResource aProperty, in nsIRDFNode aTarget); */
NS_IMETHOD Unassert(nsIRDFResource *aSource, nsIRDFResource *aProperty, nsIRDFNode *aTarget) = 0;
/* boolean HasAssertion (in nsIRDFResource aSource, in nsIRDFResource aProperty, in nsIRDFNode aTarget, in boolean aTruthValue); */
NS_IMETHOD HasAssertion(nsIRDFResource *aSource, nsIRDFResource *aProperty, nsIRDFNode *aTarget, PRBool aTruthValue, PRBool *_retval) = 0;
/* void AddObserver (in nsIRDFObserver aObserver); */
NS_IMETHOD AddObserver(nsIRDFObserver *aObserver) = 0;
/* void RemoveObserver (in nsIRDFObserver aObserver); */
NS_IMETHOD RemoveObserver(nsIRDFObserver *aObserver) = 0;
/* nsISimpleEnumerator ArcLabelsIn (in nsIRDFNode aNode); */
NS_IMETHOD ArcLabelsIn(nsIRDFNode *aNode, nsISimpleEnumerator **_retval) = 0;
/* nsISimpleEnumerator ArcLabelsOut (in nsIRDFResource aSource); */
NS_IMETHOD ArcLabelsOut(nsIRDFResource *aSource, nsISimpleEnumerator **_retval) = 0;
/* nsISimpleEnumerator GetAllResources (); */
NS_IMETHOD GetAllResources(nsISimpleEnumerator **_retval) = 0;
/* void Flush (); */
NS_IMETHOD Flush() = 0;
/* nsIEnumerator GetAllCommands (in nsIRDFResource aSource); */
NS_IMETHOD GetAllCommands(nsIRDFResource *aSource, nsIEnumerator **_retval) = 0;
/* boolean IsCommandEnabled (in nsISupportsArray aSources, in nsIRDFResource aCommand, in nsISupportsArray aArguments); */
NS_IMETHOD IsCommandEnabled(nsISupportsArray *aSources, nsIRDFResource *aCommand, nsISupportsArray *aArguments, PRBool *_retval) = 0;
/* void DoCommand (in nsISupportsArray aSources, in nsIRDFResource aCommand, in nsISupportsArray aArguments); */
NS_IMETHOD DoCommand(nsISupportsArray *aSources, nsIRDFResource *aCommand, nsISupportsArray *aArguments) = 0;
#ifdef XPIDL_JS_STUBS
static NS_EXPORT_(JSObject *) InitJSClass(JSContext *cx);
static NS_EXPORT_(JSObject *) GetJSObject(JSContext *cx, nsIRDFDataSource *priv);
#endif
};
/* starting interface: nsIRDFCompositeDataSource */
/* {96343820-307C-11D2-BC15-00805F912FE7} */
#define NS_IRDFCOMPOSITEDATASOURCE_IID_STR "96343820-307C-11D2-BC15-00805F912FE7"
#define NS_IRDFCOMPOSITEDATASOURCE_IID \
{0x96343820, 0x307C, 0x11D2, \
{ 0xBC, 0x15, 0x00, 0x80, 0x5F, 0x91, 0x2F, 0xE7 }}
class nsIRDFCompositeDataSource : public nsIRDFDataSource {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IRDFCOMPOSITEDATASOURCE_IID)
/* void AddDataSource (in nsIRDFDataSource aDataSource); */
NS_IMETHOD AddDataSource(nsIRDFDataSource *aDataSource) = 0;
/* void RemoveDataSource (in nsIRDFDataSource aDataSource); */
NS_IMETHOD RemoveDataSource(nsIRDFDataSource *aDataSource) = 0;
#ifdef XPIDL_JS_STUBS
static NS_EXPORT_(JSObject *) InitJSClass(JSContext *cx);
static NS_EXPORT_(JSObject *) GetJSObject(JSContext *cx, nsIRDFCompositeDataSource *priv);
#endif
};
/* starting interface: nsIRDFService */
/* {BFD05261-834C-11d2-8EAC-00805F29F370} */
#define NS_IRDFSERVICE_IID_STR "BFD05261-834C-11d2-8EAC-00805F29F370"
#define NS_IRDFSERVICE_IID \
{0xBFD05261, 0x834C, 0x11d2, \
{ 0x8E, 0xAC, 0x00, 0x80, 0x5F, 0x29, 0xF3, 0x70 }}
class nsIRDFService : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IRDFSERVICE_IID)
/* nsIRDFResource GetResource (in string aURI); */
NS_IMETHOD GetResource(const char *aURI, nsIRDFResource **_retval) = 0;
/* nsIRDFResource GetUnicodeResource (in wstring aURI); */
NS_IMETHOD GetUnicodeResource(const PRUnichar *aURI, nsIRDFResource **_retval) = 0;
/* nsIRDFLiteral GetLiteral (in wstring aValue); */
NS_IMETHOD GetLiteral(const PRUnichar *aValue, nsIRDFLiteral **_retval) = 0;
/* nsIRDFDate GetDateLiteral (in long long aValue); */
NS_IMETHOD GetDateLiteral(PRInt64 aValue, nsIRDFDate **_retval) = 0;
/* nsIRDFInt GetIntLiteral (in long aValue); */
NS_IMETHOD GetIntLiteral(PRInt32 aValue, nsIRDFInt **_retval) = 0;
/* void RegisterResource (in nsIRDFResource aResource, in boolean aReplace); */
NS_IMETHOD RegisterResource(nsIRDFResource *aResource, PRBool aReplace) = 0;
/* void UnregisterResource (in nsIRDFResource aResource); */
NS_IMETHOD UnregisterResource(nsIRDFResource *aResource) = 0;
/* void RegisterDataSource (in nsIRDFDataSource aDataSource, in boolean aReplace); */
NS_IMETHOD RegisterDataSource(nsIRDFDataSource *aDataSource, PRBool aReplace) = 0;
/* void UnregisterDataSource (in nsIRDFDataSource aDataSource); */
NS_IMETHOD UnregisterDataSource(nsIRDFDataSource *aDataSource) = 0;
/* nsIRDFDataSource GetDataSource (in string aURI); */
NS_IMETHOD GetDataSource(const char *aURI, nsIRDFDataSource **_retval) = 0;
#ifdef XPIDL_JS_STUBS
static NS_EXPORT_(JSObject *) InitJSClass(JSContext *cx);
static NS_EXPORT_(JSObject *) GetJSObject(JSContext *cx, nsIRDFService *priv);
#endif
};
/* starting interface: nsIRDFContainer */
/* {D4214E90-FB94-11D2-BDD8-00104BDE6048} */
#define NS_IRDFCONTAINER_IID_STR "D4214E90-FB94-11D2-BDD8-00104BDE6048"
#define NS_IRDFCONTAINER_IID \
{0xD4214E90, 0xFB94, 0x11D2, \
{ 0xBD, 0xD8, 0x00, 0x10, 0x4B, 0xDE, 0x60, 0x48 }}
class nsIRDFContainer : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IRDFCONTAINER_IID)
/* void Init (in nsIRDFDataSource aDataSource, in nsIRDFResource aContainer); */
NS_IMETHOD Init(nsIRDFDataSource *aDataSource, nsIRDFResource *aContainer) = 0;
/* long GetCount (); */
NS_IMETHOD GetCount(PRInt32 *_retval) = 0;
/* nsISimpleEnumerator GetElements (); */
NS_IMETHOD GetElements(nsISimpleEnumerator **_retval) = 0;
/* void AppendElement (in nsIRDFNode aElement); */
NS_IMETHOD AppendElement(nsIRDFNode *aElement) = 0;
/* void RemoveElement (in nsIRDFNode aElement, in boolean aRenumber); */
NS_IMETHOD RemoveElement(nsIRDFNode *aElement, PRBool aRenumber) = 0;
/* void InsertElementAt (in nsIRDFNode aElement, in long aIndex, in boolean aRenumber); */
NS_IMETHOD InsertElementAt(nsIRDFNode *aElement, PRInt32 aIndex, PRBool aRenumber) = 0;
/* long IndexOf (in nsIRDFNode aElement); */
NS_IMETHOD IndexOf(nsIRDFNode *aElement, PRInt32 *_retval) = 0;
#ifdef XPIDL_JS_STUBS
static NS_EXPORT_(JSObject *) InitJSClass(JSContext *cx);
static NS_EXPORT_(JSObject *) GetJSObject(JSContext *cx, nsIRDFContainer *priv);
#endif
};
/* starting interface: nsIRDFContainerUtils */
/* {D4214E91-FB94-11D2-BDD8-00104BDE6048} */
#define NS_IRDFCONTAINERUTILS_IID_STR "D4214E91-FB94-11D2-BDD8-00104BDE6048"
#define NS_IRDFCONTAINERUTILS_IID \
{0xD4214E91, 0xFB94, 0x11D2, \
{ 0xBD, 0xD8, 0x00, 0x10, 0x4B, 0xDE, 0x60, 0x48 }}
class nsIRDFContainerUtils : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IRDFCONTAINERUTILS_IID)
/* boolean IsOrdinalProperty (in nsIRDFResource aProperty); */
NS_IMETHOD IsOrdinalProperty(nsIRDFResource *aProperty, PRBool *_retval) = 0;
/* nsIRDFResource IndexToOrdinalResource (in long aIndex); */
NS_IMETHOD IndexToOrdinalResource(PRInt32 aIndex, nsIRDFResource **_retval) = 0;
/* long OrdinalResourceToIndex (in nsIRDFResource aOrdinal); */
NS_IMETHOD OrdinalResourceToIndex(nsIRDFResource *aOrdinal, PRInt32 *_retval) = 0;
/* boolean IsContainer (in nsIRDFDataSource aDataSource, in nsIRDFResource aResource); */
NS_IMETHOD IsContainer(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, PRBool *_retval) = 0;
/* boolean IsBag (in nsIRDFDataSource aDataSource, in nsIRDFResource aResource); */
NS_IMETHOD IsBag(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, PRBool *_retval) = 0;
/* boolean IsSeq (in nsIRDFDataSource aDataSource, in nsIRDFResource aResource); */
NS_IMETHOD IsSeq(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, PRBool *_retval) = 0;
/* boolean IsAlt (in nsIRDFDataSource aDataSource, in nsIRDFResource aResource); */
NS_IMETHOD IsAlt(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, PRBool *_retval) = 0;
/* nsIRDFContainer MakeBag (in nsIRDFDataSource aDataSource, in nsIRDFResource aResource); */
NS_IMETHOD MakeBag(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, nsIRDFContainer **_retval) = 0;
/* nsIRDFContainer MakeSeq (in nsIRDFDataSource aDataSource, in nsIRDFResource aResource); */
NS_IMETHOD MakeSeq(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, nsIRDFContainer **_retval) = 0;
/* nsIRDFContainer MakeAlt (in nsIRDFDataSource aDataSource, in nsIRDFResource aResource); */
NS_IMETHOD MakeAlt(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, nsIRDFContainer **_retval) = 0;
#ifdef XPIDL_JS_STUBS
static NS_EXPORT_(JSObject *) InitJSClass(JSContext *cx);
static NS_EXPORT_(JSObject *) GetJSObject(JSContext *cx, nsIRDFContainerUtils *priv);
#endif
};
#endif /* __gen_nsRDFInterfaces_h__ */

View File

@@ -1,105 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
A catch-all header file for miscellaneous RDF stuff. Currently
contains error codes and vocabulary macros.
*/
#ifndef rdf_h___
#define rdf_h___
#include "nsError.h"
/**
* The following macros are to aid in vocabulary definition. They
* creates const char*'s for "kURI[prefix]_[name]", appropriate
* complete namespace qualification on the URI, e.g.,
*
* #define RDF_NAMESPACE_URI "http://www.w3.org/TR/WD-rdf-syntax#"
* DEFINE_RDF_ELEMENT(RDF_NAMESPACE_URI, RDF, ID);
*
* will define:
*
* kURIRDF_ID to be "http://www.w3.org/TR/WD-rdf-syntax#ID"
*/
#define DEFINE_RDF_VOCAB(ns, prefix, name) \
static const char* kURI##prefix##_##name = ns #name
/**
* Core RDF vocabularies that we use to define semantics
*/
#define RDF_NAMESPACE_URI "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
#define WEB_NAMESPACE_URI "http://home.netscape.com/WEB-rdf#"
#define NC_NAMESPACE_URI "http://home.netscape.com/NC-rdf#"
/**
* @name Standard RDF error codes
*/
/*@{*/
/* Returned from nsIRDFCursor::Advance() if the cursor has no more
elements to enuemrate */
#define NS_RDF_CURSOR_EMPTY NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_RDF, 1)
/* Returned from nsIRDFDataSource::GetSource() and GetTarget() if the source/target
has no value */
#define NS_RDF_NO_VALUE NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_RDF, 2)
/* Returned from nsIRDFDataSource::Assert() and Unassert() if the assertion (or
unassertion was accepted by the datasource*/
#define NS_RDF_ASSERTION_ACCEPTED NS_OK
/* Returned from nsIRDFDataSource::Assert() and Unassert() if the assertion (or
unassertion) was rejected by the datasource; i.e., the datasource was not
willing to record the statement. */
#define NS_RDF_ASSERTION_REJECTED NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_RDF, 3)
/* ProgID prefixes for RDF DLL registration. */
#define NS_RDF_PROGID "component://netscape/rdf"
#define NS_RDF_DATASOURCE_PROGID NS_RDF_PROGID "/datasource"
#define NS_RDF_DATASOURCE_PROGID_PREFIX NS_RDF_DATASOURCE_PROGID "?name="
#define NS_RDF_RESOURCE_FACTORY_PROGID "component://netscape/rdf/resource-factory"
#define NS_RDF_RESOURCE_FACTORY_PROGID_PREFIX NS_RDF_RESOURCE_FACTORY_PROGID "?name="
/*@}*/
#ifdef _IMPL_NS_RDF
#ifdef XP_PC
#define NS_RDF _declspec(dllexport)
#else /* !XP_PC */
#define NS_RDF
#endif /* !XP_PC */
#else /* !_IMPL_NS_RDF */
#ifdef XP_PC
#define NS_RDF _declspec(dllimport)
#else /* !XP_PC */
#define NS_RDF
#endif /* !XP_PC */
#endif /* !_IMPL_NS_RDF */
#endif /* rdf_h___ */

View File

@@ -1,60 +0,0 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH=../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/config.mk
LIBRARY_NAME = rdfbase_s
CPPSRCS = \
nsCompositeDataSource.cpp \
nsContainerEnumerator.cpp \
nsDefaultResourceFactory.cpp \
nsInMemoryDataSource.cpp \
nsRDFContentSink.cpp \
nsRDFContainer.cpp \
nsRDFContainerUtils.cpp \
nsRDFParserUtils.cpp \
nsRDFService.cpp \
nsRDFXMLDataSource.cpp \
rdfutil.cpp \
$(NULL)
EXPORTS = \
$(NULL)
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
MODULE = rdfbase
REQUIRES = netlib rdf rdfutil raptor xpcom
MKSHLIB :=
# we don't want the shared lib, but we want to force the creation of a static lib.
override NO_SHARED_LIB=1
override NO_STATIC_LIB=
include $(topsrcdir)/config/rules.mk

View File

@@ -1,53 +0,0 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH=..\..\..
LCFLAGS=
MODULE=rdf
LIBRARY_NAME=rdfbase_s
CPP_OBJS=\
.\$(OBJDIR)\nsCompositeDataSource.obj \
.\$(OBJDIR)\nsContainerEnumerator.obj \
.\$(OBJDIR)\nsDefaultResourceFactory.obj \
.\$(OBJDIR)\nsInMemoryDataSource.obj \
.\$(OBJDIR)\nsRDFContentSink.obj \
.\$(OBJDIR)\nsRDFContainer.obj \
.\$(OBJDIR)\nsRDFContainerUtils.obj \
.\$(OBJDIR)\nsRDFParserUtils.obj \
.\$(OBJDIR)\nsRDFService.obj \
.\$(OBJDIR)\nsRDFXMLDataSource.obj \
.\$(OBJDIR)\rdfutil.obj \
$(NULL)
LINCS= -I$(PUBLIC)\rdf \
-I$(PUBLIC)\rdfutil \
-I$(PUBLIC)\xpcom \
-I$(PUBLIC)\raptor \
-I$(PUBLIC)\netlib \
-I$(PUBLIC)\js \
$(NULL)
include <$(DEPTH)\config\rules.mak>
libs:: $(LIBRARY)
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
clobber::
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib

File diff suppressed because it is too large Load Diff

View File

@@ -1,256 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
A simple cursor that enumerates the elements of an RDF container
(RDF:Bag, RDF:Seq, or RDF:Alt).
Caveats
-------
1. This uses an implementation-specific detail to determine the
index of the last element in the container; specifically, the RDF
utilities maintain a counter attribute on the container that
holds the numeric value of the next value that is to be
assigned. So, this cursor will bust if you use it with a bag that
hasn't been created using the RDF utility routines.
*/
#include "nscore.h"
#include "nsCOMPtr.h"
#include "nsIRDFDataSource.h"
#include "nsIRDFNode.h"
#include "nsIRDFService.h"
#include "nsIServiceManager.h"
#include "nsRDFCID.h"
#include "nsString.h"
#include "nsXPIDLString.h"
#include "prlog.h"
#include "rdf.h"
#include "rdfutil.h"
////////////////////////////////////////////////////////////////////////
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
static NS_DEFINE_CID(kRDFContainerUtilsCID, NS_RDFCONTAINERUTILS_CID);
////////////////////////////////////////////////////////////////////////
class ContainerEnumeratorImpl : public nsISimpleEnumerator {
private:
// pseudo-constants
static nsrefcnt gRefCnt;
static nsIRDFResource* kRDF_nextVal;
nsCOMPtr<nsIRDFDataSource> mDataSource;
nsCOMPtr<nsIRDFResource> mContainer;
nsCOMPtr<nsIRDFResource> mOrdinalProperty;
nsISimpleEnumerator* mCurrent;
nsIRDFNode* mResult;
PRInt32 mNextIndex;
public:
ContainerEnumeratorImpl(nsIRDFDataSource* ds, nsIRDFResource* container);
virtual ~ContainerEnumeratorImpl(void);
NS_DECL_ISUPPORTS
NS_IMETHOD HasMoreElements(PRBool* aResult);
NS_IMETHOD GetNext(nsISupports** aResult);
};
nsrefcnt ContainerEnumeratorImpl::gRefCnt;
nsIRDFResource* ContainerEnumeratorImpl::kRDF_nextVal;
ContainerEnumeratorImpl::ContainerEnumeratorImpl(nsIRDFDataSource* aDataSource,
nsIRDFResource* aContainer)
: mCurrent(nsnull),
mResult(nsnull),
mNextIndex(1)
{
NS_INIT_REFCNT();
mDataSource = dont_QueryInterface(aDataSource);
mContainer = dont_QueryInterface(aContainer);
if (gRefCnt++ == 0) {
nsresult rv;
nsIRDFService* service;
rv = nsServiceManager::GetService(kRDFServiceCID,
nsIRDFService::GetIID(),
(nsISupports**) &service);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to acquire resource manager");
if (! service)
return;
rv = service->GetResource(RDF_NAMESPACE_URI "nextVal", &kRDF_nextVal);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get resource");
}
}
ContainerEnumeratorImpl::~ContainerEnumeratorImpl(void)
{
NS_IF_RELEASE(mResult);
NS_IF_RELEASE(mCurrent);
if (--gRefCnt == 0) {
NS_IF_RELEASE(kRDF_nextVal);
}
}
NS_IMPL_ISUPPORTS(ContainerEnumeratorImpl, nsISimpleEnumerator::GetIID());
NS_IMETHODIMP
ContainerEnumeratorImpl::HasMoreElements(PRBool* aResult)
{
NS_PRECONDITION(aResult != nsnull, "null ptr");
if (! aResult)
return NS_ERROR_NULL_POINTER;
nsresult rv;
// If we've already queued up a next value, then we know there are more elements.
if (mResult) {
*aResult = PR_TRUE;
return NS_OK;
}
// Otherwise, we need to grovel
// Figure out the upper bound so we'll know when we're done.
nsCOMPtr<nsIRDFNode> nextValNode;
rv = mDataSource->GetTarget(mContainer, kRDF_nextVal, PR_TRUE, getter_AddRefs(nextValNode));
if (NS_FAILED(rv)) return rv;
if (rv != NS_OK)
return NS_ERROR_UNEXPECTED;
nsCOMPtr<nsIRDFLiteral> nextVal = do_QueryInterface(nextValNode);
if (! nextVal)
return NS_ERROR_UNEXPECTED;
nsXPIDLString nextValStr;
rv = nextVal->GetValue(getter_Copies(nextValStr));
if (NS_FAILED(rv)) return rv;
PRInt32 err;
PRInt32 count = nsAutoString(nextValStr).ToInteger(&err);
if (NS_FAILED(err))
return NS_ERROR_UNEXPECTED;
// Now iterate through each index.
while (mNextIndex < count) {
if (! mCurrent) {
NS_WITH_SERVICE(nsIRDFContainerUtils, rdfc, kRDFContainerUtilsCID, &rv);
if (NS_FAILED(rv)) return rv;
rv = rdfc->IndexToOrdinalResource(mNextIndex, getter_AddRefs(mOrdinalProperty));
if (NS_FAILED(rv)) return rv;
rv = mDataSource->GetTargets(mContainer, mOrdinalProperty, PR_TRUE, &mCurrent);
if (NS_FAILED(rv)) return rv;
++mNextIndex;
}
do {
PRBool hasMore;
rv = mCurrent->HasMoreElements(&hasMore);
if (NS_FAILED(rv)) return rv;
// Is the current enumerator depleted?
if (! hasMore) {
NS_RELEASE(mCurrent);
break;
}
// "Peek" ahead and pull out the next target.
nsCOMPtr<nsISupports> result;
rv = mCurrent->GetNext(getter_AddRefs(result));
if (NS_FAILED(rv)) return rv;
rv = result->QueryInterface(nsIRDFNode::GetIID(), (void**) &mResult);
if (NS_FAILED(rv)) return rv;
*aResult = PR_TRUE;
return NS_OK;
} while (1);
}
// If we get here, we ran out of elements. The cursor is empty.
*aResult = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
ContainerEnumeratorImpl::GetNext(nsISupports** aResult)
{
nsresult rv;
PRBool hasMore;
rv = HasMoreElements(&hasMore);
if (NS_FAILED(rv)) return rv;
if (! hasMore)
return NS_ERROR_UNEXPECTED;
// Don't AddRef: we "transfer" ownership to the caller
*aResult = mResult;
mResult = nsnull;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
nsresult
NS_NewContainerEnumerator(nsIRDFDataSource* aDataSource,
nsIRDFResource* aContainer,
nsISimpleEnumerator** aResult)
{
NS_PRECONDITION(aDataSource != nsnull, "null ptr");
if (! aDataSource)
return NS_ERROR_NULL_POINTER;
NS_PRECONDITION(aContainer != nsnull, "null ptr");
if (! aContainer)
return NS_ERROR_NULL_POINTER;
NS_PRECONDITION(aResult != nsnull, "null ptr");
if (! aResult)
return NS_ERROR_NULL_POINTER;
ContainerEnumeratorImpl* result = new ContainerEnumeratorImpl(aDataSource, aContainer);
if (! result)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(result);
*aResult = result;
return NS_OK;
}

View File

@@ -1,43 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
The default resource factory implementation. This resource factory
produces nsIRDFResource objects for any URI prefix that is not
covered by some other factory.
*/
#include "nsRDFResource.h"
nsresult
NS_NewDefaultResource(nsIRDFResource** aResult)
{
NS_PRECONDITION(aResult != nsnull, "null ptr");
if (! aResult)
return NS_ERROR_NULL_POINTER;
nsRDFResource* resource = new nsRDFResource();
if (! resource)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(resource);
*aResult = resource;
return NS_OK;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,40 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
This header file just contains prototypes for the factory methods
for "builtin" data sources that are included in rdf.dll.
Each of these data sources is exposed to the external world via its
CID in ../include/nsRDFCID.h.
*/
#ifndef nsBaseDataSources_h__
#define nsBaseDataSources_h__
#include "nsError.h"
class nsIRDFDataSource;
// in nsInMemoryDataSource.cpp
nsresult NS_NewRDFInMemoryDataSource(nsIRDFDataSource** result);
#endif // nsBaseDataSources_h__

View File

@@ -1,556 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
/*
Implementation for the RDF container.
*/
#include "nsCOMPtr.h"
#include "nsIRDFContainer.h"
#include "nsIRDFService.h"
#include "nsIServiceManager.h"
#include "nsRDFCID.h"
#include "nsString.h"
#include "nsXPIDLString.h"
#include "rdf.h"
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
static NS_DEFINE_CID(kRDFContainerUtilsCID, NS_RDFCONTAINERUTILS_CID);
static const char kRDFNameSpaceURI[] = RDF_NAMESPACE_URI;
class RDFContainerImpl : public nsIRDFContainer
{
public:
// nsISupports interface
NS_DECL_ISUPPORTS
// nsIRDFContainer interface
NS_IMETHOD Init(nsIRDFDataSource *aDataSource, nsIRDFResource *aContainer);
NS_IMETHOD GetCount(PRInt32 *_retval);
NS_IMETHOD GetElements(nsISimpleEnumerator **_retval);
NS_IMETHOD AppendElement(nsIRDFNode *aElement);
NS_IMETHOD RemoveElement(nsIRDFNode *aElement, PRBool aRenumber);
NS_IMETHOD InsertElementAt(nsIRDFNode *aElement, PRInt32 aIndex, PRBool aRenumber);
NS_IMETHOD IndexOf(nsIRDFNode *aElement, PRInt32 *_retval);
private:
friend nsresult NS_NewRDFContainer(nsIRDFContainer** aResult);
RDFContainerImpl();
virtual ~RDFContainerImpl();
nsresult Renumber(PRInt32 aStartIndex);
nsresult SetNextValue(PRInt32 aIndex);
nsresult GetNextValue(nsIRDFResource** aResult);
nsIRDFDataSource* mDataSource;
nsIRDFResource* mContainer;
// pseudo constants
static PRInt32 gRefCnt;
static nsIRDFService* gRDFService;
static nsIRDFContainerUtils* gRDFContainerUtils;
static nsIRDFResource* kRDF_nextVal;
};
PRInt32 RDFContainerImpl::gRefCnt = 0;
nsIRDFService* RDFContainerImpl::gRDFService;
nsIRDFContainerUtils* RDFContainerImpl::gRDFContainerUtils;
nsIRDFResource* RDFContainerImpl::kRDF_nextVal;
////////////////////////////////////////////////////////////////////////
// nsISupports interface
NS_IMPL_ISUPPORTS(RDFContainerImpl, nsIRDFContainer::GetIID());
////////////////////////////////////////////////////////////////////////
// nsIRDFContainer interface
NS_IMETHODIMP
RDFContainerImpl::Init(nsIRDFDataSource *aDataSource, nsIRDFResource *aContainer)
{
NS_PRECONDITION(aDataSource != nsnull, "null ptr");
if (! aDataSource)
return NS_ERROR_NULL_POINTER;
NS_PRECONDITION(aContainer != nsnull, "null ptr");
if (! aContainer)
return NS_ERROR_NULL_POINTER;
NS_IF_RELEASE(mDataSource);
mDataSource = aDataSource;
NS_ADDREF(mDataSource);
NS_IF_RELEASE(mContainer);
mContainer = aContainer;
NS_ADDREF(mContainer);
return NS_OK;
}
NS_IMETHODIMP
RDFContainerImpl::GetCount(PRInt32 *aCount)
{
NS_PRECONDITION(aCount != nsnull, "null ptr");
if (! aCount)
return NS_ERROR_NULL_POINTER;
nsresult rv;
// Get the next value, which hangs off of the bag via the
// RDF:nextVal property.
nsCOMPtr<nsIRDFNode> nextValNode;
rv = mDataSource->GetTarget(mContainer, kRDF_nextVal, PR_TRUE, getter_AddRefs(nextValNode));
if (NS_FAILED(rv)) return rv;
if (rv == NS_RDF_NO_VALUE)
return NS_ERROR_UNEXPECTED;
nsCOMPtr<nsIRDFLiteral> nextValLiteral;
rv = nextValNode->QueryInterface(nsIRDFLiteral::GetIID(), getter_AddRefs(nextValLiteral));
if (NS_FAILED(rv)) return rv;
nsXPIDLString s;
rv = nextValLiteral->GetValue( getter_Copies(s) );
if (NS_FAILED(rv)) return rv;
nsAutoString nextValStr = (const PRUnichar*) s;
PRInt32 err;
*aCount = nextValStr.ToInteger(&err);
if (NS_FAILED(err))
return NS_ERROR_UNEXPECTED;
return NS_OK;
}
NS_IMETHODIMP
RDFContainerImpl::GetElements(nsISimpleEnumerator **_retval)
{
return NS_NewContainerEnumerator(mDataSource, mContainer, _retval);
}
NS_IMETHODIMP
RDFContainerImpl::AppendElement(nsIRDFNode *aElement)
{
NS_PRECONDITION(aElement != nsnull, "null ptr");
if (! aElement)
return NS_ERROR_NULL_POINTER;
nsresult rv;
PRBool isContainer;
rv = gRDFContainerUtils->IsContainer(mDataSource, mContainer, &isContainer);
if (NS_FAILED(rv)) return rv;
NS_PRECONDITION(isContainer, "not a container");
if (! isContainer)
return NS_ERROR_UNEXPECTED;
nsCOMPtr<nsIRDFResource> nextVal;
rv = GetNextValue(getter_AddRefs(nextVal));
if (NS_FAILED(rv)) return rv;
rv = mDataSource->Assert(mContainer, nextVal, aElement, PR_TRUE);
if (NS_FAILED(rv)) return rv;
return NS_OK;
}
NS_IMETHODIMP
RDFContainerImpl::RemoveElement(nsIRDFNode *aElement, PRBool aRenumber)
{
NS_PRECONDITION(aElement != nsnull, "null ptr");
if (! aElement)
return NS_ERROR_NULL_POINTER;
nsresult rv;
PRInt32 index;
rv = IndexOf(aElement, &index);
if (NS_FAILED(rv)) return rv;
if (index < 0) {
NS_WARNING("attempt to remove non-existant element");
return NS_OK;
}
// Remove the element.
nsCOMPtr<nsIRDFResource> ordinal;
rv = gRDFContainerUtils->IndexToOrdinalResource(index, getter_AddRefs(ordinal));
if (NS_FAILED(rv)) return rv;
rv = mDataSource->Unassert(mContainer, ordinal, aElement);
if (NS_FAILED(rv)) return rv;
if (aRenumber) {
// Now slide the rest of the collection backwards to fill in
// the gap. This will have the side effect of completely
// renumber the container from index to the end.
rv = Renumber(index);
if (NS_FAILED(rv)) return rv;
}
return NS_OK;
}
NS_IMETHODIMP
RDFContainerImpl::InsertElementAt(nsIRDFNode *aElement, PRInt32 aIndex, PRBool aRenumber)
{
NS_PRECONDITION(aElement != nsnull, "null ptr");
if (! aElement)
return NS_ERROR_NULL_POINTER;
NS_PRECONDITION(aIndex >= 1, "illegal value");
if (aIndex < 1)
return NS_ERROR_ILLEGAL_VALUE;
nsresult rv;
PRInt32 count;
rv = GetCount(&count);
if (NS_FAILED(rv)) return rv;
NS_ASSERTION(aIndex <= count, "illegal value");
if (aIndex > count)
return NS_ERROR_ILLEGAL_VALUE;
if (aRenumber) {
// Make a hole for the element. This will have the side effect of
// completely renumbering the container from 'aIndex' to 'count',
// and will spew assertions.
rv = Renumber(aIndex);
if (NS_FAILED(rv)) return rv;
}
nsCOMPtr<nsIRDFResource> ordinal;
rv = gRDFContainerUtils->IndexToOrdinalResource(aIndex, getter_AddRefs(ordinal));
if (NS_FAILED(rv)) return rv;
rv = mDataSource->Assert(mContainer, ordinal, aElement, PR_TRUE);
if (NS_FAILED(rv)) return rv;
return NS_OK;
}
NS_IMETHODIMP
RDFContainerImpl::IndexOf(nsIRDFNode *aElement, PRInt32 *aIndex)
{
NS_PRECONDITION(aElement != nsnull, "null ptr");
if (! aElement)
return NS_ERROR_NULL_POINTER;
NS_PRECONDITION(aIndex != nsnull, "null ptr");
if (! aIndex)
return NS_ERROR_NULL_POINTER;
nsresult rv;
PRInt32 count;
rv = GetCount(&count);
if (NS_FAILED(rv)) return rv;
for (PRInt32 index = 0; index < count; ++index) {
nsCOMPtr<nsIRDFResource> ordinal;
rv = gRDFContainerUtils->IndexToOrdinalResource(index, getter_AddRefs(ordinal));
if (NS_FAILED(rv)) return rv;
// Get all of the elements in the container with the specified
// ordinal. This is an ultra-paranoid way to do it, but -- due
// to aggregation, we may end up with a container that has >1
// element for the same ordinal.
nsCOMPtr<nsISimpleEnumerator> targets;
rv = mDataSource->GetTargets(mContainer, ordinal, PR_TRUE, getter_AddRefs(targets));
if (NS_FAILED(rv)) return rv;
while (1) {
PRBool hasMore;
rv = targets->HasMoreElements(&hasMore);
if (NS_FAILED(rv)) return rv;
if (! hasMore)
break;
nsCOMPtr<nsISupports> isupports;
rv = targets->GetNext(getter_AddRefs(isupports));
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to read cursor");
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIRDFNode> element = do_QueryInterface(isupports);
if (element.get() != aElement)
continue;
// Okay, we've found it!
*aIndex = index;
return NS_OK;
}
}
NS_WARNING("element not found");
*aIndex = -1;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
RDFContainerImpl::RDFContainerImpl()
: mDataSource(nsnull), mContainer(nsnull)
{
NS_INIT_REFCNT();
if (gRefCnt++ == 0) {
nsresult rv;
rv = nsServiceManager::GetService(kRDFServiceCID,
nsIRDFService::GetIID(),
(nsISupports**) &gRDFService);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get RDF service");
if (NS_SUCCEEDED(rv)) {
gRDFService->GetResource(RDF_NAMESPACE_URI "nextVal", &kRDF_nextVal);
}
rv = nsServiceManager::GetService(kRDFContainerUtilsCID,
nsIRDFContainerUtils::GetIID(),
(nsISupports**) &gRDFContainerUtils);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get RDF container utils service");
}
}
RDFContainerImpl::~RDFContainerImpl()
{
NS_IF_RELEASE(mContainer);
NS_IF_RELEASE(mDataSource);
if (--gRefCnt == 0) {
nsServiceManager::ReleaseService(kRDFContainerUtilsCID, gRDFContainerUtils);
nsServiceManager::ReleaseService(kRDFServiceCID, gRDFService);
}
}
nsresult
NS_NewRDFContainer(nsIRDFContainer** aResult)
{
NS_PRECONDITION(aResult != nsnull, "null ptr");
if (! aResult)
return NS_ERROR_NULL_POINTER;
RDFContainerImpl* result =
new RDFContainerImpl();
if (! result)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(result);
*aResult = result;
return NS_OK;
}
nsresult
NS_NewRDFContainer(nsIRDFDataSource* aDataSource,
nsIRDFResource* aResource,
nsIRDFContainer** aResult)
{
nsresult rv;
rv = NS_NewRDFContainer(aResult);
if (NS_FAILED(rv)) return rv;
rv = (*aResult)->Init(aDataSource, aResource);
if (NS_FAILED(rv)) {
NS_RELEASE(*aResult);
}
return rv;
}
nsresult
RDFContainerImpl::Renumber(PRInt32 aStartIndex)
{
// Renumber the elements in the container
nsresult rv;
PRInt32 count;
rv = GetCount(&count);
if (NS_FAILED(rv)) return rv;
PRInt32 oldIndex = aStartIndex;
PRInt32 newIndex = aStartIndex;
while (oldIndex < count) {
nsCOMPtr<nsIRDFResource> oldOrdinal;
rv = gRDFContainerUtils->IndexToOrdinalResource(oldIndex, getter_AddRefs(oldOrdinal));
if (NS_FAILED(rv)) return rv;
// Because of aggregation, we need to be paranoid about
// the possibility that >1 element may be present per
// ordinal.
nsCOMPtr<nsISimpleEnumerator> targets;
rv = mDataSource->GetTargets(mContainer, oldOrdinal, PR_TRUE, getter_AddRefs(targets));
if (NS_FAILED(rv)) return rv;
while (1) {
PRBool hasMore;
rv = targets->HasMoreElements(&hasMore);
if (NS_FAILED(rv)) return rv;
if (! hasMore)
break;
nsCOMPtr<nsISupports> isupports;
rv = targets->GetNext(getter_AddRefs(isupports));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIRDFNode> element( do_QueryInterface(isupports) );
NS_ASSERTION(element != nsnull, "something funky in the enumerator");
if (! element)
return NS_ERROR_UNEXPECTED;
rv = mDataSource->Unassert(mContainer, oldOrdinal, element);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIRDFResource> newOrdinal;
rv = gRDFContainerUtils->IndexToOrdinalResource(++newIndex, getter_AddRefs(newOrdinal));
if (NS_FAILED(rv)) return rv;
rv = mDataSource->Assert(mContainer, newOrdinal, element, PR_TRUE);
if (NS_FAILED(rv)) return rv;
}
}
// Update the container's nextVal to reflect the renumbering
rv = SetNextValue(++newIndex);
if (NS_FAILED(rv)) return rv;
return NS_OK;
}
nsresult
RDFContainerImpl::SetNextValue(PRInt32 aIndex)
{
nsresult rv;
// Remove the current value of nextVal, if there is one.
nsCOMPtr<nsIRDFNode> nextValNode;
if (NS_SUCCEEDED(rv = mDataSource->GetTarget(mContainer,
kRDF_nextVal,
PR_TRUE,
getter_AddRefs(nextValNode)))) {
if (NS_FAILED(rv = mDataSource->Unassert(mContainer, kRDF_nextVal, nextValNode))) {
NS_ERROR("unable to update nextVal");
return rv;
}
}
nsAutoString s;
s.Append(aIndex, 10);
nsCOMPtr<nsIRDFLiteral> nextVal;
if (NS_FAILED(rv = gRDFService->GetLiteral(s.GetUnicode(), getter_AddRefs(nextVal)))) {
NS_ERROR("unable to get nextVal literal");
return rv;
}
rv = mDataSource->Assert(mContainer, kRDF_nextVal, nextVal, PR_TRUE);
if (rv != NS_RDF_ASSERTION_ACCEPTED) {
NS_ERROR("unable to update nextVal");
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult
RDFContainerImpl::GetNextValue(nsIRDFResource** aResult)
{
NS_PRECONDITION(aResult != nsnull, "null ptr");
if (! aResult)
return NS_ERROR_NULL_POINTER;
nsresult rv;
// Get the next value, which hangs off of the bag via the
// RDF:nextVal property.
nsCOMPtr<nsIRDFNode> nextValNode;
rv = mDataSource->GetTarget(mContainer, kRDF_nextVal, PR_TRUE, getter_AddRefs(nextValNode));
if (NS_FAILED(rv)) return rv;
if (rv == NS_RDF_NO_VALUE)
return NS_ERROR_UNEXPECTED;
nsCOMPtr<nsIRDFLiteral> nextValLiteral;
rv = nextValNode->QueryInterface(nsIRDFLiteral::GetIID(), getter_AddRefs(nextValLiteral));
if (NS_FAILED(rv)) return rv;
nsXPIDLString s;
rv = nextValLiteral->GetValue( getter_Copies(s) );
if (NS_FAILED(rv)) return rv;
nsAutoString nextValStr = (const PRUnichar*) s;
PRInt32 err;
PRInt32 nextVal = nextValStr.ToInteger(&err);
if (NS_FAILED(err))
return NS_ERROR_UNEXPECTED;
// Generate a URI that we can return.
nextValStr = kRDFNameSpaceURI;
nextValStr.Append("_");
nextValStr.Append(nextVal, 10);
rv = gRDFService->GetUnicodeResource(nextValStr.GetUnicode(), aResult);
if (NS_FAILED(rv)) return rv;
// Now increment the RDF:nextVal property.
rv = mDataSource->Unassert(mContainer, kRDF_nextVal, nextValLiteral);
if (NS_FAILED(rv)) return rv;
++nextVal;
nextValStr.Truncate();
nextValStr.Append(nextVal, 10);
rv = gRDFService->GetLiteral(nextValStr.GetUnicode(), getter_AddRefs(nextValLiteral));
if (NS_FAILED(rv)) return rv;
rv = mDataSource->Assert(mContainer, kRDF_nextVal, nextValLiteral, PR_TRUE);
if (NS_FAILED(rv)) return rv;
return NS_OK;
}

View File

@@ -1,362 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
/*
Implementation for the RDF container utils.
*/
#include "nsCOMPtr.h"
#include "nsIServiceManager.h"
#include "nsIRDFContainer.h"
#include "nsIRDFContainerUtils.h"
#include "nsIRDFService.h"
#include "nsRDFCID.h"
#include "nsString.h"
#include "nsXPIDLString.h"
#include "plstr.h"
#include "prprf.h"
#include "rdf.h"
#include "rdfutil.h"
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
static const char kRDFNameSpaceURI[] = RDF_NAMESPACE_URI;
class RDFContainerUtilsImpl : public nsIRDFContainerUtils
{
public:
// nsISupports interface
NS_DECL_ISUPPORTS
// nsIRDFContainerUtils interface
NS_IMETHOD IsOrdinalProperty(nsIRDFResource *aProperty, PRBool *_retval);
NS_IMETHOD IndexToOrdinalResource(PRInt32 aIndex, nsIRDFResource **_retval);
NS_IMETHOD OrdinalResourceToIndex(nsIRDFResource *aOrdinal, PRInt32 *_retval);
NS_IMETHOD IsContainer(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, PRBool *_retval);
NS_IMETHOD IsBag(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, PRBool *_retval);
NS_IMETHOD IsSeq(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, PRBool *_retval);
NS_IMETHOD IsAlt(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, PRBool *_retval);
NS_IMETHOD MakeBag(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, nsIRDFContainer **_retval);
NS_IMETHOD MakeSeq(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, nsIRDFContainer **_retval);
NS_IMETHOD MakeAlt(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, nsIRDFContainer **_retval);
private:
friend nsresult NS_NewRDFContainerUtils(nsIRDFContainerUtils** aResult);
RDFContainerUtilsImpl();
virtual ~RDFContainerUtilsImpl();
nsresult MakeContainer(nsIRDFDataSource* aDataSource,
nsIRDFResource* aResource,
nsIRDFResource* aType,
nsIRDFContainer** aResult);
// pseudo constants
static PRInt32 gRefCnt;
static nsIRDFService* gRDFService;
static nsIRDFResource* kRDF_instanceOf;
static nsIRDFResource* kRDF_nextVal;
static nsIRDFResource* kRDF_Bag;
static nsIRDFResource* kRDF_Seq;
static nsIRDFResource* kRDF_Alt;
};
PRInt32 RDFContainerUtilsImpl::gRefCnt = 0;
nsIRDFService* RDFContainerUtilsImpl::gRDFService;
nsIRDFResource* RDFContainerUtilsImpl::kRDF_instanceOf;
nsIRDFResource* RDFContainerUtilsImpl::kRDF_nextVal;
nsIRDFResource* RDFContainerUtilsImpl::kRDF_Bag;
nsIRDFResource* RDFContainerUtilsImpl::kRDF_Seq;
nsIRDFResource* RDFContainerUtilsImpl::kRDF_Alt;
////////////////////////////////////////////////////////////////////////
// nsISupports interface
NS_IMPL_ISUPPORTS(RDFContainerUtilsImpl, nsIRDFContainerUtils::GetIID());
////////////////////////////////////////////////////////////////////////
// nsIRDFContainerUtils interface
NS_IMETHODIMP
RDFContainerUtilsImpl::IsOrdinalProperty(nsIRDFResource *aProperty, PRBool *_retval)
{
nsresult rv;
nsXPIDLCString propertyStr;
rv = aProperty->GetValue( getter_Copies(propertyStr) );
if (NS_FAILED(rv)) return rv;
if (PL_strncmp(propertyStr, kRDFNameSpaceURI, sizeof(kRDFNameSpaceURI) - 1) != 0) {
*_retval = PR_FALSE;
return NS_OK;
}
const char* s = propertyStr;
s += sizeof(kRDFNameSpaceURI) - 1;
if (*s != '_') {
*_retval = PR_FALSE;
return NS_OK;
}
++s;
while (*s) {
if (*s < '0' || *s > '9') {
*_retval = PR_FALSE;
return NS_OK;
}
++s;
}
*_retval = PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP
RDFContainerUtilsImpl::IndexToOrdinalResource(PRInt32 aIndex, nsIRDFResource **aOrdinal)
{
NS_PRECONDITION(aIndex > 0, "illegal value");
if (aIndex <= 0)
return NS_ERROR_ILLEGAL_VALUE;
// 16 digits should be plenty to hold a decimal version of a
// PRInt32.
char buf[sizeof(kRDFNameSpaceURI) + 16 + 1];
PL_strcpy(buf, kRDFNameSpaceURI);
buf[sizeof(kRDFNameSpaceURI) - 1] = '_';
PR_snprintf(buf + sizeof(kRDFNameSpaceURI), 16, "%ld", aIndex);
nsresult rv;
rv = gRDFService->GetResource(buf, aOrdinal);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get ordinal resource");
if (NS_FAILED(rv)) return rv;
return NS_OK;
}
NS_IMETHODIMP
RDFContainerUtilsImpl::OrdinalResourceToIndex(nsIRDFResource *aOrdinal, PRInt32 *aIndex)
{
nsXPIDLCString ordinalStr;
if (NS_FAILED(aOrdinal->GetValue( getter_Copies(ordinalStr) )))
return PR_FALSE;
const char* s = ordinalStr;
if (PL_strncmp(s, kRDFNameSpaceURI, sizeof(kRDFNameSpaceURI) - 1) != 0) {
NS_ERROR("not an ordinal");
return NS_ERROR_UNEXPECTED;
}
s += sizeof(kRDFNameSpaceURI) - 1;
if (*s != '_') {
NS_ERROR("not an ordinal");
return NS_ERROR_UNEXPECTED;
}
PRInt32 index = 0;
++s;
while (*s) {
if (*s < '0' || *s > '9') {
NS_ERROR("not an ordinal");
return NS_ERROR_UNEXPECTED;
}
index *= 10;
index += (*s - '0');
++s;
}
*aIndex = index;
return NS_OK;
}
NS_IMETHODIMP
RDFContainerUtilsImpl::IsContainer(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, PRBool *_retval)
{
NS_PRECONDITION(_retval != nsnull, "null ptr");
if (! _retval)
return NS_ERROR_NULL_POINTER;
if (rdf_IsA(aDataSource, aResource, kRDF_Bag) ||
rdf_IsA(aDataSource, aResource, kRDF_Seq) ||
rdf_IsA(aDataSource, aResource, kRDF_Alt)) {
*_retval = PR_TRUE;
}
else {
*_retval = PR_FALSE;
}
return NS_OK;
}
NS_IMETHODIMP
RDFContainerUtilsImpl::IsBag(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, PRBool *_retval)
{
NS_PRECONDITION(_retval != nsnull, "null ptr");
if (! _retval)
return NS_ERROR_NULL_POINTER;
*_retval = rdf_IsA(aDataSource, aResource, kRDF_Bag);
return NS_OK;
}
NS_IMETHODIMP
RDFContainerUtilsImpl::IsSeq(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, PRBool *_retval)
{
NS_PRECONDITION(_retval != nsnull, "null ptr");
if (! _retval)
return NS_ERROR_NULL_POINTER;
*_retval = rdf_IsA(aDataSource, aResource, kRDF_Seq);
return NS_OK;
}
NS_IMETHODIMP
RDFContainerUtilsImpl::IsAlt(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, PRBool *_retval)
{
NS_PRECONDITION(_retval != nsnull, "null ptr");
if (! _retval)
return NS_ERROR_NULL_POINTER;
*_retval = rdf_IsA(aDataSource, aResource, kRDF_Alt);
return NS_OK;
}
NS_IMETHODIMP
RDFContainerUtilsImpl::MakeBag(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, nsIRDFContainer **_retval)
{
return MakeContainer(aDataSource, aResource, kRDF_Bag, _retval);
}
NS_IMETHODIMP
RDFContainerUtilsImpl::MakeSeq(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, nsIRDFContainer **_retval)
{
return MakeContainer(aDataSource, aResource, kRDF_Seq, _retval);
}
NS_IMETHODIMP
RDFContainerUtilsImpl::MakeAlt(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, nsIRDFContainer **_retval)
{
return MakeContainer(aDataSource, aResource, kRDF_Alt, _retval);
}
////////////////////////////////////////////////////////////////////////
RDFContainerUtilsImpl::RDFContainerUtilsImpl()
{
NS_INIT_REFCNT();
if (gRefCnt++ == 0) {
nsresult rv;
rv = nsServiceManager::GetService(kRDFServiceCID,
nsIRDFService::GetIID(),
(nsISupports**) &gRDFService);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get RDF service");
if (NS_SUCCEEDED(rv)) {
gRDFService->GetResource(RDF_NAMESPACE_URI "instanceOf", &kRDF_instanceOf);
gRDFService->GetResource(RDF_NAMESPACE_URI "nextVal", &kRDF_nextVal);
gRDFService->GetResource(RDF_NAMESPACE_URI "Bag", &kRDF_Bag);
gRDFService->GetResource(RDF_NAMESPACE_URI "Seq", &kRDF_Seq);
gRDFService->GetResource(RDF_NAMESPACE_URI "Alt", &kRDF_Alt);
}
}
}
RDFContainerUtilsImpl::~RDFContainerUtilsImpl()
{
if (--gRefCnt == 0) {
if (gRDFService) {
nsServiceManager::ReleaseService(kRDFServiceCID, gRDFService);
gRDFService = nsnull;
}
NS_IF_RELEASE(kRDF_instanceOf);
NS_IF_RELEASE(kRDF_nextVal);
NS_IF_RELEASE(kRDF_Bag);
NS_IF_RELEASE(kRDF_Seq);
NS_IF_RELEASE(kRDF_Alt);
}
}
nsresult
NS_NewRDFContainerUtils(nsIRDFContainerUtils** aResult)
{
NS_PRECONDITION(aResult != nsnull, "null ptr");
if (! aResult)
return NS_ERROR_NULL_POINTER;
RDFContainerUtilsImpl* result =
new RDFContainerUtilsImpl();
if (! result)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(result);
*aResult = result;
return NS_OK;
}
nsresult
RDFContainerUtilsImpl::MakeContainer(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource, nsIRDFResource* aType, nsIRDFContainer** aResult)
{
nsresult rv;
rv = aDataSource->Assert(aResource, kRDF_instanceOf, aType, PR_TRUE);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIRDFLiteral> nextVal;
rv = gRDFService->GetLiteral(nsAutoString("1").GetUnicode(), getter_AddRefs(nextVal));
if (NS_FAILED(rv)) return rv;
rv = aDataSource->Assert(aResource, kRDF_nextVal, nextVal, PR_TRUE);
if (NS_FAILED(rv)) return rv;
if (aResult) {
rv = NS_NewRDFContainer(aResult);
if (NS_FAILED(rv)) return rv;
rv = (*aResult)->Init(aDataSource, aResource);
if (NS_FAILED(rv)) return rv;
}
return NS_OK;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,137 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
/*
*/
#ifndef nsRDFContentSink_h__
#define nsRDFContentSink_h__
#include "nsIRDFContentSink.h"
class nsIURL;
class nsVoidArray;
class nsIRDFResource;
class nsIRDFDataSource;
class nsIRDFService;
class nsINameSpaceManager;
typedef enum {
eRDFContentSinkState_InProlog,
eRDFContentSinkState_InDocumentElement,
eRDFContentSinkState_InDescriptionElement,
eRDFContentSinkState_InContainerElement,
eRDFContentSinkState_InPropertyElement,
eRDFContentSinkState_InMemberElement,
eRDFContentSinkState_InEpilog
} RDFContentSinkState;
class RDFContentSinkImpl : public nsIRDFContentSink
{
public:
RDFContentSinkImpl();
virtual ~RDFContentSinkImpl();
// nsISupports
NS_DECL_ISUPPORTS
// nsIContentSink
NS_IMETHOD WillBuildModel(void);
NS_IMETHOD DidBuildModel(PRInt32 aQualityLevel);
NS_IMETHOD WillInterrupt(void);
NS_IMETHOD WillResume(void);
NS_IMETHOD SetParser(nsIParser* aParser);
NS_IMETHOD OpenContainer(const nsIParserNode& aNode);
NS_IMETHOD CloseContainer(const nsIParserNode& aNode);
NS_IMETHOD AddLeaf(const nsIParserNode& aNode);
NS_IMETHOD AddComment(const nsIParserNode& aNode);
NS_IMETHOD AddProcessingInstruction(const nsIParserNode& aNode);
NS_IMETHOD NotifyError(nsresult aErrorResult);
// nsIXMLContentSink
NS_IMETHOD AddXMLDecl(const nsIParserNode& aNode);
NS_IMETHOD AddDocTypeDecl(const nsIParserNode& aNode);
NS_IMETHOD AddCharacterData(const nsIParserNode& aNode);
NS_IMETHOD AddUnparsedEntity(const nsIParserNode& aNode);
NS_IMETHOD AddNotation(const nsIParserNode& aNode);
NS_IMETHOD AddEntityReference(const nsIParserNode& aNode);
// nsIRDFContentSink
NS_IMETHOD SetDataSource(nsIRDFDataSource* ds);
NS_IMETHOD GetDataSource(nsIRDFDataSource*& ds);
NS_IMETHOD Init(nsIURL* aURL, nsINameSpaceManager* aNameSpaceManager);
protected:
// Text management
nsresult FlushText(PRBool aCreateTextNode=PR_TRUE,
PRBool* aDidFlush=nsnull);
PRUnichar* mText;
PRInt32 mTextLength;
PRInt32 mTextSize;
PRBool mConstrainSize;
// namespace management
void PushNameSpacesFrom(const nsIParserNode& aNode);
nsIAtom* CutNameSpacePrefix(nsString& aString);
PRInt32 GetNameSpaceID(nsIAtom* aPrefix);
void GetNameSpaceURI(PRInt32 aID, nsString& aURI);
void PopNameSpaces();
nsINameSpaceManager* mNameSpaceManager;
nsVoidArray* mNameSpaceStack;
PRInt32 mRDFNameSpaceID;
void SplitQualifiedName(const nsString& aQualifiedName,
PRInt32& rNameSpaceID,
nsString& rProperty);
// RDF-specific parsing
nsresult GetIdAboutAttribute(const nsIParserNode& aNode, nsString& rResource);
nsresult GetResourceAttribute(const nsIParserNode& aNode, nsString& rResource);
nsresult AddProperties(const nsIParserNode& aNode, nsIRDFResource* aSubject);
virtual nsresult OpenRDF(const nsIParserNode& aNode);
virtual nsresult OpenObject(const nsIParserNode& aNode);
virtual nsresult OpenProperty(const nsIParserNode& aNode);
virtual nsresult OpenMember(const nsIParserNode& aNode);
virtual nsresult OpenValue(const nsIParserNode& aNode);
// Miscellaneous RDF junk
nsIRDFService* mRDFService;
nsIRDFDataSource* mDataSource;
RDFContentSinkState mState;
// content stack management
PRInt32 PushContext(nsIRDFResource *aContext, RDFContentSinkState aState);
nsresult PopContext(nsIRDFResource*& rContext, RDFContentSinkState& rState);
nsIRDFResource* GetContextElement(PRInt32 ancestor = 0);
nsVoidArray* mContextStack;
nsIURL* mDocumentURL;
PRUint32 mGenSym; // for generating anonymous resources
};
#endif // nsRDFContentSink_h__

File diff suppressed because it is too large Load Diff

View File

@@ -1,245 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
/*
Some useful parsing routines.
This isn't the best place for them: I wish that they'd go into some
shared area (like mozilla/base).
*/
#include <stdlib.h> // XXX for atoi(), maybe this should go into nsCRT?
#include "nsCRT.h"
#include "nsIURL.h"
#include "nsString.h"
#include "nsRDFParserUtils.h"
// XXX This totally sucks. I wish that mozilla/base had this code.
PRUnichar
nsRDFParserUtils::EntityToUnicode(const char* buf)
{
if ((buf[0] == 'g' || buf[0] == 'G') &&
(buf[1] == 't' || buf[1] == 'T'))
return PRUnichar('>');
if ((buf[0] == 'l' || buf[0] == 'L') &&
(buf[1] == 't' || buf[1] == 'T'))
return PRUnichar('<');
if ((buf[0] == 'a' || buf[0] == 'A') &&
(buf[1] == 'm' || buf[1] == 'M') &&
(buf[2] == 'p' || buf[2] == 'P'))
return PRUnichar('&');
NS_NOTYETIMPLEMENTED("this is a named entity that I can't handle...");
return PRUnichar('?');
}
// XXX Code copied from nsHTMLContentSink. It should be shared.
void
nsRDFParserUtils::StripAndConvert(nsString& aResult)
{
// Strip quotes if present
PRUnichar first = aResult.First();
if ((first == '"') || (first == '\'')) {
if (aResult.Last() == first) {
aResult.Cut(0, 1);
PRInt32 pos = aResult.Length() - 1;
if (pos >= 0) {
aResult.Cut(pos, 1);
}
} else {
// Mismatched quotes - leave them in
}
}
// Reduce any entities
// XXX Note: as coded today, this will only convert well formed
// entities. This may not be compatible enough.
// XXX there is a table in navigator that translates some numeric entities
// should we be doing that? If so then it needs to live in two places (bad)
// so we should add a translate numeric entity method from the parser...
char cbuf[100];
PRInt32 index = 0;
while (index < aResult.Length()) {
// If we have the start of an entity (and it's not at the end of
// our string) then translate the entity into it's unicode value.
if ((aResult.CharAt(index++) == '&') && (index < aResult.Length())) {
PRInt32 start = index - 1;
PRUnichar e = aResult.CharAt(index);
if (e == '#') {
// Convert a numeric character reference
index++;
char* cp = cbuf;
char* limit = cp + sizeof(cbuf) - 1;
PRBool ok = PR_FALSE;
PRInt32 slen = aResult.Length();
while ((index < slen) && (cp < limit)) {
PRUnichar e = aResult.CharAt(index);
if (e == ';') {
index++;
ok = PR_TRUE;
break;
}
if ((e >= '0') && (e <= '9')) {
*cp++ = char(e);
index++;
continue;
}
break;
}
if (!ok || (cp == cbuf)) {
continue;
}
*cp = '\0';
if (cp - cbuf > 5) {
continue;
}
PRInt32 ch = PRInt32( ::atoi(cbuf) );
if (ch > 65535) {
continue;
}
// Remove entity from string and replace it with the integer
// value.
aResult.Cut(start, index - start);
aResult.Insert(PRUnichar(ch), start);
index = start + 1;
}
else if (((e >= 'A') && (e <= 'Z')) ||
((e >= 'a') && (e <= 'z'))) {
// Convert a named entity
index++;
char* cp = cbuf;
char* limit = cp + sizeof(cbuf) - 1;
*cp++ = char(e);
PRBool ok = PR_FALSE;
PRInt32 slen = aResult.Length();
while ((index < slen) && (cp < limit)) {
PRUnichar e = aResult.CharAt(index);
if (e == ';') {
index++;
ok = PR_TRUE;
break;
}
if (((e >= '0') && (e <= '9')) ||
((e >= 'A') && (e <= 'Z')) ||
((e >= 'a') && (e <= 'z'))) {
*cp++ = char(e);
index++;
continue;
}
break;
}
if (!ok || (cp == cbuf)) {
continue;
}
*cp = '\0';
PRInt32 ch;
// XXX Um, here's where we should be converting a
// named entity. I removed this to avoid a link-time
// dependency on core raptor.
ch = EntityToUnicode(cbuf);
if (ch < 0) {
continue;
}
// Remove entity from string and replace it with the integer
// value.
aResult.Cut(start, index - start);
aResult.Insert(PRUnichar(ch), start);
index = start + 1;
}
else if (e == '{') {
// Convert a script entity
// XXX write me!
NS_NOTYETIMPLEMENTED("convert a script entity");
}
}
}
}
nsresult
nsRDFParserUtils::GetQuotedAttributeValue(const nsString& aSource,
const nsString& aAttribute,
nsString& aValue)
{
static const char kQuote = '\"';
static const char kApostrophe = '\'';
PRInt32 offset;
PRInt32 endOffset = -1;
nsresult result = NS_OK;
offset = aSource.Find(aAttribute);
if (-1 != offset) {
offset = aSource.Find('=', offset);
PRUnichar next = aSource.CharAt(++offset);
if (kQuote == next) {
endOffset = aSource.Find(kQuote, ++offset);
}
else if (kApostrophe == next) {
endOffset = aSource.Find(kApostrophe, ++offset);
}
if (-1 != endOffset) {
aSource.Mid(aValue, offset, endOffset-offset);
}
else {
// Mismatched quotes - return an error
result = NS_ERROR_FAILURE;
}
}
else {
aValue.Truncate();
}
return result;
}
PRBool
nsRDFParserUtils::IsJavaScriptLanguage(const nsString& aName)
{
if (aName.EqualsIgnoreCase("JavaScript") ||
aName.EqualsIgnoreCase("LiveScript") ||
aName.EqualsIgnoreCase("Mocha")) {
return PR_TRUE;
}
else if (aName.EqualsIgnoreCase("JavaScript1.1")) {
return PR_TRUE;
}
else if (aName.EqualsIgnoreCase("JavaScript1.2")) {
return PR_TRUE;
}
else if (aName.EqualsIgnoreCase("JavaScript1.3")) {
return PR_TRUE;
}
else if (aName.EqualsIgnoreCase("JavaScript1.4")) {
return PR_TRUE;
}
else {
return PR_FALSE;
}
}

View File

@@ -1,56 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
/*
Some useful parsing routines.
*/
#ifndef nsRDFParserUtils_h__
#define nsRDFParserUtils_h__
#include "nscore.h"
#include "nsError.h"
class nsIURL;
class nsString;
class nsRDFParserUtils {
public:
static PRUnichar
EntityToUnicode(const char* buf);
static void
StripAndConvert(nsString& aResult);
static nsresult
GetQuotedAttributeValue(const nsString& aSource,
const nsString& aAttribute,
nsString& aValue);
static PRBool
IsJavaScriptLanguage(const nsString& aName);
};
#endif // nsRDFPasrserUtils_h__

View File

@@ -1,951 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
This file provides the implementation for the RDF service manager.
TO DO
-----
1) Implement the CreateDataBase() methods.
2) Cache date and int literals.
*/
#include "nsCOMPtr.h"
#include "nsIAtom.h"
#include "nsIComponentManager.h"
#include "nsIRDFDataSource.h"
#include "nsIRDFNode.h"
#include "nsIRDFResourceFactory.h"
#include "nsIRDFService.h"
#include "nsIRDFXMLDataSource.h"
#include "nsRDFCID.h"
#include "nsString.h"
#include "nsXPIDLString.h"
#include "plhash.h"
#include "plstr.h"
#include "prlog.h"
#include "prprf.h"
#include "rdf.h"
////////////////////////////////////////////////////////////////////////
static NS_DEFINE_CID(kRDFXMLDataSourceCID, NS_RDFXMLDATASOURCE_CID);
static NS_DEFINE_IID(kIRDFServiceIID, NS_IRDFSERVICE_IID);
static NS_DEFINE_IID(kIRDFLiteralIID, NS_IRDFLITERAL_IID);
static NS_DEFINE_IID(kIRDFDateIID, NS_IRDFDATE_IID);
static NS_DEFINE_IID(kIRDFIntIID, NS_IRDFINT_IID);
static NS_DEFINE_IID(kIRDFResourceIID, NS_IRDFRESOURCE_IID);
static NS_DEFINE_IID(kIRDFNodeIID, NS_IRDFNODE_IID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
////////////////////////////////////////////////////////////////////////
// ServiceImpl
//
// This is the RDF service.
//
class ServiceImpl : public nsIRDFService
{
protected:
PLHashTable* mNamedDataSources;
PLHashTable* mResources;
PLHashTable* mLiterals;
ServiceImpl(void);
virtual ~ServiceImpl(void);
public:
static nsresult GetRDFService(nsIRDFService** result);
// nsISupports
NS_DECL_ISUPPORTS
// nsIRDFService
NS_IMETHOD GetResource(const char* uri, nsIRDFResource** resource);
NS_IMETHOD GetUnicodeResource(const PRUnichar* uri, nsIRDFResource** resource);
NS_IMETHOD GetLiteral(const PRUnichar* value, nsIRDFLiteral** literal);
NS_IMETHOD GetDateLiteral(PRTime value, nsIRDFDate** date) ;
NS_IMETHOD GetIntLiteral(PRInt32 value, nsIRDFInt** intLiteral);
NS_IMETHOD RegisterResource(nsIRDFResource* aResource, PRBool replace = PR_FALSE);
NS_IMETHOD UnregisterResource(nsIRDFResource* aResource);
NS_IMETHOD RegisterDataSource(nsIRDFDataSource* dataSource, PRBool replace = PR_FALSE);
NS_IMETHOD UnregisterDataSource(nsIRDFDataSource* dataSource);
NS_IMETHOD GetDataSource(const char* uri, nsIRDFDataSource** dataSource);
// Implementation methods
nsresult RegisterLiteral(nsIRDFLiteral* aLiteral, PRBool aReplace = PR_FALSE);
nsresult UnregisterLiteral(nsIRDFLiteral* aLiteral);
};
static ServiceImpl* gRDFService; // The one-and-only RDF service
////////////////////////////////////////////////////////////////////////
// LiteralImpl
//
// Currently, all literals are implemented exactly the same way;
// i.e., there is are no resource factories to allow you to generate
// customer resources. I doubt that makes sense, anyway.
//
class LiteralImpl : public nsIRDFLiteral {
public:
LiteralImpl(const PRUnichar* s);
virtual ~LiteralImpl(void);
// nsISupports
NS_DECL_ISUPPORTS
// nsIRDFNode
NS_IMETHOD EqualsNode(nsIRDFNode* node, PRBool* result);
// nsIRDFLiteral
NS_IMETHOD GetValue(PRUnichar* *value);
NS_IMETHOD EqualsLiteral(nsIRDFLiteral* literal, PRBool* result);
private:
nsAutoString mValue;
};
LiteralImpl::LiteralImpl(const PRUnichar* s)
: mValue(s)
{
NS_INIT_REFCNT();
gRDFService->RegisterLiteral(this);
}
LiteralImpl::~LiteralImpl(void)
{
gRDFService->UnregisterLiteral(this);
}
NS_IMPL_ADDREF(LiteralImpl);
NS_IMPL_RELEASE(LiteralImpl);
nsresult
LiteralImpl::QueryInterface(REFNSIID iid, void** result)
{
if (! result)
return NS_ERROR_NULL_POINTER;
*result = nsnull;
if (iid.Equals(kIRDFLiteralIID) ||
iid.Equals(kIRDFNodeIID) ||
iid.Equals(kISupportsIID)) {
*result = NS_STATIC_CAST(nsIRDFLiteral*, this);
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMETHODIMP
LiteralImpl::EqualsNode(nsIRDFNode* node, PRBool* result)
{
nsresult rv;
nsIRDFLiteral* literal;
if (NS_SUCCEEDED(node->QueryInterface(kIRDFLiteralIID, (void**) &literal))) {
rv = EqualsLiteral(literal, result);
NS_RELEASE(literal);
}
else {
*result = PR_FALSE;
rv = NS_OK;
}
return rv;
}
NS_IMETHODIMP
LiteralImpl::GetValue(PRUnichar* *value)
{
NS_ASSERTION(value, "null ptr");
if (! value)
return NS_ERROR_NULL_POINTER;
*value = nsXPIDLString::Copy(mValue.GetUnicode());
return NS_OK;
}
NS_IMETHODIMP
LiteralImpl::EqualsLiteral(nsIRDFLiteral* literal, PRBool* result)
{
NS_ASSERTION(literal && result, "null ptr");
if (!literal || !result)
return NS_ERROR_NULL_POINTER;
nsresult rv;
nsXPIDLString p;
if (NS_FAILED(rv = literal->GetValue(getter_Copies(p))))
return rv;
nsAutoString s((const PRUnichar*) p);
*result = s.Equals(mValue);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
// DateImpl
//
class DateImpl : public nsIRDFDate {
public:
DateImpl(const PRTime s);
virtual ~DateImpl(void);
// nsISupports
NS_DECL_ISUPPORTS
// nsIRDFNode
NS_IMETHOD EqualsNode(nsIRDFNode* node, PRBool* result);
// nsIRDFDate
NS_IMETHOD GetValue(PRTime *value);
NS_IMETHOD EqualsDate(nsIRDFDate* date, PRBool* result);
private:
PRTime mValue;
};
DateImpl::DateImpl(const PRTime s)
: mValue(s)
{
NS_INIT_REFCNT();
}
DateImpl::~DateImpl(void)
{
}
NS_IMPL_ADDREF(DateImpl);
NS_IMPL_RELEASE(DateImpl);
nsresult
DateImpl::QueryInterface(REFNSIID iid, void** result)
{
if (! result)
return NS_ERROR_NULL_POINTER;
*result = nsnull;
if (iid.Equals(kIRDFDateIID) ||
iid.Equals(kIRDFNodeIID) ||
iid.Equals(kISupportsIID)) {
*result = NS_STATIC_CAST(nsIRDFDate*, this);
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMETHODIMP
DateImpl::EqualsNode(nsIRDFNode* node, PRBool* result)
{
nsresult rv;
nsIRDFDate* date;
if (NS_SUCCEEDED(node->QueryInterface(kIRDFDateIID, (void**) &date))) {
rv = EqualsDate(date, result);
NS_RELEASE(date);
}
else {
*result = PR_FALSE;
rv = NS_OK;
}
return rv;
}
NS_IMETHODIMP
DateImpl::GetValue(PRTime *value)
{
NS_ASSERTION(value, "null ptr");
if (! value)
return NS_ERROR_NULL_POINTER;
*value = mValue;
return NS_OK;
}
NS_IMETHODIMP
DateImpl::EqualsDate(nsIRDFDate* date, PRBool* result)
{
NS_ASSERTION(date && result, "null ptr");
if (!date || !result)
return NS_ERROR_NULL_POINTER;
nsresult rv;
PRTime p;
if (NS_FAILED(rv = date->GetValue(&p)))
return rv;
*result = LL_EQ(p, mValue);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
// IntImpl
//
class IntImpl : public nsIRDFInt {
public:
IntImpl(PRInt32 s);
virtual ~IntImpl(void);
// nsISupports
NS_DECL_ISUPPORTS
// nsIRDFNode
NS_IMETHOD EqualsNode(nsIRDFNode* node, PRBool* result);
// nsIRDFInt
NS_IMETHOD GetValue(PRInt32 *value);
NS_IMETHOD EqualsInt(nsIRDFInt* value, PRBool* result);
private:
PRInt32 mValue;
};
IntImpl::IntImpl(PRInt32 s)
: mValue(s)
{
NS_INIT_REFCNT();
}
IntImpl::~IntImpl(void)
{
}
NS_IMPL_ADDREF(IntImpl);
NS_IMPL_RELEASE(IntImpl);
nsresult
IntImpl::QueryInterface(REFNSIID iid, void** result)
{
if (! result)
return NS_ERROR_NULL_POINTER;
*result = nsnull;
if (iid.Equals(kIRDFIntIID) ||
iid.Equals(kIRDFNodeIID) ||
iid.Equals(kISupportsIID)) {
*result = NS_STATIC_CAST(nsIRDFInt*, this);
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMETHODIMP
IntImpl::EqualsNode(nsIRDFNode* node, PRBool* result)
{
nsresult rv;
nsIRDFInt* intValue;
if (NS_SUCCEEDED(node->QueryInterface(kIRDFIntIID, (void**) &intValue))) {
rv = EqualsInt(intValue, result);
NS_RELEASE(intValue);
}
else {
*result = PR_FALSE;
rv = NS_OK;
}
return rv;
}
NS_IMETHODIMP
IntImpl::GetValue(PRInt32 *value)
{
NS_ASSERTION(value, "null ptr");
if (! value)
return NS_ERROR_NULL_POINTER;
*value = mValue;
return NS_OK;
}
NS_IMETHODIMP
IntImpl::EqualsInt(nsIRDFInt* intValue, PRBool* result)
{
NS_ASSERTION(intValue && result, "null ptr");
if (!intValue || !result)
return NS_ERROR_NULL_POINTER;
nsresult rv;
PRInt32 p;
if (NS_FAILED(rv = intValue->GetValue(&p)))
return rv;
*result = (p == mValue);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
// ServiceImpl
static PLHashNumber
rdf_HashWideString(const void* key)
{
PLHashNumber result = 0;
for (PRUnichar* s = (PRUnichar*) key; *s != nsnull; ++s)
result = (result >> 28) ^ (result << 4) ^ *s;
return result;
}
ServiceImpl::ServiceImpl(void)
: mNamedDataSources(nsnull), mResources(nsnull), mLiterals(nsnull)
{
NS_INIT_REFCNT();
mResources = PL_NewHashTable(1023, // nbuckets
PL_HashString, // hash fn
PL_CompareStrings, // key compare fn
PL_CompareValues, // value compare fn
nsnull, nsnull); // alloc ops & priv
mLiterals = PL_NewHashTable(1023,
rdf_HashWideString,
PL_CompareStrings,
PL_CompareValues,
nsnull, nsnull);
mNamedDataSources = PL_NewHashTable(23,
PL_HashString,
PL_CompareStrings,
PL_CompareValues,
nsnull, nsnull);
}
ServiceImpl::~ServiceImpl(void)
{
if (mNamedDataSources) {
PL_HashTableDestroy(mNamedDataSources);
mNamedDataSources = nsnull;
}
if (mResources) {
PL_HashTableDestroy(mResources);
mResources = nsnull;
}
if (mLiterals) {
PL_HashTableDestroy(mLiterals);
mLiterals = nsnull;
}
gRDFService = nsnull;
}
nsresult
ServiceImpl::GetRDFService(nsIRDFService** mgr)
{
if (! gRDFService) {
ServiceImpl* serv = new ServiceImpl();
if (! serv)
return NS_ERROR_OUT_OF_MEMORY;
gRDFService = serv;
}
NS_ADDREF(gRDFService);
*mgr = gRDFService;
return NS_OK;
}
NS_IMETHODIMP_(nsrefcnt)
ServiceImpl::AddRef(void)
{
return 2;
}
NS_IMETHODIMP_(nsrefcnt)
ServiceImpl::Release(void)
{
return 1;
}
NS_IMPL_QUERY_INTERFACE(ServiceImpl, kIRDFServiceIID);
NS_IMETHODIMP
ServiceImpl::GetResource(const char* aURI, nsIRDFResource** aResource)
{
// Sanity checks
NS_PRECONDITION(aURI != nsnull, "null ptr");
if (! aURI)
return NS_ERROR_NULL_POINTER;
NS_PRECONDITION(aResource != nsnull, "null ptr");
if (! aResource)
return NS_ERROR_NULL_POINTER;
// First, check the cache to see if we've already created and
// registered this thing.
nsIRDFResource* result =
NS_STATIC_CAST(nsIRDFResource*, PL_HashTableLookup(mResources, aURI));
if (result) {
// Addref for the callee.
NS_ADDREF(result);
*aResource = result;
return NS_OK;
}
// Nope. So go to the repository to create it.
nsresult rv;
char* p = PL_strchr(aURI, ':');
if (!p) {
// no colon, so try the default resource factory
rv = nsComponentManager::CreateInstance(NS_RDF_RESOURCE_FACTORY_PROGID,
nsnull, nsIRDFResource::GetIID(),
(void**)&result);
if (NS_FAILED(rv)) {
NS_ERROR("unable to create resource");
return rv;
}
}
else {
// the resource is qualified, so construct a ProgID and
// construct it from the repository.
static const char kRDFResourceFactoryProgIDPrefix[]
= NS_RDF_RESOURCE_FACTORY_PROGID_PREFIX;
PRInt32 pos = (p) ? (p - aURI) : (-1);
PRInt32 len = pos + sizeof(kRDFResourceFactoryProgIDPrefix) - 1;
// Safely convert to a C-string for the XPCOM APIs
char buf[128];
char* progID = buf;
if (len >= sizeof(buf))
progID = new char[len + 1];
if (progID == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
PL_strcpy(progID, kRDFResourceFactoryProgIDPrefix);
PL_strncpy(progID + sizeof(kRDFResourceFactoryProgIDPrefix) - 1, aURI, pos);
progID[len] = '\0';
rv = nsComponentManager::CreateInstance(progID, nsnull,
nsIRDFResource::GetIID(),
(void**)&result);
if (progID != buf)
delete[] progID;
if (NS_FAILED(rv)) {
// if we failed, try the default resource factory
rv = nsComponentManager::CreateInstance(NS_RDF_RESOURCE_FACTORY_PROGID,
nsnull, nsIRDFResource::GetIID(),
(void**)&result);
if (NS_FAILED(rv)) {
NS_ERROR("unable to create resource");
return rv;
}
}
}
// Now initialize it with it's URI. At this point, the resource
// implementation should register itself with the RDF service.
rv = result->Init(aURI);
if (NS_FAILED(rv)) {
NS_ERROR("unable to initialize resource");
NS_RELEASE(result);
return rv;
}
*aResource = result; // already refcounted from repository
return rv;
}
NS_IMETHODIMP
ServiceImpl::GetUnicodeResource(const PRUnichar* aURI, nsIRDFResource** aResource)
{
nsAutoString uriStr(aURI);
char buf[128];
char* uri = buf;
if (uriStr.Length() >= sizeof(buf))
uri = new char[uriStr.Length() + 1];
uriStr.ToCString(uri, uriStr.Length() + 1);
nsresult rv = GetResource(uri, aResource);
if (uri != buf)
delete[] uri;
return rv;
}
NS_IMETHODIMP
ServiceImpl::GetLiteral(const PRUnichar* aValue, nsIRDFLiteral** aLiteral)
{
NS_PRECONDITION(aValue != nsnull, "null ptr");
if (! aValue)
return NS_ERROR_NULL_POINTER;
NS_PRECONDITION(aLiteral != nsnull, "null ptr");
if (! aLiteral)
return NS_ERROR_NULL_POINTER;
// See if we have on already cached
nsIRDFLiteral* literal =
NS_STATIC_CAST(nsIRDFLiteral*, PL_HashTableLookup(mLiterals, aValue));
if (literal) {
NS_ADDREF(literal);
*aLiteral = literal;
return NS_OK;
}
// Nope. Create a new one
literal = new LiteralImpl(aValue);
if (! literal)
return NS_ERROR_OUT_OF_MEMORY;
*aLiteral = literal;
NS_ADDREF(literal);
return NS_OK;
}
NS_IMETHODIMP
ServiceImpl::GetDateLiteral(PRTime time, nsIRDFDate** literal)
{
// XXX how do we cache these? should they live in their own hashtable?
DateImpl* result = new DateImpl(time);
if (! result)
return NS_ERROR_OUT_OF_MEMORY;
*literal = result;
NS_ADDREF(result);
return NS_OK;
}
NS_IMETHODIMP
ServiceImpl::GetIntLiteral(PRInt32 value, nsIRDFInt** literal)
{
// XXX how do we cache these? should they live in their own hashtable?
IntImpl* result = new IntImpl(value);
if (! result)
return NS_ERROR_OUT_OF_MEMORY;
*literal = result;
NS_ADDREF(result);
return NS_OK;
}
NS_IMETHODIMP
ServiceImpl::RegisterResource(nsIRDFResource* aResource, PRBool replace)
{
NS_PRECONDITION(aResource != nsnull, "null ptr");
if (! aResource)
return NS_ERROR_NULL_POINTER;
nsresult rv;
nsXPIDLCString uri;
rv = aResource->GetValue(getter_Copies(uri));
if (NS_FAILED(rv)) {
NS_ERROR("unable to get URI from resource");
return rv;
}
NS_ASSERTION(uri != nsnull, "resource has no URI");
if (! uri)
return NS_ERROR_NULL_POINTER;
PLHashEntry** hep = PL_HashTableRawLookup(mResources, (*mResources->keyHash)(uri), uri);
if (*hep) {
if (!replace) {
NS_WARNING("resource already registered, and replace not specified");
return NS_ERROR_FAILURE; // already registered
}
// N.B., we do _not_ release the original resource because we
// only ever held a weak reference to it. We simply replace
// it.
(*hep)->value = aResource;
}
else {
const char* key = PL_strdup(uri);
if (! key)
return NS_ERROR_OUT_OF_MEMORY;
PL_HashTableAdd(mResources, key, aResource);
// N.B., we only hold a weak reference to the resource: that
// way, the resource can be destroyed when the last refcount
// goes away. The single addref that the CreateResource() call
// made will be owned by the callee.
}
return NS_OK;
}
NS_IMETHODIMP
ServiceImpl::UnregisterResource(nsIRDFResource* resource)
{
NS_PRECONDITION(resource != nsnull, "null ptr");
if (! resource)
return NS_ERROR_NULL_POINTER;
nsresult rv;
nsXPIDLCString uri;
rv = resource->GetValue(getter_Copies(uri));
if (NS_FAILED(rv)) return rv;
PLHashEntry** hep = PL_HashTableRawLookup(mResources, (*mResources->keyHash)(uri), uri);
NS_ASSERTION(*hep != nsnull, "resource wasn't registered");
if (! *hep)
return NS_ERROR_FAILURE;
PL_strfree((char*) (*hep)->key);
// N.B. that we _don't_ release the resource: we only held a weak
// reference to it in the hashtable.
PL_HashTableRawRemove(mResources, hep, *hep);
return NS_OK;
}
NS_IMETHODIMP
ServiceImpl::RegisterDataSource(nsIRDFDataSource* aDataSource, PRBool replace)
{
NS_PRECONDITION(aDataSource != nsnull, "null ptr");
if (! aDataSource)
return NS_ERROR_NULL_POINTER;
nsresult rv;
nsXPIDLCString uri;
rv = aDataSource->GetURI(getter_Copies(uri));
if (NS_FAILED(rv)) return rv;
PLHashEntry** hep =
PL_HashTableRawLookup(mNamedDataSources, (*mNamedDataSources->keyHash)(uri), uri);
if (*hep) {
if (! replace)
return NS_ERROR_FAILURE; // already registered
// N.B., we only hold a weak reference to the datasource, so
// just replace the old with the new and don't touch any
// refcounts.
(*hep)->value = aDataSource;
}
else {
const char* key = PL_strdup(uri);
if (! key)
return NS_ERROR_OUT_OF_MEMORY;
PL_HashTableAdd(mNamedDataSources, key, aDataSource);
// N.B., we only hold a weak reference to the datasource, so don't
// addref.
}
return NS_OK;
}
NS_IMETHODIMP
ServiceImpl::UnregisterDataSource(nsIRDFDataSource* aDataSource)
{
NS_PRECONDITION(aDataSource != nsnull, "null ptr");
if (! aDataSource)
return NS_ERROR_NULL_POINTER;
nsresult rv;
nsXPIDLCString uri;
rv = aDataSource->GetURI(getter_Copies(uri));
if (NS_FAILED(rv)) return rv;
//NS_ASSERTION(uri != nsnull, "datasource has no URI");
if (! uri)
return NS_ERROR_UNEXPECTED;
PLHashEntry** hep =
PL_HashTableRawLookup(mNamedDataSources, (*mNamedDataSources->keyHash)(uri), uri);
NS_ASSERTION(*hep != nsnull, "datasource was never registered");
if (! *hep)
return NS_ERROR_ILLEGAL_VALUE;
PL_strfree((char*) (*hep)->key);
// N.B., we only held a weak reference to the datasource, so we
// don't release here.
PL_HashTableRawRemove(mNamedDataSources, hep, *hep);
return NS_OK;
}
NS_IMETHODIMP
ServiceImpl::GetDataSource(const char* uri, nsIRDFDataSource** aDataSource)
{
// First, check the cache to see if we already have this
// datasource loaded and initialized.
nsIRDFDataSource* ds =
NS_STATIC_CAST(nsIRDFDataSource*, PL_HashTableLookup(mNamedDataSources, uri));
if (ds) {
NS_ADDREF(ds);
*aDataSource = ds;
return NS_OK;
}
// Nope. So go to the repository to try to create it.
nsresult rv;
nsAutoString rdfName(uri);
static const char kRDFPrefix[] = "rdf:";
PRInt32 pos = rdfName.Find(kRDFPrefix);
if (pos == 0) {
// It's a built-in data source
nsAutoString dataSourceName;
rdfName.Right(dataSourceName, rdfName.Length() - (pos + sizeof(kRDFPrefix) - 1));
nsAutoString progIDStr(NS_RDF_DATASOURCE_PROGID_PREFIX);
progIDStr.Append(dataSourceName);
// Safely convert it to a C-string for the XPCOM APIs
char buf[64];
char* progID = buf;
if (progIDStr.Length() >= sizeof(buf))
progID = new char[progIDStr.Length() + 1];
if (progID == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
progIDStr.ToCString(progID, progIDStr.Length() + 1);
rv = nsComponentManager::CreateInstance(progID, nsnull,
nsIRDFDataSource::GetIID(),
(void**)&ds);
if (progID != buf)
delete[] progID;
}
else {
// Try to load this as an RDF/XML data source
rv = nsComponentManager::CreateInstance(kRDFXMLDataSourceCID,
nsnull,
nsIRDFDataSource::GetIID(),
(void**) &ds);
// XXX hack for now: make sure that the data source is
// synchronously loaded. In the long run, we should factor out
// the "loading" from the "creating". See nsRDFXMLDataSource::Init().
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIRDFXMLDataSource> rdfxmlDataSource(do_QueryInterface(ds));
NS_ASSERTION(rdfxmlDataSource, "not an RDF/XML data source!");
if (rdfxmlDataSource) {
rv = rdfxmlDataSource->SetSynchronous(PR_TRUE);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to make RDF/XML data source synchronous");
}
}
}
if (NS_FAILED(rv)) {
// XXX only a warning, because the URI may have been ill-formed.
NS_WARNING("unable to create data source");
return rv;
}
rv = ds->Init(uri);
if (NS_FAILED(rv)) {
NS_RELEASE(ds);
NS_ERROR("unable to initialize data source");
return rv;
}
*aDataSource = ds;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
nsresult
ServiceImpl::RegisterLiteral(nsIRDFLiteral* aLiteral, PRBool aReplace)
{
NS_PRECONDITION(aLiteral != nsnull, "null ptr");
nsresult rv;
nsXPIDLString value;
rv = aLiteral->GetValue(getter_Copies(value));
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get literal's value");
if (NS_FAILED(rv)) return rv;
nsIRDFLiteral* prevLiteral =
NS_STATIC_CAST(nsIRDFLiteral*, PL_HashTableLookup(mLiterals, value));
if (prevLiteral) {
if (aReplace) {
NS_RELEASE(prevLiteral);
// XXXwaterson LEAK! free the previous key
}
else {
NS_WARNING("literal already registered and replace not specified");
return NS_ERROR_FAILURE;
}
}
const PRUnichar* key = nsXPIDLString::Copy(value);
if (! key)
return NS_ERROR_OUT_OF_MEMORY;
PL_HashTableAdd(mLiterals, key, aLiteral);
return NS_OK;
}
nsresult
ServiceImpl::UnregisterLiteral(nsIRDFLiteral* aLiteral)
{
NS_PRECONDITION(aLiteral != nsnull, "null ptr");
nsresult rv;
nsXPIDLString value;
rv = aLiteral->GetValue(getter_Copies(value));
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get literal's value");
if (NS_FAILED(rv)) return rv;
PL_HashTableRemove(mLiterals, value);
// XXXwaterson LEAK! free the key
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
nsresult
NS_NewRDFService(nsIRDFService** mgr)
{
return ServiceImpl::GetRDFService(mgr);
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,186 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/* We need this because Solaris' version of qsort is broken and
* causes array bounds reads.
*/
#include <stdlib.h>
#include "prtypes.h"
#if !defined(DEBUG) && (defined(__cplusplus) || defined(__gcc))
# ifndef INLINE
# define INLINE inline
# endif
#else
# define INLINE
#endif
typedef int cmp_t(const void *, const void *, void *);
static INLINE char *med3(char *, char *, char *, cmp_t *, void *);
static INLINE void swapfunc(char *, char *, int, int);
/*
* Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
*/
#define swapcode(TYPE, parmi, parmj, n) { \
long i = (n) / sizeof (TYPE); \
register TYPE *pi = (TYPE *) (parmi); \
register TYPE *pj = (TYPE *) (parmj); \
do { \
register TYPE t = *pi; \
*pi++ = *pj; \
*pj++ = t; \
} while (--i > 0); \
}
#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
static INLINE void
swapfunc(a, b, n, swaptype)
char *a, *b;
int n, swaptype;
{
if(swaptype <= 1)
swapcode(long, a, b, n)
else
swapcode(char, a, b, n)
}
#define swap(a, b) \
if (swaptype == 0) { \
long t = *(long *)(a); \
*(long *)(a) = *(long *)(b); \
*(long *)(b) = t; \
} else \
swapfunc(a, b, es, swaptype)
#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
static INLINE char *
med3(a, b, c, cmp, data)
char *a, *b, *c;
cmp_t *cmp;
void *data;
{
return cmp(a, b, data) < 0 ?
(cmp(b, c, data) < 0 ? b : (cmp(a, c, data) < 0 ? c : a ))
:(cmp(b, c, data) > 0 ? b : (cmp(a, c, data) < 0 ? a : c ));
}
void rdf_qsort (
void *a,
unsigned n,
unsigned es,
cmp_t *cmp,
void *data
)
{
char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
int d, r, swaptype, swap_cnt;
loop: SWAPINIT(a, es);
swap_cnt = 0;
if (n < 7) {
for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
for (pl = pm; pl > (char *)a && cmp(pl - es, pl, data) > 0;
pl -= es)
swap(pl, pl - es);
return;
}
pm = (char *)a + (n / 2) * es;
if (n > 7) {
pl = a;
pn = (char *)a + (n - 1) * es;
if (n > 40) {
d = (n / 8) * es;
pl = med3(pl, pl + d, pl + 2 * d, cmp, data);
pm = med3(pm - d, pm, pm + d, cmp, data);
pn = med3(pn - 2 * d, pn - d, pn, cmp, data);
}
pm = med3(pl, pm, pn, cmp, data);
}
swap(a, pm);
pa = pb = (char *)a + es;
pc = pd = (char *)a + (n - 1) * es;
for (;;) {
while (pb <= pc && (r = cmp(pb, a, data)) <= 0) {
if (r == 0) {
swap_cnt = 1;
swap(pa, pb);
pa += es;
}
pb += es;
}
while (pb <= pc && (r = cmp(pc, a, data)) >= 0) {
if (r == 0) {
swap_cnt = 1;
swap(pc, pd);
pd -= es;
}
pc -= es;
}
if (pb > pc)
break;
swap(pb, pc);
swap_cnt = 1;
pb += es;
pc -= es;
}
if (swap_cnt == 0) { /* Switch to insertion sort */
for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
for (pl = pm; pl > (char *)a && cmp(pl - es, pl, data) > 0;
pl -= es)
swap(pl, pl - es);
return;
}
pn = (char *)a + n * es;
r = PR_MIN(pa - (char *)a, pb - pa);
vecswap(a, pb - r, r);
r = PR_MIN(pd - pc, pn - pd - es);
vecswap(pb, pn - r, r);
if ((r = pb - pa) > es)
rdf_qsort(a, r / es, es, cmp, data);
if ((r = pd - pc) > es) {
/* Iterate rather than recurse to save stack space */
a = pn - r;
n = r / es;
goto loop;
}
/* rdf_qsort(pn - r, r / es, es, cmp, data);*/
}

View File

@@ -1,222 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
/*
Implementations for a bunch of useful RDF utility routines. Many of
these will eventually be exported outside of RDF.DLL via the
nsIRDFService interface.
TO DO
1) Make this so that it doesn't permanently leak the RDF service
object.
2) Make container functions thread-safe. They currently don't ensure
that the RDF:nextVal property is maintained safely.
*/
#include "nsCOMPtr.h"
#include "nsIRDFDataSource.h"
#include "nsIRDFNode.h"
#include "nsIRDFService.h"
#include "nsIServiceManager.h"
#include "nsRDFCID.h"
#include "nsString.h"
#include "nsXPIDLString.h"
#include "plstr.h"
#include "prprf.h"
#include "rdfutil.h"
#include "rdf.h"
static const char kRDFNameSpaceURI[] = RDF_NAMESPACE_URI;
////////////////////////////////////////////////////////////////////////
static NS_DEFINE_IID(kIRDFResourceIID, NS_IRDFRESOURCE_IID);
static NS_DEFINE_IID(kIRDFLiteralIID, NS_IRDFLITERAL_IID);
static NS_DEFINE_IID(kIRDFServiceIID, NS_IRDFSERVICE_IID);
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
////////////////////////////////////////////////////////////////////////
// XXX This'll permanently leak
static nsIRDFService* gRDFService = nsnull;
static nsIRDFResource* kRDF_instanceOf = nsnull;
static nsIRDFResource* kRDF_Bag = nsnull;
static nsIRDFResource* kRDF_Seq = nsnull;
static nsIRDFResource* kRDF_Alt = nsnull;
static nsIRDFResource* kRDF_nextVal = nsnull;
static nsresult
rdf_EnsureRDFService(void)
{
if (gRDFService)
return NS_OK;
nsresult rv;
rv = nsServiceManager::GetService(kRDFServiceCID,
kIRDFServiceIID,
(nsISupports**) &gRDFService);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get RDF service");
if (NS_FAILED(rv)) return rv;
rv = gRDFService->GetResource(RDF_NAMESPACE_URI "instanceOf", &kRDF_instanceOf);
rv = gRDFService->GetResource(RDF_NAMESPACE_URI "Bag", &kRDF_Bag);
rv = gRDFService->GetResource(RDF_NAMESPACE_URI "Seq", &kRDF_Seq);
rv = gRDFService->GetResource(RDF_NAMESPACE_URI "Alt", &kRDF_Alt);
rv = gRDFService->GetResource(RDF_NAMESPACE_URI "nextVal", &kRDF_nextVal);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
PR_IMPLEMENT(PRBool)
rdf_IsA(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource, nsIRDFResource* aType)
{
nsresult rv;
rv = rdf_EnsureRDFService();
if (NS_FAILED(rv)) return PR_FALSE;
PRBool result;
rv = aDataSource->HasAssertion(aResource, kRDF_instanceOf, aType, PR_TRUE, &result);
if (NS_FAILED(rv)) return PR_FALSE;
return result;
}
nsresult
rdf_CreateAnonymousResource(const nsString& aContextURI, nsIRDFResource** aResult)
{
static PRUint32 gCounter = 0;
nsresult rv;
rv = rdf_EnsureRDFService();
if (NS_FAILED(rv)) return rv;
do {
nsAutoString s(aContextURI);
s.Append("#$");
s.Append(++gCounter, 10);
nsIRDFResource* resource;
if (NS_FAILED(rv = gRDFService->GetUnicodeResource(s.GetUnicode(), &resource)))
return rv;
// XXX an ugly but effective way to make sure that this
// resource is really unique in the world.
nsrefcnt refcnt = resource->AddRef();
resource->Release();
if (refcnt == 2) {
*aResult = resource;
break;
}
} while (1);
return NS_OK;
}
PRBool
rdf_IsAnonymousResource(const nsString& aContextURI, nsIRDFResource* aResource)
{
nsresult rv;
nsXPIDLCString s;
if (NS_FAILED(rv = aResource->GetValue( getter_Copies(s) ))) {
NS_ASSERTION(PR_FALSE, "unable to get resource URI");
return PR_FALSE;
}
nsAutoString uri((const char*) s);
// Make sure that they have the same context (prefix)
if (uri.Find(aContextURI) != 0)
return PR_FALSE;
uri.Cut(0, aContextURI.Length());
// Anonymous resources look like the regexp "\$[0-9]+"
if (uri.CharAt(0) != '#' || uri.CharAt(1) != '$')
return PR_FALSE;
for (PRInt32 i = uri.Length() - 1; i >= 1; --i) {
if (uri.CharAt(i) < '0' || uri.CharAt(i) > '9')
return PR_FALSE;
}
return PR_TRUE;
}
PR_EXTERN(nsresult)
rdf_PossiblyMakeRelative(const nsString& aContextURI, nsString& aURI)
{
// This implementation is extremely simple: no ".." or anything
// fancy like that. If the context URI is not a prefix of the URI
// in question, we'll just bail.
if (aURI.Find(aContextURI) != 0)
return NS_OK;
// Otherwise, pare down the target URI, removing the context URI.
aURI.Cut(0, aContextURI.Length());
if (aURI.First() == '#' || aURI.First() == '/')
aURI.Cut(0, 1);
return NS_OK;
}
PR_EXTERN(nsresult)
rdf_PossiblyMakeAbsolute(const nsString& aContextURI, nsString& aURI)
{
PRInt32 index = aURI.Find(':');
if (index > 0 && index < 25 /* XXX */)
return NS_OK;
PRUnichar last = aContextURI.Last();
PRUnichar first = aURI.First();
nsAutoString result(aContextURI);
if (last == '#' || last == '/') {
if (first == '#') {
result.Truncate(result.Length() - 2);
}
result.Append(aURI);
}
else if (first == '#') {
result.Append(aURI);
}
else {
result.Append('#');
result.Append(aURI);
}
aURI = result;
return NS_OK;
}

View File

@@ -1,89 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
/*
A bunch of useful RDF utility routines. Many of these will
eventually be exported outside of RDF.DLL via the nsIRDFService
interface.
TO DO
1) Create an nsIRDFContainerService and lump all the container
utilities there.
2) Move the anonymous resource stuff to nsIRDFService
3) All that's left is rdf_PossiblyMakeRelative() and
-Absolute(). Maybe those go on nsIRDFService, too.
*/
#ifndef rdfutil_h__
#define rdfutil_h__
#include "prtypes.h"
class nsIRDFDataSource;
class nsISimpleEnumerator;
class nsIRDFResource;
class nsIRDFNode;
class nsIRDFResource;
class nsString;
/**
* The dreaded is-a function. Uses rdf:instanceOf to determine if aResource is aType.
*/
PR_EXTERN(PRBool)
rdf_IsA(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource, nsIRDFResource* aType);
/**
* Construct a new, "anonymous" node; that is, a node with an internal
* resource URI.
*/
PR_EXTERN(nsresult)
rdf_CreateAnonymousResource(const nsString& aContextURI, nsIRDFResource** result);
/**
* Determine if a resource is an "anonymous" resource that we've constructed
* ourselves.
*/
PR_EXTERN(PRBool)
rdf_IsAnonymousResource(const nsString& aContextURI, nsIRDFResource* aResource);
/**
* Try to convert the absolute URL into a relative URL.
*/
PR_EXTERN(nsresult)
rdf_PossiblyMakeRelative(const nsString& aContextURI, nsString& aURI);
/**
* Try to convert the possibly-relative URL into an absolute URL.
*/
PR_EXTERN(nsresult)
rdf_PossiblyMakeAbsolute(const nsString& aContextURI, nsString& aURI);
PR_EXTERN(void) SHTtest ();
#endif // rdfutil_h__

View File

@@ -1,29 +0,0 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH = ../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = public src build
include $(topsrcdir)/config/config.mk
include $(topsrcdir)/config/rules.mk

View File

@@ -1,70 +0,0 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH=../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/config.mk
LIBRARY_NAME = brprof
IS_COMPONENT = 1
CPPSRCS = \
nsBrowsingProfileFactory.cpp \
$(NULL)
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
MODULE = brprof
REQUIRES = xpcom
SHARED_LIBRARY_LIBS = \
$(DIST)/lib/libbrprof_s.a \
$(NULL)
ifeq ($(OS_ARCH),HP-UX)
EXTRA_DSO_LDOPTS = -c objs/objslist
else
EXTRA_DSO_LDOPTS = \
$(MKSHLIB_FORCE_ALL) \
$(SHARED_LIBRARY_LIBS) \
$(MKSHLIB_UNFORCE_ALL)
endif
EXTRA_DSO_LDOPTS += -L$(DIST)/bin $(NULL)
include $(topsrcdir)/config/rules.mk
ifeq ($(OS_ARCH),HP-UX)
shared_library_objs: $(SHARED_LIBRARY_LIBS)
rm -rf objs
mkdir objs
(cd objs; for lib in $(SHARED_LIBRARY_LIBS); do ar xv ../$$lib; done) \
| awk '{ print "objs/"$$3 }' > objs/objslist
$(LIBRARY) $(SHARED_LIBRARY): shared_library_objs Makefile
else
$(LIBRARY) $(SHARED_LIBRARY): $(SHARED_LIBRARY_LIBS) Makefile
endif
install:: $(TARGETS)
$(INSTALL) $(srcdir)/directory.rdf $(DIST)/bin/res/samples

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More