1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552 |
- /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- *
- * This Original Code has been modified by IBM Corporation.
- * Modifications made by IBM described herein are
- * Copyright (c) International Business Machines
- * Corporation, 2000
- *
- * Modifications to Mozilla code or documentation
- * identified per MPL Section 3.3
- *
- * Date Modified by Description of modification
- * 03/27/2000 IBM Corp. Added PR_CALLBACK for Optlink
- * use in OS2
- */
- /*
- This file provides the implementation for the RDF service manager.
- TO DO
- -----
- 1) Implement the CreateDataBase() methods.
- 2) Cache date and int literals.
- */
- #include "nsRDFService.h"
- #include "nsCOMPtr.h"
- #include "nsAutoPtr.h"
- #include "nsMemory.h"
- #include "nsIAtom.h"
- #include "nsIComponentManager.h"
- #include "nsIRDFDataSource.h"
- #include "nsIRDFNode.h"
- #include "nsIRDFRemoteDataSource.h"
- #include "nsIServiceManager.h"
- #include "nsIFactory.h"
- #include "nsRDFCID.h"
- #include "nsString.h"
- #include "nsXPIDLString.h"
- #include "nsNetUtil.h"
- #include "nsIURI.h"
- #include "PLDHashTable.h"
- #include "plhash.h"
- #include "plstr.h"
- #include "mozilla/Logging.h"
- #include "prprf.h"
- #include "prmem.h"
- #include "rdf.h"
- #include "nsCRT.h"
- #include "nsCRTGlue.h"
- #include "mozilla/HashFunctions.h"
- using namespace mozilla;
- ////////////////////////////////////////////////////////////////////////
- static NS_DEFINE_CID(kRDFXMLDataSourceCID, NS_RDFXMLDATASOURCE_CID);
- static NS_DEFINE_CID(kRDFDefaultResourceCID, NS_RDFDEFAULTRESOURCE_CID);
- 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(kIRDFNodeIID, NS_IRDFNODE_IID);
- static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
- static LazyLogModule gLog("nsRDFService");
- class BlobImpl;
- // These functions are copied from nsprpub/lib/ds/plhash.c, with one
- // change to free the key in DataSourceFreeEntry.
- // XXX sigh, why were DefaultAllocTable et. al. declared static, anyway?
- static void *
- DataSourceAllocTable(void *pool, size_t size)
- {
- return PR_MALLOC(size);
- }
- static void
- DataSourceFreeTable(void *pool, void *item)
- {
- PR_Free(item);
- }
- static PLHashEntry *
- DataSourceAllocEntry(void *pool, const void *key)
- {
- return PR_NEW(PLHashEntry);
- }
- static void
- DataSourceFreeEntry(void *pool, PLHashEntry *he, unsigned flag)
- {
- if (flag == HT_FREE_ENTRY) {
- PL_strfree((char*) he->key);
- PR_Free(he);
- }
- }
- static PLHashAllocOps dataSourceHashAllocOps = {
- DataSourceAllocTable, DataSourceFreeTable,
- DataSourceAllocEntry, DataSourceFreeEntry
- };
- //----------------------------------------------------------------------
- //
- // For the mResources hashtable.
- //
- struct ResourceHashEntry : public PLDHashEntryHdr {
- const char *mKey;
- nsIRDFResource *mResource;
- static PLDHashNumber
- HashKey(const void *key)
- {
- return HashString(static_cast<const char *>(key));
- }
- static bool
- MatchEntry(const PLDHashEntryHdr *hdr, const void *key)
- {
- const ResourceHashEntry *entry =
- static_cast<const ResourceHashEntry *>(hdr);
- return 0 == nsCRT::strcmp(static_cast<const char *>(key),
- entry->mKey);
- }
- };
- static const PLDHashTableOps gResourceTableOps = {
- ResourceHashEntry::HashKey,
- ResourceHashEntry::MatchEntry,
- PLDHashTable::MoveEntryStub,
- PLDHashTable::ClearEntryStub,
- nullptr
- };
- // ----------------------------------------------------------------------
- //
- // For the mLiterals hashtable.
- //
- struct LiteralHashEntry : public PLDHashEntryHdr {
- nsIRDFLiteral *mLiteral;
- const char16_t *mKey;
- static PLDHashNumber
- HashKey(const void *key)
- {
- return HashString(static_cast<const char16_t *>(key));
- }
- static bool
- MatchEntry(const PLDHashEntryHdr *hdr, const void *key)
- {
- const LiteralHashEntry *entry =
- static_cast<const LiteralHashEntry *>(hdr);
- return 0 == nsCRT::strcmp(static_cast<const char16_t *>(key),
- entry->mKey);
- }
- };
- static const PLDHashTableOps gLiteralTableOps = {
- LiteralHashEntry::HashKey,
- LiteralHashEntry::MatchEntry,
- PLDHashTable::MoveEntryStub,
- PLDHashTable::ClearEntryStub,
- nullptr
- };
- // ----------------------------------------------------------------------
- //
- // For the mInts hashtable.
- //
- struct IntHashEntry : public PLDHashEntryHdr {
- nsIRDFInt *mInt;
- int32_t mKey;
- static PLDHashNumber
- HashKey(const void *key)
- {
- return PLDHashNumber(*static_cast<const int32_t *>(key));
- }
- static bool
- MatchEntry(const PLDHashEntryHdr *hdr, const void *key)
- {
- const IntHashEntry *entry =
- static_cast<const IntHashEntry *>(hdr);
- return *static_cast<const int32_t *>(key) == entry->mKey;
- }
- };
- static const PLDHashTableOps gIntTableOps = {
- IntHashEntry::HashKey,
- IntHashEntry::MatchEntry,
- PLDHashTable::MoveEntryStub,
- PLDHashTable::ClearEntryStub,
- nullptr
- };
- // ----------------------------------------------------------------------
- //
- // For the mDates hashtable.
- //
- struct DateHashEntry : public PLDHashEntryHdr {
- nsIRDFDate *mDate;
- PRTime mKey;
- static PLDHashNumber
- HashKey(const void *key)
- {
- // xor the low 32 bits with the high 32 bits.
- PRTime t = *static_cast<const PRTime *>(key);
- int32_t h32 = int32_t(t >> 32);
- int32_t l32 = int32_t(0xffffffff & t);
- return PLDHashNumber(l32 ^ h32);
- }
- static bool
- MatchEntry(const PLDHashEntryHdr *hdr, const void *key)
- {
- const DateHashEntry *entry =
- static_cast<const DateHashEntry *>(hdr);
- return *static_cast<const PRTime *>(key) == entry->mKey;
- }
- };
- static const PLDHashTableOps gDateTableOps = {
- DateHashEntry::HashKey,
- DateHashEntry::MatchEntry,
- PLDHashTable::MoveEntryStub,
- PLDHashTable::ClearEntryStub,
- nullptr
- };
- class BlobImpl : public nsIRDFBlob
- {
- public:
- struct Data {
- int32_t mLength;
- uint8_t *mBytes;
- };
- BlobImpl(const uint8_t *aBytes, int32_t aLength)
- {
- mData.mLength = aLength;
- mData.mBytes = new uint8_t[aLength];
- memcpy(mData.mBytes, aBytes, aLength);
- NS_ADDREF(RDFServiceImpl::gRDFService);
- RDFServiceImpl::gRDFService->RegisterBlob(this);
- }
- protected:
- virtual ~BlobImpl()
- {
- RDFServiceImpl::gRDFService->UnregisterBlob(this);
- // Use NS_RELEASE2() here, because we want to decrease the
- // refcount, but not null out the gRDFService pointer (which is
- // what a vanilla NS_RELEASE() would do).
- nsrefcnt refcnt;
- NS_RELEASE2(RDFServiceImpl::gRDFService, refcnt);
- delete[] mData.mBytes;
- }
- public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSIRDFNODE
- NS_DECL_NSIRDFBLOB
- Data mData;
- };
- NS_IMPL_ISUPPORTS(BlobImpl, nsIRDFNode, nsIRDFBlob)
- NS_IMETHODIMP
- BlobImpl::EqualsNode(nsIRDFNode *aNode, bool *aEquals)
- {
- nsCOMPtr<nsIRDFBlob> blob = do_QueryInterface(aNode);
- if (blob) {
- int32_t length;
- blob->GetLength(&length);
- if (length == mData.mLength) {
- const uint8_t *bytes;
- blob->GetValue(&bytes);
- if (0 == memcmp(bytes, mData.mBytes, length)) {
- *aEquals = true;
- return NS_OK;
- }
- }
- }
- *aEquals = false;
- return NS_OK;
- }
- NS_IMETHODIMP
- BlobImpl::GetValue(const uint8_t **aResult)
- {
- *aResult = mData.mBytes;
- return NS_OK;
- }
- NS_IMETHODIMP
- BlobImpl::GetLength(int32_t *aResult)
- {
- *aResult = mData.mLength;
- return NS_OK;
- }
- // ----------------------------------------------------------------------
- //
- // For the mBlobs hashtable.
- //
- struct BlobHashEntry : public PLDHashEntryHdr {
- BlobImpl *mBlob;
- static PLDHashNumber
- HashKey(const void *key)
- {
- const BlobImpl::Data *data =
- static_cast<const BlobImpl::Data *>(key);
- return HashBytes(data->mBytes, data->mLength);
- }
- static bool
- MatchEntry(const PLDHashEntryHdr *hdr, const void *key)
- {
- const BlobHashEntry *entry =
- static_cast<const BlobHashEntry *>(hdr);
- const BlobImpl::Data *left = &entry->mBlob->mData;
- const BlobImpl::Data *right =
- static_cast<const BlobImpl::Data *>(key);
- return (left->mLength == right->mLength)
- && 0 == memcmp(left->mBytes, right->mBytes, right->mLength);
- }
- };
- static const PLDHashTableOps gBlobTableOps = {
- BlobHashEntry::HashKey,
- BlobHashEntry::MatchEntry,
- PLDHashTable::MoveEntryStub,
- PLDHashTable::ClearEntryStub,
- nullptr
- };
- ////////////////////////////////////////////////////////////////////////
- // 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:
- static nsresult
- Create(const char16_t* aValue, nsIRDFLiteral** aResult);
- // nsISupports
- NS_DECL_THREADSAFE_ISUPPORTS
- // nsIRDFNode
- NS_DECL_NSIRDFNODE
- // nsIRDFLiteral
- NS_DECL_NSIRDFLITERAL
- protected:
- explicit LiteralImpl(const char16_t* s);
- virtual ~LiteralImpl();
- const char16_t* GetValue() const {
- size_t objectSize = ((sizeof(LiteralImpl) + sizeof(char16_t) - 1) / sizeof(char16_t)) * sizeof(char16_t);
- return reinterpret_cast<const char16_t*>(reinterpret_cast<const unsigned char*>(this) + objectSize);
- }
- };
- nsresult
- LiteralImpl::Create(const char16_t* aValue, nsIRDFLiteral** aResult)
- {
- // Goofy math to get alignment right. Copied from nsSharedString.h.
- size_t objectSize = ((sizeof(LiteralImpl) + sizeof(char16_t) - 1) / sizeof(char16_t)) * sizeof(char16_t);
- size_t stringLen = nsCharTraits<char16_t>::length(aValue);
- size_t stringSize = (stringLen + 1) * sizeof(char16_t);
- void* objectPtr = operator new(objectSize + stringSize);
- if (! objectPtr)
- return NS_ERROR_NULL_POINTER;
- char16_t* buf = reinterpret_cast<char16_t*>(static_cast<unsigned char*>(objectPtr) + objectSize);
- nsCharTraits<char16_t>::copy(buf, aValue, stringLen + 1);
- NS_ADDREF(*aResult = new (objectPtr) LiteralImpl(buf));
- return NS_OK;
- }
- LiteralImpl::LiteralImpl(const char16_t* s)
- {
- RDFServiceImpl::gRDFService->RegisterLiteral(this);
- NS_ADDREF(RDFServiceImpl::gRDFService);
- }
- LiteralImpl::~LiteralImpl()
- {
- RDFServiceImpl::gRDFService->UnregisterLiteral(this);
- // Use NS_RELEASE2() here, because we want to decrease the
- // refcount, but not null out the gRDFService pointer (which is
- // what a vanilla NS_RELEASE() would do).
- nsrefcnt refcnt;
- NS_RELEASE2(RDFServiceImpl::gRDFService, refcnt);
- }
- NS_IMPL_ADDREF(LiteralImpl)
- NS_IMPL_RELEASE(LiteralImpl)
- nsresult
- LiteralImpl::QueryInterface(REFNSIID iid, void** result)
- {
- if (! result)
- return NS_ERROR_NULL_POINTER;
- *result = nullptr;
- if (iid.Equals(kIRDFLiteralIID) ||
- iid.Equals(kIRDFNodeIID) ||
- iid.Equals(kISupportsIID)) {
- *result = static_cast<nsIRDFLiteral*>(this);
- AddRef();
- return NS_OK;
- }
- return NS_NOINTERFACE;
- }
- NS_IMETHODIMP
- LiteralImpl::EqualsNode(nsIRDFNode* aNode, bool* aResult)
- {
- nsresult rv;
- nsIRDFLiteral* literal;
- rv = aNode->QueryInterface(kIRDFLiteralIID, (void**) &literal);
- if (NS_SUCCEEDED(rv)) {
- *aResult = (static_cast<nsIRDFLiteral*>(this) == literal);
- NS_RELEASE(literal);
- return NS_OK;
- }
- else if (rv == NS_NOINTERFACE) {
- *aResult = false;
- return NS_OK;
- }
- else {
- return rv;
- }
- }
- NS_IMETHODIMP
- LiteralImpl::GetValue(char16_t* *value)
- {
- NS_ASSERTION(value, "null ptr");
- if (! value)
- return NS_ERROR_NULL_POINTER;
- const char16_t *temp = GetValue();
- *value = temp? NS_strdup(temp) : 0;
- return NS_OK;
- }
- NS_IMETHODIMP
- LiteralImpl::GetValueConst(const char16_t** aValue)
- {
- *aValue = GetValue();
- return NS_OK;
- }
- ////////////////////////////////////////////////////////////////////////
- // DateImpl
- //
- class DateImpl : public nsIRDFDate {
- public:
- explicit DateImpl(const PRTime s);
- // nsISupports
- NS_DECL_ISUPPORTS
- // nsIRDFNode
- NS_DECL_NSIRDFNODE
- // nsIRDFDate
- NS_IMETHOD GetValue(PRTime *value) override;
- private:
- virtual ~DateImpl();
- nsresult EqualsDate(nsIRDFDate* date, bool* result);
- PRTime mValue;
- };
- DateImpl::DateImpl(const PRTime s)
- : mValue(s)
- {
- RDFServiceImpl::gRDFService->RegisterDate(this);
- NS_ADDREF(RDFServiceImpl::gRDFService);
- }
- DateImpl::~DateImpl()
- {
- RDFServiceImpl::gRDFService->UnregisterDate(this);
- // Use NS_RELEASE2() here, because we want to decrease the
- // refcount, but not null out the gRDFService pointer (which is
- // what a vanilla NS_RELEASE() would do).
- nsrefcnt refcnt;
- NS_RELEASE2(RDFServiceImpl::gRDFService, refcnt);
- }
- NS_IMPL_ADDREF(DateImpl)
- NS_IMPL_RELEASE(DateImpl)
- nsresult
- DateImpl::QueryInterface(REFNSIID iid, void** result)
- {
- if (! result)
- return NS_ERROR_NULL_POINTER;
- *result = nullptr;
- if (iid.Equals(kIRDFDateIID) ||
- iid.Equals(kIRDFNodeIID) ||
- iid.Equals(kISupportsIID)) {
- *result = static_cast<nsIRDFDate*>(this);
- AddRef();
- return NS_OK;
- }
- return NS_NOINTERFACE;
- }
- NS_IMETHODIMP
- DateImpl::EqualsNode(nsIRDFNode* node, bool* result)
- {
- nsresult rv;
- nsIRDFDate* date;
- if (NS_SUCCEEDED(node->QueryInterface(kIRDFDateIID, (void**) &date))) {
- rv = EqualsDate(date, result);
- NS_RELEASE(date);
- }
- else {
- *result = 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;
- }
- nsresult
- DateImpl::EqualsDate(nsIRDFDate* date, bool* 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 = p == mValue;
- return NS_OK;
- }
- ////////////////////////////////////////////////////////////////////////
- // IntImpl
- //
- class IntImpl : public nsIRDFInt {
- public:
- explicit IntImpl(int32_t s);
- // nsISupports
- NS_DECL_ISUPPORTS
- // nsIRDFNode
- NS_DECL_NSIRDFNODE
- // nsIRDFInt
- NS_IMETHOD GetValue(int32_t *value) override;
- private:
- virtual ~IntImpl();
- nsresult EqualsInt(nsIRDFInt* value, bool* result);
- int32_t mValue;
- };
- IntImpl::IntImpl(int32_t s)
- : mValue(s)
- {
- RDFServiceImpl::gRDFService->RegisterInt(this);
- NS_ADDREF(RDFServiceImpl::gRDFService);
- }
- IntImpl::~IntImpl()
- {
- RDFServiceImpl::gRDFService->UnregisterInt(this);
- // Use NS_RELEASE2() here, because we want to decrease the
- // refcount, but not null out the gRDFService pointer (which is
- // what a vanilla NS_RELEASE() would do).
- nsrefcnt refcnt;
- NS_RELEASE2(RDFServiceImpl::gRDFService, refcnt);
- }
- NS_IMPL_ADDREF(IntImpl)
- NS_IMPL_RELEASE(IntImpl)
- nsresult
- IntImpl::QueryInterface(REFNSIID iid, void** result)
- {
- if (! result)
- return NS_ERROR_NULL_POINTER;
- *result = nullptr;
- if (iid.Equals(kIRDFIntIID) ||
- iid.Equals(kIRDFNodeIID) ||
- iid.Equals(kISupportsIID)) {
- *result = static_cast<nsIRDFInt*>(this);
- AddRef();
- return NS_OK;
- }
- return NS_NOINTERFACE;
- }
- NS_IMETHODIMP
- IntImpl::EqualsNode(nsIRDFNode* node, bool* result)
- {
- nsresult rv;
- nsIRDFInt* intValue;
- if (NS_SUCCEEDED(node->QueryInterface(kIRDFIntIID, (void**) &intValue))) {
- rv = EqualsInt(intValue, result);
- NS_RELEASE(intValue);
- }
- else {
- *result = false;
- rv = NS_OK;
- }
- return rv;
- }
- NS_IMETHODIMP
- IntImpl::GetValue(int32_t *value)
- {
- NS_ASSERTION(value, "null ptr");
- if (! value)
- return NS_ERROR_NULL_POINTER;
- *value = mValue;
- return NS_OK;
- }
- nsresult
- IntImpl::EqualsInt(nsIRDFInt* intValue, bool* result)
- {
- NS_ASSERTION(intValue && result, "null ptr");
- if (!intValue || !result)
- return NS_ERROR_NULL_POINTER;
- nsresult rv;
- int32_t p;
- if (NS_FAILED(rv = intValue->GetValue(&p)))
- return rv;
- *result = (p == mValue);
- return NS_OK;
- }
- ////////////////////////////////////////////////////////////////////////
- // RDFServiceImpl
- RDFServiceImpl*
- RDFServiceImpl::gRDFService;
- RDFServiceImpl::RDFServiceImpl()
- : mNamedDataSources(nullptr)
- , mResources(&gResourceTableOps, sizeof(ResourceHashEntry))
- , mLiterals(&gLiteralTableOps, sizeof(LiteralHashEntry))
- , mInts(&gIntTableOps, sizeof(IntHashEntry))
- , mDates(&gDateTableOps, sizeof(DateHashEntry))
- , mBlobs(&gBlobTableOps, sizeof(BlobHashEntry))
- {
- gRDFService = this;
- }
- nsresult
- RDFServiceImpl::Init()
- {
- nsresult rv;
- mNamedDataSources = PL_NewHashTable(23,
- PL_HashString,
- PL_CompareStrings,
- PL_CompareValues,
- &dataSourceHashAllocOps, nullptr);
- if (! mNamedDataSources)
- return NS_ERROR_OUT_OF_MEMORY;
- mDefaultResourceFactory = do_GetClassObject(kRDFDefaultResourceCID, &rv);
- NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get default resource factory");
- if (NS_FAILED(rv)) return rv;
- return NS_OK;
- }
- RDFServiceImpl::~RDFServiceImpl()
- {
- if (mNamedDataSources) {
- PL_HashTableDestroy(mNamedDataSources);
- mNamedDataSources = nullptr;
- }
- gRDFService = nullptr;
- }
- // static
- nsresult
- RDFServiceImpl::CreateSingleton(nsISupports* aOuter,
- const nsIID& aIID, void **aResult)
- {
- NS_ENSURE_NO_AGGREGATION(aOuter);
- if (gRDFService) {
- NS_ERROR("Trying to create RDF serviec twice.");
- return gRDFService->QueryInterface(aIID, aResult);
- }
- RefPtr<RDFServiceImpl> serv = new RDFServiceImpl();
- nsresult rv = serv->Init();
- if (NS_FAILED(rv))
- return rv;
- return serv->QueryInterface(aIID, aResult);
- }
- NS_IMPL_ISUPPORTS(RDFServiceImpl, nsIRDFService, nsISupportsWeakReference)
- // Per RFC2396.
- static const uint8_t
- kLegalSchemeChars[] = {
- // ASCII Bits Ordered Hex
- // 01234567 76543210
- 0x00, // 00-07
- 0x00, // 08-0F
- 0x00, // 10-17
- 0x00, // 18-1F
- 0x00, // 20-27 !"#$%&' 00000000 00000000
- 0x28, // 28-2F ()*+,-./ 00010100 00101000 0x28
- 0xff, // 30-37 01234567 11111111 11111111 0xFF
- 0x03, // 38-3F 89:;<=>? 11000000 00000011 0x03
- 0xfe, // 40-47 @ABCDEFG 01111111 11111110 0xFE
- 0xff, // 48-4F HIJKLMNO 11111111 11111111 0xFF
- 0xff, // 50-57 PQRSTUVW 11111111 11111111 0xFF
- 0x87, // 58-5F XYZ[\]^_ 11100001 10000111 0x87
- 0xfe, // 60-67 `abcdefg 01111111 11111110 0xFE
- 0xff, // 68-6F hijklmno 11111111 11111111 0xFF
- 0xff, // 70-77 pqrstuvw 11111111 11111111 0xFF
- 0x07, // 78-7F xyz{|}~ 11100000 00000111 0x07
- 0x00, 0x00, 0x00, 0x00, // >= 80
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00
- };
- static inline bool
- IsLegalSchemeCharacter(const char aChar)
- {
- uint8_t mask = kLegalSchemeChars[aChar >> 3];
- uint8_t bit = 1u << (aChar & 0x7);
- return bool((mask & bit) != 0);
- }
- NS_IMETHODIMP
- RDFServiceImpl::GetResource(const nsACString& aURI, nsIRDFResource** aResource)
- {
- // Sanity checks
- NS_PRECONDITION(aResource != nullptr, "null ptr");
- NS_PRECONDITION(!aURI.IsEmpty(), "URI is empty");
- if (! aResource)
- return NS_ERROR_NULL_POINTER;
- if (aURI.IsEmpty())
- return NS_ERROR_INVALID_ARG;
- const nsAFlatCString& flatURI = PromiseFlatCString(aURI);
- MOZ_LOG(gLog, LogLevel::Debug, ("rdfserv get-resource %s", flatURI.get()));
- // First, check the cache to see if we've already created and
- // registered this thing.
- PLDHashEntryHdr *hdr = mResources.Search(flatURI.get());
- if (hdr) {
- ResourceHashEntry *entry = static_cast<ResourceHashEntry *>(hdr);
- NS_ADDREF(*aResource = entry->mResource);
- return NS_OK;
- }
- // Nope. So go to the repository to create it.
- // Compute the scheme of the URI. Scan forward until we either:
- //
- // 1. Reach the end of the string
- // 2. Encounter a non-alpha character
- // 3. Encouter a colon.
- //
- // If we encounter a colon _before_ encountering a non-alpha
- // character, then assume it's the scheme.
- //
- // XXX Although it's really not correct, we'll allow underscore
- // characters ('_'), too.
- nsACString::const_iterator p, end;
- aURI.BeginReading(p);
- aURI.EndReading(end);
- while (p != end && IsLegalSchemeCharacter(*p))
- ++p;
- nsresult rv;
- nsCOMPtr<nsIFactory> factory;
- nsACString::const_iterator begin;
- aURI.BeginReading(begin);
- if (*p == ':') {
- // There _was_ a scheme. First see if it's the same scheme
- // that we just tried to use...
- if (mLastFactory && mLastURIPrefix.Equals(Substring(begin, p)))
- factory = mLastFactory;
- else {
- // Try to find a factory using the component manager.
- nsACString::const_iterator begin;
- aURI.BeginReading(begin);
- nsAutoCString contractID;
- contractID = NS_LITERAL_CSTRING(NS_RDF_RESOURCE_FACTORY_CONTRACTID_PREFIX) +
- Substring(begin, p);
- factory = do_GetClassObject(contractID.get());
- if (factory) {
- // Store the factory in our one-element cache.
- if (p != begin) {
- mLastFactory = factory;
- mLastURIPrefix = Substring(begin, p);
- }
- }
- }
- }
- if (! factory) {
- // fall through to using the "default" resource factory if either:
- //
- // 1. The URI didn't have a scheme, or
- // 2. There was no resource factory registered for the scheme.
- factory = mDefaultResourceFactory;
- // Store the factory in our one-element cache.
- if (p != begin) {
- mLastFactory = factory;
- mLastURIPrefix = Substring(begin, p);
- }
- }
- nsIRDFResource *result;
- rv = factory->CreateInstance(nullptr, NS_GET_IID(nsIRDFResource), (void**) &result);
- if (NS_FAILED(rv)) return rv;
- // Now initialize it with its URI. At this point, the resource
- // implementation should register itself with the RDF service.
- rv = result->Init(flatURI.get());
- 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
- RDFServiceImpl::GetUnicodeResource(const nsAString& aURI, nsIRDFResource** aResource)
- {
- return GetResource(NS_ConvertUTF16toUTF8(aURI), aResource);
- }
- NS_IMETHODIMP
- RDFServiceImpl::GetAnonymousResource(nsIRDFResource** aResult)
- {
- static uint32_t gCounter = 0;
- static char gChars[] = "0123456789abcdef"
- "ghijklmnopqrstuv"
- "wxyzABCDEFGHIJKL"
- "MNOPQRSTUVWXYZ.+";
- static int32_t kMask = 0x003f;
- static int32_t kShift = 6;
- if (! gCounter) {
- // Start it at a semi-unique value, just to minimize the
- // chance that we get into a situation where
- //
- // 1. An anonymous resource gets serialized out in a graph
- // 2. Reboot
- // 3. The same anonymous resource gets requested, and refers
- // to something completely different.
- // 4. The serialization is read back in.
- gCounter = uint32_t(PR_Now());
- }
- nsresult rv;
- nsAutoCString s;
- do {
- // Ugh, this is a really sloppy way to do this; I copied the
- // implementation from the days when it lived outside the RDF
- // service. Now that it's a member we can be more cleverer.
- s.Truncate();
- s.AppendLiteral("rdf:#$");
- uint32_t id = ++gCounter;
- while (id) {
- char ch = gChars[(id & kMask)];
- s.Append(ch);
- id >>= kShift;
- }
- nsIRDFResource* resource;
- rv = GetResource(s, &resource);
- if (NS_FAILED(rv)) return rv;
- // XXX an ugly but effective way to make sure that this
- // resource is really unique in the world.
- resource->AddRef();
- nsrefcnt refcnt = resource->Release();
- if (refcnt == 1) {
- *aResult = resource;
- break;
- }
- NS_RELEASE(resource);
- } while (1);
- return NS_OK;
- }
- NS_IMETHODIMP
- RDFServiceImpl::GetLiteral(const char16_t* aValue, nsIRDFLiteral** aLiteral)
- {
- NS_PRECONDITION(aValue != nullptr, "null ptr");
- if (! aValue)
- return NS_ERROR_NULL_POINTER;
- NS_PRECONDITION(aLiteral != nullptr, "null ptr");
- if (! aLiteral)
- return NS_ERROR_NULL_POINTER;
- // See if we have one already cached
- PLDHashEntryHdr *hdr = mLiterals.Search(aValue);
- if (hdr) {
- LiteralHashEntry *entry = static_cast<LiteralHashEntry *>(hdr);
- NS_ADDREF(*aLiteral = entry->mLiteral);
- return NS_OK;
- }
- // Nope. Create a new one
- return LiteralImpl::Create(aValue, aLiteral);
- }
- NS_IMETHODIMP
- RDFServiceImpl::GetDateLiteral(PRTime aTime, nsIRDFDate** aResult)
- {
- // See if we have one already cached
- PLDHashEntryHdr *hdr = mDates.Search(&aTime);
- if (hdr) {
- DateHashEntry *entry = static_cast<DateHashEntry *>(hdr);
- NS_ADDREF(*aResult = entry->mDate);
- return NS_OK;
- }
- DateImpl* result = new DateImpl(aTime);
- if (! result)
- return NS_ERROR_OUT_OF_MEMORY;
- NS_ADDREF(*aResult = result);
- return NS_OK;
- }
- NS_IMETHODIMP
- RDFServiceImpl::GetIntLiteral(int32_t aInt, nsIRDFInt** aResult)
- {
- // See if we have one already cached
- PLDHashEntryHdr *hdr = mInts.Search(&aInt);
- if (hdr) {
- IntHashEntry *entry = static_cast<IntHashEntry *>(hdr);
- NS_ADDREF(*aResult = entry->mInt);
- return NS_OK;
- }
- IntImpl* result = new IntImpl(aInt);
- if (! result)
- return NS_ERROR_OUT_OF_MEMORY;
- NS_ADDREF(*aResult = result);
- return NS_OK;
- }
- NS_IMETHODIMP
- RDFServiceImpl::GetBlobLiteral(const uint8_t *aBytes, int32_t aLength,
- nsIRDFBlob **aResult)
- {
- BlobImpl::Data key = { aLength, const_cast<uint8_t *>(aBytes) };
- PLDHashEntryHdr *hdr = mBlobs.Search(&key);
- if (hdr) {
- BlobHashEntry *entry = static_cast<BlobHashEntry *>(hdr);
- NS_ADDREF(*aResult = entry->mBlob);
- return NS_OK;
- }
- BlobImpl *result = new BlobImpl(aBytes, aLength);
- if (! result)
- return NS_ERROR_OUT_OF_MEMORY;
- NS_ADDREF(*aResult = result);
- return NS_OK;
- }
- NS_IMETHODIMP
- RDFServiceImpl::IsAnonymousResource(nsIRDFResource* aResource, bool* _result)
- {
- NS_PRECONDITION(aResource != nullptr, "null ptr");
- if (! aResource)
- return NS_ERROR_NULL_POINTER;
- nsresult rv;
- const char* uri;
- rv = aResource->GetValueConst(&uri);
- if (NS_FAILED(rv)) return rv;
- if ((uri[0] == 'r') &&
- (uri[1] == 'd') &&
- (uri[2] == 'f') &&
- (uri[3] == ':') &&
- (uri[4] == '#') &&
- (uri[5] == '$')) {
- *_result = true;
- }
- else {
- *_result = false;
- }
- return NS_OK;
- }
- NS_IMETHODIMP
- RDFServiceImpl::RegisterResource(nsIRDFResource* aResource, bool aReplace)
- {
- NS_PRECONDITION(aResource != nullptr, "null ptr");
- if (! aResource)
- return NS_ERROR_NULL_POINTER;
- nsresult rv;
- const char* uri;
- rv = aResource->GetValueConst(&uri);
- NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get URI from resource");
- if (NS_FAILED(rv)) return rv;
- NS_ASSERTION(uri != nullptr, "resource has no URI");
- if (! uri)
- return NS_ERROR_NULL_POINTER;
- PLDHashEntryHdr *hdr = mResources.Search(uri);
- if (hdr) {
- if (!aReplace) {
- 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.
- MOZ_LOG(gLog, LogLevel::Debug,
- ("rdfserv replace-resource [%p] <-- [%p] %s",
- static_cast<ResourceHashEntry *>(hdr)->mResource,
- aResource, (const char*) uri));
- }
- else {
- hdr = mResources.Add(uri, fallible);
- if (! hdr)
- return NS_ERROR_OUT_OF_MEMORY;
- MOZ_LOG(gLog, LogLevel::Debug,
- ("rdfserv register-resource [%p] %s",
- aResource, (const char*) uri));
- }
- // 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.
- ResourceHashEntry *entry = static_cast<ResourceHashEntry *>(hdr);
- entry->mResource = aResource;
- entry->mKey = uri;
- return NS_OK;
- }
- NS_IMETHODIMP
- RDFServiceImpl::UnregisterResource(nsIRDFResource* aResource)
- {
- NS_PRECONDITION(aResource != nullptr, "null ptr");
- if (! aResource)
- return NS_ERROR_NULL_POINTER;
- nsresult rv;
- const char* uri;
- rv = aResource->GetValueConst(&uri);
- if (NS_FAILED(rv)) return rv;
- NS_ASSERTION(uri != nullptr, "resource has no URI");
- if (! uri)
- return NS_ERROR_UNEXPECTED;
- MOZ_LOG(gLog, LogLevel::Debug,
- ("rdfserv unregister-resource [%p] %s",
- aResource, (const char*) uri));
- #ifdef DEBUG
- if (!mResources.Search(uri))
- NS_WARNING("resource was never registered");
- #endif
- mResources.Remove(uri);
- return NS_OK;
- }
- NS_IMETHODIMP
- RDFServiceImpl::RegisterDataSource(nsIRDFDataSource* aDataSource, bool aReplace)
- {
- NS_PRECONDITION(aDataSource != nullptr, "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 (! aReplace)
- 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.
- MOZ_LOG(gLog, LogLevel::Debug,
- ("rdfserv replace-datasource [%p] <-- [%p] %s",
- (*hep)->value, aDataSource, (const char*) uri));
- (*hep)->value = aDataSource;
- }
- else {
- const char* key = PL_strdup(uri);
- if (! key)
- return NS_ERROR_OUT_OF_MEMORY;
- PL_HashTableAdd(mNamedDataSources, key, aDataSource);
- MOZ_LOG(gLog, LogLevel::Debug,
- ("rdfserv register-datasource [%p] %s",
- aDataSource, (const char*) uri));
- // N.B., we only hold a weak reference to the datasource, so don't
- // addref.
- }
- return NS_OK;
- }
- NS_IMETHODIMP
- RDFServiceImpl::UnregisterDataSource(nsIRDFDataSource* aDataSource)
- {
- NS_PRECONDITION(aDataSource != nullptr, "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 != nullptr, "datasource has no URI");
- if (! uri)
- return NS_ERROR_UNEXPECTED;
- PLHashEntry** hep =
- PL_HashTableRawLookup(mNamedDataSources, (*mNamedDataSources->keyHash)(uri), uri);
- // It may well be that this datasource was never registered. If
- // so, don't unregister it.
- if (! *hep || ((*hep)->value != aDataSource))
- return NS_OK;
- // N.B., we only held a weak reference to the datasource, so we
- // don't release here.
- PL_HashTableRawRemove(mNamedDataSources, hep, *hep);
- MOZ_LOG(gLog, LogLevel::Debug,
- ("rdfserv unregister-datasource [%p] %s",
- aDataSource, (const char*) uri));
- return NS_OK;
- }
- NS_IMETHODIMP
- RDFServiceImpl::GetDataSource(const char* aURI, nsIRDFDataSource** aDataSource)
- {
- // Use the other GetDataSource and ask for a non-blocking Refresh.
- // If you wanted it loaded synchronously, then you should've tried to do it
- // yourself, or used GetDataSourceBlocking.
- return GetDataSource( aURI, false, aDataSource );
- }
- NS_IMETHODIMP
- RDFServiceImpl::GetDataSourceBlocking(const char* aURI, nsIRDFDataSource** aDataSource)
- {
- // Use GetDataSource and ask for a blocking Refresh.
- return GetDataSource( aURI, true, aDataSource );
- }
- nsresult
- RDFServiceImpl::GetDataSource(const char* aURI, bool aBlock, nsIRDFDataSource** aDataSource)
- {
- NS_PRECONDITION(aURI != nullptr, "null ptr");
- if (! aURI)
- return NS_ERROR_NULL_POINTER;
- nsresult rv;
- // Attempt to canonify the URI before we look for it in the
- // cache. We won't bother doing this on `rdf:' URIs to avoid
- // useless (and expensive) protocol handler lookups.
- nsAutoCString spec(aURI);
- if (!StringBeginsWith(spec, NS_LITERAL_CSTRING("rdf:"))) {
- nsCOMPtr<nsIURI> uri;
- NS_NewURI(getter_AddRefs(uri), spec);
- if (uri) {
- rv = uri->GetSpec(spec);
- if (NS_FAILED(rv)) return rv;
- }
- }
- // First, check the cache to see if we already have this
- // datasource loaded and initialized.
- {
- nsIRDFDataSource* cached =
- static_cast<nsIRDFDataSource*>(PL_HashTableLookup(mNamedDataSources, spec.get()));
- if (cached) {
- NS_ADDREF(cached);
- *aDataSource = cached;
- return NS_OK;
- }
- }
- // Nope. So go to the repository to try to create it.
- nsCOMPtr<nsIRDFDataSource> ds;
- if (StringBeginsWith(spec, NS_LITERAL_CSTRING("rdf:"))) {
- // It's a built-in data source. Convert it to a contract ID.
- nsAutoCString contractID(
- NS_LITERAL_CSTRING(NS_RDF_DATASOURCE_CONTRACTID_PREFIX) +
- Substring(spec, 4, spec.Length() - 4));
- // Strip params to get ``base'' contractID for data source.
- int32_t p = contractID.FindChar(char16_t('&'));
- if (p >= 0)
- contractID.Truncate(p);
- ds = do_GetService(contractID.get(), &rv);
- if (NS_FAILED(rv)) return rv;
- nsCOMPtr<nsIRDFRemoteDataSource> remote = do_QueryInterface(ds);
- if (remote) {
- rv = remote->Init(spec.get());
- if (NS_FAILED(rv)) return rv;
- }
- }
- else {
- // Try to load this as an RDF/XML data source
- ds = do_CreateInstance(kRDFXMLDataSourceCID, &rv);
- if (NS_FAILED(rv)) return rv;
- nsCOMPtr<nsIRDFRemoteDataSource> remote(do_QueryInterface(ds));
- NS_ASSERTION(remote, "not a remote RDF/XML data source!");
- if (! remote) return NS_ERROR_UNEXPECTED;
- rv = remote->Init(spec.get());
- if (NS_FAILED(rv)) return rv;
- rv = remote->Refresh(aBlock);
- if (NS_FAILED(rv)) return rv;
- }
- *aDataSource = ds;
- NS_ADDREF(*aDataSource);
- return NS_OK;
- }
- ////////////////////////////////////////////////////////////////////////
- nsresult
- RDFServiceImpl::RegisterLiteral(nsIRDFLiteral* aLiteral)
- {
- const char16_t* value;
- aLiteral->GetValueConst(&value);
- NS_ASSERTION(!mLiterals.Search(value), "literal already registered");
- PLDHashEntryHdr *hdr = mLiterals.Add(value, fallible);
- if (! hdr)
- return NS_ERROR_OUT_OF_MEMORY;
- LiteralHashEntry *entry = static_cast<LiteralHashEntry *>(hdr);
- // N.B., we only hold a weak reference to the literal: that
- // way, the literal can be destroyed when the last refcount
- // goes away. The single addref that the CreateLiteral() call
- // made will be owned by the callee.
- entry->mLiteral = aLiteral;
- entry->mKey = value;
- MOZ_LOG(gLog, LogLevel::Debug,
- ("rdfserv register-literal [%p] %s",
- aLiteral, (const char16_t*) value));
- return NS_OK;
- }
- nsresult
- RDFServiceImpl::UnregisterLiteral(nsIRDFLiteral* aLiteral)
- {
- const char16_t* value;
- aLiteral->GetValueConst(&value);
- NS_ASSERTION(mLiterals.Search(value), "literal was never registered");
- mLiterals.Remove(value);
- // N.B. that we _don't_ release the literal: we only held a weak
- // reference to it in the hashtable.
- MOZ_LOG(gLog, LogLevel::Debug,
- ("rdfserv unregister-literal [%p] %s",
- aLiteral, (const char16_t*) value));
- return NS_OK;
- }
- //----------------------------------------------------------------------
- nsresult
- RDFServiceImpl::RegisterInt(nsIRDFInt* aInt)
- {
- int32_t value;
- aInt->GetValue(&value);
- NS_ASSERTION(!mInts.Search(&value), "int already registered");
- PLDHashEntryHdr *hdr = mInts.Add(&value, fallible);
- if (! hdr)
- return NS_ERROR_OUT_OF_MEMORY;
- IntHashEntry *entry = static_cast<IntHashEntry *>(hdr);
- // N.B., we only hold a weak reference to the literal: that
- // way, the literal can be destroyed when the last refcount
- // goes away. The single addref that the CreateInt() call
- // made will be owned by the callee.
- entry->mInt = aInt;
- entry->mKey = value;
- MOZ_LOG(gLog, LogLevel::Debug,
- ("rdfserv register-int [%p] %d",
- aInt, value));
- return NS_OK;
- }
- nsresult
- RDFServiceImpl::UnregisterInt(nsIRDFInt* aInt)
- {
- int32_t value;
- aInt->GetValue(&value);
- NS_ASSERTION(mInts.Search(&value), "int was never registered");
- mInts.Remove(&value);
- // N.B. that we _don't_ release the literal: we only held a weak
- // reference to it in the hashtable.
- MOZ_LOG(gLog, LogLevel::Debug,
- ("rdfserv unregister-int [%p] %d",
- aInt, value));
- return NS_OK;
- }
- //----------------------------------------------------------------------
- nsresult
- RDFServiceImpl::RegisterDate(nsIRDFDate* aDate)
- {
- PRTime value;
- aDate->GetValue(&value);
- NS_ASSERTION(!mDates.Search(&value), "date already registered");
- PLDHashEntryHdr *hdr = mDates.Add(&value, fallible);
- if (! hdr)
- return NS_ERROR_OUT_OF_MEMORY;
- DateHashEntry *entry = static_cast<DateHashEntry *>(hdr);
- // N.B., we only hold a weak reference to the literal: that
- // way, the literal can be destroyed when the last refcount
- // goes away. The single addref that the CreateDate() call
- // made will be owned by the callee.
- entry->mDate = aDate;
- entry->mKey = value;
- MOZ_LOG(gLog, LogLevel::Debug,
- ("rdfserv register-date [%p] %ld",
- aDate, value));
- return NS_OK;
- }
- nsresult
- RDFServiceImpl::UnregisterDate(nsIRDFDate* aDate)
- {
- PRTime value;
- aDate->GetValue(&value);
- NS_ASSERTION(mDates.Search(&value), "date was never registered");
- mDates.Remove(&value);
- // N.B. that we _don't_ release the literal: we only held a weak
- // reference to it in the hashtable.
- MOZ_LOG(gLog, LogLevel::Debug,
- ("rdfserv unregister-date [%p] %ld",
- aDate, value));
- return NS_OK;
- }
- nsresult
- RDFServiceImpl::RegisterBlob(BlobImpl *aBlob)
- {
- NS_ASSERTION(!mBlobs.Search(&aBlob->mData), "blob already registered");
- PLDHashEntryHdr *hdr = mBlobs.Add(&aBlob->mData, fallible);
- if (! hdr)
- return NS_ERROR_OUT_OF_MEMORY;
- BlobHashEntry *entry = static_cast<BlobHashEntry *>(hdr);
- // N.B., we only hold a weak reference to the literal: that
- // way, the literal can be destroyed when the last refcount
- // goes away. The single addref that the CreateInt() call
- // made will be owned by the callee.
- entry->mBlob = aBlob;
- MOZ_LOG(gLog, LogLevel::Debug,
- ("rdfserv register-blob [%p] %s",
- aBlob, aBlob->mData.mBytes));
- return NS_OK;
- }
- nsresult
- RDFServiceImpl::UnregisterBlob(BlobImpl *aBlob)
- {
- NS_ASSERTION(mBlobs.Search(&aBlob->mData), "blob was never registered");
- mBlobs.Remove(&aBlob->mData);
- // N.B. that we _don't_ release the literal: we only held a weak
- // reference to it in the hashtable.
- MOZ_LOG(gLog, LogLevel::Debug,
- ("rdfserv unregister-blob [%p] %s",
- aBlob, aBlob->mData.mBytes));
- return NS_OK;
- }
|