LCOV - code coverage report
Current view: top level - rdf/base - nsRDFContainerUtils.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 68 241 28.2 %
Date: 2017-07-14 16:53:18 Functions: 9 21 42.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : /*
       7             : 
       8             :   Implementation for the RDF container utils.
       9             : 
      10             :  */
      11             : 
      12             : 
      13             : #include "nsCOMPtr.h"
      14             : #include "nsIServiceManager.h"
      15             : #include "nsIRDFContainer.h"
      16             : #include "nsIRDFContainerUtils.h"
      17             : #include "nsIRDFService.h"
      18             : #include "nsRDFCID.h"
      19             : #include "nsString.h"
      20             : #include "nsXPIDLString.h"
      21             : #include "plstr.h"
      22             : #include "rdf.h"
      23             : #include "rdfutil.h"
      24             : 
      25             : class RDFContainerUtilsImpl : public nsIRDFContainerUtils
      26             : {
      27             : public:
      28             :     // nsISupports interface
      29             :     NS_DECL_ISUPPORTS
      30             : 
      31             :     // nsIRDFContainerUtils interface
      32             :     NS_DECL_NSIRDFCONTAINERUTILS
      33             : 
      34             : private:
      35             :     friend nsresult NS_NewRDFContainerUtils(nsIRDFContainerUtils** aResult);
      36             : 
      37             :     RDFContainerUtilsImpl();
      38             :     virtual ~RDFContainerUtilsImpl();
      39             : 
      40             :     nsresult MakeContainer(nsIRDFDataSource* aDataSource,
      41             :                            nsIRDFResource* aResource,
      42             :                            nsIRDFResource* aType,
      43             :                            nsIRDFContainer** aResult);
      44             : 
      45             :     bool IsA(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource, nsIRDFResource* aType);
      46             : 
      47             :     // pseudo constants
      48             :     static int32_t gRefCnt;
      49             :     static nsIRDFService* gRDFService;
      50             :     static nsIRDFResource* kRDF_instanceOf;
      51             :     static nsIRDFResource* kRDF_nextVal;
      52             :     static nsIRDFResource* kRDF_Bag;
      53             :     static nsIRDFResource* kRDF_Seq;
      54             :     static nsIRDFResource* kRDF_Alt;
      55             :     static nsIRDFLiteral* kOne;
      56             :     static const char kRDFNameSpaceURI[];
      57             : };
      58             : 
      59             : int32_t         RDFContainerUtilsImpl::gRefCnt = 0;
      60             : nsIRDFService*  RDFContainerUtilsImpl::gRDFService;
      61             : nsIRDFResource* RDFContainerUtilsImpl::kRDF_instanceOf;
      62             : nsIRDFResource* RDFContainerUtilsImpl::kRDF_nextVal;
      63             : nsIRDFResource* RDFContainerUtilsImpl::kRDF_Bag;
      64             : nsIRDFResource* RDFContainerUtilsImpl::kRDF_Seq;
      65             : nsIRDFResource* RDFContainerUtilsImpl::kRDF_Alt;
      66             : nsIRDFLiteral*  RDFContainerUtilsImpl::kOne;
      67             : const char      RDFContainerUtilsImpl::kRDFNameSpaceURI[] = RDF_NAMESPACE_URI;
      68             : 
      69             : ////////////////////////////////////////////////////////////////////////
      70             : // nsISupports interface
      71             : 
      72          33 : NS_IMPL_ISUPPORTS(RDFContainerUtilsImpl, nsIRDFContainerUtils)
      73             : 
      74             : ////////////////////////////////////////////////////////////////////////
      75             : // nsIRDFContainerUtils interface
      76             : 
      77             : NS_IMETHODIMP
      78           0 : RDFContainerUtilsImpl::IsOrdinalProperty(nsIRDFResource *aProperty, bool *_retval)
      79             : {
      80           0 :     NS_PRECONDITION(aProperty != nullptr, "null ptr");
      81           0 :     if (! aProperty)
      82           0 :         return NS_ERROR_NULL_POINTER;
      83             : 
      84             :     nsresult rv;
      85             : 
      86             :     const char  *propertyStr;
      87           0 :     rv = aProperty->GetValueConst( &propertyStr );
      88           0 :     if (NS_FAILED(rv)) return rv;
      89             : 
      90           0 :     if (PL_strncmp(propertyStr, kRDFNameSpaceURI, sizeof(kRDFNameSpaceURI) - 1) != 0) {
      91           0 :         *_retval = false;
      92           0 :         return NS_OK;
      93             :     }
      94             : 
      95           0 :     const char* s = propertyStr;
      96           0 :     s += sizeof(kRDFNameSpaceURI) - 1;
      97           0 :     if (*s != '_') {
      98           0 :         *_retval = false;
      99           0 :         return NS_OK;
     100             :     }
     101             : 
     102           0 :     ++s;
     103           0 :     while (*s) {
     104           0 :         if (*s < '0' || *s > '9') {
     105           0 :             *_retval = false;
     106           0 :             return NS_OK;
     107             :         }
     108             : 
     109           0 :         ++s;
     110             :     }
     111             : 
     112           0 :     *_retval = true;
     113           0 :     return NS_OK;
     114             : }
     115             : 
     116             : 
     117             : NS_IMETHODIMP
     118           0 : RDFContainerUtilsImpl::IndexToOrdinalResource(int32_t aIndex, nsIRDFResource **aOrdinal)
     119             : {
     120           0 :     NS_PRECONDITION(aIndex > 0, "illegal value");
     121           0 :     if (aIndex <= 0)
     122           0 :         return NS_ERROR_ILLEGAL_VALUE;
     123             : 
     124           0 :     nsAutoCString uri(kRDFNameSpaceURI);
     125           0 :     uri.Append('_');
     126           0 :     uri.AppendInt(aIndex);
     127             : 
     128           0 :     nsresult rv = gRDFService->GetResource(uri, aOrdinal);
     129           0 :     NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get ordinal resource");
     130           0 :     if (NS_FAILED(rv)) return rv;
     131             : 
     132           0 :     return NS_OK;
     133             : }
     134             : 
     135             : 
     136             : NS_IMETHODIMP
     137           0 : RDFContainerUtilsImpl::OrdinalResourceToIndex(nsIRDFResource *aOrdinal, int32_t *aIndex)
     138             : {
     139           0 :     NS_PRECONDITION(aOrdinal != nullptr, "null ptr");
     140           0 :     if (! aOrdinal)
     141           0 :         return NS_ERROR_NULL_POINTER;
     142             : 
     143             :     const char  *ordinalStr;
     144           0 :     if (NS_FAILED(aOrdinal->GetValueConst( &ordinalStr )))
     145           0 :         return NS_ERROR_FAILURE;
     146             : 
     147           0 :     const char* s = ordinalStr;
     148           0 :     if (PL_strncmp(s, kRDFNameSpaceURI, sizeof(kRDFNameSpaceURI) - 1) != 0) {
     149           0 :         NS_ERROR("not an ordinal");
     150           0 :         return NS_ERROR_UNEXPECTED;
     151             :     }
     152             : 
     153           0 :     s += sizeof(kRDFNameSpaceURI) - 1;
     154           0 :     if (*s != '_') {
     155           0 :         NS_ERROR("not an ordinal");
     156           0 :         return NS_ERROR_UNEXPECTED;
     157             :     }
     158             : 
     159           0 :     int32_t idx = 0;
     160             : 
     161           0 :     ++s;
     162           0 :     while (*s) {
     163           0 :         if (*s < '0' || *s > '9') {
     164           0 :             NS_ERROR("not an ordinal");
     165           0 :             return NS_ERROR_UNEXPECTED;
     166             :         }
     167             : 
     168           0 :         idx *= 10;
     169           0 :         idx += (*s - '0');
     170             : 
     171           0 :         ++s;
     172             :     }
     173             : 
     174           0 :     *aIndex = idx;
     175           0 :     return NS_OK;
     176             : }
     177             : 
     178             : NS_IMETHODIMP
     179           6 : RDFContainerUtilsImpl::IsContainer(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, bool *_retval)
     180             : {
     181           6 :     NS_PRECONDITION(aDataSource != nullptr, "null ptr");
     182           6 :     if (! aDataSource)
     183           0 :         return NS_ERROR_NULL_POINTER;
     184             : 
     185           6 :     NS_PRECONDITION(aResource != nullptr, "null ptr");
     186           6 :     if (! aResource)
     187           0 :         return NS_ERROR_NULL_POINTER;
     188             : 
     189           6 :     NS_PRECONDITION(_retval != nullptr, "null ptr");
     190           6 :     if (! _retval)
     191           0 :         return NS_ERROR_NULL_POINTER;
     192             : 
     193          15 :     if (IsA(aDataSource, aResource, kRDF_Seq) ||
     194           9 :         IsA(aDataSource, aResource, kRDF_Bag) ||
     195           3 :         IsA(aDataSource, aResource, kRDF_Alt)) {
     196           3 :         *_retval = true;
     197             :     }
     198             :     else {
     199           3 :         *_retval = false;
     200             :     }
     201           6 :     return NS_OK;
     202             : }
     203             : 
     204             : 
     205             : NS_IMETHODIMP
     206           0 : RDFContainerUtilsImpl::IsEmpty(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource, bool* _retval)
     207             : {
     208           0 :     if (! aDataSource)
     209           0 :         return NS_ERROR_NULL_POINTER;
     210             : 
     211             :     nsresult rv;
     212             : 
     213             :     // By default, say that we're an empty container. Even if we're not
     214             :     // really even a container.
     215           0 :     *_retval = true;
     216             : 
     217           0 :     nsCOMPtr<nsIRDFNode> nextValNode;
     218           0 :     rv = aDataSource->GetTarget(aResource, kRDF_nextVal, true, getter_AddRefs(nextValNode));
     219           0 :     if (NS_FAILED(rv)) return rv;
     220             : 
     221           0 :     if (rv == NS_RDF_NO_VALUE)
     222           0 :         return NS_OK;
     223             : 
     224           0 :     nsCOMPtr<nsIRDFLiteral> nextValLiteral;
     225           0 :     rv = nextValNode->QueryInterface(NS_GET_IID(nsIRDFLiteral), getter_AddRefs(nextValLiteral));
     226           0 :     if (NS_FAILED(rv)) return rv;
     227             : 
     228           0 :     if (nextValLiteral.get() != kOne)
     229           0 :         *_retval = false;
     230             : 
     231           0 :     return NS_OK;
     232             : }
     233             : 
     234             : 
     235             : NS_IMETHODIMP
     236           0 : RDFContainerUtilsImpl::IsBag(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, bool *_retval)
     237             : {
     238           0 :     NS_PRECONDITION(aDataSource != nullptr, "null ptr");
     239           0 :     if (! aDataSource)
     240           0 :         return NS_ERROR_NULL_POINTER;
     241             : 
     242           0 :     NS_PRECONDITION(aResource != nullptr, "null ptr");
     243           0 :     if (! aResource)
     244           0 :         return NS_ERROR_NULL_POINTER;
     245             : 
     246           0 :     NS_PRECONDITION(_retval != nullptr, "null ptr");
     247           0 :     if (! _retval)
     248           0 :         return NS_ERROR_NULL_POINTER;
     249             : 
     250           0 :     *_retval = IsA(aDataSource, aResource, kRDF_Bag);
     251           0 :     return NS_OK;
     252             : }
     253             : 
     254             : 
     255             : NS_IMETHODIMP
     256           0 : RDFContainerUtilsImpl::IsSeq(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, bool *_retval)
     257             : {
     258           0 :     NS_PRECONDITION(aDataSource != nullptr, "null ptr");
     259           0 :     if (! aDataSource)
     260           0 :         return NS_ERROR_NULL_POINTER;
     261             : 
     262           0 :     NS_PRECONDITION(aResource != nullptr, "null ptr");
     263           0 :     if (! aResource)
     264           0 :         return NS_ERROR_NULL_POINTER;
     265             : 
     266           0 :     NS_PRECONDITION(_retval != nullptr, "null ptr");
     267           0 :     if (! _retval)
     268           0 :         return NS_ERROR_NULL_POINTER;
     269             : 
     270           0 :     *_retval = IsA(aDataSource, aResource, kRDF_Seq);
     271           0 :     return NS_OK;
     272             : }
     273             : 
     274             : 
     275             : NS_IMETHODIMP
     276           0 : RDFContainerUtilsImpl::IsAlt(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, bool *_retval)
     277             : {
     278           0 :     NS_PRECONDITION(aDataSource != nullptr, "null ptr");
     279           0 :     if (! aDataSource)
     280           0 :         return NS_ERROR_NULL_POINTER;
     281             : 
     282           0 :     NS_PRECONDITION(aResource != nullptr, "null ptr");
     283           0 :     if (! aResource)
     284           0 :         return NS_ERROR_NULL_POINTER;
     285             : 
     286           0 :     NS_PRECONDITION(_retval != nullptr, "null ptr");
     287           0 :     if (! _retval)
     288           0 :         return NS_ERROR_NULL_POINTER;
     289             : 
     290           0 :     *_retval = IsA(aDataSource, aResource, kRDF_Alt);
     291           0 :     return NS_OK;
     292             : }
     293             : 
     294             : 
     295             : NS_IMETHODIMP
     296           0 : RDFContainerUtilsImpl::MakeBag(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, nsIRDFContainer **_retval)
     297             : {
     298           0 :     return MakeContainer(aDataSource, aResource, kRDF_Bag, _retval);
     299             : }
     300             : 
     301             : 
     302             : NS_IMETHODIMP
     303           3 : RDFContainerUtilsImpl::MakeSeq(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, nsIRDFContainer **_retval)
     304             : {
     305           3 :     return MakeContainer(aDataSource, aResource, kRDF_Seq, _retval);
     306             : }
     307             : 
     308             : 
     309             : NS_IMETHODIMP
     310           0 : RDFContainerUtilsImpl::MakeAlt(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, nsIRDFContainer **_retval)
     311             : {
     312           0 :     return MakeContainer(aDataSource, aResource, kRDF_Alt, _retval);
     313             : }
     314             : 
     315             : 
     316             : 
     317             : ////////////////////////////////////////////////////////////////////////
     318             : 
     319             : 
     320           3 : RDFContainerUtilsImpl::RDFContainerUtilsImpl()
     321             : {
     322           3 :     if (gRefCnt++ == 0) {
     323             :         nsresult rv;
     324             : 
     325           3 :         NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
     326           3 :         rv = CallGetService(kRDFServiceCID, &gRDFService);
     327             : 
     328           3 :         NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get RDF service");
     329           3 :         if (NS_SUCCEEDED(rv)) {
     330           9 :             gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "instanceOf"),
     331           9 :                                      &kRDF_instanceOf);
     332           9 :             gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "nextVal"),
     333           9 :                                      &kRDF_nextVal);
     334           9 :             gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "Bag"),
     335           9 :                                      &kRDF_Bag);
     336           9 :             gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "Seq"),
     337           9 :                                      &kRDF_Seq);
     338           9 :             gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "Alt"),
     339           9 :                                      &kRDF_Alt);
     340           3 :             gRDFService->GetLiteral(u"1", &kOne);
     341             :         }
     342             :     }
     343           3 : }
     344             : 
     345             : 
     346           0 : RDFContainerUtilsImpl::~RDFContainerUtilsImpl()
     347             : {
     348             : #ifdef DEBUG_REFS
     349             :     --gInstanceCount;
     350             :     fprintf(stdout, "%d - RDF: RDFContainerUtilsImpl\n", gInstanceCount);
     351             : #endif
     352             : 
     353           0 :     if (--gRefCnt == 0) {
     354           0 :         NS_IF_RELEASE(gRDFService);
     355           0 :         NS_IF_RELEASE(kRDF_instanceOf);
     356           0 :         NS_IF_RELEASE(kRDF_nextVal);
     357           0 :         NS_IF_RELEASE(kRDF_Bag);
     358           0 :         NS_IF_RELEASE(kRDF_Seq);
     359           0 :         NS_IF_RELEASE(kRDF_Alt);
     360           0 :         NS_IF_RELEASE(kOne);
     361             :     }
     362           0 : }
     363             : 
     364             : 
     365             : 
     366             : nsresult
     367           3 : NS_NewRDFContainerUtils(nsIRDFContainerUtils** aResult)
     368             : {
     369           3 :     NS_PRECONDITION(aResult != nullptr, "null ptr");
     370           3 :     if (! aResult)
     371           0 :         return NS_ERROR_NULL_POINTER;
     372             : 
     373             :     RDFContainerUtilsImpl* result =
     374           3 :         new RDFContainerUtilsImpl();
     375             : 
     376           3 :     if (! result)
     377           0 :         return NS_ERROR_OUT_OF_MEMORY;
     378             : 
     379           3 :     NS_ADDREF(result);
     380           3 :     *aResult = result;
     381           3 :     return NS_OK;
     382             : }
     383             : 
     384             : 
     385             : nsresult
     386           3 : RDFContainerUtilsImpl::MakeContainer(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource, nsIRDFResource* aType, nsIRDFContainer** aResult)
     387             : {
     388           3 :     NS_PRECONDITION(aDataSource != nullptr, "null ptr");
     389           3 :     if (! aDataSource)  return NS_ERROR_NULL_POINTER;
     390             : 
     391           3 :     NS_PRECONDITION(aResource != nullptr, "null ptr");
     392           3 :     if (! aResource)    return NS_ERROR_NULL_POINTER;
     393             : 
     394           3 :     NS_PRECONDITION(aType != nullptr, "null ptr");
     395           3 :     if (! aType)        return NS_ERROR_NULL_POINTER;
     396             : 
     397           3 :     if (aResult)        *aResult = nullptr;
     398             : 
     399             :     nsresult rv;
     400             : 
     401             :     // Check to see if somebody has already turned it into a container; if so
     402             :     // don't try to do it again.
     403             :     bool isContainer;
     404           3 :     rv = IsContainer(aDataSource, aResource, &isContainer);
     405           3 :     if (NS_FAILED(rv)) return rv;
     406             : 
     407           3 :     if (!isContainer)
     408             :     {
     409           3 :         rv = aDataSource->Assert(aResource, kRDF_instanceOf, aType, true);
     410           3 :         if (NS_FAILED(rv)) return rv;
     411             : 
     412           3 :         rv = aDataSource->Assert(aResource, kRDF_nextVal, kOne, true);
     413           3 :         if (NS_FAILED(rv)) return rv;
     414             :     }
     415             : 
     416           3 :     if (aResult) {
     417           3 :         rv = NS_NewRDFContainer(aResult);
     418           3 :         if (NS_FAILED(rv)) return rv;
     419             : 
     420           3 :         rv = (*aResult)->Init(aDataSource, aResource);
     421           3 :         if (NS_FAILED(rv)) return rv;
     422             :     }
     423             : 
     424           3 :     return NS_OK;
     425             : }
     426             : 
     427             : bool
     428          12 : RDFContainerUtilsImpl::IsA(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource, nsIRDFResource* aType)
     429             : {
     430          12 :     if (!aDataSource || !aResource || !aType) {
     431           0 :         NS_WARNING("Unexpected null argument");
     432           0 :         return false;
     433             :     }
     434             : 
     435             :     nsresult rv;
     436             : 
     437             :     bool result;
     438          12 :     rv = aDataSource->HasAssertion(aResource, kRDF_instanceOf, aType, true, &result);
     439          12 :     if (NS_FAILED(rv))
     440           0 :       return false;
     441             : 
     442          12 :     return result;
     443             : }
     444             : 
     445             : NS_IMETHODIMP
     446           0 : RDFContainerUtilsImpl::IndexOf(nsIRDFDataSource* aDataSource, nsIRDFResource* aContainer, nsIRDFNode* aElement, int32_t* aIndex)
     447             : {
     448           0 :     if (!aDataSource || !aContainer)
     449           0 :         return NS_ERROR_NULL_POINTER;
     450             : 
     451             :     // Assume we can't find it.
     452           0 :     *aIndex = -1;
     453             : 
     454             :     // If the resource is null, bail quietly
     455           0 :     if (! aElement)
     456           0 :       return NS_OK;
     457             : 
     458             :     // We'll assume that fan-out is much higher than fan-in, so grovel
     459             :     // through the inbound arcs, look for an ordinal resource, and
     460             :     // decode it.
     461           0 :     nsCOMPtr<nsISimpleEnumerator> arcsIn;
     462           0 :     aDataSource->ArcLabelsIn(aElement, getter_AddRefs(arcsIn));
     463           0 :     if (! arcsIn)
     464           0 :         return NS_OK;
     465             : 
     466             :     while (1) {
     467           0 :         bool hasMoreArcs = false;
     468           0 :         arcsIn->HasMoreElements(&hasMoreArcs);
     469           0 :         if (! hasMoreArcs)
     470           0 :             break;
     471             : 
     472           0 :         nsCOMPtr<nsISupports> isupports;
     473           0 :         arcsIn->GetNext(getter_AddRefs(isupports));
     474           0 :         if (! isupports)
     475           0 :             break;
     476             : 
     477             :         nsCOMPtr<nsIRDFResource> property =
     478           0 :             do_QueryInterface(isupports);
     479             : 
     480           0 :         if (! property)
     481           0 :             continue;
     482             : 
     483             :         bool isOrdinal;
     484           0 :         IsOrdinalProperty(property, &isOrdinal);
     485           0 :         if (! isOrdinal)
     486           0 :             continue;
     487             : 
     488           0 :         nsCOMPtr<nsISimpleEnumerator> sources;
     489           0 :         aDataSource->GetSources(property, aElement, true, getter_AddRefs(sources));
     490           0 :         if (! sources)
     491           0 :             continue;
     492             : 
     493             :         while (1) {
     494           0 :             bool hasMoreSources = false;
     495           0 :             sources->HasMoreElements(&hasMoreSources);
     496           0 :             if (! hasMoreSources)
     497           0 :                 break;
     498             : 
     499           0 :             nsCOMPtr<nsISupports> isupports2;
     500           0 :             sources->GetNext(getter_AddRefs(isupports2));
     501           0 :             if (! isupports2)
     502           0 :                 break;
     503             : 
     504             :             nsCOMPtr<nsIRDFResource> source =
     505           0 :                 do_QueryInterface(isupports2);
     506             : 
     507           0 :             if (source == aContainer)
     508             :                 // Found it.
     509           0 :                 return OrdinalResourceToIndex(property, aIndex);
     510           0 :         }
     511           0 :     }
     512             : 
     513           0 :     return NS_OK;
     514             : }

Generated by: LCOV version 1.13