Back to index

lightning-sunbird  0.9+nobinonly
Classes | Public Types | Public Member Functions | Static Public Attributes | Protected Types | Protected Member Functions | Protected Attributes
RDFContentSinkImpl Class Reference
Inheritance diagram for RDFContentSinkImpl:
Inheritance graph
[legend]
Collaboration diagram for RDFContentSinkImpl:
Collaboration graph
[legend]

List of all members.

Classes

struct  ContainerInfo

Public Types

typedef struct
RDFContentSinkImpl::ContainerInfo 
ContainerInfo

Public Member Functions

 RDFContentSinkImpl ()
virtual ~RDFContentSinkImpl ()
NS_DECL_ISUPPORTS
NS_DECL_NSIEXPATSINK
NS_IMETHOD 
WillBuildModel (void)
 This method gets called when the parser begins the process of building the content model via the content sink.
NS_IMETHOD DidBuildModel (void)
 This method gets called when the parser concludes the process of building the content model via the content sink.
NS_IMETHOD WillInterrupt (void)
 This method gets called when the parser gets i/o blocked, and wants to notify the sink that it may be a while before more data is available.
NS_IMETHOD WillResume (void)
 This method gets called when the parser i/o gets unblocked, and we're about to start dumping content again to the sink.
NS_IMETHOD SetParser (nsIParser *aParser)
 This method gets called by the parser so that the content sink can retain a reference to the parser.
virtual void FlushPendingNotifications (mozFlushType aType)
 Flush content so that the content model is in sync with the state of the sink.
NS_IMETHOD SetDocumentCharset (nsACString &aCharset)
 Set the document character set.
virtual nsISupports * GetTarget ()
 Returns the target object (often a document object) into which the content built by this content sink is being added, if any (IOW, may return null).
NS_IMETHOD Init (nsIURI *aURL)
 Initialize the content sink.
NS_IMETHOD SetDataSource (nsIRDFDataSource *aDataSource)
 Set the content sink's RDF Data source.
NS_IMETHOD GetDataSource (nsIRDFDataSource *&aDataSource)
 Retrieve the content sink's RDF data source.
void HandleStartElement (in wstring aName,[array, size_is(aAttsCount)] in wstring aAtts, in unsigned long aAttsCount, in long aIndex, in unsigned long aLineNumber)
 Called to handle the opening tag of an element.
void HandleEndElement (in wstring aName)
 Called to handle the closing tag of an element.
void HandleComment (in wstring aCommentText)
 Called to handle a comment.
void HandleCDataSection ([size_is(aLength)] in wstring aData, in unsigned long aLength)
 Called to handle a CDATA section.
void HandleDoctypeDecl (in AString aSubset, in AString aName, in AString aSystemId, in AString aPublicId, in nsISupports aCatalogData)
 Called to handle the doctype declaration.
void HandleCharacterData ([size_is(aLength)] in wstring aData, in unsigned long aLength)
 Called to handle character data.
void HandleProcessingInstruction (in wstring aTarget, in wstring aData)
 Called to handle a processing instruction.
void HandleXMLDeclaration (in wstring aVersion, in wstring aEncoding, in long aStandalone)
 Handle the XML Declaration.
void ReportError (in wstring aErrorText, in wstring aSourceText)

Static Public Attributes

static PRInt32 gRefCnt = 0
static nsIRDFServicegRDFService
static nsIRDFContainerUtilsgRDFContainerUtils
static nsIRDFResourcekRDF_type
static nsIRDFResourcekRDF_instanceOf
static nsIRDFResourcekRDF_Alt
static nsIRDFResourcekRDF_Bag
static nsIRDFResourcekRDF_Seq
static nsIRDFResourcekRDF_nextVal
static nsIAtomkAboutAtom
static nsIAtomkIdAtom
static nsIAtomkNodeIdAtom
static nsIAtomkAboutEachAtom
static nsIAtomkResourceAtom
static nsIAtomkRDFAtom
static nsIAtomkDescriptionAtom
static nsIAtomkBagAtom
static nsIAtomkSeqAtom
static nsIAtomkAltAtom
static nsIAtomkLiAtom
static nsIAtomkXMLNSAtom
static nsIAtomkParseTypeAtom

Protected Types

enum  eContainerType { eBag, eSeq, eAlt }

Protected Member Functions

void ParseText (nsIRDFNode **aResult)
nsresult FlushText (PRBool aCreateTextNode=PR_TRUE, PRBool *aDidFlush=nsnull)
nsresult AddText (const PRUnichar *aText, PRInt32 aLength)
nsresult OpenRDF (const PRUnichar *aName)
nsresult OpenObject (const PRUnichar *aName, const PRUnichar **aAttributes)
nsresult OpenProperty (const PRUnichar *aName, const PRUnichar **aAttributes)
nsresult OpenMember (const PRUnichar *aName, const PRUnichar **aAttributes)
nsresult OpenValue (const PRUnichar *aName, const PRUnichar **aAttributes)
nsresult GetIdAboutAttribute (const PRUnichar **aAttributes, nsIRDFResource **aResource, PRBool *aIsAnonymous=nsnull)
nsresult GetResourceAttribute (const PRUnichar **aAttributes, nsIRDFResource **aResource)
nsresult AddProperties (const PRUnichar **aAttributes, nsIRDFResource *aSubject, PRInt32 *aCount=nsnull)
void SetParseMode (const PRUnichar **aAttributes)
void RegisterNamespaces (const PRUnichar **aAttributes)
 From the set of given attributes, this method extracts the namespace definitions and feeds them to the datasource.
const nsDependentSubstring SplitExpatName (const PRUnichar *aExpatName, nsIAtom **aLocalName)
 Extracts the localname from aExpatName, the name that the Expat parser passes us.
nsresult InitContainer (nsIRDFResource *aContainerType, nsIRDFResource *aContainer)
nsresult ReinitContainer (nsIRDFResource *aContainerType, nsIRDFResource *aContainer)
PRInt32 PushContext (nsIRDFResource *aContext, RDFContentSinkState aState, RDFContentSinkParseMode aParseMode)
nsresult PopContext (nsIRDFResource *&aContext, RDFContentSinkState &aState, RDFContentSinkParseMode &aParseMode)
nsIRDFResourceGetContextElement (PRInt32 ancestor=0)

Protected Attributes

PRUnicharmText
PRInt32 mTextLength
PRInt32 mTextSize
nsCOMPtr< nsIRDFDataSourcemDataSource
nsInterfaceHashtable
< nsStringHashKey,
nsIRDFResource
mNodeIDMap
RDFContentSinkState mState
RDFContentSinkParseMode mParseMode
nsAutoVoidArray * mContextStack
nsIURImDocumentURL

Detailed Description

Definition at line 152 of file nsRDFContentSink.cpp.


Class Documentation

struct RDFContentSinkImpl::ContainerInfo

Definition at line 204 of file nsRDFContentSink.cpp.

Collaboration diagram for RDFContentSinkImpl::ContainerInfo:
Class Members
nsMakeContainerFn mMakeFn
nsContainerTestFn mTestFn
nsIRDFResource ** mType

Member Typedef Documentation


Member Enumeration Documentation

Enumerator:
eBag 
eSeq 
eAlt 

Definition at line 252 of file nsRDFContentSink.cpp.

{ eBag, eSeq, eAlt };

Constructor & Destructor Documentation

Definition at line 368 of file nsRDFContentSink.cpp.

{
#ifdef DEBUG_REFS
    --gInstanceCount;
    fprintf(stdout, "%d - RDF: RDFContentSinkImpl\n", gInstanceCount);
#endif

    NS_IF_RELEASE(mDocumentURL);

    if (mContextStack) {
        PR_LOG(gLog, PR_LOG_WARNING,
               ("rdfxml: warning! unclosed tag"));

        // XXX we should never need to do this, but, we'll write the
        // code all the same. If someone left the content stack dirty,
        // pop all the elements off the stack and release them.
        PRInt32 i = mContextStack->Count();
        while (0 < i--) {
            nsIRDFResource* resource;
            RDFContentSinkState state;
            RDFContentSinkParseMode parseMode;
            PopContext(resource, state, parseMode);

#ifdef PR_LOGGING
            // print some fairly useless debugging info
            // XXX we should save line numbers on the context stack: this'd
            // be about 1000x more helpful.
            if (resource) {
                nsXPIDLCString uri;
                resource->GetValue(getter_Copies(uri));
                PR_LOG(gLog, PR_LOG_NOTICE,
                       ("rdfxml:   uri=%s", (const char*) uri));
            }
#endif

            NS_IF_RELEASE(resource);
        }

        delete mContextStack;
    }
    PR_FREEIF(mText);


    if (--gRefCnt == 0) {
        NS_IF_RELEASE(gRDFService);
        NS_IF_RELEASE(gRDFContainerUtils);
        NS_IF_RELEASE(kRDF_type);
        NS_IF_RELEASE(kRDF_instanceOf);
        NS_IF_RELEASE(kRDF_Alt);
        NS_IF_RELEASE(kRDF_Bag);
        NS_IF_RELEASE(kRDF_Seq);
        NS_IF_RELEASE(kRDF_nextVal);
    }
}

Here is the call graph for this function:


Member Function Documentation

nsresult RDFContentSinkImpl::AddProperties ( const PRUnichar **  aAttributes,
nsIRDFResource aSubject,
PRInt32 aCount = nsnull 
) [protected]

Definition at line 989 of file nsRDFContentSink.cpp.

{
  if (aCount)
      *aCount = 0;

  nsCOMPtr<nsIAtom> localName;
  for (; *aAttributes; aAttributes += 2) {
      const nsDependentSubstring& nameSpaceURI =
          SplitExpatName(aAttributes[0], getter_AddRefs(localName));

      // skip 'xmlns' directives, these are "meta" information
      if (nameSpaceURI.EqualsLiteral("http://www.w3.org/2000/xmlns/")) {
        continue;
      }

      // skip `about', `ID', `resource', and 'nodeID' attributes (either with or
      // without the `rdf:' prefix); these are all "special" and
      // should've been dealt with by the caller.
      if (localName == kAboutAtom || localName == kIdAtom ||
          localName == kResourceAtom || localName == kNodeIdAtom) {
          if (nameSpaceURI.IsEmpty() ||
              nameSpaceURI.EqualsLiteral(RDF_NAMESPACE_URI))
              continue;
      }

      // Skip `parseType', `RDF:parseType', and `NC:parseType'. This
      // is meta-information that will be handled in SetParseMode.
      if (localName == kParseTypeAtom) {
          if (nameSpaceURI.IsEmpty() ||
              nameSpaceURI.EqualsLiteral(RDF_NAMESPACE_URI) ||
              nameSpaceURI.EqualsLiteral(NC_NAMESPACE_URI)) {
              continue;
          }
      }

      nsAutoString v(aAttributes[1]);
      nsRDFParserUtils::StripAndConvert(v);

      const char* attrName;
      localName->GetUTF8String(&attrName);

      NS_ConvertUTF16toUTF8 propertyStr(nameSpaceURI);    
      propertyStr.Append(attrName);

      // Add the assertion to RDF
      nsCOMPtr<nsIRDFResource> property;
      gRDFService->GetResource(propertyStr, getter_AddRefs(property));

      nsCOMPtr<nsIRDFLiteral> target;
      gRDFService->GetLiteral(v.get(), getter_AddRefs(target));

      mDataSource->Assert(aSubject, property, target, PR_TRUE);
  }
  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult RDFContentSinkImpl::AddText ( const PRUnichar aText,
PRInt32  aLength 
) [protected]

Definition at line 804 of file nsRDFContentSink.cpp.

{
    // Create buffer when we first need it
    if (0 == mTextSize) {
        mText = (PRUnichar *) PR_MALLOC(sizeof(PRUnichar) * 4096);
        if (!mText) {
            return NS_ERROR_OUT_OF_MEMORY;
        }
        mTextSize = 4096;
    }

    // Copy data from string into our buffer; grow the buffer as needed.
    // It never shrinks, but since the content sink doesn't stick around,
    // this shouldn't be a bloat issue.
    PRInt32 amount = mTextSize - mTextLength;
    if (amount < aLength) {
        // Grow the buffer by at least a factor of two to prevent thrashing.
        // Since PR_REALLOC will leave mText intact if the call fails,
        // don't clobber mText or mTextSize until the new mem is allocated.
        PRInt32 newSize = (2 * mTextSize > (mTextSize + aLength)) ?
                          (2 * mTextSize) : (mTextSize + aLength);
        PRUnichar* newText = 
            (PRUnichar *) PR_REALLOC(mText, sizeof(PRUnichar) * newSize);
        if (!newText)
            return NS_ERROR_OUT_OF_MEMORY;
        mTextSize = newSize;
        mText = newText;
    }
    memcpy(&mText[mTextLength], aText, sizeof(PRUnichar) * aLength);
    mTextLength += aLength;

    return NS_OK;
}

Here is the call graph for this function:

This method gets called when the parser concludes the process of building the content model via the content sink.

5/7/98 gess

Implements nsIContentSink.

Definition at line 617 of file nsRDFContentSink.cpp.

{
    if (mDataSource) {
        nsCOMPtr<nsIRDFXMLSink> sink = do_QueryInterface(mDataSource);
        if (sink)
            return sink->EndLoad();
    }
    return NS_OK;
}

Here is the call graph for this function:

virtual void RDFContentSinkImpl::FlushPendingNotifications ( mozFlushType  aType) [inline, virtual]

Flush content so that the content model is in sync with the state of the sink.

Parameters:
aTypethe type of flush to perform

Implements nsIContentSink.

Definition at line 169 of file nsRDFContentSink.cpp.

{ }
nsresult RDFContentSinkImpl::FlushText ( PRBool  aCreateTextNode = PR_TRUE,
PRBool aDidFlush = nsnull 
) [protected]

Definition at line 760 of file nsRDFContentSink.cpp.

{
    nsresult rv = NS_OK;
    PRBool didFlush = PR_FALSE;
    if (0 != mTextLength) {
        if (aCreateTextNode && rdf_IsDataInBuffer(mText, mTextLength)) {
            // XXX if there's anything but whitespace, then we'll
            // create a text node.

            switch (mState) {
            case eRDFContentSinkState_InMemberElement: {
                nsCOMPtr<nsIRDFNode> node;
                ParseText(getter_AddRefs(node));

                nsCOMPtr<nsIRDFContainer> container;
                NS_NewRDFContainer(getter_AddRefs(container));
                container->Init(mDataSource, GetContextElement(1));

                container->AppendElement(node);
            } break;

            case eRDFContentSinkState_InPropertyElement: {
                nsCOMPtr<nsIRDFNode> node;
                ParseText(getter_AddRefs(node));

                mDataSource->Assert(GetContextElement(1), GetContextElement(0), node, PR_TRUE);
            } break;

            default:
                // just ignore it
                break;
            }
        }
        mTextLength = 0;
        didFlush = PR_TRUE;
    }
    if (nsnull != aDidFlush) {
        *aDidFlush = didFlush;
    }
    return rv;
}

Here is the call graph for this function:

Definition at line 1470 of file nsRDFContentSink.cpp.

{
    if ((nsnull == mContextStack) ||
        (ancestor >= mContextStack->Count())) {
        return nsnull;
    }

    RDFContextStackElement* e =
        NS_STATIC_CAST(RDFContextStackElement*, mContextStack->ElementAt(mContextStack->Count()-ancestor-1));

    return e->mResource;
}

Here is the caller graph for this function:

Retrieve the content sink's RDF data source.

Implements nsIRDFContentSink.

Definition at line 683 of file nsRDFContentSink.cpp.

{
    aDataSource = mDataSource;
    NS_IF_ADDREF(aDataSource);
    return NS_OK;
}
nsresult RDFContentSinkImpl::GetIdAboutAttribute ( const PRUnichar **  aAttributes,
nsIRDFResource **  aResource,
PRBool aIsAnonymous = nsnull 
) [protected]

Definition at line 839 of file nsRDFContentSink.cpp.

{
    // This corresponds to the dirty work of production [6.5]
    nsresult rv = NS_OK;

    nsCAutoString docURI;
    rv = mDocumentURL->GetSpec(docURI);
    if (NS_FAILED(rv)) return rv;

    nsAutoString nodeID;

    nsCOMPtr<nsIAtom> localName;
    for (; *aAttributes; aAttributes += 2) {
        const nsDependentSubstring& nameSpaceURI =
            SplitExpatName(aAttributes[0], getter_AddRefs(localName));

        // We'll accept either `ID' or `rdf:ID' (ibid with `about' or
        // `rdf:about') in the spirit of being liberal towards the
        // input that we receive.
        if (!nameSpaceURI.IsEmpty() &&
            !nameSpaceURI.EqualsLiteral(RDF_NAMESPACE_URI)) {
          continue;
        }

        // XXX you can't specify both, but we'll just pick up the
        // first thing that was specified and ignore the other.
      
        if (localName == kAboutAtom) {
            if (aIsAnonymous)
                *aIsAnonymous = PR_FALSE;

            nsAutoString uri(aAttributes[1]);
            nsRDFParserUtils::StripAndConvert(uri);

            rdf_MakeAbsoluteURI(NS_ConvertUTF8toUCS2(docURI), uri);

            return gRDFService->GetUnicodeResource(uri, aResource);
        }
        else if (localName == kIdAtom) {
            if (aIsAnonymous)
                *aIsAnonymous = PR_FALSE;

            nsAutoString name(aAttributes[1]);
            nsRDFParserUtils::StripAndConvert(name);

            // In the spirit of leniency, we do not bother trying to
            // enforce that this be a valid "XML Name" (see
            // http://www.w3.org/TR/REC-xml#NT-Nmtoken), as per
            // 6.21. If we wanted to, this would be where to do it.

            // Construct an in-line resource whose URI is the
            // document's URI plus the XML name specified in the ID
            // attribute.
            name.Insert(PRUnichar('#'), 0);
          
            rdf_MakeAbsoluteURI(NS_ConvertUTF8toUCS2(docURI), name);

            return gRDFService->GetUnicodeResource(name, aResource);
        }
        else if (localName == kNodeIdAtom) {
            nodeID.Assign(aAttributes[1]);
        }
        else if (localName == kAboutEachAtom) {
            // XXX we don't deal with aboutEach...
            //PR_LOG(gLog, PR_LOG_WARNING,
            //       ("rdfxml: ignoring aboutEach at line %d",
            //        aNode.GetSourceLineNumber()));
        }
    }

    // Otherwise, we couldn't find anything, so just gensym one...
    if (aIsAnonymous)
        *aIsAnonymous = PR_TRUE;

    // If nodeID is present, check if we already know about it. If we've seen
    // the nodeID before, use the same resource, otherwise generate a new one.
    if (!nodeID.IsEmpty()) {
        mNodeIDMap.Get(nodeID,aResource);

        if (!*aResource) {
            rv = gRDFService->GetAnonymousResource(aResource);
            mNodeIDMap.Put(nodeID,*aResource);
        }
    }
    else {
        rv = gRDFService->GetAnonymousResource(aResource);
    }

    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult RDFContentSinkImpl::GetResourceAttribute ( const PRUnichar **  aAttributes,
nsIRDFResource **  aResource 
) [protected]

Definition at line 933 of file nsRDFContentSink.cpp.

{
  nsCOMPtr<nsIAtom> localName;

  nsAutoString nodeID;

  for (; *aAttributes; aAttributes += 2) {
      const nsDependentSubstring& nameSpaceURI =
          SplitExpatName(aAttributes[0], getter_AddRefs(localName));

      // We'll accept `resource' or `rdf:resource', under the spirit
      // that we should be liberal towards the input that we
      // receive.
      if (!nameSpaceURI.IsEmpty() &&
          !nameSpaceURI.EqualsLiteral(RDF_NAMESPACE_URI)) {
          continue;
      }

      // XXX you can't specify both, but we'll just pick up the
      // first thing that was specified and ignore the other.

      if (localName == kResourceAtom) {
          nsAutoString uri(aAttributes[1]);
          nsRDFParserUtils::StripAndConvert(uri);

          // XXX Take the URI and make it fully qualified by
          // sticking it into the document's URL. This may not be
          // appropriate...
          nsCAutoString documentURL;
          mDocumentURL->GetSpec(documentURL);
          rdf_MakeAbsoluteURI(NS_ConvertUTF8toUCS2(documentURL), uri);

          return gRDFService->GetUnicodeResource(uri, aResource);
      }
      else if (localName == kNodeIdAtom) {
          nodeID.Assign(aAttributes[1]);
      }
  }

  // If nodeID is present, check if we already know about it. If we've seen
  // the nodeID before, use the same resource, otherwise generate a new one.
  if (!nodeID.IsEmpty()) {
      mNodeIDMap.Get(nodeID,aResource);

      if (!*aResource) {
          mNodeIDMap.Put(nodeID,*aResource);
          return gRDFService->GetAnonymousResource(aResource);
      }
      return NS_OK;
  }

  return NS_ERROR_FAILURE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

virtual nsISupports* RDFContentSinkImpl::GetTarget ( ) [inline, virtual]

Returns the target object (often a document object) into which the content built by this content sink is being added, if any (IOW, may return null).

Implements nsIContentSink.

Definition at line 171 of file nsRDFContentSink.cpp.

{ return nsnull; }
void nsIExpatSink::HandleCDataSection ( [size_is(aLength)] in wstring  aData,
in unsigned long  aLength 
) [inherited]

Called to handle a CDATA section.

Parameters:
aDatathe text in the CDATA section. This is null-terminated.
aLengththe length of the aData string
void nsIExpatSink::HandleCharacterData ( [size_is(aLength)] in wstring  aData,
in unsigned long  aLength 
) [inherited]

Called to handle character data.

Note that this does NOT get called for the contents of CDATA sections.

Parameters:
aDatathe data to handle. aData is NOT NULL-TERMINATED.
aLengththe length of the aData string
void nsIExpatSink::HandleComment ( in wstring  aCommentText) [inherited]

Called to handle a comment.

Parameters:
aCommentTextthe text of the comment (not including the "<!--" and "-->")
void nsIExpatSink::HandleDoctypeDecl ( in AString  aSubset,
in AString  aName,
in AString  aSystemId,
in AString  aPublicId,
in nsISupports  aCatalogData 
) [inherited]

Called to handle the doctype declaration.

void nsIExpatSink::HandleEndElement ( in wstring  aName) [inherited]

Called to handle the closing tag of an element.

Parameters:
aNamethe fully qualified tagname of the element
void nsIExpatSink::HandleProcessingInstruction ( in wstring  aTarget,
in wstring  aData 
) [inherited]

Called to handle a processing instruction.

Parameters:
aTargetthe PI target (e.g. xml-stylesheet)
aDataall the rest of the data in the PI
void nsIExpatSink::HandleStartElement ( in wstring  aName,
[array, size_is(aAttsCount)] in wstring  aAtts,
in unsigned long  aAttsCount,
in long  aIndex,
in unsigned long  aLineNumber 
) [inherited]

Called to handle the opening tag of an element.

Parameters:
aNamethe fully qualified tagname of the element
aAttsthe array of attribute names and values. There are aAttsCount/2 names and aAttsCount/2 values, so the total number of elements in the array is aAttsCount. The names and values alternate. Thus, if we number attributes starting with 0, aAtts[2*k] is the name of the k-th attribute and aAtts[2*k+1] is the value of that attribute Both explicitly specified attributes and attributes that are defined to have default values in a DTD are present in aAtts.
aAttsCountthe number of elements in aAtts.
aIndexIf the element has an attribute of type ID, then aAtts[aIndex] is the name of that attribute. Otherwise, aIndex is -1
aLineNumberthe line number of the start tag in the data stream.
void nsIExpatSink::HandleXMLDeclaration ( in wstring  aVersion,
in wstring  aEncoding,
in long  aStandalone 
) [inherited]

Handle the XML Declaration.

Parameters:
aVersionThe version string, can be null if not specified.
aEncodingThe encoding string, can be null if not specified.
aStandalone-1, 0, or 1 indicating respectively that there was no standalone parameter in the declaration, that it was given as no, or that it was given as yes.

Initialize the content sink.

Implements nsIRDFContentSink.

Definition at line 659 of file nsRDFContentSink.cpp.

{
    NS_PRECONDITION(aURL != nsnull, "null ptr");
    if (! aURL)
        return NS_ERROR_NULL_POINTER;

    mDocumentURL = aURL;
    NS_ADDREF(aURL);

    mState = eRDFContentSinkState_InProlog;
    return NS_OK;
}

Here is the call graph for this function:

nsresult RDFContentSinkImpl::InitContainer ( nsIRDFResource aContainerType,
nsIRDFResource aContainer 
) [protected]

Definition at line 1395 of file nsRDFContentSink.cpp.

{
    // Do the right kind of initialization based on the container
    // 'type' resource, and the state of the container (i.e., 'make' a
    // new container vs. 'reinitialize' the container).
    nsresult rv;

    static const ContainerInfo gContainerInfo[] = {
        { &RDFContentSinkImpl::kRDF_Alt, &nsIRDFContainerUtils::IsAlt, &nsIRDFContainerUtils::MakeAlt },
        { &RDFContentSinkImpl::kRDF_Bag, &nsIRDFContainerUtils::IsBag, &nsIRDFContainerUtils::MakeBag },
        { &RDFContentSinkImpl::kRDF_Seq, &nsIRDFContainerUtils::IsSeq, &nsIRDFContainerUtils::MakeSeq },
        { 0, 0, 0 },
    };

    for (const ContainerInfo* info = gContainerInfo; info->mType != 0; ++info) {
        if (*info->mType != aContainerType)
            continue;

        PRBool isContainer;
        rv = (gRDFContainerUtils->*(info->mTestFn))(mDataSource, aContainer, &isContainer);
        if (isContainer) {
            rv = ReinitContainer(aContainerType, aContainer);
        }
        else {
            rv = (gRDFContainerUtils->*(info->mMakeFn))(mDataSource, aContainer, nsnull);
        }
        return rv;
    }

    NS_NOTREACHED("not an RDF container type");
    return NS_ERROR_FAILURE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult RDFContentSinkImpl::OpenMember ( const PRUnichar aName,
const PRUnichar **  aAttributes 
) [protected]

Definition at line 1258 of file nsRDFContentSink.cpp.

{
    // ensure that we're actually reading a member element by making
    // sure that the opening tag is <rdf:li>, where "rdf:" corresponds
    // to whatever they've declared the standard RDF namespace to be.
    nsresult rv;

    nsCOMPtr<nsIAtom> localName;
    const nsDependentSubstring& nameSpaceURI =
        SplitExpatName(aName, getter_AddRefs(localName));

    if (!nameSpaceURI.EqualsLiteral(RDF_NAMESPACE_URI) ||
        localName != kLiAtom) {
        PR_LOG(gLog, PR_LOG_ALWAYS,
               ("rdfxml: expected RDF:li at line %d",
                -1)); // XXX pass in line number

        return NS_ERROR_UNEXPECTED;
    }

    // The parent element is the container.
    nsIRDFResource* container = GetContextElement(0);
    if (! container)
        return NS_ERROR_NULL_POINTER;

    nsIRDFResource* resource;
    if (NS_SUCCEEDED(rv = GetResourceAttribute(aAttributes, &resource))) {
        // Okay, this node has an RDF:resource="..." attribute. That
        // means that it's a "referenced item," as covered in [6.29].
        nsCOMPtr<nsIRDFContainer> c;
        NS_NewRDFContainer(getter_AddRefs(c));
        c->Init(mDataSource, container);
        c->AppendElement(resource);

        // XXX Technically, we should _not_ fall through here and push
        // the element onto the stack: this is supposed to be a closed
        // node. But right now I'm lazy and the code will just Do The
        // Right Thing so long as the RDF is well-formed.
        NS_RELEASE(resource);
    }

    // Change state. Pushing a null context element is a bit weird,
    // but the idea is that there really is _no_ context "property".
    // The contained element will use nsIRDFContainer::AppendElement() to add
    // the element to the container, which requires only the container
    // and the element to be added.
    PushContext(nsnull, mState, mParseMode);
    mState = eRDFContentSinkState_InMemberElement;
    SetParseMode(aAttributes);

    return NS_OK;
}

Here is the call graph for this function:

nsresult RDFContentSinkImpl::OpenObject ( const PRUnichar aName,
const PRUnichar **  aAttributes 
) [protected]

Definition at line 1105 of file nsRDFContentSink.cpp.

{
    // an "object" non-terminal is either a "description", a "typed
    // node", or a "container", so this change the content sink's
    // state appropriately.
    nsCOMPtr<nsIAtom> localName;
    const nsDependentSubstring& nameSpaceURI =
        SplitExpatName(aName, getter_AddRefs(localName));

    // Figure out the URI of this object, and create an RDF node for it.
    nsCOMPtr<nsIRDFResource> source;
    GetIdAboutAttribute(aAttributes, getter_AddRefs(source));

    // If there is no `ID' or `about', then there's not much we can do.
    if (! source)
        return NS_ERROR_FAILURE;

    // Push the element onto the context stack
    PushContext(source, mState, mParseMode);

    // Now figure out what kind of state transition we need to
    // make. We'll either be going into a mode where we parse a
    // description or a container.
    PRBool isaTypedNode = PR_TRUE;

    if (nameSpaceURI.EqualsLiteral(RDF_NAMESPACE_URI)) {
        isaTypedNode = PR_FALSE;

        if (localName == kDescriptionAtom) {
            // it's a description
            mState = eRDFContentSinkState_InDescriptionElement;
        }
        else if (localName == kBagAtom) {
            // it's a bag container
            InitContainer(kRDF_Bag, source);
            mState = eRDFContentSinkState_InContainerElement;
        }
        else if (localName == kSeqAtom) {
            // it's a seq container
            InitContainer(kRDF_Seq, source);
            mState = eRDFContentSinkState_InContainerElement;
        }
        else if (localName == kAltAtom) {
            // it's an alt container
            InitContainer(kRDF_Alt, source);
            mState = eRDFContentSinkState_InContainerElement;
        }
        else {
            // heh, that's not *in* the RDF namespace: just treat it
            // like a typed node
            isaTypedNode = PR_TRUE;
        }
    }

    if (isaTypedNode) {
        const char* attrName;
        localName->GetUTF8String(&attrName);

        NS_ConvertUTF16toUTF8 typeStr(nameSpaceURI);
        typeStr.Append(attrName);

        nsCOMPtr<nsIRDFResource> type;
        nsresult rv = gRDFService->GetResource(typeStr, getter_AddRefs(type));
        if (NS_FAILED(rv)) return rv;

        rv = mDataSource->Assert(source, kRDF_type, type, PR_TRUE);
        if (NS_FAILED(rv)) return rv;

        mState = eRDFContentSinkState_InDescriptionElement;
    }

    AddProperties(aAttributes, source);
    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult RDFContentSinkImpl::OpenProperty ( const PRUnichar aName,
const PRUnichar **  aAttributes 
) [protected]

Definition at line 1182 of file nsRDFContentSink.cpp.

{
    nsresult rv;

    // an "object" non-terminal is either a "description", a "typed
    // node", or a "container", so this change the content sink's
    // state appropriately.
    nsCOMPtr<nsIAtom> localName;
    const nsDependentSubstring& nameSpaceURI =
        SplitExpatName(aName, getter_AddRefs(localName));

    const char* attrName;
    localName->GetUTF8String(&attrName);

    NS_ConvertUTF16toUTF8 propertyStr(nameSpaceURI);
    propertyStr.Append(attrName);

    nsCOMPtr<nsIRDFResource> property;
    rv = gRDFService->GetResource(propertyStr, getter_AddRefs(property));
    if (NS_FAILED(rv)) return rv;

    // See if they've specified a 'resource' attribute, in which case
    // they mean *that* to be the object of this property.
    nsCOMPtr<nsIRDFResource> target;
    GetResourceAttribute(aAttributes, getter_AddRefs(target));

    PRBool isAnonymous = PR_FALSE;

    if (! target) {
        // See if an 'ID' attribute has been specified, in which case
        // this corresponds to the fourth form of [6.12].

        // XXX strictly speaking, we should reject the RDF/XML as
        // invalid if they've specified both an 'ID' and a 'resource'
        // attribute. Bah.

        // XXX strictly speaking, 'about=' isn't allowed here, but
        // what the hell.
        GetIdAboutAttribute(aAttributes, getter_AddRefs(target), &isAnonymous);
    }

    if (target) {
        // They specified an inline resource for the value of this
        // property. Create an RDF resource for the inline resource
        // URI, add the properties to it, and attach the inline
        // resource to its parent.
        PRInt32 count;
        rv = AddProperties(aAttributes, target, &count);
        NS_ASSERTION(NS_SUCCEEDED(rv), "problem adding properties");
        if (NS_FAILED(rv)) return rv;

        if (count || !isAnonymous) {
            // If the resource was "anonymous" (i.e., they hadn't
            // explicitly set an ID or resource attribute), then we'll
            // only assert this property from the context element *if*
            // there were properties specified on the anonymous
            // resource.
            rv = mDataSource->Assert(GetContextElement(0), property, target, PR_TRUE);
            if (NS_FAILED(rv)) return rv;
        }

        // XXX Technically, we should _not_ fall through here and push
        // the element onto the stack: this is supposed to be a closed
        // node. But right now I'm lazy and the code will just Do The
        // Right Thing so long as the RDF is well-formed.
    }

    // Push the element onto the context stack and change state.
    PushContext(property, mState, mParseMode);
    mState = eRDFContentSinkState_InPropertyElement;
    SetParseMode(aAttributes);

    return NS_OK;
}

Here is the call graph for this function:

Definition at line 1082 of file nsRDFContentSink.cpp.

{
    // ensure that we're actually reading RDF by making sure that the
    // opening tag is <rdf:RDF>, where "rdf:" corresponds to whatever
    // they've declared the standard RDF namespace to be.
    nsCOMPtr<nsIAtom> localName;
    const nsDependentSubstring& nameSpaceURI =
        SplitExpatName(aName, getter_AddRefs(localName));

    if (!nameSpaceURI.EqualsLiteral(RDF_NAMESPACE_URI) || localName != kRDFAtom) {
       // PR_LOG(gLog, PR_LOG_ALWAYS,
       //        ("rdfxml: expected RDF:RDF at line %d",
       //         aNode.GetSourceLineNumber()));

        return NS_ERROR_UNEXPECTED;
    }

    PushContext(nsnull, mState, mParseMode);
    mState = eRDFContentSinkState_InDocumentElement;
    return NS_OK;
}

Here is the call graph for this function:

nsresult RDFContentSinkImpl::OpenValue ( const PRUnichar aName,
const PRUnichar **  aAttributes 
) [protected]

Definition at line 1314 of file nsRDFContentSink.cpp.

{
    // a "value" can either be an object or a string: we'll only get
    // *here* if it's an object, as raw text is added as a leaf.
    return OpenObject(aName,aAttributes);
}

Here is the call graph for this function:

void RDFContentSinkImpl::ParseText ( nsIRDFNode **  aResult) [protected]

Definition at line 709 of file nsRDFContentSink.cpp.

{
    // XXXwaterson wasteful, but we'd need to make a copy anyway to be
    // able to call nsIRDFService::Get[Resource|Literal|...]().
    nsAutoString value;
    value.Append(mText, mTextLength);
    value.Trim(" \t\n\r");

    switch (mParseMode) {
    case eRDFContentSinkParseMode_Literal:
        {
            nsIRDFLiteral *result;
            gRDFService->GetLiteral(value.get(), &result);
            *aResult = result;
        }
        break;

    case eRDFContentSinkParseMode_Resource:
        {
            nsIRDFResource *result;
            gRDFService->GetUnicodeResource(value, &result);
            *aResult = result;
        }
        break;

    case eRDFContentSinkParseMode_Int:
        {
            PRInt32 i, err;
            i = value.ToInteger(&err);
            nsIRDFInt *result;
            gRDFService->GetIntLiteral(i, &result);
            *aResult = result;
        }
        break;

    case eRDFContentSinkParseMode_Date:
        {
            PRTime t = rdf_ParseDate(nsDependentCString(NS_LossyConvertUCS2toASCII(value).get(), value.Length()));
            nsIRDFDate *result;
            gRDFService->GetDateLiteral(t, &result);
            *aResult = result;
        }
        break;

    default:
        NS_NOTREACHED("unknown parse type");
        break;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult RDFContentSinkImpl::PopContext ( nsIRDFResource *&  aContext,
RDFContentSinkState aState,
RDFContentSinkParseMode aParseMode 
) [protected]

Definition at line 1508 of file nsRDFContentSink.cpp.

{
    RDFContextStackElement* e;
    if ((nsnull == mContextStack) ||
        (0 == mContextStack->Count())) {
        return NS_ERROR_NULL_POINTER;
    }

    PRInt32 i = mContextStack->Count() - 1;
    e = NS_STATIC_CAST(RDFContextStackElement*, mContextStack->ElementAt(i));
    mContextStack->RemoveElementAt(i);

    // don't bother Release()-ing: call it our implicit AddRef().
    aResource  = e->mResource;
    aState     = e->mState;
    aParseMode = e->mParseMode;

    delete e;
    return NS_OK;
}

Here is the caller graph for this function:

Definition at line 1484 of file nsRDFContentSink.cpp.

{
    if (! mContextStack) {
        mContextStack = new nsAutoVoidArray();
        if (! mContextStack)
            return 0;
    }

    RDFContextStackElement* e = new RDFContextStackElement;
    if (! e)
        return mContextStack->Count();

    NS_IF_ADDREF(aResource);
    e->mResource  = aResource;
    e->mState     = aState;
    e->mParseMode = aParseMode;
  
    mContextStack->AppendElement(NS_STATIC_CAST(void*, e));
    return mContextStack->Count();
}

Here is the caller graph for this function:

From the set of given attributes, this method extracts the namespace definitions and feeds them to the datasource.

These can then be suggested to the serializer to be used again. Hopefully, this will keep namespace definitions intact in a parse - serialize cycle.

Definition at line 1324 of file nsRDFContentSink.cpp.

{
    nsCOMPtr<nsIRDFXMLSink> sink = do_QueryInterface(mDataSource);
    if (!sink) {
        return;
    }
    NS_NAMED_LITERAL_STRING(xmlns, "http://www.w3.org/2000/xmlns/");
    for (; *aAttributes; aAttributes += 2) {
        // check the namespace
        const PRUnichar* attr = aAttributes[0];
        const PRUnichar* xmlnsP = xmlns.BeginReading();
        while (*attr ==  *xmlnsP) {
            ++attr;
            ++xmlnsP;
        }
        if (*attr != 0xFFFF ||
            xmlnsP != xmlns.EndReading()) {
            continue;
        }
        // get the localname (or "xmlns" for the default namespace)
        const PRUnichar* endLocal = ++attr;
        while (*endLocal && *endLocal != 0xFFFF) {
            ++endLocal;
        }
        nsDependentSubstring lname(attr, endLocal);
        nsCOMPtr<nsIAtom> preferred = do_GetAtom(lname);
        if (preferred == kXMLNSAtom) {
            preferred = nsnull;
        }
        sink->AddNameSpace(preferred, nsDependentString(aAttributes[1]));
    }
}

Here is the call graph for this function:

nsresult RDFContentSinkImpl::ReinitContainer ( nsIRDFResource aContainerType,
nsIRDFResource aContainer 
) [protected]

Definition at line 1431 of file nsRDFContentSink.cpp.

{
    // Mega-kludge to deal with the fact that Make[Seq|Alt|Bag] is
    // idempotent, and as such, containers will have state (e.g.,
    // RDF:nextVal) maintained in the graph across loads. This
    // re-initializes each container's RDF:nextVal to '1', and 'marks'
    // the container as such.
    nsresult rv;

    nsCOMPtr<nsIRDFLiteral> one;
    rv = gRDFService->GetLiteral(NS_LITERAL_STRING("1").get(), getter_AddRefs(one));
    if (NS_FAILED(rv)) return rv;

    // Re-initialize the 'nextval' property
    nsCOMPtr<nsIRDFNode> nextval;
    rv = mDataSource->GetTarget(aContainer, kRDF_nextVal, PR_TRUE, getter_AddRefs(nextval));
    if (NS_FAILED(rv)) return rv;

    rv = mDataSource->Change(aContainer, kRDF_nextVal, nextval, one);
    if (NS_FAILED(rv)) return rv;

    // Re-mark as a container. XXX should be kRDF_type
    rv = mDataSource->Assert(aContainer, kRDF_instanceOf, aContainerType, PR_TRUE);
    NS_ASSERTION(NS_SUCCEEDED(rv), "unable to mark container as such");
    if (NS_FAILED(rv)) return rv;

    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsIExpatSink::ReportError ( in wstring  aErrorText,
in wstring  aSourceText 
) [inherited]

Set the content sink's RDF Data source.

Implements nsIRDFContentSink.

Definition at line 673 of file nsRDFContentSink.cpp.

{
    NS_PRECONDITION(aDataSource != nsnull, "SetDataSource null ptr");
    mDataSource = aDataSource;
    NS_ASSERTION(mDataSource != nsnull,"Couldn't QI RDF DataSource");
    return NS_OK;
}
NS_IMETHOD RDFContentSinkImpl::SetDocumentCharset ( nsACString &  aCharset) [inline, virtual]

Set the document character set.

This should be passed on to the document itself.

Implements nsIContentSink.

Definition at line 170 of file nsRDFContentSink.cpp.

{ return NS_OK; }
void RDFContentSinkImpl::SetParseMode ( const PRUnichar **  aAttributes) [protected]

Definition at line 1048 of file nsRDFContentSink.cpp.

{
    nsCOMPtr<nsIAtom> localName;
    for (; *aAttributes; aAttributes += 2) {
        const nsDependentSubstring& nameSpaceURI =
            SplitExpatName(aAttributes[0], getter_AddRefs(localName));

        if (localName == kParseTypeAtom) {
            nsAutoString v(aAttributes[1]);
            nsRDFParserUtils::StripAndConvert(v);

            if (nameSpaceURI.IsEmpty() ||
                nameSpaceURI.EqualsLiteral(RDF_NAMESPACE_URI)) {
                if (v.EqualsLiteral("Resource"))
                    mParseMode = eRDFContentSinkParseMode_Resource;

                break;
            }
            else if (nameSpaceURI.EqualsLiteral(NC_NAMESPACE_URI)) {
                if (v.EqualsLiteral("Date"))
                    mParseMode = eRDFContentSinkParseMode_Date;
                else if (v.EqualsLiteral("Integer"))
                    mParseMode = eRDFContentSinkParseMode_Int;

                break;
            }
        }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

This method gets called by the parser so that the content sink can retain a reference to the parser.

The expectation is that the content sink will drop the reference when it gets the DidBuildModel notification i.e. when parsing is done.

Implements nsIContentSink.

Definition at line 650 of file nsRDFContentSink.cpp.

{
    return NS_OK;
}
const nsDependentSubstring RDFContentSinkImpl::SplitExpatName ( const PRUnichar aExpatName,
nsIAtom **  aLocalName 
) [protected]

Extracts the localname from aExpatName, the name that the Expat parser passes us.

aLocalName will contain the localname in aExpatName. The return value is a dependent string containing just the namespace.

Expat can send the following: localName namespaceURI<separator>localName namespaceURI<separator>localName<separator>prefix

and we use 0xFFFF for the <separator>.

Definition at line 1361 of file nsRDFContentSink.cpp.

{
    const PRUnichar *uriEnd = aExpatName;
    const PRUnichar *nameStart = aExpatName;
    const PRUnichar *pos;
    for (pos = aExpatName; *pos; ++pos) {
        if (*pos == 0xFFFF) {
            if (uriEnd != aExpatName) {
                break;
            }

            uriEnd = pos;
            nameStart = pos + 1;
        }
    }

    const nsDependentSubstring& nameSpaceURI = Substring(aExpatName, uriEnd);
    *aLocalName = NS_NewAtom(NS_ConvertUTF16toUTF8(nameStart,
                                                   pos - nameStart));
    return nameSpaceURI;
}

Here is the call graph for this function:

Here is the caller graph for this function:

This method gets called when the parser begins the process of building the content model via the content sink.

5/7/98 gess

Implements nsIContentSink.

Definition at line 606 of file nsRDFContentSink.cpp.

{
    if (mDataSource) {
        nsCOMPtr<nsIRDFXMLSink> sink = do_QueryInterface(mDataSource);
        if (sink) 
            return sink->BeginLoad();
    }
    return NS_OK;
}

Here is the call graph for this function:

This method gets called when the parser gets i/o blocked, and wants to notify the sink that it may be a while before more data is available.

5/7/98 gess

Implements nsIContentSink.

Definition at line 628 of file nsRDFContentSink.cpp.

{
    if (mDataSource) {
        nsCOMPtr<nsIRDFXMLSink> sink = do_QueryInterface(mDataSource);
        if (sink)
            return sink->Interrupt();
    }
    return NS_OK;
}

Here is the call graph for this function:

This method gets called when the parser i/o gets unblocked, and we're about to start dumping content again to the sink.

5/7/98 gess

Implements nsIContentSink.

Definition at line 639 of file nsRDFContentSink.cpp.

{
    if (mDataSource) {
        nsCOMPtr<nsIRDFXMLSink> sink = do_QueryInterface(mDataSource);
        if (sink)
            return sink->Resume();
    }
    return NS_OK;
}

Here is the call graph for this function:


Member Data Documentation

Definition at line 181 of file nsRDFContentSink.cpp.

Definition at line 180 of file nsRDFContentSink.cpp.

Definition at line 179 of file nsRDFContentSink.cpp.

Definition at line 189 of file nsRDFContentSink.cpp.

Definition at line 192 of file nsRDFContentSink.cpp.

Definition at line 198 of file nsRDFContentSink.cpp.

Definition at line 196 of file nsRDFContentSink.cpp.

Definition at line 195 of file nsRDFContentSink.cpp.

Definition at line 190 of file nsRDFContentSink.cpp.

Definition at line 199 of file nsRDFContentSink.cpp.

Definition at line 191 of file nsRDFContentSink.cpp.

Definition at line 201 of file nsRDFContentSink.cpp.

Definition at line 184 of file nsRDFContentSink.cpp.

Definition at line 185 of file nsRDFContentSink.cpp.

Definition at line 183 of file nsRDFContentSink.cpp.

Definition at line 187 of file nsRDFContentSink.cpp.

Definition at line 186 of file nsRDFContentSink.cpp.

Definition at line 182 of file nsRDFContentSink.cpp.

Definition at line 194 of file nsRDFContentSink.cpp.

Definition at line 193 of file nsRDFContentSink.cpp.

Definition at line 197 of file nsRDFContentSink.cpp.

Definition at line 200 of file nsRDFContentSink.cpp.

nsAutoVoidArray* RDFContentSinkImpl::mContextStack [protected]

Definition at line 279 of file nsRDFContentSink.cpp.

Definition at line 257 of file nsRDFContentSink.cpp.

Definition at line 281 of file nsRDFContentSink.cpp.

Definition at line 260 of file nsRDFContentSink.cpp.

Definition at line 264 of file nsRDFContentSink.cpp.

Definition at line 263 of file nsRDFContentSink.cpp.

Definition at line 230 of file nsRDFContentSink.cpp.

Definition at line 231 of file nsRDFContentSink.cpp.

Definition at line 232 of file nsRDFContentSink.cpp.


The documentation for this class was generated from the following file: