From 4535dd3693f48ad9bada5575159f4ad10387e873 Mon Sep 17 00:00:00 2001 From: Kris Maglione Date: Mon, 7 May 2018 19:35:51 -0700 Subject: [PATCH 01/34] Bug 1457749: Part 1 - Import RDFDataSource from McCoy and modernize. r=Mossop MozReview-Commit-ID: 7y7kGE2kF9E --HG-- extra : rebase_source : a9825fc7cef14808088b7e1346fdfc9935ca89fc extra : histedit_source : b18a3096bdb2dece7f76bbad0c47314dd11cefbc --- .../extensions/internal/RDFDataSource.jsm | 1515 +++++++++++++++++ toolkit/mozapps/extensions/internal/moz.build | 1 + 2 files changed, 1516 insertions(+) create mode 100644 toolkit/mozapps/extensions/internal/RDFDataSource.jsm diff --git a/toolkit/mozapps/extensions/internal/RDFDataSource.jsm b/toolkit/mozapps/extensions/internal/RDFDataSource.jsm new file mode 100644 index 000000000000..7de69acba705 --- /dev/null +++ b/toolkit/mozapps/extensions/internal/RDFDataSource.jsm @@ -0,0 +1,1515 @@ + /* 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 module creates a new API for accessing and modifying RDF graphs. The + * goal is to be able to serialise the graph in a human readable form. Also + * if the graph was originally loaded from an RDF/XML the serialisation should + * closely match the original with any new data closely following the existing + * layout. The output should always be compatible with Mozilla's RDF parser. + * + * This is all achieved by using a DOM Document to hold the current state of the + * graph in XML form. This can be initially loaded and parsed from disk or + * a blank document used for an empty graph. As assertions are added to the + * graph, appropriate DOM nodes are added to the document to represent them + * along with any necessary whitespace to properly layout the XML. + * + * In general the order of adding assertions to the graph will impact the form + * the serialisation takes. If a resource is first added as the object of an + * assertion then it will eventually be serialised inside the assertion's + * property element. If a resource is first added as the subject of an assertion + * then it will be serialised at the top level of the XML. + */ + +const NS_XML = "http://www.w3.org/XML/1998/namespace"; +const NS_XMLNS = "http://www.w3.org/2000/xmlns/"; +const NS_RDF = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"; +const NS_NC = "http://home.netscape.com/NC-rdf#"; + +/* eslint prefer-template: 1 */ + +function raw(strings) { + return strings.raw[0].replace(/\s+/, ""); +} + +// Copied from http://www.w3.org/TR/2000/REC-xml-20001006#CharClasses +const XML_LETTER = raw` + \u0041-\u005A\u0061-\u007A\u00C0-\u00D6\u00D8-\u00F6 + \u00F8-\u00FF\u0100-\u0131\u0134-\u013E\u0141-\u0148 + \u014A-\u017E\u0180-\u01C3\u01CD-\u01F0\u01F4-\u01F5 + \u01FA-\u0217\u0250-\u02A8\u02BB-\u02C1\u0386\u0388-\u038A + \u038C\u038E-\u03A1\u03A3-\u03CE\u03D0-\u03D6\u03DA\u03DC + \u03DE\u03E0\u03E2-\u03F3\u0401-\u040C\u040E-\u044F + \u0451-\u045C\u045E-\u0481\u0490-\u04C4\u04C7-\u04C8 + \u04CB-\u04CC\u04D0-\u04EB\u04EE-\u04F5\u04F8-\u04F9 + \u0531-\u0556\u0559\u0561-\u0586\u05D0-\u05EA\u05F0-\u05F2 + \u0621-\u063A\u0641-\u064A\u0671-\u06B7\u06BA-\u06BE + \u06C0-\u06CE\u06D0-\u06D3\u06D5\u06E5-\u06E6\u0905-\u0939 + \u093D\u0958-\u0961\u0985-\u098C\u098F-\u0990\u0993-\u09A8 + \u09AA-\u09B0\u09B2\u09B6-\u09B9\u09DC-\u09DD\u09DF-\u09E1 + \u09F0-\u09F1\u0A05-\u0A0A\u0A0F-\u0A10\u0A13-\u0A28 + \u0A2A-\u0A30\u0A32-\u0A33\u0A35-\u0A36\u0A38-\u0A39 + \u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8B\u0A8D + \u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2-\u0AB3 + \u0AB5-\u0AB9\u0ABD\u0AE0\u0B05-\u0B0C\u0B0F-\u0B10 + \u0B13-\u0B28\u0B2A-\u0B30\u0B32-\u0B33\u0B36-\u0B39 + \u0B3D\u0B5C-\u0B5D\u0B5F-\u0B61\u0B85-\u0B8A\u0B8E-\u0B90 + \u0B92-\u0B95\u0B99-\u0B9A\u0B9C\u0B9E-\u0B9F\u0BA3-\u0BA4 + \u0BA8-\u0BAA\u0BAE-\u0BB5\u0BB7-\u0BB9\u0C05-\u0C0C + \u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39 + \u0C60-\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8 + \u0CAA-\u0CB3\u0CB5-\u0CB9\u0CDE\u0CE0-\u0CE1\u0D05-\u0D0C + \u0D0E-\u0D10\u0D12-\u0D28\u0D2A-\u0D39\u0D60-\u0D61 + \u0E01-\u0E2E\u0E30\u0E32-\u0E33\u0E40-\u0E45\u0E81-\u0E82 + \u0E84\u0E87-\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F + \u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA-\u0EAB\u0EAD-\u0EAE\u0EB0 + \u0EB2-\u0EB3\u0EBD\u0EC0-\u0EC4\u0F40-\u0F47\u0F49-\u0F69 + \u10A0-\u10C5\u10D0-\u10F6\u1100\u1102-\u1103\u1105-\u1107 + \u1109\u110B-\u110C\u110E-\u1112\u113C\u113E\u1140\u114C + \u114E\u1150\u1154-\u1155\u1159\u115F-\u1161\u1163\u1165 + \u1167\u1169\u116D-\u116E\u1172-\u1173\u1175\u119E\u11A8 + \u11AB\u11AE-\u11AF\u11B7-\u11B8\u11BA\u11BC-\u11C2\u11EB + \u11F0\u11F9\u1E00-\u1E9B\u1EA0-\u1EF9\u1F00-\u1F15 + \u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57 + \u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC + \u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB + \u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2126\u212A-\u212B + \u212E\u2180-\u2182\u3041-\u3094\u30A1-\u30FA\u3105-\u312C + \uAC00-\uD7A3\u4E00-\u9FA5\u3007\u3021-\u3029 +`; +const XML_DIGIT = raw` + \u0030-\u0039\u0660-\u0669\u06F0-\u06F9\u0966-\u096F + \u09E6-\u09EF\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F + \u0BE7-\u0BEF\u0C66-\u0C6F\u0CE6-\u0CEF\u0D66-\u0D6F + \u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F29 +`; +const XML_COMBINING = raw` + \u0300-\u0345\u0360-\u0361\u0483-\u0486\u0591-\u05A1 + \u05A3-\u05B9\u05BB-\u05BD\u05BF\u05C1-\u05C2\u05C4 + \u064B-\u0652\u0670\u06D6-\u06DC\u06DD-\u06DF\u06E0-\u06E4 + \u06E7-\u06E8\u06EA-\u06ED\u0901-\u0903\u093C\u093E-\u094C + \u094D\u0951-\u0954\u0962-\u0963\u0981-\u0983\u09BC\u09BE + \u09BF\u09C0-\u09C4\u09C7-\u09C8\u09CB-\u09CD\u09D7 + \u09E2-\u09E3\u0A02\u0A3C\u0A3E\u0A3F\u0A40-\u0A42 + \u0A47-\u0A48\u0A4B-\u0A4D\u0A70-\u0A71\u0A81-\u0A83 + \u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0B01-\u0B03 + \u0B3C\u0B3E-\u0B43\u0B47-\u0B48\u0B4B-\u0B4D\u0B56-\u0B57 + \u0B82-\u0B83\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7 + \u0C01-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D + \u0C55-\u0C56\u0C82-\u0C83\u0CBE-\u0CC4\u0CC6-\u0CC8 + \u0CCA-\u0CCD\u0CD5-\u0CD6\u0D02-\u0D03\u0D3E-\u0D43 + \u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0E31\u0E34-\u0E3A + \u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB-\u0EBC\u0EC8-\u0ECD + \u0F18-\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84 + \u0F86-\u0F8B\u0F90-\u0F95\u0F97\u0F99-\u0FAD\u0FB1-\u0FB7 + \u0FB9\u20D0-\u20DC\u20E1\u302A-\u302F\u3099\u309A +`; +const XML_EXTENDER = raw` + \u00B7\u02D0\u02D1\u0387\u0640\u0E46\u0EC6\u3005 + \u3031-\u3035\u309D-\u309E\u30FC-\u30FE +`; +const XML_NCNAMECHAR = String.raw`${XML_LETTER}${XML_DIGIT}\.\-_${XML_COMBINING}${XML_EXTENDER}`; +const XML_NCNAME = new RegExp(`^[${XML_LETTER}_][${XML_NCNAMECHAR}]*$`); + +const URI_SUFFIX = /[A-Za-z_][0-9A-Za-z\.\-_]*$/; +const INDENT = /\n([ \t]*)$/; +const RDF_LISTITEM = /^http:\/\/www.w3.org\/1999\/02\/22-rdf-syntax-ns#_\d+$/; + +const RDF_NODE_INVALID_TYPES = + ["RDF", "ID", "about", "bagID", "parseType", "resource", "nodeID", + "li", "aboutEach", "aboutEachPrefix"]; +const RDF_PROPERTY_INVALID_TYPES = + ["Description", "RDF", "ID", "about", "bagID", "parseType", "resource", + "nodeID", "aboutEach", "aboutEachPrefix"]; + +/** + * Whether to use properly namespaces attributes for rdf:about etc... + * When on this produces poor output in the event that the rdf namespace is the + * default namespace, and the parser recognises unnamespaced attributes and + * most of our rdf examples are unnamespaced so leaving off for the time being. + */ +const USE_RDFNS_ATTR = false; + +var EXPORTED_SYMBOLS = ["RDFLiteral", "RDFIntLiteral", "RDFDateLiteral", + "RDFBlankNode", "RDFResource", "RDFDataSource"]; + +Cu.importGlobalProperties(["DOMParser", "Element", "XMLSerializer", "fetch"]); + +ChromeUtils.defineModuleGetter(this, "OS", + "resource://gre/modules/osfile.jsm"); +ChromeUtils.defineModuleGetter(this, "Services", + "resource://gre/modules/Services.jsm"); + +function isAttr(obj) { + return obj && typeof obj == "object" && ChromeUtils.getClassName(obj) == "Attr"; +} +function isDocument(obj) { + return obj && typeof obj == "object" && obj.nodeType == Element.DOCUMENT_NODE; +} +function isElement(obj) { + return Element.isInstance(obj); +} +function isText(obj) { + return obj && typeof obj == "object" && ChromeUtils.getClassName(obj) == "Text"; +} + +/** + * Logs an error message to the error console + */ +function ERROR(str) { + Cu.reportError(str); +} + +function RDF_R(name) { + return NS_RDF + name; +} + +function renameNode(domnode, namespaceURI, qname) { + if (isElement(domnode)) { + var newdomnode = domnode.ownerDocument.createElementNS(namespaceURI, qname); + if ("listCounter" in domnode) + newdomnode.listCounter = domnode.listCounter; + domnode.replaceWith(newdomnode); + while (domnode.firstChild) + newdomnode.appendChild(domnode.firstChild); + for (let attr of domnode.attributes) { + domnode.removeAttributeNode(attr); + newdomnode.setAttributeNode(attr); + } + return newdomnode; + } else if (isAttr(domnode)) { + if (domnode.ownerElement.hasAttribute(namespaceURI, qname)) + throw new Error("attribute already exists"); + var attr = domnode.ownerDocument.createAttributeNS(namespaceURI, qname); + attr.value = domnode.value; + domnode.ownerElement.setAttributeNode(attr); + domnode.ownerElement.removeAttributeNode(domnode); + return attr; + } + throw new Error("cannot rename node of this type"); +} + +function predicateOrder(a, b) { + return a.getPredicate().localeCompare(b.getPredicate()); +} + +/** + * Returns either an rdf namespaced attribute or an un-namespaced attribute + * value. Returns null if neither exists, + */ +function getRDFAttribute(element, name) { + if (element.hasAttributeNS(NS_RDF, name)) + return element.getAttributeNS(NS_RDF, name); + if (element.hasAttribute(name)) + return element.getAttribute(name); + return undefined; +} + +/** + * Represents an assertion in the datasource + */ +class RDFAssertion { + constructor(subject, predicate, object) { + if (!(subject instanceof RDFSubject)) + throw new Error("subject must be an RDFSubject"); + + if (typeof(predicate) != "string") + throw new Error("predicate must be a string URI"); + + if (!(object instanceof RDFLiteral) && !(object instanceof RDFSubject)) + throw new Error("object must be a concrete RDFNode"); + + if (object instanceof RDFSubject && object._ds != subject._ds) + throw new Error("object must be from the same datasource as subject"); + + // The subject on this assertion, an RDFSubject + this._subject = subject; + // The predicate, a string + this._predicate = predicate; + // The object, an RDFNode + this._object = object; + // The datasource this assertion exists in + this._ds = this._subject._ds; + // Marks that _DOMnode is the subject's element + this._isSubjectElement = false; + // The DOM node that represents this assertion. Could be a property element, + // a property attribute or the subject's element for rdf:type + this._DOMNode = null; + } + + /** + * Adds content to _DOMnode to store this assertion in the DOM document. + */ + _applyToDOMNode() { + if (this._object instanceof RDFLiteral) + this._object._applyToDOMNode(this._ds, this._DOMnode); + else + this._object._addReferenceToElement(this._DOMnode); + } + + /** + * Returns the DOM Element linked to the subject that this assertion is + * attached to. + */ + _getSubjectElement() { + if (isAttr(this._DOMnode)) + return this._DOMnode.ownerElement; + if (this._isSubjectElement) + return this._DOMnode; + return this._DOMnode.parentNode; + } + + getSubject() { + return this._subject; + } + + getPredicate() { + return this._predicate; + } + + getObject() { + return this._object; + } +} + +class RDFNode { + equals(rdfnode) { + return (rdfnode.constructor === this.constructor && + rdfnode._value == this._value); + } +} + +/** + * A simple literal value + */ +class RDFLiteral extends RDFNode { + constructor(value) { + super(); + this._value = value; + } + + /** + * This stores the value of the literal in the given DOM node + */ + _applyToDOMNode(ds, domnode) { + if (isElement(domnode)) + domnode.textContent = this._value; + else if (isAttr(domnode)) + domnode.value = this._value; + else + throw new Error("cannot use this node for a literal"); + } + + getValue() { + return this._value; + } +} + +/** + * A literal that is integer typed. + */ +class RDFIntLiteral extends RDFLiteral { + constructor(value) { + super(parseInt(value)); + } + + /** + * This stores the value of the literal in the given DOM node + */ + _applyToDOMNode(ds, domnode) { + if (!isElement(domnode)) + throw new Error("cannot use this node for a literal"); + + RDFLiteral.prototype._applyToDOMNode.call(this, ds, domnode); + var prefix = ds._resolvePrefix(domnode, `${NS_NC}parseType`); + domnode.setAttributeNS(prefix.namespaceURI, prefix.qname, "Integer"); + } +} + +/** + * A literal that represents a date. + */ +class RDFDateLiteral extends RDFLiteral { + constructor(value) { + if (!(value instanceof Date)) + throw new Error("RDFDateLiteral must be constructed with a Date object"); + + super(value); + } + + /** + * This stores the value of the literal in the given DOM node + */ + _applyToDOMNode(ds, domnode) { + if (!isElement(domnode)) + throw new Error("cannot use this node for a literal"); + + domnode.textContent = this._value.getTime(); + var prefix = ds._resolvePrefix(domnode, `${NS_NC}parseType`); + domnode.setAttributeNS(prefix.namespaceURI, prefix.qname, "Date"); + } +} + +/** + * This is an RDF node that can be a subject so a resource or a blank node + */ +class RDFSubject extends RDFNode { + constructor(ds) { + super(); + // A lookup of the assertions with this as the subject. Keyed on predicate + this._assertions = {}; + // A lookup of the assertions with this as the object. Keyed on predicate + this._backwards = {}; + // The datasource this subject belongs to + this._ds = ds; + // The DOM elements in the document that represent this subject. Array of Element + this._elements = []; + } + + /** + * Creates a new Element in the document for holding assertions about this + * subject. The URI controls what tagname to use. + */ + _createElement(uri) { + // Seek an appropriate reference to this node to add this node under + var parent = null; + for (var p in this._backwards) { + for (let back of this._backwards[p]) { + // Don't add under an rdf:type + if (back.getPredicate() == RDF_R("type")) + continue; + // The assertion already has a child node, probably one of ours + if (back._DOMnode.firstChild) + continue; + parent = back._DOMnode; + var element = this._ds._addElement(parent, uri); + this._removeReferenceFromElement(parent); + break; + } + if (parent) + break; + } + + // No back assertions that are sensible to use + if (!parent) + element = this._ds._addElement(this._ds._document.documentElement, uri); + + element.listCounter = 1; + this._applyToElement(element); + this._elements.push(element); + return element; + } + + /** + * When a DOM node representing this subject is removed from the document + * we must remove the node and recreate any child assertions elsewhere. + */ + _removeElement(element) { + var pos = this._elements.indexOf(element); + if (pos < 0) + throw new Error("invalid element"); + this._elements.splice(pos, 1); + if (element.parentNode != element.ownerDocument.documentElement) + this._addReferenceToElement(element.parentNode); + this._ds._removeElement(element); + + // Find all the assertions that are represented here and create new + // nodes for them. + for (var predicate in this._assertions) { + for (let assertion of this._assertions[predicate]) { + if (assertion._getSubjectElement() == element) + this._createDOMNodeForAssertion(assertion); + } + } + } + + /** + * Creates a DOM node to represent the assertion in the document. If the + * assertion has rdf:type as the predicate then an attempt will be made to + * create a typed subject Element, otherwise a new property Element is + * created. For list items an attempt is made to find an appropriate container + * that an rdf:li element can be added to. + */ + _createDOMNodeForAssertion(assertion) { + let elements; + if (RDF_LISTITEM.test(assertion.getPredicate())) { + // Find all the containers + elements = this._elements.filter(function(element) { + return (element.namespaceURI == NS_RDF && (element.localName == "Seq" || + element.localName == "Bag" || + element.localName == "Alt")); + }); + if (elements.length > 0) { + // Look for one whose listCounter matches the item we want to add + var item = parseInt(assertion.getPredicate().substring(NS_RDF.length + 1)); + for (let element of elements) { + if (element.listCounter == item) { + assertion._DOMnode = this._ds._addElement(element, RDF_R("li")); + assertion._applyToDOMNode(); + element.listCounter++; + return; + } + } + // No good container to add to, shove in the first real container + assertion._DOMnode = this._ds._addElement(elements[0], assertion.getPredicate()); + assertion._applyToDOMNode(); + return; + } + // TODO No containers, this will end up in a non-container for now + } else if (assertion.getPredicate() == RDF_R("type")) { + // Try renaming an existing rdf:Description + for (let element of this.elements) { + if (element.namespaceURI == NS_RDF && + element.localName == "Description") { + try { + var prefix = this._ds._resolvePrefix(element.parentNode, assertion.getObject().getURI()); + element = renameNode(element, prefix.namespaceURI, prefix.qname); + assertion._DOMnode = element; + assertion._isSubjectElement = true; + return; + } catch (e) { + // If the type cannot be sensibly turned into a prefix then just set + // as a regular property + } + } + } + } + + // Filter out all the containers + elements = this._elements.filter(function(element) { + return (element.namespaceURI != NS_RDF || (element.localName != "Seq" && + element.localName != "Bag" && + element.localName != "Alt")); + }); + if (elements.length == 0) { + // Create a new node of the right type + if (assertion.getPredicate() == RDF_R("type")) { + try { + assertion._DOMnode = this._createElement(assertion.getObject().getURI()); + assertion._isSubjectElement = true; + return; + } catch (e) { + // If the type cannot be sensibly turned into a prefix then just set + // as a regular property + } + } + elements[0] = this._createElement(RDF_R("Description")); + } + assertion._DOMnode = this._ds._addElement(elements[0], assertion.getPredicate()); + assertion._applyToDOMNode(); + } + + /** + * Removes the DOM node representing the assertion. + */ + _removeDOMNodeForAssertion(assertion) { + if (isAttr(assertion._DOMnode)) { + var parent = assertion._DOMnode.ownerElement; + parent.removeAttributeNode(assertion._DOMnode); + } else if (assertion._isSubjectElement) { + var domnode = renameNode(assertion._DOMnode, NS_RDF, "Description"); + if (domnode != assertion._DOMnode) { + var pos = this._elements.indexOf(assertion._DOMnode); + this._elements.splice(pos, 1, domnode); + } + parent = domnode; + } else { + var object = assertion.getObject(); + if (object instanceof RDFSubject && assertion._DOMnode.firstChild) { + // Object is a subject that has an Element inside this assertion's node. + for (let element of object._elements) { + if (element.parentNode == assertion._DOMnode) { + object._removeElement(element); + break; + } + } + } + parent = assertion._DOMnode.parentNode; + if (assertion._DOMnode.namespaceURI == NS_RDF && + assertion._DOMnode.localName == "li") + parent.listCounter--; + this._ds._removeElement(assertion._DOMnode); + } + + // If there are no assertions left using the assertion's containing dom node + // then remove it from the document. + // TODO could do with a quick lookup list for assertions attached to a node + for (var p in this._assertions) { + for (let assertion of this._assertions[p]) { + if (assertion._getSubjectElement() == parent) + return; + } + } + // No assertions left in this element. + this._removeElement(parent); + } + + /** + * Parses the given Element from the DOM document + */ + _parseElement(element) { + this._elements.push(element); + + // There might be an inferred rdf:type assertion in the element name + if (element.namespaceURI != NS_RDF || + element.localName != "Description") { + if (element.namespaceURI == NS_RDF && element.localName == "li") + throw new Error("rdf:li is not a valid type for a subject node"); + var assertion = new RDFAssertion(this, RDF_R("type"), + this._ds.getResource(element.namespaceURI + element.localName)); + assertion._DOMnode = element; + assertion._isSubjectElement = true; + this._addAssertion(assertion); + } + + // Certain attributes can be literal properties + for (let attr of element.attributes) { + if (attr.namespaceURI == NS_XML || attr.namespaceURI == NS_XMLNS || + attr.nodeName == "xmlns") + continue; + if ((attr.namespaceURI == NS_RDF || !attr.namespaceURI) && + (["nodeID", "about", "resource", "ID", "parseType"].includes(attr.localName))) + continue; + var object = null; + if (attr.namespaceURI == NS_RDF) { + if (attr.localName == "type") + object = this._ds.getResource(attr.nodeValue); + else if (attr.localName == "li") + throw new Error("rdf:li is not allowed as a property attribute"); + else if (attr.localName == "aboutEach") + throw new Error("rdf:aboutEach is deprecated"); + else if (attr.localName == "aboutEachPrefix") + throw new Error("rdf:aboutEachPrefix is deprecated"); + else if (attr.localName == "aboutEach") + throw new Error("rdf:aboutEach is deprecated"); + else if (attr.localName == "bagID") + throw new Error("rdf:bagID is deprecated"); + } + if (!object) + object = new RDFLiteral(attr.nodeValue); + assertion = new RDFAssertion(this, attr.namespaceURI + attr.localName, object); + assertion._DOMnode = attr; + this._addAssertion(assertion); + } + + var child = element.firstChild; + element.listCounter = 1; + while (child) { + if (isText(child) && /\S/.test(child.nodeValue)) { + ERROR(`Text ${child.nodeValue} is not allowed in a subject node`); + throw new Error("subject nodes cannot contain text content"); + } else if (isElement(child)) { + object = null; + var predicate = child.namespaceURI + child.localName; + if (child.namespaceURI == NS_RDF) { + if (RDF_PROPERTY_INVALID_TYPES.includes(child.localName) && + !child.localName.match(/^_\d+$/)) + throw new Error(`${child.nodeName} is an invalid property`); + if (child.localName == "li") { + predicate = RDF_R(`_${element.listCounter}`); + element.listCounter++; + } + } + + // Check for and bail out on unknown attributes on the property element + for (let attr of child.attributes) { + // Ignore XML namespaced attributes + if (attr.namespaceURI == NS_XML) + continue; + // These are reserved by XML for future use + if (attr.localName.substring(0, 3).toLowerCase() == "xml") + continue; + // We can handle these RDF attributes + if ((!attr.namespaceURI || attr.namespaceURI == NS_RDF) && + ["resource", "nodeID"].includes(attr.localName)) + continue; + // This is a special attribute we handle for compatibility with Mozilla RDF + if (attr.namespaceURI == NS_NC && + attr.localName == "parseType") + continue; + throw new Error(`Attribute ${attr.nodeName} is not supported`); + } + + var parseType = child.getAttributeNS(NS_NC, "parseType"); + if (parseType && parseType != "Date" && parseType != "Integer") { + ERROR(`parseType ${parseType} is not supported`); + throw new Error("unsupported parseType"); + } + + var resource = getRDFAttribute(child, "resource"); + var nodeID = getRDFAttribute(child, "nodeID"); + if ((resource && (nodeID || parseType)) || + (nodeID && (resource || parseType))) { + ERROR("Cannot use more than one of parseType, resource and nodeID on a single node"); + throw new Error("Invalid rdf assertion"); + } + + if (resource !== undefined) { + var base = Services.io.newURI(element.baseURI); + object = this._ds.getResource(base.resolve(resource)); + } else if (nodeID !== undefined) { + if (!nodeID.match(XML_NCNAME)) + throw new Error("rdf:nodeID must be a valid XML name"); + object = this._ds.getBlankNode(nodeID); + } else { + var hasText = false; + var childElement = null; + var subchild = child.firstChild; + while (subchild) { + if (isText(subchild) && /\S/.test(subchild.nodeValue)) { + hasText = true; + } else if (isElement(subchild)) { + if (childElement) { + new Error(`Multiple object elements found in ${child.nodeName}`); + } + childElement = subchild; + } + subchild = subchild.nextSibling; + } + + if ((resource || nodeID) && (hasText || childElement)) { + ERROR("Assertion references a resource so should not contain additional contents"); + throw new Error("assertion cannot contain multiple objects"); + } + + if (hasText && childElement) { + ERROR(`Both literal and resource objects found in ${child.nodeName}`); + throw new Error("assertion cannot contain multiple objects"); + } + + if (childElement) { + if (parseType) { + ERROR("Cannot specify a parseType for an assertion with resource object"); + throw new Error("parseType is not valid in this context"); + } + object = this._ds._getSubjectForElement(childElement); + object._parseElement(childElement); + } else if (parseType == "Integer") + object = new RDFIntLiteral(child.textContent); + else if (parseType == "Date") + object = new RDFDateLiteral(new Date(child.textContent)); + else + object = new RDFLiteral(child.textContent); + } + + assertion = new RDFAssertion(this, predicate, object); + this._addAssertion(assertion); + assertion._DOMnode = child; + } + child = child.nextSibling; + } + } + + /** + * Adds a new assertion to the internal hashes. Should be called for every + * new assertion parsed or created programmatically. + */ + _addAssertion(assertion) { + var predicate = assertion.getPredicate(); + if (predicate in this._assertions) + this._assertions[predicate].push(assertion); + else + this._assertions[predicate] = [ assertion ]; + + var object = assertion.getObject(); + if (object instanceof RDFSubject) { + // Create reverse assertion + if (predicate in object._backwards) + object._backwards[predicate].push(assertion); + else + object._backwards[predicate] = [ assertion ]; + } + } + + /** + * Removes an assertion from the internal hashes. Should be called for all + * assertions that are programatically deleted. + */ + _removeAssertion(assertion) { + var predicate = assertion.getPredicate(); + if (predicate in this._assertions) { + var pos = this._assertions[predicate].indexOf(assertion); + if (pos >= 0) + this._assertions[predicate].splice(pos, 1); + if (this._assertions[predicate].length == 0) + delete this._assertions[predicate]; + } + + var object = assertion.getObject(); + if (object instanceof RDFSubject) { + // Delete reverse assertion + if (predicate in object._backwards) { + pos = object._backwards[predicate].indexOf(assertion); + if (pos >= 0) + object._backwards[predicate].splice(pos, 1); + if (object._backwards[predicate].length == 0) + delete object._backwards[predicate]; + } + } + } + + /** + * Returns the ordinal assertions from this subject in order. + */ + _getChildAssertions() { + var assertions = []; + for (var i in this._assertions) { + if (RDF_LISTITEM.test(i)) + assertions.push(...this._assertions[i]); + } + assertions.sort(predicateOrder); + return assertions; + } + + /** + * Compares this to another rdf node + */ + equals(rdfnode) { + // subjects are created by the datasource so no two objects ever correspond + // to the same one. + return this === rdfnode; + } + + /** + * Adds a new assertion with this as the subject + */ + assert(predicate, object) { + if (predicate == RDF_R("type") && !(object instanceof RDFResource)) + throw new Error("rdf:type must be an RDFResource"); + + var assertion = new RDFAssertion(this, predicate, object); + this._createDOMNodeForAssertion(assertion); + this._addAssertion(assertion); + } + + /** + * Removes an assertion matching the predicate and node given, if such an + * assertion exists. + */ + unassert(predicate, object) { + if (!(predicate in this._assertions)) + return; + + for (let assertion of this._assertions[predicate]) { + if (assertion.getObject().equals(object)) { + this._removeAssertion(assertion); + this._removeDOMNodeForAssertion(assertion); + return; + } + } + } + + /** + * Returns an array of all the predicates that exist in assertions from this + * subject. + */ + getPredicates() { + return Object.keys(this._assertions); + } + + /** + * Returns all objects in assertions with this subject and the given predicate. + */ + getObjects(predicate) { + if (predicate in this._assertions) + return Array.from(this._assertions[predicate], + i => i.getObject()); + + return []; + } + + /** + * Returns all of the ordinal children of this subject in order. + */ + getChildren() { + return Array.from(this._getChildAssertions(), + i => i.getObject()); + } + + /** + * Removes the child at the given index. This is the index based on the + * children returned from getChildren. Forces a reordering of the later + * children. + */ + removeChildAt(pos) { + if (pos < 0) + throw new Error("no such child"); + var assertions = this._getChildAssertions(); + if (pos >= assertions.length) + throw new Error("no such child"); + for (var i = pos; i < assertions.length; i++) { + this._removeAssertion(assertions[i]); + this._removeDOMNodeForAssertion(assertions[i]); + } + var index = 1; + if (pos > 0) + index = parseInt(assertions[pos - 1].getPredicate().substring(NS_RDF.length + 1)) + 1; + for (let i = pos + 1; i < assertions.length; i++) { + assertions[i]._predicate = RDF_R(`_${index}`); + this._addAssertion(assertions[i]); + this._createDOMNodeForAssertion(assertions[i]); + index++; + } + } + + /** + * Removes the child with the given object. It is unspecified which child is + * removed if the object features more than once. + */ + removeChild(object) { + var assertions = this._getChildAssertions(); + for (var pos = 0; pos < assertions.length; pos++) { + if (assertions[pos].getObject().equals(object)) { + for (var i = pos; i < assertions.length; i++) { + this._removeAssertion(assertions[i]); + this._removeDOMNodeForAssertion(assertions[i]); + } + var index = 1; + if (pos > 0) + index = parseInt(assertions[pos - 1].getPredicate().substring(NS_RDF.length + 1)) + 1; + for (let i = pos + 1; i < assertions.length; i++) { + assertions[i]._predicate = RDF_R(`_${index}`); + this._addAssertion(assertions[i]); + this._createDOMNodeForAssertion(assertions[i]); + index++; + } + return; + } + } + throw new Error("no such child"); + } + + /** + * Adds a new ordinal child to this subject. + */ + addChild(object) { + var max = 0; + for (var i in this._assertions) { + if (RDF_LISTITEM.test(i)) + max = Math.max(max, parseInt(i.substring(NS_RDF.length + 1))); + } + max++; + this.assert(RDF_R(`_${max}`), object); + } + + /** + * This reorders the child assertions to remove duplicates and gaps in the + * sequence. Generally this will move all children to be under the same + * container element and all represented as an rdf:li + */ + reorderChildren() { + var assertions = this._getChildAssertions(); + for (let assertion of assertions) { + this._removeAssertion(assertion); + this._removeDOMNodeForAssertion(assertion); + } + var index = 1; + for (let assertion of assertions) { + assertion._predicate = RDF_R(`_${index}`); + this._addAssertion(assertion); + this._createDOMNodeForAssertion(assertion); + index++; + } + } + + /** + * Returns the type of this subject or null if there is no specified type. + */ + getType() { + var type = this.getProperty(RDF_R("type")); + if (type && type instanceof RDFResource) + return type.getURI(); + return null; + } + + /** + * Tests if a property exists for the given predicate. + */ + hasProperty(predicate) { + return (predicate in this._assertions); + } + + /** + * Retrieves the first property value for the given predicate. + */ + getProperty(predicate) { + if (predicate in this._assertions) + return this._assertions[predicate][0].getObject(); + return null; + } + + /** + * Sets the property value for the given predicate, clearing any existing + * values. + */ + setProperty(predicate, object) { + // TODO optimise by replacing the first assertion and clearing the rest + this.clearProperty(predicate); + this.assert(predicate, object); + } + + /** + * Clears any existing properties for the given predicate. + */ + clearProperty(predicate) { + if (!(predicate in this._assertions)) + return; + + var assertions = this._assertions[predicate]; + while (assertions.length > 0) { + var assertion = assertions[0]; + this._removeAssertion(assertion); + this._removeDOMNodeForAssertion(assertion); + } + } +} + +/** + * Creates a new RDFResource for the datasource. Private. + */ +class RDFResource extends RDFSubject { + constructor(ds, uri) { + if (!(ds instanceof RDFDataSource)) + throw new Error("datasource must be an RDFDataSource"); + + if (!uri) + throw new Error("An RDFResource requires a non-null uri"); + + super(ds); + // This is the uri that the resource represents. + this._uri = uri; + } + + /** + * Sets attributes on the DOM element to mark it as representing this resource + */ + _applyToElement(element) { + if (USE_RDFNS_ATTR) { + var prefix = this._ds._resolvePrefix(element, RDF_R("about")); + element.setAttributeNS(prefix.namespaceURI, prefix.qname, this._uri); + } else { + element.setAttribute("about", this._uri); + } + } + + /** + * Adds a reference to this resource to the given property Element. + */ + _addReferenceToElement(element) { + if (USE_RDFNS_ATTR) { + var prefix = this._ds._resolvePrefix(element, RDF_R("resource")); + element.setAttributeNS(prefix.namespaceURI, prefix.qname, this._uri); + } else { + element.setAttribute("resource", this._uri); + } + } + + /** + * Removes any reference to this resource from the given property Element. + */ + _removeReferenceFromElement(element) { + if (element.hasAttributeNS(NS_RDF, "resource")) + element.removeAttributeNS(NS_RDF, "resource"); + if (element.hasAttribute("resource")) + element.removeAttribute("resource"); + } + + getURI() { + return this._uri; + } +} + +/** + * Creates a new blank node. Private. + */ +class RDFBlankNode extends RDFSubject { + constructor(ds, nodeID) { + if (!(ds instanceof RDFDataSource)) + throw new Error("datasource must be an RDFDataSource"); + + super(ds); + // The nodeID of this node. May be null if there is no ID. + this._nodeID = nodeID; + } + + /** + * Sets attributes on the DOM element to mark it as representing this node + */ + _applyToElement(element) { + if (!this._nodeID) + return; + if (USE_RDFNS_ATTR) { + var prefix = this._ds._resolvePrefix(element, RDF_R("nodeID")); + element.setAttributeNS(prefix.namespaceURI, prefix.qname, this._nodeID); + } else { + element.setAttribute("nodeID", this._nodeID); + } + } + + /** + * Creates a new Element in the document for holding assertions about this + * subject. The URI controls what tagname to use. + */ + _createNewElement(uri) { + // If there are already nodes representing this in the document then we need + // a nodeID to match them + if (!this._nodeID && this._elements.length > 0) { + this._ds._createNodeID(this); + for (let element of this._elements) + this._applyToElement(element); + } + + return super._createNewElement.call(uri); + } + + /** + * Adds a reference to this node to the given property Element. + */ + _addReferenceToElement(element) { + if (this._elements.length > 0 && !this._nodeID) { + // In document elsewhere already + // Create a node ID and update the other nodes referencing + this._ds._createNodeID(this); + for (let element of this._elements) + this._applyToElement(element); + } + + if (this._nodeID) { + if (USE_RDFNS_ATTR) { + let prefix = this._ds._resolvePrefix(element, RDF_R("nodeID")); + element.setAttributeNS(prefix.namespaceURI, prefix.qname, this._nodeID); + } else { + element.setAttribute("nodeID", this._nodeID); + } + } else { + // Add the empty blank node, this is generally right since further + // assertions will be added to fill this out + var newelement = this._ds._addElement(element, RDF_R("Description")); + newelement.listCounter = 1; + this._elements.push(newelement); + } + } + + /** + * Removes any reference to this node from the given property Element. + */ + _removeReferenceFromElement(element) { + if (element.hasAttributeNS(NS_RDF, "nodeID")) + element.removeAttributeNS(NS_RDF, "nodeID"); + if (element.hasAttribute("nodeID")) + element.removeAttribute("nodeID"); + } + + getNodeID() { + return this._nodeID; + } +} + +/** + * Creates a new RDFDataSource from the given document. The document will be + * changed as assertions are added and removed to the RDF. Pass a null document + * to start with an empty graph. + */ +class RDFDataSource { + constructor(document) { + // All known resources, indexed on URI + this._resources = {}; + // All blank nodes + this._allBlankNodes = []; + // All blank nodes with IDs, indexed on ID + this._blankNodes = {}; + // Suggested prefixes to use for namespaces, index is prefix, value is namespaceURI. + this._prefixes = { + rdf: NS_RDF, + NC: NS_NC + }; + + if (!document) { + // Creating a document through xpcom leaves out the xml prolog so just parse + // something small + var parser = Cc["@mozilla.org/xmlextras/domparser;1"]. + createInstance(Ci.nsIDOMParser); + var doctext = `\n\n`; + document = parser.parseFromString(doctext, "text/xml"); + } + // The underlying DOM document for this datasource + this._document = document; + this._parseDocument(); + } + + static loadFromString(text) { + let parser = new DOMParser(); + let document = parser.parseFromString(text, "application/xml"); + + return new this(document); + } + + static loadFromBuffer(buffer) { + let parser = new DOMParser(); + let document = parser.parseFromBuffer(new Uint8Array(buffer), "application/xml"); + + return new this(document); + } + + static async loadFromFile(uri) { + if (uri instanceof Ci.nsIFile) + uri = Services.io.newFileURI(uri); + else if (typeof(uri) == "string") + uri = Services.io.newURI(uri); + + let resp = await fetch(uri.spec); + return this.loadFromBuffer(await resp.arrayBuffer()); + } + + get uri() { + return this._document.documentURI; + } + + /** + * Creates a new nodeID for an unnamed blank node. Just node. + */ + _createNodeID(blanknode) { + var i = 1; + while (`node${i}` in this._blankNodes) + i++; + blanknode._nodeID = `node${i}`; + this._blankNodes[blanknode._nodeID] = blanknode; + } + + /** + * Returns an rdf subject for the given DOM Element. If the subject has not + * been seen before a new one is created. + */ + _getSubjectForElement(element) { + if (element.namespaceURI == NS_RDF && + RDF_NODE_INVALID_TYPES.includes(element.localName)) + throw new Error(`${element.nodeName} is not a valid class for a subject node`); + + var about = getRDFAttribute(element, "about"); + var id = getRDFAttribute(element, "ID"); + var nodeID = getRDFAttribute(element, "nodeID"); + + if ((about && (id || nodeID)) || + (nodeID && (id || about))) { + ERROR("More than one of about, ID and nodeID present on the same subject"); + throw new Error("invalid subject in rdf"); + } + + if (about !== undefined) { + let base = Services.io.newURI(element.baseURI); + return this.getResource(base.resolve(about)); + } + if (id !== undefined) { + if (!id.match(XML_NCNAME)) + throw new Error("rdf:ID must be a valid XML name"); + let base = Services.io.newURI(element.baseURI); + return this.getResource(base.resolve(`#${id}`)); + } + if (nodeID !== undefined) + return this.getBlankNode(nodeID); + return this.getBlankNode(null); + } + + /** + * Parses the document for subjects at the top level. + */ + _parseDocument() { + if (!this._document.documentElement) { + ERROR("No document element in document"); + throw new Error("document contains no root element"); + } + + if (this._document.documentElement.namespaceURI != NS_RDF || + this._document.documentElement.localName != "RDF") { + ERROR(`${this._document.documentElement.nodeName} is not rdf:RDF`); + throw new Error("document does not appear to be RDF"); + } + + var domnode = this._document.documentElement.firstChild; + while (domnode) { + if (isText(domnode) && /\S/.test(domnode.nodeValue)) { + ERROR("RDF does not allow for text in the root of the document"); + throw new Error("invalid markup in document"); + } else if (isElement(domnode)) { + var subject = this._getSubjectForElement(domnode); + subject._parseElement(domnode); + } + domnode = domnode.nextSibling; + } + } + + /** + * Works out a sensible namespace prefix to use for the given uri. node should + * be the parent of where the element is to be inserted, or the node that an + * attribute is to be added to. This will recursively walk to the top of the + * document finding an already registered prefix that matches for the uri. + * If none is found a new prefix is registered. + * This returns an object with keys namespaceURI, prefix, localName and qname. + * Pass null or undefined for badPrefixes for the first call. + */ + _resolvePrefix(domnode, uri, badPrefixes) { + if (!badPrefixes) + badPrefixes = []; + + // No known prefix, try to create one from the lookup list + if (!domnode || isDocument(domnode)) { + for (let i in this._prefixes) { + if (badPrefixes.includes(i)) + continue; + if (this._prefixes[i] == uri.substring(0, this._prefixes[i].length)) { + var local = uri.substring(this._prefixes[i].length); + var test = URI_SUFFIX.exec(local); + // Remaining part of uri is a good XML Name + if (test && test[0] == local) { + this._document.documentElement.setAttributeNS(NS_XMLNS, `xmlns:${i}`, this._prefixes[i]); + return { + namespaceURI: this._prefixes[i], + prefix: i, + localName: local, + qname: i ? `${i}:${local}` : local + }; + } + } + } + + // No match, make something up + test = URI_SUFFIX.exec(uri); + if (test) { + var namespaceURI = uri.substring(0, uri.length - test[0].length); + local = test[0]; + let i = 1; + while (badPrefixes.includes(`NS${i}`)) + i++; + this._document.documentElement.setAttributeNS(NS_XMLNS, `xmlns:NS${i}`, namespaceURI); + return { + namespaceURI, + prefix: `NS${i}`, + localName: local, + qname: `NS${i}:${local}`, + }; + } + // There is no end part of this URI that is an XML Name + throw new Error(`invalid node name: ${uri}`); + } + + for (let attr of domnode.attributes) { + // Not a namespace declaration, ignore this attribute + if (attr.namespaceURI != NS_XMLNS && attr.nodeName != "xmlns") + continue; + + var prefix = attr.prefix ? attr.localName : ""; + // Seen this prefix before, cannot use it + if (badPrefixes.includes(prefix)) + continue; + + // Namespace matches the start of the uri + if (attr.value == uri.substring(0, attr.value.length)) { + local = uri.substring(attr.value.length); + test = URI_SUFFIX.exec(local); + // Remaining part of uri is a good XML Name + if (test && test[0] == local) { + return { + namespaceURI: attr.value, + prefix, + localName: local, + qname: prefix ? `${prefix}:${local}` : local + }; + } + } + + badPrefixes.push(prefix); + } + + // No prefix found here, move up the document + return this._resolvePrefix(domnode.parentNode, uri, badPrefixes); + } + + /** + * Guess the indent level within the given Element. The method looks for + * elements that are preceeded by whitespace including a newline. The + * whitespace following the newline is presumed to be the indentation for the + * element. + * If the indentation cannot be guessed then it recurses up the document + * hierarchy until it can guess the indent or until the Document is reached. + */ + _guessIndent(element) { + // The indent at document level is 0 + if (!element || isDocument(element)) + return ""; + + // Check the text immediately preceeding each child node. One could be + // a valid indent + var pretext = ""; + var child = element.firstChild; + while (child) { + if (isText(child)) { + pretext += child.nodeValue; + } else if (isElement(child)) { + var result = INDENT.exec(pretext); + if (result) + return result[1]; + pretext = ""; + } + child = child.nextSibling; + } + + // pretext now contains any trailing text in the element. This can be + // the indent of the end tag. If so add a little to it. + result = INDENT.exec(pretext); + if (result) + return `${result[1]} `; + + // Check the text immediately before this node + pretext = ""; + var sibling = element.previousSibling; + while (sibling && isText(sibling)) { + pretext += sibling.nodeValue; + sibling = sibling.previousSibling; + } + + // If there is a sensible indent then just add to it. + result = INDENT.exec(pretext); + if (result) + return `${result[1]} `; + + // Last chance, get the indent level for the tag above and add to it + return `${this._guessIndent(element.parentNode)} `; + } + + _addElement(parent, uri) { + var prefix = this._resolvePrefix(parent, uri); + var element = this._document.createElementNS(prefix.namespaceURI, prefix.qname); + + if (parent.lastChild) { + // We want to insert immediately after the last child element + var last = parent.lastChild; + while (last && isText(last)) + last = last.previousSibling; + // No child elements so insert at the start + if (!last) + last = parent.firstChild; + else + last = last.nextSibling; + + let indent = this._guessIndent(parent); + parent.insertBefore(this._document.createTextNode(`\n${indent}`), last); + parent.insertBefore(element, last); + } else { + // No children, must indent our element and the end tag + let indent = this._guessIndent(parent.parentNode); + parent.append(`\n${indent} `, element, `\n${indent}`); + } + return element; + } + + /** + * Removes the element from its parent. Should also remove surrounding + * white space as appropriate. + */ + _removeElement(element) { + var parent = element.parentNode; + var sibling = element.previousSibling; + // Drop any text nodes immediately preceeding the element + while (sibling && isText(sibling)) { + var temp = sibling; + sibling = sibling.previousSibling; + parent.removeChild(temp); + } + + sibling = element.nextSibling; + // Drop the element + parent.removeChild(element); + + // If the next node after element is now the first child then element was + // the first child. If there are no other child elements then remove the + // remaining child nodes. + if (parent.firstChild == sibling) { + while (sibling && isText(sibling)) + sibling = sibling.nextSibling; + if (!sibling) { + // No other child elements + while (parent.lastChild) + parent.removeChild(parent.lastChild); + } + } + } + + /** + * Requests that a given prefix be used for the namespace where possible. + * This must be called before any assertions are made using the namespace + * and the registration will not override any existing prefix used in the + * document. + */ + registerPrefix(prefix, namespaceURI) { + this._prefixes[prefix] = namespaceURI; + } + + /** + * Gets a blank node. nodeID may be null and if so a new blank node is created. + * If a nodeID is given then the blank node with that ID is returned or created. + */ + getBlankNode(nodeID) { + if (nodeID && nodeID in this._blankNodes) + return this._blankNodes[nodeID]; + + if (nodeID && !nodeID.match(XML_NCNAME)) + throw new Error("rdf:nodeID must be a valid XML name"); + + var rdfnode = new RDFBlankNode(this, nodeID); + this._allBlankNodes.push(rdfnode); + if (nodeID) + this._blankNodes[nodeID] = rdfnode; + return rdfnode; + } + + /** + * Gets all blank nodes + */ + getAllBlankNodes() { + return this._allBlankNodes.slice(); + } + + /** + * Gets the resource for the URI. The resource is created if it has not been + * used already. + */ + getResource(uri) { + if (uri in this._resources) + return this._resources[uri]; + + var resource = new RDFResource(this, uri); + this._resources[uri] = resource; + return resource; + } + + /** + * Gets all resources that have been used. + */ + getAllResources() { + return Object.values(this._resources); + } + + /** + * Returns all blank nodes and resources + */ + getAllSubjects() { + return [...Object.values(this._resources), + ...this._allBlankNodes]; + } + + /** + * Saves the RDF/XML to a string. + */ + serializeToString() { + var serializer = new XMLSerializer(); + return serializer.serializeToString(this._document); + } + + /** + * Saves the RDF/XML to a file. + */ + async saveToFile(file) { + return OS.File.writeAtomic(file, new TextEncoder().encode(this.serializeToString())); + } +} diff --git a/toolkit/mozapps/extensions/internal/moz.build b/toolkit/mozapps/extensions/internal/moz.build index 18c728197137..3d96f33d31f2 100644 --- a/toolkit/mozapps/extensions/internal/moz.build +++ b/toolkit/mozapps/extensions/internal/moz.build @@ -12,6 +12,7 @@ EXTRA_JS_MODULES.addons += [ 'GMPProvider.jsm', 'LightweightThemeImageOptimizer.jsm', 'ProductAddonChecker.jsm', + 'RDFDataSource.jsm', 'SpellCheckDictionaryBootstrap.js', 'UpdateRDFConverter.jsm', 'XPIDatabase.jsm', From 142b1154b078669d1a6da0123d1fddb19ee05551 Mon Sep 17 00:00:00 2001 From: Kris Maglione Date: Sat, 28 Apr 2018 19:20:38 -0700 Subject: [PATCH 02/34] Bug 1457749: Part 2 - Update UpdateRDFConverter to use RDFDataSource.jsm. r=Mossop MozReview-Commit-ID: HbJ3vBSBXH2 --HG-- extra : rebase_source : f9a52c5ea9384caa1ca119461e6b7913ee26f61d extra : histedit_source : b3f9432f6c60cda8c47eef3c83313f0b7d05a9be --- .../internal/UpdateRDFConverter.jsm | 221 ++++++++---------- 1 file changed, 102 insertions(+), 119 deletions(-) diff --git a/toolkit/mozapps/extensions/internal/UpdateRDFConverter.jsm b/toolkit/mozapps/extensions/internal/UpdateRDFConverter.jsm index af1af0decdbe..30396552765c 100644 --- a/toolkit/mozapps/extensions/internal/UpdateRDFConverter.jsm +++ b/toolkit/mozapps/extensions/internal/UpdateRDFConverter.jsm @@ -5,155 +5,138 @@ var EXPORTED_SYMBOLS = ["UpdateRDFConverter"]; -const PREFIX_NS_EM = "http://www.mozilla.org/2004/em-rdf#"; +ChromeUtils.defineModuleGetter(this, "RDFDataSource", + "resource://gre/modules/addons/RDFDataSource.jsm"); +ChromeUtils.defineModuleGetter(this, "Services", + "resource://gre/modules/Services.jsm"); + const PREFIX_ITEM = "urn:mozilla:item:"; const PREFIX_EXTENSION = "urn:mozilla:extension:"; const PREFIX_THEME = "urn:mozilla:theme:"; const TOOLKIT_ID = "toolkit@mozilla.org"; -ChromeUtils.import("resource://gre/modules/Services.jsm"); -ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); +function EM_R(aProperty) { + return `http://www.mozilla.org/2004/em-rdf#${aProperty}`; +} -XPCOMUtils.defineLazyServiceGetters(this, { - gRDF: ["@mozilla.org/rdf/rdf-service;1", "nsIRDFService"], - containerUtils: ["@mozilla.org/rdf/container-utils;1", "nsIRDFContainerUtils"], -}); +function getValue(literal) { + return literal && literal.getValue(); +} -const RDFContainer = Components.Constructor( - "@mozilla.org/rdf/container;1", "nsIRDFContainer", "Init"); -const RDFDataSource = Components.Constructor( - "@mozilla.org/rdf/datasource;1?name=in-memory-datasource", "nsIRDFDataSource"); -const RDFParser = Components.Constructor( - "@mozilla.org/rdf/xml-parser;1", "nsIRDFXMLParser"); +function getProperty(resource, property) { + return getValue(resource.getProperty(EM_R(property))); +} -/** - * Parses an RDF style update manifest into a JSON-style update - * manifest. - * - * @param {XMLHttpRequest> aRequest - * The XMLHttpRequest that has retrieved the update manifest - * @returns {object} a JSON update manifest. - */ -function parseRDFManifest(aRequest) { - function EM_R(aProp) { - return gRDF.GetResource(PREFIX_NS_EM + aProp); +function getBoolProperty(resource, property) { + return getValue(resource.getProperty(EM_R(property))) == "true"; +} + +class Manifest { + constructor(ds) { + this.ds = ds; } - function getValue(aLiteral) { - if (aLiteral instanceof Ci.nsIRDFLiteral) - return aLiteral.Value; - if (aLiteral instanceof Ci.nsIRDFResource) - return aLiteral.Value; - if (aLiteral instanceof Ci.nsIRDFInt) - return aLiteral.Value; - return null; + static loadFromString(text) { + return new this(RDFDataSource.loadFromString(text)); } - function getProperty(aDs, aSource, aProperty) { - return getValue(aDs.GetTarget(aSource, EM_R(aProperty), true)); + static loadFromBuffer(buffer) { + return new this(RDFDataSource.loadFromBuffer(buffer)); } - function getBooleanProperty(aDs, aSource, aProperty) { - let propValue = aDs.GetTarget(aSource, EM_R(aProperty), true); - if (!propValue) - return undefined; - return getValue(propValue) == "true"; + static async loadFromFile(uri) { + return new this(await RDFDataSource.loadFromFile(uri)); } +} - let rdfParser = new RDFParser(); - let ds = new RDFDataSource(); - rdfParser.parseString(ds, aRequest.channel.URI, aRequest.responseText); +class UpdateRDF extends Manifest { + decode() { + let addons = {}; + let result = {addons}; - let addons = {}; - let result = {addons}; - - for (let addonRes of XPCOMUtils.IterSimpleEnumerator(ds.GetAllResources(), Ci.nsIRDFResource)) { - let value = addonRes.ValueUTF8; - let id; - for (let prefix of [PREFIX_EXTENSION, PREFIX_THEME, PREFIX_ITEM]) { - if (value.startsWith(prefix)) { - id = value.substr(prefix.length); - break; - } - } - if (!id) { - continue; - } - - let addon = {}; - addons[id] = addon; - - let updatesTarget = ds.GetTarget(addonRes, EM_R("updates"), true); - if (!(updatesTarget instanceof Ci.nsIRDFResource) || - !containerUtils.IsContainer(ds, updatesTarget)) { - continue; - } - - let updates = []; - addon.updates = updates; - - let ctr = new RDFContainer(ds, updatesTarget); - for (let item of XPCOMUtils.IterSimpleEnumerator(ctr.GetElements(), - Ci.nsIRDFResource)) { - let version = getProperty(ds, item, "version"); - - let targetApps = ds.GetTargets(item, EM_R("targetApplication"), true); - for (let targetApp of XPCOMUtils.IterSimpleEnumerator(targetApps, - Ci.nsIRDFResource)) { - let appEntry = {}; - - let minVersion = getProperty(ds, targetApp, "minVersion"); - if (minVersion) { - appEntry.strict_min_version = minVersion; + for (let resource of this.ds.getAllResources()) { + let id; + let uri = resource.getURI(); + for (let prefix of [PREFIX_EXTENSION, PREFIX_THEME, PREFIX_ITEM]) { + if (uri.startsWith(prefix)) { + id = uri.substr(prefix.length); + break; } + } + if (!id) { + continue; + } - let maxVersion = getProperty(ds, targetApp, "maxVersion"); - if (maxVersion) { - if (getBooleanProperty(ds, targetApp, "strictCompatibility")) { - appEntry.strict_max_version = maxVersion; - } else { - appEntry.advisory_max_version = maxVersion; + let addon = {}; + addons[id] = addon; + + let updatesProp = resource.getProperty(EM_R("updates")); + if (!updatesProp || !updatesProp.getChildren) { + continue; + } + + let updates = []; + addon.updates = updates; + + for (let item of updatesProp.getChildren()) { + let version = getProperty(item, "version"); + + for (let targetApp of item.getObjects(EM_R("targetApplication"))) { + let appEntry = {}; + + let minVersion = getProperty(targetApp, "minVersion"); + if (minVersion) { + appEntry.strict_min_version = minVersion; } - } - let appId = getProperty(ds, targetApp, "id"); - if (!appId) { - continue; - } - if (appId === TOOLKIT_ID || appId === Services.appinfo.ID) { - appId = "gecko"; - } + let maxVersion = getProperty(targetApp, "maxVersion"); + if (maxVersion) { + if (getBoolProperty(targetApp, "strictCompatibility")) { + appEntry.strict_max_version = maxVersion; + } else { + appEntry.advisory_max_version = maxVersion; + } + } - let update = { - applications: {[appId]: appEntry}, - }; - if (version) { - update.version = version; - } - let updateLink = getProperty(ds, targetApp, "updateLink"); - if (updateLink) { - update.update_link = updateLink; - } - let updateInfoURL = getProperty(ds, targetApp, "updateInfoURL"); - if (updateInfoURL) { - update.update_info_url = updateInfoURL; - } - let updateHash = getProperty(ds, targetApp, "updateHash"); - if (updateHash) { - update.update_hash = updateHash; - } + let appId = getProperty(targetApp, "id"); + if (!appId) { + continue; + } + if (appId === TOOLKIT_ID || appId === Services.appinfo.ID) { + appId = "gecko"; + } - updates.push(update); + let update = { + applications: {[appId]: appEntry}, + }; + if (version) { + update.version = version; + } + let updateLink = getProperty(targetApp, "updateLink"); + if (updateLink) { + update.update_link = updateLink; + } + let updateInfoURL = getProperty(targetApp, "updateInfoURL"); + if (updateInfoURL) { + update.update_info_url = updateInfoURL; + } + let updateHash = getProperty(targetApp, "updateHash"); + if (updateHash) { + update.update_hash = updateHash; + } + + updates.push(update); + } } } - } - return result; + return result; + } } var UpdateRDFConverter = { convertToJSON(request) { - return parseRDFManifest(request); + return UpdateRDF.loadFromString(request.responseText).decode(); }, }; From b826ec73b96b3835252c909973b846387a57a08e Mon Sep 17 00:00:00 2001 From: Kris Maglione Date: Sat, 28 Apr 2018 19:27:33 -0700 Subject: [PATCH 03/34] Bug 1457749: Part 3 - Migrate install.rdf parser to use RDFDataSource.jsm. r=Mossop This is based on a script I'd already created to migrate test extensions to the JSON format we use to generate fixture add-ons. The delay update add-ons used invalid XML in their manifests, which the built-in parser ignored but the new parser doesn't accept, so I had to fix those, too. MozReview-Commit-ID: BnuxZiBhhJL --HG-- rename : toolkit/mozapps/extensions/internal/UpdateRDFConverter.jsm => toolkit/mozapps/extensions/internal/RDFManifestConverter.jsm extra : rebase_source : 0ed84e6d80a2b64c9c8c90823a239b6ecd3b4342 extra : histedit_source : 22aefc7eaf2663ebe65c1ab35cfbe48f93718a69 --- .../extensions/internal/AddonTestUtils.jsm | 22 +-- .../internal/AddonUpdateChecker.jsm | 2 +- ...Converter.jsm => RDFManifestConverter.jsm} | 76 ++++++++- .../extensions/internal/XPIInstall.jsm | 150 ++++-------------- toolkit/mozapps/extensions/internal/moz.build | 2 +- .../test_delay_update_complete_v2/install.rdf | 1 + .../test_delay_update_defer_v2/install.rdf | 1 + .../test/xpcshell/test_update_rdf.js | 3 +- 8 files changed, 116 insertions(+), 141 deletions(-) rename toolkit/mozapps/extensions/internal/{UpdateRDFConverter.jsm => RDFManifestConverter.jsm} (61%) diff --git a/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm b/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm index bb418f390c42..3d31b9771533 100644 --- a/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm +++ b/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm @@ -34,13 +34,14 @@ ChromeUtils.defineModuleGetter(this, "FileTestUtils", "resource://testing-common/FileTestUtils.jsm"); ChromeUtils.defineModuleGetter(this, "HttpServer", "resource://testing-common/httpd.js"); +ChromeUtils.defineModuleGetter(this, "InstallRDF", + "resource://gre/modules/addons/RDFManifestConverter.jsm"); ChromeUtils.defineModuleGetter(this, "MockRegistrar", "resource://testing-common/MockRegistrar.jsm"); XPCOMUtils.defineLazyServiceGetters(this, { aomStartup: ["@mozilla.org/addons/addon-manager-startup;1", "amIAddonManagerStartup"], proxyService: ["@mozilla.org/network/protocol-proxy-service;1", "nsIProtocolProxyService"], - rdfService: ["@mozilla.org/rdf/rdf-service;1", "nsIRDFService"], uuidGen: ["@mozilla.org/uuid-generator;1", "nsIUUIDGenerator"], }); @@ -61,14 +62,6 @@ const nsFile = Components.Constructor( "@mozilla.org/file/local;1", "nsIFile", "initWithPath"); -const RDFXMLParser = Components.Constructor( - "@mozilla.org/rdf/xml-parser;1", - "nsIRDFXMLParser", "parseString"); - -const RDFDataSource = Components.Constructor( - "@mozilla.org/rdf/datasource;1?name=in-memory-datasource", - "nsIRDFDataSource"); - const ZipReader = Components.Constructor( "@mozilla.org/libjar/zip-reader;1", "nsIZipReader", "open"); @@ -613,15 +606,8 @@ var AddonTestUtils = { let body = await fetch(manifestURI.spec); if (manifestURI.spec.endsWith(".rdf")) { - let data = await body.text(); - - let ds = new RDFDataSource(); - new RDFXMLParser(ds, manifestURI, data); - - let rdfID = ds.GetTarget(rdfService.GetResource("urn:mozilla:install-manifest"), - rdfService.GetResource("http://www.mozilla.org/2004/em-rdf#id"), - true); - return rdfID.QueryInterface(Ci.nsIRDFLiteral).Value; + let manifest = InstallRDF.loadFromBuffer(await body.arrayBuffer()).decode(); + return manifest.id; } let manifest = await body.json(); diff --git a/toolkit/mozapps/extensions/internal/AddonUpdateChecker.jsm b/toolkit/mozapps/extensions/internal/AddonUpdateChecker.jsm index a3ccb42e40ad..62fe10142778 100644 --- a/toolkit/mozapps/extensions/internal/AddonUpdateChecker.jsm +++ b/toolkit/mozapps/extensions/internal/AddonUpdateChecker.jsm @@ -32,7 +32,7 @@ ChromeUtils.defineModuleGetter(this, "CertUtils", ChromeUtils.defineModuleGetter(this, "ServiceRequest", "resource://gre/modules/ServiceRequest.jsm"); ChromeUtils.defineModuleGetter(this, "UpdateRDFConverter", - "resource://gre/modules/addons/UpdateRDFConverter.jsm"); + "resource://gre/modules/addons/RDFManifestConverter.jsm"); ChromeUtils.import("resource://gre/modules/Log.jsm"); const LOGGER_ID = "addons.update-checker"; diff --git a/toolkit/mozapps/extensions/internal/UpdateRDFConverter.jsm b/toolkit/mozapps/extensions/internal/RDFManifestConverter.jsm similarity index 61% rename from toolkit/mozapps/extensions/internal/UpdateRDFConverter.jsm rename to toolkit/mozapps/extensions/internal/RDFManifestConverter.jsm index 30396552765c..9430299f920a 100644 --- a/toolkit/mozapps/extensions/internal/UpdateRDFConverter.jsm +++ b/toolkit/mozapps/extensions/internal/RDFManifestConverter.jsm @@ -1,9 +1,9 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public + /* 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/. */ "use strict"; -var EXPORTED_SYMBOLS = ["UpdateRDFConverter"]; +var EXPORTED_SYMBOLS = ["InstallRDF", "UpdateRDFConverter"]; ChromeUtils.defineModuleGetter(this, "RDFDataSource", "resource://gre/modules/addons/RDFDataSource.jsm"); @@ -16,6 +16,8 @@ const PREFIX_THEME = "urn:mozilla:theme:"; const TOOLKIT_ID = "toolkit@mozilla.org"; +const RDFURI_INSTALL_MANIFEST_ROOT = "urn:mozilla:install-manifest"; + function EM_R(aProperty) { return `http://www.mozilla.org/2004/em-rdf#${aProperty}`; } @@ -50,6 +52,76 @@ class Manifest { } } +class InstallRDF extends Manifest { + _readProps(source, obj, props) { + for (let prop of props) { + let val = getProperty(source, prop); + if (val != null) { + obj[prop] = val; + } + } + } + + _readArrayProp(source, obj, prop, target, decode = getValue) { + let result = Array.from(source.getObjects(EM_R(prop)), + target => decode(target)); + if (result.length) { + obj[target] = result; + } + } + + _readArrayProps(source, obj, props, decode = getValue) { + for (let [prop, target] of Object.entries(props)) { + this._readArrayProp(source, obj, prop, target, decode); + } + } + + _readLocaleStrings(source, obj) { + this._readProps(source, obj, ["name", "description", "creator", "homepageURL"]); + this._readArrayProps(source, obj, { + locale: "locales", + developer: "developers", + translator: "translators", + contributor: "contributors", + }); + } + + decode() { + let root = this.ds.getResource(RDFURI_INSTALL_MANIFEST_ROOT); + let result = {}; + + let props = ["id", "version", "type", "updateURL", "optionsURL", + "optionsType", "aboutURL", "iconURL", "icon64URL", + "bootstrap", "unpack", "strictCompatibility", + "hasEmbeddedWebExtension"]; + this._readProps(root, result, props); + + let decodeTargetApplication = source => { + let app = {}; + this._readProps(source, app, ["id", "minVersion", "maxVersion"]); + return app; + }; + + let decodeLocale = source => { + let localized = {}; + this._readLocaleStrings(source, localized); + return localized; + }; + + this._readLocaleStrings(root, result); + + this._readArrayProps(root, result, {"targetPlatform": "targetPlatforms"}); + this._readArrayProps(root, result, {"targetApplication": "targetApplications"}, + decodeTargetApplication); + this._readArrayProps(root, result, {"localized": "localized"}, + decodeLocale); + this._readArrayProps(root, result, {"dependency": "dependencies"}, + source => getProperty(source, "id")); + + return result; + } +} + class UpdateRDF extends Manifest { decode() { let addons = {}; diff --git a/toolkit/mozapps/extensions/internal/XPIInstall.jsm b/toolkit/mozapps/extensions/internal/XPIInstall.jsm index 0f931be618fe..7bab287c55d0 100644 --- a/toolkit/mozapps/extensions/internal/XPIInstall.jsm +++ b/toolkit/mozapps/extensions/internal/XPIInstall.jsm @@ -45,6 +45,7 @@ XPCOMUtils.defineLazyModuleGetters(this, { ZipUtils: "resource://gre/modules/ZipUtils.jsm", AddonInternal: "resource://gre/modules/addons/XPIDatabase.jsm", + InstallRDF: "resource://gre/modules/addons/RDFManifestConverter.jsm", XPIDatabase: "resource://gre/modules/addons/XPIDatabase.jsm", XPIInternal: "resource://gre/modules/addons/XPIProvider.jsm", XPIProvider: "resource://gre/modules/addons/XPIProvider.jsm", @@ -68,16 +69,11 @@ const FileOutputStream = Components.Constructor("@mozilla.org/network/file-outpu const ZipReader = Components.Constructor("@mozilla.org/libjar/zip-reader;1", "nsIZipReader", "open"); -const RDFDataSource = Components.Constructor( - "@mozilla.org/rdf/datasource;1?name=in-memory-datasource", "nsIRDFDataSource"); -const parseRDFString = Components.Constructor( - "@mozilla.org/rdf/xml-parser;1", "nsIRDFXMLParser", "parseString"); - XPCOMUtils.defineLazyServiceGetters(this, { gCertDB: ["@mozilla.org/security/x509certdb;1", "nsIX509CertDB"], - gRDF: ["@mozilla.org/rdf/rdf-service;1", "nsIRDFService"], }); +const hasOwnProperty = Function.call.bind(Object.prototype.hasOwnProperty); const PREF_ALLOW_NON_RESTARTLESS = "extensions.legacy.non-restartless.enabled"; const PREF_DISTRO_ADDONS_PERMS = "extensions.distroAddons.promptForPermissions"; @@ -165,16 +161,12 @@ const KEY_APP_PROFILE = "app-profile"; const DIR_STAGE = "staged"; const DIR_TRASH = "trash"; -const RDFURI_INSTALL_MANIFEST_ROOT = "urn:mozilla:install-manifest"; -const PREFIX_NS_EM = "http://www.mozilla.org/2004/em-rdf#"; - // Properties that exist in the install manifest const PROP_METADATA = ["id", "version", "type", "internalName", "updateURL", "optionsURL", "optionsType", "aboutURL", "iconURL", "icon64URL"]; const PROP_LOCALE_SINGLE = ["name", "description", "creator", "homepageURL"]; const PROP_LOCALE_MULTI = ["developers", "translators", "contributors"]; -const PROP_TARGETAPP = ["id", "minVersion", "maxVersion"]; // Map new string type identifiers to old style nsIUpdateItem types. // Retired values: @@ -448,44 +440,6 @@ function waitForAllPromises(promises) { }); } -function EM_R(aProperty) { - return gRDF.GetResource(PREFIX_NS_EM + aProperty); -} - -/** - * Converts an RDF literal, resource or integer into a string. - * - * @param {nsISupports} aLiteral - * The RDF object to convert - * @returns {string?} - * A string if the object could be converted or null - */ -function getRDFValue(aLiteral) { - if (aLiteral instanceof Ci.nsIRDFLiteral) - return aLiteral.Value; - if (aLiteral instanceof Ci.nsIRDFResource) - return aLiteral.Value; - if (aLiteral instanceof Ci.nsIRDFInt) - return aLiteral.Value; - return null; -} - -/** - * Gets an RDF property as a string - * - * @param {nsIRDFDataSource} aDs - * The RDF datasource to read the property from - * @param {nsIRDFResource} aResource - * The RDF resource to read the property from - * @param {string} aProperty - * The property to read - * @returns {string?} - * A string if the property existed or null - */ -function getRDFProperty(aDs, aResource, aProperty) { - return getRDFValue(aDs.GetTarget(aResource, EM_R(aProperty), true)); -} - /** * Reads an AddonInternal object from a manifest stream. * @@ -628,23 +582,12 @@ async function loadManifestFromWebManifest(aUri) { * be read */ async function loadManifestFromRDF(aUri, aData) { - function getPropertyArray(aDs, aSource, aProperty) { - let values = []; - let targets = aDs.GetTargets(aSource, EM_R(aProperty), true); - while (targets.hasMoreElements()) - values.push(getRDFValue(targets.getNext())); - - return values; - } - /** * Reads locale properties from either the main install manifest root or * an em:localized section in the install manifest. * - * @param {nsIRDFDataSource} aDs - * The datasource to read from. - * @param {nsIRDFResource} aSource - * The resource to read the properties from. + * @param {Object} aSource + * The resource to read the properties from. * @param {boolean} isDefault * True if the locale is to be read from the main install manifest * root @@ -655,13 +598,11 @@ async function loadManifestFromRDF(aUri, aData) { * @returns {Object} * an object containing the locale properties */ - function readLocale(aDs, aSource, isDefault, aSeenLocales) { - let locale = { }; + function readLocale(aSource, isDefault, aSeenLocales) { + let locale = {}; if (!isDefault) { locale.locales = []; - let targets = ds.GetTargets(aSource, EM_R("locale"), true); - while (targets.hasMoreElements()) { - let localeName = getRDFValue(targets.getNext()); + for (let localeName of aSource.locales || []) { if (!localeName) { logger.warn("Ignoring empty locale in localized properties"); continue; @@ -680,32 +621,26 @@ async function loadManifestFromRDF(aUri, aData) { } } - for (let prop of PROP_LOCALE_SINGLE) { - locale[prop] = getRDFProperty(aDs, aSource, prop); - } - - for (let prop of PROP_LOCALE_MULTI) { - // Don't store empty arrays - let props = getPropertyArray(aDs, aSource, - prop.substring(0, prop.length - 1)); - if (props.length > 0) - locale[prop] = props; + for (let prop of [...PROP_LOCALE_SINGLE, ...PROP_LOCALE_MULTI]) { + if (hasOwnProperty(aSource, prop)) { + locale[prop] = aSource[prop]; + } } return locale; } - let ds = new RDFDataSource(); - parseRDFString(ds, aUri, aData); + let manifest = InstallRDF.loadFromString(aData).decode(); - let root = gRDF.GetResource(RDFURI_INSTALL_MANIFEST_ROOT); let addon = new AddonInternal(); for (let prop of PROP_METADATA) { - addon[prop] = getRDFProperty(ds, root, prop); + if (hasOwnProperty(manifest, prop)) { + addon[prop] = manifest[prop]; + } } if (!addon.type) { - addon.type = addon.internalName ? "theme" : "extension"; + addon.type = "extension"; } else { let type = addon.type; addon.type = null; @@ -727,16 +662,16 @@ async function loadManifestFromRDF(aUri, aData) { if (!addon.version) throw new Error("No version in install manifest"); - addon.strictCompatibility = !(addon.type in COMPATIBLE_BY_DEFAULT_TYPES) || - getRDFProperty(ds, root, "strictCompatibility") == "true"; + addon.strictCompatibility = (!(addon.type in COMPATIBLE_BY_DEFAULT_TYPES) || + manifest.strictCompatibility == "true"); // Only read these properties for extensions. if (addon.type == "extension") { - addon.bootstrap = getRDFProperty(ds, root, "bootstrap") == "true"; + addon.bootstrap = manifest.bootstrap == "true"; if (!addon.bootstrap && !Services.prefs.getBoolPref(PREF_ALLOW_NON_RESTARTLESS, false)) throw new Error(`Non-restartless extensions no longer supported`); - addon.hasEmbeddedWebExtension = getRDFProperty(ds, root, "hasEmbeddedWebExtension") == "true"; + addon.hasEmbeddedWebExtension = manifest.hasEmbeddedWebExtension == "true"; if (addon.optionsType && addon.optionsType != AddonManager.OPTIONS_INLINE_BROWSER && @@ -768,63 +703,42 @@ async function loadManifestFromRDF(aUri, aData) { addon.optionsBrowserStyle = null; addon.optionsType = null; addon.optionsURL = null; - - if (addon.type == "theme") { - if (!addon.internalName) - throw new Error("Themes must include an internalName property"); - addon.skinnable = getRDFProperty(ds, root, "skinnable") == "true"; - } } - addon.defaultLocale = readLocale(ds, root, true); + addon.defaultLocale = readLocale(manifest, true); let seenLocales = []; addon.locales = []; - let targets = ds.GetTargets(root, EM_R("localized"), true); - while (targets.hasMoreElements()) { - let target = targets.getNext().QueryInterface(Ci.nsIRDFResource); - let locale = readLocale(ds, target, false, seenLocales); + for (let localeData of manifest.localized || []) { + let locale = readLocale(localeData, false, seenLocales); if (locale) addon.locales.push(locale); } - let dependencies = new Set(); - targets = ds.GetTargets(root, EM_R("dependency"), true); - while (targets.hasMoreElements()) { - let target = targets.getNext().QueryInterface(Ci.nsIRDFResource); - let id = getRDFProperty(ds, target, "id"); - dependencies.add(id); - } + let dependencies = new Set(manifest.dependencies); addon.dependencies = Object.freeze(Array.from(dependencies)); let seenApplications = []; addon.targetApplications = []; - targets = ds.GetTargets(root, EM_R("targetApplication"), true); - while (targets.hasMoreElements()) { - let target = targets.getNext().QueryInterface(Ci.nsIRDFResource); - let targetAppInfo = {}; - for (let prop of PROP_TARGETAPP) { - targetAppInfo[prop] = getRDFProperty(ds, target, prop); - } - if (!targetAppInfo.id || !targetAppInfo.minVersion || - !targetAppInfo.maxVersion) { + for (let targetApp of manifest.targetApplications || []) { + if (!targetApp.id || !targetApp.minVersion || + !targetApp.maxVersion) { logger.warn("Ignoring invalid targetApplication entry in install manifest"); continue; } - if (seenApplications.includes(targetAppInfo.id)) { - logger.warn("Ignoring duplicate targetApplication entry for " + targetAppInfo.id + + if (seenApplications.includes(targetApp.id)) { + logger.warn("Ignoring duplicate targetApplication entry for " + targetApp.id + " in install manifest"); continue; } - seenApplications.push(targetAppInfo.id); - addon.targetApplications.push(targetAppInfo); + seenApplications.push(targetApp.id); + addon.targetApplications.push(targetApp); } // Note that we don't need to check for duplicate targetPlatform entries since // the RDF service coalesces them for us. - let targetPlatforms = getPropertyArray(ds, root, "targetPlatform"); addon.targetPlatforms = []; - for (let targetPlatform of targetPlatforms) { + for (let targetPlatform of manifest.targetPlatforms || []) { let platform = { os: null, abi: null diff --git a/toolkit/mozapps/extensions/internal/moz.build b/toolkit/mozapps/extensions/internal/moz.build index 3d96f33d31f2..5068dfc1f1c4 100644 --- a/toolkit/mozapps/extensions/internal/moz.build +++ b/toolkit/mozapps/extensions/internal/moz.build @@ -13,8 +13,8 @@ EXTRA_JS_MODULES.addons += [ 'LightweightThemeImageOptimizer.jsm', 'ProductAddonChecker.jsm', 'RDFDataSource.jsm', + 'RDFManifestConverter.jsm', 'SpellCheckDictionaryBootstrap.js', - 'UpdateRDFConverter.jsm', 'XPIDatabase.jsm', 'XPIInstall.jsm', 'XPIProvider.jsm', diff --git a/toolkit/mozapps/extensions/test/addons/test_delay_update_complete_v2/install.rdf b/toolkit/mozapps/extensions/test/addons/test_delay_update_complete_v2/install.rdf index 3ebbe16b07a0..b3d9719f78f1 100644 --- a/toolkit/mozapps/extensions/test/addons/test_delay_update_complete_v2/install.rdf +++ b/toolkit/mozapps/extensions/test/addons/test_delay_update_complete_v2/install.rdf @@ -25,3 +25,4 @@ + diff --git a/toolkit/mozapps/extensions/test/addons/test_delay_update_defer_v2/install.rdf b/toolkit/mozapps/extensions/test/addons/test_delay_update_defer_v2/install.rdf index 75c7666bbaf7..aec47ebc5631 100644 --- a/toolkit/mozapps/extensions/test/addons/test_delay_update_defer_v2/install.rdf +++ b/toolkit/mozapps/extensions/test/addons/test_delay_update_defer_v2/install.rdf @@ -25,3 +25,4 @@ + diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_update_rdf.js b/toolkit/mozapps/extensions/test/xpcshell/test_update_rdf.js index 99c75f516289..21fd37defa8e 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_update_rdf.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_update_rdf.js @@ -3,7 +3,8 @@ // Tests the update RDF to JSON converter. ChromeUtils.import("resource://gre/modules/addons/AddonUpdateChecker.jsm"); -ChromeUtils.import("resource://gre/modules/addons/UpdateRDFConverter.jsm"); +ChromeUtils.defineModuleGetter(this, "UpdateRDFConverter", + "resource://gre/modules/addons/RDFManifestConverter.jsm"); var testserver = AddonTestUtils.createHttpServer({hosts: ["example.com"]}); From 4d240e91377816239bb4dc05b631488a819fcd77 Mon Sep 17 00:00:00 2001 From: Kris Maglione Date: Sat, 28 Apr 2018 21:28:03 -0700 Subject: [PATCH 04/34] Bug 833098: Part 1 - Remove dead code in xpfe directory viewer. r=Mossop Most of this module is dead code, intended to convert directory listings into RDF data sources for a XUL front-end which no longer exists. Rather than keep the remaining code which still has any effect, I opted to just replace it with a JS stub, which winds up being much simpler. MozReview-Commit-ID: CiBpV0mrOo0 --HG-- extra : rebase_source : 9958bce108ad98a9e3cc1eaae1a0094e71132464 extra : histedit_source : daa889b1d69dcab4518b89d26cfb5ef74824263f --- modules/libpref/init/all.js | 6 - toolkit/components/utils/simpleServices.js | 35 +- toolkit/components/utils/utils.manifest | 4 + toolkit/toolkit.mozbuild | 1 - xpfe/components/build/moz.build | 18 - xpfe/components/build/nsModule.cpp | 44 - xpfe/components/directory/moz.build | 23 - .../directory/nsDirectoryViewer.cpp | 1376 ----------------- xpfe/components/directory/nsDirectoryViewer.h | 126 -- xpfe/components/directory/nsIHTTPIndex.idl | 50 - xpfe/components/moz.build | 14 - 11 files changed, 38 insertions(+), 1659 deletions(-) delete mode 100644 xpfe/components/build/moz.build delete mode 100644 xpfe/components/build/nsModule.cpp delete mode 100644 xpfe/components/directory/moz.build delete mode 100644 xpfe/components/directory/nsDirectoryViewer.cpp delete mode 100644 xpfe/components/directory/nsDirectoryViewer.h delete mode 100644 xpfe/components/directory/nsIHTTPIndex.idl delete mode 100644 xpfe/components/moz.build diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 9046b1c25df2..906945185ae9 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -2020,12 +2020,6 @@ pref("network.standard-url.punycode-host", true); // Idle timeout for ftp control connections - 5 minute default pref("network.ftp.idleConnectionTimeout", 300); -// directory listing format -// 2: HTML -// 3: XUL directory viewer -// all other values are treated like 2 -pref("network.dir.format", 2); - // enables the prefetch service (i.e., prefetching of and // URLs). pref("network.prefetch-next", true); diff --git a/toolkit/components/utils/simpleServices.js b/toolkit/components/utils/simpleServices.js index 90cee5272ee1..75bb9a02508e 100644 --- a/toolkit/components/utils/simpleServices.js +++ b/toolkit/components/utils/simpleServices.js @@ -21,6 +21,11 @@ ChromeUtils.defineModuleGetter(this, "NetUtil", ChromeUtils.defineModuleGetter(this, "Services", "resource://gre/modules/Services.jsm"); +XPCOMUtils.defineLazyServiceGetter(this, "catMan", "@mozilla.org/categorymanager;1", + "nsICategoryManager"); +XPCOMUtils.defineLazyServiceGetter(this, "streamConv", "@mozilla.org/streamConverters;1", + "nsIStreamConverterService"); + /* * This class provides a stream filter for locale messages in CSS files served * by the moz-extension: protocol handler. @@ -111,4 +116,32 @@ AddonLocalizationConverter.prototype = { }, }; -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([AddonLocalizationConverter]); +function HttpIndexViewer() { +} + +HttpIndexViewer.prototype = { + classID: Components.ID("{742ad274-34c5-43d1-a8b7-293eaf8962d6}"), + QueryInterface: ChromeUtils.generateQI([Ci.nsIDocumentLoaderFactory]), + + createInstance(aCommand, aChannel, aLoadGroup, aContentType, aContainer, + aExtraInfo, aDocListenerResult) { + aChannel.contentType = "text/html"; + + let contract = catMan.getCategoryEntry("Gecko-Content-Viewers", "text/html"); + let factory = Cc[contract].getService(Ci.nsIDocumentLoaderFactory); + + let listener = {}; + let res = factory.createInstance("view", aChannel, aLoadGroup, + "text/html", aContainer, aExtraInfo, + listener); + + aDocListenerResult.value = + streamConv.asyncConvertData("application/http-index-format", + "text/html", listener.value, null); + + return res; + }, +}; + +this.NSGetFactory = XPCOMUtils.generateNSGetFactory([AddonLocalizationConverter, + HttpIndexViewer]); diff --git a/toolkit/components/utils/utils.manifest b/toolkit/components/utils/utils.manifest index cd45ff07d8a6..fa266f7322d2 100644 --- a/toolkit/components/utils/utils.manifest +++ b/toolkit/components/utils/utils.manifest @@ -2,3 +2,7 @@ component {dfd07380-6083-11e4-9803-0800200c9a66} simpleServices.js contract @mozilla.org/addons/remote-tag-service;1 {dfd07380-6083-11e4-9803-0800200c9a66} component {ded150e3-c92e-4077-a396-0dba9953e39f} simpleServices.js contract @mozilla.org/streamconv;1?from=application/vnd.mozilla.webext.unlocalized&to=text/css {ded150e3-c92e-4077-a396-0dba9953e39f} + +component {742ad274-34c5-43d1-a8b7-293eaf8962d6} simpleServices.js +contract @mozilla.org/content-viewsers/http-index-format {742ad274-34c5-43d1-a8b7-293eaf8962d6} +category Gecko-Content-Viewers application/http-index-format @mozilla.org/content-viewsers/http-index-format diff --git a/toolkit/toolkit.mozbuild b/toolkit/toolkit.mozbuild index 8162a0d81a25..873a91f0f8aa 100644 --- a/toolkit/toolkit.mozbuild +++ b/toolkit/toolkit.mozbuild @@ -135,7 +135,6 @@ DIRS += [ '/tools/code-coverage', '/tools/power', '/tools/profiler', - '/xpfe/components', ] if CONFIG['MOZ_ENABLE_XREMOTE']: diff --git a/xpfe/components/build/moz.build b/xpfe/components/build/moz.build deleted file mode 100644 index c8f67f9e7884..000000000000 --- a/xpfe/components/build/moz.build +++ /dev/null @@ -1,18 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -with Files("**"): - BUG_COMPONENT = ("Core", "Window Management") - -SOURCES += [ - 'nsModule.cpp', -] - -FINAL_LIBRARY = 'xul' - -LOCAL_INCLUDES += [ - '../directory', -] diff --git a/xpfe/components/build/nsModule.cpp b/xpfe/components/build/nsModule.cpp deleted file mode 100644 index 43966f94d1f2..000000000000 --- a/xpfe/components/build/nsModule.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* -*- 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/. */ - -#include "mozilla/ModuleUtils.h" -#include "nsDirectoryViewer.h" -#include "rdf.h" -#include "nsRDFCID.h" -#include "nsCURILoader.h" - -// Factory constructors -NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsHTTPIndex, Init) -NS_GENERIC_FACTORY_CONSTRUCTOR(nsDirectoryViewerFactory) - -NS_DEFINE_NAMED_CID(NS_DIRECTORYVIEWERFACTORY_CID); -NS_DEFINE_NAMED_CID(NS_HTTPINDEX_SERVICE_CID); - -static const mozilla::Module::CIDEntry kXPFECIDs[] = { - { &kNS_DIRECTORYVIEWERFACTORY_CID, false, nullptr, nsDirectoryViewerFactoryConstructor }, - { &kNS_HTTPINDEX_SERVICE_CID, false, nullptr, nsHTTPIndexConstructor }, - { nullptr } -}; - -static const mozilla::Module::ContractIDEntry kXPFEContracts[] = { - { "@mozilla.org/xpfe/http-index-format-factory-constructor", &kNS_DIRECTORYVIEWERFACTORY_CID }, - { NS_HTTPINDEX_SERVICE_CONTRACTID, &kNS_HTTPINDEX_SERVICE_CID }, - { NS_HTTPINDEX_DATASOURCE_CONTRACTID, &kNS_HTTPINDEX_SERVICE_CID }, - { nullptr } -}; - -static const mozilla::Module::CategoryEntry kXPFECategories[] = { - { "Gecko-Content-Viewers", "application/http-index-format", "@mozilla.org/xpfe/http-index-format-factory-constructor" }, - { nullptr } -}; - -static const mozilla::Module kXPFEModule = { - mozilla::Module::kVersion, - kXPFECIDs, - kXPFEContracts, - kXPFECategories -}; - -NSMODULE_DEFN(application) = &kXPFEModule; diff --git a/xpfe/components/directory/moz.build b/xpfe/components/directory/moz.build deleted file mode 100644 index 980001ecd0c6..000000000000 --- a/xpfe/components/directory/moz.build +++ /dev/null @@ -1,23 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -with Files("**"): - BUG_COMPONENT = ("Core", "Window Management") - -XPIDL_SOURCES += [ - 'nsIHTTPIndex.idl', -] - -XPIDL_MODULE = 'directory' - -SOURCES += [ - 'nsDirectoryViewer.cpp', -] - -FINAL_LIBRARY = 'xul' - -if CONFIG['CC_TYPE'] in ('clang', 'gcc'): - CXXFLAGS += ['-Wno-error=shadow'] diff --git a/xpfe/components/directory/nsDirectoryViewer.cpp b/xpfe/components/directory/nsDirectoryViewer.cpp deleted file mode 100644 index 272c2a05499e..000000000000 --- a/xpfe/components/directory/nsDirectoryViewer.cpp +++ /dev/null @@ -1,1376 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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/. */ - -/* - - A directory viewer object. Parses "application/http-index-format" - per Lou Montulli's original spec: - - http://www.mozilla.org/projects/netlib/dirindexformat.html - - One added change is for a description entry, for when the - target does not match the filename - -*/ - -#include "nsDirectoryViewer.h" -#include "nsArray.h" -#include "nsArrayUtils.h" -#include "nsIDirIndex.h" -#include "nsIDocShell.h" -#include "jsapi.h" -#include "nsCOMPtr.h" -#include "nsEnumeratorUtils.h" -#include "nsEscape.h" -#include "nsIRDFService.h" -#include "nsRDFCID.h" -#include "rdf.h" -#include "nsIServiceManager.h" -#include "nsIXPConnect.h" -#include "nsEnumeratorUtils.h" -#include "nsString.h" -#include "nsReadableUtils.h" -#include "nsITextToSubURI.h" -#include "nsIInterfaceRequestor.h" -#include "nsIInterfaceRequestorUtils.h" -#include "nsIFTPChannel.h" -#include "nsIWindowWatcher.h" -#include "nsIPrompt.h" -#include "nsIAuthPrompt.h" -#include "nsIProgressEventSink.h" -#include "nsIDOMWindow.h" -#include "nsIStreamConverterService.h" -#include "nsICategoryManager.h" -#include "nsXPCOMCID.h" -#include "nsIDocument.h" -#include "mozilla/Preferences.h" -#include "mozilla/dom/ScriptSettings.h" -#include "nsContentUtils.h" -#include "nsIURI.h" -#include "nsNetUtil.h" - -using namespace mozilla; - -static const int FORMAT_XUL = 3; - -//---------------------------------------------------------------------- -// -// Common CIDs -// - -static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); - -// Various protocols we have to special case -static const char kFTPProtocol[] = "ftp://"; - -//---------------------------------------------------------------------- -// -// nsHTTPIndex -// - -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsHTTPIndex) - NS_INTERFACE_MAP_ENTRY(nsIHTTPIndex) - NS_INTERFACE_MAP_ENTRY(nsIRDFDataSource) - NS_INTERFACE_MAP_ENTRY(nsIStreamListener) - NS_INTERFACE_MAP_ENTRY(nsIDirIndexListener) - NS_INTERFACE_MAP_ENTRY(nsIRequestObserver) - NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor) - NS_INTERFACE_MAP_ENTRY(nsIFTPEventSink) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIHTTPIndex) -NS_INTERFACE_MAP_END - -NS_IMPL_CYCLE_COLLECTION(nsHTTPIndex, mInner) -NS_IMPL_CYCLE_COLLECTING_ADDREF(nsHTTPIndex) -NS_IMPL_CYCLE_COLLECTING_RELEASE(nsHTTPIndex) - -NS_IMETHODIMP -nsHTTPIndex::GetInterface(const nsIID &anIID, void **aResult ) -{ - if (anIID.Equals(NS_GET_IID(nsIFTPEventSink))) { - // If we don't have a container to store the logged data - // then don't report ourselves back to the caller - - if (!mRequestor) - return NS_ERROR_NO_INTERFACE; - *aResult = static_cast(this); - NS_ADDREF(this); - return NS_OK; - } - - if (anIID.Equals(NS_GET_IID(nsIPrompt))) { - - if (!mRequestor) - return NS_ERROR_NO_INTERFACE; - - nsCOMPtr aDOMWindow = do_GetInterface(mRequestor); - if (!aDOMWindow) - return NS_ERROR_NO_INTERFACE; - - nsCOMPtr wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID)); - - return wwatch->GetNewPrompter(aDOMWindow, (nsIPrompt**)aResult); - } - - if (anIID.Equals(NS_GET_IID(nsIAuthPrompt))) { - - if (!mRequestor) - return NS_ERROR_NO_INTERFACE; - - nsCOMPtr aDOMWindow = do_GetInterface(mRequestor); - if (!aDOMWindow) - return NS_ERROR_NO_INTERFACE; - - nsCOMPtr wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID)); - - return wwatch->GetNewAuthPrompter(aDOMWindow, (nsIAuthPrompt**)aResult); - } - - if (anIID.Equals(NS_GET_IID(nsIProgressEventSink))) { - - if (!mRequestor) - return NS_ERROR_NO_INTERFACE; - - nsCOMPtr sink = do_GetInterface(mRequestor); - if (!sink) - return NS_ERROR_NO_INTERFACE; - - *aResult = sink; - NS_ADDREF((nsISupports*)*aResult); - return NS_OK; - } - - return NS_ERROR_NO_INTERFACE; -} - -NS_IMETHODIMP -nsHTTPIndex::OnFTPControlLog(bool server, const char *msg) -{ - NS_ENSURE_TRUE(mRequestor, NS_OK); - - nsCOMPtr globalObject = do_GetInterface(mRequestor); - NS_ENSURE_TRUE(globalObject, NS_OK); - - // We're going to run script via JS_CallFunctionName, so we need an - // AutoEntryScript. This is Gecko specific and not in any spec. - dom::AutoEntryScript aes(globalObject, - "nsHTTPIndex OnFTPControlLog"); - JSContext* cx = aes.cx(); - - JS::Rooted global(cx, JS::CurrentGlobalOrNull(cx)); - NS_ENSURE_TRUE(global, NS_OK); - - nsString unicodeMsg; - CopyASCIItoUTF16(msg, unicodeMsg); - JSString* jsMsgStr = JS_NewUCStringCopyZ(cx, unicodeMsg.get()); - NS_ENSURE_TRUE(jsMsgStr, NS_ERROR_OUT_OF_MEMORY); - - JS::AutoValueArray<2> params(cx); - params[0].setBoolean(server); - params[1].setString(jsMsgStr); - - JS::Rooted val(cx); - JS_CallFunctionName(cx, - global, - "OnFTPControlLog", - params, - &val); - return NS_OK; -} - -NS_IMETHODIMP -nsHTTPIndex::SetEncoding(const char *encoding) -{ - mEncoding = encoding; - return(NS_OK); -} - -NS_IMETHODIMP -nsHTTPIndex::GetEncoding(char **encoding) -{ - NS_PRECONDITION(encoding, "null ptr"); - if (! encoding) - return(NS_ERROR_NULL_POINTER); - - *encoding = ToNewCString(mEncoding); - if (!*encoding) - return(NS_ERROR_OUT_OF_MEMORY); - - return(NS_OK); -} - -NS_IMETHODIMP -nsHTTPIndex::OnStartRequest(nsIRequest *request, nsISupports* aContext) -{ - nsresult rv; - - mParser = do_CreateInstance(NS_DIRINDEXPARSER_CONTRACTID, &rv); - if (NS_FAILED(rv)) return rv; - - rv = mParser->SetEncoding(mEncoding.get()); - if (NS_FAILED(rv)) return rv; - - rv = mParser->SetListener(this); - if (NS_FAILED(rv)) return rv; - - rv = mParser->OnStartRequest(request,aContext); - if (NS_FAILED(rv)) return rv; - - // This should only run once... - // Unless we don't have a container to start with - // (ie called from bookmarks as an rdf datasource) - if (mBindToGlobalObject && mRequestor) { - mBindToGlobalObject = false; - - nsCOMPtr globalObject = do_GetInterface(mRequestor); - NS_ENSURE_TRUE(globalObject, NS_ERROR_FAILURE); - - // We might run script via JS_SetProperty, so we need an AutoEntryScript. - // This is Gecko specific and not in any spec. - dom::AutoEntryScript aes(globalObject, - "nsHTTPIndex set HTTPIndex property"); - JSContext* cx = aes.cx(); - - JS::Rooted global(cx, JS::CurrentGlobalOrNull(cx)); - - // Using XPConnect, wrap the HTTP index object... - static NS_DEFINE_CID(kXPConnectCID, NS_XPCONNECT_CID); - nsCOMPtr xpc(do_GetService(kXPConnectCID, &rv)); - if (NS_FAILED(rv)) return rv; - - JS::Rooted jsobj(cx); - rv = xpc->WrapNative(cx, - global, - static_cast(this), - NS_GET_IID(nsIHTTPIndex), - jsobj.address()); - - NS_ASSERTION(NS_SUCCEEDED(rv), "unable to xpconnect-wrap http-index"); - if (NS_FAILED(rv)) return rv; - - NS_ASSERTION(jsobj, - "unable to get jsobj from xpconnect wrapper"); - if (!jsobj) return NS_ERROR_UNEXPECTED; - - JS::Rooted jslistener(cx, JS::ObjectValue(*jsobj)); - - // ...and stuff it into the global context - bool ok = JS_SetProperty(cx, global, "HTTPIndex", jslistener); - NS_ASSERTION(ok, "unable to set Listener property"); - if (!ok) - return NS_ERROR_FAILURE; - } - - if (!aContext) { - nsCOMPtr channel(do_QueryInterface(request)); - NS_ASSERTION(channel, "request should be a channel"); - - // lets hijack the notifications: - channel->SetNotificationCallbacks(this); - - // now create the top most resource - nsCOMPtr uri; - channel->GetURI(getter_AddRefs(uri)); - - nsAutoCString entryuriC; - rv = uri->GetSpec(entryuriC); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr entry; - rv = mDirRDF->GetResource(entryuriC, getter_AddRefs(entry)); - - NS_ConvertUTF8toUTF16 uriUnicode(entryuriC); - - nsCOMPtr URLVal; - rv = mDirRDF->GetLiteral(uriUnicode.get(), getter_AddRefs(URLVal)); - - Assert(entry, kNC_URL, URLVal, true); - mDirectory = do_QueryInterface(entry); - } - else - { - // Get the directory from the context - mDirectory = do_QueryInterface(aContext); - } - - if (!mDirectory) { - request->Cancel(NS_BINDING_ABORTED); - return NS_BINDING_ABORTED; - } - - // Mark the directory as "loading" - rv = Assert(mDirectory, kNC_Loading, - kTrueLiteral, true); - if (NS_FAILED(rv)) return rv; - - return NS_OK; -} - - -NS_IMETHODIMP -nsHTTPIndex::OnStopRequest(nsIRequest *request, - nsISupports* aContext, - nsresult aStatus) -{ - // If mDirectory isn't set, then we should just bail. Either an - // error occurred and OnStartRequest() never got called, or - // something exploded in OnStartRequest(). - if (! mDirectory) - return NS_BINDING_ABORTED; - - mParser->OnStopRequest(request,aContext,aStatus); - - nsresult rv; - - nsCString commentStr; - mParser->GetComment(getter_Copies(commentStr)); - - nsCOMPtr comment; - rv = mDirRDF->GetLiteral(NS_ConvertASCIItoUTF16(commentStr).get(), getter_AddRefs(comment)); - if (NS_FAILED(rv)) return rv; - - rv = Assert(mDirectory, kNC_Comment, comment, true); - if (NS_FAILED(rv)) return rv; - - // hack: Remove the 'loading' annotation (ignore errors) - AddElement(mDirectory, kNC_Loading, kTrueLiteral); - - return NS_OK; -} - - -NS_IMETHODIMP -nsHTTPIndex::OnDataAvailable(nsIRequest *request, - nsISupports* aContext, - nsIInputStream* aStream, - uint64_t aSourceOffset, - uint32_t aCount) -{ - // If mDirectory isn't set, then we should just bail. Either an - // error occurred and OnStartRequest() never got called, or - // something exploded in OnStartRequest(). - if (! mDirectory) - return NS_BINDING_ABORTED; - - return mParser->OnDataAvailable(request, mDirectory, aStream, aSourceOffset, aCount); -} - - -nsresult -nsHTTPIndex::OnIndexAvailable(nsIRequest* aRequest, nsISupports *aContext, - nsIDirIndex* aIndex) -{ - nsCOMPtr parentRes = do_QueryInterface(aContext); - if (!parentRes) { - NS_ERROR("Could not obtain parent resource"); - return(NS_ERROR_UNEXPECTED); - } - - const char* baseStr; - parentRes->GetValueConst(&baseStr); - if (! baseStr) { - NS_ERROR("Could not reconstruct base uri"); - return NS_ERROR_UNEXPECTED; - } - - // we found the filename; construct a resource for its entry - nsAutoCString entryuriC(baseStr); - - nsCString filename; - nsresult rv = aIndex->GetLocation(getter_Copies(filename)); - if (NS_FAILED(rv)) return rv; - entryuriC.Append(filename); - - // if its a directory, make sure it ends with a trailing slash. - uint32_t type; - rv = aIndex->GetType(&type); - if (NS_FAILED(rv)) - return rv; - - bool isDirType = (type == nsIDirIndex::TYPE_DIRECTORY); - if (isDirType && entryuriC.Last() != '/') { - entryuriC.Append('/'); - } - - nsCOMPtr entry; - rv = mDirRDF->GetResource(entryuriC, getter_AddRefs(entry)); - - // At this point, we'll (hopefully) have found the filename and - // constructed a resource for it, stored in entry. So now take a - // second pass through the values and add as statements to the RDF - // datasource. - - if (entry && NS_SUCCEEDED(rv)) { - nsCOMPtr lit; - nsString str; - - CopyASCIItoUTF16(entryuriC, str); - - rv = mDirRDF->GetLiteral(str.get(), getter_AddRefs(lit)); - - if (NS_SUCCEEDED(rv)) { - rv = Assert(entry, kNC_URL, lit, true); - if (NS_FAILED(rv)) return rv; - - nsString xpstr; - - // description - rv = aIndex->GetDescription(getter_Copies(xpstr)); - if (NS_FAILED(rv)) return rv; - if (xpstr.Last() == '/') - xpstr.Truncate(xpstr.Length() - 1); - - rv = mDirRDF->GetLiteral(xpstr.get(), getter_AddRefs(lit)); - if (NS_FAILED(rv)) return rv; - rv = Assert(entry, kNC_Description, lit, true); - if (NS_FAILED(rv)) return rv; - - // contentlength - int64_t size; - rv = aIndex->GetSize(&size); - if (NS_FAILED(rv)) return rv; - int64_t minus1 = UINT64_MAX; - if (size != minus1) { - int32_t intSize = int32_t(size); - // XXX RDF should support 64 bit integers (bug 240160) - nsCOMPtr val; - rv = mDirRDF->GetIntLiteral(intSize, getter_AddRefs(val)); - if (NS_FAILED(rv)) return rv; - rv = Assert(entry, kNC_ContentLength, val, true); - if (NS_FAILED(rv)) return rv; - } - - // lastmodified - PRTime tm; - rv = aIndex->GetLastModified(&tm); - if (NS_FAILED(rv)) return rv; - if (tm != -1) { - nsCOMPtr val; - rv = mDirRDF->GetDateLiteral(tm, getter_AddRefs(val)); - if (NS_FAILED(rv)) return rv; - rv = Assert(entry, kNC_LastModified, val, true); - } - - // filetype - uint32_t type; - rv = aIndex->GetType(&type); - switch (type) { - case nsIDirIndex::TYPE_UNKNOWN: - rv = mDirRDF->GetLiteral(u"UNKNOWN", getter_AddRefs(lit)); - break; - case nsIDirIndex::TYPE_DIRECTORY: - rv = mDirRDF->GetLiteral(u"DIRECTORY", getter_AddRefs(lit)); - break; - case nsIDirIndex::TYPE_FILE: - rv = mDirRDF->GetLiteral(u"FILE", getter_AddRefs(lit)); - break; - case nsIDirIndex::TYPE_SYMLINK: - rv = mDirRDF->GetLiteral(u"SYMLINK", getter_AddRefs(lit)); - break; - } - - if (NS_FAILED(rv)) return rv; - rv = Assert(entry, kNC_FileType, lit, true); - if (NS_FAILED(rv)) return rv; - } - - // Since the definition of a directory depends on the protocol, we would have - // to do string comparisons all the time. - // But we're told if we're a container right here - so save that fact - if (isDirType) - Assert(entry, kNC_IsContainer, kTrueLiteral, true); - else - Assert(entry, kNC_IsContainer, kFalseLiteral, true); - -// instead of -// rv = Assert(parentRes, kNC_Child, entry, true); -// if (NS_FAILED(rv)) return rv; -// defer insertion onto a timer so that the UI isn't starved - AddElement(parentRes, kNC_Child, entry); - } - - return rv; -} - -nsresult -nsHTTPIndex::OnInformationAvailable(nsIRequest *aRequest, - nsISupports *aCtxt, - const nsAString& aInfo) { - return NS_ERROR_NOT_IMPLEMENTED; -} - -//---------------------------------------------------------------------- -// -// nsHTTPIndex implementation -// - -nsHTTPIndex::nsHTTPIndex() - : mBindToGlobalObject(true), - mRequestor(nullptr) -{ -} - - -nsHTTPIndex::nsHTTPIndex(nsIInterfaceRequestor* aRequestor) - : mBindToGlobalObject(true), - mRequestor(aRequestor) -{ -} - - -nsHTTPIndex::~nsHTTPIndex() -{ - // note: these are NOT statics due to the native of nsHTTPIndex - // where it may or may not be treated as a singleton - - if (mTimer) - { - // be sure to cancel the timer, as it holds a - // weak reference back to nsHTTPIndex - mTimer->Cancel(); - mTimer = nullptr; - } - - mConnectionList = nullptr; - mNodeList = nullptr; - - if (mDirRDF) - { - // UnregisterDataSource() may fail; just ignore errors - mDirRDF->UnregisterDataSource(this); - } -} - - - -nsresult -nsHTTPIndex::CommonInit() -{ - nsresult rv = NS_OK; - - // set initial/default encoding to windows-1252 (not UTF-8) - mEncoding = "windows-1252"; - - mDirRDF = do_GetService(kRDFServiceCID, &rv); - NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get RDF service"); - if (NS_FAILED(rv)) { - return(rv); - } - - mInner = do_CreateInstance("@mozilla.org/rdf/datasource;1?name=in-memory-datasource", &rv); - - if (NS_FAILED(rv)) - return rv; - - mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "child"), - getter_AddRefs(kNC_Child)); - mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "loading"), - getter_AddRefs(kNC_Loading)); - mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "Comment"), - getter_AddRefs(kNC_Comment)); - mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "URL"), - getter_AddRefs(kNC_URL)); - mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "Name"), - getter_AddRefs(kNC_Description)); - mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "Content-Length"), - getter_AddRefs(kNC_ContentLength)); - mDirRDF->GetResource(NS_LITERAL_CSTRING(WEB_NAMESPACE_URI "LastModifiedDate"), - getter_AddRefs(kNC_LastModified)); - mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "Content-Type"), - getter_AddRefs(kNC_ContentType)); - mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "File-Type"), - getter_AddRefs(kNC_FileType)); - mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "IsContainer"), - getter_AddRefs(kNC_IsContainer)); - - rv = mDirRDF->GetLiteral(u"true", getter_AddRefs(kTrueLiteral)); - if (NS_FAILED(rv)) return(rv); - rv = mDirRDF->GetLiteral(u"false", getter_AddRefs(kFalseLiteral)); - if (NS_FAILED(rv)) return(rv); - - mConnectionList = nsArray::Create(); - - // note: don't register DS here - return rv; -} - - -nsresult -nsHTTPIndex::Init() -{ - nsresult rv; - - // set initial/default encoding to windows-1252 (not UTF-8) - mEncoding = "windows-1252"; - - rv = CommonInit(); - if (NS_FAILED(rv)) return(rv); - - // (do this last) register this as a named data source with the RDF service - rv = mDirRDF->RegisterDataSource(this, false); - if (NS_FAILED(rv)) return(rv); - - return(NS_OK); -} - - - -nsresult -nsHTTPIndex::Init(nsIURI* aBaseURL) -{ - NS_PRECONDITION(aBaseURL != nullptr, "null ptr"); - if (! aBaseURL) - return NS_ERROR_NULL_POINTER; - - nsresult rv; - - rv = CommonInit(); - if (NS_FAILED(rv)) return(rv); - - // note: don't register DS here (singleton case) - - rv = aBaseURL->GetSpec(mBaseURL); - if (NS_FAILED(rv)) return rv; - - // Mark the base url as a container - nsCOMPtr baseRes; - mDirRDF->GetResource(mBaseURL, getter_AddRefs(baseRes)); - Assert(baseRes, kNC_IsContainer, kTrueLiteral, true); - - return NS_OK; -} - - - -nsresult -nsHTTPIndex::Create(nsIURI* aBaseURL, nsIInterfaceRequestor* aRequestor, - nsIHTTPIndex** aResult) -{ - *aResult = nullptr; - - nsHTTPIndex* result = new nsHTTPIndex(aRequestor); - nsresult rv = result->Init(aBaseURL); - if (NS_SUCCEEDED(rv)) - { - NS_ADDREF(result); - *aResult = result; - } - else - { - delete result; - } - return rv; -} - -NS_IMETHODIMP -nsHTTPIndex::GetBaseURL(char** _result) -{ - *_result = ToNewCString(mBaseURL); - if (! *_result) - return NS_ERROR_OUT_OF_MEMORY; - - return NS_OK; -} - -NS_IMETHODIMP -nsHTTPIndex::GetDataSource(nsIRDFDataSource** _result) -{ - NS_ADDREF(*_result = this); - return NS_OK; -} - -// This function finds the destination when following a given nsIRDFResource -// If the resource has a URL attribute, we use that. If not, just use -// the uri. -// -// Do NOT try to get the destination of a uri in any other way -void nsHTTPIndex::GetDestination(nsIRDFResource* r, nsACString& dest) { - // First try the URL attribute - nsCOMPtr node; - - GetTarget(r, kNC_URL, true, getter_AddRefs(node)); - nsCOMPtr url; - - if (node) - url = do_QueryInterface(node); - - if (!url) { - const char* temp; - r->GetValueConst(&temp); - dest.Adopt(temp ? strdup(temp) : 0); - } else { - const char16_t* uri; - url->GetValueConst(&uri); - dest.Adopt(ToNewUTF8String(nsDependentString(uri))); - } -} - -// rjc: isWellknownContainerURI() decides whether a URI is a container for which, -// when asked (say, by the template builder), we'll make a network connection -// to get its contents. For the moment, all we speak is ftp:// URLs, even though -// a) we can get "http-index" mimetypes for really anything -// b) we could easily handle file:// URLs here -// Q: Why don't we? -// A: The file system datasource ("rdf:file"); at some point, the two -// should be perhaps united. Until then, we can't aggregate both -// "rdf:file" and "http-index" (such as with bookmarks) because we'd -// get double the # of answers we really want... also, "rdf:file" is -// less expensive in terms of both memory usage as well as speed - - - -// We use an rdf attribute to mark if this is a container or not. -// Note that we still have to do string comparisons as a fallback -// because stuff like the personal toolbar and bookmarks check whether -// a URL is a container, and we have no attribute in that case. -bool -nsHTTPIndex::isWellknownContainerURI(nsIRDFResource *r) -{ - nsCOMPtr node; - GetTarget(r, kNC_IsContainer, true, getter_AddRefs(node)); - if (node) { - bool isContainerFlag; - if (NS_SUCCEEDED(node->EqualsNode(kTrueLiteral, &isContainerFlag))) - return isContainerFlag; - } - - nsCString uri; - GetDestination(r, uri); - return StringBeginsWith(uri, nsDependentCString(kFTPProtocol)) && - (uri.Last() == '/'); -} - - -NS_IMETHODIMP -nsHTTPIndex::GetURI(nsACString& aURI) -{ - aURI.AssignLiteral("rdf:httpindex"); - return NS_OK; -} - -NS_IMETHODIMP -nsHTTPIndex::GetSource(nsIRDFResource *aProperty, nsIRDFNode *aTarget, bool aTruthValue, - nsIRDFResource **_retval) -{ - nsresult rv = NS_ERROR_UNEXPECTED; - - *_retval = nullptr; - - if (mInner) - { - rv = mInner->GetSource(aProperty, aTarget, aTruthValue, _retval); - } - return(rv); -} - -NS_IMETHODIMP -nsHTTPIndex::GetSources(nsIRDFResource *aProperty, nsIRDFNode *aTarget, bool aTruthValue, - nsISimpleEnumerator **_retval) -{ - nsresult rv = NS_ERROR_UNEXPECTED; - - if (mInner) - { - rv = mInner->GetSources(aProperty, aTarget, aTruthValue, _retval); - } - else - { - rv = NS_NewEmptyEnumerator(_retval); - } - return(rv); -} - -NS_IMETHODIMP -nsHTTPIndex::GetTarget(nsIRDFResource *aSource, nsIRDFResource *aProperty, bool aTruthValue, - nsIRDFNode **_retval) -{ - nsresult rv = NS_ERROR_UNEXPECTED; - - *_retval = nullptr; - - if ((aTruthValue) && (aProperty == kNC_Child) && isWellknownContainerURI(aSource)) - { - // fake out the generic builder (i.e. return anything in this case) - // so that search containers never appear to be empty - NS_IF_ADDREF(aSource); - *_retval = aSource; - return(NS_OK); - } - - if (mInner) - { - rv = mInner->GetTarget(aSource, aProperty, aTruthValue, _retval); - } - return(rv); -} - -NS_IMETHODIMP -nsHTTPIndex::GetTargets(nsIRDFResource *aSource, nsIRDFResource *aProperty, bool aTruthValue, - nsISimpleEnumerator **_retval) -{ - nsresult rv = NS_ERROR_UNEXPECTED; - - if (mInner) - { - rv = mInner->GetTargets(aSource, aProperty, aTruthValue, _retval); - } - else - { - rv = NS_NewEmptyEnumerator(_retval); - } - - if ((aProperty == kNC_Child) && isWellknownContainerURI(aSource)) - { - bool doNetworkRequest = true; - if (NS_SUCCEEDED(rv) && (_retval)) - { - // check and see if we already have data for the search in question; - // if we do, don't bother doing the search again - bool hasResults; - if (NS_SUCCEEDED((*_retval)->HasMoreElements(&hasResults)) && - hasResults) - doNetworkRequest = false; - } - - // Note: if we need to do a network request, do it out-of-band - // (because the XUL template builder isn't re-entrant) - // by using a global connection list and an immediately-firing timer - if (doNetworkRequest && mConnectionList) - { - uint32_t connectionIndex; - nsresult idx_rv = mConnectionList->IndexOf(0, aSource, &connectionIndex); - if (NS_FAILED(idx_rv)) - { - // add aSource into list of connections to make - mConnectionList->AppendElement(aSource); - - // if we don't have a timer about to fire, create one - // which should fire as soon as possible (out-of-band) - if (!mTimer) - { - rv = NS_NewTimerWithFuncCallback(getter_AddRefs(mTimer), - nsHTTPIndex::FireTimer, - this, - 1, - nsITimer::TYPE_ONE_SHOT, - "nsHTTPIndex::GetTargets"); - // Note: don't addref "this" as we'll cancel the - // timer in the httpIndex destructor - NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create a timer"); - } - } - } - } - - return(rv); -} - - -nsresult -nsHTTPIndex::AddElement(nsIRDFResource *parent, nsIRDFResource *prop, nsIRDFNode *child) -{ - - if (!mNodeList) - { - mNodeList = nsArray::Create(); - } - - // order required: parent, prop, then child - mNodeList->AppendElement(parent); - mNodeList->AppendElement(prop); - mNodeList->AppendElement(child); - - if (!mTimer) - { - return NS_NewTimerWithFuncCallback(getter_AddRefs(mTimer), - nsHTTPIndex::FireTimer, - this, - 1, - nsITimer::TYPE_ONE_SHOT, - "nsHTTPIndex::AddElement"); - // Note: don't addref "this" as we'll cancel the - // timer in the httpIndex destructor - } - - return(NS_OK); -} - -void -nsHTTPIndex::FireTimer(nsITimer* aTimer, void* aClosure) -{ - nsHTTPIndex *httpIndex = static_cast(aClosure); - if (!httpIndex) - return; - - // don't return out of this loop as mTimer may need to be cancelled afterwards - uint32_t numItems = 0; - if (httpIndex->mConnectionList) - { - httpIndex->mConnectionList->GetLength(&numItems); - if (numItems > 0) - { - nsCOMPtr source = - do_QueryElementAt(httpIndex->mConnectionList, 0); - httpIndex->mConnectionList->RemoveElementAt(0); - - nsCString uri = VoidCString(); - if (source) { - httpIndex->GetDestination(source, uri); - } - - if (uri.IsVoid()) { - NS_ERROR("Could not reconstruct uri"); - return; - } - - nsresult rv = NS_OK; - nsCOMPtr url; - - rv = NS_NewURI(getter_AddRefs(url), uri.get()); - nsCOMPtr channel; - if (NS_SUCCEEDED(rv) && (url)) { - rv = NS_NewChannel(getter_AddRefs(channel), - url, - nsContentUtils::GetSystemPrincipal(), - nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, - nsIContentPolicy::TYPE_OTHER); - } - if (NS_SUCCEEDED(rv) && (channel)) { - channel->SetNotificationCallbacks(httpIndex); - rv = channel->AsyncOpen2(httpIndex); - } - } - } - - if (httpIndex->mNodeList) - { - httpIndex->mNodeList->GetLength(&numItems); - if (numItems > 0) - { - // account for order required: src, prop, then target - numItems /=3; - if (numItems > 10) - numItems = 10; - - int32_t loop; - for (loop=0; loop<(int32_t)numItems; loop++) - { - nsCOMPtr src = do_QueryElementAt(httpIndex->mNodeList, 0); - httpIndex->mNodeList->RemoveElementAt(0); - - nsCOMPtr prop = do_QueryElementAt(httpIndex->mNodeList, 0); - httpIndex->mNodeList->RemoveElementAt(0); - - nsCOMPtr target = do_QueryElementAt(httpIndex->mNodeList, 0); - httpIndex->mNodeList->RemoveElementAt(0); - - if (src && prop && target) - { - if (prop.get() == httpIndex->kNC_Loading) - { - httpIndex->Unassert(src, prop, target); - } - else - { - httpIndex->Assert(src, prop, target, true); - } - } - } - } - } - - bool refireTimer = false; - // check both lists to see if the timer needs to continue firing - if (httpIndex->mConnectionList) - { - httpIndex->mConnectionList->GetLength(&numItems); - if (numItems > 0) - { - refireTimer = true; - } - else - { - httpIndex->mConnectionList->Clear(); - } - } - - if (httpIndex->mNodeList) - { - httpIndex->mNodeList->GetLength(&numItems); - if (numItems > 0) - { - refireTimer = true; - } - else - { - httpIndex->mNodeList->Clear(); - } - } - - // be sure to cancel the timer, as it holds a - // weak reference back to nsHTTPIndex - httpIndex->mTimer->Cancel(); - httpIndex->mTimer = nullptr; - - // after firing off any/all of the connections be sure - // to cancel the timer if we don't need to refire it - if (refireTimer) - { - NS_NewTimerWithFuncCallback(getter_AddRefs(httpIndex->mTimer), - nsHTTPIndex::FireTimer, - aClosure, - 10, - nsITimer::TYPE_ONE_SHOT, - "nsHTTPIndex::FireTimer"); - // Note: don't addref "this" as we'll cancel the - // timer in the httpIndex destructor - } -} - -NS_IMETHODIMP -nsHTTPIndex::Assert(nsIRDFResource *aSource, nsIRDFResource *aProperty, nsIRDFNode *aTarget, - bool aTruthValue) -{ - nsresult rv = NS_ERROR_UNEXPECTED; - if (mInner) - { - rv = mInner->Assert(aSource, aProperty, aTarget, aTruthValue); - } - return(rv); -} - -NS_IMETHODIMP -nsHTTPIndex::Unassert(nsIRDFResource *aSource, nsIRDFResource *aProperty, nsIRDFNode *aTarget) -{ - nsresult rv = NS_ERROR_UNEXPECTED; - if (mInner) - { - rv = mInner->Unassert(aSource, aProperty, aTarget); - } - return(rv); -} - -NS_IMETHODIMP -nsHTTPIndex::Change(nsIRDFResource *aSource, nsIRDFResource *aProperty, - nsIRDFNode *aOldTarget, nsIRDFNode *aNewTarget) -{ - nsresult rv = NS_ERROR_UNEXPECTED; - if (mInner) - { - rv = mInner->Change(aSource, aProperty, aOldTarget, aNewTarget); - } - return(rv); -} - -NS_IMETHODIMP -nsHTTPIndex::Move(nsIRDFResource *aOldSource, nsIRDFResource *aNewSource, - nsIRDFResource *aProperty, nsIRDFNode *aTarget) -{ - nsresult rv = NS_ERROR_UNEXPECTED; - if (mInner) - { - rv = mInner->Move(aOldSource, aNewSource, aProperty, aTarget); - } - return(rv); -} - -NS_IMETHODIMP -nsHTTPIndex::HasAssertion(nsIRDFResource *aSource, nsIRDFResource *aProperty, - nsIRDFNode *aTarget, bool aTruthValue, bool *_retval) -{ - nsresult rv = NS_ERROR_UNEXPECTED; - if (mInner) - { - rv = mInner->HasAssertion(aSource, aProperty, aTarget, aTruthValue, _retval); - } - return(rv); -} - -NS_IMETHODIMP -nsHTTPIndex::AddObserver(nsIRDFObserver *aObserver) -{ - nsresult rv = NS_ERROR_UNEXPECTED; - if (mInner) - { - rv = mInner->AddObserver(aObserver); - } - return(rv); -} - -NS_IMETHODIMP -nsHTTPIndex::RemoveObserver(nsIRDFObserver *aObserver) -{ - nsresult rv = NS_ERROR_UNEXPECTED; - if (mInner) - { - rv = mInner->RemoveObserver(aObserver); - } - return(rv); -} - -NS_IMETHODIMP -nsHTTPIndex::HasArcIn(nsIRDFNode *aNode, nsIRDFResource *aArc, bool *result) -{ - if (!mInner) { - *result = false; - return NS_OK; - } - return mInner->HasArcIn(aNode, aArc, result); -} - -NS_IMETHODIMP -nsHTTPIndex::HasArcOut(nsIRDFResource *aSource, nsIRDFResource *aArc, bool *result) -{ - if (aArc == kNC_Child && isWellknownContainerURI(aSource)) { - *result = true; - return NS_OK; - } - - if (mInner) { - return mInner->HasArcOut(aSource, aArc, result); - } - - *result = false; - return NS_OK; -} - -NS_IMETHODIMP -nsHTTPIndex::ArcLabelsIn(nsIRDFNode *aNode, nsISimpleEnumerator **_retval) -{ - nsresult rv = NS_ERROR_UNEXPECTED; - if (mInner) - { - rv = mInner->ArcLabelsIn(aNode, _retval); - } - return(rv); -} - -NS_IMETHODIMP -nsHTTPIndex::ArcLabelsOut(nsIRDFResource *aSource, nsISimpleEnumerator **_retval) -{ - *_retval = nullptr; - - nsCOMPtr child, anonArcs; - if (isWellknownContainerURI(aSource)) - { - NS_NewSingletonEnumerator(getter_AddRefs(child), kNC_Child); - } - - if (mInner) - { - mInner->ArcLabelsOut(aSource, getter_AddRefs(anonArcs)); - } - - return NS_NewUnionEnumerator(_retval, child, anonArcs); -} - -NS_IMETHODIMP -nsHTTPIndex::GetAllResources(nsISimpleEnumerator **_retval) -{ - nsresult rv = NS_ERROR_UNEXPECTED; - if (mInner) - { - rv = mInner->GetAllResources(_retval); - } - return(rv); -} - -NS_IMETHODIMP -nsHTTPIndex::IsCommandEnabled(nsISupports *aSources, nsIRDFResource *aCommand, - nsISupports *aArguments, bool *_retval) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -nsHTTPIndex::DoCommand(nsISupports *aSources, nsIRDFResource *aCommand, - nsISupports *aArguments) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -nsHTTPIndex::BeginUpdateBatch() -{ - return mInner->BeginUpdateBatch(); -} - -NS_IMETHODIMP -nsHTTPIndex::EndUpdateBatch() -{ - return mInner->EndUpdateBatch(); -} - -NS_IMETHODIMP -nsHTTPIndex::GetAllCmds(nsIRDFResource *aSource, nsISimpleEnumerator **_retval) -{ - nsresult rv = NS_ERROR_UNEXPECTED; - if (mInner) - { - rv = mInner->GetAllCmds(aSource, _retval); - } - return(rv); -} - - -//---------------------------------------------------------------------- -// -// nsDirectoryViewerFactory -// -nsDirectoryViewerFactory::nsDirectoryViewerFactory() -{ -} - - - -nsDirectoryViewerFactory::~nsDirectoryViewerFactory() -{ -} - - -NS_IMPL_ISUPPORTS(nsDirectoryViewerFactory, nsIDocumentLoaderFactory) - - - -NS_IMETHODIMP -nsDirectoryViewerFactory::CreateInstance(const char *aCommand, - nsIChannel* aChannel, - nsILoadGroup* aLoadGroup, - const nsACString& aContentType, - nsIDocShell* aContainer, - nsISupports* aExtraInfo, - nsIStreamListener** aDocListenerResult, - nsIContentViewer** aDocViewerResult) -{ - nsresult rv; - - bool viewSource = FindInReadable(NS_LITERAL_CSTRING("view-source"), - aContentType); - - if (!viewSource && - Preferences::GetInt("network.dir.format", FORMAT_XUL) == FORMAT_XUL) { - // ... and setup the original channel's content type - (void)aChannel->SetContentType(NS_LITERAL_CSTRING("application/vnd.mozilla.xul+xml")); - - // This is where we shunt the HTTP/Index stream into our datasource, - // and open the directory viewer XUL file as the content stream to - // load in its place. - - // Create a dummy loader that will load a stub XUL document. - nsCOMPtr catMan(do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv)); - if (NS_FAILED(rv)) - return rv; - nsCString contractID; - rv = catMan->GetCategoryEntry("Gecko-Content-Viewers", "application/vnd.mozilla.xul+xml", - getter_Copies(contractID)); - if (NS_FAILED(rv)) - return rv; - - nsCOMPtr - factory(do_GetService(contractID.get(), &rv)); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr uri; - rv = NS_NewURI(getter_AddRefs(uri), "chrome://communicator/content/directory/directory.xul"); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr channel; - rv = NS_NewChannel(getter_AddRefs(channel), - uri, - nsContentUtils::GetSystemPrincipal(), - nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, - nsIContentPolicy::TYPE_OTHER, - nullptr, // PerformanceStorage - aLoadGroup); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr listener; - rv = factory->CreateInstance(aCommand, channel, aLoadGroup, - NS_LITERAL_CSTRING("application/vnd.mozilla.xul+xml"), - aContainer, aExtraInfo, getter_AddRefs(listener), - aDocViewerResult); - if (NS_FAILED(rv)) return rv; - - rv = channel->AsyncOpen2(listener); - if (NS_FAILED(rv)) return rv; - - // Create an HTTPIndex object so that we can stuff it into the script context - nsCOMPtr baseuri; - rv = aChannel->GetURI(getter_AddRefs(baseuri)); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr requestor = do_QueryInterface(aContainer,&rv); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr httpindex; - rv = nsHTTPIndex::Create(baseuri, requestor, getter_AddRefs(httpindex)); - if (NS_FAILED(rv)) return rv; - - // Now shanghai the stream into our http-index parsing datasource - // wrapper beastie. - listener = do_QueryInterface(httpindex,&rv); - *aDocListenerResult = listener.get(); - NS_ADDREF(*aDocListenerResult); - - return NS_OK; - } - - // setup the original channel's content type - (void)aChannel->SetContentType(NS_LITERAL_CSTRING("text/html")); - - // Otherwise, lets use the html listing - nsCOMPtr catMan(do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv)); - if (NS_FAILED(rv)) - return rv; - nsCString contractID; - rv = catMan->GetCategoryEntry("Gecko-Content-Viewers", "text/html", - getter_Copies(contractID)); - if (NS_FAILED(rv)) - return rv; - - nsCOMPtr - factory(do_GetService(contractID.get(), &rv)); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr listener; - - if (viewSource) { - rv = factory->CreateInstance("view-source", aChannel, aLoadGroup, - NS_LITERAL_CSTRING("text/html; x-view-type=view-source"), - aContainer, aExtraInfo, getter_AddRefs(listener), - aDocViewerResult); - } else { - rv = factory->CreateInstance("view", aChannel, aLoadGroup, - NS_LITERAL_CSTRING("text/html"), - aContainer, aExtraInfo, getter_AddRefs(listener), - aDocViewerResult); - } - - if (NS_FAILED(rv)) return rv; - - nsCOMPtr scs = do_GetService("@mozilla.org/streamConverters;1", &rv); - if (NS_FAILED(rv)) return rv; - - rv = scs->AsyncConvertData("application/http-index-format", - "text/html", - listener, - nullptr, - aDocListenerResult); - - if (NS_FAILED(rv)) return rv; - - return NS_OK; -} - - - -NS_IMETHODIMP -nsDirectoryViewerFactory::CreateInstanceForDocument(nsISupports* aContainer, - nsIDocument* aDocument, - const char *aCommand, - nsIContentViewer** aDocViewerResult) -{ - MOZ_ASSERT_UNREACHABLE("didn't expect to get here"); - return NS_ERROR_NOT_IMPLEMENTED; -} diff --git a/xpfe/components/directory/nsDirectoryViewer.h b/xpfe/components/directory/nsDirectoryViewer.h deleted file mode 100644 index ecb32b0a1404..000000000000 --- a/xpfe/components/directory/nsDirectoryViewer.h +++ /dev/null @@ -1,126 +0,0 @@ -/* -*- 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/. */ - -#ifndef nsdirectoryviewer__h____ -#define nsdirectoryviewer__h____ - -#include "nsCOMPtr.h" -#include "nsIStreamListener.h" -#include "nsIContentViewer.h" -#include "nsIHTTPIndex.h" -#include "nsIRDFService.h" -#include "nsIRDFDataSource.h" -#include "nsIRDFLiteral.h" -#include "nsIDocumentLoaderFactory.h" -#include "nsITimer.h" -#include "nsString.h" -#include "nsIDirIndexListener.h" -#include "nsIFTPChannel.h" -#include "nsCycleCollectionParticipant.h" -#include "nsIInterfaceRequestor.h" -#include "nsIURI.h" - -class nsIMutableArray; - -class nsDirectoryViewerFactory : public nsIDocumentLoaderFactory -{ -public: - nsDirectoryViewerFactory(); - - // nsISupports interface - NS_DECL_ISUPPORTS - NS_DECL_NSIDOCUMENTLOADERFACTORY - -protected: - virtual ~nsDirectoryViewerFactory(); -}; - -class nsHTTPIndex final : public nsIHTTPIndex, - public nsIRDFDataSource, - public nsIStreamListener, - public nsIDirIndexListener, - public nsIInterfaceRequestor, - public nsIFTPEventSink -{ -private: - - // note: these are NOT statics due to the native of nsHTTPIndex - // where it may or may not be treated as a singleton - - nsCOMPtr kNC_Child; - nsCOMPtr kNC_Comment; - nsCOMPtr kNC_Loading; - nsCOMPtr kNC_URL; - nsCOMPtr kNC_Description; - nsCOMPtr kNC_ContentLength; - nsCOMPtr kNC_LastModified; - nsCOMPtr kNC_ContentType; - nsCOMPtr kNC_FileType; - nsCOMPtr kNC_IsContainer; - nsCOMPtr kTrueLiteral; - nsCOMPtr kFalseLiteral; - - nsCOMPtr mDirRDF; - -protected: - // We grab a reference to the content viewer container (which - // indirectly owns us) so that we can insert ourselves as a global - // in the script context _after_ the XUL doc has been embedded into - // content viewer. We'll know that this has happened once we receive - // an OnStartRequest() notification - - nsCOMPtr mInner; - nsCOMPtr mConnectionList; - nsCOMPtr mNodeList; - nsCOMPtr mTimer; - nsCOMPtr mParser; - nsCString mBaseURL; - nsCString mEncoding; - bool mBindToGlobalObject; - nsIInterfaceRequestor* mRequestor; // WEAK - nsCOMPtr mDirectory; - - explicit nsHTTPIndex(nsIInterfaceRequestor* aRequestor); - nsresult CommonInit(void); - nsresult Init(nsIURI* aBaseURL); - void GetDestination(nsIRDFResource* r, nsACString& dest); - bool isWellknownContainerURI(nsIRDFResource *r); - nsresult AddElement(nsIRDFResource *parent, nsIRDFResource *prop, - nsIRDFNode *child); - - static void FireTimer(nsITimer* aTimer, void* aClosure); - - virtual ~nsHTTPIndex(); - -public: - nsHTTPIndex(); - nsresult Init(void); - - static nsresult Create(nsIURI* aBaseURI, nsIInterfaceRequestor* aContainer, - nsIHTTPIndex** aResult); - - // nsIHTTPIndex interface - NS_DECL_NSIHTTPINDEX - - // NSIRDFDataSource interface - NS_DECL_NSIRDFDATASOURCE - - NS_DECL_NSIREQUESTOBSERVER - NS_DECL_NSISTREAMLISTENER - - NS_DECL_NSIDIRINDEXLISTENER - NS_DECL_NSIINTERFACEREQUESTOR - NS_DECL_NSIFTPEVENTSINK - - // nsISupports interface - NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsHTTPIndex, nsIHTTPIndex) -}; - -// {82776710-5690-11d3-BE36-00104BDE6048} -#define NS_DIRECTORYVIEWERFACTORY_CID \ -{ 0x82776710, 0x5690, 0x11d3, { 0xbe, 0x36, 0x0, 0x10, 0x4b, 0xde, 0x60, 0x48 } } - -#endif // nsdirectoryviewer__h____ diff --git a/xpfe/components/directory/nsIHTTPIndex.idl b/xpfe/components/directory/nsIHTTPIndex.idl deleted file mode 100644 index 47697172bcc5..000000000000 --- a/xpfe/components/directory/nsIHTTPIndex.idl +++ /dev/null @@ -1,50 +0,0 @@ -/* -*- 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/. */ - -/* - - The interface to an HTTP index - -*/ - -#include "nsISupports.idl" - -interface nsIStreamListener; -interface nsIRDFDataSource; -interface nsIRDFNode; -interface nsIRDFResource; - -[scriptable, uuid(6F2BDBD0-58C3-11d3-BE36-00104BDE6048)] -interface nsIHTTPIndex : nsISupports -{ - /** - * The base URL of the HTTP index - */ - readonly attribute string BaseURL; - - /** - * The RDF datasource that contains the HTTP index information. - */ - readonly attribute nsIRDFDataSource DataSource; - - /** - * The charset to use for decoding FTP filenames - */ - attribute string encoding; -}; - -%{C++ - -// {{2587e382-1324-11d4-a652-eadbb2be3484} -#define NS_HTTPINDEX_SERVICE_CID \ -{ 0x2587e382, 0x1324, 0x11d4, { 0xa6, 0x52, 0xea, 0xdb, 0xb2, 0xbe, 0x34, 0x84 } } - -#define NS_HTTPINDEX_SERVICE_CONTRACTID \ - "@mozilla.org/browser/httpindex-service;1" - -#define NS_HTTPINDEX_DATASOURCE_CONTRACTID \ - "@mozilla.org/rdf/datasource;1?name=httpindex" - -%} diff --git a/xpfe/components/moz.build b/xpfe/components/moz.build deleted file mode 100644 index d85bd09e2750..000000000000 --- a/xpfe/components/moz.build +++ /dev/null @@ -1,14 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -with Files("**"): - BUG_COMPONENT = ("Core", "Window Management") - -DIRS += [ - 'directory', - 'build', -] - From d977920517a1e73ff4f5e045d1e7d1d33804a98b Mon Sep 17 00:00:00 2001 From: Kris Maglione Date: Sat, 28 Apr 2018 20:06:40 -0700 Subject: [PATCH 05/34] Bug 833098: Part 2 - Remove RDF service. r=hsivonen,Mossop,pike MozReview-Commit-ID: 32Nl5McAFGJ --HG-- extra : rebase_source : 16fa6bd9809078dee570ce3869436d6546c5ee8d extra : histedit_source : b577bd104042a0c5f300bc3b4e3e5dd799333c94 --- browser/components/build/nsModule.cpp | 1 - dom/bindings/Bindings.conf | 3 - dom/xul/XULDocument.h | 7 - dom/xul/nsXULCommandDispatcher.cpp | 1 - dom/xul/nsXULContentSink.cpp | 1 - dom/xul/nsXULContentUtils.cpp | 17 - dom/xul/nsXULContentUtils.h | 11 - layout/build/nsLayoutStatics.cpp | 10 - rdf/base/moz.build | 59 - rdf/base/nsCompositeDataSource.cpp | 1357 ------------ rdf/base/nsContainerEnumerator.cpp | 262 --- rdf/base/nsDefaultResourceFactory.cpp | 30 - rdf/base/nsIRDFCompositeDataSource.idl | 68 - rdf/base/nsIRDFContainer.idl | 94 - rdf/base/nsIRDFContainerUtils.idl | 82 - rdf/base/nsIRDFContentSink.h | 57 - rdf/base/nsIRDFDataSource.idl | 181 -- rdf/base/nsIRDFDelegateFactory.idl | 40 - rdf/base/nsIRDFInMemoryDataSource.idl | 14 - rdf/base/nsIRDFInferDataSource.idl | 28 - rdf/base/nsIRDFLiteral.idl | 68 - rdf/base/nsIRDFNode.idl | 15 - rdf/base/nsIRDFObserver.idl | 94 - rdf/base/nsIRDFPropagatableDataSource.idl | 27 - rdf/base/nsIRDFPurgeableDataSource.idl | 19 - rdf/base/nsIRDFRemoteDataSource.idl | 44 - rdf/base/nsIRDFResource.idl | 81 - rdf/base/nsIRDFService.idl | 146 -- rdf/base/nsIRDFXMLParser.idl | 33 - rdf/base/nsIRDFXMLSerializer.idl | 31 - rdf/base/nsIRDFXMLSink.idl | 133 -- rdf/base/nsIRDFXMLSource.idl | 20 - rdf/base/nsInMemoryDataSource.cpp | 1938 ----------------- rdf/base/nsNameSpaceMap.cpp | 64 - rdf/base/nsNameSpaceMap.h | 98 - rdf/base/nsRDFBaseDataSources.h | 32 - rdf/base/nsRDFContainer.cpp | 724 ------ rdf/base/nsRDFContainerUtils.cpp | 513 ----- rdf/base/nsRDFContentSink.cpp | 1444 ------------ rdf/base/nsRDFResource.cpp | 220 -- rdf/base/nsRDFResource.h | 59 - rdf/base/nsRDFService.cpp | 1540 ------------- rdf/base/nsRDFService.h | 66 - rdf/base/nsRDFXMLDataSource.cpp | 1173 ---------- rdf/base/nsRDFXMLParser.cpp | 137 -- rdf/base/nsRDFXMLParser.h | 31 - rdf/base/nsRDFXMLSerializer.cpp | 1123 ---------- rdf/base/nsRDFXMLSerializer.h | 117 - rdf/base/rdf.h | 57 - rdf/base/rdfIDataSource.idl | 38 - rdf/base/rdfITripleVisitor.idl | 31 - rdf/base/rdfutil.cpp | 110 - rdf/base/rdfutil.h | 38 - rdf/build/moz.build | 20 - rdf/build/nsRDFCID.h | 76 - rdf/build/nsRDFModule.cpp | 120 - rdf/datasource/moz.build | 21 - rdf/datasource/nsILocalStore.h | 34 - rdf/datasource/nsIRDFFTP.h | 33 - rdf/datasource/nsLocalStore.cpp | 474 ---- rdf/datasource/nsRDFBuiltInDataSources.h | 27 - rdf/moz.build | 12 - rdf/tests/moz.build | 7 - rdf/tests/unit/sample.rdf | 9 - rdf/tests/unit/test_rdfredirect.js | 92 - rdf/tests/unit/xpcshell.ini | 5 - .../components/build/nsToolkitCompsModule.cpp | 1 - toolkit/toolkit.mozbuild | 4 - 68 files changed, 13522 deletions(-) delete mode 100644 rdf/base/moz.build delete mode 100644 rdf/base/nsCompositeDataSource.cpp delete mode 100644 rdf/base/nsContainerEnumerator.cpp delete mode 100644 rdf/base/nsDefaultResourceFactory.cpp delete mode 100644 rdf/base/nsIRDFCompositeDataSource.idl delete mode 100644 rdf/base/nsIRDFContainer.idl delete mode 100644 rdf/base/nsIRDFContainerUtils.idl delete mode 100644 rdf/base/nsIRDFContentSink.h delete mode 100644 rdf/base/nsIRDFDataSource.idl delete mode 100644 rdf/base/nsIRDFDelegateFactory.idl delete mode 100644 rdf/base/nsIRDFInMemoryDataSource.idl delete mode 100644 rdf/base/nsIRDFInferDataSource.idl delete mode 100644 rdf/base/nsIRDFLiteral.idl delete mode 100644 rdf/base/nsIRDFNode.idl delete mode 100644 rdf/base/nsIRDFObserver.idl delete mode 100644 rdf/base/nsIRDFPropagatableDataSource.idl delete mode 100644 rdf/base/nsIRDFPurgeableDataSource.idl delete mode 100644 rdf/base/nsIRDFRemoteDataSource.idl delete mode 100644 rdf/base/nsIRDFResource.idl delete mode 100644 rdf/base/nsIRDFService.idl delete mode 100644 rdf/base/nsIRDFXMLParser.idl delete mode 100644 rdf/base/nsIRDFXMLSerializer.idl delete mode 100644 rdf/base/nsIRDFXMLSink.idl delete mode 100644 rdf/base/nsIRDFXMLSource.idl delete mode 100644 rdf/base/nsInMemoryDataSource.cpp delete mode 100644 rdf/base/nsNameSpaceMap.cpp delete mode 100644 rdf/base/nsNameSpaceMap.h delete mode 100644 rdf/base/nsRDFBaseDataSources.h delete mode 100644 rdf/base/nsRDFContainer.cpp delete mode 100644 rdf/base/nsRDFContainerUtils.cpp delete mode 100644 rdf/base/nsRDFContentSink.cpp delete mode 100644 rdf/base/nsRDFResource.cpp delete mode 100644 rdf/base/nsRDFResource.h delete mode 100644 rdf/base/nsRDFService.cpp delete mode 100644 rdf/base/nsRDFService.h delete mode 100644 rdf/base/nsRDFXMLDataSource.cpp delete mode 100644 rdf/base/nsRDFXMLParser.cpp delete mode 100644 rdf/base/nsRDFXMLParser.h delete mode 100644 rdf/base/nsRDFXMLSerializer.cpp delete mode 100644 rdf/base/nsRDFXMLSerializer.h delete mode 100644 rdf/base/rdf.h delete mode 100644 rdf/base/rdfIDataSource.idl delete mode 100644 rdf/base/rdfITripleVisitor.idl delete mode 100644 rdf/base/rdfutil.cpp delete mode 100644 rdf/base/rdfutil.h delete mode 100644 rdf/build/moz.build delete mode 100644 rdf/build/nsRDFCID.h delete mode 100644 rdf/build/nsRDFModule.cpp delete mode 100644 rdf/datasource/moz.build delete mode 100644 rdf/datasource/nsILocalStore.h delete mode 100644 rdf/datasource/nsIRDFFTP.h delete mode 100644 rdf/datasource/nsLocalStore.cpp delete mode 100644 rdf/datasource/nsRDFBuiltInDataSources.h delete mode 100644 rdf/moz.build delete mode 100644 rdf/tests/moz.build delete mode 100755 rdf/tests/unit/sample.rdf delete mode 100644 rdf/tests/unit/test_rdfredirect.js delete mode 100644 rdf/tests/unit/xpcshell.ini diff --git a/browser/components/build/nsModule.cpp b/browser/components/build/nsModule.cpp index 167efa4020c2..662321f3ff75 100644 --- a/browser/components/build/nsModule.cpp +++ b/browser/components/build/nsModule.cpp @@ -20,7 +20,6 @@ #include "nsIEHistoryEnumerator.h" #endif -#include "rdf.h" #include "nsFeedSniffer.h" #include "AboutRedirector.h" #include "nsIAboutModule.h" diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index 242c2d5ce0c7..33285168b49c 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -1707,9 +1707,6 @@ addExternalIface('LoadInfo', nativeType='nsILoadInfo', addExternalIface('MenuBuilder', nativeType='nsIMenuBuilder', notflattened=True) addExternalIface('XULControllers', nativeType='nsIControllers', notflattened=True) addExternalIface('MozObserver', nativeType='nsIObserver', notflattened=True) -addExternalIface('MozRDFCompositeDataSource', nativeType='nsIRDFCompositeDataSource', - notflattened=True) -addExternalIface('MozRDFResource', nativeType='nsIRDFResource', notflattened=True) addExternalIface('MozTreeView', nativeType='nsITreeView', headerFile='nsITreeView.h', notflattened=True) addExternalIface('MozWakeLockListener', headerFile='nsIDOMWakeLockListener.h') diff --git a/dom/xul/XULDocument.h b/dom/xul/XULDocument.h index 9f497fe72414..3b4b0ffd222e 100644 --- a/dom/xul/XULDocument.h +++ b/dom/xul/XULDocument.h @@ -29,8 +29,6 @@ #include "js/TracingAPI.h" #include "js/TypeDecls.h" -class nsIRDFResource; -class nsIRDFService; class nsPIWindowRoot; class nsXULPrototypeElement; #if 0 // XXXbe save me, scc (need NSCAP_FORWARD_DECL(nsXULPrototypeScript)) @@ -254,11 +252,6 @@ protected: // pseudo constants static int32_t gRefCnt; - static nsIRDFService* gRDFService; - static nsIRDFResource* kNC_persist; - static nsIRDFResource* kNC_attribute; - static nsIRDFResource* kNC_value; - static LazyLogModule gXULLog; nsresult diff --git a/dom/xul/nsXULCommandDispatcher.cpp b/dom/xul/nsXULCommandDispatcher.cpp index 55e88bfde5fc..f2ae9a9a4fe0 100644 --- a/dom/xul/nsXULCommandDispatcher.cpp +++ b/dom/xul/nsXULCommandDispatcher.cpp @@ -21,7 +21,6 @@ #include "nsIScriptGlobalObject.h" #include "nsPIDOMWindow.h" #include "nsPIWindowRoot.h" -#include "nsRDFCID.h" #include "nsXULCommandDispatcher.h" #include "mozilla/Logging.h" #include "nsContentUtils.h" diff --git a/dom/xul/nsXULContentSink.cpp b/dom/xul/nsXULContentSink.cpp index 36cbbfa20867..d4354fd44fe2 100644 --- a/dom/xul/nsXULContentSink.cpp +++ b/dom/xul/nsXULContentSink.cpp @@ -34,7 +34,6 @@ #include "nsIScriptSecurityManager.h" #include "nsLayoutCID.h" #include "nsNetUtil.h" -#include "nsRDFCID.h" #include "nsString.h" #include "nsReadableUtils.h" #include "nsXULElement.h" diff --git a/dom/xul/nsXULContentUtils.cpp b/dom/xul/nsXULContentUtils.cpp index 1680447da9fb..3f18d500c9f4 100644 --- a/dom/xul/nsXULContentUtils.cpp +++ b/dom/xul/nsXULContentUtils.cpp @@ -19,11 +19,9 @@ #include "nsICollation.h" #include "nsIDocument.h" #include "nsIDOMXULCommandDispatcher.h" -#include "nsIRDFService.h" #include "nsIServiceManager.h" #include "nsXULContentUtils.h" #include "nsLayoutCID.h" -#include "nsRDFCID.h" #include "nsString.h" #include "nsGkAtoms.h" #include "XULDocument.h" @@ -33,30 +31,15 @@ using dom::XULDocument; //------------------------------------------------------------------------ -nsIRDFService* nsXULContentUtils::gRDF; nsICollation *nsXULContentUtils::gCollation; //------------------------------------------------------------------------ // Constructors n' stuff // -nsresult -nsXULContentUtils::Init() -{ - static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); - nsresult rv = CallGetService(kRDFServiceCID, &gRDF); - if (NS_FAILED(rv)) { - return rv; - } - - return NS_OK; -} - - nsresult nsXULContentUtils::Finish() { - NS_IF_RELEASE(gRDF); NS_IF_RELEASE(gCollation); return NS_OK; diff --git a/dom/xul/nsXULContentUtils.h b/dom/xul/nsXULContentUtils.h index 00b080cb4f30..2635d9df2cd9 100644 --- a/dom/xul/nsXULContentUtils.h +++ b/dom/xul/nsXULContentUtils.h @@ -18,7 +18,6 @@ class nsAtom; class nsICollation; class nsIContent; class nsIDocument; -class nsIRDFService; namespace mozilla { namespace dom { @@ -29,7 +28,6 @@ class Element; class nsXULContentUtils { protected: - static nsIRDFService* gRDF; static nsICollation *gCollation; static bool gDisableXULCache; @@ -38,9 +36,6 @@ protected: DisableXULCacheChangedCallback(const char* aPrefName, void* aClosure); public: - static nsresult - Init(); - static nsresult Finish(); @@ -53,12 +48,6 @@ public: static nsresult SetCommandUpdater(nsIDocument* aDocument, mozilla::dom::Element* aElement); - static nsIRDFService* - RDFService() - { - return gRDF; - } - static nsICollation* GetCollation(); }; diff --git a/layout/build/nsLayoutStatics.cpp b/layout/build/nsLayoutStatics.cpp index 1c52452e6d71..80a42627f203 100644 --- a/layout/build/nsLayoutStatics.cpp +++ b/layout/build/nsLayoutStatics.cpp @@ -49,7 +49,6 @@ #include "nsHTMLDNSPrefetch.h" #include "nsHtml5Module.h" #include "nsHTMLTags.h" -#include "nsIRDFContentSink.h" // for RDF atom initialization #include "mozilla/dom/FallbackEncoding.h" #include "nsFocusManager.h" #include "nsListControlFrame.h" @@ -181,15 +180,6 @@ nsLayoutStatics::Initialize() return rv; } -#ifdef MOZ_XUL - rv = nsXULContentUtils::Init(); - if (NS_FAILED(rv)) { - NS_ERROR("Could not initialize nsXULContentUtils"); - return rv; - } - -#endif - nsMathMLOperators::AddRefTable(); #ifdef DEBUG diff --git a/rdf/base/moz.build b/rdf/base/moz.build deleted file mode 100644 index 0411d6292463..000000000000 --- a/rdf/base/moz.build +++ /dev/null @@ -1,59 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -XPIDL_SOURCES += [ - 'nsIRDFCompositeDataSource.idl', - 'nsIRDFContainer.idl', - 'nsIRDFContainerUtils.idl', - 'nsIRDFDataSource.idl', - 'nsIRDFDelegateFactory.idl', - 'nsIRDFInferDataSource.idl', - 'nsIRDFInMemoryDataSource.idl', - 'nsIRDFLiteral.idl', - 'nsIRDFNode.idl', - 'nsIRDFObserver.idl', - 'nsIRDFPropagatableDataSource.idl', - 'nsIRDFPurgeableDataSource.idl', - 'nsIRDFRemoteDataSource.idl', - 'nsIRDFResource.idl', - 'nsIRDFService.idl', - 'nsIRDFXMLParser.idl', - 'nsIRDFXMLSerializer.idl', - 'nsIRDFXMLSink.idl', - 'nsIRDFXMLSource.idl', - 'rdfIDataSource.idl', - 'rdfITripleVisitor.idl', -] - -XPIDL_MODULE = 'rdf' - -EXPORTS += [ - 'nsIRDFContentSink.h', - 'nsRDFResource.h', - 'rdf.h', -] - -UNIFIED_SOURCES += [ - 'nsCompositeDataSource.cpp', - 'nsContainerEnumerator.cpp', - 'nsDefaultResourceFactory.cpp', - 'nsInMemoryDataSource.cpp', - 'nsNameSpaceMap.cpp', - 'nsRDFContainer.cpp', - 'nsRDFContainerUtils.cpp', - 'nsRDFContentSink.cpp', - 'nsRDFResource.cpp', - 'nsRDFService.cpp', - 'nsRDFXMLDataSource.cpp', - 'nsRDFXMLParser.cpp', - 'nsRDFXMLSerializer.cpp', - 'rdfutil.cpp', -] - -FINAL_LIBRARY = 'xul' - -if CONFIG['CC_TYPE'] in ('clang', 'gcc'): - CXXFLAGS += ['-Wno-error=shadow'] diff --git a/rdf/base/nsCompositeDataSource.cpp b/rdf/base/nsCompositeDataSource.cpp deleted file mode 100644 index f5c7492497b5..000000000000 --- a/rdf/base/nsCompositeDataSource.cpp +++ /dev/null @@ -1,1357 +0,0 @@ -/* -*- 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/. */ - -/* - - A simple composite data source implementation. A composit data - source is just a strategy for combining individual data sources into - a collective graph. - - - 1) A composite data source holds a sequence of data sources. The set - of data sources can be specified during creation of the - database. Data sources can also be added/deleted from a database - later. - - 2) The aggregation mechanism is based on simple super-positioning of - the graphs from the datasources. If there is a conflict (i.e., - data source A has a true arc from foo to bar while data source B - has a false arc from foo to bar), the data source that it earlier - in the sequence wins. - - The implementation below doesn't really do this and needs to be - fixed. - -*/ - -#include "xpcom-config.h" -#include "nsCOMPtr.h" -#include "nsIComponentManager.h" -#include "nsIRDFCompositeDataSource.h" -#include "nsIRDFNode.h" -#include "nsIRDFObserver.h" -#include "nsIRDFRemoteDataSource.h" -#include "nsTArray.h" -#include "nsCOMArray.h" -#include "nsArrayEnumerator.h" -#include "nsString.h" -#include "rdf.h" -#include "nsCycleCollectionParticipant.h" - -#include "nsEnumeratorUtils.h" - -#include "mozilla/Logging.h" -#include -mozilla::LazyLogModule nsRDFLog("RDF"); - -//---------------------------------------------------------------------- -// -// CompositeDataSourceImpl -// - -class CompositeEnumeratorImpl; -class CompositeArcsInOutEnumeratorImpl; -class CompositeAssertionEnumeratorImpl; - -class CompositeDataSourceImpl : public nsIRDFCompositeDataSource, - public nsIRDFObserver -{ -public: - CompositeDataSourceImpl(void); - explicit CompositeDataSourceImpl(char** dataSources); - - // nsISupports interface - NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(CompositeDataSourceImpl, - nsIRDFCompositeDataSource) - - // nsIRDFDataSource interface - NS_DECL_NSIRDFDATASOURCE - - // nsIRDFCompositeDataSource interface - NS_DECL_NSIRDFCOMPOSITEDATASOURCE - - // nsIRDFObserver interface - NS_DECL_NSIRDFOBSERVER - - bool HasAssertionN(int n, nsIRDFResource* source, - nsIRDFResource* property, - nsIRDFNode* target, - bool tv); - -protected: - nsCOMArray mObservers; - nsCOMArray mDataSources; - - bool mAllowNegativeAssertions; - bool mCoalesceDuplicateArcs; - int32_t mUpdateBatchNest; - - virtual ~CompositeDataSourceImpl() {} - - friend class CompositeEnumeratorImpl; - friend class CompositeArcsInOutEnumeratorImpl; - friend class CompositeAssertionEnumeratorImpl; -}; - -//---------------------------------------------------------------------- -// -// CompositeEnumeratorImpl -// - -class CompositeEnumeratorImpl : public nsISimpleEnumerator -{ - // nsISupports - NS_DECL_ISUPPORTS - - // nsISimpleEnumerator interface - NS_DECL_NSISIMPLEENUMERATOR - - // pure abstract methods to be overridden - virtual nsresult - GetEnumerator(nsIRDFDataSource* aDataSource, nsISimpleEnumerator** aResult) = 0; - - virtual nsresult - HasNegation(nsIRDFDataSource* aDataSource, nsIRDFNode* aNode, bool* aResult) = 0; - -protected: - CompositeEnumeratorImpl(CompositeDataSourceImpl* aCompositeDataSource, - bool aAllowNegativeAssertions, - bool aCoalesceDuplicateArcs); - - virtual ~CompositeEnumeratorImpl(); - - CompositeDataSourceImpl* mCompositeDataSource; - - nsISimpleEnumerator* mCurrent; - nsIRDFNode* mResult; - int32_t mNext; - AutoTArray, 8> mAlreadyReturned; - bool mAllowNegativeAssertions; - bool mCoalesceDuplicateArcs; -}; - - -CompositeEnumeratorImpl::CompositeEnumeratorImpl(CompositeDataSourceImpl* aCompositeDataSource, - bool aAllowNegativeAssertions, - bool aCoalesceDuplicateArcs) - : mCompositeDataSource(aCompositeDataSource), - mCurrent(nullptr), - mResult(nullptr), - mNext(0), - mAllowNegativeAssertions(aAllowNegativeAssertions), - mCoalesceDuplicateArcs(aCoalesceDuplicateArcs) -{ - NS_ADDREF(mCompositeDataSource); -} - - -CompositeEnumeratorImpl::~CompositeEnumeratorImpl(void) -{ - NS_IF_RELEASE(mCurrent); - NS_IF_RELEASE(mResult); - NS_RELEASE(mCompositeDataSource); -} - -NS_IMPL_ADDREF(CompositeEnumeratorImpl) -NS_IMPL_RELEASE(CompositeEnumeratorImpl) -NS_IMPL_QUERY_INTERFACE(CompositeEnumeratorImpl, nsISimpleEnumerator) - -NS_IMETHODIMP -CompositeEnumeratorImpl::HasMoreElements(bool* aResult) -{ - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - nsresult rv; - - // If we've already queued up a next target, then yep, there are - // more elements. - if (mResult) { - *aResult = true; - return NS_OK; - } - - // Otherwise, we'll need to find a next target, switching cursors - // if necessary. - for ( ; mNext < mCompositeDataSource->mDataSources.Count(); ++mNext) { - if (! mCurrent) { - // We don't have a current enumerator, so create a new one on - // the next data source. - nsIRDFDataSource* datasource = - mCompositeDataSource->mDataSources[mNext]; - - rv = GetEnumerator(datasource, &mCurrent); - if (NS_FAILED(rv)) return rv; - if (rv == NS_RDF_NO_VALUE) - continue; - - NS_ASSERTION(mCurrent != nullptr, "you're always supposed to return an enumerator from GetEnumerator, punk."); - if (! mCurrent) - continue; - } - - do { - int32_t i; - - bool hasMore; - rv = mCurrent->HasMoreElements(&hasMore); - if (NS_FAILED(rv)) return rv; - - // Is the current enumerator depleted? - if (! hasMore) { - NS_RELEASE(mCurrent); - break; - } - - // Even if the current enumerator has more elements, we still - // need to check that the current element isn't masked by - // a negation in an earlier data source. - - // "Peek" ahead and pull out the next target. - nsCOMPtr result; - rv = mCurrent->GetNext(getter_AddRefs(result)); - if (NS_FAILED(rv)) return rv; - - rv = result->QueryInterface(NS_GET_IID(nsIRDFNode), (void**) &mResult); - if (NS_FAILED(rv)) return rv; - - if (mAllowNegativeAssertions) - { - // See if any previous data source negates this - bool hasNegation = false; - for (i = mNext - 1; i >= 0; --i) - { - nsIRDFDataSource* datasource = - mCompositeDataSource->mDataSources[i]; - - rv = HasNegation(datasource, mResult, &hasNegation); - if (NS_FAILED(rv)) return rv; - - if (hasNegation) - break; - } - - // if so, we've gotta keep looking - if (hasNegation) - { - NS_RELEASE(mResult); - continue; - } - } - - if (mCoalesceDuplicateArcs) - { - // Now see if we've returned it once already. - // XXX N.B. performance here...may want to hash if things get large? - bool alreadyReturned = false; - for (i = mAlreadyReturned.Length() - 1; i >= 0; --i) - { - if (mAlreadyReturned[i] == mResult) - { - alreadyReturned = true; - break; - } - } - if (alreadyReturned) - { - NS_RELEASE(mResult); - continue; - } - } - - // If we get here, then we've really found one. It'll - // remain cached in mResult until GetNext() sucks it out. - *aResult = true; - - // Remember that we returned it, so we don't return duplicates. - - // XXX I wonder if we should make unique-checking be - // optional. This could get to be pretty expensive (this - // implementation turns iteration into O(n^2)). - - if (mCoalesceDuplicateArcs) - { - mAlreadyReturned.AppendElement(mResult); - } - - return NS_OK; - } while (1); - } - - // if we get here, there aren't any elements left. - *aResult = false; - return NS_OK; -} - - -NS_IMETHODIMP -CompositeEnumeratorImpl::GetNext(nsISupports** aResult) -{ - nsresult rv; - - bool hasMore; - rv = HasMoreElements(&hasMore); - if (NS_FAILED(rv)) return rv; - - if (! hasMore) - return NS_ERROR_UNEXPECTED; - - // Don't AddRef: we "transfer" ownership to the caller - *aResult = mResult; - mResult = nullptr; - - return NS_OK; -} - -//---------------------------------------------------------------------- -// -// CompositeArcsInOutEnumeratorImpl -// -// - -class CompositeArcsInOutEnumeratorImpl : public CompositeEnumeratorImpl -{ -public: - enum Type { eArcsIn, eArcsOut }; - - virtual ~CompositeArcsInOutEnumeratorImpl(); - - virtual nsresult - GetEnumerator(nsIRDFDataSource* aDataSource, nsISimpleEnumerator** aResult) override; - - virtual nsresult - HasNegation(nsIRDFDataSource* aDataSource, nsIRDFNode* aNode, bool* aResult) override; - - CompositeArcsInOutEnumeratorImpl(CompositeDataSourceImpl* aCompositeDataSource, - nsIRDFNode* aNode, - Type aType, - bool aAllowNegativeAssertions, - bool aCoalesceDuplicateArcs); - -private: - nsIRDFNode* mNode; - Type mType; -}; - - -CompositeArcsInOutEnumeratorImpl::CompositeArcsInOutEnumeratorImpl( - CompositeDataSourceImpl* aCompositeDataSource, - nsIRDFNode* aNode, - Type aType, - bool aAllowNegativeAssertions, - bool aCoalesceDuplicateArcs) - : CompositeEnumeratorImpl(aCompositeDataSource, aAllowNegativeAssertions, aCoalesceDuplicateArcs), - mNode(aNode), - mType(aType) -{ - NS_ADDREF(mNode); -} - -CompositeArcsInOutEnumeratorImpl::~CompositeArcsInOutEnumeratorImpl() -{ - NS_RELEASE(mNode); -} - - -nsresult -CompositeArcsInOutEnumeratorImpl::GetEnumerator( - nsIRDFDataSource* aDataSource, - nsISimpleEnumerator** aResult) -{ - if (mType == eArcsIn) { - return aDataSource->ArcLabelsIn(mNode, aResult); - } - else { - nsCOMPtr resource( do_QueryInterface(mNode) ); - return aDataSource->ArcLabelsOut(resource, aResult); - } -} - -nsresult -CompositeArcsInOutEnumeratorImpl::HasNegation( - nsIRDFDataSource* aDataSource, - nsIRDFNode* aNode, - bool* aResult) -{ - *aResult = false; - return NS_OK; -} - - -//---------------------------------------------------------------------- -// -// CompositeAssertionEnumeratorImpl -// - -class CompositeAssertionEnumeratorImpl : public CompositeEnumeratorImpl -{ -public: - virtual nsresult - GetEnumerator(nsIRDFDataSource* aDataSource, nsISimpleEnumerator** aResult) override; - - virtual nsresult - HasNegation(nsIRDFDataSource* aDataSource, nsIRDFNode* aNode, bool* aResult) override; - - CompositeAssertionEnumeratorImpl(CompositeDataSourceImpl* aCompositeDataSource, - nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue, - bool aAllowNegativeAssertions, - bool aCoalesceDuplicateArcs); - - virtual ~CompositeAssertionEnumeratorImpl(); - -private: - nsIRDFResource* mSource; - nsIRDFResource* mProperty; - nsIRDFNode* mTarget; - bool mTruthValue; -}; - - -CompositeAssertionEnumeratorImpl::CompositeAssertionEnumeratorImpl( - CompositeDataSourceImpl* aCompositeDataSource, - nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue, - bool aAllowNegativeAssertions, - bool aCoalesceDuplicateArcs) - : CompositeEnumeratorImpl(aCompositeDataSource, aAllowNegativeAssertions, aCoalesceDuplicateArcs), - mSource(aSource), - mProperty(aProperty), - mTarget(aTarget), - mTruthValue(aTruthValue) -{ - NS_IF_ADDREF(mSource); - NS_ADDREF(mProperty); // always must be specified - NS_IF_ADDREF(mTarget); -} - -CompositeAssertionEnumeratorImpl::~CompositeAssertionEnumeratorImpl() -{ - NS_IF_RELEASE(mSource); - NS_RELEASE(mProperty); - NS_IF_RELEASE(mTarget); -} - - -nsresult -CompositeAssertionEnumeratorImpl::GetEnumerator( - nsIRDFDataSource* aDataSource, - nsISimpleEnumerator** aResult) -{ - if (mSource) { - return aDataSource->GetTargets(mSource, mProperty, mTruthValue, aResult); - } - else { - return aDataSource->GetSources(mProperty, mTarget, mTruthValue, aResult); - } -} - -nsresult -CompositeAssertionEnumeratorImpl::HasNegation( - nsIRDFDataSource* aDataSource, - nsIRDFNode* aNode, - bool* aResult) -{ - if (mSource) { - return aDataSource->HasAssertion(mSource, mProperty, aNode, !mTruthValue, aResult); - } - else { - nsCOMPtr source( do_QueryInterface(aNode) ); - return aDataSource->HasAssertion(source, mProperty, mTarget, !mTruthValue, aResult); - } -} - -//////////////////////////////////////////////////////////////////////// - -nsresult -NS_NewRDFCompositeDataSource(nsIRDFCompositeDataSource** result) -{ - CompositeDataSourceImpl* db = new CompositeDataSourceImpl(); - if (! db) - return NS_ERROR_OUT_OF_MEMORY; - - *result = db; - NS_ADDREF(*result); - return NS_OK; -} - - -CompositeDataSourceImpl::CompositeDataSourceImpl(void) - : mAllowNegativeAssertions(true), - mCoalesceDuplicateArcs(true), - mUpdateBatchNest(0) -{ -} - -//---------------------------------------------------------------------- -// -// nsISupports interface -// - -NS_IMPL_CYCLE_COLLECTION_CLASS(CompositeDataSourceImpl) - -NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CompositeDataSourceImpl) - uint32_t i, count = tmp->mDataSources.Count(); - for (i = count; i > 0; --i) { - tmp->mDataSources[i - 1]->RemoveObserver(tmp); - tmp->mDataSources.RemoveObjectAt(i - 1); - } - NS_IMPL_CYCLE_COLLECTION_UNLINK(mObservers); -NS_IMPL_CYCLE_COLLECTION_UNLINK_END -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(CompositeDataSourceImpl) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mObservers) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDataSources) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END - - -NS_IMPL_CYCLE_COLLECTING_ADDREF(CompositeDataSourceImpl) -NS_IMPL_CYCLE_COLLECTING_RELEASE(CompositeDataSourceImpl) - -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CompositeDataSourceImpl) - NS_INTERFACE_MAP_ENTRY(nsIRDFCompositeDataSource) - NS_INTERFACE_MAP_ENTRY(nsIRDFDataSource) - NS_INTERFACE_MAP_ENTRY(nsIRDFObserver) - NS_INTERFACE_MAP_ENTRY(nsIRDFCompositeDataSource) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRDFCompositeDataSource) -NS_INTERFACE_MAP_END - - -//---------------------------------------------------------------------- -// -// nsIRDFDataSource interface -// - -NS_IMETHODIMP -CompositeDataSourceImpl::GetURI(nsACString& aURI) -{ - aURI.SetIsVoid(true); - return NS_OK; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::GetSource(nsIRDFResource* property, - nsIRDFNode* target, - bool tv, - nsIRDFResource** source) -{ - if (!mAllowNegativeAssertions && !tv) - return(NS_RDF_NO_VALUE); - - int32_t count = mDataSources.Count(); - for (int32_t i = 0; i < count; ++i) { - nsresult rv; - rv = mDataSources[i]->GetSource(property, target, tv, source); - if (NS_FAILED(rv)) return rv; - - if (rv == NS_RDF_NO_VALUE) - continue; - - if (!mAllowNegativeAssertions) return(NS_OK); - - // okay, found it. make sure we don't have the opposite - // asserted in a more local data source - if (!HasAssertionN(count-1, *source, property, target, !tv)) - return NS_OK; - - NS_RELEASE(*source); - return NS_RDF_NO_VALUE; - } - return NS_RDF_NO_VALUE; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::GetSources(nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue, - nsISimpleEnumerator** aResult) -{ - NS_PRECONDITION(aProperty != nullptr, "null ptr"); - if (! aProperty) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aTarget != nullptr, "null ptr"); - if (! aTarget) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - if (! mAllowNegativeAssertions && ! aTruthValue) - return(NS_RDF_NO_VALUE); - - *aResult = new CompositeAssertionEnumeratorImpl(this, nullptr, aProperty, - aTarget, aTruthValue, - mAllowNegativeAssertions, - mCoalesceDuplicateArcs); - - if (! *aResult) - return NS_ERROR_OUT_OF_MEMORY; - - NS_ADDREF(*aResult); - return NS_OK; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::GetTarget(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - bool aTruthValue, - nsIRDFNode** aResult) -{ - NS_PRECONDITION(aSource != nullptr, "null ptr"); - if (! aSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aProperty != nullptr, "null ptr"); - if (! aProperty) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - if (! mAllowNegativeAssertions && ! aTruthValue) - return(NS_RDF_NO_VALUE); - - int32_t count = mDataSources.Count(); - for (int32_t i = 0; i < count; ++i) { - nsresult rv; - rv = mDataSources[i]->GetTarget(aSource, aProperty, aTruthValue, - aResult); - if (NS_FAILED(rv)) - return rv; - - if (rv == NS_OK) { - // okay, found it. make sure we don't have the opposite - // asserted in an earlier data source - - if (mAllowNegativeAssertions) { - if (HasAssertionN(count-1, aSource, aProperty, *aResult, !aTruthValue)) { - // whoops, it's been negated. - NS_RELEASE(*aResult); - return NS_RDF_NO_VALUE; - } - } - return NS_OK; - } - } - - // Otherwise, we couldn't find it at all. - return NS_RDF_NO_VALUE; -} - -bool -CompositeDataSourceImpl::HasAssertionN(int n, - nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue) -{ - nsresult rv; - for (int32_t m = 0; m < n; ++m) { - bool result; - rv = mDataSources[m]->HasAssertion(aSource, aProperty, aTarget, - aTruthValue, &result); - if (NS_FAILED(rv)) - return false; - - // found it! - if (result) - return true; - } - return false; -} - - - -NS_IMETHODIMP -CompositeDataSourceImpl::GetTargets(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - bool aTruthValue, - nsISimpleEnumerator** aResult) -{ - NS_PRECONDITION(aSource != nullptr, "null ptr"); - if (! aSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aProperty != nullptr, "null ptr"); - if (! aProperty) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - if (! mAllowNegativeAssertions && ! aTruthValue) - return(NS_RDF_NO_VALUE); - - *aResult = - new CompositeAssertionEnumeratorImpl(this, - aSource, aProperty, nullptr, - aTruthValue, - mAllowNegativeAssertions, - mCoalesceDuplicateArcs); - - if (! *aResult) - return NS_ERROR_OUT_OF_MEMORY; - - NS_ADDREF(*aResult); - return NS_OK; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::Assert(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue) -{ - NS_PRECONDITION(aSource != nullptr, "null ptr"); - if (! aSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aProperty != nullptr, "null ptr"); - if (! aProperty) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aTarget != nullptr, "null ptr"); - if (! aTarget) - return NS_ERROR_NULL_POINTER; - - if (! mAllowNegativeAssertions && ! aTruthValue) - return(NS_RDF_ASSERTION_REJECTED); - - nsresult rv; - - // XXX Need to add back the stuff for unblocking ... - - // We iterate backwards from the last data source which was added - // ("the most remote") to the first ("the most local"), trying to - // apply the assertion in each. - for (int32_t i = mDataSources.Count() - 1; i >= 0; --i) { - rv = mDataSources[i]->Assert(aSource, aProperty, aTarget, aTruthValue); - if (NS_RDF_ASSERTION_ACCEPTED == rv) - return rv; - - if (NS_FAILED(rv)) - return rv; - } - - // nobody wanted to accept it - return NS_RDF_ASSERTION_REJECTED; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::Unassert(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget) -{ - NS_PRECONDITION(aSource != nullptr, "null ptr"); - if (! aSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aProperty != nullptr, "null ptr"); - if (! aProperty) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aTarget != nullptr, "null ptr"); - if (! aTarget) - return NS_ERROR_NULL_POINTER; - - nsresult rv; - - // Iterate through each of the datasources, starting with "the - // most local" and moving to "the most remote". If _any_ of the - // datasources have the assertion, attempt to unassert it. - bool unasserted = true; - int32_t i; - int32_t count = mDataSources.Count(); - for (i = 0; i < count; ++i) { - nsIRDFDataSource* ds = mDataSources[i]; - - bool hasAssertion; - rv = ds->HasAssertion(aSource, aProperty, aTarget, true, &hasAssertion); - if (NS_FAILED(rv)) return rv; - - if (hasAssertion) { - rv = ds->Unassert(aSource, aProperty, aTarget); - if (NS_FAILED(rv)) return rv; - - if (rv != NS_RDF_ASSERTION_ACCEPTED) { - unasserted = false; - break; - } - } - } - - // Either none of the datasources had it, or they were all willing - // to let it be unasserted. - if (unasserted) - return NS_RDF_ASSERTION_ACCEPTED; - - // If we get here, one of the datasources already had the - // assertion, and was adamant about not letting us remove - // it. Iterate from the "most local" to the "most remote" - // attempting to assert the negation... - for (i = 0; i < count; ++i) { - rv = mDataSources[i]->Assert(aSource, aProperty, aTarget, false); - if (NS_FAILED(rv)) return rv; - - // Did it take? - if (rv == NS_RDF_ASSERTION_ACCEPTED) - return rv; - } - - // Couln't get anyone to accept the negation, either. - return NS_RDF_ASSERTION_REJECTED; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::Change(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aOldTarget, - nsIRDFNode* aNewTarget) -{ - NS_PRECONDITION(aSource != nullptr, "null ptr"); - if (! aSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aProperty != nullptr, "null ptr"); - if (! aProperty) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aOldTarget != nullptr, "null ptr"); - if (! aOldTarget) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aNewTarget != nullptr, "null ptr"); - if (! aNewTarget) - return NS_ERROR_NULL_POINTER; - - nsresult rv; - - // XXX So we're assuming that a datasource _must_ accept the - // atomic change; i.e., we can't split it up across two - // datasources. That sucks. - - // We iterate backwards from the last data source which was added - // ("the most remote") to the first ("the most local"), trying to - // apply the change in each. - for (int32_t i = mDataSources.Count() - 1; i >= 0; --i) { - rv = mDataSources[i]->Change(aSource, aProperty, aOldTarget, aNewTarget); - if (NS_RDF_ASSERTION_ACCEPTED == rv) - return rv; - - if (NS_FAILED(rv)) - return rv; - } - - // nobody wanted to accept it - return NS_RDF_ASSERTION_REJECTED; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::Move(nsIRDFResource* aOldSource, - nsIRDFResource* aNewSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget) -{ - NS_PRECONDITION(aOldSource != nullptr, "null ptr"); - if (! aOldSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aNewSource != nullptr, "null ptr"); - if (! aNewSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aProperty != nullptr, "null ptr"); - if (! aProperty) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aTarget != nullptr, "null ptr"); - if (! aTarget) - return NS_ERROR_NULL_POINTER; - - nsresult rv; - - // XXX So we're assuming that a datasource _must_ accept the - // atomic move; i.e., we can't split it up across two - // datasources. That sucks. - - // We iterate backwards from the last data source which was added - // ("the most remote") to the first ("the most local"), trying to - // apply the assertion in each. - for (int32_t i = mDataSources.Count() - 1; i >= 0; --i) { - rv = mDataSources[i]->Move(aOldSource, aNewSource, aProperty, aTarget); - if (NS_RDF_ASSERTION_ACCEPTED == rv) - return rv; - - if (NS_FAILED(rv)) - return rv; - } - - // nobody wanted to accept it - return NS_RDF_ASSERTION_REJECTED; -} - - -NS_IMETHODIMP -CompositeDataSourceImpl::HasAssertion(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue, - bool* aResult) -{ - NS_PRECONDITION(aSource != nullptr, "null ptr"); - if (! aSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aProperty != nullptr, "null ptr"); - if (! aProperty) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - if (! mAllowNegativeAssertions && ! aTruthValue) - { - *aResult = false; - return(NS_OK); - } - - nsresult rv; - - // Otherwise, look through all the data sources to see if anyone - // has the positive... - int32_t count = mDataSources.Count(); - for (int32_t i = 0; i < count; ++i) { - nsIRDFDataSource* datasource = mDataSources[i]; - rv = datasource->HasAssertion(aSource, aProperty, aTarget, aTruthValue, aResult); - if (NS_FAILED(rv)) return rv; - - if (*aResult) - return NS_OK; - - if (mAllowNegativeAssertions) - { - bool hasNegation; - rv = datasource->HasAssertion(aSource, aProperty, aTarget, !aTruthValue, &hasNegation); - if (NS_FAILED(rv)) return rv; - - if (hasNegation) - { - *aResult = false; - return NS_OK; - } - } - } - - // If we get here, nobody had the assertion at all - *aResult = false; - return NS_OK; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::AddObserver(nsIRDFObserver* aObserver) -{ - NS_PRECONDITION(aObserver != nullptr, "null ptr"); - if (! aObserver) - return NS_ERROR_NULL_POINTER; - - // XXX ensure uniqueness? - mObservers.AppendObject(aObserver); - - return NS_OK; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::RemoveObserver(nsIRDFObserver* aObserver) -{ - NS_PRECONDITION(aObserver != nullptr, "null ptr"); - if (! aObserver) - return NS_ERROR_NULL_POINTER; - - mObservers.RemoveObject(aObserver); - - return NS_OK; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::HasArcIn(nsIRDFNode *aNode, nsIRDFResource *aArc, bool *result) -{ - nsresult rv; - *result = false; - int32_t count = mDataSources.Count(); - for (int32_t i = 0; i < count; ++i) { - rv = mDataSources[i]->HasArcIn(aNode, aArc, result); - if (NS_FAILED(rv)) return rv; - if (*result) - return NS_OK; - } - return NS_OK; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::HasArcOut(nsIRDFResource *aSource, nsIRDFResource *aArc, bool *result) -{ - nsresult rv; - *result = false; - int32_t count = mDataSources.Count(); - for (int32_t i = 0; i < count; ++i) { - rv = mDataSources[i]->HasArcOut(aSource, aArc, result); - if (NS_FAILED(rv)) return rv; - if (*result) - return NS_OK; - } - return NS_OK; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::ArcLabelsIn(nsIRDFNode* aTarget, nsISimpleEnumerator** aResult) -{ - NS_PRECONDITION(aTarget != nullptr, "null ptr"); - if (! aTarget) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - nsISimpleEnumerator* result = - new CompositeArcsInOutEnumeratorImpl(this, aTarget, - CompositeArcsInOutEnumeratorImpl::eArcsIn, - mAllowNegativeAssertions, - mCoalesceDuplicateArcs); - - if (! result) - return NS_ERROR_OUT_OF_MEMORY; - - NS_ADDREF(result); - *aResult = result; - return NS_OK; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::ArcLabelsOut(nsIRDFResource* aSource, - nsISimpleEnumerator** aResult) -{ - NS_PRECONDITION(aSource != nullptr, "null ptr"); - if (! aSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - nsISimpleEnumerator* result = - new CompositeArcsInOutEnumeratorImpl(this, aSource, - CompositeArcsInOutEnumeratorImpl::eArcsOut, - mAllowNegativeAssertions, - mCoalesceDuplicateArcs); - - if (! result) - return NS_ERROR_OUT_OF_MEMORY; - - NS_ADDREF(result); - *aResult = result; - return NS_OK; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::GetAllResources(nsISimpleEnumerator** aResult) -{ - MOZ_ASSERT_UNREACHABLE("CompositeDataSourceImpl::GetAllResources"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::GetAllCmds(nsIRDFResource* source, - nsISimpleEnumerator/**/** result) -{ - nsresult rv; - nsCOMPtr set; - - for (int32_t i = 0; i < mDataSources.Count(); i++) - { - nsCOMPtr dsCmds; - - rv = mDataSources[i]->GetAllCmds(source, getter_AddRefs(dsCmds)); - if (NS_SUCCEEDED(rv)) - { - nsCOMPtr tmp; - rv = NS_NewUnionEnumerator(getter_AddRefs(tmp), set, dsCmds); - set.swap(tmp); - if (NS_FAILED(rv)) return(rv); - } - } - - set.forget(result); - return NS_OK; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::IsCommandEnabled(nsISupports/* nsIRDFResource container */* aSources, - nsIRDFResource* aCommand, - nsISupports/* nsIRDFResource container */* aArguments, - bool* aResult) -{ - nsresult rv; - for (int32_t i = mDataSources.Count() - 1; i >= 0; --i) { - bool enabled = true; - rv = mDataSources[i]->IsCommandEnabled(aSources, aCommand, aArguments, &enabled); - if (NS_FAILED(rv) && (rv != NS_ERROR_NOT_IMPLEMENTED)) - { - return(rv); - } - - if (! enabled) { - *aResult = false; - return(NS_OK); - } - } - *aResult = true; - return(NS_OK); -} - -NS_IMETHODIMP -CompositeDataSourceImpl::DoCommand(nsISupports/* nsIRDFResource container */* aSources, - nsIRDFResource* aCommand, - nsISupports/* nsIRDFResource container */* aArguments) -{ - for (int32_t i = mDataSources.Count() - 1; i >= 0; --i) { - nsresult rv = mDataSources[i]->DoCommand(aSources, aCommand, aArguments); - if (NS_FAILED(rv) && (rv != NS_ERROR_NOT_IMPLEMENTED)) - { - return(rv); // all datasources must succeed - } - } - return(NS_OK); -} - -NS_IMETHODIMP -CompositeDataSourceImpl::BeginUpdateBatch() -{ - for (int32_t i = mDataSources.Count() - 1; i >= 0; --i) { - mDataSources[i]->BeginUpdateBatch(); - } - return NS_OK; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::EndUpdateBatch() -{ - for (int32_t i = mDataSources.Count() - 1; i >= 0; --i) { - mDataSources[i]->EndUpdateBatch(); - } - return NS_OK; -} - -//////////////////////////////////////////////////////////////////////// -// nsIRDFCompositeDataSource methods -// XXX rvg We should make this take an additional argument specifying where -// in the sequence of data sources (of the db), the new data source should -// fit in. Right now, the new datasource gets stuck at the end. -// need to add the observers of the CompositeDataSourceImpl to the new data source. - -NS_IMETHODIMP -CompositeDataSourceImpl::GetAllowNegativeAssertions(bool *aAllowNegativeAssertions) -{ - *aAllowNegativeAssertions = mAllowNegativeAssertions; - return(NS_OK); -} - -NS_IMETHODIMP -CompositeDataSourceImpl::SetAllowNegativeAssertions(bool aAllowNegativeAssertions) -{ - mAllowNegativeAssertions = aAllowNegativeAssertions; - return(NS_OK); -} - -NS_IMETHODIMP -CompositeDataSourceImpl::GetCoalesceDuplicateArcs(bool *aCoalesceDuplicateArcs) -{ - *aCoalesceDuplicateArcs = mCoalesceDuplicateArcs; - return(NS_OK); -} - -NS_IMETHODIMP -CompositeDataSourceImpl::SetCoalesceDuplicateArcs(bool aCoalesceDuplicateArcs) -{ - mCoalesceDuplicateArcs = aCoalesceDuplicateArcs; - return(NS_OK); -} - -NS_IMETHODIMP -CompositeDataSourceImpl::AddDataSource(nsIRDFDataSource* aDataSource) -{ - NS_ASSERTION(aDataSource != nullptr, "null ptr"); - if (! aDataSource) - return NS_ERROR_NULL_POINTER; - - mDataSources.AppendObject(aDataSource); - aDataSource->AddObserver(this); - return NS_OK; -} - - - -NS_IMETHODIMP -CompositeDataSourceImpl::RemoveDataSource(nsIRDFDataSource* aDataSource) -{ - NS_ASSERTION(aDataSource != nullptr, "null ptr"); - if (! aDataSource) - return NS_ERROR_NULL_POINTER; - - - if (mDataSources.IndexOf(aDataSource) >= 0) { - aDataSource->RemoveObserver(this); - mDataSources.RemoveObject(aDataSource); - } - return NS_OK; -} - - -NS_IMETHODIMP -CompositeDataSourceImpl::GetDataSources(nsISimpleEnumerator** _result) -{ - // NS_NewArrayEnumerator for an nsCOMArray takes a snapshot of the - // current state. - return NS_NewArrayEnumerator(_result, mDataSources); -} - -NS_IMETHODIMP -CompositeDataSourceImpl::OnAssert(nsIRDFDataSource* aDataSource, - nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget) -{ - // Make sure that the assertion isn't masked by another - // datasource. - // - // XXX We could make this more efficient if we knew _which_ - // datasource actually served up the OnAssert(): we could use - // HasAssertionN() to only search datasources _before_ the - // datasource that coughed up the assertion. - nsresult rv = NS_OK; - - if (mAllowNegativeAssertions) - { - bool hasAssertion; - rv = HasAssertion(aSource, aProperty, aTarget, true, &hasAssertion); - if (NS_FAILED(rv)) return rv; - - if (! hasAssertion) - return(NS_OK); - } - - for (int32_t i = mObservers.Count() - 1; i >= 0; --i) { - mObservers[i]->OnAssert(this, aSource, aProperty, aTarget); - } - return NS_OK; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::OnUnassert(nsIRDFDataSource* aDataSource, - nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget) -{ - // Make sure that the un-assertion doesn't just unmask the - // same assertion in a different datasource. - // - // XXX We could make this more efficient if we knew _which_ - // datasource actually served up the OnAssert(): we could use - // HasAssertionN() to only search datasources _before_ the - // datasource that coughed up the assertion. - nsresult rv; - - if (mAllowNegativeAssertions) - { - bool hasAssertion; - rv = HasAssertion(aSource, aProperty, aTarget, true, &hasAssertion); - if (NS_FAILED(rv)) return rv; - - if (hasAssertion) - return NS_OK; - } - - for (int32_t i = mObservers.Count() - 1; i >= 0; --i) { - mObservers[i]->OnUnassert(this, aSource, aProperty, aTarget); - } - return NS_OK; -} - - -NS_IMETHODIMP -CompositeDataSourceImpl::OnChange(nsIRDFDataSource* aDataSource, - nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aOldTarget, - nsIRDFNode* aNewTarget) -{ - // Make sure that the change is actually visible, and not hidden - // by an assertion in a different datasource. - // - // XXX Because of aggregation, this could actually mutate into a - // variety of OnAssert or OnChange notifications, which we'll - // ignore for now :-/. - for (int32_t i = mObservers.Count() - 1; i >= 0; --i) { - mObservers[i]->OnChange(this, aSource, aProperty, - aOldTarget, aNewTarget); - } - return NS_OK; -} - - -NS_IMETHODIMP -CompositeDataSourceImpl::OnMove(nsIRDFDataSource* aDataSource, - nsIRDFResource* aOldSource, - nsIRDFResource* aNewSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget) -{ - // Make sure that the move is actually visible, and not hidden - // by an assertion in a different datasource. - // - // XXX Because of aggregation, this could actually mutate into a - // variety of OnAssert or OnMove notifications, which we'll - // ignore for now :-/. - for (int32_t i = mObservers.Count() - 1; i >= 0; --i) { - mObservers[i]->OnMove(this, aOldSource, aNewSource, - aProperty, aTarget); - } - return NS_OK; -} - - -NS_IMETHODIMP -CompositeDataSourceImpl::OnBeginUpdateBatch(nsIRDFDataSource* aDataSource) -{ - if (mUpdateBatchNest++ == 0) { - for (int32_t i = mObservers.Count() - 1; i >= 0; --i) { - mObservers[i]->OnBeginUpdateBatch(this); - } - } - return NS_OK; -} - - -NS_IMETHODIMP -CompositeDataSourceImpl::OnEndUpdateBatch(nsIRDFDataSource* aDataSource) -{ - NS_ASSERTION(mUpdateBatchNest > 0, "badly nested update batch"); - if (--mUpdateBatchNest == 0) { - for (int32_t i = mObservers.Count() - 1; i >= 0; --i) { - mObservers[i]->OnEndUpdateBatch(this); - } - } - return NS_OK; -} diff --git a/rdf/base/nsContainerEnumerator.cpp b/rdf/base/nsContainerEnumerator.cpp deleted file mode 100644 index 19700a9e1c0a..000000000000 --- a/rdf/base/nsContainerEnumerator.cpp +++ /dev/null @@ -1,262 +0,0 @@ -/* -*- 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/. */ - -/* - - A simple cursor that enumerates the elements of an RDF container - (RDF:Bag, RDF:Seq, or RDF:Alt). - - Caveats - ------- - - 1. This uses an implementation-specific detail to determine the - index of the last element in the container; specifically, the RDF - utilities maintain a counter attribute on the container that - holds the numeric value of the next value that is to be - assigned. So, this cursor will bust if you use it with a bag that - hasn't been created using the RDF utility routines. - - */ - -#include "nscore.h" -#include "nsCOMPtr.h" -#include "nsIRDFContainerUtils.h" -#include "nsIRDFDataSource.h" -#include "nsIRDFNode.h" -#include "nsIRDFService.h" -#include "nsIServiceManager.h" -#include "nsRDFCID.h" -#include "nsString.h" -#include "mozilla/Logging.h" -#include "rdf.h" -#include "rdfutil.h" - -//////////////////////////////////////////////////////////////////////// - -class ContainerEnumeratorImpl : public nsISimpleEnumerator { -private: - // pseudo-constants - static nsrefcnt gRefCnt; - static nsIRDFResource* kRDF_nextVal; - static nsIRDFContainerUtils* gRDFC; - - nsCOMPtr mDataSource; - nsCOMPtr mContainer; - nsCOMPtr mOrdinalProperty; - - nsCOMPtr mCurrent; - nsCOMPtr mResult; - int32_t mNextIndex; - - virtual ~ContainerEnumeratorImpl(); - -public: - ContainerEnumeratorImpl(nsIRDFDataSource* ds, nsIRDFResource* container); - - nsresult Init(); - - NS_DECL_ISUPPORTS - NS_DECL_NSISIMPLEENUMERATOR -}; - -nsrefcnt ContainerEnumeratorImpl::gRefCnt; -nsIRDFResource* ContainerEnumeratorImpl::kRDF_nextVal; -nsIRDFContainerUtils* ContainerEnumeratorImpl::gRDFC; - - -ContainerEnumeratorImpl::ContainerEnumeratorImpl(nsIRDFDataSource* aDataSource, - nsIRDFResource* aContainer) - : mDataSource(aDataSource), - mContainer(aContainer), - mNextIndex(1) -{ -} - -nsresult -ContainerEnumeratorImpl::Init() -{ - if (gRefCnt++ == 0) { - nsresult rv; - - NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); - nsCOMPtr rdf = do_GetService(kRDFServiceCID); - NS_ASSERTION(rdf != nullptr, "unable to acquire resource manager"); - if (! rdf) - return NS_ERROR_FAILURE; - - rv = rdf->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "nextVal"), &kRDF_nextVal); - NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get resource"); - if (NS_FAILED(rv)) return rv; - - NS_DEFINE_CID(kRDFContainerUtilsCID, NS_RDFCONTAINERUTILS_CID); - rv = CallGetService(kRDFContainerUtilsCID, &gRDFC); - if (NS_FAILED(rv)) return rv; - } - - return NS_OK; -} - - -ContainerEnumeratorImpl::~ContainerEnumeratorImpl() -{ - if (--gRefCnt == 0) { - NS_IF_RELEASE(kRDF_nextVal); - NS_IF_RELEASE(gRDFC); - } -} - -NS_IMPL_ISUPPORTS(ContainerEnumeratorImpl, nsISimpleEnumerator) - - -NS_IMETHODIMP -ContainerEnumeratorImpl::HasMoreElements(bool* aResult) -{ - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - nsresult rv; - - // If we've already queued up a next value, then we know there are more elements. - if (mResult) { - *aResult = true; - return NS_OK; - } - - // Otherwise, we need to grovel - - // Figure out the upper bound so we'll know when we're done. Since it's - // possible that we're targeting a composite datasource, we'll need to - // "GetTargets()" and take the maximum value of "nextVal" to know the - // upper bound. - // - // Remember that since nextVal is the next index that we'd assign - // to an element in a container, it's *one more* than count of - // elements in the container. - int32_t max = 0; - - nsCOMPtr targets; - rv = mDataSource->GetTargets(mContainer, kRDF_nextVal, true, getter_AddRefs(targets)); - if (NS_FAILED(rv)) return rv; - - while (1) { - bool hasmore; - targets->HasMoreElements(&hasmore); - if (! hasmore) - break; - - nsCOMPtr isupports; - targets->GetNext(getter_AddRefs(isupports)); - - nsCOMPtr nextValLiteral = do_QueryInterface(isupports); - if (! nextValLiteral) - continue; - - const char16_t *nextValStr; - nextValLiteral->GetValueConst(&nextValStr); - - nsresult err; - int32_t nextVal = nsAutoString(nextValStr).ToInteger(&err); - - if (nextVal > max) - max = nextVal; - } - - // Now pre-fetch our next value into mResult. - while (mCurrent || mNextIndex < max) { - - // If mCurrent has been depleted, then conjure up a new one - if (! mCurrent) { - rv = gRDFC->IndexToOrdinalResource(mNextIndex, getter_AddRefs(mOrdinalProperty)); - if (NS_FAILED(rv)) return rv; - - rv = mDataSource->GetTargets(mContainer, mOrdinalProperty, true, getter_AddRefs(mCurrent)); - if (NS_FAILED(rv)) return rv; - - ++mNextIndex; - } - - if (mCurrent) { - bool hasMore; - rv = mCurrent->HasMoreElements(&hasMore); - if (NS_FAILED(rv)) return rv; - - // Is the current enumerator depleted? If so, iterate to - // the next index. - if (! hasMore) { - mCurrent = nullptr; - continue; - } - - // "Peek" ahead and pull out the next target. - nsCOMPtr result; - rv = mCurrent->GetNext(getter_AddRefs(result)); - if (NS_FAILED(rv)) return rv; - - mResult = do_QueryInterface(result, &rv); - if (NS_FAILED(rv)) return rv; - - *aResult = true; - return NS_OK; - } - } - - // If we get here, we ran out of elements. The cursor is empty. - *aResult = false; - return NS_OK; -} - - -NS_IMETHODIMP -ContainerEnumeratorImpl::GetNext(nsISupports** aResult) -{ - nsresult rv; - - bool hasMore; - rv = HasMoreElements(&hasMore); - if (NS_FAILED(rv)) return rv; - - if (! hasMore) - return NS_ERROR_UNEXPECTED; - - NS_ADDREF(*aResult = mResult); - mResult = nullptr; - - return NS_OK; -} - - -//////////////////////////////////////////////////////////////////////// - -nsresult -NS_NewContainerEnumerator(nsIRDFDataSource* aDataSource, - nsIRDFResource* aContainer, - nsISimpleEnumerator** aResult) -{ - NS_PRECONDITION(aDataSource != nullptr, "null ptr"); - if (! aDataSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aContainer != nullptr, "null ptr"); - if (! aContainer) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - ContainerEnumeratorImpl* result = new ContainerEnumeratorImpl(aDataSource, aContainer); - if (! result) - return NS_ERROR_OUT_OF_MEMORY; - - NS_ADDREF(result); - - nsresult rv = result->Init(); - if (NS_FAILED(rv)) - NS_RELEASE(result); - - *aResult = result; - return rv; -} diff --git a/rdf/base/nsDefaultResourceFactory.cpp b/rdf/base/nsDefaultResourceFactory.cpp deleted file mode 100644 index 448822a9d96a..000000000000 --- a/rdf/base/nsDefaultResourceFactory.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- 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/. */ - -/* - - The default resource factory implementation. This resource factory - produces nsIRDFResource objects for any URI prefix that is not - covered by some other factory. - - */ - -#include "nsRDFResource.h" - -nsresult -NS_NewDefaultResource(nsIRDFResource** aResult) -{ - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - nsRDFResource* resource = new nsRDFResource(); - if (! resource) - return NS_ERROR_OUT_OF_MEMORY; - - NS_ADDREF(resource); - *aResult = resource; - return NS_OK; -} diff --git a/rdf/base/nsIRDFCompositeDataSource.idl b/rdf/base/nsIRDFCompositeDataSource.idl deleted file mode 100644 index 071b8f3ace44..000000000000 --- a/rdf/base/nsIRDFCompositeDataSource.idl +++ /dev/null @@ -1,68 +0,0 @@ -/* -*- 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/. */ - -#include "nsIRDFDataSource.idl" - -interface nsISimpleEnumerator; - -/** - * An nsIRDFCompositeDataSource composes individual data sources, providing - * the illusion of a single, coherent RDF graph. - */ -[scriptable, uuid(96343820-307C-11D2-BC15-00805F912FE7)] -interface nsIRDFCompositeDataSource : nsIRDFDataSource { - - /** - * - * Set this value to true if the composite datasource - * may contains at least one datasource that has negative - * assertions. (This is the default.) - * - * Set this value to false if none of the datasources - * being composed contains a negative assertion. This allows the - * composite datasource to perform some query optimizations. - * - * By default, this value is true. - */ - attribute boolean allowNegativeAssertions; - - /** - * Set to true if the composite datasource should - * take care to coalesce duplicate arcs when returning values from - * queries. (This is the default.) - * - * Set to false if the composite datasource shouldn't - * bother to check for duplicates. This allows the composite - * datasource to more efficiently answer queries. - * - * By default, this value is true. - */ - attribute boolean coalesceDuplicateArcs; - - /** - * Add a datasource the the composite data source. - * @param aDataSource the datasource to add to composite - */ - void AddDataSource(in nsIRDFDataSource aDataSource); - - /** - * Remove a datasource from the composite data source. - * @param aDataSource the datasource to remove from the composite - */ - void RemoveDataSource(in nsIRDFDataSource aDataSource); - - /** - * Retrieve the datasources in the composite data source. - * @return an nsISimpleEnumerator that will enumerate each - * of the datasources in the composite - */ - nsISimpleEnumerator GetDataSources(); -}; - -%{C++ -extern nsresult -NS_NewRDFCompositeDataSource(nsIRDFCompositeDataSource** result); -%} - diff --git a/rdf/base/nsIRDFContainer.idl b/rdf/base/nsIRDFContainer.idl deleted file mode 100644 index 78352b2b3c88..000000000000 --- a/rdf/base/nsIRDFContainer.idl +++ /dev/null @@ -1,94 +0,0 @@ -/* -*- 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/. */ - -#include "nsISupports.idl" -#include "nsIRDFDataSource.idl" -#include "nsIRDFResource.idl" -#include "nsIRDFNode.idl" -#include "nsISimpleEnumerator.idl" - -// A wrapper for manipulating RDF containers -[scriptable, uuid(D4214E90-FB94-11D2-BDD8-00104BDE6048)] -interface nsIRDFContainer : nsISupports { - readonly attribute nsIRDFDataSource DataSource; - readonly attribute nsIRDFResource Resource; - - /** - * Initialize the container wrapper to the specified resource - * using the specified datasource for context. - */ - void Init(in nsIRDFDataSource aDataSource, in nsIRDFResource aContainer); - - /** - * Return the number of elements in the container. Note that this - * may not always be accurate due to aggregation. - */ - long GetCount(); - - /** - * Return an enumerator that can be used to enumerate the contents - * of the container in ascending order. - */ - nsISimpleEnumerator GetElements(); - - /** - * Append an element to the container, assigning it the next - * available ordinal. - */ - void AppendElement(in nsIRDFNode aElement); - - /** - * Remove the first occurence of the specified element from the - * container. If aRenumber is 'true', then the underlying RDF graph - * will be 're-numbered' to account for the removal. - */ - void RemoveElement(in nsIRDFNode aElement, in boolean aRenumber); - - /** - * Insert aElement at the specified index. If aRenumber is 'true', then - * the underlying RDF graph will be 're-numbered' to accomodate the new - * element. - */ - void InsertElementAt(in nsIRDFNode aElement, in long aIndex, in boolean aRenumber); - - /** - * Remove the element at the specified index. If aRenumber is 'true', then - * the underlying RDF graph will be 're-numbered' to account for the - * removal. - * - * @return the element that was removed. - */ - nsIRDFNode RemoveElementAt(in long aIndex, in boolean aRenumber); - - /** - * Determine the index of an element in the container. - * - * @return The index of the specified element in the container. If - * the element is not contained in the container, this function - * returns '-1'. - */ - long IndexOf(in nsIRDFNode aElement); -}; - -%{C++ -nsresult -NS_NewRDFContainer(nsIRDFContainer** aResult); - -nsresult -NS_NewRDFContainer(nsIRDFDataSource* aDataSource, - nsIRDFResource* aResource, - nsIRDFContainer** aResult); - -/** - * Create a cursor on a container that enumerates its contents in - * order - */ -nsresult -NS_NewContainerEnumerator(nsIRDFDataSource* aDataSource, - nsIRDFResource* aContainer, - nsISimpleEnumerator** aResult); - - -%} diff --git a/rdf/base/nsIRDFContainerUtils.idl b/rdf/base/nsIRDFContainerUtils.idl deleted file mode 100644 index 21cb0b625f5f..000000000000 --- a/rdf/base/nsIRDFContainerUtils.idl +++ /dev/null @@ -1,82 +0,0 @@ -/* -*- 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/. */ - -#include "nsISupports.idl" -#include "nsIRDFContainer.idl" -#include "nsIRDFResource.idl" - - -// Container utilities -[scriptable, uuid(D4214E91-FB94-11D2-BDD8-00104BDE6048)] -interface nsIRDFContainerUtils : nsISupports { - /** - * Returns 'true' if the property is an RDF ordinal property. - */ - boolean IsOrdinalProperty(in nsIRDFResource aProperty); - - /** - * Convert the specified index to an ordinal property. - */ - nsIRDFResource IndexToOrdinalResource(in long aIndex); - - /** - * Convert the specified ordinal property into an index - */ - long OrdinalResourceToIndex(in nsIRDFResource aOrdinal); - - /** - * Return 'true' if the specified resource is a container - */ - boolean IsContainer(in nsIRDFDataSource aDataSource, in nsIRDFResource aResource); - - /** - * Return 'true' if the specified resource is a container and it is empty - */ - boolean IsEmpty(in nsIRDFDataSource aDataSource, in nsIRDFResource aResource); - - /** - * Return 'true' if the specified resource is a bag - */ - boolean IsBag(in nsIRDFDataSource aDataSource, in nsIRDFResource aResource); - - /** - * Return 'true' if the specified resource is a sequence - */ - boolean IsSeq(in nsIRDFDataSource aDataSource, in nsIRDFResource aResource); - - /** - * Return 'true' if the specified resource is an alternation - */ - boolean IsAlt(in nsIRDFDataSource aDataSource, in nsIRDFResource aResource); - - /** - * Decorates the specified resource appropriately to make it - * usable as an empty bag in the specified data source. - */ - nsIRDFContainer MakeBag(in nsIRDFDataSource aDataSource, in nsIRDFResource aResource); - - /** - * Decorates the specified resource appropriately to make it - * usable as an empty sequence in the specified data source. - */ - nsIRDFContainer MakeSeq(in nsIRDFDataSource aDataSource, in nsIRDFResource aResource); - - /** - * Decorates the specified resource appropriately to make it - * usable as an empty alternation in the specified data source. - */ - nsIRDFContainer MakeAlt(in nsIRDFDataSource aDataSource, in nsIRDFResource aResource); - - /** - * Retrieve the index of element in the container. Returns -1 if - * the element is not in the container. - */ - long indexOf(in nsIRDFDataSource aDataSource, in nsIRDFResource aContainer, in nsIRDFNode aElement); -}; - -%{C++ -extern nsresult -NS_NewRDFContainerUtils(nsIRDFContainerUtils** aResult); -%} diff --git a/rdf/base/nsIRDFContentSink.h b/rdf/base/nsIRDFContentSink.h deleted file mode 100644 index 293e8baadea4..000000000000 --- a/rdf/base/nsIRDFContentSink.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- 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/. */ - -/* - - An RDF-specific content sink. The content sink is targeted by the - parser for building the RDF content model. - - */ - -#ifndef nsIRDFContentSink_h___ -#define nsIRDFContentSink_h___ - -#include "nsIXMLContentSink.h" -class nsIRDFDataSource; -class nsIURI; - -// {3a7459d7-d723-483c-aef0-404fc48e09b8} -#define NS_IRDFCONTENTSINK_IID \ -{ 0x3a7459d7, 0xd723, 0x483c, { 0xae, 0xf0, 0x40, 0x4f, 0xc4, 0x8e, 0x09, 0xb8 } } - -/** - * This interface represents a content sink for RDF files. - */ - -class nsIRDFContentSink : public nsIXMLContentSink { -public: - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IRDFCONTENTSINK_IID) - - /** - * Initialize the content sink. - */ - NS_IMETHOD Init(nsIURI* aURL) = 0; - - /** - * Set the content sink's RDF Data source - */ - NS_IMETHOD SetDataSource(nsIRDFDataSource* aDataSource) = 0; - - /** - * Retrieve the content sink's RDF data source. - */ - NS_IMETHOD GetDataSource(nsIRDFDataSource*& rDataSource) = 0; -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIRDFContentSink, NS_IRDFCONTENTSINK_IID) - -/** - * This constructs a content sink that can be used without a - * document, say, to create a stand-alone in-memory graph. - */ -nsresult -NS_NewRDFContentSink(nsIRDFContentSink** aResult); - -#endif // nsIRDFContentSink_h___ diff --git a/rdf/base/nsIRDFDataSource.idl b/rdf/base/nsIRDFDataSource.idl deleted file mode 100644 index 6083b6117874..000000000000 --- a/rdf/base/nsIRDFDataSource.idl +++ /dev/null @@ -1,181 +0,0 @@ -/* -*- 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/. */ - -#include "nsISupports.idl" -#include "nsIRDFResource.idl" -#include "nsIRDFNode.idl" -#include "nsISimpleEnumerator.idl" -#include "nsIRDFObserver.idl" - -[scriptable, uuid(0F78DA58-8321-11d2-8EAC-00805F29F370)] -interface nsIRDFDataSource : nsISupports -{ - /** The "URI" of the data source. This used by the RDF service's - * |GetDataSource()| method to cache datasources. - */ - readonly attribute ACString URI; - - /** Find an RDF resource that points to a given node over the - * specified arc & truth value - * - * @throws NS_RDF_NO_VALUE if there is no source that leads - * to the target with the specified property. - */ - nsIRDFResource GetSource(in nsIRDFResource aProperty, - in nsIRDFNode aTarget, - in boolean aTruthValue); - - /** - * Find all RDF resources that point to a given node over the - * specified arc & truth value - */ - nsISimpleEnumerator GetSources(in nsIRDFResource aProperty, - in nsIRDFNode aTarget, - in boolean aTruthValue); - - /** - * Find a child of that is related to the source by the given arc - * arc and truth value - * - * @throws NS_RDF_NO_VALUE if there is no target accessible from the - * source via the specified property. - */ - nsIRDFNode GetTarget(in nsIRDFResource aSource, - in nsIRDFResource aProperty, - in boolean aTruthValue); - - /** - * Find all children of that are related to the source by the given arc - * arc and truth value. - */ - nsISimpleEnumerator GetTargets(in nsIRDFResource aSource, - in nsIRDFResource aProperty, - in boolean aTruthValue); - - /** - * Add an assertion to the graph. - */ - void Assert(in nsIRDFResource aSource, - in nsIRDFResource aProperty, - in nsIRDFNode aTarget, - in boolean aTruthValue); - - /** - * Remove an assertion from the graph. - */ - void Unassert(in nsIRDFResource aSource, - in nsIRDFResource aProperty, - in nsIRDFNode aTarget); - - /** - * Change an assertion from - * - * [aSource]--[aProperty]-->[aOldTarget] - * - * to - * - * [aSource]--[aProperty]-->[aNewTarget] - */ - void Change(in nsIRDFResource aSource, - in nsIRDFResource aProperty, - in nsIRDFNode aOldTarget, - in nsIRDFNode aNewTarget); - - /** - * 'Move' an assertion from - * - * [aOldSource]--[aProperty]-->[aTarget] - * - * to - * - * [aNewSource]--[aProperty]-->[aTarget] - */ - void Move(in nsIRDFResource aOldSource, - in nsIRDFResource aNewSource, - in nsIRDFResource aProperty, - in nsIRDFNode aTarget); - - /** - * Query whether an assertion exists in this graph. - */ - boolean HasAssertion(in nsIRDFResource aSource, - in nsIRDFResource aProperty, - in nsIRDFNode aTarget, - in boolean aTruthValue); - - /** - * Add an observer to this data source. If the datasource - * supports observers, the datasource source should hold a strong - * reference to the observer. - */ - void AddObserver(in nsIRDFObserver aObserver); - - /** - * Remove an observer from this data source. - */ - void RemoveObserver(in nsIRDFObserver aObserver); - - /** - * Get a cursor to iterate over all the arcs that point into a node. - */ - nsISimpleEnumerator ArcLabelsIn(in nsIRDFNode aNode); - - /** - * Get a cursor to iterate over all the arcs that originate in - * a resource. - */ - nsISimpleEnumerator ArcLabelsOut(in nsIRDFResource aSource); - - /** - * Retrieve all of the resources that the data source currently - * refers to. - */ - nsISimpleEnumerator GetAllResources(); - - /** - * Returns whether a given command is enabled for a set of sources. - */ - boolean IsCommandEnabled(in nsISupports aSources, - in nsIRDFResource aCommand, - in nsISupports aArguments); - - /** - * Perform the specified command on set of sources. - */ - void DoCommand(in nsISupports aSources, - in nsIRDFResource aCommand, - in nsISupports aArguments); - - /** - * Returns the set of all commands defined for a given source. - */ - nsISimpleEnumerator GetAllCmds(in nsIRDFResource aSource); - - /** - * Returns true if the specified node is pointed to by the specified arc. - * Equivalent to enumerating ArcLabelsIn and comparing for the specified arc. - */ - boolean hasArcIn(in nsIRDFNode aNode, in nsIRDFResource aArc); - - /** - * Returns true if the specified node has the specified outward arc. - * Equivalent to enumerating ArcLabelsOut and comparing for the specified arc. - */ - boolean hasArcOut(in nsIRDFResource aSource, in nsIRDFResource aArc); - - /** - * Notify observers that the datasource is about to send several - * notifications at once. - * This must be followed by calling endUpdateBatch(), otherwise - * viewers will get out of sync. - */ - void beginUpdateBatch(); - - /** - * Notify observers that the datasource has completed issuing - * a notification group. - */ - void endUpdateBatch(); -}; diff --git a/rdf/base/nsIRDFDelegateFactory.idl b/rdf/base/nsIRDFDelegateFactory.idl deleted file mode 100644 index 6fbc42fd54c6..000000000000 --- a/rdf/base/nsIRDFDelegateFactory.idl +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- 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/. */ - -/* - - An interface used for runtime pseudo-aggregation of RDF delegate - objects. - -*/ - -#include "nsrootidl.idl" -#include "nsISupports.idl" -interface nsIRDFResource; - -/** - * This interface should be implemented by an XPCOM factory that - * is registered to handle "@mozilla.org/rdf/delegate-factory/[key]/[scheme];1" - * ContractIDs. - * - * The factory will be invoked to create delegate objects from - * nsIRDFResource::GetDelegate(). - */ -[scriptable, uuid(A1B89470-A124-11d3-BE59-0020A6361667)] -interface nsIRDFDelegateFactory : nsISupports -{ - /** - * Create a delegate for the specified RDF resource. - * - * The created delegate should forward AddRef() and Release() - * calls to the aOuter object. - */ - void CreateDelegate(in nsIRDFResource aOuter, - in string aKey, - in nsIIDRef aIID, - [retval, iid_is(aIID)] out nsQIResult aResult); -}; - - diff --git a/rdf/base/nsIRDFInMemoryDataSource.idl b/rdf/base/nsIRDFInMemoryDataSource.idl deleted file mode 100644 index 35734efe63cd..000000000000 --- a/rdf/base/nsIRDFInMemoryDataSource.idl +++ /dev/null @@ -1,14 +0,0 @@ -/* -*- 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/. */ - -#include "nsISupports.idl" -#include "nsIRDFResource.idl" -#include "nsIRDFNode.idl" - -[scriptable, uuid(17C4E0AA-1DD2-11B2-8029-BF6F668DE500)] -interface nsIRDFInMemoryDataSource : nsISupports -{ - void EnsureFastContainment(in nsIRDFResource aSource); -}; diff --git a/rdf/base/nsIRDFInferDataSource.idl b/rdf/base/nsIRDFInferDataSource.idl deleted file mode 100644 index 07bafcfff9a6..000000000000 --- a/rdf/base/nsIRDFInferDataSource.idl +++ /dev/null @@ -1,28 +0,0 @@ -/* -*- 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/. */ - -#include "nsIRDFDataSource.idl" - -/** - * An nsIRDFInferDataSource is implemented by a infer engine. This - * engine mimics assertions in addition to those in the baseDataSource - * according to a particular vocabulary. - * Infer engines have contract IDs in the form of - * "@mozilla.org/rdf/infer-datasource;1?engine=" - */ - -[scriptable, uuid(2b04860f-4017-40f6-8a57-784a1e35077a)] -interface nsIRDFInferDataSource : nsIRDFDataSource { - /** - * - * The wrapped datasource. - * - * The InferDataSource contains all arcs from the wrapped - * datasource plus those infered by the vocabulary implemented - * by the InferDataSource. - */ - attribute nsIRDFDataSource baseDataSource; -}; - diff --git a/rdf/base/nsIRDFLiteral.idl b/rdf/base/nsIRDFLiteral.idl deleted file mode 100644 index 3d289c4fee69..000000000000 --- a/rdf/base/nsIRDFLiteral.idl +++ /dev/null @@ -1,68 +0,0 @@ -/* -*- 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/. */ - -#include "nsIRDFNode.idl" - -%{C++ -#include "nscore.h" // for char16_t -%} - -[ptr] native const_octet_ptr(const uint8_t); - -/** - * A literal node in the graph, whose value is a string. - */ -[scriptable, uuid(E0C493D2-9542-11d2-8EB8-00805F29F370)] -interface nsIRDFLiteral : nsIRDFNode { - /** - * The Unicode string value of the literal. - */ - readonly attribute wstring Value; - - /** - * An unscriptable version used to avoid a string copy. Meant - * for use as a performance optimization. - */ - [noscript] void GetValueConst([shared] out wstring aConstValue); -}; - -/** - * A literal node in the graph, whose value is a date - */ -[scriptable, uuid(E13A24E1-C77A-11d2-80BE-006097B76B8E)] -interface nsIRDFDate : nsIRDFNode { - /** - * The date value of the literal - */ - readonly attribute PRTime Value; -}; - -/** - * A literal node in the graph, whose value is an integer - */ -[scriptable, uuid(E13A24E3-C77A-11d2-80BE-006097B76B8E)] -interface nsIRDFInt : nsIRDFNode { - /** - * The integer value of the literal - */ - readonly attribute long Value; -}; - -/** - * A literal node in the graph, whose value is arbitrary - * binary data. - */ -[scriptable, uuid(237f85a2-1dd2-11b2-94af-8122582fc45e)] -interface nsIRDFBlob : nsIRDFNode { - /** - * The binary data. - */ - [noscript] readonly attribute const_octet_ptr value; - - /** - * The data's length. - */ - readonly attribute long length; -}; diff --git a/rdf/base/nsIRDFNode.idl b/rdf/base/nsIRDFNode.idl deleted file mode 100644 index 2bd7d4967ee3..000000000000 --- a/rdf/base/nsIRDFNode.idl +++ /dev/null @@ -1,15 +0,0 @@ -/* -*- 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/. */ - -#include "nsISupports.idl" - -// An nsIRDFNode object is an abstract placeholder for a node in the -// RDF data model. Its concreted implementations (e.g., nsIRDFResource -// or nsIRDFLiteral) are the actual objects that populate the graph. -[scriptable, uuid(0F78DA50-8321-11d2-8EAC-00805F29F370)] -interface nsIRDFNode : nsISupports { - // Determine if two nodes are identical - boolean EqualsNode(in nsIRDFNode aNode); -}; diff --git a/rdf/base/nsIRDFObserver.idl b/rdf/base/nsIRDFObserver.idl deleted file mode 100644 index 1923c5b38e4e..000000000000 --- a/rdf/base/nsIRDFObserver.idl +++ /dev/null @@ -1,94 +0,0 @@ -/* -*- 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/. */ - -#include "nsISupports.idl" -#include "nsIRDFResource.idl" -#include "nsIRDFNode.idl" - -interface nsIRDFDataSource; - -// An nsIRDFObserver object is an observer that will be notified -// when assertions are made or removed from a datasource -[scriptable, uuid(3CC75360-484A-11D2-BC16-00805F912FE7)] -interface nsIRDFObserver : nsISupports { - /** - * This method is called whenever a new assertion is made - * in the data source - * @param aDataSource the datasource that is issuing - * the notification. - * @param aSource the subject of the assertion - * @param aProperty the predicate of the assertion - * @param aTarget the object of the assertion - */ - void onAssert(in nsIRDFDataSource aDataSource, - in nsIRDFResource aSource, - in nsIRDFResource aProperty, - in nsIRDFNode aTarget); - - /** - * This method is called whenever an assertion is removed - * from the data source - * @param aDataSource the datasource that is issuing - * the notification. - * @param aSource the subject of the assertion - * @param aProperty the predicate of the assertion - * @param aTarget the object of the assertion - */ - void onUnassert(in nsIRDFDataSource aDataSource, - in nsIRDFResource aSource, - in nsIRDFResource aProperty, - in nsIRDFNode aTarget); - - /** - * This method is called when the object of an assertion - * changes from one value to another. - * @param aDataSource the datasource that is issuing - * the notification. - * @param aSource the subject of the assertion - * @param aProperty the predicate of the assertion - * @param aOldTarget the old object of the assertion - * @param aNewTarget the new object of the assertion - */ - void onChange(in nsIRDFDataSource aDataSource, - in nsIRDFResource aSource, - in nsIRDFResource aProperty, - in nsIRDFNode aOldTarget, - in nsIRDFNode aNewTarget); - - /** - * This method is called when the subject of an assertion - * changes from one value to another. - * @param aDataSource the datasource that is issuing - * the notification. - * @param aOldSource the old subject of the assertion - * @param aNewSource the new subject of the assertion - * @param aProperty the predicate of the assertion - * @param aTarget the object of the assertion - */ - void onMove(in nsIRDFDataSource aDataSource, - in nsIRDFResource aOldSource, - in nsIRDFResource aNewSource, - in nsIRDFResource aProperty, - in nsIRDFNode aTarget); - - /** - * This method is called when a datasource is about to - * send several notifications at once. The observer can - * use this as a cue to optimize its behavior. The observer - * can expect the datasource to call endUpdateBatch() when - * the group of notifications has completed. - * @param aDataSource the datasource that is going to - * be issuing the notifications. - */ - void onBeginUpdateBatch(in nsIRDFDataSource aDataSource); - - /** - * This method is called when a datasource has completed - * issuing a notification group. - * @param aDataSource the datasource that has finished - * issuing a group of notifications - */ - void onEndUpdateBatch(in nsIRDFDataSource aDataSource); -}; diff --git a/rdf/base/nsIRDFPropagatableDataSource.idl b/rdf/base/nsIRDFPropagatableDataSource.idl deleted file mode 100644 index dfe510e9c2ad..000000000000 --- a/rdf/base/nsIRDFPropagatableDataSource.idl +++ /dev/null @@ -1,27 +0,0 @@ -/* -*- Mode: idl; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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/. */ - - -#include "nsISupports.idl" - -/** - * An nsIRDFPropagatableDataSource provides an ability to suppress - * synchronization notifications. - */ -[scriptable, uuid(5a9b4770-9fcb-4307-a12e-4b6708e78b97)] -interface nsIRDFPropagatableDataSource: nsISupports { - - /** - * Set this value to true to enable synchronization - * notifications. - * - * Set this value to false to disable synchronization - * notifications. - * - * By default, this value is true. - */ - attribute boolean propagateChanges; - -}; diff --git a/rdf/base/nsIRDFPurgeableDataSource.idl b/rdf/base/nsIRDFPurgeableDataSource.idl deleted file mode 100644 index 05973df0e43a..000000000000 --- a/rdf/base/nsIRDFPurgeableDataSource.idl +++ /dev/null @@ -1,19 +0,0 @@ -/* -*- 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/. */ - -#include "nsISupports.idl" -#include "nsIRDFResource.idl" -#include "nsIRDFNode.idl" - -[scriptable, uuid(951700F0-FED0-11D2-BDD9-00104BDE6048)] -interface nsIRDFPurgeableDataSource : nsISupports -{ - boolean Mark(in nsIRDFResource aSource, - in nsIRDFResource aProperty, - in nsIRDFNode aTarget, - in boolean aTruthValue); - - void Sweep(); -}; diff --git a/rdf/base/nsIRDFRemoteDataSource.idl b/rdf/base/nsIRDFRemoteDataSource.idl deleted file mode 100644 index fd2cd1b0b069..000000000000 --- a/rdf/base/nsIRDFRemoteDataSource.idl +++ /dev/null @@ -1,44 +0,0 @@ -/* -*- 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/. */ - -#include "nsISupports.idl" - -/** - * A datasource that may load asynchronously - */ -[scriptable, uuid(1D297320-27F7-11d3-BE01-000064657374)] -interface nsIRDFRemoteDataSource : nsISupports -{ - /** - * This value is true when the datasource has - * fully loaded itself. - */ - readonly attribute boolean loaded; - - /** - * Specify the URI for the data source: this is the prefix - * that will be used to register the data source in the - * data source registry. - * @param aURI the URI to load - */ - void Init(in string aURI); - - /** - * Refresh the remote datasource, re-loading its contents - * from the URI. - * - * @param aBlocking If true, the call will block - * until the datasource has completely reloaded. - */ - void Refresh(in boolean aBlocking); - - /** - * Request that a data source write its contents out to - * permanent storage, if applicable. - */ - void Flush(); - void FlushTo(in string aURI); -}; - diff --git a/rdf/base/nsIRDFResource.idl b/rdf/base/nsIRDFResource.idl deleted file mode 100644 index df4d4b8ffd6d..000000000000 --- a/rdf/base/nsIRDFResource.idl +++ /dev/null @@ -1,81 +0,0 @@ -/* -*- 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/. */ - -#include "nsrootidl.idl" -#include "nsIRDFNode.idl" - - -/** - * An nsIRDFResource is an object that has unique identity in the - * RDF data model. The object's identity is determined by its URI. - */ -[scriptable, uuid(fb9686a7-719a-49dc-9107-10dea5739341)] -interface nsIRDFResource : nsIRDFNode { - /** - * The single-byte string value of the resource. - * @note THIS IS OBSOLETE. C++ should use GetValueConst and script - * should use .valueUTF8 - */ - readonly attribute string Value; - - /** - * The UTF-8 URI of the resource. - */ - readonly attribute AUTF8String ValueUTF8; - - /** - * An unscriptable version used to avoid a string copy. Meant - * for use as a performance optimization. The string is encoded - * in UTF-8. - */ - [noscript] void GetValueConst([shared] out string aConstValue); - - /** - * This method is called by the nsIRDFService after constructing - * a resource object to initialize its URI. You would not normally - * call this method directly - */ - void Init(in string uri); - - /** - * Determine if the resource has the given URI. - */ - boolean EqualsString(in string aURI); - - /** - * Retrieve the "delegate" object for this resource. A resource - * may have several delegate objects, each of whose lifetimes is - * bound to the life of the resource object. - * - * This method will return the delegate for the given key after - * QueryInterface()-ing it to the requested IID. - * - * If no delegate exists for the specified key, this method will - * attempt to create one using the component manager. Specifically, - * it will combine aKey with the resource's URI scheme to produce - * a ContractID as follows: - * - * component:/rdf/delegate-factory/[key]/[scheme] - * - * This ContractID will be used to locate a factory using the - * FindFactory() method of nsIComponentManager. If the nsIFactory - * exists, it will be used to create a "delegate factory"; that - * is, an object that supports nsIRDFDelegateFactory. The delegate - * factory will be used to construct the delegate object. - */ - void GetDelegate(in string aKey, in nsIIDRef aIID, - [iid_is(aIID),retval] out nsQIResult aResult); - - /** - * Force a delegate to be "unbound" from the resource. - * - * Normally, a delegate object's lifetime will be identical to - * that of the resource to which it is bound; this method allows a - * delegate to unlink itself from an RDF resource prematurely. - */ - void ReleaseDelegate(in string aKey); -}; - - diff --git a/rdf/base/nsIRDFService.idl b/rdf/base/nsIRDFService.idl deleted file mode 100644 index 08023feab7ea..000000000000 --- a/rdf/base/nsIRDFService.idl +++ /dev/null @@ -1,146 +0,0 @@ -/* -*- 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/. */ - -#include "nsISupports.idl" -#include "nsIRDFResource.idl" -#include "nsIRDFLiteral.idl" -#include "nsIRDFDataSource.idl" - - -/** - * The RDF service interface. This is a singleton object which should be - * obtained from the nsServiceManager. - */ -[scriptable, uuid(BFD05261-834C-11d2-8EAC-00805F29F370)] -interface nsIRDFService : nsISupports { - /** - * Construct an RDF resource from a single-byte URI. nsIRDFService - * caches resources that are in-use, so multiple calls to GetResource() - * for the same uri will return identical pointers. FindResource - * is used to find out whether there already exists a resource corresponding to that url. - */ - nsIRDFResource GetResource(in AUTF8String aURI); - - /** - * Construct an RDF resource from a Unicode URI. This is provided - * as a convenience method, allowing automatic, in-line C++ - * conversion from nsString objects. The uri will - * be converted to a single-byte representation internally. - */ - nsIRDFResource GetUnicodeResource(in AString aURI); - - nsIRDFResource GetAnonymousResource(); - - /** - * Construct an RDF literal from a Unicode string. - */ - nsIRDFLiteral GetLiteral(in wstring aValue); - - /** - * Construct an RDF literal from a PRTime. - */ - nsIRDFDate GetDateLiteral(in PRTime aValue); - - /** - * Construct an RDF literal from an int. - */ - nsIRDFInt GetIntLiteral(in long aValue); - - /** - * Construct an RDF literal from a data blob - */ - [noscript] nsIRDFBlob getBlobLiteral(in const_octet_ptr aValue, in long aLength); - - boolean IsAnonymousResource(in nsIRDFResource aResource); - - /** - * Registers a resource with the RDF system, making it unique w.r.t. - * GetResource. - * - * An implementation of nsIRDFResource should call this in its - * Init() method if it wishes the resource to be globally unique - * (which is usually the case). - * - * @note that the resource will not be ref-counted by the - * RDF service: the assumption is that the resource implementation - * will call nsIRDFService::UnregisterResource() when the last - * reference to the resource is released. - * - * @note that the nsIRDFService implementation may choose to - * maintain a reference to the resource's URI; therefore, the - * resource implementation should ensure that the resource's URI - * (accessible via nsIRDFResource::GetValue(const char* *aURI)) is - * valid before calling RegisterResource(). Furthermore, the - * resource implementation should ensure that this pointer - * remains valid for the lifetime of the resource. (The - * implementation of the resource cache in nsIRDFService uses the - * URI maintained "internally" in the resource as a key into the - * cache rather than copying the resource URI itself.) - */ - void RegisterResource(in nsIRDFResource aResource, in boolean aReplace); - - /** - * Called to notify the resource manager that a resource is no - * longer in use. This method should only be called from the - * destructor of a "custom" resource implementation to notify the - * RDF service that the last reference to the resource has been - * released, so the resource is no longer valid. - * - * @note As mentioned in nsIRDFResourceFactory::CreateResource(), - * the RDF service will use the result of - * nsIRDFResource::GetValue() as a key into its cache. For this - * reason, you must always un-cache the resource before - * releasing the storage for the const char* URI. - */ - void UnregisterResource(in nsIRDFResource aResource); - - /** - * Register a named data source. The RDF service will call - * nsIRDFDataSource::GetURI() to determine the URI under - * which to register the data source. - * - * @note that the data source will not be refcounted by the - * RDF service! The assumption is that an RDF data source - * registers with the service once it is initialized (via - * nsIRDFDataSource::Init()), and unregisters when the - * last reference to the data source is released. - */ - void RegisterDataSource(in nsIRDFDataSource aDataSource, - in boolean aReplace); - - /** - * Unregister a named data source. The RDF service will call - * nsIRDFDataSource::GetURI() to determine the URI under which the - * data source was registered. - */ - void UnregisterDataSource(in nsIRDFDataSource aDataSource); - - /** - * Get the named data source corresponding to the URI. If a data - * source has been registered via RegisterDataSource(), that - * data source will be returned. - * - * If no data source is currently - * registered for the specified URI, and a data source constructor - * function has been registered via RegisterDatasourceConstructor(), - * the RDF service will call the constructor to attempt to construct a - * new data source. If construction is successful, the data source will - * be initialized via nsIRDFDataSource::Init(). - */ - nsIRDFDataSource GetDataSource(in string aURI); - - /** - * Same as GetDataSource, but if a remote/XML data source needs to be - * constructed, then this method will issue a blocking Refresh - * call on that data source. - */ - nsIRDFDataSource GetDataSourceBlocking(in string aURI); -}; - -%{C++ -extern nsresult -NS_NewRDFService(nsIRDFService** result); -%} - diff --git a/rdf/base/nsIRDFXMLParser.idl b/rdf/base/nsIRDFXMLParser.idl deleted file mode 100644 index 1e7dde51f185..000000000000 --- a/rdf/base/nsIRDFXMLParser.idl +++ /dev/null @@ -1,33 +0,0 @@ -/* -*- 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/. */ - -#include "nsISupports.idl" -#include "nsIRDFDataSource.idl" -#include "nsIStreamListener.idl" -#include "nsIURI.idl" - -[scriptable, uuid(1831dd2e-1dd2-11b2-bdb3-86b7b50b70b5)] -interface nsIRDFXMLParser : nsISupports -{ - /** - * Create a stream listener that can be used to asynchronously - * parse RDF/XML. - * @param aSink the RDF datasource the will receive the data - * @param aBaseURI the base URI used to resolve relative - * references in the RDF/XML - * @return an nsIStreamListener object to handle the data - */ - nsIStreamListener parseAsync(in nsIRDFDataSource aSink, in nsIURI aBaseURI); - - /** - * Parse a string of RDF/XML - * @param aSink the RDF datasource that will receive the data - * @param aBaseURI the base URI used to resolve relative - * references in the RDF/XML - * @param aSource a UTF8 string containing RDF/XML data. - */ - void parseString(in nsIRDFDataSource aSink, in nsIURI aBaseURI, in AUTF8String aSource); -}; diff --git a/rdf/base/nsIRDFXMLSerializer.idl b/rdf/base/nsIRDFXMLSerializer.idl deleted file mode 100644 index edf113d4bead..000000000000 --- a/rdf/base/nsIRDFXMLSerializer.idl +++ /dev/null @@ -1,31 +0,0 @@ -/* -*- 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/. */ - -#include "nsISupports.idl" -#include "nsIRDFDataSource.idl" - -%{C++ -class nsAtom; -%} -[ptr] native nsAtomPtr(nsAtom); - -[scriptable, uuid(8ae1fbf8-1dd2-11b2-bd21-d728069cca92)] -interface nsIRDFXMLSerializer : nsISupports -{ - /** - * Initialize the serializer with the specified datasource. - * @param aDataSource the datasource from which data will be - * serialized - */ - void init(in nsIRDFDataSource aDataSource); - - /** - * Add the specified namespace to the serializer. - * @param aPrefix the attribute namespace prefix - * @param aURI the namespace URI - */ - [noscript] void addNameSpace(in nsAtomPtr aPrefix, in DOMString aURI); -}; diff --git a/rdf/base/nsIRDFXMLSink.idl b/rdf/base/nsIRDFXMLSink.idl deleted file mode 100644 index 1c950c867ab4..000000000000 --- a/rdf/base/nsIRDFXMLSink.idl +++ /dev/null @@ -1,133 +0,0 @@ -/* -*- 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/. */ - -/* - - Interfaces for the RDF/XML sink, which parses RDF/XML into - a graph representation. - -*/ - -#include "nsISupports.idl" - -%{C++ -class nsAtom; -%} -[ptr] native nsAtomPtr(nsAtom); - -// XXX Until these get scriptable. See nsIRDFXMLSink::AddNameSpace() -[ref] native nsStringRef(nsString); -%{C++ -#include "nsStringFwd.h" -%} - -interface nsIRDFXMLSink; - -/** - * An observer that is notified as progress is made on the load - * of an RDF/XML document in an nsIRDFXMLSink. - */ -[scriptable, uuid(EB1A5D30-AB33-11D2-8EC6-00805F29F370)] -interface nsIRDFXMLSinkObserver : nsISupports -{ - /** - * Called when the load begins. - * @param aSink the RDF/XML sink on which the load is beginning. - */ - void onBeginLoad(in nsIRDFXMLSink aSink); - - /** - * Called when the load is suspended (e.g., for network quantization). - * @param aSink the RDF/XML sink that is being interrupted. - */ - void onInterrupt(in nsIRDFXMLSink aSink); - - /** - * Called when a suspended load is resuming. - * @param aSink the RDF/XML sink that is resuming. - */ - void onResume(in nsIRDFXMLSink aSink); - - /** - * Called when an RDF/XML load completes successfully. - * @param aSink the RDF/XML sink that has finished loading. - */ - void onEndLoad(in nsIRDFXMLSink aSink); - - /** - * Called when an error occurs during the load - * @param aSink the RDF/XML sink in which the error occurred - * @param aStatus the networking result code - * @param aErrorMsg an error message, if applicable - */ - void onError(in nsIRDFXMLSink aSink, in nsresult aStatus, in wstring aErrorMsg); -}; - - - -/** - * A "sink" that receives and processes RDF/XML. This interface is used - * by the RDF/XML parser. - */ -[scriptable, uuid(EB1A5D31-AB33-11D2-8EC6-00805F29F370)] -interface nsIRDFXMLSink : nsISupports -{ - /** - * Set to true if the sink is read-only and cannot - * be modified - */ - attribute boolean readOnly; - - /** - * Initiate the RDF/XML load. - */ - void beginLoad(); - - /** - * Suspend the RDF/XML load. - */ - void interrupt(); - - /** - * Resume the RDF/XML load. - */ - void resume(); - - /** - * Complete the RDF/XML load. - */ - void endLoad(); - - /** - * Add namespace information to the RDF/XML sink. - * @param aPrefix the namespace prefix - * @param aURI the namespace URI - */ - [noscript] void addNameSpace(in nsAtomPtr aPrefix, - [const] in nsStringRef aURI); - - /** - * Add an observer that will be notified as the RDF/XML load - * progresses. - *

- * - * Note that the sink will acquire a strong reference to the - * observer, so care should be taken to avoid cyclical references - * that cannot be released (i.e., if the observer holds a - * reference to the sink, it should be sure that it eventually - * clears the reference). - * - * @param aObserver the observer to add to the sink's set of - * load observers. - */ - void addXMLSinkObserver(in nsIRDFXMLSinkObserver aObserver); - - /** - * Remove an observer from the sink's set of observers. - * @param aObserver the observer to remove. - */ - void removeXMLSinkObserver(in nsIRDFXMLSinkObserver aObserver); -}; - diff --git a/rdf/base/nsIRDFXMLSource.idl b/rdf/base/nsIRDFXMLSource.idl deleted file mode 100644 index 794d8b66269b..000000000000 --- a/rdf/base/nsIRDFXMLSource.idl +++ /dev/null @@ -1,20 +0,0 @@ -/* -*- 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/. */ - -#include "nsISupports.idl" -#include "nsIOutputStream.idl" - -[scriptable, uuid(4DA56F10-99FE-11d2-8EBB-00805F29F370)] -interface nsIRDFXMLSource : nsISupports -{ - /** - * Serialize the contents of the datasource to aStream. - * @param aStream the output stream the will receive the - * RDF/XML. Currently, the output stream need only - * implement the |write()| method. - */ - void Serialize(in nsIOutputStream aStream); -}; - diff --git a/rdf/base/nsInMemoryDataSource.cpp b/rdf/base/nsInMemoryDataSource.cpp deleted file mode 100644 index fe2d3199bf7e..000000000000 --- a/rdf/base/nsInMemoryDataSource.cpp +++ /dev/null @@ -1,1938 +0,0 @@ -/* -*- 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/. */ - -/* - - Implementation for an in-memory RDF data store. - - TO DO - - 1) Instrument this code to gather space and time performance - characteristics. - - 2) Optimize lookups for datasources which have a small number - of properties + fanning out to a large number of targets. - - 3) Complete implementation of thread-safety; specifically, make - assertions be reference counted objects (so that a cursor can - still refer to an assertion that gets removed from the graph). - - */ - -#include "nsAgg.h" -#include "nsCOMPtr.h" -#include "nscore.h" -#include "nsArrayEnumerator.h" -#include "nsIOutputStream.h" -#include "nsIRDFDataSource.h" -#include "nsIRDFLiteral.h" -#include "nsIRDFNode.h" -#include "nsIRDFObserver.h" -#include "nsIRDFInMemoryDataSource.h" -#include "nsIRDFPropagatableDataSource.h" -#include "nsIRDFPurgeableDataSource.h" -#include "nsIRDFService.h" -#include "nsIServiceManager.h" -#include "nsCOMArray.h" -#include "nsEnumeratorUtils.h" -#include "nsTArray.h" -#include "nsCRT.h" -#include "nsRDFCID.h" -#include "nsRDFBaseDataSources.h" -#include "nsString.h" -#include "nsReadableUtils.h" -#include "nsString.h" -#include "rdfutil.h" -#include "PLDHashTable.h" -#include "plstr.h" -#include "mozilla/Logging.h" -#include "rdf.h" - -#include "rdfIDataSource.h" -#include "rdfITripleVisitor.h" - -using mozilla::LogLevel; - -// This struct is used as the slot value in the forward and reverse -// arcs hash tables. -// -// Assertion objects are reference counted, because each Assertion's -// ownership is shared between the datasource and any enumerators that -// are currently iterating over the datasource. -// -class Assertion -{ -public: - Assertion(nsIRDFResource* aSource, // normal assertion - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue); - explicit Assertion(nsIRDFResource* aSource); // PLDHashTable assertion variant - -private: - ~Assertion(); - -public: - void AddRef() { - if (mRefCnt == UINT16_MAX) { - NS_WARNING("refcount overflow, leaking Assertion"); - return; - } - ++mRefCnt; - } - - void Release() { - if (mRefCnt == UINT16_MAX) { - NS_WARNING("refcount overflow, leaking Assertion"); - return; - } - if (--mRefCnt == 0) - delete this; - } - - // For nsIRDFPurgeableDataSource - inline void Mark() { u.as.mMarked = true; } - inline bool IsMarked() { return u.as.mMarked; } - inline void Unmark() { u.as.mMarked = false; } - - // public for now, because I'm too lazy to go thru and clean this up. - - // These are shared between hash/as (see the union below) - nsIRDFResource* mSource; - Assertion* mNext; - - union - { - struct hash - { - PLDHashTable* mPropertyHash; - } hash; - struct as - { - nsIRDFResource* mProperty; - nsIRDFNode* mTarget; - Assertion* mInvNext; - // make sure bool are final elements - bool mTruthValue; - bool mMarked; - } as; - } u; - - // also shared between hash/as (see the union above) - // but placed after union definition to ensure that - // all 32-bit entries are long aligned - uint16_t mRefCnt; - bool mHashEntry; -}; - - -struct Entry : PLDHashEntryHdr { - nsIRDFNode* mNode; - Assertion* mAssertions; -}; - - -Assertion::Assertion(nsIRDFResource* aSource) - : mSource(aSource), - mNext(nullptr), - mRefCnt(0), - mHashEntry(true) -{ - MOZ_COUNT_CTOR(Assertion); - - NS_ADDREF(mSource); - - u.hash.mPropertyHash = - new PLDHashTable(PLDHashTable::StubOps(), sizeof(Entry)); -} - -Assertion::Assertion(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue) - : mSource(aSource), - mNext(nullptr), - mRefCnt(0), - mHashEntry(false) -{ - MOZ_COUNT_CTOR(Assertion); - - u.as.mProperty = aProperty; - u.as.mTarget = aTarget; - - NS_ADDREF(mSource); - NS_ADDREF(u.as.mProperty); - NS_ADDREF(u.as.mTarget); - - u.as.mInvNext = nullptr; - u.as.mTruthValue = aTruthValue; - u.as.mMarked = false; -} - -Assertion::~Assertion() -{ - if (mHashEntry && u.hash.mPropertyHash) { - for (auto i = u.hash.mPropertyHash->Iter(); !i.Done(); i.Next()) { - auto entry = static_cast(i.Get()); - Assertion* as = entry->mAssertions; - while (as) { - Assertion* doomed = as; - as = as->mNext; - - // Unlink, and release the datasource's reference. - doomed->mNext = doomed->u.as.mInvNext = nullptr; - doomed->Release(); - } - } - delete u.hash.mPropertyHash; - u.hash.mPropertyHash = nullptr; - } - - MOZ_COUNT_DTOR(Assertion); -#ifdef DEBUG_REFS - --gInstanceCount; - fprintf(stdout, "%d - RDF: Assertion\n", gInstanceCount); -#endif - - NS_RELEASE(mSource); - if (!mHashEntry) - { - NS_RELEASE(u.as.mProperty); - NS_RELEASE(u.as.mTarget); - } -} - -//////////////////////////////////////////////////////////////////////// -// InMemoryDataSource -class InMemoryArcsEnumeratorImpl; -class InMemoryAssertionEnumeratorImpl; -class InMemoryResourceEnumeratorImpl; - -class InMemoryDataSource : public nsIRDFDataSource, - public nsIRDFInMemoryDataSource, - public nsIRDFPropagatableDataSource, - public nsIRDFPurgeableDataSource, - public rdfIDataSource -{ -protected: - // These hash tables are keyed on pointers to nsIRDFResource - // objects (the nsIRDFService ensures that there is only ever one - // nsIRDFResource object per unique URI). The value of an entry is - // an Assertion struct, which is a linked list of (subject - // predicate object) triples. - PLDHashTable mForwardArcs; - PLDHashTable mReverseArcs; - - nsCOMArray mObservers; - uint32_t mNumObservers; - - // VisitFoo needs to block writes, [Un]Assert only allowed - // during mReadCount == 0 - uint32_t mReadCount; - - friend class InMemoryArcsEnumeratorImpl; - friend class InMemoryAssertionEnumeratorImpl; - friend class InMemoryResourceEnumeratorImpl; // b/c it needs to enumerate mForwardArcs - - // Thread-safe writer implementation methods. - nsresult - LockedAssert(nsIRDFResource* source, - nsIRDFResource* property, - nsIRDFNode* target, - bool tv); - - nsresult - LockedUnassert(nsIRDFResource* source, - nsIRDFResource* property, - nsIRDFNode* target); - - explicit InMemoryDataSource(nsISupports* aOuter); - virtual ~InMemoryDataSource(); - - friend nsresult - NS_NewRDFInMemoryDataSource(nsISupports* aOuter, const nsIID& aIID, void** aResult); - -public: - NS_DECL_CYCLE_COLLECTING_AGGREGATED - NS_DECL_AGGREGATED_CYCLE_COLLECTION_CLASS(InMemoryDataSource) - - // nsIRDFDataSource methods - NS_DECL_NSIRDFDATASOURCE - - // nsIRDFInMemoryDataSource methods - NS_DECL_NSIRDFINMEMORYDATASOURCE - - // nsIRDFPropagatableDataSource methods - NS_DECL_NSIRDFPROPAGATABLEDATASOURCE - - // nsIRDFPurgeableDataSource methods - NS_DECL_NSIRDFPURGEABLEDATASOURCE - - // rdfIDataSource methods - NS_DECL_RDFIDATASOURCE - -protected: - struct SweepInfo { - Assertion* mUnassertList; - PLDHashTable* mReverseArcs; - }; - - static void - SweepForwardArcsEntries(PLDHashTable* aTable, SweepInfo* aArg); - -public: - // Implementation methods - Assertion* - GetForwardArcs(nsIRDFResource* u) { - PLDHashEntryHdr* hdr = mForwardArcs.Search(u); - return hdr ? static_cast(hdr)->mAssertions : nullptr; - } - - Assertion* - GetReverseArcs(nsIRDFNode* v) { - PLDHashEntryHdr* hdr = mReverseArcs.Search(v); - return hdr ? static_cast(hdr)->mAssertions : nullptr; - } - - void - SetForwardArcs(nsIRDFResource* u, Assertion* as) { - if (as) { - auto entry = - static_cast(mForwardArcs.Add(u, mozilla::fallible)); - if (entry) { - entry->mNode = u; - entry->mAssertions = as; - } - } - else { - mForwardArcs.Remove(u); - } - } - - void - SetReverseArcs(nsIRDFNode* v, Assertion* as) { - if (as) { - auto entry = - static_cast(mReverseArcs.Add(v, mozilla::fallible)); - if (entry) { - entry->mNode = v; - entry->mAssertions = as; - } - } - else { - mReverseArcs.Remove(v); - } - } - - void - LogOperation(const char* aOperation, - nsIRDFResource* asource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue = true); - - bool mPropagateChanges; - -private: - static mozilla::LazyLogModule gLog; -}; - -mozilla::LazyLogModule InMemoryDataSource::gLog("InMemoryDataSource"); - -//---------------------------------------------------------------------- -// -// InMemoryAssertionEnumeratorImpl -// - -/** - * InMemoryAssertionEnumeratorImpl - */ -class InMemoryAssertionEnumeratorImpl : public nsISimpleEnumerator -{ -private: - InMemoryDataSource* mDataSource; - nsIRDFResource* mSource; - nsIRDFResource* mProperty; - nsIRDFNode* mTarget; - nsIRDFNode* mValue; - bool mTruthValue; - Assertion* mNextAssertion; - - virtual ~InMemoryAssertionEnumeratorImpl(); - -public: - InMemoryAssertionEnumeratorImpl(InMemoryDataSource* aDataSource, - nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue); - - // nsISupports interface - NS_DECL_ISUPPORTS - - // nsISimpleEnumerator interface - NS_DECL_NSISIMPLEENUMERATOR -}; - -//////////////////////////////////////////////////////////////////////// - - -InMemoryAssertionEnumeratorImpl::InMemoryAssertionEnumeratorImpl( - InMemoryDataSource* aDataSource, - nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue) - : mDataSource(aDataSource), - mSource(aSource), - mProperty(aProperty), - mTarget(aTarget), - mValue(nullptr), - mTruthValue(aTruthValue), - mNextAssertion(nullptr) -{ - NS_ADDREF(mDataSource); - NS_IF_ADDREF(mSource); - NS_ADDREF(mProperty); - NS_IF_ADDREF(mTarget); - - if (mSource) { - mNextAssertion = mDataSource->GetForwardArcs(mSource); - - if (mNextAssertion && mNextAssertion->mHashEntry) { - // its our magical HASH_ENTRY forward hash for assertions - PLDHashEntryHdr* hdr = - mNextAssertion->u.hash.mPropertyHash->Search(aProperty); - mNextAssertion = - hdr ? static_cast(hdr)->mAssertions : nullptr; - } - } - else { - mNextAssertion = mDataSource->GetReverseArcs(mTarget); - } - - // Add an owning reference from the enumerator - if (mNextAssertion) - mNextAssertion->AddRef(); -} - -InMemoryAssertionEnumeratorImpl::~InMemoryAssertionEnumeratorImpl() -{ -#ifdef DEBUG_REFS - --gInstanceCount; - fprintf(stdout, "%d - RDF: InMemoryAssertionEnumeratorImpl\n", gInstanceCount); -#endif - - if (mNextAssertion) - mNextAssertion->Release(); - - NS_IF_RELEASE(mDataSource); - NS_IF_RELEASE(mSource); - NS_IF_RELEASE(mProperty); - NS_IF_RELEASE(mTarget); - NS_IF_RELEASE(mValue); -} - -NS_IMPL_ADDREF(InMemoryAssertionEnumeratorImpl) -NS_IMPL_RELEASE(InMemoryAssertionEnumeratorImpl) -NS_IMPL_QUERY_INTERFACE(InMemoryAssertionEnumeratorImpl, nsISimpleEnumerator) - -NS_IMETHODIMP -InMemoryAssertionEnumeratorImpl::HasMoreElements(bool* aResult) -{ - if (mValue) { - *aResult = true; - return NS_OK; - } - - while (mNextAssertion) { - bool foundIt = false; - if ((mProperty == mNextAssertion->u.as.mProperty) && - (mTruthValue == mNextAssertion->u.as.mTruthValue)) { - if (mSource) { - mValue = mNextAssertion->u.as.mTarget; - NS_ADDREF(mValue); - } - else { - mValue = mNextAssertion->mSource; - NS_ADDREF(mValue); - } - foundIt = true; - } - - // Remember the last assertion we were holding on to - Assertion* as = mNextAssertion; - - // iterate - mNextAssertion = (mSource) ? mNextAssertion->mNext : mNextAssertion->u.as.mInvNext; - - // grab an owning reference from the enumerator to the next assertion - if (mNextAssertion) - mNextAssertion->AddRef(); - - // ...and release the reference from the enumerator to the old one. - as->Release(); - - if (foundIt) { - *aResult = true; - return NS_OK; - } - } - - *aResult = false; - return NS_OK; -} - - -NS_IMETHODIMP -InMemoryAssertionEnumeratorImpl::GetNext(nsISupports** aResult) -{ - nsresult rv; - - bool hasMore; - rv = HasMoreElements(&hasMore); - if (NS_FAILED(rv)) return rv; - - if (! hasMore) - return NS_ERROR_UNEXPECTED; - - // Don't AddRef: we "transfer" ownership to the caller - *aResult = mValue; - mValue = nullptr; - - return NS_OK; -} - -//////////////////////////////////////////////////////////////////////// -// - -/** - * This class is a little bit bizarre in that it implements both the - * nsIRDFArcsOutCursor and nsIRDFArcsInCursor interfaces. - * Because the structure of the in-memory graph is pretty flexible, it's - * fairly easy to parameterize this class. The only funky thing to watch - * out for is the multiple inheritance clashes. - */ - -class InMemoryArcsEnumeratorImpl : public nsISimpleEnumerator -{ -private: - InMemoryDataSource* mDataSource; - nsIRDFResource* mSource; - nsIRDFNode* mTarget; - AutoTArray, 8> mAlreadyReturned; - nsIRDFResource* mCurrent; - Assertion* mAssertion; - nsCOMArray* mHashArcs; - - virtual ~InMemoryArcsEnumeratorImpl(); - -public: - InMemoryArcsEnumeratorImpl(InMemoryDataSource* aDataSource, - nsIRDFResource* aSource, - nsIRDFNode* aTarget); - - // nsISupports interface - NS_DECL_ISUPPORTS - - // nsISimpleEnumerator interface - NS_DECL_NSISIMPLEENUMERATOR -}; - - -InMemoryArcsEnumeratorImpl::InMemoryArcsEnumeratorImpl(InMemoryDataSource* aDataSource, - nsIRDFResource* aSource, - nsIRDFNode* aTarget) - : mDataSource(aDataSource), - mSource(aSource), - mTarget(aTarget), - mCurrent(nullptr), - mHashArcs(nullptr) -{ - NS_ADDREF(mDataSource); - NS_IF_ADDREF(mSource); - NS_IF_ADDREF(mTarget); - - if (mSource) { - // cast okay because it's a closed system - mAssertion = mDataSource->GetForwardArcs(mSource); - - if (mAssertion && mAssertion->mHashEntry) { - // its our magical HASH_ENTRY forward hash for assertions - mHashArcs = new nsCOMArray(); - for (auto i = mAssertion->u.hash.mPropertyHash->Iter(); - !i.Done(); - i.Next()) { - auto entry = static_cast(i.Get()); - mHashArcs->AppendElement(entry->mNode); - } - mAssertion = nullptr; - } - } - else { - mAssertion = mDataSource->GetReverseArcs(mTarget); - } -} - -InMemoryArcsEnumeratorImpl::~InMemoryArcsEnumeratorImpl() -{ -#ifdef DEBUG_REFS - --gInstanceCount; - fprintf(stdout, "%d - RDF: InMemoryArcsEnumeratorImpl\n", gInstanceCount); -#endif - - NS_RELEASE(mDataSource); - NS_IF_RELEASE(mSource); - NS_IF_RELEASE(mTarget); - NS_IF_RELEASE(mCurrent); - delete mHashArcs; -} - -NS_IMPL_ADDREF(InMemoryArcsEnumeratorImpl) -NS_IMPL_RELEASE(InMemoryArcsEnumeratorImpl) -NS_IMPL_QUERY_INTERFACE(InMemoryArcsEnumeratorImpl, nsISimpleEnumerator) - -NS_IMETHODIMP -InMemoryArcsEnumeratorImpl::HasMoreElements(bool* aResult) -{ - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - if (mCurrent) { - *aResult = true; - return NS_OK; - } - - if (mHashArcs) { - if (!mHashArcs->IsEmpty()) { - const uint32_t last = mHashArcs->Length() - 1; - nsCOMPtr tmp(do_QueryInterface(mHashArcs->ObjectAt(last))); - tmp.forget(&mCurrent); - mHashArcs->RemoveElementAt(last); - *aResult = true; - return NS_OK; - } - } - else - while (mAssertion) { - nsIRDFResource* next = mAssertion->u.as.mProperty; - - // "next" is the property arc we are tentatively going to return - // in a subsequent GetNext() call. It is important to do two - // things, however, before that can happen: - // 1) Make sure it's not an arc we've already returned. - // 2) Make sure that |mAssertion| is not left pointing to - // another assertion that has the same property as this one. - // The first is a practical concern; the second a defense against - // an obscure crash and other erratic behavior. To ensure the - // second condition, skip down the chain until we find the next - // assertion with a property that doesn't match the current one. - // (All these assertions would be skipped via mAlreadyReturned - // checks anyways; this is even a bit faster.) - - do { - mAssertion = (mSource ? mAssertion->mNext : - mAssertion->u.as.mInvNext); - } - while (mAssertion && (next == mAssertion->u.as.mProperty)); - - bool alreadyReturned = false; - for (int32_t i = mAlreadyReturned.Length() - 1; i >= 0; --i) { - if (mAlreadyReturned[i] == next) { - alreadyReturned = true; - break; - } - } - - if (! alreadyReturned) { - mCurrent = next; - NS_ADDREF(mCurrent); - *aResult = true; - return NS_OK; - } - } - - *aResult = false; - return NS_OK; -} - - -NS_IMETHODIMP -InMemoryArcsEnumeratorImpl::GetNext(nsISupports** aResult) -{ - nsresult rv; - - bool hasMore; - rv = HasMoreElements(&hasMore); - if (NS_FAILED(rv)) return rv; - - if (! hasMore) - return NS_ERROR_UNEXPECTED; - - // Add this to the set of things we've already returned so that we - // can ensure uniqueness - mAlreadyReturned.AppendElement(mCurrent); - - // Don't AddRef: we "transfer" ownership to the caller - *aResult = mCurrent; - mCurrent = nullptr; - - return NS_OK; -} - - -//////////////////////////////////////////////////////////////////////// -// InMemoryDataSource - -nsresult -NS_NewRDFInMemoryDataSource(nsISupports* aOuter, const nsIID& aIID, void** aResult) -{ - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - *aResult = nullptr; - - if (aOuter && !aIID.Equals(NS_GET_IID(nsISupports))) { - NS_ERROR("aggregation requires nsISupports"); - return NS_ERROR_ILLEGAL_VALUE; - } - - InMemoryDataSource* datasource = new InMemoryDataSource(aOuter); - NS_ADDREF(datasource); - - datasource->fAggregated.AddRef(); - nsresult rv = datasource->AggregatedQueryInterface(aIID, aResult); // This'll AddRef() - datasource->fAggregated.Release(); - - NS_RELEASE(datasource); - return rv; -} - - -InMemoryDataSource::InMemoryDataSource(nsISupports* aOuter) - : mForwardArcs(PLDHashTable::StubOps(), sizeof(Entry)) - , mReverseArcs(PLDHashTable::StubOps(), sizeof(Entry)) - , mNumObservers(0) - , mReadCount(0) -{ - NS_INIT_AGGREGATED(aOuter); - - mPropagateChanges = true; -} - - -InMemoryDataSource::~InMemoryDataSource() -{ -#ifdef DEBUG_REFS - --gInstanceCount; - fprintf(stdout, "%d - RDF: InMemoryDataSource\n", gInstanceCount); -#endif - - if (mForwardArcs.EntryCount() > 0) { - // This'll release all of the Assertion objects that are - // associated with this data source. We only need to do this - // for the forward arcs, because the reverse arcs table - // indexes the exact same set of resources. - for (auto iter = mForwardArcs.Iter(); !iter.Done(); iter.Next()) { - auto entry = static_cast(iter.Get()); - Assertion* as = entry->mAssertions; - while (as) { - Assertion* doomed = as; - as = as->mNext; - - // Unlink, and release the datasource's reference. - doomed->mNext = doomed->u.as.mInvNext = nullptr; - doomed->Release(); - } - } - } - - MOZ_LOG(gLog, LogLevel::Debug, - ("InMemoryDataSource(%p): destroyed.", this)); -} - - -//////////////////////////////////////////////////////////////////////// - -NS_IMPL_CYCLE_COLLECTION_CLASS(InMemoryDataSource) - -NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(InMemoryDataSource) - NS_IMPL_CYCLE_COLLECTION_UNLINK(mObservers) -NS_IMPL_CYCLE_COLLECTION_UNLINK_END -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_AGGREGATED(InMemoryDataSource) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mObservers) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END - -NS_IMPL_CYCLE_COLLECTING_AGGREGATED(InMemoryDataSource) -NS_INTERFACE_MAP_BEGIN_AGGREGATED(InMemoryDataSource) - NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION_AGGREGATED(InMemoryDataSource) - NS_INTERFACE_MAP_ENTRY(nsIRDFDataSource) - NS_INTERFACE_MAP_ENTRY(nsIRDFInMemoryDataSource) - NS_INTERFACE_MAP_ENTRY(nsIRDFPropagatableDataSource) - NS_INTERFACE_MAP_ENTRY(nsIRDFPurgeableDataSource) - NS_INTERFACE_MAP_ENTRY(rdfIDataSource) -NS_INTERFACE_MAP_END - -//////////////////////////////////////////////////////////////////////// - - -void -InMemoryDataSource::LogOperation(const char* aOperation, - nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue) -{ - if (! MOZ_LOG_TEST(gLog, LogLevel::Debug)) - return; - - nsCString uri; - aSource->GetValue(getter_Copies(uri)); - MOZ_LOG(gLog, LogLevel::Debug, - ("InMemoryDataSource(%p): %s", this, aOperation)); - - MOZ_LOG(gLog, LogLevel::Debug, - (" [(%p)%s]--", aSource, uri.get())); - - aProperty->GetValue(getter_Copies(uri)); - - char tv = (aTruthValue ? '-' : '!'); - MOZ_LOG(gLog, LogLevel::Debug, - (" --%c[(%p)%s]--", tv, aProperty, uri.get())); - - nsCOMPtr resource; - nsCOMPtr literal; - - if ((resource = do_QueryInterface(aTarget)) != nullptr) { - resource->GetValue(getter_Copies(uri)); - MOZ_LOG(gLog, LogLevel::Debug, - (" -->[(%p)%s]", aTarget, uri.get())); - } - else if ((literal = do_QueryInterface(aTarget)) != nullptr) { - nsString value; - literal->GetValue(getter_Copies(value)); - MOZ_LOG(gLog, LogLevel::Debug, - (" -->(\"%s\")\n", NS_ConvertUTF16toUTF8(value).get())); - } - else { - MOZ_LOG(gLog, LogLevel::Debug, - (" -->(unknown-type)\n")); - } -} - - -NS_IMETHODIMP -InMemoryDataSource::GetURI(nsACString& aURI) -{ - aURI.SetIsVoid(true); - return NS_OK; -} - -NS_IMETHODIMP -InMemoryDataSource::GetSource(nsIRDFResource* property, - nsIRDFNode* target, - bool tv, - nsIRDFResource** source) -{ - NS_PRECONDITION(source != nullptr, "null ptr"); - if (! source) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(property != nullptr, "null ptr"); - if (! property) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(target != nullptr, "null ptr"); - if (! target) - return NS_ERROR_NULL_POINTER; - - for (Assertion* as = GetReverseArcs(target); as; as = as->u.as.mInvNext) { - if ((property == as->u.as.mProperty) && (tv == as->u.as.mTruthValue)) { - *source = as->mSource; - NS_ADDREF(*source); - return NS_OK; - } - } - *source = nullptr; - return NS_RDF_NO_VALUE; -} - -NS_IMETHODIMP -InMemoryDataSource::GetTarget(nsIRDFResource* source, - nsIRDFResource* property, - bool tv, - nsIRDFNode** target) -{ - NS_PRECONDITION(source != nullptr, "null ptr"); - if (! source) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(property != nullptr, "null ptr"); - if (! property) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(target != nullptr, "null ptr"); - if (! target) - return NS_ERROR_NULL_POINTER; - - Assertion *as = GetForwardArcs(source); - if (as && as->mHashEntry) { - PLDHashEntryHdr* hdr = as->u.hash.mPropertyHash->Search(property); - Assertion* val = hdr ? static_cast(hdr)->mAssertions : nullptr; - while (val) { - if (tv == val->u.as.mTruthValue) { - *target = val->u.as.mTarget; - NS_IF_ADDREF(*target); - return NS_OK; - } - val = val->mNext; - } - } - else - for (; as != nullptr; as = as->mNext) { - if ((property == as->u.as.mProperty) && (tv == (as->u.as.mTruthValue))) { - *target = as->u.as.mTarget; - NS_ADDREF(*target); - return NS_OK; - } - } - - // If we get here, then there was no target with for the specified - // property & truth value. - *target = nullptr; - return NS_RDF_NO_VALUE; -} - -NS_IMETHODIMP -InMemoryDataSource::HasAssertion(nsIRDFResource* source, - nsIRDFResource* property, - nsIRDFNode* target, - bool tv, - bool* hasAssertion) -{ - if (! source) - return NS_ERROR_NULL_POINTER; - - if (! property) - return NS_ERROR_NULL_POINTER; - - if (! target) - return NS_ERROR_NULL_POINTER; - - Assertion *as = GetForwardArcs(source); - if (as && as->mHashEntry) { - PLDHashEntryHdr* hdr = as->u.hash.mPropertyHash->Search(property); - Assertion* val = hdr ? static_cast(hdr)->mAssertions : nullptr; - while (val) { - if ((val->u.as.mTarget == target) && (tv == (val->u.as.mTruthValue))) { - *hasAssertion = true; - return NS_OK; - } - val = val->mNext; - } - } - else - for (; as != nullptr; as = as->mNext) { - // check target first as its most unique - if (target != as->u.as.mTarget) - continue; - - if (property != as->u.as.mProperty) - continue; - - if (tv != (as->u.as.mTruthValue)) - continue; - - // found it! - *hasAssertion = true; - return NS_OK; - } - - // If we get here, we couldn't find the assertion - *hasAssertion = false; - return NS_OK; -} - -NS_IMETHODIMP -InMemoryDataSource::GetSources(nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue, - nsISimpleEnumerator** aResult) -{ - NS_PRECONDITION(aProperty != nullptr, "null ptr"); - if (! aProperty) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aTarget != nullptr, "null ptr"); - if (! aTarget) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - InMemoryAssertionEnumeratorImpl* result = - new InMemoryAssertionEnumeratorImpl(this, nullptr, aProperty, - aTarget, aTruthValue); - - if (! result) - return NS_ERROR_OUT_OF_MEMORY; - - NS_ADDREF(result); - *aResult = result; - - return NS_OK; -} - -NS_IMETHODIMP -InMemoryDataSource::GetTargets(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - bool aTruthValue, - nsISimpleEnumerator** aResult) -{ - NS_PRECONDITION(aSource != nullptr, "null ptr"); - if (! aSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aProperty != nullptr, "null ptr"); - if (! aProperty) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - InMemoryAssertionEnumeratorImpl* result = - new InMemoryAssertionEnumeratorImpl(this, aSource, aProperty, - nullptr, aTruthValue); - - if (! result) - return NS_ERROR_OUT_OF_MEMORY; - - NS_ADDREF(result); - *aResult = result; - - return NS_OK; -} - - -nsresult -InMemoryDataSource::LockedAssert(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue) -{ - LogOperation("ASSERT", aSource, aProperty, aTarget, aTruthValue); - - Assertion* next = GetForwardArcs(aSource); - Assertion* prev = next; - Assertion* as = nullptr; - - bool haveHash = (next) ? next->mHashEntry : false; - if (haveHash) { - PLDHashEntryHdr* hdr = next->u.hash.mPropertyHash->Search(aProperty); - Assertion* val = hdr ? static_cast(hdr)->mAssertions : nullptr; - while (val) { - if (val->u.as.mTarget == aTarget) { - // Wow, we already had the assertion. Make sure that the - // truth values are correct and bail. - val->u.as.mTruthValue = aTruthValue; - return NS_OK; - } - val = val->mNext; - } - } - else - { - while (next) { - // check target first as its most unique - if (aTarget == next->u.as.mTarget) { - if (aProperty == next->u.as.mProperty) { - // Wow, we already had the assertion. Make sure that the - // truth values are correct and bail. - next->u.as.mTruthValue = aTruthValue; - return NS_OK; - } - } - - prev = next; - next = next->mNext; - } - } - - as = new Assertion(aSource, aProperty, aTarget, aTruthValue); - if (! as) - return NS_ERROR_OUT_OF_MEMORY; - - // Add the datasource's owning reference. - as->AddRef(); - - if (haveHash) - { - PLDHashEntryHdr* hdr = next->u.hash.mPropertyHash->Search(aProperty); - Assertion *asRef = - hdr ? static_cast(hdr)->mAssertions : nullptr; - if (asRef) - { - as->mNext = asRef->mNext; - asRef->mNext = as; - } - else - { - hdr = next->u.hash.mPropertyHash->Add(aProperty, mozilla::fallible); - if (hdr) - { - Entry* entry = static_cast(hdr); - entry->mNode = aProperty; - entry->mAssertions = as; - } - } - } - else - { - // Link it in to the "forward arcs" table - if (!prev) { - SetForwardArcs(aSource, as); - } else { - prev->mNext = as; - } - } - - // Link it in to the "reverse arcs" table - - next = GetReverseArcs(aTarget); - as->u.as.mInvNext = next; - next = as; - SetReverseArcs(aTarget, next); - - return NS_OK; -} - -NS_IMETHODIMP -InMemoryDataSource::Assert(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue) -{ - NS_PRECONDITION(aSource != nullptr, "null ptr"); - if (! aSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aProperty != nullptr, "null ptr"); - if (! aProperty) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aTarget != nullptr, "null ptr"); - if (! aTarget) - return NS_ERROR_NULL_POINTER; - - if (mReadCount) { - NS_WARNING("Writing to InMemoryDataSource during read\n"); - return NS_RDF_ASSERTION_REJECTED; - } - - nsresult rv; - rv = LockedAssert(aSource, aProperty, aTarget, aTruthValue); - if (NS_FAILED(rv)) return rv; - - // notify observers - for (int32_t i = (int32_t)mNumObservers - 1; mPropagateChanges && i >= 0; --i) { - nsIRDFObserver* obs = mObservers[i]; - - // XXX this should never happen, but it does, and we can't figure out why. - NS_ASSERTION(obs, "observer array corrupted!"); - if (! obs) - continue; - - obs->OnAssert(this, aSource, aProperty, aTarget); - // XXX ignore return value? - } - - return NS_RDF_ASSERTION_ACCEPTED; -} - - -nsresult -InMemoryDataSource::LockedUnassert(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget) -{ - LogOperation("UNASSERT", aSource, aProperty, aTarget); - - Assertion* next = GetForwardArcs(aSource); - Assertion* prev = next; - Assertion* root = next; - Assertion* as = nullptr; - - bool haveHash = (next) ? next->mHashEntry : false; - if (haveHash) { - PLDHashEntryHdr* hdr = next->u.hash.mPropertyHash->Search(aProperty); - prev = next = hdr ? static_cast(hdr)->mAssertions : nullptr; - bool first = true; - while (next) { - if (aTarget == next->u.as.mTarget) { - break; - } - first = false; - prev = next; - next = next->mNext; - } - // We don't even have the assertion, so just bail. - if (!next) - return NS_OK; - - as = next; - - if (first) { - root->u.hash.mPropertyHash->RawRemove(hdr); - - if (next && next->mNext) { - PLDHashEntryHdr* hdr = - root->u.hash.mPropertyHash->Add(aProperty, - mozilla::fallible); - if (hdr) { - Entry* entry = static_cast(hdr); - entry->mNode = aProperty; - entry->mAssertions = next->mNext; - } - } - else { - // If this second-level hash empties out, clean it up. - if (!root->u.hash.mPropertyHash->EntryCount()) { - root->Release(); - SetForwardArcs(aSource, nullptr); - } - } - } - else { - prev->mNext = next->mNext; - } - } - else - { - while (next) { - // check target first as its most unique - if (aTarget == next->u.as.mTarget) { - if (aProperty == next->u.as.mProperty) { - if (prev == next) { - SetForwardArcs(aSource, next->mNext); - } else { - prev->mNext = next->mNext; - } - as = next; - break; - } - } - - prev = next; - next = next->mNext; - } - } - // We don't even have the assertion, so just bail. - if (!as) - return NS_OK; - -#ifdef DEBUG - bool foundReverseArc = false; -#endif - - next = prev = GetReverseArcs(aTarget); - while (next) { - if (next == as) { - if (prev == next) { - SetReverseArcs(aTarget, next->u.as.mInvNext); - } else { - prev->u.as.mInvNext = next->u.as.mInvNext; - } -#ifdef DEBUG - foundReverseArc = true; -#endif - break; - } - prev = next; - next = next->u.as.mInvNext; - } - -#ifdef DEBUG - NS_ASSERTION(foundReverseArc, "in-memory db corrupted: unable to find reverse arc"); -#endif - - // Unlink, and release the datasource's reference - as->mNext = as->u.as.mInvNext = nullptr; - as->Release(); - - return NS_OK; -} - -NS_IMETHODIMP -InMemoryDataSource::Unassert(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget) -{ - NS_PRECONDITION(aSource != nullptr, "null ptr"); - if (! aSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aProperty != nullptr, "null ptr"); - if (! aProperty) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aTarget != nullptr, "null ptr"); - if (! aTarget) - return NS_ERROR_NULL_POINTER; - - if (mReadCount) { - NS_WARNING("Writing to InMemoryDataSource during read\n"); - return NS_RDF_ASSERTION_REJECTED; - } - - nsresult rv; - - rv = LockedUnassert(aSource, aProperty, aTarget); - if (NS_FAILED(rv)) return rv; - - // Notify the world - for (int32_t i = int32_t(mNumObservers) - 1; mPropagateChanges && i >= 0; --i) { - nsIRDFObserver* obs = mObservers[i]; - - // XXX this should never happen, but it does, and we can't figure out why. - NS_ASSERTION(obs, "observer array corrupted!"); - if (! obs) - continue; - - obs->OnUnassert(this, aSource, aProperty, aTarget); - // XXX ignore return value? - } - - return NS_RDF_ASSERTION_ACCEPTED; -} - - -NS_IMETHODIMP -InMemoryDataSource::Change(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aOldTarget, - nsIRDFNode* aNewTarget) -{ - NS_PRECONDITION(aSource != nullptr, "null ptr"); - if (! aSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aProperty != nullptr, "null ptr"); - if (! aProperty) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aOldTarget != nullptr, "null ptr"); - if (! aOldTarget) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aNewTarget != nullptr, "null ptr"); - if (! aNewTarget) - return NS_ERROR_NULL_POINTER; - - if (mReadCount) { - NS_WARNING("Writing to InMemoryDataSource during read\n"); - return NS_RDF_ASSERTION_REJECTED; - } - - nsresult rv; - - // XXX We can implement LockedChange() if we decide that this - // is a performance bottleneck. - - rv = LockedUnassert(aSource, aProperty, aOldTarget); - if (NS_FAILED(rv)) return rv; - - rv = LockedAssert(aSource, aProperty, aNewTarget, true); - if (NS_FAILED(rv)) return rv; - - // Notify the world - for (int32_t i = int32_t(mNumObservers) - 1; mPropagateChanges && i >= 0; --i) { - nsIRDFObserver* obs = mObservers[i]; - - // XXX this should never happen, but it does, and we can't figure out why. - NS_ASSERTION(obs, "observer array corrupted!"); - if (! obs) - continue; - - obs->OnChange(this, aSource, aProperty, aOldTarget, aNewTarget); - // XXX ignore return value? - } - - return NS_RDF_ASSERTION_ACCEPTED; -} - - -NS_IMETHODIMP -InMemoryDataSource::Move(nsIRDFResource* aOldSource, - nsIRDFResource* aNewSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget) -{ - NS_PRECONDITION(aOldSource != nullptr, "null ptr"); - if (! aOldSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aNewSource != nullptr, "null ptr"); - if (! aNewSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aProperty != nullptr, "null ptr"); - if (! aProperty) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aTarget != nullptr, "null ptr"); - if (! aTarget) - return NS_ERROR_NULL_POINTER; - - if (mReadCount) { - NS_WARNING("Writing to InMemoryDataSource during read\n"); - return NS_RDF_ASSERTION_REJECTED; - } - - nsresult rv; - - // XXX We can implement LockedMove() if we decide that this - // is a performance bottleneck. - - rv = LockedUnassert(aOldSource, aProperty, aTarget); - if (NS_FAILED(rv)) return rv; - - rv = LockedAssert(aNewSource, aProperty, aTarget, true); - if (NS_FAILED(rv)) return rv; - - // Notify the world - for (int32_t i = int32_t(mNumObservers) - 1; mPropagateChanges && i >= 0; --i) { - nsIRDFObserver* obs = mObservers[i]; - - // XXX this should never happen, but it does, and we can't figure out why. - NS_ASSERTION(obs, "observer array corrupted!"); - if (! obs) - continue; - - obs->OnMove(this, aOldSource, aNewSource, aProperty, aTarget); - // XXX ignore return value? - } - - return NS_RDF_ASSERTION_ACCEPTED; -} - - -NS_IMETHODIMP -InMemoryDataSource::AddObserver(nsIRDFObserver* aObserver) -{ - NS_PRECONDITION(aObserver != nullptr, "null ptr"); - if (! aObserver) - return NS_ERROR_NULL_POINTER; - - mObservers.AppendObject(aObserver); - mNumObservers = mObservers.Count(); - - return NS_OK; -} - -NS_IMETHODIMP -InMemoryDataSource::RemoveObserver(nsIRDFObserver* aObserver) -{ - NS_PRECONDITION(aObserver != nullptr, "null ptr"); - if (! aObserver) - return NS_ERROR_NULL_POINTER; - - mObservers.RemoveObject(aObserver); - // note: use Count() instead of just decrementing - // in case aObserver wasn't in list, for example - mNumObservers = mObservers.Count(); - - return NS_OK; -} - -NS_IMETHODIMP -InMemoryDataSource::HasArcIn(nsIRDFNode *aNode, nsIRDFResource *aArc, bool *result) -{ - Assertion* ass = GetReverseArcs(aNode); - while (ass) { - nsIRDFResource* elbow = ass->u.as.mProperty; - if (elbow == aArc) { - *result = true; - return NS_OK; - } - ass = ass->u.as.mInvNext; - } - *result = false; - return NS_OK; -} - -NS_IMETHODIMP -InMemoryDataSource::HasArcOut(nsIRDFResource *aSource, nsIRDFResource *aArc, bool *result) -{ - Assertion* ass = GetForwardArcs(aSource); - if (ass && ass->mHashEntry) { - PLDHashEntryHdr* hdr = ass->u.hash.mPropertyHash->Search(aArc); - Assertion* val = hdr ? static_cast(hdr)->mAssertions : nullptr; - if (val) { - *result = true; - return NS_OK; - } - ass = ass->mNext; - } - while (ass) { - nsIRDFResource* elbow = ass->u.as.mProperty; - if (elbow == aArc) { - *result = true; - return NS_OK; - } - ass = ass->mNext; - } - *result = false; - return NS_OK; -} - -NS_IMETHODIMP -InMemoryDataSource::ArcLabelsIn(nsIRDFNode* aTarget, nsISimpleEnumerator** aResult) -{ - NS_PRECONDITION(aTarget != nullptr, "null ptr"); - if (! aTarget) - return NS_ERROR_NULL_POINTER; - - InMemoryArcsEnumeratorImpl* result = - new InMemoryArcsEnumeratorImpl(this, nullptr, aTarget); - - if (! result) - return NS_ERROR_OUT_OF_MEMORY; - - NS_ADDREF(result); - *aResult = result; - - return NS_OK; -} - -NS_IMETHODIMP -InMemoryDataSource::ArcLabelsOut(nsIRDFResource* aSource, nsISimpleEnumerator** aResult) -{ - NS_PRECONDITION(aSource != nullptr, "null ptr"); - if (! aSource) - return NS_ERROR_NULL_POINTER; - - InMemoryArcsEnumeratorImpl* result = - new InMemoryArcsEnumeratorImpl(this, aSource, nullptr); - - if (! result) - return NS_ERROR_OUT_OF_MEMORY; - - NS_ADDREF(result); - *aResult = result; - - return NS_OK; -} - - -NS_IMETHODIMP -InMemoryDataSource::GetAllResources(nsISimpleEnumerator** aResult) -{ - nsCOMArray nodes; - nodes.SetCapacity(mForwardArcs.EntryCount()); - - // Get all of our entries into an nsCOMArray - for (auto iter = mForwardArcs.Iter(); !iter.Done(); iter.Next()) { - auto entry = static_cast(iter.Get()); - nodes.AppendObject(entry->mNode); - } - return NS_NewArrayEnumerator(aResult, nodes); -} - -NS_IMETHODIMP -InMemoryDataSource::GetAllCmds(nsIRDFResource* source, - nsISimpleEnumerator/**/** commands) -{ - return(NS_NewEmptyEnumerator(commands)); -} - -NS_IMETHODIMP -InMemoryDataSource::IsCommandEnabled(nsISupports* aSources, - nsIRDFResource* aCommand, - nsISupports* aArguments, - bool* aResult) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -InMemoryDataSource::DoCommand(nsISupports* aSources, - nsIRDFResource* aCommand, - nsISupports* aArguments) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -InMemoryDataSource::BeginUpdateBatch() -{ - for (int32_t i = int32_t(mNumObservers) - 1; mPropagateChanges && i >= 0; --i) { - nsIRDFObserver* obs = mObservers[i]; - obs->OnBeginUpdateBatch(this); - } - return NS_OK; -} - -NS_IMETHODIMP -InMemoryDataSource::EndUpdateBatch() -{ - for (int32_t i = int32_t(mNumObservers) - 1; mPropagateChanges && i >= 0; --i) { - nsIRDFObserver* obs = mObservers[i]; - obs->OnEndUpdateBatch(this); - } - return NS_OK; -} - - - -//////////////////////////////////////////////////////////////////////// -// nsIRDFInMemoryDataSource methods - -NS_IMETHODIMP -InMemoryDataSource::EnsureFastContainment(nsIRDFResource* aSource) -{ - Assertion *as = GetForwardArcs(aSource); - bool haveHash = (as) ? as->mHashEntry : false; - - // if its already a hash, then nothing to do - if (haveHash) return(NS_OK); - - // convert aSource in forward hash into a hash - Assertion *hashAssertion = new Assertion(aSource); - NS_ASSERTION(hashAssertion, "unable to create Assertion"); - if (!hashAssertion) return(NS_ERROR_OUT_OF_MEMORY); - - // Add the datasource's owning reference. - hashAssertion->AddRef(); - - Assertion *first = GetForwardArcs(aSource); - SetForwardArcs(aSource, hashAssertion); - - // mutate references of existing forward assertions into this hash - PLDHashTable *table = hashAssertion->u.hash.mPropertyHash; - Assertion *nextRef; - while(first) { - nextRef = first->mNext; - nsIRDFResource *prop = first->u.as.mProperty; - - PLDHashEntryHdr* hdr = table->Search(prop); - Assertion* val = hdr ? static_cast(hdr)->mAssertions : nullptr; - if (val) { - first->mNext = val->mNext; - val->mNext = first; - } - else { - PLDHashEntryHdr* hdr = table->Add(prop, mozilla::fallible); - if (hdr) { - Entry* entry = static_cast(hdr); - entry->mNode = prop; - entry->mAssertions = first; - first->mNext = nullptr; - } - } - first = nextRef; - } - return(NS_OK); -} - - -//////////////////////////////////////////////////////////////////////// -// nsIRDFPropagatableDataSource methods -NS_IMETHODIMP -InMemoryDataSource::GetPropagateChanges(bool* aPropagateChanges) -{ - *aPropagateChanges = mPropagateChanges; - return NS_OK; -} - -NS_IMETHODIMP -InMemoryDataSource::SetPropagateChanges(bool aPropagateChanges) -{ - mPropagateChanges = aPropagateChanges; - return NS_OK; -} - - -//////////////////////////////////////////////////////////////////////// -// nsIRDFPurgeableDataSource methods - -NS_IMETHODIMP -InMemoryDataSource::Mark(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue, - bool* aDidMark) -{ - NS_PRECONDITION(aSource != nullptr, "null ptr"); - if (! aSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aProperty != nullptr, "null ptr"); - if (! aProperty) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aTarget != nullptr, "null ptr"); - if (! aTarget) - return NS_ERROR_NULL_POINTER; - - Assertion *as = GetForwardArcs(aSource); - if (as && as->mHashEntry) { - PLDHashEntryHdr* hdr = as->u.hash.mPropertyHash->Search(aProperty); - Assertion* val = hdr ? static_cast(hdr)->mAssertions : nullptr; - while (val) { - if ((val->u.as.mTarget == aTarget) && - (aTruthValue == (val->u.as.mTruthValue))) { - - // found it! so mark it. - as->Mark(); - *aDidMark = true; - - LogOperation("MARK", aSource, aProperty, aTarget, aTruthValue); - - return NS_OK; - } - val = val->mNext; - } - } - else for (; as != nullptr; as = as->mNext) { - // check target first as its most unique - if (aTarget != as->u.as.mTarget) - continue; - - if (aProperty != as->u.as.mProperty) - continue; - - if (aTruthValue != (as->u.as.mTruthValue)) - continue; - - // found it! so mark it. - as->Mark(); - *aDidMark = true; - - LogOperation("MARK", aSource, aProperty, aTarget, aTruthValue); - - return NS_OK; - } - - // If we get here, we couldn't find the assertion - *aDidMark = false; - return NS_OK; -} - -NS_IMETHODIMP -InMemoryDataSource::Sweep() -{ - SweepInfo info = { nullptr, &mReverseArcs }; - - // Remove all the assertions, but don't notify anyone. - SweepForwardArcsEntries(&mForwardArcs, &info); - - // Now do the notification. - Assertion* as = info.mUnassertList; - while (as) { - LogOperation("SWEEP", as->mSource, as->u.as.mProperty, as->u.as.mTarget, as->u.as.mTruthValue); - if (!(as->mHashEntry)) - { - for (int32_t i = int32_t(mNumObservers) - 1; mPropagateChanges && i >= 0; --i) { - nsIRDFObserver* obs = mObservers[i]; - // XXXbz other loops over mObservers null-check |obs| here! - obs->OnUnassert(this, as->mSource, as->u.as.mProperty, as->u.as.mTarget); - // XXX ignore return value? - } - } - - Assertion* doomed = as; - as = as->mNext; - - // Unlink, and release the datasource's reference - doomed->mNext = doomed->u.as.mInvNext = nullptr; - doomed->Release(); - } - - return NS_OK; -} - - -void -InMemoryDataSource::SweepForwardArcsEntries(PLDHashTable* aTable, - SweepInfo* aInfo) -{ - for (auto iter = aTable->Iter(); !iter.Done(); iter.Next()) { - auto entry = static_cast(iter.Get()); - - Assertion* as = entry->mAssertions; - if (as && (as->mHashEntry)) { - // Stuff in sub-hashes must be swept recursively (max depth: 1) - SweepForwardArcsEntries(as->u.hash.mPropertyHash, aInfo); - - // If the sub-hash is now empty, clean it up. - if (!as->u.hash.mPropertyHash->EntryCount()) { - as->Release(); - iter.Remove(); - } - continue; - } - - Assertion* prev = nullptr; - while (as) { - if (as->IsMarked()) { - prev = as; - as->Unmark(); - as = as->mNext; - } - else { - // remove from the list of assertions in the datasource - Assertion* next = as->mNext; - if (prev) { - prev->mNext = next; - } - else { - // it's the first one. update the hashtable entry. - entry->mAssertions = next; - } - - // remove from the reverse arcs - PLDHashEntryHdr* hdr = - aInfo->mReverseArcs->Search(as->u.as.mTarget); - NS_ASSERTION(hdr, "no assertion in reverse arcs"); - - Entry* rentry = static_cast(hdr); - Assertion* ras = rentry->mAssertions; - Assertion* rprev = nullptr; - while (ras) { - if (ras == as) { - if (rprev) { - rprev->u.as.mInvNext = ras->u.as.mInvNext; - } - else { - // it's the first one. update the hashtable entry. - rentry->mAssertions = ras->u.as.mInvNext; - } - as->u.as.mInvNext = nullptr; // for my sanity. - break; - } - rprev = ras; - ras = ras->u.as.mInvNext; - } - - // Wow, it was the _only_ one. Unhash it. - if (! rentry->mAssertions) { - aInfo->mReverseArcs->RawRemove(hdr); - } - - // add to the list of assertions to unassert - as->mNext = aInfo->mUnassertList; - aInfo->mUnassertList = as; - - // Advance to the next assertion - as = next; - } - } - - // if no more assertions exist for this resource, then unhash it. - if (! entry->mAssertions) { - iter.Remove(); - } - } -} - -//////////////////////////////////////////////////////////////////////// -// rdfIDataSource methods - -NS_IMETHODIMP -InMemoryDataSource::VisitAllSubjects(rdfITripleVisitor *aVisitor) -{ - // Lock datasource against writes - ++mReadCount; - - // Enumerate all of our entries. - nsresult rv = NS_OK; - for (auto iter = mForwardArcs.Iter(); !iter.Done(); iter.Next()) { - auto entry = static_cast(iter.Get()); - nsresult rv2; - nsCOMPtr subject = do_QueryInterface(entry->mNode, &rv2); - if (NS_FAILED(rv2)) { - NS_WARNING("QI to nsIRDFNode failed"); - continue; - } - rv = aVisitor->Visit(subject, nullptr, nullptr, true); - if (NS_FAILED(rv) || rv == NS_RDF_STOP_VISIT) { - break; - } - } - - // Unlock datasource - --mReadCount; - - return rv; -} - -NS_IMETHODIMP -InMemoryDataSource::VisitAllTriples(rdfITripleVisitor *aVisitor) -{ - // Lock datasource against writes - ++mReadCount; - - // Enumerate all of our entries. - nsresult rv = NS_OK; - for (auto iter = mForwardArcs.Iter(); !iter.Done(); iter.Next()) { - auto entry = static_cast(iter.Get()); - - nsresult rv2; - nsCOMPtr subject = do_QueryInterface(entry->mNode, &rv2); - if (NS_FAILED(rv2)) { - NS_WARNING("QI to nsIRDFNode failed"); - - } else if (entry->mAssertions->mHashEntry) { - for (auto iter = entry->mAssertions->u.hash.mPropertyHash->Iter(); - !iter.Done(); - iter.Next()) { - auto entry = static_cast(iter.Get()); - Assertion* assertion = entry->mAssertions; - while (assertion) { - NS_ASSERTION(!assertion->mHashEntry, "shouldn't have to hashes"); - rv = aVisitor->Visit(subject, assertion->u.as.mProperty, - assertion->u.as.mTarget, - assertion->u.as.mTruthValue); - if (NS_FAILED(rv)) { - goto end; - } - if (rv == NS_RDF_STOP_VISIT) { - goto inner_end; - } - assertion = assertion->mNext; - } - } - - } else { - Assertion* assertion = entry->mAssertions; - while (assertion) { - NS_ASSERTION(!assertion->mHashEntry, "shouldn't have to hashes"); - rv = aVisitor->Visit(subject, assertion->u.as.mProperty, - assertion->u.as.mTarget, - assertion->u.as.mTruthValue); - if (NS_FAILED(rv) || rv == NS_RDF_STOP_VISIT) { - goto end; - } - assertion = assertion->mNext; - } - } - - inner_end: - (void) 0; - } - - end: - // Unlock datasource - --mReadCount; - - return rv; -} - -//////////////////////////////////////////////////////////////////////// - diff --git a/rdf/base/nsNameSpaceMap.cpp b/rdf/base/nsNameSpaceMap.cpp deleted file mode 100644 index 4ddf945c6f54..000000000000 --- a/rdf/base/nsNameSpaceMap.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* -*- 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/. */ - -#include "nsNameSpaceMap.h" -#include "nsReadableUtils.h" - -nsNameSpaceMap::nsNameSpaceMap() - : mEntries(nullptr) -{ - MOZ_COUNT_CTOR(nsNameSpaceMap); -} - -nsNameSpaceMap::~nsNameSpaceMap() -{ - MOZ_COUNT_DTOR(nsNameSpaceMap); - - while (mEntries) { - Entry* doomed = mEntries; - mEntries = mEntries->mNext; - delete doomed; - } -} - -nsresult -nsNameSpaceMap::Put(const nsAString& aURI, nsAtom* aPrefix) -{ - nsCString uriUTF8; - AppendUTF16toUTF8(aURI, uriUTF8); - return Put(uriUTF8, aPrefix); -} - -nsresult -nsNameSpaceMap::Put(const nsACString& aURI, nsAtom* aPrefix) -{ - Entry* entry; - - // Make sure we're not adding a duplicate - for (entry = mEntries; entry != nullptr; entry = entry->mNext) { - if (entry->mURI == aURI || entry->mPrefix == aPrefix) - return NS_ERROR_FAILURE; - } - - entry = new Entry(aURI, aPrefix); - if (! entry) - return NS_ERROR_OUT_OF_MEMORY; - - entry->mNext = mEntries; - mEntries = entry; - return NS_OK; -} - -nsNameSpaceMap::const_iterator -nsNameSpaceMap::GetNameSpaceOf(const nsACString& aURI) const -{ - for (Entry* entry = mEntries; entry != nullptr; entry = entry->mNext) { - if (StringBeginsWith(aURI, entry->mURI)) - return const_iterator(entry); - } - - return last(); -} diff --git a/rdf/base/nsNameSpaceMap.h b/rdf/base/nsNameSpaceMap.h deleted file mode 100644 index 96a80fd13f13..000000000000 --- a/rdf/base/nsNameSpaceMap.h +++ /dev/null @@ -1,98 +0,0 @@ -/* -*- 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/. */ - -#ifndef nsNameSpaceMap_h__ -#define nsNameSpaceMap_h__ - -#include "nsCOMPtr.h" -#include "nsString.h" -#include "nsAtom.h" - -class nsNameSpaceMap -{ -public: - class Entry { - public: - Entry(const nsACString& aURI, nsAtom* aPrefix) - : mURI(aURI), mPrefix(aPrefix), mNext(nullptr) { - MOZ_COUNT_CTOR(nsNameSpaceMap::Entry); } - - ~Entry() { MOZ_COUNT_DTOR(nsNameSpaceMap::Entry); } - - nsCString mURI; - RefPtr mPrefix; - - Entry* mNext; - }; - - nsNameSpaceMap(); - ~nsNameSpaceMap(); - - nsresult - Put(const nsAString& aURI, nsAtom* aPrefix); - - nsresult - Put(const nsACString& aURI, nsAtom* aPrefix); - - class const_iterator { - protected: - friend class nsNameSpaceMap; - - explicit const_iterator(const Entry* aCurrent) - : mCurrent(aCurrent) {} - - const Entry* mCurrent; - - public: - const_iterator() - : mCurrent(nullptr) {} - - const_iterator(const const_iterator& iter) - : mCurrent(iter.mCurrent) {} - - const_iterator& - operator=(const const_iterator& iter) { - mCurrent = iter.mCurrent; - return *this; } - - const_iterator& - operator++() { - mCurrent = mCurrent->mNext; - return *this; } - - const_iterator - operator++(int) { - const_iterator tmp(*this); - mCurrent = mCurrent->mNext; - return tmp; } - - const Entry* operator->() const { return mCurrent; } - - const Entry& operator*() const { return *mCurrent; } - - bool - operator==(const const_iterator& iter) const { - return mCurrent == iter.mCurrent; } - - bool - operator!=(const const_iterator& iter) const { - return ! iter.operator==(*this); } - }; - - const_iterator first() const { - return const_iterator(mEntries); } - - const_iterator last() const { - return const_iterator(nullptr); } - - const_iterator GetNameSpaceOf(const nsACString& aURI) const; - -protected: - Entry* mEntries; -}; - - -#endif // nsNameSpaceMap_h__ diff --git a/rdf/base/nsRDFBaseDataSources.h b/rdf/base/nsRDFBaseDataSources.h deleted file mode 100644 index 0243e1359559..000000000000 --- a/rdf/base/nsRDFBaseDataSources.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -*- 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 header file just contains prototypes for the factory methods - for "builtin" data sources that are included in rdf.dll. - - Each of these data sources is exposed to the external world via its - CID in ../include/nsRDFCID.h. - -*/ - -#ifndef nsBaseDataSources_h__ -#define nsBaseDataSources_h__ - -#include "nsError.h" -class nsIRDFDataSource; - -// in nsInMemoryDataSource.cpp -nsresult -NS_NewRDFInMemoryDataSource(nsISupports* aOuter, const nsIID& aIID, void** aResult); - -// in nsRDFXMLDataSource.cpp -extern nsresult -NS_NewRDFXMLDataSource(nsIRDFDataSource** aResult); - -#endif // nsBaseDataSources_h__ - - diff --git a/rdf/base/nsRDFContainer.cpp b/rdf/base/nsRDFContainer.cpp deleted file mode 100644 index 1ef97ab0f0d3..000000000000 --- a/rdf/base/nsRDFContainer.cpp +++ /dev/null @@ -1,724 +0,0 @@ -/* -*- 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/. */ - -/* - - Implementation for the RDF container. - - Notes - ----- - - 1. RDF containers are one-indexed. This means that a lot of the loops - that you'd normally think you'd write like this: - - for (i = 0; i < count; ++i) {} - - You've gotta write like this: - - for (i = 1; i <= count; ++i) {} - - "Sure, right, yeah, of course.", you say. Well maybe I'm just - thick, but it's easy to slip up. - - 2. The RDF:nextVal property on the container is an - implementation-level hack that is used to quickly compute the - next value for appending to the container. It will no doubt - become royally screwed up in the case of aggregation. - - 3. The RDF:nextVal property is also used to retrieve the count of - elements in the container. - - */ - - -#include "nsCOMPtr.h" -#include "nsIRDFContainer.h" -#include "nsIRDFContainerUtils.h" -#include "nsIRDFInMemoryDataSource.h" -#include "nsIRDFPropagatableDataSource.h" -#include "nsIRDFService.h" -#include "nsIServiceManager.h" -#include "nsRDFCID.h" -#include "nsString.h" -#include "rdf.h" - -#define RDF_SEQ_LIST_LIMIT 8 - -class RDFContainerImpl : public nsIRDFContainer -{ -public: - - // nsISupports interface - NS_DECL_ISUPPORTS - - // nsIRDFContainer interface - NS_DECL_NSIRDFCONTAINER - -private: - friend nsresult NS_NewRDFContainer(nsIRDFContainer** aResult); - - RDFContainerImpl(); - virtual ~RDFContainerImpl(); - - nsresult Init(); - - nsresult Renumber(int32_t aStartIndex, int32_t aIncrement); - nsresult SetNextValue(int32_t aIndex); - nsresult GetNextValue(nsIRDFResource** aResult); - - nsIRDFDataSource* mDataSource; - nsIRDFResource* mContainer; - - // pseudo constants - static int32_t gRefCnt; - static nsIRDFService* gRDFService; - static nsIRDFContainerUtils* gRDFContainerUtils; - static nsIRDFResource* kRDF_nextVal; -}; - - -int32_t RDFContainerImpl::gRefCnt = 0; -nsIRDFService* RDFContainerImpl::gRDFService; -nsIRDFContainerUtils* RDFContainerImpl::gRDFContainerUtils; -nsIRDFResource* RDFContainerImpl::kRDF_nextVal; - -//////////////////////////////////////////////////////////////////////// -// nsISupports interface - -NS_IMPL_ISUPPORTS(RDFContainerImpl, nsIRDFContainer) - - - -//////////////////////////////////////////////////////////////////////// -// nsIRDFContainer interface - -NS_IMETHODIMP -RDFContainerImpl::GetDataSource(nsIRDFDataSource** _retval) -{ - *_retval = mDataSource; - NS_IF_ADDREF(*_retval); - return NS_OK; -} - - -NS_IMETHODIMP -RDFContainerImpl::GetResource(nsIRDFResource** _retval) -{ - *_retval = mContainer; - NS_IF_ADDREF(*_retval); - return NS_OK; -} - - -NS_IMETHODIMP -RDFContainerImpl::Init(nsIRDFDataSource *aDataSource, nsIRDFResource *aContainer) -{ - NS_PRECONDITION(aDataSource != nullptr, "null ptr"); - if (! aDataSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aContainer != nullptr, "null ptr"); - if (! aContainer) - return NS_ERROR_NULL_POINTER; - - nsresult rv; - bool isContainer; - rv = gRDFContainerUtils->IsContainer(aDataSource, aContainer, &isContainer); - if (NS_FAILED(rv)) return rv; - - // ``throw'' if we can't create a container on the specified - // datasource/resource combination. - if (! isContainer) - return NS_ERROR_FAILURE; - - NS_IF_RELEASE(mDataSource); - mDataSource = aDataSource; - NS_ADDREF(mDataSource); - - NS_IF_RELEASE(mContainer); - mContainer = aContainer; - NS_ADDREF(mContainer); - - return NS_OK; -} - - -NS_IMETHODIMP -RDFContainerImpl::GetCount(int32_t *aCount) -{ - if (!mDataSource || !mContainer) - return NS_ERROR_NOT_INITIALIZED; - - nsresult rv; - - // Get the next value, which hangs off of the bag via the - // RDF:nextVal property. This is the _next value_ that will get - // assigned in a one-indexed array. So, it's actually _one more_ - // than the actual count of elements in the container. - // - // XXX To handle aggregation, this should probably be a - // GetTargets() that enumerates all of the values and picks the - // largest one. - nsCOMPtr nextValNode; - rv = mDataSource->GetTarget(mContainer, kRDF_nextVal, true, getter_AddRefs(nextValNode)); - if (NS_FAILED(rv)) return rv; - - if (rv == NS_RDF_NO_VALUE) - return NS_ERROR_UNEXPECTED; - - nsCOMPtr nextValLiteral; - rv = nextValNode->QueryInterface(NS_GET_IID(nsIRDFLiteral), getter_AddRefs(nextValLiteral)); - if (NS_FAILED(rv)) return rv; - - const char16_t *s; - rv = nextValLiteral->GetValueConst( &s ); - if (NS_FAILED(rv)) return rv; - - nsAutoString nextValStr(s); - - int32_t nextVal; - nsresult err; - nextVal = nextValStr.ToInteger(&err); - if (NS_FAILED(err)) - return NS_ERROR_UNEXPECTED; - - *aCount = nextVal - 1; - return NS_OK; -} - - -NS_IMETHODIMP -RDFContainerImpl::GetElements(nsISimpleEnumerator **_retval) -{ - if (!mDataSource || !mContainer) - return NS_ERROR_NOT_INITIALIZED; - - return NS_NewContainerEnumerator(mDataSource, mContainer, _retval); -} - - -NS_IMETHODIMP -RDFContainerImpl::AppendElement(nsIRDFNode *aElement) -{ - if (!mDataSource || !mContainer) - return NS_ERROR_NOT_INITIALIZED; - - NS_PRECONDITION(aElement != nullptr, "null ptr"); - if (! aElement) - return NS_ERROR_NULL_POINTER; - - nsresult rv; - - nsCOMPtr nextVal; - rv = GetNextValue(getter_AddRefs(nextVal)); - if (NS_FAILED(rv)) return rv; - - rv = mDataSource->Assert(mContainer, nextVal, aElement, true); - if (NS_FAILED(rv)) return rv; - - return NS_OK; -} - - -NS_IMETHODIMP -RDFContainerImpl::RemoveElement(nsIRDFNode *aElement, bool aRenumber) -{ - if (!mDataSource || !mContainer) - return NS_ERROR_NOT_INITIALIZED; - - NS_PRECONDITION(aElement != nullptr, "null ptr"); - if (! aElement) - return NS_ERROR_NULL_POINTER; - - nsresult rv; - - int32_t idx; - rv = IndexOf(aElement, &idx); - if (NS_FAILED(rv)) return rv; - - if (idx < 0) - return NS_OK; - - // Remove the element. - nsCOMPtr ordinal; - rv = gRDFContainerUtils->IndexToOrdinalResource(idx, - getter_AddRefs(ordinal)); - if (NS_FAILED(rv)) return rv; - - rv = mDataSource->Unassert(mContainer, ordinal, aElement); - if (NS_FAILED(rv)) return rv; - - if (aRenumber) { - // Now slide the rest of the collection backwards to fill in - // the gap. This will have the side effect of completely - // renumber the container from index to the end. - rv = Renumber(idx + 1, -1); - if (NS_FAILED(rv)) return rv; - } - - return NS_OK; -} - - -NS_IMETHODIMP -RDFContainerImpl::InsertElementAt(nsIRDFNode *aElement, int32_t aIndex, bool aRenumber) -{ - if (!mDataSource || !mContainer) - return NS_ERROR_NOT_INITIALIZED; - - NS_PRECONDITION(aElement != nullptr, "null ptr"); - if (! aElement) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aIndex >= 1, "illegal value"); - if (aIndex < 1) - return NS_ERROR_ILLEGAL_VALUE; - - nsresult rv; - - int32_t count; - rv = GetCount(&count); - if (NS_FAILED(rv)) return rv; - - NS_ASSERTION(aIndex <= count + 1, "illegal value"); - if (aIndex > count + 1) - return NS_ERROR_ILLEGAL_VALUE; - - if (aRenumber) { - // Make a hole for the element. This will have the side effect of - // completely renumbering the container from 'aIndex' to 'count', - // and will spew assertions. - rv = Renumber(aIndex, +1); - if (NS_FAILED(rv)) return rv; - } - - nsCOMPtr ordinal; - rv = gRDFContainerUtils->IndexToOrdinalResource(aIndex, getter_AddRefs(ordinal)); - if (NS_FAILED(rv)) return rv; - - rv = mDataSource->Assert(mContainer, ordinal, aElement, true); - if (NS_FAILED(rv)) return rv; - - return NS_OK; -} - -NS_IMETHODIMP -RDFContainerImpl::RemoveElementAt(int32_t aIndex, bool aRenumber, nsIRDFNode** _retval) -{ - if (!mDataSource || !mContainer) - return NS_ERROR_NOT_INITIALIZED; - - *_retval = nullptr; - - if (aIndex< 1) - return NS_ERROR_ILLEGAL_VALUE; - - nsresult rv; - - int32_t count; - rv = GetCount(&count); - if (NS_FAILED(rv)) return rv; - - if (aIndex > count) - return NS_ERROR_ILLEGAL_VALUE; - - nsCOMPtr ordinal; - rv = gRDFContainerUtils->IndexToOrdinalResource(aIndex, getter_AddRefs(ordinal)); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr old; - rv = mDataSource->GetTarget(mContainer, ordinal, true, getter_AddRefs(old)); - if (NS_FAILED(rv)) return rv; - - if (rv == NS_OK) { - rv = mDataSource->Unassert(mContainer, ordinal, old); - if (NS_FAILED(rv)) return rv; - - if (aRenumber) { - // Now slide the rest of the collection backwards to fill in - // the gap. This will have the side effect of completely - // renumber the container from index to the end. - rv = Renumber(aIndex + 1, -1); - if (NS_FAILED(rv)) return rv; - } - } - - old.swap(*_retval); - - return NS_OK; -} - -NS_IMETHODIMP -RDFContainerImpl::IndexOf(nsIRDFNode *aElement, int32_t *aIndex) -{ - if (!mDataSource || !mContainer) - return NS_ERROR_NOT_INITIALIZED; - - return gRDFContainerUtils->IndexOf(mDataSource, mContainer, - aElement, aIndex); -} - - -//////////////////////////////////////////////////////////////////////// - - -RDFContainerImpl::RDFContainerImpl() - : mDataSource(nullptr), mContainer(nullptr) -{ -} - - -nsresult -RDFContainerImpl::Init() -{ - if (gRefCnt++ == 0) { - nsresult rv; - - NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); - rv = CallGetService(kRDFServiceCID, &gRDFService); - if (NS_FAILED(rv)) { - NS_ERROR("unable to get RDF service"); - return rv; - } - - rv = gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "nextVal"), - &kRDF_nextVal); - if (NS_FAILED(rv)) return rv; - - NS_DEFINE_CID(kRDFContainerUtilsCID, NS_RDFCONTAINERUTILS_CID); - rv = CallGetService(kRDFContainerUtilsCID, &gRDFContainerUtils); - if (NS_FAILED(rv)) { - NS_ERROR("unable to get RDF container utils service"); - return rv; - } - } - - return NS_OK; -} - - -RDFContainerImpl::~RDFContainerImpl() -{ -#ifdef DEBUG_REFS - --gInstanceCount; - fprintf(stdout, "%d - RDF: RDFContainerImpl\n", gInstanceCount); -#endif - - NS_IF_RELEASE(mContainer); - NS_IF_RELEASE(mDataSource); - - if (--gRefCnt == 0) { - NS_IF_RELEASE(gRDFContainerUtils); - NS_IF_RELEASE(gRDFService); - NS_IF_RELEASE(kRDF_nextVal); - } -} - - -nsresult -NS_NewRDFContainer(nsIRDFContainer** aResult) -{ - RDFContainerImpl* result = new RDFContainerImpl(); - if (! result) - return NS_ERROR_OUT_OF_MEMORY; - - nsresult rv; - rv = result->Init(); - if (NS_FAILED(rv)) { - delete result; - return rv; - } - - NS_ADDREF(result); - *aResult = result; - return NS_OK; -} - - -nsresult -NS_NewRDFContainer(nsIRDFDataSource* aDataSource, - nsIRDFResource* aResource, - nsIRDFContainer** aResult) -{ - nsresult rv; - rv = NS_NewRDFContainer(aResult); - if (NS_FAILED(rv)) return rv; - - rv = (*aResult)->Init(aDataSource, aResource); - if (NS_FAILED(rv)) { - NS_RELEASE(*aResult); - } - return rv; -} - - -nsresult -RDFContainerImpl::Renumber(int32_t aStartIndex, int32_t aIncrement) -{ - if (!mDataSource || !mContainer) - return NS_ERROR_NOT_INITIALIZED; - - // Renumber the elements in the container starting with - // aStartIndex, updating each element's index by aIncrement. For - // example, - // - // (1:a 2:b 3:c) - // Renumber(2, +1); - // (1:a 3:b 4:c) - // Renumber(3, -1); - // (1:a 2:b 3:c) - // - nsresult rv; - - if (! aIncrement) - return NS_OK; - - int32_t count; - rv = GetCount(&count); - if (NS_FAILED(rv)) return rv; - - if (aIncrement > 0) { - // Update the container's nextVal to reflect the - // renumbering. We do this now if aIncrement > 0 because we'll - // want to be able to acknowledge that new elements are in the - // container. - rv = SetNextValue(count + aIncrement + 1); - if (NS_FAILED(rv)) return rv; - } - - int32_t i; - if (aIncrement < 0) { - i = aStartIndex; - } - else { - i = count; // we're one-indexed. - } - - // Note: once we disable notifications, don't exit this method until - // enabling notifications - nsCOMPtr propagatable = - do_QueryInterface(mDataSource); - if (propagatable) { - propagatable->SetPropagateChanges(false); - } - - bool err = false; - while (!err && ((aIncrement < 0) ? (i <= count) : (i >= aStartIndex))) - { - nsCOMPtr oldOrdinal; - rv = gRDFContainerUtils->IndexToOrdinalResource(i, getter_AddRefs(oldOrdinal)); - if (NS_FAILED(rv)) - { - err = true; - continue; - } - - nsCOMPtr newOrdinal; - rv = gRDFContainerUtils->IndexToOrdinalResource(i + aIncrement, getter_AddRefs(newOrdinal)); - if (NS_FAILED(rv)) - { - err = true; - continue; - } - - // Because of aggregation, we need to be paranoid about the - // possibility that >1 element may be present per ordinal. If - // there _is_ in fact more than one element, they'll all get - // assigned to the same new ordinal; i.e., we don't make any - // attempt to "clean up" the duplicate numbering. (Doing so - // would require two passes.) - nsCOMPtr targets; - rv = mDataSource->GetTargets(mContainer, oldOrdinal, true, getter_AddRefs(targets)); - if (NS_FAILED(rv)) - { - err = true; - continue; - } - - while (1) { - bool hasMore; - rv = targets->HasMoreElements(&hasMore); - if (NS_FAILED(rv)) - { - err = true; - break; - } - - if (! hasMore) - break; - - nsCOMPtr isupports; - rv = targets->GetNext(getter_AddRefs(isupports)); - if (NS_FAILED(rv)) - { - err = true; - break; - } - - nsCOMPtr element( do_QueryInterface(isupports) ); - NS_ASSERTION(element != nullptr, "something funky in the enumerator"); - if (! element) - { - err = true; - rv = NS_ERROR_UNEXPECTED; - break; - } - - rv = mDataSource->Unassert(mContainer, oldOrdinal, element); - if (NS_FAILED(rv)) - { - err = true; - break; - } - - rv = mDataSource->Assert(mContainer, newOrdinal, element, true); - if (NS_FAILED(rv)) - { - err = true; - break; - } - } - - i -= aIncrement; - } - - if (!err && (aIncrement < 0)) - { - // Update the container's nextVal to reflect the - // renumbering. We do this now if aIncrement < 0 because, up - // until this point, we'll want people to be able to find - // things that are still "at the end". - rv = SetNextValue(count + aIncrement + 1); - if (NS_FAILED(rv)) - { - err = true; - } - } - - // Note: MUST enable notifications before exiting this method - if (propagatable) { - propagatable->SetPropagateChanges(true); - } - - if (err) return(rv); - - return NS_OK; -} - - - -nsresult -RDFContainerImpl::SetNextValue(int32_t aIndex) -{ - if (!mDataSource || !mContainer) - return NS_ERROR_NOT_INITIALIZED; - - nsresult rv; - - // Remove the current value of nextVal, if there is one. - nsCOMPtr nextValNode; - if (NS_SUCCEEDED(rv = mDataSource->GetTarget(mContainer, - kRDF_nextVal, - true, - getter_AddRefs(nextValNode)))) { - if (NS_FAILED(rv = mDataSource->Unassert(mContainer, kRDF_nextVal, nextValNode))) { - NS_ERROR("unable to update nextVal"); - return rv; - } - } - - nsAutoString s; - s.AppendInt(aIndex, 10); - - nsCOMPtr nextVal; - if (NS_FAILED(rv = gRDFService->GetLiteral(s.get(), getter_AddRefs(nextVal)))) { - NS_ERROR("unable to get nextVal literal"); - return rv; - } - - rv = mDataSource->Assert(mContainer, kRDF_nextVal, nextVal, true); - if (rv != NS_RDF_ASSERTION_ACCEPTED) { - NS_ERROR("unable to update nextVal"); - return NS_ERROR_FAILURE; - } - - return NS_OK; -} - - -nsresult -RDFContainerImpl::GetNextValue(nsIRDFResource** aResult) -{ - if (!mDataSource || !mContainer) - return NS_ERROR_NOT_INITIALIZED; - - nsresult rv; - - // Get the next value, which hangs off of the bag via the - // RDF:nextVal property. - nsCOMPtr nextValNode; - rv = mDataSource->GetTarget(mContainer, kRDF_nextVal, true, getter_AddRefs(nextValNode)); - if (NS_FAILED(rv)) return rv; - - if (rv == NS_RDF_NO_VALUE) - return NS_ERROR_UNEXPECTED; - - nsCOMPtr nextValLiteral; - rv = nextValNode->QueryInterface(NS_GET_IID(nsIRDFLiteral), getter_AddRefs(nextValLiteral)); - if (NS_FAILED(rv)) return rv; - - const char16_t* s; - rv = nextValLiteral->GetValueConst(&s); - if (NS_FAILED(rv)) return rv; - - int32_t nextVal = 0; - { - for (const char16_t* p = s; *p != 0; ++p) { - NS_ASSERTION(*p >= '0' && *p <= '9', "not a digit"); - if (*p < '0' || *p > '9') - break; - - nextVal *= 10; - nextVal += *p - '0'; - } - } - - static const char kRDFNameSpaceURI[] = RDF_NAMESPACE_URI; - nsAutoCStringN nextValStr; - nextValStr = kRDFNameSpaceURI; - nextValStr.Append('_'); - nextValStr.AppendInt(nextVal, 10); - - rv = gRDFService->GetResource(nextValStr, aResult); - if (NS_FAILED(rv)) return rv; - - // Now increment the RDF:nextVal property. - rv = mDataSource->Unassert(mContainer, kRDF_nextVal, nextValLiteral); - if (NS_FAILED(rv)) return rv; - - ++nextVal; - nextValStr.Truncate(); - nextValStr.AppendInt(nextVal, 10); - - rv = gRDFService->GetLiteral(NS_ConvertASCIItoUTF16(nextValStr).get(), getter_AddRefs(nextValLiteral)); - if (NS_FAILED(rv)) return rv; - - rv = mDataSource->Assert(mContainer, kRDF_nextVal, nextValLiteral, true); - if (NS_FAILED(rv)) return rv; - - if (RDF_SEQ_LIST_LIMIT == nextVal) - { - // focal point for RDF container mutation; - // basically, provide a hint to allow for fast access - nsCOMPtr inMem = do_QueryInterface(mDataSource); - if (inMem) - { - // ignore error; failure just means slower access - (void)inMem->EnsureFastContainment(mContainer); - } - } - - return NS_OK; -} diff --git a/rdf/base/nsRDFContainerUtils.cpp b/rdf/base/nsRDFContainerUtils.cpp deleted file mode 100644 index d92f00c3e8a9..000000000000 --- a/rdf/base/nsRDFContainerUtils.cpp +++ /dev/null @@ -1,513 +0,0 @@ -/* -*- 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/. */ - -/* - - Implementation for the RDF container utils. - - */ - - -#include "nsCOMPtr.h" -#include "nsIServiceManager.h" -#include "nsIRDFContainer.h" -#include "nsIRDFContainerUtils.h" -#include "nsIRDFService.h" -#include "nsRDFCID.h" -#include "nsString.h" -#include "plstr.h" -#include "rdf.h" -#include "rdfutil.h" - -class RDFContainerUtilsImpl : public nsIRDFContainerUtils -{ -public: - // nsISupports interface - NS_DECL_ISUPPORTS - - // nsIRDFContainerUtils interface - NS_DECL_NSIRDFCONTAINERUTILS - -private: - friend nsresult NS_NewRDFContainerUtils(nsIRDFContainerUtils** aResult); - - RDFContainerUtilsImpl(); - virtual ~RDFContainerUtilsImpl(); - - nsresult MakeContainer(nsIRDFDataSource* aDataSource, - nsIRDFResource* aResource, - nsIRDFResource* aType, - nsIRDFContainer** aResult); - - bool IsA(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource, nsIRDFResource* aType); - - // pseudo constants - static int32_t gRefCnt; - static nsIRDFService* gRDFService; - static nsIRDFResource* kRDF_instanceOf; - static nsIRDFResource* kRDF_nextVal; - static nsIRDFResource* kRDF_Bag; - static nsIRDFResource* kRDF_Seq; - static nsIRDFResource* kRDF_Alt; - static nsIRDFLiteral* kOne; - static const char kRDFNameSpaceURI[]; -}; - -int32_t RDFContainerUtilsImpl::gRefCnt = 0; -nsIRDFService* RDFContainerUtilsImpl::gRDFService; -nsIRDFResource* RDFContainerUtilsImpl::kRDF_instanceOf; -nsIRDFResource* RDFContainerUtilsImpl::kRDF_nextVal; -nsIRDFResource* RDFContainerUtilsImpl::kRDF_Bag; -nsIRDFResource* RDFContainerUtilsImpl::kRDF_Seq; -nsIRDFResource* RDFContainerUtilsImpl::kRDF_Alt; -nsIRDFLiteral* RDFContainerUtilsImpl::kOne; -const char RDFContainerUtilsImpl::kRDFNameSpaceURI[] = RDF_NAMESPACE_URI; - -//////////////////////////////////////////////////////////////////////// -// nsISupports interface - -NS_IMPL_ISUPPORTS(RDFContainerUtilsImpl, nsIRDFContainerUtils) - -//////////////////////////////////////////////////////////////////////// -// nsIRDFContainerUtils interface - -NS_IMETHODIMP -RDFContainerUtilsImpl::IsOrdinalProperty(nsIRDFResource *aProperty, bool *_retval) -{ - NS_PRECONDITION(aProperty != nullptr, "null ptr"); - if (! aProperty) - return NS_ERROR_NULL_POINTER; - - nsresult rv; - - const char *propertyStr; - rv = aProperty->GetValueConst( &propertyStr ); - if (NS_FAILED(rv)) return rv; - - if (PL_strncmp(propertyStr, kRDFNameSpaceURI, sizeof(kRDFNameSpaceURI) - 1) != 0) { - *_retval = false; - return NS_OK; - } - - const char* s = propertyStr; - s += sizeof(kRDFNameSpaceURI) - 1; - if (*s != '_') { - *_retval = false; - return NS_OK; - } - - ++s; - while (*s) { - if (*s < '0' || *s > '9') { - *_retval = false; - return NS_OK; - } - - ++s; - } - - *_retval = true; - return NS_OK; -} - - -NS_IMETHODIMP -RDFContainerUtilsImpl::IndexToOrdinalResource(int32_t aIndex, nsIRDFResource **aOrdinal) -{ - NS_PRECONDITION(aIndex > 0, "illegal value"); - if (aIndex <= 0) - return NS_ERROR_ILLEGAL_VALUE; - - nsAutoCString uri(kRDFNameSpaceURI); - uri.Append('_'); - uri.AppendInt(aIndex); - - nsresult rv = gRDFService->GetResource(uri, aOrdinal); - NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get ordinal resource"); - if (NS_FAILED(rv)) return rv; - - return NS_OK; -} - - -NS_IMETHODIMP -RDFContainerUtilsImpl::OrdinalResourceToIndex(nsIRDFResource *aOrdinal, int32_t *aIndex) -{ - NS_PRECONDITION(aOrdinal != nullptr, "null ptr"); - if (! aOrdinal) - return NS_ERROR_NULL_POINTER; - - const char *ordinalStr; - if (NS_FAILED(aOrdinal->GetValueConst( &ordinalStr ))) - return NS_ERROR_FAILURE; - - const char* s = ordinalStr; - if (PL_strncmp(s, kRDFNameSpaceURI, sizeof(kRDFNameSpaceURI) - 1) != 0) { - NS_ERROR("not an ordinal"); - return NS_ERROR_UNEXPECTED; - } - - s += sizeof(kRDFNameSpaceURI) - 1; - if (*s != '_') { - NS_ERROR("not an ordinal"); - return NS_ERROR_UNEXPECTED; - } - - int32_t idx = 0; - - ++s; - while (*s) { - if (*s < '0' || *s > '9') { - NS_ERROR("not an ordinal"); - return NS_ERROR_UNEXPECTED; - } - - idx *= 10; - idx += (*s - '0'); - - ++s; - } - - *aIndex = idx; - return NS_OK; -} - -NS_IMETHODIMP -RDFContainerUtilsImpl::IsContainer(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, bool *_retval) -{ - NS_PRECONDITION(aDataSource != nullptr, "null ptr"); - if (! aDataSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aResource != nullptr, "null ptr"); - if (! aResource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(_retval != nullptr, "null ptr"); - if (! _retval) - return NS_ERROR_NULL_POINTER; - - if (IsA(aDataSource, aResource, kRDF_Seq) || - IsA(aDataSource, aResource, kRDF_Bag) || - IsA(aDataSource, aResource, kRDF_Alt)) { - *_retval = true; - } - else { - *_retval = false; - } - return NS_OK; -} - - -NS_IMETHODIMP -RDFContainerUtilsImpl::IsEmpty(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource, bool* _retval) -{ - if (! aDataSource) - return NS_ERROR_NULL_POINTER; - - nsresult rv; - - // By default, say that we're an empty container. Even if we're not - // really even a container. - *_retval = true; - - nsCOMPtr nextValNode; - rv = aDataSource->GetTarget(aResource, kRDF_nextVal, true, getter_AddRefs(nextValNode)); - if (NS_FAILED(rv)) return rv; - - if (rv == NS_RDF_NO_VALUE) - return NS_OK; - - nsCOMPtr nextValLiteral; - rv = nextValNode->QueryInterface(NS_GET_IID(nsIRDFLiteral), getter_AddRefs(nextValLiteral)); - if (NS_FAILED(rv)) return rv; - - if (nextValLiteral.get() != kOne) - *_retval = false; - - return NS_OK; -} - - -NS_IMETHODIMP -RDFContainerUtilsImpl::IsBag(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, bool *_retval) -{ - NS_PRECONDITION(aDataSource != nullptr, "null ptr"); - if (! aDataSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aResource != nullptr, "null ptr"); - if (! aResource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(_retval != nullptr, "null ptr"); - if (! _retval) - return NS_ERROR_NULL_POINTER; - - *_retval = IsA(aDataSource, aResource, kRDF_Bag); - return NS_OK; -} - - -NS_IMETHODIMP -RDFContainerUtilsImpl::IsSeq(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, bool *_retval) -{ - NS_PRECONDITION(aDataSource != nullptr, "null ptr"); - if (! aDataSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aResource != nullptr, "null ptr"); - if (! aResource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(_retval != nullptr, "null ptr"); - if (! _retval) - return NS_ERROR_NULL_POINTER; - - *_retval = IsA(aDataSource, aResource, kRDF_Seq); - return NS_OK; -} - - -NS_IMETHODIMP -RDFContainerUtilsImpl::IsAlt(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, bool *_retval) -{ - NS_PRECONDITION(aDataSource != nullptr, "null ptr"); - if (! aDataSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aResource != nullptr, "null ptr"); - if (! aResource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(_retval != nullptr, "null ptr"); - if (! _retval) - return NS_ERROR_NULL_POINTER; - - *_retval = IsA(aDataSource, aResource, kRDF_Alt); - return NS_OK; -} - - -NS_IMETHODIMP -RDFContainerUtilsImpl::MakeBag(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, nsIRDFContainer **_retval) -{ - return MakeContainer(aDataSource, aResource, kRDF_Bag, _retval); -} - - -NS_IMETHODIMP -RDFContainerUtilsImpl::MakeSeq(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, nsIRDFContainer **_retval) -{ - return MakeContainer(aDataSource, aResource, kRDF_Seq, _retval); -} - - -NS_IMETHODIMP -RDFContainerUtilsImpl::MakeAlt(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, nsIRDFContainer **_retval) -{ - return MakeContainer(aDataSource, aResource, kRDF_Alt, _retval); -} - - - -//////////////////////////////////////////////////////////////////////// - - -RDFContainerUtilsImpl::RDFContainerUtilsImpl() -{ - if (gRefCnt++ == 0) { - nsresult rv; - - NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); - rv = CallGetService(kRDFServiceCID, &gRDFService); - - NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get RDF service"); - if (NS_SUCCEEDED(rv)) { - gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "instanceOf"), - &kRDF_instanceOf); - gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "nextVal"), - &kRDF_nextVal); - gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "Bag"), - &kRDF_Bag); - gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "Seq"), - &kRDF_Seq); - gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "Alt"), - &kRDF_Alt); - gRDFService->GetLiteral(u"1", &kOne); - } - } -} - - -RDFContainerUtilsImpl::~RDFContainerUtilsImpl() -{ -#ifdef DEBUG_REFS - --gInstanceCount; - fprintf(stdout, "%d - RDF: RDFContainerUtilsImpl\n", gInstanceCount); -#endif - - if (--gRefCnt == 0) { - NS_IF_RELEASE(gRDFService); - NS_IF_RELEASE(kRDF_instanceOf); - NS_IF_RELEASE(kRDF_nextVal); - NS_IF_RELEASE(kRDF_Bag); - NS_IF_RELEASE(kRDF_Seq); - NS_IF_RELEASE(kRDF_Alt); - NS_IF_RELEASE(kOne); - } -} - - - -nsresult -NS_NewRDFContainerUtils(nsIRDFContainerUtils** aResult) -{ - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - RDFContainerUtilsImpl* result = - new RDFContainerUtilsImpl(); - - if (! result) - return NS_ERROR_OUT_OF_MEMORY; - - NS_ADDREF(result); - *aResult = result; - return NS_OK; -} - - -nsresult -RDFContainerUtilsImpl::MakeContainer(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource, nsIRDFResource* aType, nsIRDFContainer** aResult) -{ - NS_PRECONDITION(aDataSource != nullptr, "null ptr"); - if (! aDataSource) return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aResource != nullptr, "null ptr"); - if (! aResource) return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aType != nullptr, "null ptr"); - if (! aType) return NS_ERROR_NULL_POINTER; - - if (aResult) *aResult = nullptr; - - nsresult rv; - - // Check to see if somebody has already turned it into a container; if so - // don't try to do it again. - bool isContainer; - rv = IsContainer(aDataSource, aResource, &isContainer); - if (NS_FAILED(rv)) return rv; - - if (!isContainer) - { - rv = aDataSource->Assert(aResource, kRDF_instanceOf, aType, true); - if (NS_FAILED(rv)) return rv; - - rv = aDataSource->Assert(aResource, kRDF_nextVal, kOne, true); - if (NS_FAILED(rv)) return rv; - } - - if (aResult) { - rv = NS_NewRDFContainer(aResult); - if (NS_FAILED(rv)) return rv; - - rv = (*aResult)->Init(aDataSource, aResource); - if (NS_FAILED(rv)) return rv; - } - - return NS_OK; -} - -bool -RDFContainerUtilsImpl::IsA(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource, nsIRDFResource* aType) -{ - if (!aDataSource || !aResource || !aType) { - NS_WARNING("Unexpected null argument"); - return false; - } - - nsresult rv; - - bool result; - rv = aDataSource->HasAssertion(aResource, kRDF_instanceOf, aType, true, &result); - if (NS_FAILED(rv)) - return false; - - return result; -} - -NS_IMETHODIMP -RDFContainerUtilsImpl::IndexOf(nsIRDFDataSource* aDataSource, nsIRDFResource* aContainer, nsIRDFNode* aElement, int32_t* aIndex) -{ - if (!aDataSource || !aContainer) - return NS_ERROR_NULL_POINTER; - - // Assume we can't find it. - *aIndex = -1; - - // If the resource is null, bail quietly - if (! aElement) - return NS_OK; - - // We'll assume that fan-out is much higher than fan-in, so grovel - // through the inbound arcs, look for an ordinal resource, and - // decode it. - nsCOMPtr arcsIn; - aDataSource->ArcLabelsIn(aElement, getter_AddRefs(arcsIn)); - if (! arcsIn) - return NS_OK; - - while (1) { - bool hasMoreArcs = false; - arcsIn->HasMoreElements(&hasMoreArcs); - if (! hasMoreArcs) - break; - - nsCOMPtr isupports; - arcsIn->GetNext(getter_AddRefs(isupports)); - if (! isupports) - break; - - nsCOMPtr property = - do_QueryInterface(isupports); - - if (! property) - continue; - - bool isOrdinal; - IsOrdinalProperty(property, &isOrdinal); - if (! isOrdinal) - continue; - - nsCOMPtr sources; - aDataSource->GetSources(property, aElement, true, getter_AddRefs(sources)); - if (! sources) - continue; - - while (1) { - bool hasMoreSources = false; - sources->HasMoreElements(&hasMoreSources); - if (! hasMoreSources) - break; - - nsCOMPtr isupports2; - sources->GetNext(getter_AddRefs(isupports2)); - if (! isupports2) - break; - - nsCOMPtr source = - do_QueryInterface(isupports2); - - if (source == aContainer) - // Found it. - return OrdinalResourceToIndex(property, aIndex); - } - } - - return NS_OK; -} diff --git a/rdf/base/nsRDFContentSink.cpp b/rdf/base/nsRDFContentSink.cpp deleted file mode 100644 index 3557e817baff..000000000000 --- a/rdf/base/nsRDFContentSink.cpp +++ /dev/null @@ -1,1444 +0,0 @@ -/* -*- 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/. */ - -/* - - An implementation for an NGLayout-style content sink that knows how - to build an RDF content model from XML-serialized RDF. - - For more information on the RDF/XML syntax, - see http://www.w3.org/TR/REC-rdf-syntax/ - - This code is based on the final W3C Recommendation, - http://www.w3.org/TR/1999/REC-rdf-syntax-19990222. - - Open Issues ------------------ - - 1) factoring code with nsXMLContentSink - There's some amount of - common code between this and the HTML content sink. This will - increase as we support more and more HTML elements. How can code - from XML/HTML be factored? - - 2) We don't support the `parseType' attribute on the Description - tag; therefore, it is impossible to "inline" raw XML in this - implemenation. - - 3) We don't build the reifications at parse time due to the - footprint overhead it would incur for large RDF documents. (It - may be possible to attach a "reification" wrapper datasource that - would present this information at query-time.) Because of this, - the `bagID' attribute is not processed correctly. - - 4) No attempt is made to `resolve URIs' to a canonical form (the - specification hints that an implementation should do this). This - is omitted for the obvious reason that we can ill afford to - resolve each URI reference. - -*/ - -#include "nsCOMPtr.h" -#include "nsInterfaceHashtable.h" -#include "nsIContentSink.h" -#include "nsIRDFContainer.h" -#include "nsIRDFContainerUtils.h" -#include "nsIRDFContentSink.h" -#include "nsIRDFNode.h" -#include "nsIRDFService.h" -#include "nsIRDFXMLSink.h" -#include "nsIServiceManager.h" -#include "nsIURL.h" -#include "nsIXMLContentSink.h" -#include "nsRDFCID.h" -#include "nsTArray.h" -#include "nsString.h" -#include "mozilla/Logging.h" -#include "rdf.h" -#include "rdfutil.h" -#include "nsReadableUtils.h" -#include "nsIExpatSink.h" -#include "nsCRT.h" -#include "nsAtom.h" -#include "nsGkAtoms.h" -#include "nsIScriptError.h" -#include "nsIDTD.h" - -using namespace mozilla; - -/////////////////////////////////////////////////////////////////////// - -enum RDFContentSinkState { - eRDFContentSinkState_InProlog, - eRDFContentSinkState_InDocumentElement, - eRDFContentSinkState_InDescriptionElement, - eRDFContentSinkState_InContainerElement, - eRDFContentSinkState_InPropertyElement, - eRDFContentSinkState_InMemberElement, - eRDFContentSinkState_InEpilog -}; - -enum RDFContentSinkParseMode { - eRDFContentSinkParseMode_Resource, - eRDFContentSinkParseMode_Literal, - eRDFContentSinkParseMode_Int, - eRDFContentSinkParseMode_Date -}; - -typedef decltype(&nsIRDFContainerUtils::IsAlt) nsContainerTestFn; -typedef decltype(&nsIRDFContainerUtils::MakeAlt) nsMakeContainerFn; - -class RDFContentSinkImpl : public nsIRDFContentSink, - public nsIExpatSink -{ -public: - RDFContentSinkImpl(); - - // nsISupports - NS_DECL_ISUPPORTS - NS_DECL_NSIEXPATSINK - - // nsIContentSink - NS_IMETHOD WillParse(void) override; - NS_IMETHOD WillBuildModel(nsDTDMode aDTDMode) override; - NS_IMETHOD DidBuildModel(bool aTerminated) override; - NS_IMETHOD WillInterrupt(void) override; - NS_IMETHOD WillResume(void) override; - NS_IMETHOD SetParser(nsParserBase* aParser) override; - virtual void FlushPendingNotifications(mozilla::FlushType aType) override { } - virtual void SetDocumentCharset(NotNull aEncoding) - override { } - virtual nsISupports *GetTarget() override { return nullptr; } - - // nsIRDFContentSink - NS_IMETHOD Init(nsIURI* aURL) override; - NS_IMETHOD SetDataSource(nsIRDFDataSource* aDataSource) override; - NS_IMETHOD GetDataSource(nsIRDFDataSource*& aDataSource) override; - - // pseudo constants - static int32_t gRefCnt; - static nsIRDFService* gRDFService; - static nsIRDFContainerUtils* gRDFContainerUtils; - static nsIRDFResource* kRDF_type; - static nsIRDFResource* kRDF_instanceOf; // XXX should be RDF:type - static nsIRDFResource* kRDF_Alt; - static nsIRDFResource* kRDF_Bag; - static nsIRDFResource* kRDF_Seq; - static nsIRDFResource* kRDF_nextVal; - - typedef struct ContainerInfo { - nsIRDFResource** mType; - nsContainerTestFn mTestFn; - nsMakeContainerFn mMakeFn; - } ContainerInfo; - -protected: - virtual ~RDFContentSinkImpl(); - - // Text management - void ParseText(nsIRDFNode **aResult); - - nsresult FlushText(); - nsresult AddText(const char16_t* aText, int32_t aLength); - - // RDF-specific parsing - nsresult OpenRDF(const char16_t* aName); - nsresult OpenObject(const char16_t* aName ,const char16_t** aAttributes); - nsresult OpenProperty(const char16_t* aName, const char16_t** aAttributes); - nsresult OpenMember(const char16_t* aName, const char16_t** aAttributes); - nsresult OpenValue(const char16_t* aName, const char16_t** aAttributes); - - nsresult GetIdAboutAttribute(const char16_t** aAttributes, nsIRDFResource** aResource, bool* aIsAnonymous = nullptr); - nsresult GetResourceAttribute(const char16_t** aAttributes, nsIRDFResource** aResource); - nsresult AddProperties(const char16_t** aAttributes, nsIRDFResource* aSubject, int32_t* aCount = nullptr); - void SetParseMode(const char16_t **aAttributes); - - char16_t* mText; - int32_t mTextLength; - int32_t mTextSize; - - /** - * 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. - */ - void RegisterNamespaces(const char16_t **aAttributes); - - /** - * 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. - */ - const nsDependentSubstring SplitExpatName(const char16_t *aExpatName, - nsAtom **aLocalName); - - enum eContainerType { eBag, eSeq, eAlt }; - nsresult InitContainer(nsIRDFResource* aContainerType, nsIRDFResource* aContainer); - nsresult ReinitContainer(nsIRDFResource* aContainerType, nsIRDFResource* aContainer); - - // The datasource in which we're assigning assertions - nsCOMPtr mDataSource; - - // A hash of all the node IDs referred to - nsInterfaceHashtable mNodeIDMap; - - // The current state of the content sink - RDFContentSinkState mState; - RDFContentSinkParseMode mParseMode; - - // content stack management - int32_t - PushContext(nsIRDFResource *aContext, - RDFContentSinkState aState, - RDFContentSinkParseMode aParseMode); - - nsresult - PopContext(nsIRDFResource *&aContext, - RDFContentSinkState &aState, - RDFContentSinkParseMode &aParseMode); - - nsIRDFResource* GetContextElement(int32_t ancestor = 0); - - - struct RDFContextStackElement { - nsCOMPtr mResource; - RDFContentSinkState mState; - RDFContentSinkParseMode mParseMode; - }; - - AutoTArray* mContextStack; - - nsCOMPtr mDocumentURL; - -private: - static mozilla::LazyLogModule gLog; -}; - -int32_t RDFContentSinkImpl::gRefCnt = 0; -nsIRDFService* RDFContentSinkImpl::gRDFService; -nsIRDFContainerUtils* RDFContentSinkImpl::gRDFContainerUtils; -nsIRDFResource* RDFContentSinkImpl::kRDF_type; -nsIRDFResource* RDFContentSinkImpl::kRDF_instanceOf; -nsIRDFResource* RDFContentSinkImpl::kRDF_Alt; -nsIRDFResource* RDFContentSinkImpl::kRDF_Bag; -nsIRDFResource* RDFContentSinkImpl::kRDF_Seq; -nsIRDFResource* RDFContentSinkImpl::kRDF_nextVal; - -mozilla::LazyLogModule RDFContentSinkImpl::gLog("nsRDFContentSink"); - -//////////////////////////////////////////////////////////////////////// - -RDFContentSinkImpl::RDFContentSinkImpl() - : mText(nullptr), - mTextLength(0), - mTextSize(0), - mState(eRDFContentSinkState_InProlog), - mParseMode(eRDFContentSinkParseMode_Literal), - mContextStack(nullptr) -{ - if (gRefCnt++ == 0) { - NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); - nsresult rv = CallGetService(kRDFServiceCID, &gRDFService); - - NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get RDF service"); - if (NS_SUCCEEDED(rv)) { - rv = gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "type"), - &kRDF_type); - rv = gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "instanceOf"), - &kRDF_instanceOf); - rv = gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "Alt"), - &kRDF_Alt); - rv = gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "Bag"), - &kRDF_Bag); - rv = gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "Seq"), - &kRDF_Seq); - rv = gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "nextVal"), - &kRDF_nextVal); - } - - NS_DEFINE_CID(kRDFContainerUtilsCID, NS_RDFCONTAINERUTILS_CID); - rv = CallGetService(kRDFContainerUtilsCID, &gRDFContainerUtils); - } -} - - -RDFContentSinkImpl::~RDFContentSinkImpl() -{ -#ifdef DEBUG_REFS - --gInstanceCount; - fprintf(stdout, "%d - RDF: RDFContentSinkImpl\n", gInstanceCount); -#endif - - if (mContextStack) { - MOZ_LOG(gLog, LogLevel::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. - int32_t i = mContextStack->Length(); - while (0 < i--) { - nsIRDFResource* resource = nullptr; - RDFContentSinkState state; - RDFContentSinkParseMode parseMode; - PopContext(resource, state, parseMode); - - // 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 && MOZ_LOG_TEST(gLog, LogLevel::Debug)) { - nsCString uri; - resource->GetValue(getter_Copies(uri)); - MOZ_LOG(gLog, LogLevel::Debug, - ("rdfxml: uri=%s", uri.get())); - } - - NS_IF_RELEASE(resource); - } - - delete mContextStack; - } - free(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); - } -} - -//////////////////////////////////////////////////////////////////////// -// nsISupports interface - -NS_IMPL_ADDREF(RDFContentSinkImpl) -NS_IMPL_RELEASE(RDFContentSinkImpl) - -NS_IMETHODIMP -RDFContentSinkImpl::QueryInterface(REFNSIID iid, void** result) -{ - NS_PRECONDITION(result, "null ptr"); - if (! result) - return NS_ERROR_NULL_POINTER; - - NS_DEFINE_IID(kIContentSinkIID, NS_ICONTENT_SINK_IID); - NS_DEFINE_IID(kIExpatSinkIID, NS_IEXPATSINK_IID); - NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); - NS_DEFINE_IID(kIXMLContentSinkIID, NS_IXMLCONTENT_SINK_IID); - NS_DEFINE_IID(kIRDFContentSinkIID, NS_IRDFCONTENTSINK_IID); - - *result = nullptr; - if (iid.Equals(kIRDFContentSinkIID) || - iid.Equals(kIXMLContentSinkIID) || - iid.Equals(kIContentSinkIID) || - iid.Equals(kISupportsIID)) { - *result = static_cast(this); - AddRef(); - return NS_OK; - } - else if (iid.Equals(kIExpatSinkIID)) { - *result = static_cast(this); - AddRef(); - return NS_OK; - } - return NS_NOINTERFACE; -} - -NS_IMETHODIMP -RDFContentSinkImpl::HandleStartElement(const char16_t *aName, - const char16_t **aAtts, - uint32_t aAttsCount, - uint32_t aLineNumber) -{ - FlushText(); - - nsresult rv = NS_ERROR_UNEXPECTED; // XXX - - RegisterNamespaces(aAtts); - - switch (mState) { - case eRDFContentSinkState_InProlog: - rv = OpenRDF(aName); - break; - - case eRDFContentSinkState_InDocumentElement: - rv = OpenObject(aName,aAtts); - break; - - case eRDFContentSinkState_InDescriptionElement: - rv = OpenProperty(aName,aAtts); - break; - - case eRDFContentSinkState_InContainerElement: - rv = OpenMember(aName,aAtts); - break; - - case eRDFContentSinkState_InPropertyElement: - case eRDFContentSinkState_InMemberElement: - rv = OpenValue(aName,aAtts); - break; - - case eRDFContentSinkState_InEpilog: - MOZ_LOG(gLog, LogLevel::Warning, - ("rdfxml: unexpected content in epilog at line %d", - aLineNumber)); - break; - } - - return rv; -} - -NS_IMETHODIMP -RDFContentSinkImpl::HandleEndElement(const char16_t *aName) -{ - FlushText(); - - nsIRDFResource* resource; - if (NS_FAILED(PopContext(resource, mState, mParseMode))) { - // XXX parser didn't catch unmatched tags? - if (MOZ_LOG_TEST(gLog, LogLevel::Warning)) { - nsAutoString tagStr(aName); - char* tagCStr = ToNewCString(tagStr); - - MOZ_LOG(gLog, LogLevel::Warning, - ("rdfxml: extra close tag '%s' at line %d", - tagCStr, 0/*XXX fix me */)); - - free(tagCStr); - } - - return NS_ERROR_UNEXPECTED; // XXX - } - - // If we've just popped a member or property element, _now_ is the - // time to add that element to the graph. - switch (mState) { - case eRDFContentSinkState_InMemberElement: - { - nsCOMPtr container; - NS_NewRDFContainer(getter_AddRefs(container)); - container->Init(mDataSource, GetContextElement(1)); - container->AppendElement(resource); - } - break; - - case eRDFContentSinkState_InPropertyElement: - { - mDataSource->Assert(GetContextElement(1), GetContextElement(0), resource, true); - } break; - default: - break; - } - - if (mContextStack->IsEmpty()) - mState = eRDFContentSinkState_InEpilog; - - NS_IF_RELEASE(resource); - return NS_OK; -} - -NS_IMETHODIMP -RDFContentSinkImpl::HandleComment(const char16_t *aName) -{ - return NS_OK; -} - -NS_IMETHODIMP -RDFContentSinkImpl::HandleCDataSection(const char16_t *aData, - uint32_t aLength) -{ - return aData ? AddText(aData, aLength) : NS_OK; -} - -NS_IMETHODIMP -RDFContentSinkImpl::HandleDoctypeDecl(const nsAString & aSubset, - const nsAString & aName, - const nsAString & aSystemId, - const nsAString & aPublicId, - nsISupports* aCatalogData) -{ - return NS_OK; -} - -NS_IMETHODIMP -RDFContentSinkImpl::HandleCharacterData(const char16_t *aData, - uint32_t aLength) -{ - return aData ? AddText(aData, aLength) : NS_OK; -} - -NS_IMETHODIMP -RDFContentSinkImpl::HandleProcessingInstruction(const char16_t *aTarget, - const char16_t *aData) -{ - return NS_OK; -} - -NS_IMETHODIMP -RDFContentSinkImpl::HandleXMLDeclaration(const char16_t *aVersion, - const char16_t *aEncoding, - int32_t aStandalone) -{ - return NS_OK; -} - -NS_IMETHODIMP -RDFContentSinkImpl::ReportError(const char16_t* aErrorText, - const char16_t* aSourceText, - nsIScriptError *aError, - bool *_retval) -{ - NS_PRECONDITION(aError && aSourceText && aErrorText, "Check arguments!!!"); - - // The expat driver should report the error. - *_retval = true; - return NS_OK; -} - -//////////////////////////////////////////////////////////////////////// -// nsIContentSink interface - -NS_IMETHODIMP -RDFContentSinkImpl::WillParse(void) -{ - return NS_OK; -} - - -NS_IMETHODIMP -RDFContentSinkImpl::WillBuildModel(nsDTDMode) -{ - if (mDataSource) { - nsCOMPtr sink = do_QueryInterface(mDataSource); - if (sink) - return sink->BeginLoad(); - } - return NS_OK; -} - -NS_IMETHODIMP -RDFContentSinkImpl::DidBuildModel(bool aTerminated) -{ - if (mDataSource) { - nsCOMPtr sink = do_QueryInterface(mDataSource); - if (sink) - return sink->EndLoad(); - } - return NS_OK; -} - -NS_IMETHODIMP -RDFContentSinkImpl::WillInterrupt(void) -{ - if (mDataSource) { - nsCOMPtr sink = do_QueryInterface(mDataSource); - if (sink) - return sink->Interrupt(); - } - return NS_OK; -} - -NS_IMETHODIMP -RDFContentSinkImpl::WillResume(void) -{ - if (mDataSource) { - nsCOMPtr sink = do_QueryInterface(mDataSource); - if (sink) - return sink->Resume(); - } - return NS_OK; -} - -NS_IMETHODIMP -RDFContentSinkImpl::SetParser(nsParserBase* aParser) -{ - return NS_OK; -} - -//////////////////////////////////////////////////////////////////////// -// nsIRDFContentSink interface - -NS_IMETHODIMP -RDFContentSinkImpl::Init(nsIURI* aURL) -{ - NS_PRECONDITION(aURL != nullptr, "null ptr"); - if (! aURL) - return NS_ERROR_NULL_POINTER; - - mDocumentURL = aURL; - mState = eRDFContentSinkState_InProlog; - return NS_OK; -} - -NS_IMETHODIMP -RDFContentSinkImpl::SetDataSource(nsIRDFDataSource* aDataSource) -{ - NS_PRECONDITION(aDataSource != nullptr, "SetDataSource null ptr"); - mDataSource = aDataSource; - NS_ASSERTION(mDataSource != nullptr,"Couldn't QI RDF DataSource"); - return NS_OK; -} - - -NS_IMETHODIMP -RDFContentSinkImpl::GetDataSource(nsIRDFDataSource*& aDataSource) -{ - aDataSource = mDataSource; - NS_IF_ADDREF(aDataSource); - return NS_OK; -} - -//////////////////////////////////////////////////////////////////////// -// Text buffering - -static bool -rdf_IsDataInBuffer(char16_t* buffer, int32_t length) -{ - for (int32_t i = 0; i < length; ++i) { - if (buffer[i] == ' ' || - buffer[i] == '\t' || - buffer[i] == '\n' || - buffer[i] == '\r') - continue; - - return true; - } - return false; -} - -void -RDFContentSinkImpl::ParseText(nsIRDFNode **aResult) -{ - // 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: - { - nsresult err; - int32_t i = value.ToInteger(&err); - nsIRDFInt *result; - gRDFService->GetIntLiteral(i, &result); - *aResult = result; - } - break; - - case eRDFContentSinkParseMode_Date: - { - PRTime t = rdf_ParseDate(nsDependentCString(NS_LossyConvertUTF16toASCII(value).get(), value.Length())); - nsIRDFDate *result; - gRDFService->GetDateLiteral(t, &result); - *aResult = result; - } - break; - - default: - NS_NOTREACHED("unknown parse type"); - break; - } -} - -nsresult -RDFContentSinkImpl::FlushText() -{ - nsresult rv = NS_OK; - if (0 != mTextLength) { - if (rdf_IsDataInBuffer(mText, mTextLength)) { - // XXX if there's anything but whitespace, then we'll - // create a text node. - - switch (mState) { - case eRDFContentSinkState_InMemberElement: { - nsCOMPtr node; - ParseText(getter_AddRefs(node)); - - nsCOMPtr container; - NS_NewRDFContainer(getter_AddRefs(container)); - container->Init(mDataSource, GetContextElement(1)); - - container->AppendElement(node); - } break; - - case eRDFContentSinkState_InPropertyElement: { - nsCOMPtr node; - ParseText(getter_AddRefs(node)); - - mDataSource->Assert(GetContextElement(1), GetContextElement(0), node, true); - } break; - - default: - // just ignore it - break; - } - } - mTextLength = 0; - } - return rv; -} - - -nsresult -RDFContentSinkImpl::AddText(const char16_t* aText, int32_t aLength) -{ - // Create buffer when we first need it - if (0 == mTextSize) { - mText = (char16_t *) malloc(sizeof(char16_t) * 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. - int32_t amount = mTextSize - mTextLength; - if (amount < aLength) { - // Grow the buffer by at least a factor of two to prevent thrashing. - // Since realloc() will leave mText intact if the call fails, - // don't clobber mText or mTextSize until the new mem is allocated. - int32_t newSize = (2 * mTextSize > (mTextSize + aLength)) ? - (2 * mTextSize) : (mTextSize + aLength); - char16_t* newText = - (char16_t *) realloc(mText, sizeof(char16_t) * newSize); - if (!newText) - return NS_ERROR_OUT_OF_MEMORY; - mTextSize = newSize; - mText = newText; - } - memcpy(&mText[mTextLength], aText, sizeof(char16_t) * aLength); - mTextLength += aLength; - - return NS_OK; -} - -bool -rdf_RequiresAbsoluteURI(const nsString& uri) -{ - // cheap shot at figuring out if this requires an absolute url translation - return !(StringBeginsWith(uri, NS_LITERAL_STRING("urn:")) || - StringBeginsWith(uri, NS_LITERAL_STRING("chrome:"))); -} - -nsresult -RDFContentSinkImpl::GetIdAboutAttribute(const char16_t** aAttributes, - nsIRDFResource** aResource, - bool* aIsAnonymous) -{ - // This corresponds to the dirty work of production [6.5] - nsresult rv = NS_OK; - - nsAutoString nodeID; - - RefPtr 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 == nsGkAtoms::about) { - if (aIsAnonymous) - *aIsAnonymous = false; - - nsAutoString relURI(aAttributes[1]); - if (rdf_RequiresAbsoluteURI(relURI)) { - nsAutoCString uri; - rv = mDocumentURL->Resolve(NS_ConvertUTF16toUTF8(aAttributes[1]), uri); - if (NS_FAILED(rv)) return rv; - - return gRDFService->GetResource(uri, - aResource); - } - return gRDFService->GetResource(NS_ConvertUTF16toUTF8(aAttributes[1]), - aResource); - } - else if (localName == nsGkAtoms::ID) { - if (aIsAnonymous) - *aIsAnonymous = false; - // 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. - nsAutoCString name; - nsAutoCString ref('#'); - AppendUTF16toUTF8(aAttributes[1], ref); - - rv = mDocumentURL->Resolve(ref, name); - if (NS_FAILED(rv)) return rv; - - return gRDFService->GetResource(name, aResource); - } - else if (localName == nsGkAtoms::nodeID) { - nodeID.Assign(aAttributes[1]); - } - else if (localName == nsGkAtoms::about) { - // XXX we don't deal with aboutEach... - //MOZ_LOG(gLog, LogLevel::Warning, - // ("rdfxml: ignoring aboutEach at line %d", - // aNode.GetSourceLineNumber())); - } - } - - // Otherwise, we couldn't find anything, so just gensym one... - if (aIsAnonymous) - *aIsAnonymous = 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; -} - -nsresult -RDFContentSinkImpl::GetResourceAttribute(const char16_t** aAttributes, - nsIRDFResource** aResource) -{ - RefPtr 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 == nsGkAtoms::resource) { - // XXX Take the URI and make it fully qualified by - // sticking it into the document's URL. This may not be - // appropriate... - nsAutoString relURI(aAttributes[1]); - if (rdf_RequiresAbsoluteURI(relURI)) { - nsresult rv; - nsAutoCString uri; - - rv = mDocumentURL->Resolve(NS_ConvertUTF16toUTF8(aAttributes[1]), uri); - if (NS_FAILED(rv)) return rv; - - return gRDFService->GetResource(uri, aResource); - } - return gRDFService->GetResource(NS_ConvertUTF16toUTF8(aAttributes[1]), - aResource); - } - else if (localName == nsGkAtoms::nodeID) { - 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) { - nsresult rv; - rv = gRDFService->GetAnonymousResource(aResource); - if (NS_FAILED(rv)) { - return rv; - } - mNodeIDMap.Put(nodeID,*aResource); - } - return NS_OK; - } - - return NS_ERROR_FAILURE; -} - -nsresult -RDFContentSinkImpl::AddProperties(const char16_t** aAttributes, - nsIRDFResource* aSubject, - int32_t* aCount) -{ - if (aCount) - *aCount = 0; - - RefPtr 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 == nsGkAtoms::about || localName == nsGkAtoms::ID || - localName == nsGkAtoms::resource || localName == nsGkAtoms::nodeID) { - 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 == nsGkAtoms::parseType) { - if (nameSpaceURI.IsEmpty() || - nameSpaceURI.EqualsLiteral(RDF_NAMESPACE_URI) || - nameSpaceURI.EqualsLiteral(NC_NAMESPACE_URI)) { - continue; - } - } - - NS_ConvertUTF16toUTF8 propertyStr(nameSpaceURI); - propertyStr.Append(nsAtomCString(localName)); - - // Add the assertion to RDF - nsCOMPtr property; - gRDFService->GetResource(propertyStr, getter_AddRefs(property)); - - nsCOMPtr target; - gRDFService->GetLiteral(aAttributes[1], - getter_AddRefs(target)); - - mDataSource->Assert(aSubject, property, target, true); - } - return NS_OK; -} - -void -RDFContentSinkImpl::SetParseMode(const char16_t **aAttributes) -{ - RefPtr localName; - for (; *aAttributes; aAttributes += 2) { - const nsDependentSubstring& nameSpaceURI = - SplitExpatName(aAttributes[0], getter_AddRefs(localName)); - - if (localName == nsGkAtoms::parseType) { - nsDependentString v(aAttributes[1]); - - 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; - } - } - } -} - -//////////////////////////////////////////////////////////////////////// -// RDF-specific routines used to build the model - -nsresult -RDFContentSinkImpl::OpenRDF(const char16_t* aName) -{ - // ensure that we're actually reading RDF by making sure that the - // opening tag is , where "rdf:" corresponds to whatever - // they've declared the standard RDF namespace to be. - RefPtr localName; - const nsDependentSubstring& nameSpaceURI = - SplitExpatName(aName, getter_AddRefs(localName)); - - if (!nameSpaceURI.EqualsLiteral(RDF_NAMESPACE_URI) || - localName != nsGkAtoms::RDF) { - // MOZ_LOG(gLog, LogLevel::Info, - // ("rdfxml: expected RDF:RDF at line %d", - // aNode.GetSourceLineNumber())); - - return NS_ERROR_UNEXPECTED; - } - - PushContext(nullptr, mState, mParseMode); - mState = eRDFContentSinkState_InDocumentElement; - return NS_OK; -} - -nsresult -RDFContentSinkImpl::OpenObject(const char16_t* aName, - const char16_t** aAttributes) -{ - // an "object" non-terminal is either a "description", a "typed - // node", or a "container", so this change the content sink's - // state appropriately. - RefPtr localName; - const nsDependentSubstring& nameSpaceURI = - SplitExpatName(aName, getter_AddRefs(localName)); - - // Figure out the URI of this object, and create an RDF node for it. - nsCOMPtr 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. - bool isaTypedNode = true; - - if (nameSpaceURI.EqualsLiteral(RDF_NAMESPACE_URI)) { - isaTypedNode = false; - - if (localName == nsGkAtoms::Description) { - // it's a description - mState = eRDFContentSinkState_InDescriptionElement; - } - else if (localName == nsGkAtoms::Bag) { - // it's a bag container - InitContainer(kRDF_Bag, source); - mState = eRDFContentSinkState_InContainerElement; - } - else if (localName == nsGkAtoms::Seq) { - // it's a seq container - InitContainer(kRDF_Seq, source); - mState = eRDFContentSinkState_InContainerElement; - } - else if (localName == nsGkAtoms::Alt) { - // 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 = true; - } - } - - if (isaTypedNode) { - NS_ConvertUTF16toUTF8 typeStr(nameSpaceURI); - typeStr.Append(nsAtomCString(localName)); - - nsCOMPtr type; - nsresult rv = gRDFService->GetResource(typeStr, getter_AddRefs(type)); - if (NS_FAILED(rv)) return rv; - - rv = mDataSource->Assert(source, kRDF_type, type, true); - if (NS_FAILED(rv)) return rv; - - mState = eRDFContentSinkState_InDescriptionElement; - } - - AddProperties(aAttributes, source); - return NS_OK; -} - -nsresult -RDFContentSinkImpl::OpenProperty(const char16_t* aName, const char16_t** aAttributes) -{ - 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. - RefPtr localName; - const nsDependentSubstring& nameSpaceURI = - SplitExpatName(aName, getter_AddRefs(localName)); - - NS_ConvertUTF16toUTF8 propertyStr(nameSpaceURI); - propertyStr.Append(nsAtomCString(localName)); - - nsCOMPtr 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 target; - GetResourceAttribute(aAttributes, getter_AddRefs(target)); - - bool isAnonymous = 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. - int32_t 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, 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; -} - -nsresult -RDFContentSinkImpl::OpenMember(const char16_t* aName, - const char16_t** aAttributes) -{ - // ensure that we're actually reading a member element by making - // sure that the opening tag is , where "rdf:" corresponds - // to whatever they've declared the standard RDF namespace to be. - nsresult rv; - - RefPtr localName; - const nsDependentSubstring& nameSpaceURI = - SplitExpatName(aName, getter_AddRefs(localName)); - - if (!nameSpaceURI.EqualsLiteral(RDF_NAMESPACE_URI) || - localName != nsGkAtoms::li) { - MOZ_LOG(gLog, LogLevel::Error, - ("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 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(nullptr, mState, mParseMode); - mState = eRDFContentSinkState_InMemberElement; - SetParseMode(aAttributes); - - return NS_OK; -} - - -nsresult -RDFContentSinkImpl::OpenValue(const char16_t* aName, const char16_t** aAttributes) -{ - // 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); -} - -//////////////////////////////////////////////////////////////////////// -// namespace resolution -void -RDFContentSinkImpl::RegisterNamespaces(const char16_t **aAttributes) -{ - nsCOMPtr 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 char16_t* attr = aAttributes[0]; - const char16_t* 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 char16_t* endLocal = ++attr; - while (*endLocal && *endLocal != 0xFFFF) { - ++endLocal; - } - nsDependentSubstring lname(attr, endLocal); - RefPtr preferred = NS_Atomize(lname); - if (preferred == nsGkAtoms::xmlns) { - preferred = nullptr; - } - sink->AddNameSpace(preferred, nsDependentString(aAttributes[1])); - } -} - -//////////////////////////////////////////////////////////////////////// -// Qualified name resolution - -const nsDependentSubstring -RDFContentSinkImpl::SplitExpatName(const char16_t *aExpatName, - nsAtom **aLocalName) -{ - /** - * Expat can send the following: - * localName - * namespaceURIlocalName - * namespaceURIlocalNameprefix - * - * and we use 0xFFFF for the . - * - */ - - const char16_t *uriEnd = aExpatName; - const char16_t *nameStart = aExpatName; - const char16_t *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_Atomize(Substring(nameStart, pos)).take(); - return nameSpaceURI; -} - -nsresult -RDFContentSinkImpl::InitContainer(nsIRDFResource* aContainerType, nsIRDFResource* aContainer) -{ - // 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; - - bool isContainer; - rv = (gRDFContainerUtils->*(info->mTestFn))(mDataSource, aContainer, &isContainer); - if (isContainer) { - rv = ReinitContainer(aContainerType, aContainer); - } - else { - rv = (gRDFContainerUtils->*(info->mMakeFn))(mDataSource, aContainer, nullptr); - } - return rv; - } - - NS_NOTREACHED("not an RDF container type"); - return NS_ERROR_FAILURE; -} - - - -nsresult -RDFContentSinkImpl::ReinitContainer(nsIRDFResource* aContainerType, nsIRDFResource* aContainer) -{ - // 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 one; - rv = gRDFService->GetLiteral(u"1", getter_AddRefs(one)); - if (NS_FAILED(rv)) return rv; - - // Re-initialize the 'nextval' property - nsCOMPtr nextval; - rv = mDataSource->GetTarget(aContainer, kRDF_nextVal, 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, true); - NS_ASSERTION(NS_SUCCEEDED(rv), "unable to mark container as such"); - if (NS_FAILED(rv)) return rv; - - return NS_OK; -} - -//////////////////////////////////////////////////////////////////////// -// Content stack management - -nsIRDFResource* -RDFContentSinkImpl::GetContextElement(int32_t ancestor /* = 0 */) -{ - if ((nullptr == mContextStack) || - (uint32_t(ancestor) >= mContextStack->Length())) { - return nullptr; - } - - return mContextStack->ElementAt( - mContextStack->Length()-ancestor-1).mResource; -} - -int32_t -RDFContentSinkImpl::PushContext(nsIRDFResource *aResource, - RDFContentSinkState aState, - RDFContentSinkParseMode aParseMode) -{ - if (! mContextStack) { - mContextStack = new AutoTArray(); - if (! mContextStack) - return 0; - } - - RDFContextStackElement* e = mContextStack->AppendElement(); - if (! e) - return mContextStack->Length(); - - e->mResource = aResource; - e->mState = aState; - e->mParseMode = aParseMode; - - return mContextStack->Length(); -} - -nsresult -RDFContentSinkImpl::PopContext(nsIRDFResource *&aResource, - RDFContentSinkState &aState, - RDFContentSinkParseMode &aParseMode) -{ - if ((nullptr == mContextStack) || - (mContextStack->IsEmpty())) { - return NS_ERROR_NULL_POINTER; - } - - uint32_t i = mContextStack->Length() - 1; - RDFContextStackElement &e = mContextStack->ElementAt(i); - - aResource = e.mResource; - NS_IF_ADDREF(aResource); - aState = e.mState; - aParseMode = e.mParseMode; - - mContextStack->RemoveElementAt(i); - return NS_OK; -} - - -//////////////////////////////////////////////////////////////////////// - -nsresult -NS_NewRDFContentSink(nsIRDFContentSink** aResult) -{ - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - RDFContentSinkImpl* sink = new RDFContentSinkImpl(); - if (! sink) - return NS_ERROR_OUT_OF_MEMORY; - - NS_ADDREF(sink); - *aResult = sink; - return NS_OK; -} diff --git a/rdf/base/nsRDFResource.cpp b/rdf/base/nsRDFResource.cpp deleted file mode 100644 index 46e078a4cc13..000000000000 --- a/rdf/base/nsRDFResource.cpp +++ /dev/null @@ -1,220 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; 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/. */ - -#include "nsRDFResource.h" -#include "nsIServiceManager.h" -#include "nsIRDFDelegateFactory.h" -#include "nsIRDFService.h" -#include "nsRDFCID.h" -#include "mozilla/Logging.h" -#include "nsComponentManagerUtils.h" -#include "nsServiceManagerUtils.h" - -static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); - -nsIRDFService* nsRDFResource::gRDFService = nullptr; -nsrefcnt nsRDFResource::gRDFServiceRefCnt = 0; - -//////////////////////////////////////////////////////////////////////////////// - -nsRDFResource::nsRDFResource(void) - : mDelegates(nullptr) -{ -} - -nsRDFResource::~nsRDFResource(void) -{ - // Release all of the delegate objects - while (mDelegates) { - DelegateEntry* doomed = mDelegates; - mDelegates = mDelegates->mNext; - delete doomed; - } - - if (!gRDFService) - return; - - gRDFService->UnregisterResource(this); - - if (--gRDFServiceRefCnt == 0) - NS_RELEASE(gRDFService); -} - -NS_IMPL_ISUPPORTS(nsRDFResource, nsIRDFResource, nsIRDFNode) - -//////////////////////////////////////////////////////////////////////////////// -// nsIRDFNode methods: - -NS_IMETHODIMP -nsRDFResource::EqualsNode(nsIRDFNode* aNode, bool* aResult) -{ - NS_PRECONDITION(aNode != nullptr, "null ptr"); - if (! aNode) - return NS_ERROR_NULL_POINTER; - - nsresult rv; - nsIRDFResource* resource; - rv = aNode->QueryInterface(NS_GET_IID(nsIRDFResource), (void**)&resource); - if (NS_SUCCEEDED(rv)) { - *aResult = (static_cast(this) == resource); - NS_RELEASE(resource); - return NS_OK; - } - if (rv == NS_NOINTERFACE) { - *aResult = false; - return NS_OK; - } - - return rv; -} - -//////////////////////////////////////////////////////////////////////////////// -// nsIRDFResource methods: - -NS_IMETHODIMP -nsRDFResource::Init(const char* aURI) -{ - NS_PRECONDITION(aURI != nullptr, "null ptr"); - if (! aURI) - return NS_ERROR_NULL_POINTER; - - mURI = aURI; - - if (gRDFServiceRefCnt++ == 0) { - nsresult rv = CallGetService(kRDFServiceCID, &gRDFService); - if (NS_FAILED(rv)) return rv; - } - - // don't replace an existing resource with the same URI automatically - return gRDFService->RegisterResource(this, true); -} - -NS_IMETHODIMP -nsRDFResource::GetValue(char* *aURI) -{ - NS_ASSERTION(aURI, "Null out param."); - - *aURI = ToNewCString(mURI); - - if (!*aURI) - return NS_ERROR_OUT_OF_MEMORY; - - return NS_OK; -} - -NS_IMETHODIMP -nsRDFResource::GetValueUTF8(nsACString& aResult) -{ - aResult = mURI; - return NS_OK; -} - -NS_IMETHODIMP -nsRDFResource::GetValueConst(const char** aURI) -{ - *aURI = mURI.get(); - return NS_OK; -} - -NS_IMETHODIMP -nsRDFResource::EqualsString(const char* aURI, bool* aResult) -{ - NS_PRECONDITION(aURI != nullptr, "null ptr"); - if (! aURI) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aResult, "null ptr"); - - *aResult = mURI.Equals(aURI); - return NS_OK; -} - -NS_IMETHODIMP -nsRDFResource::GetDelegate(const char* aKey, REFNSIID aIID, void** aResult) -{ - NS_PRECONDITION(aKey != nullptr, "null ptr"); - if (! aKey) - return NS_ERROR_NULL_POINTER; - - nsresult rv; - *aResult = nullptr; - - DelegateEntry* entry = mDelegates; - while (entry) { - if (entry->mKey.Equals(aKey)) { - rv = entry->mDelegate->QueryInterface(aIID, aResult); - return rv; - } - - entry = entry->mNext; - } - - // Construct a ContractID of the form "@mozilla.org/rdf/delegate/[key]/[scheme];1 - nsAutoCString contractID(NS_RDF_DELEGATEFACTORY_CONTRACTID_PREFIX); - contractID.Append(aKey); - contractID.AppendLiteral("&scheme="); - - int32_t i = mURI.FindChar(':'); - contractID += StringHead(mURI, i); - - nsCOMPtr delegateFactory = - do_CreateInstance(contractID.get(), &rv); - if (NS_FAILED(rv)) return rv; - - rv = delegateFactory->CreateDelegate(this, aKey, aIID, aResult); - if (NS_FAILED(rv)) return rv; - - // Okay, we've successfully created a delegate. Let's remember it. - entry = new DelegateEntry; - if (! entry) { - NS_RELEASE(*reinterpret_cast(aResult)); - return NS_ERROR_OUT_OF_MEMORY; - } - - entry->mKey = aKey; - entry->mDelegate = do_QueryInterface(*reinterpret_cast(aResult), &rv); - if (NS_FAILED(rv)) { - NS_ERROR("nsRDFResource::GetDelegate(): can't QI to nsISupports!"); - - delete entry; - NS_RELEASE(*reinterpret_cast(aResult)); - return NS_ERROR_FAILURE; - } - - entry->mNext = mDelegates; - - mDelegates = entry; - - return NS_OK; -} - -NS_IMETHODIMP -nsRDFResource::ReleaseDelegate(const char* aKey) -{ - NS_PRECONDITION(aKey != nullptr, "null ptr"); - if (! aKey) - return NS_ERROR_NULL_POINTER; - - DelegateEntry* entry = mDelegates; - DelegateEntry** link = &mDelegates; - - while (entry) { - if (entry->mKey.Equals(aKey)) { - *link = entry->mNext; - delete entry; - return NS_OK; - } - - link = &(entry->mNext); - entry = entry->mNext; - } - - NS_WARNING("nsRDFResource::ReleaseDelegate() no delegate found"); - return NS_OK; -} - - - -//////////////////////////////////////////////////////////////////////////////// diff --git a/rdf/base/nsRDFResource.h b/rdf/base/nsRDFResource.h deleted file mode 100644 index ace7060eb04e..000000000000 --- a/rdf/base/nsRDFResource.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; 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/. */ - -#ifndef nsRDFResource_h__ -#define nsRDFResource_h__ - -#include "nsCOMPtr.h" -#include "nsIRDFNode.h" -#include "nsIRDFResource.h" -#include "nscore.h" -#include "nsString.h" -#include "rdf.h" - -class nsIRDFService; - -/** - * This simple base class implements nsIRDFResource, and can be used as a - * superclass for more sophisticated resource implementations. - */ -class nsRDFResource : public nsIRDFResource { -public: - - NS_DECL_THREADSAFE_ISUPPORTS - - // nsIRDFNode methods: - NS_IMETHOD EqualsNode(nsIRDFNode* aNode, bool* aResult) override; - - // nsIRDFResource methods: - NS_IMETHOD Init(const char* aURI) override; - NS_IMETHOD GetValue(char* *aURI) override; - NS_IMETHOD GetValueUTF8(nsACString& aResult) override; - NS_IMETHOD GetValueConst(const char** aURI) override; - NS_IMETHOD EqualsString(const char* aURI, bool* aResult) override; - NS_IMETHOD GetDelegate(const char* aKey, REFNSIID aIID, void** aResult) override; - NS_IMETHOD ReleaseDelegate(const char* aKey) override; - - // nsRDFResource methods: - nsRDFResource(void); - -protected: - virtual ~nsRDFResource(void); - static nsIRDFService* gRDFService; - static nsrefcnt gRDFServiceRefCnt; - -protected: - nsCString mURI; - - struct DelegateEntry { - nsCString mKey; - nsCOMPtr mDelegate; - DelegateEntry* mNext; - }; - - DelegateEntry* mDelegates; -}; - -#endif // nsRDFResource_h__ diff --git a/rdf/base/nsRDFService.cpp b/rdf/base/nsRDFService.cpp deleted file mode 100644 index 842b5eb10de0..000000000000 --- a/rdf/base/nsRDFService.cpp +++ /dev/null @@ -1,1540 +0,0 @@ -/* -*- 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 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 "nsAtom.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 "nsNetUtil.h" -#include "nsIURI.h" -#include "PLDHashTable.h" -#include "plhash.h" -#include "plstr.h" -#include "mozilla/Logging.h" -#include "prprf.h" -#include "rdf.h" -#include "nsCRT.h" -#include "nsCRTGlue.h" -#include "mozilla/HashFunctions.h" -#include "mozilla/IntegerPrintfMacros.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 malloc(size); -} - -static void -DataSourceFreeTable(void *pool, void *item) -{ - free(item); -} - -static PLHashEntry * -DataSourceAllocEntry(void *pool, const void *key) -{ - return (PLHashEntry*) malloc(sizeof(PLHashEntry)); -} - -static void -DataSourceFreeEntry(void *pool, PLHashEntry *he, unsigned flag) -{ - if (flag == HT_FREE_ENTRY) { - PL_strfree((char*) he->key); - 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(key)); - } - - static bool - MatchEntry(const PLDHashEntryHdr *hdr, const void *key) - { - const ResourceHashEntry *entry = - static_cast(hdr); - - return 0 == nsCRT::strcmp(static_cast(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(key)); - } - - static bool - MatchEntry(const PLDHashEntryHdr *hdr, const void *key) - { - const LiteralHashEntry *entry = - static_cast(hdr); - - return 0 == nsCRT::strcmp(static_cast(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(key)); - } - - static bool - MatchEntry(const PLDHashEntryHdr *hdr, const void *key) - { - const IntHashEntry *entry = - static_cast(hdr); - - return *static_cast(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(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(hdr); - - return *static_cast(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 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(key); - return HashBytes(data->mBytes, data->mLength); - } - - static bool - MatchEntry(const PLDHashEntryHdr *hdr, const void *key) - { - const BlobHashEntry *entry = - static_cast(hdr); - - const BlobImpl::Data *left = &entry->mBlob->mData; - - const BlobImpl::Data *right = - static_cast(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(reinterpret_cast(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::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(static_cast(objectPtr) + objectSize); - nsCharTraits::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(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(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(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(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 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 nsCString& 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(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 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(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(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(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(aBytes) }; - - PLDHashEntryHdr *hdr = mBlobs.Search(&key); - if (hdr) { - BlobHashEntry *entry = static_cast(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(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(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; - - nsAutoCString uri; - rv = aDataSource->GetURI(uri); - if (NS_FAILED(rv)) return rv; - - PLHashEntry** hep = - PL_HashTableRawLookup(mNamedDataSources, - (*mNamedDataSources->keyHash)(uri.get()), - uri.get()); - - 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, uri.get())); - - (*hep)->value = aDataSource; - } - else { - const char* key = PL_strdup(uri.get()); - if (! key) - return NS_ERROR_OUT_OF_MEMORY; - - PL_HashTableAdd(mNamedDataSources, key, aDataSource); - - MOZ_LOG(gLog, LogLevel::Debug, - ("rdfserv register-datasource [%p] %s", - aDataSource, uri.get())); - - // 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; - - nsAutoCString uri; - rv = aDataSource->GetURI(uri); - if (NS_FAILED(rv)) return rv; - - //NS_ASSERTION(uri != nullptr, "datasource has no URI"); - if (uri.IsVoid()) - return NS_ERROR_UNEXPECTED; - - PLHashEntry** hep = - PL_HashTableRawLookup(mNamedDataSources, - (*mNamedDataSources->keyHash)(uri.get()), - uri.get()); - - // 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, uri.get())); - - 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 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(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 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 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 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(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, NS_ConvertUTF16toUTF8(value).get())); - - 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, NS_ConvertUTF16toUTF8(value).get())); - - 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(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(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] %" PRId64, - 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] %" PRId64, - 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(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; -} diff --git a/rdf/base/nsRDFService.h b/rdf/base/nsRDFService.h deleted file mode 100644 index 19ef355edb00..000000000000 --- a/rdf/base/nsRDFService.h +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- 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/. */ - -#ifndef nsRDFService_h__ -#define nsRDFService_h__ - -#include "nsIRDFService.h" -#include "nsWeakReference.h" -#include "nsIFactory.h" -#include "nsCOMPtr.h" -#include "PLDHashTable.h" -#include "nsString.h" - -struct PLHashTable; -class nsIRDFLiteral; -class nsIRDFInt; -class nsIRDFDate; -class BlobImpl; - -class RDFServiceImpl final : public nsIRDFService, - public nsSupportsWeakReference -{ -protected: - PLHashTable* mNamedDataSources; - PLDHashTable mResources; - PLDHashTable mLiterals; - PLDHashTable mInts; - PLDHashTable mDates; - PLDHashTable mBlobs; - - nsCString mLastURIPrefix; - nsCOMPtr mLastFactory; - nsCOMPtr mDefaultResourceFactory; - - RDFServiceImpl(); - nsresult Init(); - virtual ~RDFServiceImpl(); - -public: - static RDFServiceImpl *gRDFService NS_VISIBILITY_HIDDEN; - static nsresult CreateSingleton(nsISupports* aOuter, - const nsIID& aIID, void **aResult); - - // nsISupports - NS_DECL_ISUPPORTS - - // nsIRDFService - NS_DECL_NSIRDFSERVICE - - // Implementation methods - nsresult RegisterLiteral(nsIRDFLiteral* aLiteral); - nsresult UnregisterLiteral(nsIRDFLiteral* aLiteral); - nsresult RegisterInt(nsIRDFInt* aInt); - nsresult UnregisterInt(nsIRDFInt* aInt); - nsresult RegisterDate(nsIRDFDate* aDate); - nsresult UnregisterDate(nsIRDFDate* aDate); - nsresult RegisterBlob(BlobImpl* aBlob); - nsresult UnregisterBlob(BlobImpl* aBlob); - - nsresult GetDataSource(const char *aURI, bool aBlock, nsIRDFDataSource **aDataSource ); -}; - -#endif // nsRDFService_h__ diff --git a/rdf/base/nsRDFXMLDataSource.cpp b/rdf/base/nsRDFXMLDataSource.cpp deleted file mode 100644 index 5d4200a049ad..000000000000 --- a/rdf/base/nsRDFXMLDataSource.cpp +++ /dev/null @@ -1,1173 +0,0 @@ -/* -*- 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/. */ - -/* - - A data source that can read itself from and write itself to an - RDF/XML stream. - - For more information on the RDF/XML syntax, - see http://www.w3.org/TR/REC-rdf-syntax/. - - This code is based on the final W3C Recommendation, - http://www.w3.org/TR/1999/REC-rdf-syntax-19990222. - - - TO DO - ----- - - 1) Right now, the only kind of stream data sources that are _really_ - writable are "file:" URIs. (In fact, _all_ "file:" URIs are - writable, modulo file system permissions; this may lead to some - surprising behavior.) Eventually, it'd be great if we could open - an arbitrary nsIOutputStream on *any* URL, and Netlib could just - do the magic. - - 2) Implement a more terse output for "typed" nodes; that is, instead - of "RDF:Description type='ns:foo'", just output "ns:foo". - - 3) When re-serializing, we "cheat" for Descriptions that talk about - inline resources (i.e.., using the `ID' attribute specified in - [6.21]). Instead of writing an `ID="foo"' for the first instance, - and then `about="#foo"' for each subsequent instance, we just - _always_ write `about="#foo"'. - - We do this so that we can handle the case where an RDF container - has been assigned arbitrary properties: the spec says we can't - dangle the attributes directly off the container, so we need to - refer to it. Of course, with a little cleverness, we could fix - this. But who cares? - - 4) When re-serializing containers. We have to cheat on some - containers, and use an illegal "about=" construct. We do this to - handle containers that have been assigned URIs outside of the - local document. - - - Logging - ------- - - To turn on logging for this module, set - - MOZ_LOG=nsRDFXMLDataSource:5 - - */ - -#include "nsIFileStreams.h" -#include "nsIOutputStream.h" -#include "nsIFile.h" -#include "nsIFileChannel.h" -#include "nsIDTD.h" -#include "nsIRDFPurgeableDataSource.h" -#include "nsIInputStream.h" -#include "nsIOutputStream.h" -#include "nsIRDFContainerUtils.h" -#include "nsIRDFNode.h" -#include "nsIRDFRemoteDataSource.h" -#include "nsIRDFService.h" -#include "nsIRDFXMLParser.h" -#include "nsIRDFXMLSerializer.h" -#include "nsIRDFXMLSink.h" -#include "nsIRDFXMLSource.h" -#include "nsISafeOutputStream.h" -#include "nsIServiceManager.h" -#include "nsIStreamListener.h" -#include "nsIURL.h" -#include "nsIFileURL.h" -#include "nsISafeOutputStream.h" -#include "nsIChannel.h" -#include "nsRDFCID.h" -#include "nsRDFBaseDataSources.h" -#include "nsCOMArray.h" -#include "nsString.h" -#include "plstr.h" -#include "prio.h" -#include "prthread.h" -#include "rdf.h" -#include "rdfutil.h" -#include "mozilla/Logging.h" -#include "nsNameSpaceMap.h" -#include "nsCRT.h" -#include "nsCycleCollectionParticipant.h" -#include "nsIScriptSecurityManager.h" -#include "nsIChannelEventSink.h" -#include "nsIAsyncVerifyRedirectCallback.h" -#include "nsNetUtil.h" -#include "nsIContentPolicy.h" -#include "nsContentUtils.h" - -#include "rdfIDataSource.h" - -//---------------------------------------------------------------------- -// -// RDFXMLDataSourceImpl -// - -class RDFXMLDataSourceImpl : public nsIRDFDataSource, - public nsIRDFRemoteDataSource, - public nsIRDFXMLSink, - public nsIRDFXMLSource, - public nsIStreamListener, - public rdfIDataSource, - public nsIInterfaceRequestor, - public nsIChannelEventSink -{ -protected: - enum LoadState { - eLoadState_Unloaded, - eLoadState_Pending, - eLoadState_Loading, - eLoadState_Loaded - }; - - nsCOMPtr mInner; - bool mIsWritable; // true if the document can be written back - bool mIsDirty; // true if the document should be written back - LoadState mLoadState; // what we're doing now - nsCOMArray mObservers; - nsCOMPtr mURL; - nsCOMPtr mListener; - nsNameSpaceMap mNameSpaces; - - // pseudo-constants - static int32_t gRefCnt; - static nsIRDFService* gRDFService; - - static mozilla::LazyLogModule gLog; - - nsresult Init(); - RDFXMLDataSourceImpl(void); - virtual ~RDFXMLDataSourceImpl(void); - nsresult rdfXMLFlush(nsIURI *aURI); - - friend nsresult - NS_NewRDFXMLDataSource(nsIRDFDataSource** aResult); - - inline bool IsLoading() { - return (mLoadState == eLoadState_Pending) || - (mLoadState == eLoadState_Loading); - } - -public: - // nsISupports - NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(RDFXMLDataSourceImpl, - nsIRDFDataSource) - - // nsIRDFDataSource - NS_IMETHOD GetURI(nsACString& aURI) override; - - NS_IMETHOD GetSource(nsIRDFResource* property, - nsIRDFNode* target, - bool tv, - nsIRDFResource** source) override { - return mInner->GetSource(property, target, tv, source); - } - - NS_IMETHOD GetSources(nsIRDFResource* property, - nsIRDFNode* target, - bool tv, - nsISimpleEnumerator** sources) override { - return mInner->GetSources(property, target, tv, sources); - } - - NS_IMETHOD GetTarget(nsIRDFResource* source, - nsIRDFResource* property, - bool tv, - nsIRDFNode** target) override { - return mInner->GetTarget(source, property, tv, target); - } - - NS_IMETHOD GetTargets(nsIRDFResource* source, - nsIRDFResource* property, - bool tv, - nsISimpleEnumerator** targets) override { - return mInner->GetTargets(source, property, tv, targets); - } - - NS_IMETHOD Assert(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool tv) override; - - NS_IMETHOD Unassert(nsIRDFResource* source, - nsIRDFResource* property, - nsIRDFNode* target) override; - - NS_IMETHOD Change(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aOldTarget, - nsIRDFNode* aNewTarget) override; - - NS_IMETHOD Move(nsIRDFResource* aOldSource, - nsIRDFResource* aNewSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget) override; - - NS_IMETHOD HasAssertion(nsIRDFResource* source, - nsIRDFResource* property, - nsIRDFNode* target, - bool tv, - bool* hasAssertion) override { - return mInner->HasAssertion(source, property, target, tv, hasAssertion); - } - - NS_IMETHOD AddObserver(nsIRDFObserver* aObserver) override { - return mInner->AddObserver(aObserver); - } - - NS_IMETHOD RemoveObserver(nsIRDFObserver* aObserver) override { - return mInner->RemoveObserver(aObserver); - } - - NS_IMETHOD HasArcIn(nsIRDFNode *aNode, nsIRDFResource *aArc, bool *_retval) override { - return mInner->HasArcIn(aNode, aArc, _retval); - } - - NS_IMETHOD HasArcOut(nsIRDFResource *aSource, nsIRDFResource *aArc, bool *_retval) override { - return mInner->HasArcOut(aSource, aArc, _retval); - } - - NS_IMETHOD ArcLabelsIn(nsIRDFNode* node, - nsISimpleEnumerator** labels) override { - return mInner->ArcLabelsIn(node, labels); - } - - NS_IMETHOD ArcLabelsOut(nsIRDFResource* source, - nsISimpleEnumerator** labels) override { - return mInner->ArcLabelsOut(source, labels); - } - - NS_IMETHOD GetAllResources(nsISimpleEnumerator** aResult) override { - return mInner->GetAllResources(aResult); - } - - NS_IMETHOD GetAllCmds(nsIRDFResource* source, - nsISimpleEnumerator/**/** commands) override { - return mInner->GetAllCmds(source, commands); - } - - NS_IMETHOD IsCommandEnabled(nsISupports* aSources, - nsIRDFResource* aCommand, - nsISupports* aArguments, - bool* aResult) override { - return NS_ERROR_NOT_IMPLEMENTED; - } - - NS_IMETHOD DoCommand(nsISupports* aSources, - nsIRDFResource* aCommand, - nsISupports* aArguments) override { - return NS_ERROR_NOT_IMPLEMENTED; - } - - NS_IMETHOD BeginUpdateBatch() override { - return mInner->BeginUpdateBatch(); - } - - NS_IMETHOD EndUpdateBatch() override { - return mInner->EndUpdateBatch(); - } - - // nsIRDFRemoteDataSource interface - NS_DECL_NSIRDFREMOTEDATASOURCE - - // nsIRDFXMLSink interface - NS_DECL_NSIRDFXMLSINK - - // nsIRDFXMLSource interface - NS_DECL_NSIRDFXMLSOURCE - - // nsIRequestObserver - NS_DECL_NSIREQUESTOBSERVER - - // nsIStreamListener - NS_DECL_NSISTREAMLISTENER - - // nsIInterfaceRequestor - NS_DECL_NSIINTERFACEREQUESTOR - - // nsIChannelEventSink - NS_DECL_NSICHANNELEVENTSINK - - // rdfIDataSource - NS_IMETHOD VisitAllSubjects(rdfITripleVisitor *aVisitor) override { - nsresult rv; - nsCOMPtr rdfds = do_QueryInterface(mInner, &rv); - if (NS_FAILED(rv)) return rv; - return rdfds->VisitAllSubjects(aVisitor); - } - - NS_IMETHOD VisitAllTriples(rdfITripleVisitor *aVisitor) override { - nsresult rv; - nsCOMPtr rdfds = do_QueryInterface(mInner, &rv); - if (NS_FAILED(rv)) return rv; - return rdfds->VisitAllTriples(aVisitor); - } - - // Implementation methods - bool - MakeQName(nsIRDFResource* aResource, - nsString& property, - nsString& nameSpacePrefix, - nsString& nameSpaceURI); - - nsresult - SerializeAssertion(nsIOutputStream* aStream, - nsIRDFResource* aResource, - nsIRDFResource* aProperty, - nsIRDFNode* aValue); - - nsresult - SerializeProperty(nsIOutputStream* aStream, - nsIRDFResource* aResource, - nsIRDFResource* aProperty); - - bool - IsContainerProperty(nsIRDFResource* aProperty); - - nsresult - SerializeDescription(nsIOutputStream* aStream, - nsIRDFResource* aResource); - - nsresult - SerializeMember(nsIOutputStream* aStream, - nsIRDFResource* aContainer, - nsIRDFNode* aMember); - - nsresult - SerializeContainer(nsIOutputStream* aStream, - nsIRDFResource* aContainer); - - nsresult - SerializePrologue(nsIOutputStream* aStream); - - nsresult - SerializeEpilogue(nsIOutputStream* aStream); - - bool - IsA(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource, nsIRDFResource* aType); - -protected: - nsresult - BlockingParse(nsIURI* aURL, nsIStreamListener* aConsumer); -}; - -int32_t RDFXMLDataSourceImpl::gRefCnt = 0; -nsIRDFService* RDFXMLDataSourceImpl::gRDFService; - -mozilla::LazyLogModule RDFXMLDataSourceImpl::gLog("nsRDFXMLDataSource"); - -static const char kFileURIPrefix[] = "file:"; -static const char kResourceURIPrefix[] = "resource:"; - - -//---------------------------------------------------------------------- - -nsresult -NS_NewRDFXMLDataSource(nsIRDFDataSource** aResult) -{ - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - RDFXMLDataSourceImpl* datasource = new RDFXMLDataSourceImpl(); - if (! datasource) - return NS_ERROR_OUT_OF_MEMORY; - - nsresult rv; - rv = datasource->Init(); - - if (NS_FAILED(rv)) { - delete datasource; - return rv; - } - - NS_ADDREF(datasource); - *aResult = datasource; - return NS_OK; -} - - -RDFXMLDataSourceImpl::RDFXMLDataSourceImpl(void) - : mIsWritable(true), - mIsDirty(false), - mLoadState(eLoadState_Unloaded) -{ -} - - -nsresult -RDFXMLDataSourceImpl::Init() -{ - nsresult rv; - NS_DEFINE_CID(kRDFInMemoryDataSourceCID, NS_RDFINMEMORYDATASOURCE_CID); - mInner = do_CreateInstance(kRDFInMemoryDataSourceCID, &rv); - if (NS_FAILED(rv)) return rv; - - if (gRefCnt++ == 0) { - NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); - rv = CallGetService(kRDFServiceCID, &gRDFService); - - NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get RDF service"); - if (NS_FAILED(rv)) return rv; - } - - return NS_OK; -} - - -RDFXMLDataSourceImpl::~RDFXMLDataSourceImpl(void) -{ - // Unregister first so that nobody else tries to get us. - (void) gRDFService->UnregisterDataSource(this); - - // Now flush contents - (void) Flush(); - - // Release RDF/XML sink observers - mObservers.Clear(); - - if (--gRefCnt == 0) - NS_IF_RELEASE(gRDFService); -} - -NS_IMPL_CYCLE_COLLECTION_CLASS(RDFXMLDataSourceImpl) - -NS_IMPL_CYCLE_COLLECTION_UNLINK_0(RDFXMLDataSourceImpl) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(RDFXMLDataSourceImpl) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mInner) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END - -NS_IMPL_CYCLE_COLLECTING_ADDREF(RDFXMLDataSourceImpl) -NS_IMPL_CYCLE_COLLECTING_RELEASE(RDFXMLDataSourceImpl) - -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(RDFXMLDataSourceImpl) - NS_INTERFACE_MAP_ENTRY(nsIRDFDataSource) - NS_INTERFACE_MAP_ENTRY(nsIRDFRemoteDataSource) - NS_INTERFACE_MAP_ENTRY(nsIRDFXMLSink) - NS_INTERFACE_MAP_ENTRY(nsIRDFXMLSource) - NS_INTERFACE_MAP_ENTRY(nsIRequestObserver) - NS_INTERFACE_MAP_ENTRY(nsIStreamListener) - NS_INTERFACE_MAP_ENTRY(rdfIDataSource) - NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor) - NS_INTERFACE_MAP_ENTRY(nsIChannelEventSink) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRDFDataSource) -NS_INTERFACE_MAP_END - -// nsIInterfaceRequestor -NS_IMETHODIMP -RDFXMLDataSourceImpl::GetInterface(const nsIID& aIID, void** aSink) -{ - return QueryInterface(aIID, aSink); -} - -nsresult -RDFXMLDataSourceImpl::BlockingParse(nsIURI* aURL, nsIStreamListener* aConsumer) -{ - nsresult rv; - - // XXX I really hate the way that we're spoon-feeding this stuff - // to the parser: it seems like this is something that netlib - // should be able to do by itself. - - nsCOMPtr channel; - - // Null LoadGroup ? - rv = NS_NewChannel(getter_AddRefs(channel), - aURL, - nsContentUtils::GetSystemPrincipal(), - nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, - nsIContentPolicy::TYPE_OTHER); - - if (NS_FAILED(rv)) return rv; - nsCOMPtr in; - rv = channel->Open2(getter_AddRefs(in)); - - // Report success if the file doesn't exist, but propagate other errors. - if (rv == NS_ERROR_FILE_NOT_FOUND) return NS_OK; - if (NS_FAILED(rv)) return rv; - - if (! in) { - NS_ERROR("no input stream"); - return NS_ERROR_FAILURE; - } - - // Wrap the channel's input stream in a buffered stream to ensure that - // ReadSegments is implemented (which OnDataAvailable expects). - nsCOMPtr bufStream; - rv = NS_NewBufferedInputStream(getter_AddRefs(bufStream), in.forget(), - 4096 /* buffer size */); - if (NS_FAILED(rv)) return rv; - - // Notify load observers - int32_t i; - for (i = mObservers.Count() - 1; i >= 0; --i) { - // Make sure to hold a strong reference to the observer so - // that it doesn't go away in this call if it removes itself - // as an observer - nsCOMPtr obs = mObservers[i]; - - if (obs) { - obs->OnBeginLoad(this); - } - } - - rv = aConsumer->OnStartRequest(channel, nullptr); - - uint64_t offset = 0; - while (NS_SUCCEEDED(rv)) { - // Skip ODA if the channel is canceled - channel->GetStatus(&rv); - if (NS_FAILED(rv)) - break; - - uint64_t avail; - if (NS_FAILED(rv = bufStream->Available(&avail))) - break; // error - - if (avail == 0) - break; // eof - - if (avail > UINT32_MAX) - avail = UINT32_MAX; - - rv = aConsumer->OnDataAvailable(channel, nullptr, bufStream, offset, (uint32_t)avail); - if (NS_SUCCEEDED(rv)) - offset += avail; - } - - if (NS_FAILED(rv)) - channel->Cancel(rv); - - channel->GetStatus(&rv); - aConsumer->OnStopRequest(channel, nullptr, rv); - - // Notify load observers - for (i = mObservers.Count() - 1; i >= 0; --i) { - // Make sure to hold a strong reference to the observer so - // that it doesn't go away in this call if it removes itself - // as an observer - nsCOMPtr obs = mObservers[i]; - - if (obs) { - if (NS_FAILED(rv)) - obs->OnError(this, rv, nullptr); - - obs->OnEndLoad(this); - } - } - - return rv; -} - -NS_IMETHODIMP -RDFXMLDataSourceImpl::GetLoaded(bool* _result) -{ - *_result = (mLoadState == eLoadState_Loaded); - return NS_OK; -} - -NS_IMETHODIMP -RDFXMLDataSourceImpl::Init(const char* uri) -{ - NS_PRECONDITION(mInner != nullptr, "not initialized"); - if (! mInner) - return NS_ERROR_OUT_OF_MEMORY; - - nsresult rv; - - rv = NS_NewURI(getter_AddRefs(mURL), nsDependentCString(uri)); - if (NS_FAILED(rv)) return rv; - - // XXX this is a hack: any "file:" URI is considered writable. All - // others are considered read-only. - if ((PL_strncmp(uri, kFileURIPrefix, sizeof(kFileURIPrefix) - 1) != 0) && - (PL_strncmp(uri, kResourceURIPrefix, sizeof(kResourceURIPrefix) - 1) != 0)) { - mIsWritable = false; - } - - rv = gRDFService->RegisterDataSource(this, false); - if (NS_FAILED(rv)) return rv; - - return NS_OK; -} - - -NS_IMETHODIMP -RDFXMLDataSourceImpl::GetURI(nsACString& aURI) -{ - if (!mURL) { - aURI.SetIsVoid(true); - return NS_OK; - } - - return mURL->GetSpec(aURI); -} - -NS_IMETHODIMP -RDFXMLDataSourceImpl::Assert(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue) -{ - // We don't accept assertions unless we're writable (except in the - // case that we're actually _reading_ the datasource in). - nsresult rv; - - if (IsLoading()) { - bool hasAssertion = false; - - nsCOMPtr gcable = do_QueryInterface(mInner); - if (gcable) { - rv = gcable->Mark(aSource, aProperty, aTarget, aTruthValue, &hasAssertion); - if (NS_FAILED(rv)) return rv; - } - - rv = NS_RDF_ASSERTION_ACCEPTED; - - if (! hasAssertion) { - rv = mInner->Assert(aSource, aProperty, aTarget, aTruthValue); - - if (NS_SUCCEEDED(rv) && gcable) { - // Now mark the new assertion, so it doesn't get - // removed when we sweep. Ignore rv, because we want - // to return what mInner->Assert() gave us. - bool didMark; - (void) gcable->Mark(aSource, aProperty, aTarget, aTruthValue, &didMark); - } - - if (NS_FAILED(rv)) return rv; - } - - return rv; - } - else if (mIsWritable) { - rv = mInner->Assert(aSource, aProperty, aTarget, aTruthValue); - - if (rv == NS_RDF_ASSERTION_ACCEPTED) - mIsDirty = true; - - return rv; - } - else { - return NS_RDF_ASSERTION_REJECTED; - } -} - - -NS_IMETHODIMP -RDFXMLDataSourceImpl::Unassert(nsIRDFResource* source, - nsIRDFResource* property, - nsIRDFNode* target) -{ - // We don't accept assertions unless we're writable (except in the - // case that we're actually _reading_ the datasource in). - nsresult rv; - - if (IsLoading() || mIsWritable) { - rv = mInner->Unassert(source, property, target); - if (!IsLoading() && rv == NS_RDF_ASSERTION_ACCEPTED) - mIsDirty = true; - } - else { - rv = NS_RDF_ASSERTION_REJECTED; - } - - return rv; -} - -NS_IMETHODIMP -RDFXMLDataSourceImpl::Change(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aOldTarget, - nsIRDFNode* aNewTarget) -{ - nsresult rv; - - if (IsLoading() || mIsWritable) { - rv = mInner->Change(aSource, aProperty, aOldTarget, aNewTarget); - - if (!IsLoading() && rv == NS_RDF_ASSERTION_ACCEPTED) - mIsDirty = true; - } - else { - rv = NS_RDF_ASSERTION_REJECTED; - } - - return rv; -} - -NS_IMETHODIMP -RDFXMLDataSourceImpl::Move(nsIRDFResource* aOldSource, - nsIRDFResource* aNewSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget) -{ - nsresult rv; - - if (IsLoading() || mIsWritable) { - rv = mInner->Move(aOldSource, aNewSource, aProperty, aTarget); - if (!IsLoading() && rv == NS_RDF_ASSERTION_ACCEPTED) - mIsDirty = true; - } - else { - rv = NS_RDF_ASSERTION_REJECTED; - } - - return rv; -} - - -nsresult -RDFXMLDataSourceImpl::rdfXMLFlush(nsIURI *aURI) -{ - - nsresult rv; - - { - // Quick and dirty check to see if we're in XPCOM shutdown. If - // we are, we're screwed: it's too late to serialize because - // many of the services that we'll need to acquire to properly - // write the file will be unaquirable. - NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); - nsCOMPtr dummy = do_GetService(kRDFServiceCID, &rv); - if (NS_FAILED(rv)) { - NS_WARNING("unable to Flush() dirty datasource during XPCOM shutdown"); - return rv; - } - } - - // Is it a file? If so, we can write to it. Some day, it'd be nice - // if we didn't care what kind of stream this was... - nsCOMPtr fileURL = do_QueryInterface(aURI); - - if (fileURL) { - nsCOMPtr file; - fileURL->GetFile(getter_AddRefs(file)); - if (file) { - // get a safe output stream, so we don't clobber the datasource file unless - // all the writes succeeded. - nsCOMPtr out; - rv = NS_NewSafeLocalFileOutputStream(getter_AddRefs(out), - file, - PR_WRONLY | PR_CREATE_FILE, - /*octal*/ 0666, - 0); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr bufferedOut; - rv = NS_NewBufferedOutputStream(getter_AddRefs(bufferedOut), - out.forget(), 4096); - if (NS_FAILED(rv)) return rv; - - rv = Serialize(bufferedOut); - if (NS_FAILED(rv)) return rv; - - // All went ok. Maybe except for problems in Write(), but the stream detects - // that for us - nsCOMPtr safeStream = do_QueryInterface(bufferedOut, &rv); - if (NS_FAILED(rv)) return rv; - - rv = safeStream->Finish(); - if (NS_FAILED(rv)) { - NS_WARNING("failed to save datasource file! possible dataloss"); - return rv; - } - } - } - - return NS_OK; -} - - -NS_IMETHODIMP -RDFXMLDataSourceImpl::FlushTo(const char *aURI) -{ - NS_PRECONDITION(aURI != nullptr, "not initialized"); - if (!aURI) - return NS_ERROR_NULL_POINTER; - - // XXX this is a hack: any "file:" URI is considered writable. All - // others are considered read-only. - if ((PL_strncmp(aURI, kFileURIPrefix, sizeof(kFileURIPrefix) - 1) != 0) && - (PL_strncmp(aURI, kResourceURIPrefix, sizeof(kResourceURIPrefix) - 1) != 0)) - { - return NS_ERROR_ILLEGAL_VALUE; - } - - nsCOMPtr url; - nsresult rv = NS_NewURI(getter_AddRefs(url), aURI); - if (NS_FAILED(rv)) - return rv; - rv = rdfXMLFlush(url); - return rv; -} - - -NS_IMETHODIMP -RDFXMLDataSourceImpl::Flush(void) -{ - if (!mIsWritable || !mIsDirty) - return NS_OK; - - // while it is not fatal if mURL is not set, - // indicate failure since we can't flush back to an unknown origin - if (! mURL) - return NS_ERROR_NOT_INITIALIZED; - - if (MOZ_LOG_TEST(gLog, LogLevel::Debug)) { - MOZ_LOG(gLog, LogLevel::Debug, - ("rdfxml[%p] flush(%s)", this, mURL->GetSpecOrDefault().get())); - } - - nsresult rv; - if (NS_SUCCEEDED(rv = rdfXMLFlush(mURL))) - { - mIsDirty = false; - } - return rv; -} - - -//---------------------------------------------------------------------- -// -// nsIRDFXMLDataSource methods -// - -NS_IMETHODIMP -RDFXMLDataSourceImpl::GetReadOnly(bool* aIsReadOnly) -{ - *aIsReadOnly = !mIsWritable; - return NS_OK; -} - - -NS_IMETHODIMP -RDFXMLDataSourceImpl::SetReadOnly(bool aIsReadOnly) -{ - if (mIsWritable && aIsReadOnly) - mIsWritable = false; - - return NS_OK; -} - -// nsIChannelEventSink - -// This code is copied from nsSameOriginChecker::OnChannelRedirect. See -// bug 475940 on providing this code in a shared location. -NS_IMETHODIMP -RDFXMLDataSourceImpl::AsyncOnChannelRedirect(nsIChannel *aOldChannel, - nsIChannel *aNewChannel, - uint32_t aFlags, - nsIAsyncVerifyRedirectCallback *cb) -{ - NS_PRECONDITION(aNewChannel, "Redirecting to null channel?"); - - nsresult rv; - nsCOMPtr secMan = - do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr oldPrincipal; - secMan->GetChannelResultPrincipal(aOldChannel, getter_AddRefs(oldPrincipal)); - - nsCOMPtr newURI; - aNewChannel->GetURI(getter_AddRefs(newURI)); - nsCOMPtr newOriginalURI; - aNewChannel->GetOriginalURI(getter_AddRefs(newOriginalURI)); - - NS_ENSURE_STATE(oldPrincipal && newURI && newOriginalURI); - - rv = oldPrincipal->CheckMayLoad(newURI, false, false); - if (NS_SUCCEEDED(rv) && newOriginalURI != newURI) { - rv = oldPrincipal->CheckMayLoad(newOriginalURI, false, false); - } - - if (NS_FAILED(rv)) - return rv; - - cb->OnRedirectVerifyCallback(NS_OK); - return NS_OK; -} - -NS_IMETHODIMP -RDFXMLDataSourceImpl::Refresh(bool aBlocking) -{ - nsAutoCString spec; - if (mURL) { - spec = mURL->GetSpecOrDefault(); - } - MOZ_LOG(gLog, LogLevel::Debug, - ("rdfxml[%p] refresh(%s) %sblocking", this, spec.get(), (aBlocking ? "" : "non"))); - - // If an asynchronous load is already pending, then just let it do - // the honors. - if (IsLoading()) { - MOZ_LOG(gLog, LogLevel::Debug, - ("rdfxml[%p] refresh(%s) a load was pending", this, spec.get())); - - if (aBlocking) { - NS_WARNING("blocking load requested when async load pending"); - return NS_ERROR_FAILURE; - } - else { - return NS_OK; - } - } - - if (! mURL) - return NS_ERROR_FAILURE; - nsCOMPtr parser = do_CreateInstance("@mozilla.org/rdf/xml-parser;1"); - if (! parser) - return NS_ERROR_FAILURE; - - nsresult rv = parser->ParseAsync(this, mURL, getter_AddRefs(mListener)); - if (NS_FAILED(rv)) return rv; - - if (aBlocking) { - rv = BlockingParse(mURL, this); - - mListener = nullptr; // release the parser - - if (NS_FAILED(rv)) return rv; - } - else { - // Null LoadGroup ? - nsCOMPtr channel; - rv = NS_NewChannel(getter_AddRefs(channel), - mURL, - nsContentUtils::GetSystemPrincipal(), - nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, - nsIContentPolicy::TYPE_OTHER, - nullptr, // aPerformanceStorage - nullptr, // aLoadGroup - this); // aCallbacks - NS_ENSURE_SUCCESS(rv, rv); - rv = channel->AsyncOpen2(this); - NS_ENSURE_SUCCESS(rv, rv); - - // So we don't try to issue two asynchronous loads at once. - mLoadState = eLoadState_Pending; - } - - return NS_OK; -} - -NS_IMETHODIMP -RDFXMLDataSourceImpl::BeginLoad(void) -{ - if (MOZ_LOG_TEST(gLog, LogLevel::Debug)) { - MOZ_LOG(gLog, LogLevel::Debug, - ("rdfxml[%p] begin-load(%s)", this, - mURL ? mURL->GetSpecOrDefault().get() : "")); - } - - mLoadState = eLoadState_Loading; - for (int32_t i = mObservers.Count() - 1; i >= 0; --i) { - // Make sure to hold a strong reference to the observer so - // that it doesn't go away in this call if it removes itself - // as an observer - nsCOMPtr obs = mObservers[i]; - - if (obs) { - obs->OnBeginLoad(this); - } - } - return NS_OK; -} - -NS_IMETHODIMP -RDFXMLDataSourceImpl::Interrupt(void) -{ - if (MOZ_LOG_TEST(gLog, LogLevel::Debug)) { - MOZ_LOG(gLog, LogLevel::Debug, - ("rdfxml[%p] interrupt(%s)", this, - mURL ? mURL->GetSpecOrDefault().get() : "")); - } - - for (int32_t i = mObservers.Count() - 1; i >= 0; --i) { - // Make sure to hold a strong reference to the observer so - // that it doesn't go away in this call if it removes itself - // as an observer - nsCOMPtr obs = mObservers[i]; - - if (obs) { - obs->OnInterrupt(this); - } - } - return NS_OK; -} - -NS_IMETHODIMP -RDFXMLDataSourceImpl::Resume(void) -{ - if (MOZ_LOG_TEST(gLog, LogLevel::Debug)) { - MOZ_LOG(gLog, LogLevel::Debug, - ("rdfxml[%p] resume(%s)", this, - mURL ? mURL->GetSpecOrDefault().get() : "")); - } - - for (int32_t i = mObservers.Count() - 1; i >= 0; --i) { - // Make sure to hold a strong reference to the observer so - // that it doesn't go away in this call if it removes itself - // as an observer - nsCOMPtr obs = mObservers[i]; - - if (obs) { - obs->OnResume(this); - } - } - return NS_OK; -} - -NS_IMETHODIMP -RDFXMLDataSourceImpl::EndLoad(void) -{ - if (MOZ_LOG_TEST(gLog, LogLevel::Debug)) { - MOZ_LOG(gLog, LogLevel::Debug, - ("rdfxml[%p] end-load(%s)", this, - mURL ? mURL->GetSpecOrDefault().get() : "")); - } - - mLoadState = eLoadState_Loaded; - - // Clear out any unmarked assertions from the datasource. - nsCOMPtr gcable = do_QueryInterface(mInner); - if (gcable) { - gcable->Sweep(); - } - - // Notify load observers - for (int32_t i = mObservers.Count() - 1; i >= 0; --i) { - // Make sure to hold a strong reference to the observer so - // that it doesn't go away in this call if it removes itself - // as an observer - nsCOMPtr obs = mObservers[i]; - - if (obs) { - obs->OnEndLoad(this); - } - } - return NS_OK; -} - -NS_IMETHODIMP -RDFXMLDataSourceImpl::AddNameSpace(nsAtom* aPrefix, const nsString& aURI) -{ - mNameSpaces.Put(aURI, aPrefix); - return NS_OK; -} - - -NS_IMETHODIMP -RDFXMLDataSourceImpl::AddXMLSinkObserver(nsIRDFXMLSinkObserver* aObserver) -{ - if (! aObserver) - return NS_ERROR_NULL_POINTER; - - mObservers.AppendObject(aObserver); - return NS_OK; -} - -NS_IMETHODIMP -RDFXMLDataSourceImpl::RemoveXMLSinkObserver(nsIRDFXMLSinkObserver* aObserver) -{ - if (! aObserver) - return NS_ERROR_NULL_POINTER; - - mObservers.RemoveObject(aObserver); - - return NS_OK; -} - - -//---------------------------------------------------------------------- -// -// nsIRequestObserver -// - -NS_IMETHODIMP -RDFXMLDataSourceImpl::OnStartRequest(nsIRequest *request, nsISupports *ctxt) -{ - return mListener->OnStartRequest(request, ctxt); -} - -NS_IMETHODIMP -RDFXMLDataSourceImpl::OnStopRequest(nsIRequest *request, - nsISupports *ctxt, - nsresult status) -{ - if (NS_FAILED(status)) { - for (int32_t i = mObservers.Count() - 1; i >= 0; --i) { - // Make sure to hold a strong reference to the observer so - // that it doesn't go away in this call if it removes - // itself as an observer - nsCOMPtr obs = mObservers[i]; - - if (obs) { - obs->OnError(this, status, nullptr); - } - } - } - - nsresult rv; - rv = mListener->OnStopRequest(request, ctxt, status); - - mListener = nullptr; // release the parser - - return rv; -} - -//---------------------------------------------------------------------- -// -// nsIStreamListener -// - -NS_IMETHODIMP -RDFXMLDataSourceImpl::OnDataAvailable(nsIRequest *request, - nsISupports *ctxt, - nsIInputStream *inStr, - uint64_t sourceOffset, - uint32_t count) -{ - return mListener->OnDataAvailable(request, ctxt, inStr, sourceOffset, count); -} - -//---------------------------------------------------------------------- -// -// nsIRDFXMLSource -// - -NS_IMETHODIMP -RDFXMLDataSourceImpl::Serialize(nsIOutputStream* aStream) -{ - nsresult rv; - nsCOMPtr serializer - = do_CreateInstance("@mozilla.org/rdf/xml-serializer;1", &rv); - - if (! serializer) - return rv; - - rv = serializer->Init(this); - if (NS_FAILED(rv)) return rv; - - // Add any namespace information that we picked up when reading - // the RDF/XML - nsNameSpaceMap::const_iterator last = mNameSpaces.last(); - for (nsNameSpaceMap::const_iterator iter = mNameSpaces.first(); - iter != last; ++iter) { - // We might wanna change nsIRDFXMLSerializer to nsACString and - // use a heap allocated buffer here in the future. - NS_ConvertUTF8toUTF16 uri(iter->mURI); - serializer->AddNameSpace(iter->mPrefix, uri); - } - - // Serialize! - nsCOMPtr source = do_QueryInterface(serializer); - if (! source) - return NS_ERROR_FAILURE; - - return source->Serialize(aStream); -} diff --git a/rdf/base/nsRDFXMLParser.cpp b/rdf/base/nsRDFXMLParser.cpp deleted file mode 100644 index 819e53d702bb..000000000000 --- a/rdf/base/nsRDFXMLParser.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/* -*- 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/. */ - -#include "nsRDFXMLParser.h" - -#include "mozilla/Encoding.h" -#include "nsIComponentManager.h" -#include "nsIParser.h" -#include "nsCharsetSource.h" -#include "nsIRDFContentSink.h" -#include "nsParserCIID.h" -#include "nsStringStream.h" -#include "nsNetUtil.h" -#include "NullPrincipal.h" - -static NS_DEFINE_CID(kParserCID, NS_PARSER_CID); - -NS_IMPL_ISUPPORTS(nsRDFXMLParser, nsIRDFXMLParser) - -nsresult -nsRDFXMLParser::Create(nsISupports* aOuter, REFNSIID aIID, void** aResult) -{ - if (aOuter) - return NS_ERROR_NO_AGGREGATION; - - nsRDFXMLParser* result = new nsRDFXMLParser(); - if (! result) - return NS_ERROR_OUT_OF_MEMORY; - - nsresult rv; - NS_ADDREF(result); - rv = result->QueryInterface(aIID, aResult); - NS_RELEASE(result); - return rv; -} - -nsRDFXMLParser::nsRDFXMLParser() -{ -} - -nsRDFXMLParser::~nsRDFXMLParser() -{ -} - -NS_IMETHODIMP -nsRDFXMLParser::ParseAsync(nsIRDFDataSource* aSink, nsIURI* aBaseURI, nsIStreamListener** aResult) -{ - nsresult rv; - - nsCOMPtr sink = - do_CreateInstance("@mozilla.org/rdf/content-sink;1", &rv); - - if (NS_FAILED(rv)) return rv; - - rv = sink->Init(aBaseURI); - if (NS_FAILED(rv)) return rv; - - // We set the content sink's data source directly to our in-memory - // store. This allows the initial content to be generated "directly". - rv = sink->SetDataSource(aSink); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr parser = do_CreateInstance(kParserCID, &rv); - if (NS_FAILED(rv)) return rv; - - parser->SetDocumentCharset(UTF_8_ENCODING, - kCharsetFromDocTypeDefault); - parser->SetContentSink(sink); - - rv = parser->Parse(aBaseURI); - if (NS_FAILED(rv)) return rv; - - return CallQueryInterface(parser, aResult); -} - -NS_IMETHODIMP -nsRDFXMLParser::ParseString(nsIRDFDataSource* aSink, nsIURI* aBaseURI, const nsACString& aString) -{ - nsresult rv; - - nsCOMPtr sink = - do_CreateInstance("@mozilla.org/rdf/content-sink;1", &rv); - - if (NS_FAILED(rv)) return rv; - - rv = sink->Init(aBaseURI); - if (NS_FAILED(rv)) return rv; - - // We set the content sink's data source directly to our in-memory - // store. This allows the initial content to be generated "directly". - rv = sink->SetDataSource(aSink); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr parser = do_CreateInstance(kParserCID, &rv); - if (NS_FAILED(rv)) return rv; - - parser->SetDocumentCharset(UTF_8_ENCODING, - kCharsetFromOtherComponent); - parser->SetContentSink(sink); - - rv = parser->Parse(aBaseURI); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr listener = - do_QueryInterface(parser); - - if (! listener) - return NS_ERROR_FAILURE; - - nsCOMPtr stream; - rv = NS_NewCStringInputStream(getter_AddRefs(stream), aString); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr nullPrincipal = NullPrincipal::CreateWithoutOriginAttributes(); - - // The following channel is never openend, so it does not matter what - // securityFlags we pass; let's follow the principle of least privilege. - nsCOMPtr channel; - nsCOMPtr tmpStream = stream; - rv = NS_NewInputStreamChannel(getter_AddRefs(channel), - aBaseURI, - tmpStream.forget(), - nullPrincipal, - nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED, - nsIContentPolicy::TYPE_OTHER, - NS_LITERAL_CSTRING("text/xml")); - if (NS_FAILED(rv)) return rv; - - listener->OnStartRequest(channel, nullptr); - listener->OnDataAvailable(channel, nullptr, stream, 0, aString.Length()); - listener->OnStopRequest(channel, nullptr, NS_OK); - - return NS_OK; -} diff --git a/rdf/base/nsRDFXMLParser.h b/rdf/base/nsRDFXMLParser.h deleted file mode 100644 index d35c873fbecf..000000000000 --- a/rdf/base/nsRDFXMLParser.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -*- 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/. */ - -#ifndef nsRDFParser_h__ -#define nsRDFParser_h__ - -#include "nsCOMPtr.h" -#include "nsString.h" -#include "nsIRDFXMLParser.h" -#include "nsIRDFDataSource.h" - -/** - * A helper class that is used to parse RDF/XML. - */ -class nsRDFXMLParser : public nsIRDFXMLParser { -public: - static nsresult - Create(nsISupports* aOuter, REFNSIID aIID, void** aResult); - - NS_DECL_ISUPPORTS - NS_DECL_NSIRDFXMLPARSER - -protected: - nsRDFXMLParser(); - virtual ~nsRDFXMLParser(); -}; - -#endif // nsRDFParser_h__ diff --git a/rdf/base/nsRDFXMLSerializer.cpp b/rdf/base/nsRDFXMLSerializer.cpp deleted file mode 100644 index c93307c9da72..000000000000 --- a/rdf/base/nsRDFXMLSerializer.cpp +++ /dev/null @@ -1,1123 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=4 sw=4 et tw=80: - * - * 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/. */ - -#include "nsRDFXMLSerializer.h" - -#include "nsAtom.h" -#include "nsIOutputStream.h" -#include "nsIRDFService.h" -#include "nsIRDFContainerUtils.h" -#include "nsIServiceManager.h" -#include "nsString.h" -#include "nsTArray.h" -#include "rdf.h" -#include "rdfutil.h" -#include "mozilla/Attributes.h" - -#include "rdfIDataSource.h" - -int32_t nsRDFXMLSerializer::gRefCnt = 0; -nsIRDFContainerUtils* nsRDFXMLSerializer::gRDFC; -nsIRDFResource* nsRDFXMLSerializer::kRDF_instanceOf; -nsIRDFResource* nsRDFXMLSerializer::kRDF_type; -nsIRDFResource* nsRDFXMLSerializer::kRDF_nextVal; -nsIRDFResource* nsRDFXMLSerializer::kRDF_Bag; -nsIRDFResource* nsRDFXMLSerializer::kRDF_Seq; -nsIRDFResource* nsRDFXMLSerializer::kRDF_Alt; - -static const char kRDFDescriptionOpen[] = " \n"; -static const char kRDFParseTypeInteger[] = " NC:parseType=\"Integer\">"; -static const char kRDFParseTypeDate[] = " NC:parseType=\"Date\">"; -static const char kRDFUnknown[] = ">"; - -nsresult -nsRDFXMLSerializer::Create(nsISupports* aOuter, REFNSIID aIID, void** aResult) -{ - if (aOuter) - return NS_ERROR_NO_AGGREGATION; - - nsCOMPtr result = new nsRDFXMLSerializer(); - if (! result) - return NS_ERROR_OUT_OF_MEMORY; - // The serializer object is here, addref gRefCnt so that the - // destructor can safely release it. - gRefCnt++; - - nsresult rv; - rv = result->QueryInterface(aIID, aResult); - - if (NS_FAILED(rv)) return rv; - - if (gRefCnt == 1) do { - nsCOMPtr rdf = do_GetService("@mozilla.org/rdf/rdf-service;1", &rv); - if (NS_FAILED(rv)) break; - - rv = rdf->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "instanceOf"), - &kRDF_instanceOf); - if (NS_FAILED(rv)) break; - - rv = rdf->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "type"), - &kRDF_type); - if (NS_FAILED(rv)) break; - - rv = rdf->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "nextVal"), - &kRDF_nextVal); - if (NS_FAILED(rv)) break; - - rv = rdf->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "Bag"), - &kRDF_Bag); - if (NS_FAILED(rv)) break; - - rv = rdf->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "Seq"), - &kRDF_Seq); - if (NS_FAILED(rv)) break; - - rv = rdf->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "Alt"), - &kRDF_Alt); - if (NS_FAILED(rv)) break; - - rv = CallGetService("@mozilla.org/rdf/container-utils;1", &gRDFC); - if (NS_FAILED(rv)) break; - } while (0); - - return rv; -} - -nsRDFXMLSerializer::nsRDFXMLSerializer() -{ -} - -nsRDFXMLSerializer::~nsRDFXMLSerializer() -{ - if (--gRefCnt == 0) { - NS_IF_RELEASE(kRDF_Bag); - NS_IF_RELEASE(kRDF_Seq); - NS_IF_RELEASE(kRDF_Alt); - NS_IF_RELEASE(kRDF_instanceOf); - NS_IF_RELEASE(kRDF_type); - NS_IF_RELEASE(kRDF_nextVal); - NS_IF_RELEASE(gRDFC); - } -} - -NS_IMPL_ISUPPORTS(nsRDFXMLSerializer, nsIRDFXMLSerializer, nsIRDFXMLSource) - -NS_IMETHODIMP -nsRDFXMLSerializer::Init(nsIRDFDataSource* aDataSource) -{ - if (! aDataSource) - return NS_ERROR_NULL_POINTER; - - mDataSource = aDataSource; - mDataSource->GetURI(mBaseURLSpec); - - // Add the ``RDF'' prefix, by default. - RefPtr prefix; - - prefix = NS_Atomize("RDF"); - AddNameSpace(prefix, NS_LITERAL_STRING("http://www.w3.org/1999/02/22-rdf-syntax-ns#")); - - prefix = NS_Atomize("NC"); - AddNameSpace(prefix, NS_LITERAL_STRING("http://home.netscape.com/NC-rdf#")); - - mPrefixID = 0; - - return NS_OK; -} - -NS_IMETHODIMP -nsRDFXMLSerializer::AddNameSpace(nsAtom* aPrefix, const nsAString& aURI) -{ - RefPtr prefix = aPrefix; - if (!prefix) { - // Make up a prefix, we don't want default namespaces, so - // that we can use QNames for elements and attributes alike. - prefix = EnsureNewPrefix(); - } - mNameSpaces.Put(aURI, prefix); - return NS_OK; -} - -static nsresult -rdf_BlockingWrite(nsIOutputStream* stream, const char* buf, uint32_t size) -{ - uint32_t written = 0; - uint32_t remaining = size; - while (remaining > 0) { - nsresult rv; - uint32_t cb; - - if (NS_FAILED(rv = stream->Write(buf + written, remaining, &cb))) - return rv; - - written += cb; - remaining -= cb; - } - return NS_OK; -} - -static nsresult -rdf_BlockingWrite(nsIOutputStream* stream, const nsACString& s) -{ - return rdf_BlockingWrite(stream, s.BeginReading(), s.Length()); -} - -static nsresult -rdf_BlockingWrite(nsIOutputStream* stream, const nsAString& s) -{ - NS_ConvertUTF16toUTF8 utf8(s); - return rdf_BlockingWrite(stream, utf8.get(), utf8.Length()); -} - -already_AddRefed -nsRDFXMLSerializer::EnsureNewPrefix() -{ - nsAutoString qname; - RefPtr prefix; - bool isNewPrefix; - do { - isNewPrefix = true; - qname.AssignLiteral("NS"); - qname.AppendInt(++mPrefixID, 10); - prefix = NS_Atomize(qname); - nsNameSpaceMap::const_iterator iter = mNameSpaces.first(); - while (iter != mNameSpaces.last() && isNewPrefix) { - isNewPrefix = (iter->mPrefix != prefix); - ++iter; - } - } while (!isNewPrefix); - return prefix.forget(); -} - -// This converts a property resource (like -// "http://www.w3.org/TR/WD-rdf-syntax#Description") into a QName -// ("RDF:Description"), and registers the namespace, if it's made up. - -nsresult -nsRDFXMLSerializer::RegisterQName(nsIRDFResource* aResource) -{ - nsAutoCString uri, qname; - aResource->GetValueUTF8(uri); - - nsNameSpaceMap::const_iterator iter = mNameSpaces.GetNameSpaceOf(uri); - if (iter != mNameSpaces.last()) { - NS_ENSURE_TRUE(iter->mPrefix, NS_ERROR_UNEXPECTED); - iter->mPrefix->ToUTF8String(qname); - qname.Append(':'); - qname += StringTail(uri, uri.Length() - iter->mURI.Length()); - mQNames.Put(aResource, qname); - return NS_OK; - } - - // Okay, so we don't have it in our map. Try to make one up. This - // is very bogus. - int32_t i = uri.RFindChar('#'); // first try a '#' - if (i == -1) { - i = uri.RFindChar('/'); - if (i == -1) { - // Okay, just punt and assume there is _no_ namespace on - // this thing... - mQNames.Put(aResource, uri); - return NS_OK; - } - } - - // Take whatever is to the right of the '#' or '/' and call it the - // local name, make up a prefix. - RefPtr prefix = EnsureNewPrefix(); - mNameSpaces.Put(StringHead(uri, i+1), prefix); - prefix->ToUTF8String(qname); - qname.Append(':'); - qname += StringTail(uri, uri.Length() - (i + 1)); - - mQNames.Put(aResource, qname); - return NS_OK; -} - -nsresult -nsRDFXMLSerializer::GetQName(nsIRDFResource* aResource, nsCString& aQName) -{ - return mQNames.Get(aResource, &aQName) ? NS_OK : NS_ERROR_UNEXPECTED; -} - -bool -nsRDFXMLSerializer::IsContainerProperty(nsIRDFResource* aProperty) -{ - // Return `true' if the property is an internal property related - // to being a container. - if (aProperty == kRDF_instanceOf) - return true; - - if (aProperty == kRDF_nextVal) - return true; - - bool isOrdinal = false; - gRDFC->IsOrdinalProperty(aProperty, &isOrdinal); - if (isOrdinal) - return true; - - return false; -} - - -// convert '&', '<', and '>' into "&", "<", and ">", respectively. -static const char amp[] = "&"; -static const char lt[] = "<"; -static const char gt[] = ">"; -static const char quot[] = """; - -static void -rdf_EscapeAmpersandsAndAngleBrackets(nsCString& s) -{ - uint32_t newLength, origLength; - newLength = origLength = s.Length(); - - // Compute the length of the result string. - const char* start = s.BeginReading(); - const char* end = s.EndReading(); - const char* c = start; - while (c != end) { - switch (*c) { - case '&' : - newLength += sizeof(amp) - 2; - break; - case '<': - case '>': - newLength += sizeof(gt) - 2; - break; - default: - break; - } - ++c; - } - if (newLength == origLength) { - // nothing to escape - return; - } - - // escape the chars from the end back to the front. - s.SetLength(newLength); - - // Buffer might have changed, get the pointers again - start = s.BeginReading(); // begin of string - c = start + origLength - 1; // last char in original string - char* w = s.EndWriting() - 1; // last char in grown buffer - while (c >= start) { - switch (*c) { - case '&' : - w -= 4; - nsCharTraits::copy(w, amp, sizeof(amp) - 1); - break; - case '<': - w -= 3; - nsCharTraits::copy(w, lt, sizeof(lt) - 1); - break; - case '>': - w -= 3; - nsCharTraits::copy(w, gt, sizeof(gt) - 1); - break; - default: - *w = *c; - } - --w; - --c; - } -} - -// convert '"' to """ -static void -rdf_EscapeQuotes(nsCString& s) -{ - int32_t i = 0; - while ((i = s.FindChar('"', i)) != -1) { - s.Replace(i, 1, quot, sizeof(quot) - 1); - i += sizeof(quot) - 2; - } -} - -static void -rdf_EscapeAttributeValue(nsCString& s) -{ - rdf_EscapeAmpersandsAndAngleBrackets(s); - rdf_EscapeQuotes(s); -} - - -nsresult -nsRDFXMLSerializer::SerializeInlineAssertion(nsIOutputStream* aStream, - nsIRDFResource* aResource, - nsIRDFResource* aProperty, - nsIRDFLiteral* aValue) -{ - nsresult rv; - nsCString qname; - rv = GetQName(aProperty, qname); - NS_ENSURE_SUCCESS(rv, rv); - - rv = rdf_BlockingWrite(aStream, - NS_LITERAL_CSTRING("\n ")); - if (NS_FAILED(rv)) return rv; - - const char16_t* value; - aValue->GetValueConst(&value); - NS_ConvertUTF16toUTF8 s(value); - - rdf_EscapeAttributeValue(s); - - rv = rdf_BlockingWrite(aStream, qname); - if (NS_FAILED(rv)) return rv; - rv = rdf_BlockingWrite(aStream, "=\"", 2); - if (NS_FAILED(rv)) return rv; - s.Append('"'); - return rdf_BlockingWrite(aStream, s); -} - -nsresult -nsRDFXMLSerializer::SerializeChildAssertion(nsIOutputStream* aStream, - nsIRDFResource* aResource, - nsIRDFResource* aProperty, - nsIRDFNode* aValue) -{ - nsCString qname; - nsresult rv = GetQName(aProperty, qname); - NS_ENSURE_SUCCESS(rv, rv); - - rv = rdf_BlockingWrite(aStream, " <", 5); - if (NS_FAILED(rv)) return rv; - rv = rdf_BlockingWrite(aStream, qname); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr resource; - nsCOMPtr literal; - nsCOMPtr number; - nsCOMPtr date; - - if ((resource = do_QueryInterface(aValue)) != nullptr) { - nsAutoCString uri; - resource->GetValueUTF8(uri); - - rdf_MakeRelativeRef(mBaseURLSpec, uri); - rdf_EscapeAttributeValue(uri); - - rv = rdf_BlockingWrite(aStream, kRDFResource1, - sizeof(kRDFResource1) - 1); - if (NS_FAILED(rv)) return rv; - rv = rdf_BlockingWrite(aStream, uri); - if (NS_FAILED(rv)) return rv; - rv = rdf_BlockingWrite(aStream, kRDFResource2, - sizeof(kRDFResource2) - 1); - if (NS_FAILED(rv)) return rv; - - goto no_close_tag; - } - else if ((literal = do_QueryInterface(aValue)) != nullptr) { - const char16_t *value; - literal->GetValueConst(&value); - NS_ConvertUTF16toUTF8 s(value); - - rdf_EscapeAmpersandsAndAngleBrackets(s); - - rv = rdf_BlockingWrite(aStream, ">", 1); - if (NS_FAILED(rv)) return rv; - rv = rdf_BlockingWrite(aStream, s); - if (NS_FAILED(rv)) return rv; - } - else if ((number = do_QueryInterface(aValue)) != nullptr) { - int32_t value; - number->GetValue(&value); - - nsAutoCString n; - n.AppendInt(value); - - rv = rdf_BlockingWrite(aStream, kRDFParseTypeInteger, - sizeof(kRDFParseTypeInteger) - 1); - if (NS_FAILED(rv)) return rv; - rv = rdf_BlockingWrite(aStream, n); - if (NS_FAILED(rv)) return rv; - } - else if ((date = do_QueryInterface(aValue)) != nullptr) { - PRTime value; - date->GetValue(&value); - - nsAutoCString s; - rdf_FormatDate(value, s); - - rv = rdf_BlockingWrite(aStream, kRDFParseTypeDate, - sizeof(kRDFParseTypeDate) - 1); - if (NS_FAILED(rv)) return rv; - rv = rdf_BlockingWrite(aStream, s); - if (NS_FAILED(rv)) return rv; - } - else { - // XXX it doesn't support nsIRDFResource _or_ nsIRDFLiteral??? - // We should serialize nsIRDFInt, nsIRDFDate, etc... - NS_WARNING("unknown RDF node type"); - - rv = rdf_BlockingWrite(aStream, kRDFUnknown, sizeof(kRDFUnknown) - 1); - if (NS_FAILED(rv)) return rv; - } - - rv = rdf_BlockingWrite(aStream, "\n", 2); - - no_close_tag: - return NS_OK; -} - -nsresult -nsRDFXMLSerializer::SerializeProperty(nsIOutputStream* aStream, - nsIRDFResource* aResource, - nsIRDFResource* aProperty, - bool aInline, - int32_t* aSkipped) -{ - nsresult rv = NS_OK; - - int32_t skipped = 0; - - nsCOMPtr assertions; - mDataSource->GetTargets(aResource, aProperty, true, getter_AddRefs(assertions)); - if (! assertions) - return NS_ERROR_FAILURE; - - // Serializing the assertion inline is ok as long as the property has - // only one target value, and it is a literal that doesn't include line - // breaks. - bool needsChild = false; - - while (1) { - bool hasMore = false; - assertions->HasMoreElements(&hasMore); - if (! hasMore) - break; - - nsCOMPtr isupports; - assertions->GetNext(getter_AddRefs(isupports)); - nsCOMPtr literal = do_QueryInterface(isupports); - needsChild |= (!literal); - - if (!needsChild) { - assertions->HasMoreElements(&needsChild); - if (!needsChild) { - const char16_t* literalVal = nullptr; - literal->GetValueConst(&literalVal); - if (literalVal) { - for (; *literalVal; literalVal++) { - if (*literalVal == char16_t('\n') || - *literalVal == char16_t('\r')) { - needsChild = true; - break; - } - } - } - } - } - - if (aInline && !needsChild) { - rv = SerializeInlineAssertion(aStream, aResource, aProperty, literal); - } - else if (!aInline && needsChild) { - nsCOMPtr value = do_QueryInterface(isupports); - rv = SerializeChildAssertion(aStream, aResource, aProperty, value); - } - else { - ++skipped; - rv = NS_OK; - } - - if (NS_FAILED(rv)) - break; - } - - *aSkipped += skipped; - return rv; -} - - -nsresult -nsRDFXMLSerializer::SerializeDescription(nsIOutputStream* aStream, - nsIRDFResource* aResource) -{ - nsresult rv; - - bool isTypedNode = false; - nsCString typeQName; - - nsCOMPtr typeNode; - mDataSource->GetTarget(aResource, kRDF_type, true, getter_AddRefs(typeNode)); - if (typeNode) { - nsCOMPtr type = do_QueryInterface(typeNode, &rv); - if (type) { - // Try to get a namespace prefix. If none is available, - // just treat the description as if it weren't a typed node - // after all and emit rdf:type as a normal property. This - // seems preferable to using a bogus (invented) prefix. - isTypedNode = NS_SUCCEEDED(GetQName(type, typeQName)); - } - } - - nsAutoCString uri; - rv = aResource->GetValueUTF8(uri); - if (NS_FAILED(rv)) return rv; - - rdf_MakeRelativeRef(mBaseURLSpec, uri); - rdf_EscapeAttributeValue(uri); - - // Emit an open tag and the subject - if (isTypedNode) { - rv = rdf_BlockingWrite(aStream, NS_LITERAL_STRING(" <")); - if (NS_FAILED(rv)) return rv; - // Watch out for the default namespace! - rv = rdf_BlockingWrite(aStream, typeQName); - if (NS_FAILED(rv)) return rv; - } - else { - rv = rdf_BlockingWrite(aStream, kRDFDescriptionOpen, - sizeof(kRDFDescriptionOpen) - 1); - if (NS_FAILED(rv)) return rv; - } - if (uri[0] == char16_t('#')) { - uri.Cut(0, 1); - rv = rdf_BlockingWrite(aStream, kIDAttr, sizeof(kIDAttr) - 1); - } - else { - rv = rdf_BlockingWrite(aStream, kAboutAttr, sizeof(kAboutAttr) - 1); - } - if (NS_FAILED(rv)) return rv; - - uri.Append('"'); - rv = rdf_BlockingWrite(aStream, uri); - if (NS_FAILED(rv)) return rv; - - // Any value that's a literal we can write out as an inline - // attribute on the RDF:Description - AutoTArray visited; - int32_t skipped = 0; - - nsCOMPtr arcs; - mDataSource->ArcLabelsOut(aResource, getter_AddRefs(arcs)); - - if (arcs) { - // Don't re-serialize rdf:type later on - if (isTypedNode) - visited.AppendElement(kRDF_type); - - while (1) { - bool hasMore = false; - arcs->HasMoreElements(&hasMore); - if (! hasMore) - break; - - nsCOMPtr isupports; - arcs->GetNext(getter_AddRefs(isupports)); - - nsCOMPtr property = do_QueryInterface(isupports); - if (! property) - continue; - - // Ignore properties that pertain to containers; we may be - // called from SerializeContainer() if the container resource - // has been assigned non-container properties. - if (IsContainerProperty(property)) - continue; - - // Only serialize values for the property once. - if (visited.Contains(property.get())) - continue; - - visited.AppendElement(property.get()); - - SerializeProperty(aStream, aResource, property, true, &skipped); - } - } - - if (skipped) { - // Close the RDF:Description tag. - rv = rdf_BlockingWrite(aStream, NS_LITERAL_CSTRING(">\n")); - if (NS_FAILED(rv)) return rv; - - // Now write out resources (which might have their own - // substructure) as children. - mDataSource->ArcLabelsOut(aResource, getter_AddRefs(arcs)); - - if (arcs) { - // Forget that we've visited anything - visited.Clear(); - // ... except for rdf:type - if (isTypedNode) - visited.AppendElement(kRDF_type); - - while (1) { - bool hasMore = false; - arcs->HasMoreElements(&hasMore); - if (! hasMore) - break; - - nsCOMPtr isupports; - arcs->GetNext(getter_AddRefs(isupports)); - - nsCOMPtr property = do_QueryInterface(isupports); - if (! property) - continue; - - // Ignore properties that pertain to containers; we may be - // called from SerializeContainer() if the container - // resource has been assigned non-container properties. - if (IsContainerProperty(property)) - continue; - - // have we already seen this property? If so, don't write it - // out again; serialize property will write each instance. - if (visited.Contains(property.get())) - continue; - - visited.AppendElement(property.get()); - - SerializeProperty(aStream, aResource, property, false, &skipped); - } - } - - // Emit a proper close-tag. - if (isTypedNode) { - rv = rdf_BlockingWrite(aStream, NS_LITERAL_CSTRING(" \n", 2); - if (NS_FAILED(rv)) return rv; - } - else { - rv = rdf_BlockingWrite(aStream, kRDFDescriptionClose, - sizeof(kRDFDescriptionClose) - 1); - if (NS_FAILED(rv)) return rv; - } - } - else { - // If we saw _no_ child properties, then we can don't need a - // close-tag. - rv = rdf_BlockingWrite(aStream, NS_LITERAL_CSTRING(" />\n")); - if (NS_FAILED(rv)) return rv; - } - - return NS_OK; -} - -nsresult -nsRDFXMLSerializer::SerializeMember(nsIOutputStream* aStream, - nsIRDFResource* aContainer, - nsIRDFNode* aMember) -{ - // If it's a resource, then output a "" - // tag, because we'll be dumping the resource separately. (We - // iterate thru all the resources in the datasource, - // remember?) Otherwise, output the literal value. - - nsCOMPtr resource; - nsCOMPtr literal; - nsCOMPtr number; - nsCOMPtr date; - -static const char kRDFLIOpen[] = " GetValueUTF8(uri); - - rdf_MakeRelativeRef(mBaseURLSpec, uri); - rdf_EscapeAttributeValue(uri); - - rv = rdf_BlockingWrite(aStream, kRDFResource1, - sizeof(kRDFResource1) - 1); - if (NS_FAILED(rv)) return rv; - rv = rdf_BlockingWrite(aStream, uri); - if (NS_FAILED(rv)) return rv; - rv = rdf_BlockingWrite(aStream, kRDFResource2, - sizeof(kRDFResource2) - 1); - if (NS_FAILED(rv)) return rv; - - goto no_close_tag; - } - else if ((literal = do_QueryInterface(aMember)) != nullptr) { - const char16_t *value; - literal->GetValueConst(&value); -static const char kRDFLIOpenGT[] = ">"; - // close the 'GetValue(&value); - - nsAutoCString n; - n.AppendInt(value); - - rv = rdf_BlockingWrite(aStream, kRDFParseTypeInteger, - sizeof(kRDFParseTypeInteger) - 1); - if (NS_FAILED(rv)) return rv; - rv = rdf_BlockingWrite(aStream, n); - if (NS_FAILED(rv)) return rv; - } - else if ((date = do_QueryInterface(aMember)) != nullptr) { - PRTime value; - date->GetValue(&value); - - nsAutoCString s; - rdf_FormatDate(value, s); - - rv = rdf_BlockingWrite(aStream, kRDFParseTypeDate, - sizeof(kRDFParseTypeDate) - 1); - if (NS_FAILED(rv)) return rv; - rv = rdf_BlockingWrite(aStream, s); - if (NS_FAILED(rv)) return rv; - } - else { - // XXX it doesn't support nsIRDFResource _or_ nsIRDFLiteral??? - // We should serialize nsIRDFInt, nsIRDFDate, etc... - NS_WARNING("unknown RDF node type"); - - rv = rdf_BlockingWrite(aStream, kRDFUnknown, sizeof(kRDFUnknown) - 1); - if (NS_FAILED(rv)) return rv; - } - - { -static const char kRDFLIClose[] = "\n"; - rv = rdf_BlockingWrite(aStream, kRDFLIClose, sizeof(kRDFLIClose) - 1); - if (NS_FAILED(rv)) return rv; - } - - no_close_tag: - return NS_OK; -} - - -nsresult -nsRDFXMLSerializer::SerializeContainer(nsIOutputStream* aStream, - nsIRDFResource* aContainer) -{ - nsresult rv; - nsAutoCString tag; - - // Decide if it's a sequence, bag, or alternation, and print the - // appropriate tag-open sequence - - if (IsA(mDataSource, aContainer, kRDF_Bag)) { - tag.AssignLiteral("RDF:Bag"); - } - else if (IsA(mDataSource, aContainer, kRDF_Seq)) { - tag.AssignLiteral("RDF:Seq"); - } - else if (IsA(mDataSource, aContainer, kRDF_Alt)) { - tag.AssignLiteral("RDF:Alt"); - } - else { - NS_ASSERTION(false, "huh? this is _not_ a container."); - return NS_ERROR_UNEXPECTED; - } - - rv = rdf_BlockingWrite(aStream, " <", 3); - if (NS_FAILED(rv)) return rv; - rv = rdf_BlockingWrite(aStream, tag); - if (NS_FAILED(rv)) return rv; - - - // Unfortunately, we always need to print out the identity of the - // resource, even if was constructed "anonymously". We need to do - // this because we never really know who else might be referring - // to it... - - nsAutoCString uri; - if (NS_SUCCEEDED(aContainer->GetValueUTF8(uri))) { - rdf_MakeRelativeRef(mBaseURLSpec, uri); - - rdf_EscapeAttributeValue(uri); - - if (uri.First() == '#') { - // Okay, it's actually identified as an element in the - // current document, not trying to decorate some absolute - // URI. We can use the 'ID=' attribute... - - uri.Cut(0, 1); // chop the '#' - rv = rdf_BlockingWrite(aStream, kIDAttr, sizeof(kIDAttr) - 1); - if (NS_FAILED(rv)) return rv; - } - else { - // We need to cheat and spit out an illegal 'about=' on - // the sequence. - rv = rdf_BlockingWrite(aStream, kAboutAttr, - sizeof(kAboutAttr) - 1); - if (NS_FAILED(rv)) return rv; - } - - rv = rdf_BlockingWrite(aStream, uri); - if (NS_FAILED(rv)) return rv; - rv = rdf_BlockingWrite(aStream, "\"", 1); - if (NS_FAILED(rv)) return rv; - } - - rv = rdf_BlockingWrite(aStream, ">\n", 2); - if (NS_FAILED(rv)) return rv; - - // First iterate through each of the ordinal elements (the RDF/XML - // syntax doesn't allow us to place properties on RDF container - // elements). - nsCOMPtr elements; - rv = NS_NewContainerEnumerator(mDataSource, aContainer, getter_AddRefs(elements)); - - if (NS_SUCCEEDED(rv)) { - while (1) { - bool hasMore; - rv = elements->HasMoreElements(&hasMore); - if (NS_FAILED(rv)) break; - - if (! hasMore) - break; - - nsCOMPtr isupports; - elements->GetNext(getter_AddRefs(isupports)); - - nsCOMPtr element = do_QueryInterface(isupports); - NS_ASSERTION(element != nullptr, "not an nsIRDFNode"); - if (! element) - continue; - - SerializeMember(aStream, aContainer, element); - } - } - - // close the container tag - rv = rdf_BlockingWrite(aStream, " \n", 2); - rv = rdf_BlockingWrite(aStream, tag); - if (NS_FAILED(rv)) return rv; - - // Now, we iterate through _all_ of the arcs, in case someone has - // applied properties to the bag itself. These'll be placed in a - // separate RDF:Description element. - nsCOMPtr arcs; - mDataSource->ArcLabelsOut(aContainer, getter_AddRefs(arcs)); - - bool wroteDescription = false; - while (! wroteDescription) { - bool hasMore = false; - rv = arcs->HasMoreElements(&hasMore); - if (NS_FAILED(rv)) break; - - if (! hasMore) - break; - - nsIRDFResource* property; - rv = arcs->GetNext((nsISupports**) &property); - if (NS_FAILED(rv)) break; - - // If it's a membership property, then output a "LI" - // tag. Otherwise, output a property. - if (! IsContainerProperty(property)) { - rv = SerializeDescription(aStream, aContainer); - wroteDescription = true; - } - - NS_RELEASE(property); - if (NS_FAILED(rv)) - break; - } - - return NS_OK; -} - - -nsresult -nsRDFXMLSerializer::SerializePrologue(nsIOutputStream* aStream) -{ -static const char kXMLVersion[] = "\n"; - - nsresult rv; - rv = rdf_BlockingWrite(aStream, kXMLVersion, sizeof(kXMLVersion) - 1); - if (NS_FAILED(rv)) return rv; - - // global name space declarations - rv = rdf_BlockingWrite(aStream, NS_LITERAL_CSTRING("mPrefix) { - rv = rdf_BlockingWrite(aStream, NS_LITERAL_CSTRING(":")); - if (NS_FAILED(rv)) return rv; - nsAutoCString prefix; - entry->mPrefix->ToUTF8String(prefix); - rv = rdf_BlockingWrite(aStream, prefix); - if (NS_FAILED(rv)) return rv; - } - - rv = rdf_BlockingWrite(aStream, NS_LITERAL_CSTRING("=\"")); - if (NS_FAILED(rv)) return rv; - nsAutoCString uri(entry->mURI); - rdf_EscapeAttributeValue(uri); - rv = rdf_BlockingWrite(aStream, uri); - if (NS_FAILED(rv)) return rv; - rv = rdf_BlockingWrite(aStream, NS_LITERAL_CSTRING("\"")); - if (NS_FAILED(rv)) return rv; - } - - return rdf_BlockingWrite(aStream, NS_LITERAL_CSTRING(">\n")); -} - - -nsresult -nsRDFXMLSerializer::SerializeEpilogue(nsIOutputStream* aStream) -{ - return rdf_BlockingWrite(aStream, NS_LITERAL_CSTRING("\n")); -} - -class QNameCollector final : public rdfITripleVisitor { -public: - NS_DECL_ISUPPORTS - NS_DECL_RDFITRIPLEVISITOR - explicit QNameCollector(nsRDFXMLSerializer* aParent) - : mParent(aParent){} -private: - ~QNameCollector() {} - nsRDFXMLSerializer* mParent; -}; - -NS_IMPL_ISUPPORTS(QNameCollector, rdfITripleVisitor) -nsresult -QNameCollector::Visit(nsIRDFNode* aSubject, nsIRDFResource* aPredicate, - nsIRDFNode* aObject, bool aTruthValue) -{ - if (aPredicate == nsRDFXMLSerializer::kRDF_type) { - // try to get a type QName for aObject, should be a resource - nsCOMPtr resType = do_QueryInterface(aObject); - if (!resType) { - // ignore error - return NS_OK; - } - if (mParent->mQNames.Get(resType, nullptr)) { - return NS_OK; - } - mParent->RegisterQName(resType); - return NS_OK; - } - - if (mParent->mQNames.Get(aPredicate, nullptr)) { - return NS_OK; - } - if (aPredicate == nsRDFXMLSerializer::kRDF_instanceOf || - aPredicate == nsRDFXMLSerializer::kRDF_nextVal) - return NS_OK; - bool isOrdinal = false; - nsRDFXMLSerializer::gRDFC->IsOrdinalProperty(aPredicate, &isOrdinal); - if (isOrdinal) - return NS_OK; - - mParent->RegisterQName(aPredicate); - - return NS_OK; -} - -nsresult -nsRDFXMLSerializer::CollectNamespaces() -{ - // Iterate over all Triples to get namespaces for subject resource types - // and Predicates and cache all the QNames we want to use. - nsCOMPtr collector = - new QNameCollector(this); - nsCOMPtr ds = do_QueryInterface(mDataSource); // XXX API - NS_ENSURE_TRUE(collector && ds, NS_ERROR_FAILURE); - return ds->VisitAllTriples(collector); -} - -//---------------------------------------------------------------------- - -NS_IMETHODIMP -nsRDFXMLSerializer::Serialize(nsIOutputStream* aStream) -{ - nsresult rv; - - rv = CollectNamespaces(); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr resources; - rv = mDataSource->GetAllResources(getter_AddRefs(resources)); - if (NS_FAILED(rv)) return rv; - - rv = SerializePrologue(aStream); - if (NS_FAILED(rv)) - return rv; - - while (1) { - bool hasMore = false; - resources->HasMoreElements(&hasMore); - if (! hasMore) - break; - - nsCOMPtr isupports; - resources->GetNext(getter_AddRefs(isupports)); - - nsCOMPtr resource = do_QueryInterface(isupports); - if (! resource) - continue; - - if (IsA(mDataSource, resource, kRDF_Bag) || - IsA(mDataSource, resource, kRDF_Seq) || - IsA(mDataSource, resource, kRDF_Alt)) { - rv = SerializeContainer(aStream, resource); - } - else { - rv = SerializeDescription(aStream, resource); - } - - if (NS_FAILED(rv)) - break; - } - - rv = SerializeEpilogue(aStream); - - return rv; -} - - -bool -nsRDFXMLSerializer::IsA(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource, nsIRDFResource* aType) -{ - nsresult rv; - - bool result; - rv = aDataSource->HasAssertion(aResource, kRDF_instanceOf, aType, true, &result); - if (NS_FAILED(rv)) return false; - - return result; -} diff --git a/rdf/base/nsRDFXMLSerializer.h b/rdf/base/nsRDFXMLSerializer.h deleted file mode 100644 index 235753eb24d6..000000000000 --- a/rdf/base/nsRDFXMLSerializer.h +++ /dev/null @@ -1,117 +0,0 @@ -/* -*- 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/. */ - -#ifndef nsRDFXMLSerializer_h__ -#define nsRDFXMLSerializer_h__ - -#include "nsIRDFLiteral.h" -#include "nsIRDFXMLSerializer.h" -#include "nsIRDFXMLSource.h" -#include "nsNameSpaceMap.h" -#include "nsString.h" - -#include "nsDataHashtable.h" -#include "rdfITripleVisitor.h" - -class nsIOutputStream; -class nsIRDFContainerUtils; - -/** - * A helper class that can serialize RDF/XML from a - * datasource. Implements both nsIRDFXMLSerializer and - * nsIRDFXMLSource. - */ -class nsRDFXMLSerializer : public nsIRDFXMLSerializer, - public nsIRDFXMLSource -{ -public: - static nsresult - Create(nsISupports* aOuter, REFNSIID aIID, void** aResult); - - NS_DECL_ISUPPORTS - NS_DECL_NSIRDFXMLSERIALIZER - NS_DECL_NSIRDFXMLSOURCE - -protected: - nsRDFXMLSerializer(); - virtual ~nsRDFXMLSerializer(); - - // Implementation methods - nsresult - RegisterQName(nsIRDFResource* aResource); - nsresult - GetQName(nsIRDFResource* aResource, nsCString& aQName); - already_AddRefed - EnsureNewPrefix(); - - nsresult - SerializeInlineAssertion(nsIOutputStream* aStream, - nsIRDFResource* aResource, - nsIRDFResource* aProperty, - nsIRDFLiteral* aValue); - - nsresult - SerializeChildAssertion(nsIOutputStream* aStream, - nsIRDFResource* aResource, - nsIRDFResource* aProperty, - nsIRDFNode* aValue); - - nsresult - SerializeProperty(nsIOutputStream* aStream, - nsIRDFResource* aResource, - nsIRDFResource* aProperty, - bool aInline, - int32_t* aSkipped); - - bool - IsContainerProperty(nsIRDFResource* aProperty); - - nsresult - SerializeDescription(nsIOutputStream* aStream, - nsIRDFResource* aResource); - - nsresult - SerializeMember(nsIOutputStream* aStream, - nsIRDFResource* aContainer, - nsIRDFNode* aMember); - - nsresult - SerializeContainer(nsIOutputStream* aStream, - nsIRDFResource* aContainer); - - nsresult - SerializePrologue(nsIOutputStream* aStream); - - nsresult - SerializeEpilogue(nsIOutputStream* aStream); - - nsresult - CollectNamespaces(); - - bool - IsA(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource, nsIRDFResource* aType); - - nsCOMPtr mDataSource; - nsNameSpaceMap mNameSpaces; - nsCString mBaseURLSpec; - - // hash mapping resources to utf8-encoded QNames - nsDataHashtable mQNames; - friend class QNameCollector; - - uint32_t mPrefixID; - - static int32_t gRefCnt; - static nsIRDFResource* kRDF_instanceOf; - static nsIRDFResource* kRDF_type; - static nsIRDFResource* kRDF_nextVal; - static nsIRDFResource* kRDF_Bag; - static nsIRDFResource* kRDF_Seq; - static nsIRDFResource* kRDF_Alt; - static nsIRDFContainerUtils* gRDFC; -}; - -#endif // nsRDFXMLSerializer_h__ diff --git a/rdf/base/rdf.h b/rdf/base/rdf.h deleted file mode 100644 index 65087cee5174..000000000000 --- a/rdf/base/rdf.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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/. */ - -/* - - A catch-all header file for miscellaneous RDF stuff. Currently - contains error codes and vocabulary macros. - - */ - -#ifndef rdf_h___ -#define rdf_h___ - -#include "nsError.h" - -/** - * The following macros are to aid in vocabulary definition. They - * creates const char*'s for "kURI[prefix]_[name]", appropriate - * complete namespace qualification on the URI, e.g., - * - * #define RDF_NAMESPACE_URI "http://www.w3.org/TR/WD-rdf-syntax#" - * DEFINE_RDF_ELEMENT(RDF_NAMESPACE_URI, RDF, ID); - * - * will define: - * - * kURIRDF_ID to be "http://www.w3.org/TR/WD-rdf-syntax#ID" - */ - -#define DEFINE_RDF_VOCAB(ns, prefix, name) \ -static const char kURI##prefix##_##name[] = ns #name - -/** - * Core RDF vocabularies that we use to define semantics - */ - -#define RDF_NAMESPACE_URI "http://www.w3.org/1999/02/22-rdf-syntax-ns#" -#define WEB_NAMESPACE_URI "http://home.netscape.com/WEB-rdf#" -#define NC_NAMESPACE_URI "http://home.netscape.com/NC-rdf#" - -/* ContractID prefixes for RDF DLL registration. */ -#define NS_RDF_CONTRACTID "@mozilla.org/rdf" -#define NS_RDF_DATASOURCE_CONTRACTID NS_RDF_CONTRACTID "/datasource;1" -#define NS_RDF_DATASOURCE_CONTRACTID_PREFIX NS_RDF_DATASOURCE_CONTRACTID "?name=" -#define NS_RDF_RESOURCE_FACTORY_CONTRACTID "@mozilla.org/rdf/resource-factory;1" -#define NS_RDF_RESOURCE_FACTORY_CONTRACTID_PREFIX NS_RDF_RESOURCE_FACTORY_CONTRACTID "?name=" -#define NS_RDF_INFER_DATASOURCE_CONTRACTID_PREFIX NS_RDF_CONTRACTID "/infer-datasource;1?engine=" - -// contract ID is in the form -// @mozilla.org/rdf/delegate-factory;1?key=&scheme= -#define NS_RDF_DELEGATEFACTORY_CONTRACTID "@mozilla.org/rdf/delegate-factory;1" -#define NS_RDF_DELEGATEFACTORY_CONTRACTID_PREFIX NS_RDF_DELEGATEFACTORY_CONTRACTID "?key=" - -/*@}*/ - -#endif /* rdf_h___ */ diff --git a/rdf/base/rdfIDataSource.idl b/rdf/base/rdfIDataSource.idl deleted file mode 100644 index 848cbca117d7..000000000000 --- a/rdf/base/rdfIDataSource.idl +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- Mode: IDL; 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/. */ - -#include "nsISupports.idl" - -interface rdfITripleVisitor; - -/** - * Interface used in RDF to describe data sources. - * - * @status PLASMA - */ - -[scriptable, uuid(ebce86bd-1568-4a34-a808-9ccf9cde8087)] -interface rdfIDataSource : nsISupports -{ - /** - * Visit all the subject resources in the datasource. The order is - * intederminate and may change from one invocation to the next. - * The subjects will be in the aSubject argument in calls into - * aVisitor, aPredicate and aObject will be null. - * @note Implementations may throw NS_ERROR_NOT_IMPLEMENTED for - * this method, but in this case RDF serializations of this - * datasource will not be possible. - */ - void visitAllSubjects(in rdfITripleVisitor aVisitor); - - /** - * Visit all the triples in the datasource. The order is - * intederminate and may change from one invocation to the next. - * @note Implementations may throw NS_ERROR_NOT_IMPLEMENTED for - * this method, but in this case RDF serializations of this - * datasource will not be possible. - */ - void visitAllTriples(in rdfITripleVisitor aVisitor); -}; diff --git a/rdf/base/rdfITripleVisitor.idl b/rdf/base/rdfITripleVisitor.idl deleted file mode 100644 index ecac14871567..000000000000 --- a/rdf/base/rdfITripleVisitor.idl +++ /dev/null @@ -1,31 +0,0 @@ -/* -*- Mode: IDL; 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/. */ - -#include "nsISupports.idl" - -interface nsIRDFResource; -interface nsIRDFNode; - -/** - * Interface used in RDF to enumerate triples. - * Also used by rdfIDataSource::getAllSubjects, then aPredicate, - * aObject and aTruthValue are ignored. - * - * @status PLASMA - */ - -[scriptable, function, uuid(aafea151-c271-4505-9978-a100d292800c)] -interface rdfITripleVisitor : nsISupports -{ - /** - * Callback function for returning query results. - * - * @param aSubject, aPredicate, aObject describe the (sub-)arc - * @returnCode NS_RDF_STOP_VISIT to stop iterating over the query result. - * Any error code will stop the iteration as well. - */ - void visit(in nsIRDFNode aSubject, in nsIRDFResource aPredicate, - in nsIRDFNode aObject, in boolean aTruthValue); -}; diff --git a/rdf/base/rdfutil.cpp b/rdf/base/rdfutil.cpp deleted file mode 100644 index 191ee68d1a26..000000000000 --- a/rdf/base/rdfutil.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* -*- 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/. */ - -/* - - Implementations for a bunch of useful RDF utility routines. Many of - these will eventually be exported outside of RDF.DLL via the - nsIRDFService interface. - - TO DO - - 1) Make this so that it doesn't permanently leak the RDF service - object. - - 2) Make container functions thread-safe. They currently don't ensure - that the RDF:nextVal property is maintained safely. - - */ - -#include "nsCOMPtr.h" -#include "nsIRDFDataSource.h" -#include "nsIRDFNode.h" -#include "nsIRDFService.h" -#include "nsIServiceManager.h" -#include "nsIURL.h" -#include "nsIIOService.h" -#include "nsIURL.h" -#include "nsRDFCID.h" -#include "nsString.h" -#include "nsUnicharUtils.h" -#include "rdfutil.h" -#include "prtime.h" - -//////////////////////////////////////////////////////////////////////// - -nsresult -rdf_MakeRelativeRef(const nsACString& aBaseURI, nsCString& aURI) -{ - // This implementation is extremely simple: e.g., it can't compute - // relative paths, or anything fancy like that. If the context URI - // is not a prefix of the URI in question, we'll just bail. - uint32_t prefixLen = aBaseURI.Length(); - if (prefixLen != 0 && StringBeginsWith(aURI, aBaseURI)) { - if (prefixLen < aURI.Length() && aURI.CharAt(prefixLen) == '/') - ++prefixLen; // chop the leading slash so it's not `absolute' - - aURI.Cut(0, prefixLen); - } - - return NS_OK; -} - -void -rdf_FormatDate(PRTime aTime, nsACString &aResult) -{ - // Outputs Unixish date in GMT plus usecs; e.g., - // Wed Jan 9 19:15:13 2002 +002441 - // - PRExplodedTime t; - PR_ExplodeTime(aTime, PR_GMTParameters, &t); - - char buf[256]; - PR_FormatTimeUSEnglish(buf, sizeof buf, "%a %b %d %H:%M:%S %Y", &t); - aResult.Append(buf); - - // usecs - aResult.AppendLiteral(" +"); - int32_t usec = t.tm_usec; - for (int32_t digit = 100000; digit > 1; digit /= 10) { - aResult.Append(char('0' + (usec / digit))); - usec %= digit; - } - aResult.Append(char('0' + usec)); -} - -PRTime -rdf_ParseDate(const nsACString &aTime) -{ - PRTime t; - PR_ParseTimeString(PromiseFlatCString(aTime).get(), true, &t); - - int32_t usec = 0; - - nsACString::const_iterator begin, digit, end; - aTime.BeginReading(begin); - aTime.EndReading(end); - - // Walk backwards until we find a `+', run out of string, or a - // non-numeric character. - digit = end; - while (--digit != begin && *digit != '+') { - if (*digit < '0' || *digit > '9') - break; - } - - if (digit != begin && *digit == '+') { - // There's a usec field specified (or, at least, something - // that looks close enough. Parse it, and add it to the time. - while (++digit != end) { - usec *= 10; - usec += *digit - '0'; - } - - t += usec; - } - - return t; -} diff --git a/rdf/base/rdfutil.h b/rdf/base/rdfutil.h deleted file mode 100644 index 70f9b656437f..000000000000 --- a/rdf/base/rdfutil.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- 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/. */ - - -/* - - A bunch of useful RDF utility routines. Many of these will - eventually be exported outside of RDF.DLL via the nsIRDFService - interface. - - TO DO - - 1) Move the anonymous resource stuff to nsIRDFService? - - 2) All that's left is rdf_PossiblyMakeRelative() and - -Absolute(). Maybe those go on nsIRDFService, too. - - */ - -#ifndef rdfutil_h__ -#define rdfutil_h__ - -#include "nsStringFwd.h" - -nsresult -rdf_MakeRelativeRef(const nsACString& aBaseURI, nsCString& aURI); - -void -rdf_FormatDate(PRTime aTime, nsACString &aResult); - -PRTime -rdf_ParseDate(const nsACString &aTime); - -#endif // rdfutil_h__ - - diff --git a/rdf/build/moz.build b/rdf/build/moz.build deleted file mode 100644 index d7be68954dcd..000000000000 --- a/rdf/build/moz.build +++ /dev/null @@ -1,20 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -EXPORTS += [ - 'nsRDFCID.h', -] - -SOURCES += [ - 'nsRDFModule.cpp', -] - -FINAL_LIBRARY = 'xul' - -LOCAL_INCLUDES += [ - '/rdf/base', - '/rdf/datasource', -] diff --git a/rdf/build/nsRDFCID.h b/rdf/build/nsRDFCID.h deleted file mode 100644 index 18d47aed5211..000000000000 --- a/rdf/build/nsRDFCID.h +++ /dev/null @@ -1,76 +0,0 @@ -/* -*- 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/. */ - -/* - - XPCOM Class IDs for RDF objects that can be constructed via the RDF - factory. - - */ - -#ifndef nsRDFCID_h__ -#define nsRDFCID_h__ - -// {0F78DA56-8321-11d2-8EAC-00805F29F370} -#define NS_RDFDEFAULTRESOURCE_CID \ -{ 0xf78da56, 0x8321, 0x11d2, { 0x8e, 0xac, 0x0, 0x80, 0x5f, 0x29, 0xf3, 0x70 } } - -// {BFD05264-834C-11d2-8EAC-00805F29F370} -#define NS_RDFSERVICE_CID \ -{ 0xbfd05264, 0x834c, 0x11d2, { 0x8e, 0xac, 0x0, 0x80, 0x5f, 0x29, 0xf3, 0x70 } } - -// {BFD0526D-834C-11d2-8EAC-00805F29F370} -#define NS_RDFINMEMORYDATASOURCE_CID \ -{ 0xbfd0526d, 0x834c, 0x11d2, { 0x8e, 0xac, 0x0, 0x80, 0x5f, 0x29, 0xf3, 0x70 } } - -// {E638D760-8687-11d2-B530-000000000001} -#define NS_RDFFILESYSTEMDATASOURCE_CID \ -{ 0xe638d760, 0x8687, 0x11d2, { 0xb5, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x01 } } - -// {6bd1d807-1c67-11d3-9820-ed1b357eb3c4} -#define NS_RDFSEARCHDATASOURCE_CID \ -{ 0x6bd1d807, 0x1c67, 0x11d3, { 0x98, 0x20, 0xed, 0x1b, 0x35, 0x7e, 0xb3, 0xc4 } } - -// {E638D760-8687-11d2-B530-000000000002} -#define NS_RDFFINDDATASOURCE_CID \ -{ 0xe638d760, 0x8687, 0x11d2, { 0xb5, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x02 } } - -// {E638D761-8687-11d2-B530-000000000000} -#define NS_RDFCOMPOSITEDATASOURCE_CID \ -{ 0xe638d761, 0x8687, 0x11d2, { 0xb5, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } } - -// {7BAF62E0-8E61-11d2-8EB1-00805F29F370} -#define NS_RDFXMLDATASOURCE_CID \ -{ 0x7baf62e0, 0x8e61, 0x11d2, { 0x8e, 0xb1, 0x0, 0x80, 0x5f, 0x29, 0xf3, 0x70 } } - -// {0958B101-9ADA-11d2-8EBC-00805F29F370} -#define NS_RDFCONTENTSINK_CID \ -{ 0x958b101, 0x9ada, 0x11d2, { 0x8e, 0xbc, 0x0, 0x80, 0x5f, 0x29, 0xf3, 0x70 } } - -// {1EAAFD60-D596-11d2-80BE-006097B76B8E} -#define NS_RDFHISTORYDATASOURCE_CID \ -{ 0x1eaafd60, 0xd596, 0x11d2, { 0x80, 0xbe, 0x0, 0x60, 0x97, 0xb7, 0x6b, 0x8e } } - -// {D4214E92-FB94-11d2-BDD8-00104BDE6048} -#define NS_RDFCONTAINERUTILS_CID \ -{ 0xd4214e92, 0xfb94, 0x11d2, { 0xbd, 0xd8, 0x0, 0x10, 0x4b, 0xde, 0x60, 0x48 } } - -// {D4214E93-FB94-11d2-BDD8-00104BDE6048} -#define NS_RDFCONTAINER_CID \ -{ 0xd4214e93, 0xfb94, 0x11d2, { 0xbd, 0xd8, 0x0, 0x10, 0x4b, 0xde, 0x60, 0x48 } } - -// {0032d852-1dd2-11b2-95f7-e0a1910ed2da} -#define NS_RDFXMLSERIALIZER_CID \ -{ 0x0032d852, 0x1dd2, 0x11b2, { 0x95, 0xf7, 0xe0, 0xa1, 0x91, 0x0e, 0xd2, 0xda } } - -// {a4048e94-1dd1-11b2-a676-8a06c086cc7d} -#define NS_RDFXMLPARSER_CID \ -{ 0xa4048e94, 0x1dd1, 0x11b2, { 0xa6, 0x76, 0x8a, 0x06, 0xc0, 0x86, 0xcc, 0x7d } } - -// {0a5cd734-eb65-4d14-88a0-9f0bb2aba206} -#define NS_RDFNTRIPLES_SERIALIZER_CID \ -{ 0x0a5cd734, 0xeb65, 0x4d14, { 0x88, 0xa0, 0x9f, 0x0b, 0xb2, 0xab, 0xa2, 0x06 } } - -#endif // nsRDFCID_h__ diff --git a/rdf/build/nsRDFModule.cpp b/rdf/build/nsRDFModule.cpp deleted file mode 100644 index 3828fdd50bc7..000000000000 --- a/rdf/build/nsRDFModule.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* -*- 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/. */ -#include "nsCOMPtr.h" -#include "mozilla/ModuleUtils.h" - -#include "nsIFactory.h" -#include "nsRDFService.h" -#include "nsIRDFContainer.h" -#include "nsIRDFContainerUtils.h" -#include "nsIRDFCompositeDataSource.h" -#include "nsIRDFContentSink.h" -#include "nsISupports.h" -#include "nsRDFBaseDataSources.h" -#include "nsRDFBuiltInDataSources.h" -#include "nsRDFCID.h" -#include "nsIComponentManager.h" -#include "rdf.h" -#include "nsIServiceManager.h" -#include "nsILocalStore.h" -#include "nsRDFXMLParser.h" -#include "nsRDFXMLSerializer.h" - -//---------------------------------------------------------------------- - -// Functions used to create new instances of a given object by the -// generic factory. - -#define MAKE_CTOR(_func,_new,_ifname) \ -static nsresult \ -CreateNew##_func(nsISupports* aOuter, REFNSIID aIID, void **aResult) \ -{ \ - if (!aResult) { \ - return NS_ERROR_INVALID_POINTER; \ - } \ - if (aOuter) { \ - *aResult = nullptr; \ - return NS_ERROR_NO_AGGREGATION; \ - } \ - nsI##_ifname* inst; \ - nsresult rv = NS_New##_new(&inst); \ - if (NS_FAILED(rv)) { \ - *aResult = nullptr; \ - return rv; \ - } \ - rv = inst->QueryInterface(aIID, aResult); \ - if (NS_FAILED(rv)) { \ - *aResult = nullptr; \ - } \ - NS_RELEASE(inst); /* get rid of extra refcnt */ \ - return rv; \ -} - -extern nsresult -NS_NewDefaultResource(nsIRDFResource** aResult); - -MAKE_CTOR(RDFXMLDataSource,RDFXMLDataSource,RDFDataSource) -MAKE_CTOR(RDFCompositeDataSource,RDFCompositeDataSource,RDFCompositeDataSource) -MAKE_CTOR(RDFContainer,RDFContainer,RDFContainer) - -MAKE_CTOR(RDFContainerUtils,RDFContainerUtils,RDFContainerUtils) - -MAKE_CTOR(RDFContentSink,RDFContentSink,RDFContentSink) -MAKE_CTOR(RDFDefaultResource,DefaultResource,RDFResource) - -NS_DEFINE_NAMED_CID(NS_RDFCOMPOSITEDATASOURCE_CID); -NS_DEFINE_NAMED_CID(NS_RDFINMEMORYDATASOURCE_CID); -NS_DEFINE_NAMED_CID(NS_RDFXMLDATASOURCE_CID); -NS_DEFINE_NAMED_CID(NS_RDFDEFAULTRESOURCE_CID); -NS_DEFINE_NAMED_CID(NS_RDFCONTENTSINK_CID); -NS_DEFINE_NAMED_CID(NS_RDFCONTAINER_CID); -NS_DEFINE_NAMED_CID(NS_RDFCONTAINERUTILS_CID); -NS_DEFINE_NAMED_CID(NS_RDFSERVICE_CID); -NS_DEFINE_NAMED_CID(NS_RDFXMLPARSER_CID); -NS_DEFINE_NAMED_CID(NS_RDFXMLSERIALIZER_CID); -NS_DEFINE_NAMED_CID(NS_LOCALSTORE_CID); - - -static const mozilla::Module::CIDEntry kRDFCIDs[] = { - { &kNS_RDFCOMPOSITEDATASOURCE_CID, false, nullptr, CreateNewRDFCompositeDataSource }, - { &kNS_RDFINMEMORYDATASOURCE_CID, false, nullptr, NS_NewRDFInMemoryDataSource }, - { &kNS_RDFXMLDATASOURCE_CID, false, nullptr, CreateNewRDFXMLDataSource }, - { &kNS_RDFDEFAULTRESOURCE_CID, false, nullptr, CreateNewRDFDefaultResource }, - { &kNS_RDFCONTENTSINK_CID, false, nullptr, CreateNewRDFContentSink }, - { &kNS_RDFCONTAINER_CID, false, nullptr, CreateNewRDFContainer }, - { &kNS_RDFCONTAINERUTILS_CID, false, nullptr, CreateNewRDFContainerUtils }, - { &kNS_RDFSERVICE_CID, false, nullptr, RDFServiceImpl::CreateSingleton }, - { &kNS_RDFXMLPARSER_CID, false, nullptr, nsRDFXMLParser::Create }, - { &kNS_RDFXMLSERIALIZER_CID, false, nullptr, nsRDFXMLSerializer::Create }, - { &kNS_LOCALSTORE_CID, false, nullptr, NS_NewLocalStore }, - { nullptr } -}; - -static const mozilla::Module::ContractIDEntry kRDFContracts[] = { - { NS_RDF_DATASOURCE_CONTRACTID_PREFIX "composite-datasource", &kNS_RDFCOMPOSITEDATASOURCE_CID }, - { NS_RDF_DATASOURCE_CONTRACTID_PREFIX "in-memory-datasource", &kNS_RDFINMEMORYDATASOURCE_CID }, - { NS_RDF_DATASOURCE_CONTRACTID_PREFIX "xml-datasource", &kNS_RDFXMLDATASOURCE_CID }, - { NS_RDF_RESOURCE_FACTORY_CONTRACTID, &kNS_RDFDEFAULTRESOURCE_CID }, - { NS_RDF_CONTRACTID "/content-sink;1", &kNS_RDFCONTENTSINK_CID }, - { NS_RDF_CONTRACTID "/container;1", &kNS_RDFCONTAINER_CID }, - { NS_RDF_CONTRACTID "/container-utils;1", &kNS_RDFCONTAINERUTILS_CID }, - { NS_RDF_CONTRACTID "/rdf-service;1", &kNS_RDFSERVICE_CID }, - { NS_RDF_CONTRACTID "/xml-parser;1", &kNS_RDFXMLPARSER_CID }, - { NS_RDF_CONTRACTID "/xml-serializer;1", &kNS_RDFXMLSERIALIZER_CID }, - { NS_LOCALSTORE_CONTRACTID, &kNS_LOCALSTORE_CID }, - { nullptr } -}; - -static const mozilla::Module kRDFModule = { - mozilla::Module::kVersion, - kRDFCIDs, - kRDFContracts, - nullptr, - nullptr, - nullptr, - nullptr -}; - -NSMODULE_DEFN(nsRDFModule) = &kRDFModule; diff --git a/rdf/datasource/moz.build b/rdf/datasource/moz.build deleted file mode 100644 index 8267d67e2289..000000000000 --- a/rdf/datasource/moz.build +++ /dev/null @@ -1,21 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -EXPORTS += [ - 'nsILocalStore.h', -] - -UNIFIED_SOURCES += [ - 'nsLocalStore.cpp', -] - -FINAL_LIBRARY = 'xul' - -# "This is a dependency on rdfutil.h: it'll go away once that becomes -# a first-class XPCOM interface." -LOCAL_INCLUDES += [ - '/rdf/base', -] diff --git a/rdf/datasource/nsILocalStore.h b/rdf/datasource/nsILocalStore.h deleted file mode 100644 index b4122659376c..000000000000 --- a/rdf/datasource/nsILocalStore.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -*- 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/. */ - -#ifndef nsILocalStore_h__ -#define nsILocalStore_h__ - -#include "rdf.h" -#include "nsISupports.h" - -// {DF71C6F1-EC53-11d2-BDCA-000064657374} -#define NS_ILOCALSTORE_IID \ -{ 0xdf71c6f1, 0xec53, 0x11d2, { 0xbd, 0xca, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } } - -// {DF71C6F0-EC53-11d2-BDCA-000064657374} -#define NS_LOCALSTORE_CID \ -{ 0xdf71c6f0, 0xec53, 0x11d2, { 0xbd, 0xca, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } } - -#define NS_LOCALSTORE_CONTRACTID NS_RDF_DATASOURCE_CONTRACTID_PREFIX "local-store" - -class nsILocalStore : public nsISupports -{ -public: - NS_DECLARE_STATIC_IID_ACCESSOR(NS_ILOCALSTORE_IID) -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsILocalStore, NS_ILOCALSTORE_IID) - -extern nsresult -NS_NewLocalStore(nsISupports* aOuter, REFNSIID aIID, void** aResult); - - -#endif // nsILocalStore_h__ diff --git a/rdf/datasource/nsIRDFFTP.h b/rdf/datasource/nsIRDFFTP.h deleted file mode 100644 index 8965b4a3825a..000000000000 --- a/rdf/datasource/nsIRDFFTP.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -*- 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/. */ - -#ifndef nsIRDFFTP_h__ -#define nsIRDFFTP_h__ - -#include "nscore.h" -#include "nsISupports.h" -#include "nsIRDFNode.h" - - - -#define NS_IRDFFTPDATAOURCE_IID \ -{ 0x1222e6f0, 0xa5e3, 0x11d2, { 0x8b, 0x7c, 0x00, 0x80, 0x5f, 0x8a, 0x7d, 0xb7 } } - -class nsIRDFFTPDataSource : public nsIRDFDataSource -{ -public: -}; - - -#define NS_IRDFFTPDATASOURCECALLBACK_IID \ -{ 0x204a1a00, 0xa5e4, 0x11d2, { 0x8b, 0x7c, 0x00, 0x80, 0x5f, 0x8a, 0x7d, 0xb8 } } - -class nsIRDFFTPDataSourceCallback : public nsIStreamListener -{ -public: -}; - - -#endif // nsIRDFFTP_h__ diff --git a/rdf/datasource/nsLocalStore.cpp b/rdf/datasource/nsLocalStore.cpp deleted file mode 100644 index 25ad3e0ccee0..000000000000 --- a/rdf/datasource/nsLocalStore.cpp +++ /dev/null @@ -1,474 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim: set cindent tabstop=4 expandtab shiftwidth=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/. */ - -/* - - Implementation for the local store - - */ - -#include "nsNetUtil.h" -#include "nsIFile.h" -#include "nsIURI.h" -#include "nsIIOService.h" -#include "nsIOutputStream.h" -#include "nsIComponentManager.h" -#include "nsILocalStore.h" -#include "nsIRDFDataSource.h" -#include "nsIRDFRemoteDataSource.h" -#include "nsIRDFService.h" -#include "nsIServiceManager.h" -#include "nsRDFCID.h" -#include "nsString.h" -#include "plstr.h" -#include "rdf.h" -#include "nsCOMPtr.h" -#include "nsWeakPtr.h" -#include "nsAppDirectoryServiceDefs.h" -#include "nsIObserver.h" -#include "nsIObserverService.h" -#include "nsWeakReference.h" -#include "nsCRTGlue.h" -#include "nsCRT.h" -#include "nsEnumeratorUtils.h" -#include "nsCycleCollectionParticipant.h" - -//////////////////////////////////////////////////////////////////////// - -class LocalStoreImpl : public nsILocalStore, - public nsIRDFDataSource, - public nsIRDFRemoteDataSource, - public nsIObserver, - public nsSupportsWeakReference -{ -protected: - nsCOMPtr mInner; - - LocalStoreImpl(); - virtual ~LocalStoreImpl(); - nsresult Init(); - nsresult CreateLocalStore(nsIFile* aFile); - nsresult LoadData(); - - friend nsresult - NS_NewLocalStore(nsISupports* aOuter, REFNSIID aIID, void** aResult); - - nsCOMPtr mRDFService; - -public: - // nsISupports interface - NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(LocalStoreImpl, nsILocalStore) - - // nsILocalStore interface - - // nsIRDFDataSource interface. Most of these are just delegated to - // the inner, in-memory datasource. - NS_IMETHOD GetURI(nsACString& aURI) override; - - NS_IMETHOD GetSource(nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue, - nsIRDFResource** aSource) override { - return mInner->GetSource(aProperty, aTarget, aTruthValue, aSource); - } - - NS_IMETHOD GetSources(nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue, - nsISimpleEnumerator** aSources) override { - return mInner->GetSources(aProperty, aTarget, aTruthValue, aSources); - } - - NS_IMETHOD GetTarget(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - bool aTruthValue, - nsIRDFNode** aTarget) override { - return mInner->GetTarget(aSource, aProperty, aTruthValue, aTarget); - } - - NS_IMETHOD GetTargets(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - bool aTruthValue, - nsISimpleEnumerator** aTargets) override { - return mInner->GetTargets(aSource, aProperty, aTruthValue, aTargets); - } - - NS_IMETHOD Assert(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue) override { - return mInner->Assert(aSource, aProperty, aTarget, aTruthValue); - } - - NS_IMETHOD Unassert(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget) override { - return mInner->Unassert(aSource, aProperty, aTarget); - } - - NS_IMETHOD Change(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aOldTarget, - nsIRDFNode* aNewTarget) override { - return mInner->Change(aSource, aProperty, aOldTarget, aNewTarget); - } - - NS_IMETHOD Move(nsIRDFResource* aOldSource, - nsIRDFResource* aNewSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget) override { - return mInner->Move(aOldSource, aNewSource, aProperty, aTarget); - } - - NS_IMETHOD HasAssertion(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue, - bool* hasAssertion) override { - return mInner->HasAssertion(aSource, aProperty, aTarget, aTruthValue, hasAssertion); - } - - NS_IMETHOD AddObserver(nsIRDFObserver* aObserver) override { - return NS_ERROR_NOT_IMPLEMENTED; - } - - NS_IMETHOD RemoveObserver(nsIRDFObserver* aObserver) override { - return NS_ERROR_NOT_IMPLEMENTED; - } - - NS_IMETHOD HasArcIn(nsIRDFNode *aNode, nsIRDFResource *aArc, bool *_retval) override { - return mInner->HasArcIn(aNode, aArc, _retval); - } - - NS_IMETHOD HasArcOut(nsIRDFResource *aSource, nsIRDFResource *aArc, bool *_retval) override { - return mInner->HasArcOut(aSource, aArc, _retval); - } - - NS_IMETHOD ArcLabelsIn(nsIRDFNode* aNode, - nsISimpleEnumerator** aLabels) override { - return mInner->ArcLabelsIn(aNode, aLabels); - } - - NS_IMETHOD ArcLabelsOut(nsIRDFResource* aSource, - nsISimpleEnumerator** aLabels) override { - return mInner->ArcLabelsOut(aSource, aLabels); - } - - NS_IMETHOD GetAllResources(nsISimpleEnumerator** aResult) override { - return mInner->GetAllResources(aResult); - } - - NS_IMETHOD GetAllCmds(nsIRDFResource* aSource, - nsISimpleEnumerator/**/** aCommands) override; - - NS_IMETHOD IsCommandEnabled(nsISupports* aSources, - nsIRDFResource* aCommand, - nsISupports* aArguments, - bool* aResult) override; - - NS_IMETHOD DoCommand(nsISupports* aSources, - nsIRDFResource* aCommand, - nsISupports* aArguments) override; - - NS_IMETHOD BeginUpdateBatch() override { - return mInner->BeginUpdateBatch(); - } - - NS_IMETHOD EndUpdateBatch() override { - return mInner->EndUpdateBatch(); - } - - NS_IMETHOD GetLoaded(bool* _result) override; - NS_IMETHOD Init(const char *uri) override; - NS_IMETHOD Flush() override; - NS_IMETHOD FlushTo(const char *aURI) override; - NS_IMETHOD Refresh(bool sync) override; - - // nsIObserver - NS_DECL_NSIOBSERVER -}; - -//////////////////////////////////////////////////////////////////////// - - -LocalStoreImpl::LocalStoreImpl(void) -{ -} - -LocalStoreImpl::~LocalStoreImpl(void) -{ - if (mRDFService) - mRDFService->UnregisterDataSource(this); -} - - -nsresult -NS_NewLocalStore(nsISupports* aOuter, REFNSIID aIID, void** aResult) -{ - NS_PRECONDITION(aOuter == nullptr, "no aggregation"); - if (aOuter) - return NS_ERROR_NO_AGGREGATION; - - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - LocalStoreImpl* impl = new LocalStoreImpl(); - if (! impl) - return NS_ERROR_OUT_OF_MEMORY; - - NS_ADDREF(impl); - - nsresult rv; - rv = impl->Init(); - if (NS_SUCCEEDED(rv)) { - // Set up the result pointer - rv = impl->QueryInterface(aIID, aResult); - } - - NS_RELEASE(impl); - return rv; -} - -NS_IMPL_CYCLE_COLLECTION(LocalStoreImpl, mInner) -NS_IMPL_CYCLE_COLLECTING_ADDREF(LocalStoreImpl) -NS_IMPL_CYCLE_COLLECTING_RELEASE(LocalStoreImpl) - -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(LocalStoreImpl) - NS_INTERFACE_MAP_ENTRY(nsILocalStore) - NS_INTERFACE_MAP_ENTRY(nsIRDFDataSource) - NS_INTERFACE_MAP_ENTRY(nsIRDFRemoteDataSource) - NS_INTERFACE_MAP_ENTRY(nsIObserver) - NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsILocalStore) -NS_INTERFACE_MAP_END - -// nsILocalStore interface - -// nsIRDFDataSource interface - -NS_IMETHODIMP -LocalStoreImpl::GetLoaded(bool* _result) -{ - nsCOMPtr remote = do_QueryInterface(mInner); - NS_ASSERTION(remote != nullptr, "not an nsIRDFRemoteDataSource"); - if (! remote) - return NS_ERROR_UNEXPECTED; - - return remote->GetLoaded(_result); -} - - -NS_IMETHODIMP -LocalStoreImpl::Init(const char *uri) -{ - return(NS_OK); -} - -NS_IMETHODIMP -LocalStoreImpl::Flush() -{ - nsCOMPtr remote = do_QueryInterface(mInner); - // FIXME Bug 340242: Temporarily make this a warning rather than an - // assertion until we sort out the ordering of how we write - // everything to the localstore, flush it, and disconnect it when - // we're getting profile-change notifications. - NS_WARNING_ASSERTION(remote != nullptr, "not an nsIRDFRemoteDataSource"); - if (! remote) - return NS_ERROR_UNEXPECTED; - - return remote->Flush(); -} - -NS_IMETHODIMP -LocalStoreImpl::FlushTo(const char *aURI) -{ - // Do not ever implement this (security) - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -LocalStoreImpl::Refresh(bool sync) -{ - nsCOMPtr remote = do_QueryInterface(mInner); - NS_ASSERTION(remote != nullptr, "not an nsIRDFRemoteDataSource"); - if (! remote) - return NS_ERROR_UNEXPECTED; - - return remote->Refresh(sync); -} - -nsresult -LocalStoreImpl::Init() -{ - nsresult rv; - - rv = LoadData(); - if (NS_FAILED(rv)) return rv; - - // register this as a named data source with the RDF service - mRDFService = do_GetService(NS_RDF_CONTRACTID "/rdf-service;1", &rv); - if (NS_FAILED(rv)) return rv; - - mRDFService->RegisterDataSource(this, false); - - // Register as an observer of profile changes - nsCOMPtr obs = - do_GetService("@mozilla.org/observer-service;1"); - - if (obs) { - obs->AddObserver(this, "profile-before-change", true); - obs->AddObserver(this, "profile-do-change", true); - } - - return NS_OK; -} - -nsresult -LocalStoreImpl::CreateLocalStore(nsIFile* aFile) -{ - nsresult rv; - - rv = aFile->Create(nsIFile::NORMAL_FILE_TYPE, 0666); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr outStream; - rv = NS_NewLocalFileOutputStream(getter_AddRefs(outStream), aFile); - if (NS_FAILED(rv)) return rv; - - const char defaultRDF[] = - "\n" \ - "\n" \ - " \n" \ - "\n"; - - uint32_t count; - rv = outStream->Write(defaultRDF, sizeof(defaultRDF)-1, &count); - if (NS_FAILED(rv)) return rv; - - if (count != sizeof(defaultRDF)-1) - return NS_ERROR_UNEXPECTED; - - // Okay, now see if the file exists _for real_. If it's still - // not there, it could be that the profile service gave us - // back a read-only directory. Whatever. - bool fileExistsFlag = false; - aFile->Exists(&fileExistsFlag); - if (!fileExistsFlag) - return NS_ERROR_UNEXPECTED; - - return NS_OK; -} - -nsresult -LocalStoreImpl::LoadData() -{ - nsresult rv; - - // Look for localstore.rdf in the current profile - // directory. Bomb if we can't find it. - - nsCOMPtr aFile; - rv = NS_GetSpecialDirectory(NS_APP_LOCALSTORE_50_FILE, getter_AddRefs(aFile)); - if (NS_FAILED(rv)) return rv; - - bool fileExistsFlag = false; - (void)aFile->Exists(&fileExistsFlag); - if (!fileExistsFlag) { - // if file doesn't exist, create it - rv = CreateLocalStore(aFile); - if (NS_FAILED(rv)) return rv; - } - - mInner = do_CreateInstance(NS_RDF_DATASOURCE_CONTRACTID_PREFIX "xml-datasource", &rv); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr remote = do_QueryInterface(mInner, &rv); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr aURI; - rv = NS_NewFileURI(getter_AddRefs(aURI), aFile); - if (NS_FAILED(rv)) return rv; - - nsAutoCString spec; - rv = aURI->GetSpec(spec); - if (NS_FAILED(rv)) return rv; - - rv = remote->Init(spec.get()); - if (NS_FAILED(rv)) return rv; - - // Read the datasource synchronously. - rv = remote->Refresh(true); - - if (NS_FAILED(rv)) { - // Load failed, delete and recreate a fresh localstore - aFile->Remove(true); - rv = CreateLocalStore(aFile); - if (NS_FAILED(rv)) return rv; - - rv = remote->Refresh(true); - } - - return rv; -} - - -NS_IMETHODIMP -LocalStoreImpl::GetURI(nsACString& aURI) -{ - aURI.AssignLiteral("rdf:local-store"); - return NS_OK; -} - - -NS_IMETHODIMP -LocalStoreImpl::GetAllCmds(nsIRDFResource* aSource, - nsISimpleEnumerator/**/** aCommands) -{ - return(NS_NewEmptyEnumerator(aCommands)); -} - -NS_IMETHODIMP -LocalStoreImpl::IsCommandEnabled(nsISupports* aSources, - nsIRDFResource* aCommand, - nsISupports* aArguments, - bool* aResult) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -LocalStoreImpl::DoCommand(nsISupports* aSources, - nsIRDFResource* aCommand, - nsISupports* aArguments) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -LocalStoreImpl::Observe(nsISupports *aSubject, const char *aTopic, const char16_t *someData) -{ - nsresult rv = NS_OK; - - if (!nsCRT::strcmp(aTopic, "profile-before-change")) { - // Write out the old datasource's contents. - if (mInner) { - nsCOMPtr remote = do_QueryInterface(mInner); - if (remote) - remote->Flush(); - } - - // Create an in-memory datasource for use while we're - // profile-less. - mInner = do_CreateInstance(NS_RDF_DATASOURCE_CONTRACTID_PREFIX "in-memory-datasource"); - } - else if (!nsCRT::strcmp(aTopic, "profile-do-change")) { - rv = LoadData(); - } - return rv; -} diff --git a/rdf/datasource/nsRDFBuiltInDataSources.h b/rdf/datasource/nsRDFBuiltInDataSources.h deleted file mode 100644 index 297fe71640dd..000000000000 --- a/rdf/datasource/nsRDFBuiltInDataSources.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -*- 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 header file just contains prototypes for the factory methods - for "builtin" data sources that are included in rdf.dll. - - Each of these data sources is exposed to the external world via its - CID in ../include/nsRDFCID.h. - - */ - -#ifndef nsBuiltinDataSources_h__ -#define nsBuiltinDataSources_h__ - -#include "nsError.h" - -class nsIRDFDataSource; - -// in nsFileSystemDataSource.cpp -nsresult NS_NewRDFFileSystemDataSource(nsIRDFDataSource** result); - -#endif // nsBuiltinDataSources_h__ - diff --git a/rdf/moz.build b/rdf/moz.build deleted file mode 100644 index 6f678fed085b..000000000000 --- a/rdf/moz.build +++ /dev/null @@ -1,12 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -with Files('**'): - BUG_COMPONENT = ('Core', 'RDF') - -DIRS += ['base', 'datasource', 'build'] -TEST_DIRS += ['tests'] - diff --git a/rdf/tests/moz.build b/rdf/tests/moz.build deleted file mode 100644 index d8fb7519d5da..000000000000 --- a/rdf/tests/moz.build +++ /dev/null @@ -1,7 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -XPCSHELL_TESTS_MANIFESTS += ['unit/xpcshell.ini'] diff --git a/rdf/tests/unit/sample.rdf b/rdf/tests/unit/sample.rdf deleted file mode 100755 index 42de8cd08b9f..000000000000 --- a/rdf/tests/unit/sample.rdf +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - diff --git a/rdf/tests/unit/test_rdfredirect.js b/rdf/tests/unit/test_rdfredirect.js deleted file mode 100644 index f3c076ba7a61..000000000000 --- a/rdf/tests/unit/test_rdfredirect.js +++ /dev/null @@ -1,92 +0,0 @@ -ChromeUtils.import("resource://testing-common/httpd.js"); - -function getRDFService() -{ - return Cc["@mozilla.org/rdf/rdf-service;1"]. - getService(Ci.nsIRDFService); -} - -var server1, server2; - -function run_test() -{ - var samplefile = do_get_file('sample.rdf'); - - server1 = new HttpServer(); - server1.registerPathHandler("/sample-xs.rdf", xsRedirect); - server1.registerPathHandler("/sample-local.rdf", localRedirect); - server1.registerFile('/sample.rdf', samplefile); - server1.start(4444); - - server2 = new HttpServer(); - server2.registerFile('/sample.rdf', samplefile); - server2.start(4445); - - do_test_pending(); - - new rdfLoadObserver('http://localhost:4444/sample.rdf', true); - new rdfLoadObserver('http://localhost:4445/sample.rdf', true); - new rdfLoadObserver('http://localhost:4444/sample-xs.rdf', false); - new rdfLoadObserver('http://localhost:4444/sample-local.rdf', true); -} - -var gPending = 0; - -function rdfLoadObserver(uri, shouldPass) -{ - this.shouldPass = shouldPass; - this.uri = uri; - - ++gPending; - - var rdfService = getRDFService(); - this.ds = rdfService.GetDataSource(uri). - QueryInterface(Ci.nsIRDFXMLSink); - this.ds.addXMLSinkObserver(this); -} - -rdfLoadObserver.prototype = -{ - onBeginLoad : function() { }, - onInterrupt : function() { }, - onResume : function() { }, - onEndLoad : function() { - print("Testing results of loading " + this.uri); - - var rdfs = getRDFService(); - var res = rdfs.GetResource("urn:mozilla:sample-data"); - var arc = rdfs.GetResource("http://purl.org/dc/elements/1.1/title"); - var answer = this.ds.GetTarget(res, arc, true); - if (answer !== null) { - Assert.ok(this.shouldPass); - Assert.ok(answer instanceof Ci.nsIRDFLiteral); - Assert.equal(answer.Value, "Sample"); - } - else { - Assert.ok(!this.shouldPass); - } - - gPending -= 1; - - this.ds.removeXMLSinkObserver(this); - - if (gPending == 0) { - do_test_pending(); - server1.stop(do_test_finished); - server2.stop(do_test_finished); - } - }, - onError : function() { } -} - -function xsRedirect(metadata, response) -{ - response.setStatusLine(metadata.httpVersion, 301, "Moved Permanently"); - response.setHeader("Location", "http://localhost:4445/sample.rdf", false); -} - -function localRedirect(metadata, response) -{ - response.setStatusLine(metadata.httpVersion, 301, "Moved Permanently"); - response.setHeader("Location", "http://localhost:4444/sample.rdf", false); -} diff --git a/rdf/tests/unit/xpcshell.ini b/rdf/tests/unit/xpcshell.ini deleted file mode 100644 index 4cea6cc1421e..000000000000 --- a/rdf/tests/unit/xpcshell.ini +++ /dev/null @@ -1,5 +0,0 @@ -[DEFAULT] -head = -support-files = sample.rdf - -[test_rdfredirect.js] diff --git a/toolkit/components/build/nsToolkitCompsModule.cpp b/toolkit/components/build/nsToolkitCompsModule.cpp index ed0bc38b663e..6d6fad377756 100644 --- a/toolkit/components/build/nsToolkitCompsModule.cpp +++ b/toolkit/components/build/nsToolkitCompsModule.cpp @@ -20,7 +20,6 @@ #include "nsAlertsService.h" #include "DownloadPlatform.h" -#include "rdf.h" #include "nsTypeAheadFind.h" diff --git a/toolkit/toolkit.mozbuild b/toolkit/toolkit.mozbuild index 873a91f0f8aa..d6e171025d8d 100644 --- a/toolkit/toolkit.mozbuild +++ b/toolkit/toolkit.mozbuild @@ -88,10 +88,6 @@ DIRS += [ '/extensions/permissions', ] -DIRS += [ - '/rdf', -] - if CONFIG['MOZ_WEBRTC'] and CONFIG['COMPILE_ENVIRONMENT']: DIRS += [ '/media/webrtc', From d4cad70c37e1bfc01dc651099fe44e0ba1d8ed2f Mon Sep 17 00:00:00 2001 From: Chris Peterson Date: Sun, 5 Nov 2017 17:01:56 -0800 Subject: [PATCH 06/34] Bug 1457813 - Part 1: Replace asserting NS_PRECONDITIONs with NS_ASSERTIONs. r=froydnj MozReview-Commit-ID: JMNmdne85lg --HG-- extra : source : 4f90ac55e5c9a565765f742a4872c130205019b9 extra : intermediate-source : 41061cadcc2a75b9c78643a6220d012a7b64ea69 --- dom/base/nsIContentInlines.h | 6 ++++-- layout/base/PresShell.cpp | 9 ++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/dom/base/nsIContentInlines.h b/dom/base/nsIContentInlines.h index 19b79e0c70e0..6f98f3b31cab 100644 --- a/dom/base/nsIContentInlines.h +++ b/dom/base/nsIContentInlines.h @@ -33,8 +33,10 @@ inline void nsIContent::SetPrimaryFrame(nsIFrame* aFrame) { MOZ_ASSERT(IsInUncomposedDoc() || IsInShadowTree(), "This will end badly!"); - NS_PRECONDITION(!aFrame || !mPrimaryFrame || aFrame == mPrimaryFrame, - "Losing track of existing primary frame"); + + // FIXME bug 749326 + NS_ASSERTION(!aFrame || !mPrimaryFrame || aFrame == mPrimaryFrame, + "Losing track of existing primary frame"); if (aFrame) { if (MOZ_LIKELY(!IsHTMLElement(nsGkAtoms::area)) || diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp index 1a7bd0ebb001..de668b60b38f 100644 --- a/layout/base/PresShell.cpp +++ b/layout/base/PresShell.cpp @@ -2681,10 +2681,13 @@ PresShell::FrameNeedsReflow(nsIFrame *aFrame, IntrinsicDirty aIntrinsicDirty, aBitToAdd == NS_FRAME_HAS_DIRTY_CHILDREN || !aBitToAdd, "Unexpected bits being added"); - NS_PRECONDITION(!(aIntrinsicDirty == eStyleChange && - aBitToAdd == NS_FRAME_HAS_DIRTY_CHILDREN), - "bits don't correspond to style change reason"); + // FIXME bug 478135 + NS_ASSERTION(!(aIntrinsicDirty == eStyleChange && + aBitToAdd == NS_FRAME_HAS_DIRTY_CHILDREN), + "bits don't correspond to style change reason"); + + // FIXME bug 457400 NS_ASSERTION(!mIsReflowing, "can't mark frame dirty during reflow"); // If we've not yet done the initial reflow, then don't bother From 71422dcaa9e79f41c5a7be0b30d93ac5844d7fed Mon Sep 17 00:00:00 2001 From: Chris Peterson Date: Sat, 28 Apr 2018 12:50:58 -0700 Subject: [PATCH 07/34] Bug 1457813 - Part 2: Replace non-asserting NS_PRECONDITIONs with MOZ_ASSERTs. r=froydnj s/NS_PRECONDITION/MOZ_ASSERT/ and reindent MozReview-Commit-ID: KuUsnVe2h8L --HG-- extra : source : c14655ab3df2c9b1465dd8102b9d25683359a37b --- accessible/base/FocusManager.cpp | 6 +- accessible/base/TextAttrs.cpp | 14 +- accessible/generic/Accessible.cpp | 10 +- accessible/generic/Accessible.h | 2 +- accessible/mac/mozTextAccessible.mm | 4 +- accessible/xpcom/xpcAccessibleSelectable.cpp | 16 +- accessible/xul/XULTreeGridAccessible.cpp | 2 +- caps/ContentPrincipal.cpp | 2 +- caps/nsJSPrincipals.cpp | 4 +- caps/nsScriptSecurityManager.cpp | 10 +- chrome/nsChromeProtocolHandler.cpp | 2 +- docshell/base/nsDSURIContentListener.cpp | 2 +- docshell/base/nsDocShell.cpp | 28 +-- docshell/base/nsWebNavigationInfo.cpp | 4 +- docshell/build/nsDocShellModule.cpp | 2 +- docshell/shistory/nsSHEntryShared.cpp | 4 +- docshell/shistory/nsSHistory.cpp | 4 +- dom/base/CharacterData.cpp | 48 +++--- dom/base/Element.cpp | 60 +++---- dom/base/Element.h | 12 +- dom/base/EventSource.cpp | 7 +- dom/base/FragmentOrElement.cpp | 8 +- dom/base/IDTracker.h | 2 +- dom/base/Selection.cpp | 4 +- dom/base/nsAttrAndChildArray.cpp | 9 +- dom/base/nsAttrAndChildArray.h | 2 +- dom/base/nsAttrValue.cpp | 15 +- dom/base/nsAttrValueInlines.h | 18 +- dom/base/nsContentAreaDragDrop.cpp | 4 +- dom/base/nsContentList.cpp | 10 +- dom/base/nsContentList.h | 4 +- dom/base/nsContentPolicy.cpp | 4 +- dom/base/nsContentSink.cpp | 4 +- dom/base/nsContentUtils.cpp | 72 ++++---- dom/base/nsContentUtils.h | 2 +- dom/base/nsDocument.cpp | 60 +++---- dom/base/nsDocumentEncoder.cpp | 4 +- dom/base/nsFocusManager.cpp | 4 +- dom/base/nsFrameLoader.cpp | 6 +- dom/base/nsGenConImageContent.cpp | 2 +- dom/base/nsGlobalWindowInner.cpp | 6 +- dom/base/nsGlobalWindowOuter.cpp | 16 +- dom/base/nsImageLoadingContent.cpp | 14 +- dom/base/nsJSEnvironment.cpp | 2 +- dom/base/nsMappedAttributes.cpp | 4 +- dom/base/nsNameSpaceManager.cpp | 2 +- dom/base/nsNodeInfoManager.cpp | 4 +- dom/base/nsNodeUtils.cpp | 18 +- dom/base/nsPropertyTable.cpp | 6 +- dom/base/nsRange.cpp | 57 ++++--- dom/base/nsSyncLoadService.cpp | 2 +- dom/base/nsTextNode.cpp | 11 +- dom/base/nsTreeSanitizer.cpp | 8 +- dom/canvas/CanvasUtils.cpp | 2 +- .../nsControllerCommandTable.cpp | 2 +- dom/events/ContentEventHandler.cpp | 4 +- dom/events/EventListenerService.cpp | 4 +- dom/events/EventStateManager.cpp | 12 +- dom/events/WheelHandlingHelper.cpp | 2 +- dom/html/HTMLFormElement.cpp | 10 +- dom/html/HTMLFrameSetElement.cpp | 8 +- dom/html/HTMLImageElement.cpp | 2 +- dom/html/HTMLInputElement.cpp | 16 +- dom/html/HTMLSharedElement.cpp | 4 +- dom/html/nsGenericHTMLElement.cpp | 12 +- dom/html/nsGenericHTMLFrameElement.cpp | 2 +- dom/html/nsHTMLContentSink.cpp | 4 +- dom/jsurl/nsJSProtocolHandler.cpp | 2 +- dom/script/nsIScriptElement.h | 12 +- dom/security/nsCSPContext.cpp | 4 +- dom/smil/SMILBoolType.cpp | 29 ++-- dom/smil/SMILEnumType.cpp | 26 +-- dom/smil/SMILIntegerType.cpp | 27 ++- dom/smil/SMILStringType.cpp | 29 ++-- dom/smil/nsSMILFloatType.cpp | 28 +-- dom/smil/nsSMILNullType.cpp | 8 +- dom/svg/SVGIntegerPairSMILType.cpp | 27 ++- dom/svg/SVGLengthListSMILType.cpp | 27 ++- dom/svg/SVGNumberListSMILType.cpp | 27 ++- dom/svg/SVGNumberPairSMILType.cpp | 27 ++- dom/svg/SVGOrientSMILType.cpp | 27 ++- dom/svg/SVGPathSegListSMILType.cpp | 27 ++- dom/svg/SVGPointListSMILType.cpp | 27 ++- dom/svg/SVGTransformListSMILType.cpp | 39 +++-- dom/svg/SVGViewBoxSMILType.cpp | 27 ++- dom/xbl/nsBindingManager.cpp | 8 +- dom/xbl/nsXBLContentSink.cpp | 2 +- dom/xbl/nsXBLProtoImplField.cpp | 5 +- dom/xbl/nsXBLProtoImplMethod.cpp | 20 +-- dom/xbl/nsXBLProtoImplProperty.cpp | 21 +-- dom/xbl/nsXBLService.cpp | 8 +- dom/xhr/XMLHttpRequestMainThread.cpp | 2 +- dom/xml/ProcessingInstruction.cpp | 2 +- dom/xml/nsXMLContentSink.cpp | 10 +- dom/xml/nsXMLFragmentContentSink.cpp | 2 +- dom/xslt/xpath/txXPathTreeWalker.h | 3 +- dom/xslt/xslt/txExecutionState.cpp | 4 +- dom/xslt/xslt/txMozillaStylesheetCompiler.cpp | 4 +- dom/xslt/xslt/txMozillaXMLOutput.cpp | 4 +- dom/xslt/xslt/txStylesheetCompiler.cpp | 4 +- dom/xul/XULDocument.cpp | 18 +- dom/xul/nsXULCommandDispatcher.cpp | 4 +- dom/xul/nsXULContentSink.cpp | 10 +- dom/xul/nsXULContentUtils.cpp | 4 +- dom/xul/nsXULControllers.cpp | 2 +- dom/xul/nsXULElement.cpp | 12 +- dom/xul/nsXULPrototypeDocument.cpp | 6 +- editor/libeditor/EditorBase.cpp | 10 +- editor/libeditor/EditorEventListener.cpp | 2 +- editor/libeditor/HTMLEditor.cpp | 6 +- editor/libeditor/TextEditRules.cpp | 2 +- editor/libeditor/TextEditor.cpp | 2 +- .../spellcheck/src/mozInlineSpellChecker.cpp | 4 +- .../spellcheck/src/mozInlineSpellWordUtil.cpp | 6 +- gfx/thebes/gfxDWriteCommon.cpp | 4 +- gfx/thebes/gfxFT2FontBase.cpp | 2 +- gfx/thebes/gfxFT2Utils.cpp | 2 +- gfx/thebes/gfxFont.cpp | 6 +- gfx/thebes/gfxFont.h | 4 +- gfx/thebes/gfxFontEntry.h | 4 +- gfx/thebes/gfxTextRun.cpp | 4 +- gfx/thebes/gfxXlibSurface.cpp | 4 +- image/ImageURL.h | 4 +- image/decoders/icon/nsIconURI.cpp | 2 +- image/imgLoader.h | 4 +- image/imgRequest.cpp | 2 +- image/imgRequestProxy.cpp | 12 +- intl/lwbrk/WordBreaker.cpp | 12 +- intl/uconv/nsConverterOutputStream.cpp | 3 +- ipc/glue/MessageChannel.cpp | 13 +- ipc/glue/MessageLink.cpp | 4 +- js/xpconnect/src/XPCConvert.cpp | 12 +- js/xpconnect/src/XPCMaps.h | 38 ++--- js/xpconnect/src/XPCWrappedJS.cpp | 4 +- js/xpconnect/src/XPCWrappedJSClass.cpp | 2 +- js/xpconnect/src/nsXPConnect.cpp | 12 +- layout/base/PresShell.cpp | 68 ++++---- layout/base/RestyleManager.cpp | 9 +- layout/base/nsBidiPresUtils.cpp | 8 +- layout/base/nsCSSFrameConstructor.cpp | 159 +++++++++--------- layout/base/nsDocumentViewer.cpp | 6 +- layout/base/nsFrameManager.cpp | 12 +- layout/base/nsLayoutDebugger.cpp | 2 +- layout/base/nsLayoutUtils.cpp | 47 +++--- layout/base/nsPresContext.cpp | 4 +- layout/base/nsRefreshDriver.cpp | 12 +- layout/base/nsStyleSheetService.cpp | 4 +- layout/build/nsContentDLF.cpp | 2 +- layout/build/nsLayoutModule.cpp | 2 +- layout/forms/nsComboboxControlFrame.cpp | 2 +- layout/forms/nsFieldSetFrame.cpp | 5 +- layout/forms/nsListControlFrame.cpp | 14 +- layout/forms/nsTextControlFrame.cpp | 6 +- layout/generic/BlockReflowInput.cpp | 9 +- layout/generic/ReflowInput.cpp | 18 +- layout/generic/TextOverflow.cpp | 13 +- layout/generic/nsAbsoluteContainingBlock.cpp | 2 +- layout/generic/nsBlockFrame.cpp | 27 +-- layout/generic/nsBulletFrame.cpp | 2 +- layout/generic/nsContainerFrame.cpp | 82 ++++----- layout/generic/nsContainerFrame.h | 2 +- layout/generic/nsFirstLetterFrame.cpp | 2 +- layout/generic/nsFloatManager.cpp | 4 +- layout/generic/nsFrame.cpp | 54 +++--- layout/generic/nsFrameList.cpp | 68 ++++---- layout/generic/nsFrameList.h | 6 +- layout/generic/nsFrameSelection.cpp | 9 +- layout/generic/nsGfxScrollFrame.cpp | 6 +- layout/generic/nsHTMLCanvasFrame.cpp | 2 +- layout/generic/nsIFrame.h | 4 +- layout/generic/nsImageFrame.cpp | 10 +- layout/generic/nsLineBox.cpp | 18 +- layout/generic/nsLineLayout.cpp | 6 +- layout/generic/nsPageFrame.cpp | 2 +- layout/generic/nsPlaceholderFrame.cpp | 2 +- layout/generic/nsPlaceholderFrame.h | 6 +- layout/generic/nsPluginFrame.cpp | 4 +- layout/generic/nsSimplePageSequenceFrame.cpp | 4 +- layout/generic/nsSubDocumentFrame.cpp | 10 +- layout/generic/nsTextFrame.cpp | 40 ++--- layout/generic/nsVideoFrame.cpp | 2 +- layout/mathml/nsMathMLContainerFrame.cpp | 2 +- layout/painting/nsCSSRendering.cpp | 12 +- layout/painting/nsDisplayList.cpp | 26 +-- layout/printing/nsPrintJob.cpp | 2 +- layout/style/Loader.cpp | 56 +++--- layout/style/nsComputedDOMStyle.cpp | 20 +-- layout/style/nsDOMCSSDeclaration.cpp | 4 +- layout/style/nsROCSSPrimitiveValue.cpp | 12 +- layout/style/nsStyleStruct.cpp | 4 +- layout/style/nsStyleTransformMatrix.cpp | 38 ++--- layout/style/nsStyleUtil.cpp | 24 +-- layout/svg/SVGTextFrame.cpp | 2 +- layout/svg/nsSVGOuterSVGFrame.cpp | 2 +- layout/tables/nsCellMap.cpp | 10 +- layout/tables/nsCellMap.h | 4 +- layout/tables/nsTableFrame.cpp | 33 ++-- layout/tables/nsTableRowGroupFrame.cpp | 6 +- layout/tables/nsTableWrapperFrame.cpp | 2 +- layout/xul/nsBoxFrame.cpp | 9 +- layout/xul/nsListBoxBodyFrame.cpp | 2 +- layout/xul/nsPopupSetFrame.cpp | 6 +- layout/xul/nsRepeatService.cpp | 2 +- layout/xul/nsSprocketLayout.cpp | 4 +- layout/xul/tree/nsTreeBodyFrame.cpp | 22 +-- modules/libjar/nsJAR.cpp | 2 +- modules/libjar/nsJARChannel.cpp | 2 +- netwerk/base/nsBaseChannel.h | 2 +- netwerk/base/nsDirectoryIndexStream.cpp | 2 +- netwerk/base/nsNetUtil.cpp | 8 +- netwerk/base/nsNetUtil.h | 2 +- netwerk/base/nsProtocolProxyService.cpp | 4 +- netwerk/base/nsRequestObserverProxy.cpp | 6 +- netwerk/base/nsSimpleStreamListener.cpp | 2 +- netwerk/base/nsSimpleURI.cpp | 2 +- netwerk/base/nsStandardURL.cpp | 20 ++- netwerk/base/nsURLParsers.cpp | 6 +- netwerk/cache/nsCacheEntryDescriptor.cpp | 8 +- netwerk/cache2/CacheFileChunk.cpp | 2 +- netwerk/cache2/CacheFileIOManager.cpp | 2 +- netwerk/cache2/CacheFileInputStream.cpp | 2 +- netwerk/cache2/CacheFileOutputStream.cpp | 2 +- netwerk/protocol/about/nsAboutProtocolUtils.h | 2 +- .../http/AltDataOutputStreamChild.cpp | 2 +- netwerk/protocol/http/HttpBaseChannel.cpp | 2 +- netwerk/protocol/http/HttpBaseChannel.h | 2 +- netwerk/protocol/http/nsHttpChannel.cpp | 30 ++-- .../protocol/http/nsHttpChunkedDecoder.cpp | 4 +- netwerk/protocol/http/nsHttpTransaction.cpp | 6 +- .../websocket/WebSocketChannelChild.cpp | 2 +- .../protocol/wyciwyg/WyciwygChannelChild.cpp | 2 +- netwerk/protocol/wyciwyg/nsWyciwygChannel.cpp | 2 +- netwerk/sctp/datachannel/DataChannel.cpp | 2 +- .../converters/mozTXTToHTMLConv.cpp | 2 +- .../converters/nsFTPDirListingConv.cpp | 2 +- .../converters/nsHTTPCompressConv.cpp | 2 +- .../converters/nsMultiMixedConv.cpp | 2 +- .../streamconv/nsStreamConverterService.cpp | 2 +- parser/html/nsHtml5Highlighter.cpp | 28 +-- parser/html/nsHtml5OwningUTF16Buffer.cpp | 4 +- parser/html/nsHtml5Parser.cpp | 18 +- parser/html/nsHtml5Portability.cpp | 4 +- parser/html/nsHtml5SpeculativeLoad.h | 52 +++--- parser/html/nsHtml5StreamParser.cpp | 2 +- parser/html/nsHtml5StreamParser.h | 4 +- parser/html/nsHtml5StreamParserPtr.h | 4 +- parser/html/nsHtml5TreeBuilderCppSupplement.h | 60 +++---- parser/html/nsHtml5TreeOpExecutor.cpp | 2 +- parser/html/nsHtml5TreeOperation.cpp | 6 +- parser/html/nsHtml5TreeOperation.h | 125 +++++++------- parser/htmlparser/nsExpatDriver.cpp | 8 +- parser/htmlparser/nsParser.cpp | 17 +- parser/xml/nsSAXXMLReader.cpp | 2 +- storage/StorageBaseStatementInternal.cpp | 2 +- storage/mozStorageConnection.cpp | 2 +- storage/mozStorageStatementData.h | 6 +- .../browser/nsWebBrowserContentPolicy.cpp | 4 +- toolkit/components/places/History.cpp | 4 +- toolkit/components/places/PlaceInfo.cpp | 4 +- toolkit/components/places/SQLFunctions.cpp | 6 +- .../components/places/nsNavHistoryResult.cpp | 5 +- uriloader/base/nsURILoader.cpp | 18 +- .../exthandler/nsExternalHelperAppService.cpp | 9 +- .../exthandler/unix/nsOSHelperAppService.cpp | 2 +- view/nsView.cpp | 17 +- view/nsViewManager.cpp | 21 ++- widget/cocoa/TextInputHandler.h | 2 +- widget/cocoa/nsChildView.mm | 2 +- widget/cocoa/nsMenuUtilsX.mm | 2 +- widget/cocoa/nsPrintDialogX.mm | 6 +- widget/gtk/IMContextWrapper.cpp | 6 +- widget/gtk/nsPrintDialogGTK.cpp | 16 +- widget/gtk/nsWindow.cpp | 4 +- widget/nsBaseFilePicker.cpp | 3 +- widget/nsNativeTheme.cpp | 2 +- widget/windows/IMMHandler.cpp | 4 +- widget/windows/WinUtils.cpp | 4 +- widget/windows/nsColorPicker.cpp | 2 +- widget/windows/nsWindow.cpp | 2 +- xpcom/base/nsAutoPtr.h | 12 +- xpcom/base/nsCycleCollectionParticipant.h | 2 +- xpcom/base/nsIInterfaceRequestorUtils.h | 4 +- xpcom/base/nsISupportsImpl.h | 4 +- xpcom/base/nsISupportsUtils.h | 4 +- xpcom/base/nsIWeakReferenceUtils.h | 4 +- xpcom/components/nsComponentManagerUtils.h | 24 +-- xpcom/components/nsServiceManagerUtils.h | 6 +- xpcom/ds/nsArrayEnumerator.cpp | 8 +- xpcom/ds/nsEnumeratorUtils.cpp | 8 +- xpcom/ds/nsTObserverArray.cpp | 2 +- xpcom/io/nsBinaryStream.cpp | 2 +- xpcom/io/nsStringStream.cpp | 6 +- 292 files changed, 1627 insertions(+), 1642 deletions(-) diff --git a/accessible/base/FocusManager.cpp b/accessible/base/FocusManager.cpp index 6d697636e054..5251ff7230e6 100644 --- a/accessible/base/FocusManager.cpp +++ b/accessible/base/FocusManager.cpp @@ -239,7 +239,7 @@ void FocusManager::DispatchFocusEvent(DocAccessible* aDocument, Accessible* aTarget) { - NS_PRECONDITION(aDocument, "No document for focused accessible!"); + MOZ_ASSERT(aDocument, "No document for focused accessible!"); if (aDocument) { RefPtr event = new AccEvent(nsIAccessibleEvent::EVENT_FOCUS, aTarget, @@ -292,8 +292,8 @@ FocusManager::ProcessDOMFocus(nsINode* aTarget) void FocusManager::ProcessFocusEvent(AccEvent* aEvent) { - NS_PRECONDITION(aEvent->GetEventType() == nsIAccessibleEvent::EVENT_FOCUS, - "Focus event is expected!"); + MOZ_ASSERT(aEvent->GetEventType() == nsIAccessibleEvent::EVENT_FOCUS, + "Focus event is expected!"); // Emit focus event if event target is the active item. Otherwise then check // if it's still focused and then update active item and emit focus event. diff --git a/accessible/base/TextAttrs.cpp b/accessible/base/TextAttrs.cpp index 53cca870b9be..2cb6156373e7 100644 --- a/accessible/base/TextAttrs.cpp +++ b/accessible/base/TextAttrs.cpp @@ -37,13 +37,13 @@ TextAttrsMgr::GetAttributes(nsIPersistentProperties* aAttributes, // 3. Offset accessible and result hyper text offsets must not be specified // but include default text attributes flag and attributes list must be // specified in the case of default text attributes. - NS_PRECONDITION(mHyperTextAcc && - ((mOffsetAcc && mOffsetAccIdx != -1 && - aStartOffset && aEndOffset) || - (!mOffsetAcc && mOffsetAccIdx == -1 && - !aStartOffset && !aEndOffset && - mIncludeDefAttrs && aAttributes)), - "Wrong usage of TextAttrsMgr!"); + MOZ_ASSERT(mHyperTextAcc && + ((mOffsetAcc && mOffsetAccIdx != -1 && + aStartOffset && aEndOffset) || + (!mOffsetAcc && mOffsetAccIdx == -1 && + !aStartOffset && !aEndOffset && + mIncludeDefAttrs && aAttributes)), + "Wrong usage of TextAttrsMgr!"); // Embedded objects are combined into own range with empty attributes set. if (mOffsetAcc && !mOffsetAcc->IsText()) { diff --git a/accessible/generic/Accessible.cpp b/accessible/generic/Accessible.cpp index 627aa27db883..1d012ce59ec0 100644 --- a/accessible/generic/Accessible.cpp +++ b/accessible/generic/Accessible.cpp @@ -2356,7 +2356,7 @@ Accessible::IsLink() const uint32_t Accessible::StartOffset() { - NS_PRECONDITION(IsLink(), "StartOffset is called not on hyper link!"); + MOZ_ASSERT(IsLink(), "StartOffset is called not on hyper link!"); HyperTextAccessible* hyperText = mParent ? mParent->AsHyperText() : nullptr; return hyperText ? hyperText->GetChildOffset(this) : 0; @@ -2365,7 +2365,7 @@ Accessible::StartOffset() uint32_t Accessible::EndOffset() { - NS_PRECONDITION(IsLink(), "EndOffset is called on not hyper link!"); + MOZ_ASSERT(IsLink(), "EndOffset is called on not hyper link!"); HyperTextAccessible* hyperText = mParent ? mParent->AsHyperText() : nullptr; return hyperText ? (hyperText->GetChildOffset(this) + 1) : 0; @@ -2374,21 +2374,21 @@ Accessible::EndOffset() uint32_t Accessible::AnchorCount() { - NS_PRECONDITION(IsLink(), "AnchorCount is called on not hyper link!"); + MOZ_ASSERT(IsLink(), "AnchorCount is called on not hyper link!"); return 1; } Accessible* Accessible::AnchorAt(uint32_t aAnchorIndex) { - NS_PRECONDITION(IsLink(), "GetAnchor is called on not hyper link!"); + MOZ_ASSERT(IsLink(), "GetAnchor is called on not hyper link!"); return aAnchorIndex == 0 ? this : nullptr; } already_AddRefed Accessible::AnchorURIAt(uint32_t aAnchorIndex) { - NS_PRECONDITION(IsLink(), "AnchorURIAt is called on not hyper link!"); + MOZ_ASSERT(IsLink(), "AnchorURIAt is called on not hyper link!"); return nullptr; } diff --git a/accessible/generic/Accessible.h b/accessible/generic/Accessible.h index 54b9efed2e34..7da76a3ce3d9 100644 --- a/accessible/generic/Accessible.h +++ b/accessible/generic/Accessible.h @@ -743,7 +743,7 @@ public: */ inline bool IsLinkValid() { - NS_PRECONDITION(IsLink(), "IsLinkValid is called on not hyper link!"); + MOZ_ASSERT(IsLink(), "IsLinkValid is called on not hyper link!"); // XXX In order to implement this we would need to follow every link // Perhaps we can get information about invalid links from the cache diff --git a/accessible/mac/mozTextAccessible.mm b/accessible/mac/mozTextAccessible.mm index 0909cd5129b4..9ea11aa1a3a7 100644 --- a/accessible/mac/mozTextAccessible.mm +++ b/accessible/mac/mozTextAccessible.mm @@ -17,7 +17,7 @@ using namespace mozilla::a11y; inline bool ToNSRange(id aValue, NSRange* aRange) { - NS_PRECONDITION(aRange, "aRange is nil"); + MOZ_ASSERT(aRange, "aRange is nil"); if ([aValue isKindOfClass:[NSValue class]] && strcmp([(NSValue*)aValue objCType], @encode(NSRange)) == 0) { @@ -547,7 +547,7 @@ ToNSString(id aValue) - (NSString*)stringFromRange:(NSRange*)range { - NS_PRECONDITION(range, "no range"); + MOZ_ASSERT(range, "no range"); AccessibleWrap* accWrap = [self getGeckoAccessible]; ProxyAccessible* proxy = [self getProxyAccessible]; diff --git a/accessible/xpcom/xpcAccessibleSelectable.cpp b/accessible/xpcom/xpcAccessibleSelectable.cpp index 9910dc61c126..742311493969 100644 --- a/accessible/xpcom/xpcAccessibleSelectable.cpp +++ b/accessible/xpcom/xpcAccessibleSelectable.cpp @@ -19,7 +19,7 @@ xpcAccessibleSelectable::GetSelectedItems(nsIArray** aSelectedItems) if (!Intl()) return NS_ERROR_FAILURE; - NS_PRECONDITION(Intl()->IsSelect(), "Called on non selectable widget!"); + MOZ_ASSERT(Intl()->IsSelect(), "Called on non selectable widget!"); AutoTArray items; Intl()->SelectedItems(&items); @@ -48,7 +48,7 @@ xpcAccessibleSelectable::GetSelectedItemCount(uint32_t* aSelectionCount) if (!Intl()) return NS_ERROR_FAILURE; - NS_PRECONDITION(Intl()->IsSelect(), "Called on non selectable widget!"); + MOZ_ASSERT(Intl()->IsSelect(), "Called on non selectable widget!"); *aSelectionCount = Intl()->SelectedItemCount(); return NS_OK; @@ -63,7 +63,7 @@ xpcAccessibleSelectable::GetSelectedItemAt(uint32_t aIndex, if (!Intl()) return NS_ERROR_FAILURE; - NS_PRECONDITION(Intl()->IsSelect(), "Called on non selectable widget!"); + MOZ_ASSERT(Intl()->IsSelect(), "Called on non selectable widget!"); *aSelected = ToXPC(Intl()->GetSelectedItem(aIndex)); if (*aSelected) { @@ -82,7 +82,7 @@ xpcAccessibleSelectable::IsItemSelected(uint32_t aIndex, bool* aIsSelected) if (!Intl()) return NS_ERROR_FAILURE; - NS_PRECONDITION(Intl()->IsSelect(), "Called on non selectable widget!"); + MOZ_ASSERT(Intl()->IsSelect(), "Called on non selectable widget!"); *aIsSelected = Intl()->IsItemSelected(aIndex); return NS_OK; @@ -93,7 +93,7 @@ xpcAccessibleSelectable::AddItemToSelection(uint32_t aIndex) { if (!Intl()) return NS_ERROR_FAILURE; - NS_PRECONDITION(Intl()->IsSelect(), "Called on non selectable widget!"); + MOZ_ASSERT(Intl()->IsSelect(), "Called on non selectable widget!"); return Intl()->AddItemToSelection(aIndex) ? NS_OK : NS_ERROR_INVALID_ARG; } @@ -103,7 +103,7 @@ xpcAccessibleSelectable::RemoveItemFromSelection(uint32_t aIndex) { if (!Intl()) return NS_ERROR_FAILURE; - NS_PRECONDITION(Intl()->IsSelect(), "Called on non selectable widget!"); + MOZ_ASSERT(Intl()->IsSelect(), "Called on non selectable widget!"); return Intl()->RemoveItemFromSelection(aIndex) ? NS_OK : NS_ERROR_INVALID_ARG; } @@ -116,7 +116,7 @@ xpcAccessibleSelectable::SelectAll(bool* aIsMultiSelect) if (!Intl()) return NS_ERROR_FAILURE; - NS_PRECONDITION(Intl()->IsSelect(), "Called on non selectable widget!"); + MOZ_ASSERT(Intl()->IsSelect(), "Called on non selectable widget!"); *aIsMultiSelect = Intl()->SelectAll(); return NS_OK; @@ -127,7 +127,7 @@ xpcAccessibleSelectable::UnselectAll() { if (!Intl()) return NS_ERROR_FAILURE; - NS_PRECONDITION(Intl()->IsSelect(), "Called on non selectable widget!"); + MOZ_ASSERT(Intl()->IsSelect(), "Called on non selectable widget!"); Intl()->UnselectAll(); return NS_OK; diff --git a/accessible/xul/XULTreeGridAccessible.cpp b/accessible/xul/XULTreeGridAccessible.cpp index 56cdb21f7fec..1f8d90cc1877 100644 --- a/accessible/xul/XULTreeGridAccessible.cpp +++ b/accessible/xul/XULTreeGridAccessible.cpp @@ -371,7 +371,7 @@ XULTreeGridRowAccessible::ChildCount() const XULTreeGridCellAccessible* XULTreeGridRowAccessible::GetCellAccessible(nsITreeColumn* aColumn) const { - NS_PRECONDITION(aColumn, "No tree column!"); + MOZ_ASSERT(aColumn, "No tree column!"); void* key = static_cast(aColumn); XULTreeGridCellAccessible* cachedCell = mAccessibleCache.GetWeak(key); diff --git a/caps/ContentPrincipal.cpp b/caps/ContentPrincipal.cpp index a1f097e176a0..03ca5fea9963 100644 --- a/caps/ContentPrincipal.cpp +++ b/caps/ContentPrincipal.cpp @@ -330,7 +330,7 @@ ContentPrincipal::MayLoadInternal(nsIURI* aURI) NS_IMETHODIMP ContentPrincipal::GetHashValue(uint32_t* aValue) { - NS_PRECONDITION(mCodebase, "Need a codebase"); + MOZ_ASSERT(mCodebase, "Need a codebase"); *aValue = nsScriptSecurityManager::HashPrincipalByOrigin(this); return NS_OK; diff --git a/caps/nsJSPrincipals.cpp b/caps/nsJSPrincipals.cpp index 50fe96b70950..b042de33b746 100644 --- a/caps/nsJSPrincipals.cpp +++ b/caps/nsJSPrincipals.cpp @@ -28,7 +28,7 @@ NS_IMETHODIMP_(MozExternalRefCountType) nsJSPrincipals::AddRef() { MOZ_ASSERT(NS_IsMainThread()); - NS_PRECONDITION(int32_t(refcount) >= 0, "illegal refcnt"); + MOZ_ASSERT(int32_t(refcount) >= 0, "illegal refcnt"); nsrefcnt count = ++refcount; NS_LOG_ADDREF(this, count, "nsJSPrincipals", sizeof(*this)); return count; @@ -38,7 +38,7 @@ NS_IMETHODIMP_(MozExternalRefCountType) nsJSPrincipals::Release() { MOZ_ASSERT(NS_IsMainThread()); - NS_PRECONDITION(0 != refcount, "dup release"); + MOZ_ASSERT(0 != refcount, "dup release"); nsrefcnt count = --refcount; NS_LOG_RELEASE(this, count, "nsJSPrincipals"); if (count == 0) { diff --git a/caps/nsScriptSecurityManager.cpp b/caps/nsScriptSecurityManager.cpp index 56a0e5a31dce..32b885f07a32 100644 --- a/caps/nsScriptSecurityManager.cpp +++ b/caps/nsScriptSecurityManager.cpp @@ -260,7 +260,8 @@ nsScriptSecurityManager::GetChannelResultPrincipal(nsIChannel* aChannel, nsIPrincipal** aPrincipal, bool aIgnoreSandboxing) { - NS_PRECONDITION(aChannel, "Must have channel!"); + MOZ_ASSERT(aChannel, "Must have channel!"); + // Check whether we have an nsILoadInfo that says what we should do. nsCOMPtr loadInfo = aChannel->GetLoadInfo(); if (loadInfo && loadInfo->GetForceInheritPrincipalOverruleOwner()) { @@ -349,7 +350,7 @@ NS_IMETHODIMP nsScriptSecurityManager::GetChannelURIPrincipal(nsIChannel* aChannel, nsIPrincipal** aPrincipal) { - NS_PRECONDITION(aChannel, "Must have channel!"); + MOZ_ASSERT(aChannel, "Must have channel!"); // Get the principal from the URI. Make sure this does the same thing // as nsDocument::Reset and XULDocument::StartDocumentLoad. @@ -517,7 +518,7 @@ nsScriptSecurityManager::CheckLoadURIFromScript(JSContext *cx, nsIURI *aURI) static nsresult DenyAccessIfURIHasFlags(nsIURI* aURI, uint32_t aURIFlags) { - NS_PRECONDITION(aURI, "Must have URI!"); + MOZ_ASSERT(aURI, "Must have URI!"); bool uriHasFlags; nsresult rv = @@ -565,7 +566,8 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal, nsIURI *aTargetURI, uint32_t aFlags) { - NS_PRECONDITION(aPrincipal, "CheckLoadURIWithPrincipal must have a principal"); + MOZ_ASSERT(aPrincipal, "CheckLoadURIWithPrincipal must have a principal"); + // If someone passes a flag that we don't understand, we should // fail, because they may need a security check that we don't // provide. diff --git a/chrome/nsChromeProtocolHandler.cpp b/chrome/nsChromeProtocolHandler.cpp index e42744ae4f75..9dc0e842fb0c 100644 --- a/chrome/nsChromeProtocolHandler.cpp +++ b/chrome/nsChromeProtocolHandler.cpp @@ -113,7 +113,7 @@ nsChromeProtocolHandler::NewChannel2(nsIURI* aURI, NS_ENSURE_ARG_POINTER(aURI); NS_ENSURE_ARG_POINTER(aLoadInfo); - NS_PRECONDITION(aResult, "Null out param"); + MOZ_ASSERT(aResult, "Null out param"); #ifdef DEBUG // Check that the uri we got is already canonified diff --git a/docshell/base/nsDSURIContentListener.cpp b/docshell/base/nsDSURIContentListener.cpp index 0a099ca2c306..9a4df15431c8 100644 --- a/docshell/base/nsDSURIContentListener.cpp +++ b/docshell/base/nsDSURIContentListener.cpp @@ -261,7 +261,7 @@ nsDSURIContentListener::CanHandleContent(const char* aContentType, char** aDesiredContentType, bool* aCanHandleContent) { - NS_PRECONDITION(aCanHandleContent, "Null out param?"); + MOZ_ASSERT(aCanHandleContent, "Null out param?"); NS_ENSURE_ARG_POINTER(aDesiredContentType); *aCanHandleContent = false; diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index e58a60cceb2f..8185f00cf179 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -537,7 +537,7 @@ NS_INTERFACE_MAP_END_INHERITING(nsDocLoader) NS_IMETHODIMP nsDocShell::GetInterface(const nsIID& aIID, void** aSink) { - NS_PRECONDITION(aSink, "null out param"); + MOZ_ASSERT(aSink, "null out param"); *aSink = nullptr; @@ -668,9 +668,9 @@ nsDocShell::LoadURI(nsIURI* aURI, uint32_t aLoadFlags, bool aFirstParty) { - NS_PRECONDITION(aLoadInfo || (aLoadFlags & EXTRA_LOAD_FLAGS) == 0, - "Unexpected flags"); - NS_PRECONDITION((aLoadFlags & 0xf) == 0, "Should not have these flags set"); + MOZ_ASSERT(aLoadInfo || (aLoadFlags & EXTRA_LOAD_FLAGS) == 0, + "Unexpected flags"); + MOZ_ASSERT((aLoadFlags & 0xf) == 0, "Should not have these flags set"); // Note: we allow loads to get through here even if mFiredUnloadEvent is // true; that case will get handled in LoadInternal or LoadHistoryEntry, @@ -3127,7 +3127,7 @@ nsDocShell::CanAccessItem(nsIDocShellTreeItem* aTargetItem, nsIDocShellTreeItem* aAccessingItem, bool aConsiderOpener) { - NS_PRECONDITION(aTargetItem, "Must have target item!"); + MOZ_ASSERT(aTargetItem, "Must have target item!"); if (!gValidateOrigin || !aAccessingItem) { // Good to go @@ -5291,7 +5291,7 @@ nsDocShell::LoadPage(nsISupports* aPageDescriptor, uint32_t aDisplayType) NS_IMETHODIMP nsDocShell::GetCurrentDescriptor(nsISupports** aPageDescriptor) { - NS_PRECONDITION(aPageDescriptor, "Null out param?"); + MOZ_ASSERT(aPageDescriptor, "Null out param?"); *aPageDescriptor = nullptr; @@ -6345,7 +6345,7 @@ nsDocShell::ForceRefreshURIFromTimer(nsIURI* aURI, bool aMetaRefresh, nsITimer* aTimer) { - NS_PRECONDITION(aTimer, "Must have a timer here"); + MOZ_ASSERT(aTimer, "Must have a timer here"); // Remove aTimer from mRefreshURIList if needed if (mRefreshURIList) { @@ -9758,8 +9758,8 @@ nsDocShell::InternalLoad(nsIURI* aURI, if (mFiredUnloadEvent) { if (IsOKToLoadURI(aURI)) { - NS_PRECONDITION(aWindowTarget.IsEmpty(), - "Shouldn't have a window target here!"); + MOZ_ASSERT(aWindowTarget.IsEmpty(), + "Shouldn't have a window target here!"); // If this is a replace load, make whatever load triggered // the unload event also a replace load, so we don't @@ -11340,8 +11340,8 @@ nsDocShell::OnNewURI(nsIURI* aURI, nsIChannel* aChannel, uint32_t aLoadType, bool aFireOnLocationChange, bool aAddToGlobalHistory, bool aCloneSHChildren) { - NS_PRECONDITION(aURI, "uri is null"); - NS_PRECONDITION(!aChannel || !aTriggeringPrincipal, "Shouldn't have both set"); + MOZ_ASSERT(aURI, "uri is null"); + MOZ_ASSERT(!aChannel || !aTriggeringPrincipal, "Shouldn't have both set"); MOZ_ASSERT(!aPrincipalToInherit || (aPrincipalToInherit && aTriggeringPrincipal)); @@ -11992,8 +11992,8 @@ nsDocShell::AddToSessionHistory(nsIURI* aURI, nsIChannel* aChannel, bool aCloneChildren, nsISHEntry** aNewEntry) { - NS_PRECONDITION(aURI, "uri is null"); - NS_PRECONDITION(!aChannel || !aTriggeringPrincipal, "Shouldn't have both set"); + MOZ_ASSERT(aURI, "uri is null"); + MOZ_ASSERT(!aChannel || !aTriggeringPrincipal, "Shouldn't have both set"); #if defined(DEBUG) if (MOZ_LOG_TEST(gDocShellLog, LogLevel::Debug)) { @@ -13153,7 +13153,7 @@ nsDocShell::GetIsContent(bool* aIsContent) bool nsDocShell::IsOKToLoadURI(nsIURI* aURI) { - NS_PRECONDITION(aURI, "Must have a URI!"); + MOZ_ASSERT(aURI, "Must have a URI!"); if (!mFiredUnloadEvent) { return true; diff --git a/docshell/base/nsWebNavigationInfo.cpp b/docshell/base/nsWebNavigationInfo.cpp index b9448a91054d..c7cf4949d87b 100644 --- a/docshell/base/nsWebNavigationInfo.cpp +++ b/docshell/base/nsWebNavigationInfo.cpp @@ -31,7 +31,7 @@ nsWebNavigationInfo::IsTypeSupported(const nsACString& aType, nsIWebNavigation* aWebNav, uint32_t* aIsTypeSupported) { - NS_PRECONDITION(aIsTypeSupported, "null out param?"); + MOZ_ASSERT(aIsTypeSupported, "null out param?"); // Note to self: aWebNav could be an nsWebBrowser or an nsDocShell here (or // an nsSHistory, but not much we can do with that). So if we start using @@ -94,7 +94,7 @@ nsresult nsWebNavigationInfo::IsTypeSupportedInternal(const nsCString& aType, uint32_t* aIsSupported) { - NS_PRECONDITION(aIsSupported, "Null out param?"); + MOZ_ASSERT(aIsSupported, "Null out param?"); nsContentUtils::ContentViewerType vtype = nsContentUtils::TYPE_UNSUPPORTED; diff --git a/docshell/build/nsDocShellModule.cpp b/docshell/build/nsDocShellModule.cpp index 8a17bd814ff1..a98ed6716ecd 100644 --- a/docshell/build/nsDocShellModule.cpp +++ b/docshell/build/nsDocShellModule.cpp @@ -53,7 +53,7 @@ static bool gInitialized = false; static nsresult Initialize() { - NS_PRECONDITION(!gInitialized, "docshell module already initialized"); + MOZ_ASSERT(!gInitialized, "docshell module already initialized"); if (gInitialized) { return NS_OK; } diff --git a/docshell/shistory/nsSHEntryShared.cpp b/docshell/shistory/nsSHEntryShared.cpp index ddb180ca5d13..acf8612510f7 100644 --- a/docshell/shistory/nsSHEntryShared.cpp +++ b/docshell/shistory/nsSHEntryShared.cpp @@ -139,8 +139,8 @@ nsSHEntryShared::DropPresentationState() nsresult nsSHEntryShared::SetContentViewer(nsIContentViewer* aViewer) { - NS_PRECONDITION(!aViewer || !mContentViewer, - "SHEntryShared already contains viewer"); + MOZ_ASSERT(!aViewer || !mContentViewer, + "SHEntryShared already contains viewer"); if (mContentViewer || !aViewer) { DropPresentationState(); diff --git a/docshell/shistory/nsSHistory.cpp b/docshell/shistory/nsSHistory.cpp index 58adbb27fd5b..74f010181d92 100644 --- a/docshell/shistory/nsSHistory.cpp +++ b/docshell/shistory/nsSHistory.cpp @@ -689,7 +689,7 @@ nsSHistory::GetCount(int32_t* aResult) NS_IMETHODIMP nsSHistory::GetIndex(int32_t* aResult) { - NS_PRECONDITION(aResult, "null out param?"); + MOZ_ASSERT(aResult, "null out param?"); *aResult = mIndex; return NS_OK; } @@ -698,7 +698,7 @@ nsSHistory::GetIndex(int32_t* aResult) NS_IMETHODIMP nsSHistory::GetRequestedIndex(int32_t* aResult) { - NS_PRECONDITION(aResult, "null out param?"); + MOZ_ASSERT(aResult, "null out param?"); *aResult = mRequestedIndex; return NS_OK; } diff --git a/dom/base/CharacterData.cpp b/dom/base/CharacterData.cpp index 2f69c789ae1a..c4a5160ff34a 100644 --- a/dom/base/CharacterData.cpp +++ b/dom/base/CharacterData.cpp @@ -66,8 +66,8 @@ CharacterData::CharacterData(already_AddRefed&& aNodeInfo) CharacterData::~CharacterData() { - NS_PRECONDITION(!IsInUncomposedDoc(), - "Please remove this from the document properly"); + MOZ_ASSERT(!IsInUncomposedDoc(), + "Please remove this from the document properly"); if (GetParent()) { NS_RELEASE(mParent); } @@ -246,8 +246,8 @@ CharacterData::SetTextInternal(uint32_t aOffset, uint32_t aCount, uint32_t aLength, bool aNotify, CharacterDataChangeInfo::Details* aDetails) { - NS_PRECONDITION(aBuffer || !aLength, - "Null buffer passed to SetTextInternal!"); + MOZ_ASSERT(aBuffer || !aLength, + "Null buffer passed to SetTextInternal!"); // sanitize arguments uint32_t textLength = mText.GetLength(); @@ -446,28 +446,28 @@ CharacterData::BindToTree(nsIDocument* aDocument, nsIContent* aParent, nsIContent* aBindingParent, bool aCompileEventHandlers) { - NS_PRECONDITION(aParent || aDocument, "Must have document if no parent!"); - NS_PRECONDITION(NODE_FROM(aParent, aDocument)->OwnerDoc() == OwnerDoc(), - "Must have the same owner document"); - NS_PRECONDITION(!aParent || aDocument == aParent->GetUncomposedDoc(), - "aDocument must be current doc of aParent"); - NS_PRECONDITION(!GetUncomposedDoc() && !IsInUncomposedDoc(), - "Already have a document. Unbind first!"); + MOZ_ASSERT(aParent || aDocument, "Must have document if no parent!"); + MOZ_ASSERT(NODE_FROM(aParent, aDocument)->OwnerDoc() == OwnerDoc(), + "Must have the same owner document"); + MOZ_ASSERT(!aParent || aDocument == aParent->GetUncomposedDoc(), + "aDocument must be current doc of aParent"); + MOZ_ASSERT(!GetUncomposedDoc() && !IsInUncomposedDoc(), + "Already have a document. Unbind first!"); // Note that as we recurse into the kids, they'll have a non-null parent. So // only assert if our parent is _changing_ while we have a parent. - NS_PRECONDITION(!GetParent() || aParent == GetParent(), - "Already have a parent. Unbind first!"); - NS_PRECONDITION(!GetBindingParent() || - aBindingParent == GetBindingParent() || - (!aBindingParent && aParent && - aParent->GetBindingParent() == GetBindingParent()), - "Already have a binding parent. Unbind first!"); - NS_PRECONDITION(aBindingParent != this, - "Content must not be its own binding parent"); - NS_PRECONDITION(!IsRootOfNativeAnonymousSubtree() || - aBindingParent == aParent, - "Native anonymous content must have its parent as its " - "own binding parent"); + MOZ_ASSERT(!GetParent() || aParent == GetParent(), + "Already have a parent. Unbind first!"); + MOZ_ASSERT(!GetBindingParent() || + aBindingParent == GetBindingParent() || + (!aBindingParent && aParent && + aParent->GetBindingParent() == GetBindingParent()), + "Already have a binding parent. Unbind first!"); + MOZ_ASSERT(aBindingParent != this, + "Content must not be its own binding parent"); + MOZ_ASSERT(!IsRootOfNativeAnonymousSubtree() || + aBindingParent == aParent, + "Native anonymous content must have its parent as its " + "own binding parent"); if (!aBindingParent && aParent) { aBindingParent = aParent->GetBindingParent(); diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp index 7c1078f92d62..57e5bcc906e7 100644 --- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -1534,30 +1534,30 @@ Element::BindToTree(nsIDocument* aDocument, nsIContent* aParent, nsIContent* aBindingParent, bool aCompileEventHandlers) { - NS_PRECONDITION(aParent || aDocument, "Must have document if no parent!"); - NS_PRECONDITION((NODE_FROM(aParent, aDocument)->OwnerDoc() == OwnerDoc()), - "Must have the same owner document"); - NS_PRECONDITION(!aParent || aDocument == aParent->GetUncomposedDoc(), - "aDocument must be current doc of aParent"); - NS_PRECONDITION(!GetUncomposedDoc(), "Already have a document. Unbind first!"); + MOZ_ASSERT(aParent || aDocument, "Must have document if no parent!"); + MOZ_ASSERT((NODE_FROM(aParent, aDocument)->OwnerDoc() == OwnerDoc()), + "Must have the same owner document"); + MOZ_ASSERT(!aParent || aDocument == aParent->GetUncomposedDoc(), + "aDocument must be current doc of aParent"); + MOZ_ASSERT(!GetUncomposedDoc(), "Already have a document. Unbind first!"); // Note that as we recurse into the kids, they'll have a non-null parent. So // only assert if our parent is _changing_ while we have a parent. - NS_PRECONDITION(!GetParent() || aParent == GetParent(), - "Already have a parent. Unbind first!"); - NS_PRECONDITION(!GetBindingParent() || - aBindingParent == GetBindingParent() || - (!aBindingParent && aParent && - aParent->GetBindingParent() == GetBindingParent()), - "Already have a binding parent. Unbind first!"); - NS_PRECONDITION(aBindingParent != this, - "Content must not be its own binding parent"); - NS_PRECONDITION(!IsRootOfNativeAnonymousSubtree() || - aBindingParent == aParent, - "Native anonymous content must have its parent as its " - "own binding parent"); - NS_PRECONDITION(aBindingParent || !aParent || - aBindingParent == aParent->GetBindingParent(), - "We should be passed the right binding parent"); + MOZ_ASSERT(!GetParent() || aParent == GetParent(), + "Already have a parent. Unbind first!"); + MOZ_ASSERT(!GetBindingParent() || + aBindingParent == GetBindingParent() || + (!aBindingParent && aParent && + aParent->GetBindingParent() == GetBindingParent()), + "Already have a binding parent. Unbind first!"); + MOZ_ASSERT(aBindingParent != this, + "Content must not be its own binding parent"); + MOZ_ASSERT(!IsRootOfNativeAnonymousSubtree() || + aBindingParent == aParent, + "Native anonymous content must have its parent as its " + "own binding parent"); + MOZ_ASSERT(aBindingParent || !aParent || + aBindingParent == aParent->GetBindingParent(), + "We should be passed the right binding parent"); #ifdef MOZ_XUL // First set the binding parent @@ -1841,7 +1841,7 @@ RemoveFromBindingManagerRunnable::Run() void Element::UnbindFromTree(bool aDeep, bool aNullParent) { - NS_PRECONDITION(aDeep || (!GetUncomposedDoc() && !GetBindingParent()), + MOZ_ASSERT(aDeep || (!GetUncomposedDoc() && !GetBindingParent()), "Shallow unbind won't clear document and binding parent on " "kids!"); @@ -2218,9 +2218,9 @@ Element::DispatchEvent(nsPresContext* aPresContext, bool aFullDispatch, nsEventStatus* aStatus) { - NS_PRECONDITION(aTarget, "Must have target"); - NS_PRECONDITION(aEvent, "Must have source event"); - NS_PRECONDITION(aStatus, "Null out param?"); + MOZ_ASSERT(aTarget, "Must have target"); + MOZ_ASSERT(aEvent, "Must have source event"); + MOZ_ASSERT(aStatus, "Null out param?"); if (!aPresContext) { return NS_OK; @@ -2247,9 +2247,9 @@ Element::DispatchClickEvent(nsPresContext* aPresContext, const EventFlags* aExtraEventFlags, nsEventStatus* aStatus) { - NS_PRECONDITION(aTarget, "Must have target"); - NS_PRECONDITION(aSourceEvent, "Must have source event"); - NS_PRECONDITION(aStatus, "Null out param?"); + MOZ_ASSERT(aTarget, "Must have target"); + MOZ_ASSERT(aSourceEvent, "Must have source event"); + MOZ_ASSERT(aStatus, "Null out param?"); WidgetMouseEvent event(aSourceEvent->IsTrusted(), eMouseClick, aSourceEvent->mWidget, WidgetMouseEvent::eReal); @@ -2322,7 +2322,7 @@ Element::SetEventHandler(nsAtom* aEventName, return NS_OK; } - NS_PRECONDITION(aEventName, "Must have event name!"); + MOZ_ASSERT(aEventName, "Must have event name!"); bool defer = true; EventListenerManager* manager = GetEventListenerManagerForAttr(aEventName, &defer); diff --git a/dom/base/Element.h b/dom/base/Element.h index 8cf632e0f8ab..1a3497a0476d 100644 --- a/dom/base/Element.h +++ b/dom/base/Element.h @@ -603,22 +603,22 @@ protected: // those in EXTERNALLY_MANAGED_STATES. virtual void AddStates(EventStates aStates) { - NS_PRECONDITION(!aStates.HasAtLeastOneOfStates(INTRINSIC_STATES), - "Should only be adding externally-managed states here"); + MOZ_ASSERT(!aStates.HasAtLeastOneOfStates(INTRINSIC_STATES), + "Should only be adding externally-managed states here"); AddStatesSilently(aStates); NotifyStateChange(aStates); } virtual void RemoveStates(EventStates aStates) { - NS_PRECONDITION(!aStates.HasAtLeastOneOfStates(INTRINSIC_STATES), - "Should only be removing externally-managed states here"); + MOZ_ASSERT(!aStates.HasAtLeastOneOfStates(INTRINSIC_STATES), + "Should only be removing externally-managed states here"); RemoveStatesSilently(aStates); NotifyStateChange(aStates); } virtual void ToggleStates(EventStates aStates, bool aNotify) { - NS_PRECONDITION(!aStates.HasAtLeastOneOfStates(INTRINSIC_STATES), - "Should only be removing externally-managed states here"); + MOZ_ASSERT(!aStates.HasAtLeastOneOfStates(INTRINSIC_STATES), + "Should only be removing externally-managed states here"); mState ^= aStates; if (aNotify) { NotifyStateChange(aStates); diff --git a/dom/base/EventSource.cpp b/dom/base/EventSource.cpp index 57a4d4775531..59d0ac1e43bb 100644 --- a/dom/base/EventSource.cpp +++ b/dom/base/EventSource.cpp @@ -835,12 +835,12 @@ EventSourceImpl::AsyncOnChannelRedirect(nsIChannel* aOldChannel, return NS_ERROR_ABORT; } nsCOMPtr aOldRequest = do_QueryInterface(aOldChannel); - NS_PRECONDITION(aOldRequest, "Redirect from a null request?"); + MOZ_ASSERT(aOldRequest, "Redirect from a null request?"); nsresult rv = CheckHealthOfRequestCallback(aOldRequest); NS_ENSURE_SUCCESS(rv, rv); - NS_PRECONDITION(aNewChannel, "Redirect without a channel?"); + MOZ_ASSERT(aNewChannel, "Redirect without a channel?"); nsCOMPtr newURI; rv = NS_GetFinalChannelURI(aNewChannel, getter_AddRefs(newURI)); @@ -1373,8 +1373,7 @@ EventSourceImpl::TimerCallback(nsITimer* aTimer, void* aClosure) return; } - NS_PRECONDITION(!thisObject->mHttpChannel, - "the channel hasn't been cancelled!!"); + MOZ_ASSERT(!thisObject->mHttpChannel, "the channel hasn't been cancelled!!"); if (!thisObject->IsFrozen()) { nsresult rv = thisObject->InitChannelAndRequestEventSource(); diff --git a/dom/base/FragmentOrElement.cpp b/dom/base/FragmentOrElement.cpp index 372788bb41e6..6cf38c7a6eb5 100644 --- a/dom/base/FragmentOrElement.cpp +++ b/dom/base/FragmentOrElement.cpp @@ -814,8 +814,8 @@ FragmentOrElement::FragmentOrElement(already_AddRefed&& FragmentOrElement::~FragmentOrElement() { - NS_PRECONDITION(!IsInUncomposedDoc(), - "Please remove this from the document properly"); + MOZ_ASSERT(!IsInUncomposedDoc(), + "Please remove this from the document properly"); if (GetParent()) { NS_RELEASE(mParent); } @@ -1187,7 +1187,7 @@ FragmentOrElement::InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis, bool aNotify) { - NS_PRECONDITION(aKid, "null ptr"); + MOZ_ASSERT(aKid, "null ptr"); int32_t index = aBeforeThis ? ComputeIndexOf(aBeforeThis) : GetChildCount(); MOZ_ASSERT(index >= 0); @@ -1200,7 +1200,7 @@ FragmentOrElement::InsertChildAt_Deprecated(nsIContent* aKid, uint32_t aIndex, bool aNotify) { - NS_PRECONDITION(aKid, "null ptr"); + MOZ_ASSERT(aKid, "null ptr"); return doInsertChildAt(aKid, aIndex, aNotify, mAttrsAndChildren); } diff --git a/dom/base/IDTracker.h b/dom/base/IDTracker.h index c431c9d2686b..4eff1514f5d8 100644 --- a/dom/base/IDTracker.h +++ b/dom/base/IDTracker.h @@ -122,7 +122,7 @@ private: explicit Notification(IDTracker* aTarget) : mTarget(aTarget) { - NS_PRECONDITION(aTarget, "Must have a target"); + MOZ_ASSERT(aTarget, "Must have a target"); } IDTracker* mTarget; }; diff --git a/dom/base/Selection.cpp b/dom/base/Selection.cpp index 7138f7324772..a86454bb5bcd 100644 --- a/dom/base/Selection.cpp +++ b/dom/base/Selection.cpp @@ -2122,7 +2122,7 @@ nsresult Selection::StartAutoScrollTimer(nsIFrame* aFrame, const nsPoint& aPoint, uint32_t aDelay) { - NS_PRECONDITION(aFrame, "Need a frame"); + MOZ_ASSERT(aFrame, "Need a frame"); nsresult result; if (!mFrameSelection) { @@ -2160,7 +2160,7 @@ Selection::StopAutoScrollTimer() nsresult Selection::DoAutoScroll(nsIFrame* aFrame, nsPoint aPoint) { - NS_PRECONDITION(aFrame, "Need a frame"); + MOZ_ASSERT(aFrame, "Need a frame"); if (mAutoScrollTimer) { (void)mAutoScrollTimer->Stop(); diff --git a/dom/base/nsAttrAndChildArray.cpp b/dom/base/nsAttrAndChildArray.cpp index cd3477c59395..6e3cb148cb5a 100644 --- a/dom/base/nsAttrAndChildArray.cpp +++ b/dom/base/nsAttrAndChildArray.cpp @@ -614,7 +614,7 @@ nsAttrAndChildArray::SetAndSwapMappedAttr(nsAtom* aLocalName, nsresult nsAttrAndChildArray::DoSetMappedAttrStyleSheet(nsHTMLStyleSheet* aSheet) { - NS_PRECONDITION(mImpl && mImpl->mMappedAttrs, + MOZ_ASSERT(mImpl && mImpl->mMappedAttrs, "Should have mapped attrs here!"); if (aSheet == mImpl->mMappedAttrs->GetStyleSheet()) { return NS_OK; @@ -800,7 +800,7 @@ nsAttrAndChildArray::GetMapped() const nsresult nsAttrAndChildArray::EnsureCapacityToClone(const nsAttrAndChildArray& aOther, bool aAllocateChildren) { - NS_PRECONDITION(!mImpl, "nsAttrAndChildArray::EnsureCapacityToClone requires the array be empty when called"); + MOZ_ASSERT(!mImpl, "nsAttrAndChildArray::EnsureCapacityToClone requires the array be empty when called"); uint32_t attrCount = aOther.NonMappedAttrCount(); uint32_t childCount = 0; @@ -930,8 +930,8 @@ inline void nsAttrAndChildArray::SetChildAtPos(void** aPos, nsIContent* aChild, uint32_t aIndex, uint32_t aChildCount) { - NS_PRECONDITION(!aChild->GetNextSibling(), "aChild with next sibling?"); - NS_PRECONDITION(!aChild->GetPreviousSibling(), "aChild with prev sibling?"); + MOZ_ASSERT(!aChild->GetNextSibling(), "aChild with next sibling?"); + MOZ_ASSERT(!aChild->GetPreviousSibling(), "aChild with prev sibling?"); *aPos = aChild; NS_ADDREF(aChild); @@ -965,4 +965,3 @@ nsAttrAndChildArray::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) co return n; } - diff --git a/dom/base/nsAttrAndChildArray.h b/dom/base/nsAttrAndChildArray.h index 19c34a9630aa..6447d1969ae6 100644 --- a/dom/base/nsAttrAndChildArray.h +++ b/dom/base/nsAttrAndChildArray.h @@ -184,7 +184,7 @@ private: bool AttrSlotIsTaken(uint32_t aSlot) const { - NS_PRECONDITION(aSlot < AttrSlotCount(), "out-of-bounds"); + MOZ_ASSERT(aSlot < AttrSlotCount(), "out-of-bounds"); return mImpl->mBuffer[aSlot * ATTRSIZE]; } diff --git a/dom/base/nsAttrValue.cpp b/dom/base/nsAttrValue.cpp index 3ac6d763a327..46f174485e7b 100644 --- a/dom/base/nsAttrValue.cpp +++ b/dom/base/nsAttrValue.cpp @@ -737,7 +737,7 @@ nsAttrValue::GetAsAtom() const const nsCheapString nsAttrValue::GetStringValue() const { - NS_PRECONDITION(Type() == eString, "wrong type"); + MOZ_ASSERT(Type() == eString, "wrong type"); return nsCheapString(static_cast(GetPtr())); } @@ -758,7 +758,7 @@ nsAttrValue::GetColorValue(nscolor& aColor) const void nsAttrValue::GetEnumString(nsAString& aResult, bool aRealTag) const { - NS_PRECONDITION(Type() == eEnum, "wrong type"); + MOZ_ASSERT(Type() == eEnum, "wrong type"); uint32_t allEnumBits = (BaseType() == eIntegerBase) ? static_cast(GetIntInternal()) @@ -800,8 +800,8 @@ nsAttrValue::GetAtomCount() const nsAtom* nsAttrValue::AtomAt(int32_t aIndex) const { - NS_PRECONDITION(aIndex >= 0, "Index must not be negative"); - NS_PRECONDITION(GetAtomCount() > uint32_t(aIndex), "aIndex out of range"); + MOZ_ASSERT(aIndex >= 0, "Index must not be negative"); + MOZ_ASSERT(GetAtomCount() > uint32_t(aIndex), "aIndex out of range"); if (BaseType() == eAtomBase) { return GetAtomValue(); @@ -1400,8 +1400,8 @@ nsAttrValue::ParseEnumValue(const nsAString& aValue, } if (aDefaultValue) { - NS_PRECONDITION(aTable <= aDefaultValue && aDefaultValue < tableEntry, - "aDefaultValue not inside aTable?"); + MOZ_ASSERT(aTable <= aDefaultValue && aDefaultValue < tableEntry, + "aDefaultValue not inside aTable?"); SetIntValueAndType(EnumTableEntryToValue(aTable, aDefaultValue), eEnum, &aValue); return true; @@ -1443,7 +1443,7 @@ bool nsAttrValue::ParseIntWithBounds(const nsAString& aString, int32_t aMin, int32_t aMax) { - NS_PRECONDITION(aMin < aMax, "bad boundaries"); + MOZ_ASSERT(aMin < aMax, "bad boundaries"); ResetIfSet(); @@ -1965,4 +1965,3 @@ nsAttrValue::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const return n; } - diff --git a/dom/base/nsAttrValueInlines.h b/dom/base/nsAttrValueInlines.h index f11a419024dc..6da96892ed91 100644 --- a/dom/base/nsAttrValueInlines.h +++ b/dom/base/nsAttrValueInlines.h @@ -128,7 +128,7 @@ public: inline int32_t nsAttrValue::GetIntegerValue() const { - NS_PRECONDITION(Type() == eInteger, "wrong type"); + MOZ_ASSERT(Type() == eInteger, "wrong type"); return (BaseType() == eIntegerBase) ? GetIntInternal() : GetMiscContainer()->mValue.mInteger; @@ -137,7 +137,7 @@ nsAttrValue::GetIntegerValue() const inline int16_t nsAttrValue::GetEnumValue() const { - NS_PRECONDITION(Type() == eEnum, "wrong type"); + MOZ_ASSERT(Type() == eEnum, "wrong type"); // We don't need to worry about sign extension here since we're // returning an int16_t which will cut away the top bits. return static_cast(( @@ -150,7 +150,7 @@ nsAttrValue::GetEnumValue() const inline float nsAttrValue::GetPercentValue() const { - NS_PRECONDITION(Type() == ePercent, "wrong type"); + MOZ_ASSERT(Type() == ePercent, "wrong type"); return ((BaseType() == eIntegerBase) ? GetIntInternal() : GetMiscContainer()->mValue.mPercent) @@ -160,35 +160,35 @@ nsAttrValue::GetPercentValue() const inline mozilla::AtomArray* nsAttrValue::GetAtomArrayValue() const { - NS_PRECONDITION(Type() == eAtomArray, "wrong type"); + MOZ_ASSERT(Type() == eAtomArray, "wrong type"); return GetMiscContainer()->mValue.mAtomArray; } inline mozilla::DeclarationBlock* nsAttrValue::GetCSSDeclarationValue() const { - NS_PRECONDITION(Type() == eCSSDeclaration, "wrong type"); + MOZ_ASSERT(Type() == eCSSDeclaration, "wrong type"); return GetMiscContainer()->mValue.mCSSDeclaration; } inline nsIURI* nsAttrValue::GetURLValue() const { - NS_PRECONDITION(Type() == eURL, "wrong type"); + MOZ_ASSERT(Type() == eURL, "wrong type"); return GetMiscContainer()->mValue.mURL; } inline double nsAttrValue::GetDoubleValue() const { - NS_PRECONDITION(Type() == eDoubleValue, "wrong type"); + MOZ_ASSERT(Type() == eDoubleValue, "wrong type"); return GetMiscContainer()->mDoubleValue; } inline bool nsAttrValue::GetIntMarginValue(nsIntMargin& aMargin) const { - NS_PRECONDITION(Type() == eIntMarginValue, "wrong type"); + MOZ_ASSERT(Type() == eIntMarginValue, "wrong type"); nsIntMargin* m = GetMiscContainer()->mValue.mIntMargin; if (!m) return false; @@ -269,7 +269,7 @@ nsAttrValue::Type() const inline nsAtom* nsAttrValue::GetAtomValue() const { - NS_PRECONDITION(Type() == eAtom, "wrong type"); + MOZ_ASSERT(Type() == eAtom, "wrong type"); return reinterpret_cast(GetPtr()); } diff --git a/dom/base/nsContentAreaDragDrop.cpp b/dom/base/nsContentAreaDragDrop.cpp index 88c1f2389ac3..05081b964974 100644 --- a/dom/base/nsContentAreaDragDrop.cpp +++ b/dom/base/nsContentAreaDragDrop.cpp @@ -542,8 +542,8 @@ DragDataProducer::Produce(DataTransfer* aDataTransfer, nsIContent** aDragNode, nsACString& aPrincipalURISpec) { - NS_PRECONDITION(aCanDrag && aSelection && aDataTransfer && aDragNode, - "null pointer passed to Produce"); + MOZ_ASSERT(aCanDrag && aSelection && aDataTransfer && aDragNode, + "null pointer passed to Produce"); NS_ASSERTION(mWindow, "window not set"); NS_ASSERTION(mSelectionTargetNode, "selection target node should have been set"); diff --git a/dom/base/nsContentList.cpp b/dom/base/nsContentList.cpp index 6c662fa1b88f..63c2909695b0 100644 --- a/dom/base/nsContentList.cpp +++ b/dom/base/nsContentList.cpp @@ -628,7 +628,7 @@ nsContentList::AttributeChanged(Element* aElement, int32_t aModType, const nsAttrValue* aOldValue) { - NS_PRECONDITION(aElement, "Must have a content node to work with"); + MOZ_ASSERT(aElement, "Must have a content node to work with"); if (!mFunc || !mFuncMayDependOnAttr || mState == LIST_DIRTY || !MayContainRelevantNodes(aElement->GetParentNode()) || @@ -658,7 +658,7 @@ void nsContentList::ContentAppended(nsIContent* aFirstNewContent) { nsIContent* container = aFirstNewContent->GetParent(); - NS_PRECONDITION(container, "Can't get at the new content if no container!"); + MOZ_ASSERT(container, "Can't get at the new content if no container!"); /* * If the state is LIST_DIRTY then we have no useful information in our list @@ -827,9 +827,9 @@ nsContentList::Match(Element *aElement) bool nsContentList::MatchSelf(nsIContent *aContent) { - NS_PRECONDITION(aContent, "Can't match null stuff, you know"); - NS_PRECONDITION(mDeep || aContent->GetParentNode() == mRootNode, - "MatchSelf called on a node that we can't possibly match"); + MOZ_ASSERT(aContent, "Can't match null stuff, you know"); + MOZ_ASSERT(mDeep || aContent->GetParentNode() == mRootNode, + "MatchSelf called on a node that we can't possibly match"); if (!aContent->IsElement()) { return false; diff --git a/dom/base/nsContentList.h b/dom/base/nsContentList.h index 6e47026cee17..542284532c67 100644 --- a/dom/base/nsContentList.h +++ b/dom/base/nsContentList.h @@ -387,8 +387,8 @@ public: // most common namespace id is kNameSpaceID_Unknown. So check the // string first. Cases in which whether our root's ownerDocument // is HTML changes are extremely rare, so check those last. - NS_PRECONDITION(mXMLMatchAtom, - "How did we get here with a null match atom on our list?"); + MOZ_ASSERT(mXMLMatchAtom, + "How did we get here with a null match atom on our list?"); return mXMLMatchAtom->Equals(aKey.mTagname) && mRootNode == aKey.mRootNode && diff --git a/dom/base/nsContentPolicy.cpp b/dom/base/nsContentPolicy.cpp index 859018a23f24..9c338b0526ad 100644 --- a/dom/base/nsContentPolicy.cpp +++ b/dom/base/nsContentPolicy.cpp @@ -88,7 +88,7 @@ nsContentPolicy::CheckPolicy(CPMethod policyMethod, } //sanity-check passed-through parameters - NS_PRECONDITION(decision, "Null out pointer"); + MOZ_ASSERT(decision, "Null out pointer"); WARN_IF_URI_UNINITIALIZED(contentLocation, "Request URI"); WARN_IF_URI_UNINITIALIZED(requestingLocation, "Requesting URI"); @@ -208,7 +208,7 @@ nsContentPolicy::ShouldLoad(nsIURI *contentLocation, int16_t *decision) { // ShouldProcess does not need a content location, but we do - NS_PRECONDITION(contentLocation, "Must provide request location"); + MOZ_ASSERT(contentLocation, "Must provide request location"); nsresult rv = CheckPolicy(&nsIContentPolicy::ShouldLoad, contentLocation, loadInfo, mimeType, decision); diff --git a/dom/base/nsContentSink.cpp b/dom/base/nsContentSink.cpp index 6e8fa1fa5fae..33d4436ba1e3 100644 --- a/dom/base/nsContentSink.cpp +++ b/dom/base/nsContentSink.cpp @@ -195,8 +195,8 @@ nsContentSink::Init(nsIDocument* aDoc, nsISupports* aContainer, nsIChannel* aChannel) { - NS_PRECONDITION(aDoc, "null ptr"); - NS_PRECONDITION(aURI, "null ptr"); + MOZ_ASSERT(aDoc, "null ptr"); + MOZ_ASSERT(aURI, "null ptr"); if (!aDoc || !aURI) { return NS_ERROR_NULL_POINTER; diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index ba8329b6abe2..535195ee3b6a 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -770,7 +770,7 @@ nsresult nsContentUtils::RemoveWyciwygScheme(nsIURI* aURI, nsIURI** aReturn) #ifdef DEBUG bool isWyciwyg = false; aURI->SchemeIs("wyciwyg", &isWyciwyg); - NS_PRECONDITION(isWyciwyg, "Scheme should be wyciwyg"); + MOZ_ASSERT(isWyciwyg, "Scheme should be wyciwyg"); #endif nsAutoCString path; nsresult rv = aURI->GetPathQueryRef(path); @@ -1061,7 +1061,7 @@ nsContentUtils::Atob(const nsAString& aAsciiBase64String, bool nsContentUtils::IsAutocompleteEnabled(mozilla::dom::HTMLInputElement* aInput) { - NS_PRECONDITION(aInput, "aInput should not be null!"); + MOZ_ASSERT(aInput, "aInput should not be null!"); nsAutoString autocomplete; aInput->GetAutocomplete(autocomplete); @@ -2193,7 +2193,7 @@ nsContentUtils::IsAbsoluteURL(const nsACString& aURL) bool nsContentUtils::InProlog(nsINode *aNode) { - NS_PRECONDITION(aNode, "missing node to nsContentUtils::InProlog"); + MOZ_ASSERT(aNode, "missing node to nsContentUtils::InProlog"); nsINode* parent = aNode->GetParentNode(); if (!parent || !parent->IsDocument()) { @@ -2391,7 +2391,7 @@ nsContentUtils::LookupBindingMember(JSContext* aCx, nsIContent *aContent, nsINode* nsContentUtils::GetCrossDocParentNode(nsINode* aChild) { - NS_PRECONDITION(aChild, "The child is null!"); + MOZ_ASSERT(aChild, "The child is null!"); nsINode* parent = aChild->GetParentNode(); if (parent && parent->IsContent() && aChild->IsContent()) { @@ -2412,8 +2412,8 @@ bool nsContentUtils::ContentIsDescendantOf(const nsINode* aPossibleDescendant, const nsINode* aPossibleAncestor) { - NS_PRECONDITION(aPossibleDescendant, "The possible descendant is null!"); - NS_PRECONDITION(aPossibleAncestor, "The possible ancestor is null!"); + MOZ_ASSERT(aPossibleDescendant, "The possible descendant is null!"); + MOZ_ASSERT(aPossibleAncestor, "The possible ancestor is null!"); do { if (aPossibleDescendant == aPossibleAncestor) @@ -2428,8 +2428,8 @@ bool nsContentUtils::ContentIsHostIncludingDescendantOf( const nsINode* aPossibleDescendant, const nsINode* aPossibleAncestor) { - NS_PRECONDITION(aPossibleDescendant, "The possible descendant is null!"); - NS_PRECONDITION(aPossibleAncestor, "The possible ancestor is null!"); + MOZ_ASSERT(aPossibleDescendant, "The possible descendant is null!"); + MOZ_ASSERT(aPossibleAncestor, "The possible ancestor is null!"); do { if (aPossibleDescendant == aPossibleAncestor) @@ -2478,8 +2478,8 @@ bool nsContentUtils::ContentIsCrossDocDescendantOf(nsINode* aPossibleDescendant, nsINode* aPossibleAncestor) { - NS_PRECONDITION(aPossibleDescendant, "The possible descendant is null!"); - NS_PRECONDITION(aPossibleAncestor, "The possible ancestor is null!"); + MOZ_ASSERT(aPossibleDescendant, "The possible descendant is null!"); + MOZ_ASSERT(aPossibleAncestor, "The possible ancestor is null!"); do { if (aPossibleDescendant == aPossibleAncestor) @@ -2497,8 +2497,8 @@ nsContentUtils::ContentIsFlattenedTreeDescendantOf( const nsINode* aPossibleDescendant, const nsINode* aPossibleAncestor) { - NS_PRECONDITION(aPossibleDescendant, "The possible descendant is null!"); - NS_PRECONDITION(aPossibleAncestor, "The possible ancestor is null!"); + MOZ_ASSERT(aPossibleDescendant, "The possible descendant is null!"); + MOZ_ASSERT(aPossibleAncestor, "The possible ancestor is null!"); do { if (aPossibleDescendant == aPossibleAncestor) { @@ -2516,8 +2516,8 @@ nsContentUtils::ContentIsFlattenedTreeDescendantOfForStyle( const nsINode* aPossibleDescendant, const nsINode* aPossibleAncestor) { - NS_PRECONDITION(aPossibleDescendant, "The possible descendant is null!"); - NS_PRECONDITION(aPossibleAncestor, "The possible ancestor is null!"); + MOZ_ASSERT(aPossibleDescendant, "The possible descendant is null!"); + MOZ_ASSERT(aPossibleAncestor, "The possible ancestor is null!"); do { if (aPossibleDescendant == aPossibleAncestor) { @@ -3451,9 +3451,9 @@ nsContentUtils::CanLoadImage(nsIURI* aURI, nsINode* aNode, int16_t* aImageBlockingStatus, uint32_t aContentType) { - NS_PRECONDITION(aURI, "Must have a URI"); - NS_PRECONDITION(aLoadingDocument, "Must have a document"); - NS_PRECONDITION(aLoadingPrincipal, "Must have a loading principal"); + MOZ_ASSERT(aURI, "Must have a URI"); + MOZ_ASSERT(aLoadingDocument, "Must have a document"); + MOZ_ASSERT(aLoadingPrincipal, "Must have a loading principal"); nsresult rv; @@ -3676,11 +3676,11 @@ nsContentUtils::LoadImage(nsIURI* aURI, nsINode* aContext, uint32_t aContentPolicyType, bool aUseUrgentStartForChannel) { - NS_PRECONDITION(aURI, "Must have a URI"); - NS_PRECONDITION(aContext, "Must have a context"); - NS_PRECONDITION(aLoadingDocument, "Must have a document"); - NS_PRECONDITION(aLoadingPrincipal, "Must have a principal"); - NS_PRECONDITION(aRequest, "Null out param"); + MOZ_ASSERT(aURI, "Must have a URI"); + MOZ_ASSERT(aContext, "Must have a context"); + MOZ_ASSERT(aLoadingDocument, "Must have a document"); + MOZ_ASSERT(aLoadingPrincipal, "Must have a principal"); + MOZ_ASSERT(aRequest, "Null out param"); imgLoader* imgLoader = GetImgLoaderForDocument(aLoadingDocument); if (!imgLoader) { @@ -3788,7 +3788,7 @@ nsContentUtils::ContentIsDraggable(nsIContent* aContent) bool nsContentUtils::IsDraggableImage(nsIContent* aContent) { - NS_PRECONDITION(aContent, "Must have content node to test"); + MOZ_ASSERT(aContent, "Must have content node to test"); nsCOMPtr imageContent(do_QueryInterface(aContent)); if (!imageContent) { @@ -4590,7 +4590,7 @@ nsContentUtils::MatchElementId(nsIContent *aContent, const nsAtom* aId) Element * nsContentUtils::MatchElementId(nsIContent *aContent, const nsAString& aId) { - NS_PRECONDITION(!aId.IsEmpty(), "Will match random elements"); + MOZ_ASSERT(!aId.IsEmpty(), "Will match random elements"); // ID attrs are generally stored as atoms, so just atomize this up front RefPtr id(NS_Atomize(aId)); @@ -4737,9 +4737,9 @@ void nsContentUtils::MaybeFireNodeRemoved(nsINode* aChild, nsINode* aParent, nsIDocument* aOwnerDoc) { - NS_PRECONDITION(aChild, "Missing child"); - NS_PRECONDITION(aChild->GetParentNode() == aParent, "Wrong parent"); - NS_PRECONDITION(aChild->OwnerDoc() == aOwnerDoc, "Wrong owner-doc"); + MOZ_ASSERT(aChild, "Missing child"); + MOZ_ASSERT(aChild->GetParentNode() == aParent, "Wrong parent"); + MOZ_ASSERT(aChild->OwnerDoc() == aOwnerDoc, "Wrong owner-doc"); // Having an explicit check here since it's an easy mistake to fall into, // and there might be existing code with problems. We'd rather be safe @@ -5407,10 +5407,8 @@ bool nsContentUtils::IsInSameAnonymousTree(const nsINode* aNode, const nsIContent* aContent) { - NS_PRECONDITION(aNode, - "Must have a node to work with"); - NS_PRECONDITION(aContent, - "Must have a content to work with"); + MOZ_ASSERT(aNode, "Must have a node to work with"); + MOZ_ASSERT(aContent, "Must have a content to work with"); if (!aNode->IsContent()) { /** @@ -5494,7 +5492,7 @@ nsContentUtils::TriggerLink(nsIContent *aContent, nsPresContext *aPresContext, bool aClick, bool aIsTrusted) { NS_ASSERTION(aPresContext, "Need a nsPresContext"); - NS_PRECONDITION(aLinkURI, "No link URI"); + MOZ_ASSERT(aLinkURI, "No link URI"); if (aContent->IsEditable()) { return; @@ -6279,7 +6277,7 @@ SameOriginCheckerImpl::AsyncOnChannelRedirect(nsIChannel* aOldChannel, uint32_t aFlags, nsIAsyncVerifyRedirectCallback* cb) { - NS_PRECONDITION(aNewChannel, "Redirecting to null channel?"); + MOZ_ASSERT(aNewChannel, "Redirecting to null channel?"); nsresult rv = nsContentUtils::CheckSameOrigin(aOldChannel, aNewChannel); if (NS_SUCCEEDED(rv)) { @@ -6299,7 +6297,7 @@ SameOriginCheckerImpl::GetInterface(const nsIID& aIID, void** aResult) nsresult nsContentUtils::GetASCIIOrigin(nsIPrincipal* aPrincipal, nsACString& aOrigin) { - NS_PRECONDITION(aPrincipal, "missing principal"); + MOZ_ASSERT(aPrincipal, "missing principal"); aOrigin.Truncate(); @@ -6320,7 +6318,7 @@ nsContentUtils::GetASCIIOrigin(nsIPrincipal* aPrincipal, nsACString& aOrigin) nsresult nsContentUtils::GetASCIIOrigin(nsIURI* aURI, nsACString& aOrigin) { - NS_PRECONDITION(aURI, "missing uri"); + MOZ_ASSERT(aURI, "missing uri"); // For Blob URI we have to return the origin of page using its principal. nsCOMPtr uriWithPrincipal = do_QueryInterface(aURI); @@ -6374,7 +6372,7 @@ nsContentUtils::GetASCIIOrigin(nsIURI* aURI, nsACString& aOrigin) nsresult nsContentUtils::GetUTFOrigin(nsIPrincipal* aPrincipal, nsAString& aOrigin) { - NS_PRECONDITION(aPrincipal, "missing principal"); + MOZ_ASSERT(aPrincipal, "missing principal"); aOrigin.Truncate(); @@ -6395,7 +6393,7 @@ nsContentUtils::GetUTFOrigin(nsIPrincipal* aPrincipal, nsAString& aOrigin) nsresult nsContentUtils::GetUTFOrigin(nsIURI* aURI, nsAString& aOrigin) { - NS_PRECONDITION(aURI, "missing uri"); + MOZ_ASSERT(aURI, "missing uri"); bool isBlobURL = false; nsresult rv = aURI->SchemeIs(BLOBURI_SCHEME, &isBlobURL); diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h index 0d9db1a38536..aedc9d615d4f 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -2191,7 +2191,7 @@ public: static already_AddRefed GetElementsByClassName(nsINode* aRootNode, const nsAString& aClasses) { - NS_PRECONDITION(aRootNode, "Must have root node"); + MOZ_ASSERT(aRootNode, "Must have root node"); return GetFuncStringContentList(aRootNode, MatchClassNames, diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 1e4917009555..40a846f801b1 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -505,8 +505,8 @@ struct PositionComparator bool nsIdentifierMapEntry::AddIdElement(Element* aElement) { - NS_PRECONDITION(aElement, "Must have element"); - NS_PRECONDITION(!mIdContentList.Contains(nullptr), + MOZ_ASSERT(aElement, "Must have element"); + MOZ_ASSERT(!mIdContentList.Contains(nullptr), "Why is null in our list?"); #ifdef DEBUG @@ -549,7 +549,7 @@ nsIdentifierMapEntry::AddIdElement(Element* aElement) void nsIdentifierMapEntry::RemoveIdElement(Element* aElement) { - NS_PRECONDITION(aElement, "Missing element"); + MOZ_ASSERT(aElement, "Missing element"); // This should only be called while the document is in an update. // Assertions near the call to this method guarantee this. @@ -820,8 +820,8 @@ nsExternalResourceMap::RequestResource(nsIURI* aURI, // If we ever start allowing non-same-origin loads here, we might need to do // something interesting with aRequestingPrincipal even for the hashtable // gets. - NS_PRECONDITION(aURI, "Must have a URI"); - NS_PRECONDITION(aRequestingNode, "Must have a node"); + MOZ_ASSERT(aURI, "Must have a URI"); + MOZ_ASSERT(aRequestingNode, "Must have a node"); *aPendingLoad = nullptr; if (mHaveShutDown) { return nullptr; @@ -958,9 +958,9 @@ nsExternalResourceMap::AddExternalResource(nsIURI* aURI, nsILoadGroup* aLoadGroup, nsIDocument* aDisplayDocument) { - NS_PRECONDITION(aURI, "Unexpected call"); - NS_PRECONDITION((aViewer && aLoadGroup) || (!aViewer && !aLoadGroup), - "Must have both or neither"); + MOZ_ASSERT(aURI, "Unexpected call"); + MOZ_ASSERT((aViewer && aLoadGroup) || (!aViewer && !aLoadGroup), + "Must have both or neither"); RefPtr load; mPendingLoads.Remove(aURI, getter_AddRefs(load)); @@ -1050,7 +1050,7 @@ nsExternalResourceMap::PendingLoad::SetupViewer(nsIRequest* aRequest, nsIContentViewer** aViewer, nsILoadGroup** aLoadGroup) { - NS_PRECONDITION(!mTargetListener, "Unexpected call to OnStartRequest"); + MOZ_ASSERT(!mTargetListener, "Unexpected call to OnStartRequest"); *aViewer = nullptr; *aLoadGroup = nullptr; @@ -1161,8 +1161,8 @@ nsresult nsExternalResourceMap::PendingLoad::StartLoad(nsIURI* aURI, nsINode* aRequestingNode) { - NS_PRECONDITION(aURI, "Must have a URI"); - NS_PRECONDITION(aRequestingNode, "Must have a node"); + MOZ_ASSERT(aURI, "Must have a URI"); + MOZ_ASSERT(aRequestingNode, "Must have a node"); nsCOMPtr loadGroup = aRequestingNode->OwnerDoc()->GetDocumentLoadGroup(); @@ -1754,7 +1754,7 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDocument) NS_IMETHODIMP_(MozExternalRefCountType) nsDocument::Release() { - NS_PRECONDITION(0 != mRefCnt, "dup release"); + MOZ_ASSERT(0 != mRefCnt, "dup release"); NS_ASSERT_OWNINGTHREAD(nsDocument); nsISupports* base = NS_CYCLE_COLLECTION_CLASSNAME(nsDocument)::Upcast(this); bool shouldDelete = false; @@ -2229,7 +2229,7 @@ nsIDocument::ResetToURI(nsIURI* aURI, nsILoadGroup* aLoadGroup, nsIPrincipal* aPrincipal) { - NS_PRECONDITION(aURI, "Null URI passed to ResetToURI"); + MOZ_ASSERT(aURI, "Null URI passed to ResetToURI"); MOZ_LOG(gDocumentLeakPRLog, LogLevel::Debug, ("DOCUMENT %p ResetToURI %s", this, aURI->GetSpecOrDefault().get())); @@ -2532,9 +2532,9 @@ AppendSheetsToStyleSet(ServoStyleSet* aStyleSet, void nsIDocument::FillStyleSet(ServoStyleSet* aStyleSet) { - NS_PRECONDITION(aStyleSet, "Must have a style set"); - NS_PRECONDITION(aStyleSet->SheetCount(SheetType::Doc) == 0, - "Style set already has document sheets?"); + MOZ_ASSERT(aStyleSet, "Must have a style set"); + MOZ_ASSERT(aStyleSet->SheetCount(SheetType::Doc) == 0, + "Style set already has document sheets?"); MOZ_ASSERT(!mStyleSetFilled); @@ -4381,7 +4381,7 @@ nsIDocument::RemoveStyleSheetFromStyleSets(StyleSheet* aSheet) void nsIDocument::RemoveStyleSheet(StyleSheet* aSheet) { - NS_PRECONDITION(aSheet, "null arg"); + MOZ_ASSERT(aSheet, "null arg"); RefPtr sheet = aSheet; // hold ref so it won't die too soon if (!mStyleSheets.RemoveElement(aSheet)) { @@ -4407,8 +4407,8 @@ nsIDocument::UpdateStyleSheets(nsTArray>& aOldSheets, BeginUpdate(UPDATE_STYLE); // XXX Need to set the sheet on the ownernode, if any - NS_PRECONDITION(aOldSheets.Length() == aNewSheets.Length(), - "The lists must be the same length!"); + MOZ_ASSERT(aOldSheets.Length() == aNewSheets.Length(), + "The lists must be the same length!"); int32_t count = aOldSheets.Length(); RefPtr oldSheet; @@ -4459,7 +4459,7 @@ nsIDocument::InsertStyleSheetAt(StyleSheet* aSheet, size_t aIndex) void nsIDocument::SetStyleSheetApplicableState(StyleSheet* aSheet, bool aApplicable) { - NS_PRECONDITION(aSheet, "null arg"); + MOZ_ASSERT(aSheet, "null arg"); // If we're actually in the document style sheet list if (mStyleSheets.IndexOf(aSheet) != mStyleSheets.NoIndex) { @@ -4543,7 +4543,7 @@ nsresult nsIDocument::LoadAdditionalStyleSheet(additionalSheetType aType, nsIURI* aSheetURI) { - NS_PRECONDITION(aSheetURI, "null arg"); + MOZ_ASSERT(aSheetURI, "null arg"); // Checking if we have loaded this one already. if (FindSheet(mAdditionalSheets[aType], aSheetURI) >= 0) @@ -5478,8 +5478,8 @@ nsIDocument::UnblockDOMContentLoaded() void nsIDocument::ContentStateChanged(nsIContent* aContent, EventStates aStateMask) { - NS_PRECONDITION(!nsContentUtils::IsSafeToRunScript(), - "Someone forgot a scriptblocker"); + MOZ_ASSERT(!nsContentUtils::IsSafeToRunScript(), + "Someone forgot a scriptblocker"); NS_DOCUMENT_NOTIFY_OBSERVERS(ContentStateChanged, (this, aContent, aStateMask)); } @@ -6746,8 +6746,8 @@ nsIDocument::RequestExternalResource(nsIURI* aURI, nsINode* aRequestingNode, ExternalResourceLoad** aPendingLoad) { - NS_PRECONDITION(aURI, "Must have a URI"); - NS_PRECONDITION(aRequestingNode, "Must have a node"); + MOZ_ASSERT(aURI, "Must have a URI"); + MOZ_ASSERT(aRequestingNode, "Must have a node"); if (mDisplayDocument) { return mDisplayDocument->RequestExternalResource(aURI, aRequestingNode, @@ -6921,7 +6921,7 @@ bool nsIDocument::MatchNameAttribute(Element* aElement, int32_t aNamespaceID, nsAtom* aAtom, void* aData) { - NS_PRECONDITION(aElement, "Must have element to work with!"); + MOZ_ASSERT(aElement, "Must have element to work with!"); if (!aElement->HasName()) { return false; @@ -8392,11 +8392,11 @@ nsIDocument::PostUnblockOnloadEvent() void nsIDocument::DoUnblockOnload() { - NS_PRECONDITION(!mDisplayDocument, + MOZ_ASSERT(!mDisplayDocument, "Shouldn't get here for resource document"); - NS_PRECONDITION(mOnloadBlockCount != 0, - "Shouldn't have a count of zero here, since we stabilized in " - "PostUnblockOnloadEvent"); + MOZ_ASSERT(mOnloadBlockCount != 0, + "Shouldn't have a count of zero here, since we stabilized in " + "PostUnblockOnloadEvent"); --mOnloadBlockCount; diff --git a/dom/base/nsDocumentEncoder.cpp b/dom/base/nsDocumentEncoder.cpp index f7a534646ab7..36d744fb2036 100644 --- a/dom/base/nsDocumentEncoder.cpp +++ b/dom/base/nsDocumentEncoder.cpp @@ -99,7 +99,7 @@ protected: bool IsVisibleNode(nsINode* aNode) { - NS_PRECONDITION(aNode, ""); + MOZ_ASSERT(aNode, "null node"); if (mFlags & SkipInvisibleContent) { // Treat the visibility of the ShadowRoot as if it were @@ -1754,7 +1754,7 @@ nsHTMLCopyEncoder::GetChildAt(nsINode *aParent, int32_t aOffset) return resultNode; nsCOMPtr content = do_QueryInterface(aParent); - NS_PRECONDITION(content, "null content in nsHTMLCopyEncoder::GetChildAt"); + MOZ_ASSERT(content, "null content in nsHTMLCopyEncoder::GetChildAt"); resultNode = content->GetChildAt_Deprecated(aOffset); diff --git a/dom/base/nsFocusManager.cpp b/dom/base/nsFocusManager.cpp index 864c76402cb1..0482b45b4f58 100644 --- a/dom/base/nsFocusManager.cpp +++ b/dom/base/nsFocusManager.cpp @@ -1563,8 +1563,8 @@ nsFocusManager::IsWindowVisible(nsPIDOMWindowOuter* aWindow) bool nsFocusManager::IsNonFocusableRoot(nsIContent* aContent) { - NS_PRECONDITION(aContent, "aContent must not be NULL"); - NS_PRECONDITION(aContent->IsInComposedDoc(), "aContent must be in a document"); + MOZ_ASSERT(aContent, "aContent must not be NULL"); + MOZ_ASSERT(aContent->IsInComposedDoc(), "aContent must be in a document"); // If aContent is in designMode, the root element is not focusable. // NOTE: in designMode, most elements are not focusable, just the document is diff --git a/dom/base/nsFrameLoader.cpp b/dom/base/nsFrameLoader.cpp index 5eb11d6cba7c..56a558a5b6a2 100644 --- a/dom/base/nsFrameLoader.cpp +++ b/dom/base/nsFrameLoader.cpp @@ -630,7 +630,7 @@ SetTreeOwnerAndChromeEventHandlerOnDocshellTree(nsIDocShellTreeItem* aItem, nsIDocShellTreeOwner* aOwner, EventTarget* aHandler) { - NS_PRECONDITION(aItem, "Must have item"); + MOZ_ASSERT(aItem, "Must have item"); aItem->SetTreeOwner(aOwner); @@ -662,8 +662,8 @@ nsFrameLoader::AddTreeItemToTreeOwner(nsIDocShellTreeItem* aItem, int32_t aParentType, nsIDocShell* aParentNode) { - NS_PRECONDITION(aItem, "Must have docshell treeitem"); - NS_PRECONDITION(mOwnerContent, "Must have owning content"); + MOZ_ASSERT(aItem, "Must have docshell treeitem"); + MOZ_ASSERT(mOwnerContent, "Must have owning content"); nsAutoString value; bool isContent = mOwnerContent->AttrValueIs( diff --git a/dom/base/nsGenConImageContent.cpp b/dom/base/nsGenConImageContent.cpp index 366abdb1b6cf..324f83ee754a 100644 --- a/dom/base/nsGenConImageContent.cpp +++ b/dom/base/nsGenConImageContent.cpp @@ -91,7 +91,7 @@ namespace dom { already_AddRefed CreateGenConImageContent(nsIDocument* aDocument, imgRequestProxy* aImageRequest) { - NS_PRECONDITION(aImageRequest, "Must have request!"); + MOZ_ASSERT(aImageRequest, "Must have request!"); RefPtr nodeInfo = aDocument->NodeInfoManager()-> GetNodeInfo(nsGkAtoms::mozgeneratedcontentimage, diff --git a/dom/base/nsGlobalWindowInner.cpp b/dom/base/nsGlobalWindowInner.cpp index b469fcdad956..e1887b473911 100644 --- a/dom/base/nsGlobalWindowInner.cpp +++ b/dom/base/nsGlobalWindowInner.cpp @@ -1667,8 +1667,8 @@ nsGlobalWindowInner::SetNewDocument(nsIDocument* aDocument, nsISupports* aState, bool aForceReuseInnerWindow) { - NS_PRECONDITION(mDocumentPrincipal == nullptr, - "mDocumentPrincipal prematurely set!"); + MOZ_ASSERT(mDocumentPrincipal == nullptr, + "mDocumentPrincipal prematurely set!"); MOZ_ASSERT(aDocument); if (!mOuterWindow) { @@ -4780,7 +4780,7 @@ public: NS_IMETHOD Run() override { - NS_PRECONDITION(NS_IsMainThread(), "Should be called on the main thread."); + MOZ_ASSERT(NS_IsMainThread(), "Should be called on the main thread."); return mWindow->FireHashchange(mOldURL, mNewURL); } diff --git a/dom/base/nsGlobalWindowOuter.cpp b/dom/base/nsGlobalWindowOuter.cpp index fdd9c3dc8fc9..e296afd96fcc 100644 --- a/dom/base/nsGlobalWindowOuter.cpp +++ b/dom/base/nsGlobalWindowOuter.cpp @@ -1415,7 +1415,7 @@ WindowStateHolder::WindowStateHolder(nsGlobalWindowInner* aWindow) : mInnerWindow(aWindow), mInnerWindowReflector(RootingCx(), aWindow->GetWrapper()) { - NS_PRECONDITION(aWindow, "null window"); + MOZ_ASSERT(aWindow, "null window"); aWindow->Suspend(); @@ -1640,7 +1640,7 @@ nsGlobalWindowOuter::SetNewDocument(nsIDocument* aDocument, nsISupports* aState, bool aForceReuseInnerWindow) { - NS_PRECONDITION(mDocumentPrincipal == nullptr, + MOZ_ASSERT(mDocumentPrincipal == nullptr, "mDocumentPrincipal prematurely set!"); MOZ_ASSERT(aDocument); @@ -3850,7 +3850,7 @@ nsGlobalWindowOuter::WindowExists(const nsAString& aName, bool aForceNoOpener, bool aLookForCallerOnJSStack) { - NS_PRECONDITION(mDocShell, "Must have docshell"); + MOZ_ASSERT(mDocShell, "Must have docshell"); if (aForceNoOpener) { return aName.LowerCaseEqualsLiteral("_self") || @@ -6901,10 +6901,11 @@ nsGlobalWindowOuter::OpenInternal(const nsAString& aUrl, const nsAString& aName, if (argv) argv->GetLength(&argc); #endif - NS_PRECONDITION(!aExtraArgument || (!argv && argc == 0), - "Can't pass in arguments both ways"); - NS_PRECONDITION(!aCalledNoScript || (!argv && argc == 0), - "Can't pass JS args when called via the noscript methods"); + + MOZ_ASSERT(!aExtraArgument || (!argv && argc == 0), + "Can't pass in arguments both ways"); + MOZ_ASSERT(!aCalledNoScript || (!argv && argc == 0), + "Can't pass JS args when called via the noscript methods"); mozilla::Maybe closeUnblocker; @@ -7731,4 +7732,3 @@ nsAutoPopupStatePusherInternal::~nsAutoPopupStatePusherInternal() { nsContentUtils::PopPopupControlState(mOldState); } - diff --git a/dom/base/nsImageLoadingContent.cpp b/dom/base/nsImageLoadingContent.cpp index c9a484fc92d8..1c15219bf873 100644 --- a/dom/base/nsImageLoadingContent.cpp +++ b/dom/base/nsImageLoadingContent.cpp @@ -148,8 +148,8 @@ nsImageLoadingContent::Notify(imgIRequest* aRequest, // We should definitely have a request here MOZ_ASSERT(aRequest, "no request?"); - NS_PRECONDITION(aRequest == mCurrentRequest || aRequest == mPendingRequest, - "Unknown request"); + MOZ_ASSERT(aRequest == mCurrentRequest || aRequest == mPendingRequest, + "Unknown request"); } { @@ -342,7 +342,7 @@ nsImageLoadingContent::SetLoadingEnabled(bool aLoadingEnabled) NS_IMETHODIMP nsImageLoadingContent::GetImageBlockingStatus(int16_t* aStatus) { - NS_PRECONDITION(aStatus, "Null out param"); + MOZ_ASSERT(aStatus, "Null out param"); *aStatus = ImageBlockingStatus(); return NS_OK; } @@ -719,7 +719,7 @@ NS_IMETHODIMP nsImageLoadingContent::GetRequestType(imgIRequest* aRequest, int32_t* aRequestType) { - NS_PRECONDITION(aRequestType, "Null out param"); + MOZ_ASSERT(aRequestType, "Null out param"); ErrorResult result; *aRequestType = GetRequestType(aRequest, result); @@ -1239,8 +1239,8 @@ nsImageLoadingContent::StringToURI(const nsAString& aSpec, nsIDocument* aDocument, nsIURI** aURI) { - NS_PRECONDITION(aDocument, "Must have a document"); - NS_PRECONDITION(aURI, "Null out param"); + MOZ_ASSERT(aDocument, "Must have a document"); + MOZ_ASSERT(aURI, "Null out param"); // (1) Get the base URI nsIContent* thisContent = AsContent(); @@ -1748,4 +1748,4 @@ mozilla::net::ReferrerPolicy nsImageLoadingContent::GetImageReferrerPolicy() { return mozilla::net::RP_Unset; -}; +} diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp index 8e963ea4fc1b..f6f0226316a9 100644 --- a/dom/base/nsJSEnvironment.cpp +++ b/dom/base/nsJSEnvironment.cpp @@ -814,7 +814,7 @@ nsJSContext::ConvertSupportsTojsvals(nsISupports* aArgs, nsresult nsJSContext::AddSupportsPrimitiveTojsvals(nsISupports *aArg, JS::Value *aArgv) { - NS_PRECONDITION(aArg, "Empty arg"); + MOZ_ASSERT(aArg, "Empty arg"); nsCOMPtr argPrimitive(do_QueryInterface(aArg)); if (!argPrimitive) diff --git a/dom/base/nsMappedAttributes.cpp b/dom/base/nsMappedAttributes.cpp index 9a8021f17e2d..825058e517ee 100644 --- a/dom/base/nsMappedAttributes.cpp +++ b/dom/base/nsMappedAttributes.cpp @@ -152,7 +152,7 @@ void nsMappedAttributes::SetAndSwapAttr(nsAtom* aAttrName, nsAttrValue& aValue, bool* aValueWasSet) { - NS_PRECONDITION(aAttrName, "null name"); + MOZ_ASSERT(aAttrName, "null name"); *aValueWasSet = false; uint32_t i; for (i = 0; i < mAttrCount && !Attrs()[i].mName.IsSmaller(aAttrName); ++i) { @@ -178,7 +178,7 @@ nsMappedAttributes::SetAndSwapAttr(nsAtom* aAttrName, nsAttrValue& aValue, const nsAttrValue* nsMappedAttributes::GetAttr(nsAtom* aAttrName) const { - NS_PRECONDITION(aAttrName, "null name"); + MOZ_ASSERT(aAttrName, "null name"); for (uint32_t i = 0; i < mAttrCount; ++i) { if (Attrs()[i].mName.Equals(aAttrName)) { diff --git a/dom/base/nsNameSpaceManager.cpp b/dom/base/nsNameSpaceManager.cpp index 727cdfda7b69..007cab810d3f 100644 --- a/dom/base/nsNameSpaceManager.cpp +++ b/dom/base/nsNameSpaceManager.cpp @@ -126,7 +126,7 @@ nsNameSpaceManager::RegisterNameSpace(already_AddRefed aURI, nsresult nsNameSpaceManager::GetNameSpaceURI(int32_t aNameSpaceID, nsAString& aURI) { - NS_PRECONDITION(aNameSpaceID >= 0, "Bogus namespace ID"); + MOZ_ASSERT(aNameSpaceID >= 0, "Bogus namespace ID"); // We have historically treated GetNameSpaceURI calls for kNameSpaceID_None // as erroneous. diff --git a/dom/base/nsNodeInfoManager.cpp b/dom/base/nsNodeInfoManager.cpp index 2ca31c21784e..5ef019fa97cb 100644 --- a/dom/base/nsNodeInfoManager.cpp +++ b/dom/base/nsNodeInfoManager.cpp @@ -107,7 +107,7 @@ NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END nsresult nsNodeInfoManager::Init(nsIDocument *aDocument) { - NS_PRECONDITION(!mPrincipal, + MOZ_ASSERT(!mPrincipal, "Being inited when we already have a principal?"); mPrincipal = NullPrincipal::CreateWithoutOriginAttributes(); @@ -319,7 +319,7 @@ nsNodeInfoManager::SetDocumentPrincipal(nsIPrincipal *aPrincipal) void nsNodeInfoManager::RemoveNodeInfo(NodeInfo *aNodeInfo) { - NS_PRECONDITION(aNodeInfo, "Trying to remove null nodeinfo from manager!"); + MOZ_ASSERT(aNodeInfo, "Trying to remove null nodeinfo from manager!"); if (aNodeInfo == mDocumentNodeInfo) { mDocumentNodeInfo = nullptr; diff --git a/dom/base/nsNodeUtils.cpp b/dom/base/nsNodeUtils.cpp index 2e47452a623e..9625c3a71dee 100644 --- a/dom/base/nsNodeUtils.cpp +++ b/dom/base/nsNodeUtils.cpp @@ -210,8 +210,8 @@ void nsNodeUtils::ContentInserted(nsINode* aContainer, nsIContent* aChild) { - NS_PRECONDITION(aContainer->IsContent() || aContainer->IsDocument(), - "container must be an nsIContent or an nsIDocument"); + MOZ_ASSERT(aContainer->IsContent() || aContainer->IsDocument(), + "container must be an nsIContent or an nsIDocument"); nsIDocument* doc = aContainer->OwnerDoc(); IMPL_MUTATION_NOTIFICATION(ContentInserted, aContainer, (aChild), IsRemoveNotification::No); @@ -222,8 +222,8 @@ nsNodeUtils::ContentRemoved(nsINode* aContainer, nsIContent* aChild, nsIContent* aPreviousSibling) { - NS_PRECONDITION(aContainer->IsContent() || aContainer->IsDocument(), - "container must be an nsIContent or an nsIDocument"); + MOZ_ASSERT(aContainer->IsContent() || aContainer->IsDocument(), + "container must be an nsIContent or an nsIDocument"); nsIDocument* doc = aContainer->OwnerDoc(); MOZ_ASSERT(aChild->GetParentNode() == aContainer, "We expect the parent link to be still around at this point"); @@ -383,11 +383,10 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep, nsCOMArray *aNodesWithProperties, nsINode* aParent, ErrorResult& aError) { - NS_PRECONDITION((!aClone && aNewNodeInfoManager) || !aReparentScope, - "If cloning or not getting a new nodeinfo we shouldn't " - "rewrap"); - NS_PRECONDITION(!aParent || aNode->IsContent(), - "Can't insert document or attribute nodes into a parent"); + MOZ_ASSERT((!aClone && aNewNodeInfoManager) || !aReparentScope, + "If cloning or not getting a new nodeinfo we shouldn't rewrap"); + MOZ_ASSERT(!aParent || aNode->IsContent(), + "Can't insert document or attribute nodes into a parent"); // First deal with aNode and walk its attributes (and their children). Then, // if aDeep is true, deal with aNode's children (and recurse into their @@ -713,4 +712,3 @@ nsNodeUtils::GetFirstChildOfTemplateOrNode(nsINode* aNode) return aNode->GetFirstChild(); } - diff --git a/dom/base/nsPropertyTable.cpp b/dom/base/nsPropertyTable.cpp index 487f080afde0..bfef34248c5f 100644 --- a/dom/base/nsPropertyTable.cpp +++ b/dom/base/nsPropertyTable.cpp @@ -140,7 +140,7 @@ nsPropertyTable::GetPropertyInternal(nsPropertyOwner aObject, bool aRemove, nsresult* aResult) { - NS_PRECONDITION(aPropertyName && aObject, "unexpected null param"); + MOZ_ASSERT(aPropertyName && aObject, "unexpected null param"); nsresult rv = NS_PROPTABLE_PROP_NOT_THERE; void *propValue = nullptr; @@ -172,7 +172,7 @@ nsPropertyTable::SetPropertyInternal(nsPropertyOwner aObject, void* aPropDtorData, bool aTransfer) { - NS_PRECONDITION(aPropertyName && aObject, "unexpected null param"); + MOZ_ASSERT(aPropertyName && aObject, "unexpected null param"); PropertyList* propertyList = GetPropertyListFor(aPropertyName); @@ -218,7 +218,7 @@ nsresult nsPropertyTable::DeleteProperty(nsPropertyOwner aObject, nsAtom* aPropertyName) { - NS_PRECONDITION(aPropertyName && aObject, "unexpected null param"); + MOZ_ASSERT(aPropertyName && aObject, "unexpected null param"); PropertyList* propertyList = GetPropertyListFor(aPropertyName); if (propertyList) { diff --git a/dom/base/nsRange.cpp b/dom/base/nsRange.cpp index 0fa7f816b35f..70d3a67493a8 100644 --- a/dom/base/nsRange.cpp +++ b/dom/base/nsRange.cpp @@ -60,7 +60,7 @@ nsRange::GetDocGroup() const static void InvalidateAllFrames(nsINode* aNode) { - NS_PRECONDITION(aNode, "bad arg"); + MOZ_ASSERT(aNode, "bad arg"); nsIFrame* frame = nullptr; switch (aNode->NodeType()) { @@ -199,7 +199,7 @@ struct IsItemInRangeComparator nsRange::IsNodeSelected(nsINode* aNode, uint32_t aStartOffset, uint32_t aEndOffset) { - NS_PRECONDITION(aNode, "bad arg"); + MOZ_ASSERT(aNode, "bad arg"); nsINode* n = GetNextRangeCommonAncestor(aNode); NS_ASSERTION(n || !aNode->IsSelectionDescendant(), @@ -461,7 +461,7 @@ static void UnmarkDescendants(nsINode* aNode) void nsRange::RegisterCommonAncestor(nsINode* aNode) { - NS_PRECONDITION(aNode, "bad arg"); + MOZ_ASSERT(aNode, "bad arg"); MOZ_DIAGNOSTIC_ASSERT(IsInSelection(), "registering range not in selection"); @@ -482,7 +482,7 @@ nsRange::RegisterCommonAncestor(nsINode* aNode) void nsRange::UnregisterCommonAncestor(nsINode* aNode, bool aIsUnlinking) { - NS_PRECONDITION(aNode, "bad arg"); + MOZ_ASSERT(aNode, "bad arg"); NS_ASSERTION(aNode->IsCommonAncestorForRangeInSelection(), "wrong node"); MOZ_DIAGNOSTIC_ASSERT(aNode == mRegisteredCommonAncestor, "wrong node"); LinkedList* ranges = aNode->GetExistingCommonAncestorRanges(); @@ -964,29 +964,32 @@ nsRange::DoSetRange(const RawRangeBoundary& aStart, const RawRangeBoundary& aEnd, nsINode* aRoot, bool aNotInsertedYet) { - NS_PRECONDITION((aStart.IsSet() && aEnd.IsSet() && aRoot) || - (!aStart.IsSet() && !aEnd.IsSet() && !aRoot), - "Set all or none"); - NS_PRECONDITION(!aRoot || aNotInsertedYet || - (nsContentUtils::ContentIsDescendantOf(aStart.Container(), aRoot) && - nsContentUtils::ContentIsDescendantOf(aEnd.Container(), aRoot) && - aRoot == IsValidBoundary(aStart.Container()) && - aRoot == IsValidBoundary(aEnd.Container())), - "Wrong root"); - NS_PRECONDITION(!aRoot || - (aStart.Container()->IsContent() && - aEnd.Container()->IsContent() && - aRoot == - static_cast(aStart.Container())->GetBindingParent() && - aRoot == - static_cast(aEnd.Container())->GetBindingParent()) || - (!aRoot->GetParentNode() && - (aRoot->IsDocument() || - aRoot->IsAttr() || - aRoot->IsDocumentFragment() || - /*For backward compatibility*/ - aRoot->IsContent())), - "Bad root"); + MOZ_ASSERT((aStart.IsSet() && aEnd.IsSet() && aRoot) || + (!aStart.IsSet() && !aEnd.IsSet() && !aRoot), + "Set all or none"); + + MOZ_ASSERT(!aRoot || aNotInsertedYet || + (nsContentUtils::ContentIsDescendantOf(aStart.Container(), aRoot) && + nsContentUtils::ContentIsDescendantOf(aEnd.Container(), aRoot) && + aRoot == IsValidBoundary(aStart.Container()) && + aRoot == IsValidBoundary(aEnd.Container())), + "Wrong root"); + + MOZ_ASSERT(!aRoot || + (aStart.Container()->IsContent() && + aEnd.Container()->IsContent() && + aRoot == + static_cast(aStart.Container())->GetBindingParent() && + aRoot == + static_cast(aEnd.Container())->GetBindingParent()) || + (!aRoot->GetParentNode() && + (aRoot->IsDocument() || + aRoot->IsAttr() || + aRoot->IsDocumentFragment() || + /*For backward compatibility*/ + aRoot->IsContent())), + "Bad root"); + if (mRoot != aRoot) { if (mRoot) { mRoot->RemoveMutationObserver(this); diff --git a/dom/base/nsSyncLoadService.cpp b/dom/base/nsSyncLoadService.cpp index 3eefd9634d04..1b67cf4e831b 100644 --- a/dom/base/nsSyncLoadService.cpp +++ b/dom/base/nsSyncLoadService.cpp @@ -289,7 +289,7 @@ nsSyncLoader::AsyncOnChannelRedirect(nsIChannel *aOldChannel, uint32_t aFlags, nsIAsyncVerifyRedirectCallback *callback) { - NS_PRECONDITION(aNewChannel, "Redirecting to null channel?"); + MOZ_ASSERT(aNewChannel, "Redirecting to null channel?"); mChannel = aNewChannel; diff --git a/dom/base/nsTextNode.cpp b/dom/base/nsTextNode.cpp index eaacc8b1bb71..9344c07bf676 100644 --- a/dom/base/nsTextNode.cpp +++ b/dom/base/nsTextNode.cpp @@ -215,9 +215,9 @@ NS_NewAttributeContent(nsNodeInfoManager *aNodeInfoManager, int32_t aNameSpaceID, nsAtom* aAttrName, nsIContent** aResult) { - NS_PRECONDITION(aNodeInfoManager, "Missing nodeInfoManager"); - NS_PRECONDITION(aAttrName, "Must have an attr name"); - NS_PRECONDITION(aNameSpaceID != kNameSpaceID_Unknown, "Must know namespace"); + MOZ_ASSERT(aNodeInfoManager, "Missing nodeInfoManager"); + MOZ_ASSERT(aAttrName, "Must have an attr name"); + MOZ_ASSERT(aNameSpaceID != kNameSpaceID_Unknown, "Must know namespace"); *aResult = nullptr; @@ -239,8 +239,8 @@ nsAttributeTextNode::BindToTree(nsIDocument* aDocument, nsIContent* aParent, nsIContent* aBindingParent, bool aCompileEventHandlers) { - NS_PRECONDITION(aParent && aParent->GetParent(), - "This node can't be a child of the document or of the document root"); + MOZ_ASSERT(aParent && aParent->GetParent(), + "This node can't be a child of the document or of the document root"); nsresult rv = nsTextNode::BindToTree(aDocument, aParent, aBindingParent, aCompileEventHandlers); @@ -305,4 +305,3 @@ nsAttributeTextNode::UpdateText(bool aNotify) SetText(attrValue, aNotify); } } - diff --git a/dom/base/nsTreeSanitizer.cpp b/dom/base/nsTreeSanitizer.cpp index e49a656829be..0fd5094419b7 100644 --- a/dom/base/nsTreeSanitizer.cpp +++ b/dom/base/nsTreeSanitizer.cpp @@ -1357,7 +1357,7 @@ nsTreeSanitizer::Sanitize(DocumentFragment* aFragment) // If you want to relax these preconditions, be sure to check the code in // here that notifies / does not notify or that fires mutation events if // in tree. - NS_PRECONDITION(!aFragment->IsInUncomposedDoc(), "The fragment is in doc?"); + MOZ_ASSERT(!aFragment->IsInUncomposedDoc(), "The fragment is in doc?"); mFullDocument = false; SanitizeChildren(aFragment); @@ -1370,9 +1370,9 @@ nsTreeSanitizer::Sanitize(nsIDocument* aDocument) // here that notifies / does not notify or that fires mutation events if // in tree. #ifdef DEBUG - NS_PRECONDITION(!aDocument->GetContainer(), "The document is in a shell."); + MOZ_ASSERT(!aDocument->GetContainer(), "The document is in a shell."); RefPtr root = aDocument->GetRootElement(); - NS_PRECONDITION(root->IsHTMLElement(nsGkAtoms::html), "Not HTML root."); + MOZ_ASSERT(root->IsHTMLElement(nsGkAtoms::html), "Not HTML root."); #endif mFullDocument = true; @@ -1542,7 +1542,7 @@ nsTreeSanitizer::LogMessage(const char* aMessage, nsIDocument* aDoc, void nsTreeSanitizer::InitializeStatics() { - NS_PRECONDITION(!sElementsHTML, "Initializing a second time."); + MOZ_ASSERT(!sElementsHTML, "Initializing a second time."); sElementsHTML = new AtomsTable(ArrayLength(kElementsHTML)); for (uint32_t i = 0; kElementsHTML[i]; i++) { diff --git a/dom/canvas/CanvasUtils.cpp b/dom/canvas/CanvasUtils.cpp index 5fffec7a1962..d18f01e92651 100644 --- a/dom/canvas/CanvasUtils.cpp +++ b/dom/canvas/CanvasUtils.cpp @@ -257,7 +257,7 @@ DoDrawImageSecurityCheck(dom::HTMLCanvasElement *aCanvasElement, if (CORSUsed) return; - NS_PRECONDITION(aPrincipal, "Must have a principal here"); + MOZ_ASSERT(aPrincipal, "Must have a principal here"); if (aCanvasElement->NodePrincipal()->Subsumes(aPrincipal)) { // This canvas has access to that image anyway diff --git a/dom/commandhandler/nsControllerCommandTable.cpp b/dom/commandhandler/nsControllerCommandTable.cpp index 91075bba461d..c99464be43d0 100644 --- a/dom/commandhandler/nsControllerCommandTable.cpp +++ b/dom/commandhandler/nsControllerCommandTable.cpp @@ -197,7 +197,7 @@ nsControllerCommandTable::GetSupportedCommands(uint32_t* aCount, nsresult NS_NewControllerCommandTable(nsIControllerCommandTable** aResult) { - NS_PRECONDITION(aResult != nullptr, "null ptr"); + MOZ_ASSERT(aResult != nullptr, "null ptr"); if (!aResult) { return NS_ERROR_NULL_POINTER; } diff --git a/dom/events/ContentEventHandler.cpp b/dom/events/ContentEventHandler.cpp index c2ad7b385094..fdea8bcddd29 100644 --- a/dom/events/ContentEventHandler.cpp +++ b/dom/events/ContentEventHandler.cpp @@ -503,7 +503,7 @@ nsresult ContentEventHandler::QueryContentRect(nsIContent* aContent, WidgetQueryContentEvent* aEvent) { - NS_PRECONDITION(aContent, "aContent must not be null"); + MOZ_ASSERT(aContent, "aContent must not be null"); nsIFrame* frame = aContent->GetPrimaryFrame(); NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE); @@ -2699,7 +2699,7 @@ ContentEventHandler::OnQueryCharacterAtPoint(WidgetQueryContentEvent* aEvent) // The root frame's widget might be different, e.g., the event was fired on // a popup but the rootFrame is the document root. if (rootWidget != aEvent->mWidget) { - NS_PRECONDITION(aEvent->mWidget, "The event must have the widget"); + MOZ_ASSERT(aEvent->mWidget, "The event must have the widget"); nsView* view = nsView::GetViewFor(aEvent->mWidget); NS_ENSURE_TRUE(view, NS_ERROR_FAILURE); rootFrame = view->GetFrame(); diff --git a/dom/events/EventListenerService.cpp b/dom/events/EventListenerService.cpp index 8ab16e6ee58e..ee9c8832ab64 100644 --- a/dom/events/EventListenerService.cpp +++ b/dom/events/EventListenerService.cpp @@ -303,7 +303,7 @@ EventListenerService::AddSystemEventListener(EventTarget *aTarget, bool aUseCapture, JSContext* aCx) { - NS_PRECONDITION(aTarget, "Missing target"); + MOZ_ASSERT(aTarget, "Missing target"); NS_ENSURE_TRUE(aTarget, NS_ERROR_UNEXPECTED); @@ -329,7 +329,7 @@ EventListenerService::RemoveSystemEventListener(EventTarget *aTarget, bool aUseCapture, JSContext* aCx) { - NS_PRECONDITION(aTarget, "Missing target"); + MOZ_ASSERT(aTarget, "Missing target"); NS_ENSURE_TRUE(aTarget, NS_ERROR_UNEXPECTED); diff --git a/dom/events/EventStateManager.cpp b/dom/events/EventStateManager.cpp index a2686b40efd8..c426b378bc01 100644 --- a/dom/events/EventStateManager.cpp +++ b/dom/events/EventStateManager.cpp @@ -5272,11 +5272,11 @@ EventStateManager::SetContentState(nsIContent* aContent, EventStates aState) { // We manage 4 states here: ACTIVE, HOVER, DRAGOVER, URLTARGET // The input must be exactly one of them. - NS_PRECONDITION(aState == NS_EVENT_STATE_ACTIVE || - aState == NS_EVENT_STATE_HOVER || - aState == NS_EVENT_STATE_DRAGOVER || - aState == NS_EVENT_STATE_URLTARGET, - "Unexpected state"); + MOZ_ASSERT(aState == NS_EVENT_STATE_ACTIVE || + aState == NS_EVENT_STATE_HOVER || + aState == NS_EVENT_STATE_DRAGOVER || + aState == NS_EVENT_STATE_URLTARGET, + "Unexpected state"); nsCOMPtr notifyContent1; nsCOMPtr notifyContent2; @@ -5514,7 +5514,7 @@ EventStateManager::EnsureDocument(nsPresContext* aPresContext) void EventStateManager::FlushPendingEvents(nsPresContext* aPresContext) { - NS_PRECONDITION(nullptr != aPresContext, "nullptr ptr"); + MOZ_ASSERT(nullptr != aPresContext, "nullptr ptr"); nsIPresShell *shell = aPresContext->GetPresShell(); if (shell) { shell->FlushPendingNotifications(FlushType::InterruptibleLayout); diff --git a/dom/events/WheelHandlingHelper.cpp b/dom/events/WheelHandlingHelper.cpp index 38589f6ed9e0..e75edb2aa9ec 100644 --- a/dom/events/WheelHandlingHelper.cpp +++ b/dom/events/WheelHandlingHelper.cpp @@ -310,7 +310,7 @@ WheelTransaction::Shutdown() /* static */ void WheelTransaction::OnFailToScrollTarget() { - NS_PRECONDITION(sTargetFrame, "We don't have mouse scrolling transaction"); + MOZ_ASSERT(sTargetFrame, "We don't have mouse scrolling transaction"); if (Prefs::sTestMouseScroll) { // This event is used for automated tests, see bug 442774. diff --git a/dom/html/HTMLFormElement.cpp b/dom/html/HTMLFormElement.cpp index 2874e596874b..67d8b66dd05f 100644 --- a/dom/html/HTMLFormElement.cpp +++ b/dom/html/HTMLFormElement.cpp @@ -1762,9 +1762,9 @@ HTMLFormElement::GetActionURL(nsIURI** aActionURL, NS_IMETHODIMP_(nsIFormControl*) HTMLFormElement::GetDefaultSubmitElement() const { - NS_PRECONDITION(mDefaultSubmitElement == mFirstSubmitInElements || - mDefaultSubmitElement == mFirstSubmitNotInElements, - "What happened here?"); + MOZ_ASSERT(mDefaultSubmitElement == mFirstSubmitInElements || + mDefaultSubmitElement == mFirstSubmitNotInElements, + "What happened here?"); return mDefaultSubmitElement; } @@ -1772,7 +1772,7 @@ HTMLFormElement::GetDefaultSubmitElement() const bool HTMLFormElement::IsDefaultSubmitElement(const nsIFormControl* aControl) const { - NS_PRECONDITION(aControl, "Unexpected call"); + MOZ_ASSERT(aControl, "Unexpected call"); if (aControl == mDefaultSubmitElement) { // Yes, it is @@ -1821,7 +1821,7 @@ HTMLFormElement::ImplicitSubmissionIsDisabled() const bool HTMLFormElement::IsLastActiveElement(const nsIFormControl* aControl) const { - NS_PRECONDITION(aControl, "Unexpected call"); + MOZ_ASSERT(aControl, "Unexpected call"); for (auto* element : Reversed(mControls->mElements)) { if (element->IsSingleLineTextOrNumberControl(false) && diff --git a/dom/html/HTMLFrameSetElement.cpp b/dom/html/HTMLFrameSetElement.cpp index 5b7d675c980e..244525b2b33b 100644 --- a/dom/html/HTMLFrameSetElement.cpp +++ b/dom/html/HTMLFrameSetElement.cpp @@ -74,8 +74,8 @@ nsresult HTMLFrameSetElement::GetRowSpec(int32_t *aNumValues, const nsFramesetSpec** aSpecs) { - NS_PRECONDITION(aNumValues, "Must have a pointer to an integer here!"); - NS_PRECONDITION(aSpecs, "Must have a pointer to an array of nsFramesetSpecs"); + MOZ_ASSERT(aNumValues, "Must have a pointer to an integer here!"); + MOZ_ASSERT(aSpecs, "Must have a pointer to an array of nsFramesetSpecs"); *aNumValues = 0; *aSpecs = nullptr; @@ -104,8 +104,8 @@ nsresult HTMLFrameSetElement::GetColSpec(int32_t *aNumValues, const nsFramesetSpec** aSpecs) { - NS_PRECONDITION(aNumValues, "Must have a pointer to an integer here!"); - NS_PRECONDITION(aSpecs, "Must have a pointer to an array of nsFramesetSpecs"); + MOZ_ASSERT(aNumValues, "Must have a pointer to an integer here!"); + MOZ_ASSERT(aSpecs, "Must have a pointer to an array of nsFramesetSpecs"); *aNumValues = 0; *aSpecs = nullptr; diff --git a/dom/html/HTMLImageElement.cpp b/dom/html/HTMLImageElement.cpp index b21ca276697e..8a14cc175f79 100644 --- a/dom/html/HTMLImageElement.cpp +++ b/dom/html/HTMLImageElement.cpp @@ -865,7 +865,7 @@ HTMLImageElement::GetForm() const void HTMLImageElement::SetForm(HTMLFormElement* aForm) { - NS_PRECONDITION(aForm, "Don't pass null here"); + MOZ_ASSERT(aForm, "Don't pass null here"); NS_ASSERTION(!mForm, "We don't support switching from one non-null form to another."); diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp index 4ba4ef9f9371..ac2d691858f5 100644 --- a/dom/html/HTMLInputElement.cpp +++ b/dom/html/HTMLInputElement.cpp @@ -876,12 +876,12 @@ UploadLastDir::FetchDirectoryAndDisplayPicker(nsIDocument* aDoc, nsIFilePicker* aFilePicker, nsIFilePickerShownCallback* aFpCallback) { - NS_PRECONDITION(aDoc, "aDoc is null"); - NS_PRECONDITION(aFilePicker, "aFilePicker is null"); - NS_PRECONDITION(aFpCallback, "aFpCallback is null"); + MOZ_ASSERT(aDoc, "aDoc is null"); + MOZ_ASSERT(aFilePicker, "aFilePicker is null"); + MOZ_ASSERT(aFpCallback, "aFpCallback is null"); nsIURI* docURI = aDoc->GetDocumentURI(); - NS_PRECONDITION(docURI, "docURI is null"); + MOZ_ASSERT(docURI, "docURI is null"); nsCOMPtr loadContext = aDoc->GetLoadContext(); nsCOMPtr prefCallback = @@ -906,13 +906,13 @@ UploadLastDir::FetchDirectoryAndDisplayPicker(nsIDocument* aDoc, nsresult UploadLastDir::StoreLastUsedDirectory(nsIDocument* aDoc, nsIFile* aDir) { - NS_PRECONDITION(aDoc, "aDoc is null"); + MOZ_ASSERT(aDoc, "aDoc is null"); if (!aDir) { return NS_OK; } nsCOMPtr docURI = aDoc->GetDocumentURI(); - NS_PRECONDITION(docURI, "docURI is null"); + MOZ_ASSERT(docURI, "docURI is null"); // Attempt to get the CPS, if it's not present we'll just return nsCOMPtr contentPrefService = @@ -2794,8 +2794,8 @@ HTMLInputElement::SetValueInternal(const nsAString& aValue, const nsAString* aOldValue, uint32_t aFlags) { - NS_PRECONDITION(GetValueMode() != VALUE_MODE_FILENAME, - "Don't call SetValueInternal for file inputs"); + MOZ_ASSERT(GetValueMode() != VALUE_MODE_FILENAME, + "Don't call SetValueInternal for file inputs"); // We want to remember if the SetValueInternal() call is being made for a XUL // element. We do that by looking at the parent node here, and if that node diff --git a/dom/html/HTMLSharedElement.cpp b/dom/html/HTMLSharedElement.cpp index 8f74f5c9ce84..9f07c0b80e8a 100644 --- a/dom/html/HTMLSharedElement.cpp +++ b/dom/html/HTMLSharedElement.cpp @@ -120,7 +120,7 @@ HTMLSharedElement::IsAttributeMapped(const nsAtom* aAttribute) const static void SetBaseURIUsingFirstBaseWithHref(nsIDocument* aDocument, nsIContent* aMustMatch) { - NS_PRECONDITION(aDocument, "Need a document!"); + MOZ_ASSERT(aDocument, "Need a document!"); for (nsIContent* child = aDocument->GetFirstChild(); child; child = child->GetNextNode()) { @@ -173,7 +173,7 @@ static void SetBaseTargetUsingFirstBaseWithTarget(nsIDocument* aDocument, nsIContent* aMustMatch) { - NS_PRECONDITION(aDocument, "Need a document!"); + MOZ_ASSERT(aDocument, "Need a document!"); for (nsIContent* child = aDocument->GetFirstChild(); child; child = child->GetNextNode()) { diff --git a/dom/html/nsGenericHTMLElement.cpp b/dom/html/nsGenericHTMLElement.cpp index af8a7a0b90e1..d619b599d574 100644 --- a/dom/html/nsGenericHTMLElement.cpp +++ b/dom/html/nsGenericHTMLElement.cpp @@ -544,8 +544,8 @@ bool nsGenericHTMLElement::CheckHandleEventForAnchorsPreconditions( EventChainVisitor& aVisitor) { - NS_PRECONDITION(nsCOMPtr(do_QueryObject(this)), - "should be called only when |this| implements |Link|"); + MOZ_ASSERT(nsCOMPtr(do_QueryObject(this)), + "should be called only when |this| implements |Link|"); if (!aVisitor.mPresContext) { // We need a pres context to do link stuff. Some events (e.g. mutation @@ -589,7 +589,7 @@ nsGenericHTMLElement::PostHandleEventForAnchors(EventChainPostVisitor& aVisitor) bool nsGenericHTMLElement::IsHTMLLink(nsIURI** aURI) const { - NS_PRECONDITION(aURI, "Must provide aURI out param"); + MOZ_ASSERT(aURI, "Must provide aURI out param"); *aURI = GetHrefURIForAnchors().take(); // We promise out param is non-null if we return true, so base rv on it @@ -1683,7 +1683,7 @@ nsGenericHTMLFormElement::SaveSubtreeState() void nsGenericHTMLFormElement::SetForm(HTMLFormElement* aForm) { - NS_PRECONDITION(aForm, "Don't pass null here"); + MOZ_ASSERT(aForm, "Don't pass null here"); NS_ASSERTION(!mForm, "We don't support switching from one non-null form to another."); @@ -2223,8 +2223,8 @@ void nsGenericHTMLFormElement::UpdateFormOwner(bool aBindToTree, Element* aFormIdElement) { - NS_PRECONDITION(!aBindToTree || !aFormIdElement, - "aFormIdElement shouldn't be set if aBindToTree is true!"); + MOZ_ASSERT(!aBindToTree || !aFormIdElement, + "aFormIdElement shouldn't be set if aBindToTree is true!"); bool needStateUpdate = false; if (!aBindToTree) { diff --git a/dom/html/nsGenericHTMLFrameElement.cpp b/dom/html/nsGenericHTMLFrameElement.cpp index b895d83cb01a..db85fae519b3 100644 --- a/dom/html/nsGenericHTMLFrameElement.cpp +++ b/dom/html/nsGenericHTMLFrameElement.cpp @@ -84,7 +84,7 @@ nsGenericHTMLFrameElement::~nsGenericHTMLFrameElement() nsresult nsGenericHTMLFrameElement::GetContentDocument(nsIDOMDocument** aContentDocument) { - NS_PRECONDITION(aContentDocument, "Null out param"); + MOZ_ASSERT(aContentDocument, "Null out param"); nsCOMPtr document = do_QueryInterface(GetContentDocument(*nsContentUtils::SubjectPrincipal())); document.forget(aContentDocument); diff --git a/dom/html/nsHTMLContentSink.cpp b/dom/html/nsHTMLContentSink.cpp index c3200ba8095a..956b5cdaa7f7 100644 --- a/dom/html/nsHTMLContentSink.cpp +++ b/dom/html/nsHTMLContentSink.cpp @@ -785,7 +785,7 @@ HTMLContentSink::DidBuildModel(bool aTerminated) NS_IMETHODIMP HTMLContentSink::SetParser(nsParserBase* aParser) { - NS_PRECONDITION(aParser, "Should have a parser here!"); + MOZ_ASSERT(aParser, "Should have a parser here!"); mParser = aParser; return NS_OK; } @@ -968,7 +968,7 @@ HTMLContentSink::NotifyInsert(nsIContent* aContent, void HTMLContentSink::NotifyRootInsertion() { - NS_PRECONDITION(!mNotifiedRootInsertion, "Double-notifying on root?"); + MOZ_ASSERT(!mNotifiedRootInsertion, "Double-notifying on root?"); NS_ASSERTION(!mLayoutStarted, "How did we start layout without notifying on root?"); // Now make sure to notify that we have now inserted our root. If diff --git a/dom/jsurl/nsJSProtocolHandler.cpp b/dom/jsurl/nsJSProtocolHandler.cpp index 47a4abbb788a..b7ce60d1fcba 100644 --- a/dom/jsurl/nsJSProtocolHandler.cpp +++ b/dom/jsurl/nsJSProtocolHandler.cpp @@ -1415,7 +1415,7 @@ nsJSURI::EqualsInternal(nsIURI* aOther, bool* aResult) { NS_ENSURE_ARG_POINTER(aOther); - NS_PRECONDITION(aResult, "null pointer for outparam"); + MOZ_ASSERT(aResult, "null pointer for outparam"); RefPtr otherJSURI; nsresult rv = aOther->QueryInterface(kJSURICID, diff --git a/dom/script/nsIScriptElement.h b/dom/script/nsIScriptElement.h index a34d9453b2a4..efa8631bf8cd 100644 --- a/dom/script/nsIScriptElement.h +++ b/dom/script/nsIScriptElement.h @@ -64,13 +64,13 @@ public: */ nsIURI* GetScriptURI() { - NS_PRECONDITION(mFrozen, "Not ready for this call yet!"); + MOZ_ASSERT(mFrozen, "Not ready for this call yet!"); return mUri; } nsIPrincipal* GetScriptURITriggeringPrincipal() { - NS_PRECONDITION(mFrozen, "Not ready for this call yet!"); + MOZ_ASSERT(mFrozen, "Not ready for this call yet!"); return mSrcTriggeringPrincipal; } @@ -97,7 +97,7 @@ public: */ bool GetScriptIsModule() { - NS_PRECONDITION(mFrozen, "Not ready for this call yet!"); + MOZ_ASSERT(mFrozen, "Not ready for this call yet!"); return mIsModule; } @@ -106,7 +106,7 @@ public: */ bool GetScriptDeferred() { - NS_PRECONDITION(mFrozen, "Not ready for this call yet!"); + MOZ_ASSERT(mFrozen, "Not ready for this call yet!"); return mDefer; } @@ -115,7 +115,7 @@ public: */ bool GetScriptAsync() { - NS_PRECONDITION(mFrozen, "Not ready for this call yet!"); + MOZ_ASSERT(mFrozen, "Not ready for this call yet!"); return mAsync; } @@ -124,7 +124,7 @@ public: */ bool GetScriptExternal() { - NS_PRECONDITION(mFrozen, "Not ready for this call yet!"); + MOZ_ASSERT(mFrozen, "Not ready for this call yet!"); return mExternal; } diff --git a/dom/security/nsCSPContext.cpp b/dom/security/nsCSPContext.cpp index 14edf298820a..e51f58de0e74 100644 --- a/dom/security/nsCSPContext.cpp +++ b/dom/security/nsCSPContext.cpp @@ -734,8 +734,8 @@ NS_IMETHODIMP nsCSPContext::SetRequestContext(nsIDOMDocument* aDOMDocument, nsIPrincipal* aPrincipal) { - NS_PRECONDITION(aDOMDocument || aPrincipal, - "Can't set context without doc or principal"); + MOZ_ASSERT(aDOMDocument || aPrincipal, + "Can't set context without doc or principal"); NS_ENSURE_ARG(aDOMDocument || aPrincipal); if (aDOMDocument) { diff --git a/dom/smil/SMILBoolType.cpp b/dom/smil/SMILBoolType.cpp index f6ae19b794ba..a821b3852192 100644 --- a/dom/smil/SMILBoolType.cpp +++ b/dom/smil/SMILBoolType.cpp @@ -14,7 +14,7 @@ namespace mozilla { void SMILBoolType::Init(nsSMILValue& aValue) const { - NS_PRECONDITION(aValue.IsNull(), "Unexpected value type"); + MOZ_ASSERT(aValue.IsNull(), "Unexpected value type"); aValue.mU.mBool = false; aValue.mType = this; } @@ -22,7 +22,7 @@ SMILBoolType::Init(nsSMILValue& aValue) const void SMILBoolType::Destroy(nsSMILValue& aValue) const { - NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value"); + MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value"); aValue.mU.mBool = false; aValue.mType = nsSMILNullType::Singleton(); } @@ -30,8 +30,8 @@ SMILBoolType::Destroy(nsSMILValue& aValue) const nsresult SMILBoolType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const { - NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types"); - NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value"); + MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types"); + MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value"); aDest.mU.mBool = aSrc.mU.mBool; return NS_OK; } @@ -40,8 +40,8 @@ bool SMILBoolType::IsEqual(const nsSMILValue& aLeft, const nsSMILValue& aRight) const { - NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types"); - NS_PRECONDITION(aLeft.mType == this, "Unexpected type for SMIL value"); + MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types"); + MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value"); return aLeft.mU.mBool == aRight.mU.mBool; } @@ -50,9 +50,8 @@ nsresult SMILBoolType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd, uint32_t aCount) const { - NS_PRECONDITION(aValueToAdd.mType == aDest.mType, - "Trying to add invalid types"); - NS_PRECONDITION(aValueToAdd.mType == this, "Unexpected source type"); + MOZ_ASSERT(aValueToAdd.mType == aDest.mType, "Trying to add invalid types"); + MOZ_ASSERT(aValueToAdd.mType == this, "Unexpected source type"); return NS_ERROR_FAILURE; // bool values can't be added to each other } @@ -61,8 +60,8 @@ SMILBoolType::ComputeDistance(const nsSMILValue& aFrom, const nsSMILValue& aTo, double& aDistance) const { - NS_PRECONDITION(aFrom.mType == aTo.mType,"Trying to compare different types"); - NS_PRECONDITION(aFrom.mType == this, "Unexpected source type"); + MOZ_ASSERT(aFrom.mType == aTo.mType, "Trying to compare different types"); + MOZ_ASSERT(aFrom.mType == this, "Unexpected source type"); return NS_ERROR_FAILURE; // there is no concept of distance between bool values } @@ -72,11 +71,11 @@ SMILBoolType::Interpolate(const nsSMILValue& aStartVal, double aUnitDistance, nsSMILValue& aResult) const { - NS_PRECONDITION(aStartVal.mType == aEndVal.mType, - "Trying to interpolate different types"); - NS_PRECONDITION(aStartVal.mType == this, + MOZ_ASSERT(aStartVal.mType == aEndVal.mType, + "Trying to interpolate different types"); + MOZ_ASSERT(aStartVal.mType == this, "Unexpected types for interpolation"); - NS_PRECONDITION(aResult.mType == this, "Unexpected result type"); + MOZ_ASSERT(aResult.mType == this, "Unexpected result type"); return NS_ERROR_FAILURE; // bool values do not interpolate } diff --git a/dom/smil/SMILEnumType.cpp b/dom/smil/SMILEnumType.cpp index 2aa7a04c1260..a552045ea0f1 100644 --- a/dom/smil/SMILEnumType.cpp +++ b/dom/smil/SMILEnumType.cpp @@ -14,7 +14,7 @@ namespace mozilla { void SMILEnumType::Init(nsSMILValue& aValue) const { - NS_PRECONDITION(aValue.IsNull(), "Unexpected value type"); + MOZ_ASSERT(aValue.IsNull(), "Unexpected value type"); aValue.mU.mUint = 0; aValue.mType = this; } @@ -22,7 +22,7 @@ SMILEnumType::Init(nsSMILValue& aValue) const void SMILEnumType::Destroy(nsSMILValue& aValue) const { - NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value"); + MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value"); aValue.mU.mUint = 0; aValue.mType = nsSMILNullType::Singleton(); } @@ -30,8 +30,8 @@ SMILEnumType::Destroy(nsSMILValue& aValue) const nsresult SMILEnumType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const { - NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types"); - NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value"); + MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types"); + MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value"); aDest.mU.mUint = aSrc.mU.mUint; return NS_OK; } @@ -40,8 +40,8 @@ bool SMILEnumType::IsEqual(const nsSMILValue& aLeft, const nsSMILValue& aRight) const { - NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types"); - NS_PRECONDITION(aLeft.mType == this, "Unexpected type for SMIL value"); + MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types"); + MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value"); return aLeft.mU.mUint == aRight.mU.mUint; } @@ -50,9 +50,9 @@ nsresult SMILEnumType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd, uint32_t aCount) const { - NS_PRECONDITION(aValueToAdd.mType == aDest.mType, + MOZ_ASSERT(aValueToAdd.mType == aDest.mType, "Trying to add invalid types"); - NS_PRECONDITION(aValueToAdd.mType == this, "Unexpected source type"); + MOZ_ASSERT(aValueToAdd.mType == this, "Unexpected source type"); return NS_ERROR_FAILURE; // enum values can't be added to each other } @@ -61,8 +61,8 @@ SMILEnumType::ComputeDistance(const nsSMILValue& aFrom, const nsSMILValue& aTo, double& aDistance) const { - NS_PRECONDITION(aFrom.mType == aTo.mType,"Trying to compare different types"); - NS_PRECONDITION(aFrom.mType == this, "Unexpected source type"); + MOZ_ASSERT(aFrom.mType == aTo.mType,"Trying to compare different types"); + MOZ_ASSERT(aFrom.mType == this, "Unexpected source type"); return NS_ERROR_FAILURE; // there is no concept of distance between enum values } @@ -72,11 +72,11 @@ SMILEnumType::Interpolate(const nsSMILValue& aStartVal, double aUnitDistance, nsSMILValue& aResult) const { - NS_PRECONDITION(aStartVal.mType == aEndVal.mType, + MOZ_ASSERT(aStartVal.mType == aEndVal.mType, "Trying to interpolate different types"); - NS_PRECONDITION(aStartVal.mType == this, + MOZ_ASSERT(aStartVal.mType == this, "Unexpected types for interpolation"); - NS_PRECONDITION(aResult.mType == this, "Unexpected result type"); + MOZ_ASSERT(aResult.mType == this, "Unexpected result type"); return NS_ERROR_FAILURE; // enum values do not interpolate } diff --git a/dom/smil/SMILIntegerType.cpp b/dom/smil/SMILIntegerType.cpp index 194653e1b3a7..058d30c19665 100644 --- a/dom/smil/SMILIntegerType.cpp +++ b/dom/smil/SMILIntegerType.cpp @@ -22,7 +22,7 @@ SMILIntegerType::Init(nsSMILValue& aValue) const void SMILIntegerType::Destroy(nsSMILValue& aValue) const { - NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value"); + MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value"); aValue.mU.mInt = 0; aValue.mType = nsSMILNullType::Singleton(); } @@ -30,8 +30,8 @@ SMILIntegerType::Destroy(nsSMILValue& aValue) const nsresult SMILIntegerType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const { - NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types"); - NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value"); + MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types"); + MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value"); aDest.mU.mInt = aSrc.mU.mInt; return NS_OK; } @@ -40,8 +40,8 @@ bool SMILIntegerType::IsEqual(const nsSMILValue& aLeft, const nsSMILValue& aRight) const { - NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types"); - NS_PRECONDITION(aLeft.mType == this, "Unexpected type for SMIL value"); + MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types"); + MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value"); return aLeft.mU.mInt == aRight.mU.mInt; } @@ -50,9 +50,9 @@ nsresult SMILIntegerType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd, uint32_t aCount) const { - NS_PRECONDITION(aValueToAdd.mType == aDest.mType, + MOZ_ASSERT(aValueToAdd.mType == aDest.mType, "Trying to add invalid types"); - NS_PRECONDITION(aValueToAdd.mType == this, "Unexpected source type"); + MOZ_ASSERT(aValueToAdd.mType == this, "Unexpected source type"); aDest.mU.mInt += aValueToAdd.mU.mInt * aCount; return NS_OK; } @@ -62,8 +62,8 @@ SMILIntegerType::ComputeDistance(const nsSMILValue& aFrom, const nsSMILValue& aTo, double& aDistance) const { - NS_PRECONDITION(aFrom.mType == aTo.mType,"Trying to compare different types"); - NS_PRECONDITION(aFrom.mType == this, "Unexpected source type"); + MOZ_ASSERT(aFrom.mType == aTo.mType, "Trying to compare different types"); + MOZ_ASSERT(aFrom.mType == this, "Unexpected source type"); aDistance = fabs(double(aTo.mU.mInt - aFrom.mU.mInt)); return NS_OK; } @@ -74,11 +74,10 @@ SMILIntegerType::Interpolate(const nsSMILValue& aStartVal, double aUnitDistance, nsSMILValue& aResult) const { - NS_PRECONDITION(aStartVal.mType == aEndVal.mType, - "Trying to interpolate different types"); - NS_PRECONDITION(aStartVal.mType == this, - "Unexpected types for interpolation"); - NS_PRECONDITION(aResult.mType == this, "Unexpected result type"); + MOZ_ASSERT(aStartVal.mType == aEndVal.mType, + "Trying to interpolate different types"); + MOZ_ASSERT(aStartVal.mType == this, "Unexpected types for interpolation"); + MOZ_ASSERT(aResult.mType == this, "Unexpected result type"); const double startVal = double(aStartVal.mU.mInt); const double endVal = double(aEndVal.mU.mInt); diff --git a/dom/smil/SMILStringType.cpp b/dom/smil/SMILStringType.cpp index d67323b7e3dd..6510f6cf666c 100644 --- a/dom/smil/SMILStringType.cpp +++ b/dom/smil/SMILStringType.cpp @@ -14,7 +14,7 @@ namespace mozilla { void SMILStringType::Init(nsSMILValue& aValue) const { - NS_PRECONDITION(aValue.IsNull(), "Unexpected value type"); + MOZ_ASSERT(aValue.IsNull(), "Unexpected value type"); aValue.mU.mPtr = new nsString(); aValue.mType = this; } @@ -22,7 +22,7 @@ SMILStringType::Init(nsSMILValue& aValue) const void SMILStringType::Destroy(nsSMILValue& aValue) const { - NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value"); + MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value"); delete static_cast(aValue.mU.mPtr); aValue.mU.mPtr = nullptr; aValue.mType = nsSMILNullType::Singleton(); @@ -31,8 +31,8 @@ SMILStringType::Destroy(nsSMILValue& aValue) const nsresult SMILStringType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const { - NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types"); - NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value"); + MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types"); + MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value"); const nsAString* src = static_cast(aSrc.mU.mPtr); nsAString* dst = static_cast(aDest.mU.mPtr); @@ -44,8 +44,8 @@ bool SMILStringType::IsEqual(const nsSMILValue& aLeft, const nsSMILValue& aRight) const { - NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types"); - NS_PRECONDITION(aLeft.mType == this, "Unexpected type for SMIL value"); + MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types"); + MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value"); const nsAString* leftString = static_cast(aLeft.mU.mPtr); @@ -58,9 +58,9 @@ nsresult SMILStringType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd, uint32_t aCount) const { - NS_PRECONDITION(aValueToAdd.mType == aDest.mType, + MOZ_ASSERT(aValueToAdd.mType == aDest.mType, "Trying to add invalid types"); - NS_PRECONDITION(aValueToAdd.mType == this, "Unexpected source type"); + MOZ_ASSERT(aValueToAdd.mType == this, "Unexpected source type"); return NS_ERROR_FAILURE; // string values can't be added to each other } @@ -69,8 +69,8 @@ SMILStringType::ComputeDistance(const nsSMILValue& aFrom, const nsSMILValue& aTo, double& aDistance) const { - NS_PRECONDITION(aFrom.mType == aTo.mType,"Trying to compare different types"); - NS_PRECONDITION(aFrom.mType == this, "Unexpected source type"); + MOZ_ASSERT(aFrom.mType == aTo.mType, "Trying to compare different types"); + MOZ_ASSERT(aFrom.mType == this, "Unexpected source type"); return NS_ERROR_FAILURE; // there is no concept of distance between string values } @@ -80,11 +80,10 @@ SMILStringType::Interpolate(const nsSMILValue& aStartVal, double aUnitDistance, nsSMILValue& aResult) const { - NS_PRECONDITION(aStartVal.mType == aEndVal.mType, - "Trying to interpolate different types"); - NS_PRECONDITION(aStartVal.mType == this, - "Unexpected types for interpolation"); - NS_PRECONDITION(aResult.mType == this, "Unexpected result type"); + MOZ_ASSERT(aStartVal.mType == aEndVal.mType, + "Trying to interpolate different types"); + MOZ_ASSERT(aStartVal.mType == this, "Unexpected types for interpolation"); + MOZ_ASSERT(aResult.mType == this, "Unexpected result type"); return NS_ERROR_FAILURE; // string values do not interpolate } diff --git a/dom/smil/nsSMILFloatType.cpp b/dom/smil/nsSMILFloatType.cpp index d3e2980430ed..da9fd298c9a0 100644 --- a/dom/smil/nsSMILFloatType.cpp +++ b/dom/smil/nsSMILFloatType.cpp @@ -12,7 +12,7 @@ void nsSMILFloatType::Init(nsSMILValue& aValue) const { - NS_PRECONDITION(aValue.IsNull(), "Unexpected value type"); + MOZ_ASSERT(aValue.IsNull(), "Unexpected value type"); aValue.mU.mDouble = 0.0; aValue.mType = this; } @@ -20,7 +20,7 @@ nsSMILFloatType::Init(nsSMILValue& aValue) const void nsSMILFloatType::Destroy(nsSMILValue& aValue) const { - NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value"); + MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value"); aValue.mU.mDouble = 0.0; aValue.mType = nsSMILNullType::Singleton(); } @@ -28,8 +28,8 @@ nsSMILFloatType::Destroy(nsSMILValue& aValue) const nsresult nsSMILFloatType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const { - NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types"); - NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value"); + MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types"); + MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value"); aDest.mU.mDouble = aSrc.mU.mDouble; return NS_OK; } @@ -38,8 +38,8 @@ bool nsSMILFloatType::IsEqual(const nsSMILValue& aLeft, const nsSMILValue& aRight) const { - NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types"); - NS_PRECONDITION(aLeft.mType == this, "Unexpected type for SMIL value"); + MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types"); + MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value"); return aLeft.mU.mDouble == aRight.mU.mDouble; } @@ -48,9 +48,9 @@ nsresult nsSMILFloatType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd, uint32_t aCount) const { - NS_PRECONDITION(aValueToAdd.mType == aDest.mType, + MOZ_ASSERT(aValueToAdd.mType == aDest.mType, "Trying to add invalid types"); - NS_PRECONDITION(aValueToAdd.mType == this, "Unexpected source type"); + MOZ_ASSERT(aValueToAdd.mType == this, "Unexpected source type"); aDest.mU.mDouble += aValueToAdd.mU.mDouble * aCount; return NS_OK; } @@ -60,8 +60,8 @@ nsSMILFloatType::ComputeDistance(const nsSMILValue& aFrom, const nsSMILValue& aTo, double& aDistance) const { - NS_PRECONDITION(aFrom.mType == aTo.mType,"Trying to compare different types"); - NS_PRECONDITION(aFrom.mType == this, "Unexpected source type"); + MOZ_ASSERT(aFrom.mType == aTo.mType, "Trying to compare different types"); + MOZ_ASSERT(aFrom.mType == this, "Unexpected source type"); const double &from = aFrom.mU.mDouble; const double &to = aTo.mU.mDouble; @@ -77,11 +77,11 @@ nsSMILFloatType::Interpolate(const nsSMILValue& aStartVal, double aUnitDistance, nsSMILValue& aResult) const { - NS_PRECONDITION(aStartVal.mType == aEndVal.mType, - "Trying to interpolate different types"); - NS_PRECONDITION(aStartVal.mType == this, + MOZ_ASSERT(aStartVal.mType == aEndVal.mType, + "Trying to interpolate different types"); + MOZ_ASSERT(aStartVal.mType == this, "Unexpected types for interpolation"); - NS_PRECONDITION(aResult.mType == this, "Unexpected result type"); + MOZ_ASSERT(aResult.mType == this, "Unexpected result type"); const double &startVal = aStartVal.mU.mDouble; const double &endVal = aEndVal.mU.mDouble; diff --git a/dom/smil/nsSMILNullType.cpp b/dom/smil/nsSMILNullType.cpp index 795a93df4b88..2d387c18b46f 100644 --- a/dom/smil/nsSMILNullType.cpp +++ b/dom/smil/nsSMILNullType.cpp @@ -18,8 +18,8 @@ nsSMILNullType::Singleton() nsresult nsSMILNullType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const { - NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types"); - NS_PRECONDITION(aSrc.mType == this, "Unexpected source type"); + MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types"); + MOZ_ASSERT(aSrc.mType == this, "Unexpected source type"); aDest.mU = aSrc.mU; aDest.mType = Singleton(); return NS_OK; @@ -29,8 +29,8 @@ bool nsSMILNullType::IsEqual(const nsSMILValue& aLeft, const nsSMILValue& aRight) const { - NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types"); - NS_PRECONDITION(aLeft.mType == this, "Unexpected type for SMIL value"); + MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types"); + MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value"); return true; // All null-typed values are equivalent. } diff --git a/dom/svg/SVGIntegerPairSMILType.cpp b/dom/svg/SVGIntegerPairSMILType.cpp index e13fae3f58fe..ceb2990c208b 100644 --- a/dom/svg/SVGIntegerPairSMILType.cpp +++ b/dom/svg/SVGIntegerPairSMILType.cpp @@ -24,7 +24,7 @@ SVGIntegerPairSMILType::Init(nsSMILValue& aValue) const void SVGIntegerPairSMILType::Destroy(nsSMILValue& aValue) const { - NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value"); + MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value"); aValue.mU.mIntPair[0] = 0; aValue.mU.mIntPair[1] = 0; aValue.mType = nsSMILNullType::Singleton(); @@ -33,8 +33,8 @@ SVGIntegerPairSMILType::Destroy(nsSMILValue& aValue) const nsresult SVGIntegerPairSMILType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const { - NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types"); - NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value"); + MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types"); + MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value"); aDest.mU.mIntPair[0] = aSrc.mU.mIntPair[0]; aDest.mU.mIntPair[1] = aSrc.mU.mIntPair[1]; @@ -45,8 +45,8 @@ bool SVGIntegerPairSMILType::IsEqual(const nsSMILValue& aLeft, const nsSMILValue& aRight) const { - NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types"); - NS_PRECONDITION(aLeft.mType == this, "Unexpected type for SMIL value"); + MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types"); + MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value"); return aLeft.mU.mIntPair[0] == aRight.mU.mIntPair[0] && aLeft.mU.mIntPair[1] == aRight.mU.mIntPair[1]; @@ -56,9 +56,9 @@ nsresult SVGIntegerPairSMILType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd, uint32_t aCount) const { - NS_PRECONDITION(aValueToAdd.mType == aDest.mType, + MOZ_ASSERT(aValueToAdd.mType == aDest.mType, "Trying to add invalid types"); - NS_PRECONDITION(aValueToAdd.mType == this, "Unexpected source type"); + MOZ_ASSERT(aValueToAdd.mType == this, "Unexpected source type"); aDest.mU.mIntPair[0] += aValueToAdd.mU.mIntPair[0] * aCount; aDest.mU.mIntPair[1] += aValueToAdd.mU.mIntPair[1] * aCount; @@ -71,8 +71,8 @@ SVGIntegerPairSMILType::ComputeDistance(const nsSMILValue& aFrom, const nsSMILValue& aTo, double& aDistance) const { - NS_PRECONDITION(aFrom.mType == aTo.mType,"Trying to compare different types"); - NS_PRECONDITION(aFrom.mType == this, "Unexpected source type"); + MOZ_ASSERT(aFrom.mType == aTo.mType,"Trying to compare different types"); + MOZ_ASSERT(aFrom.mType == this, "Unexpected source type"); double delta[2]; delta[0] = aTo.mU.mIntPair[0] - aFrom.mU.mIntPair[0]; @@ -88,11 +88,10 @@ SVGIntegerPairSMILType::Interpolate(const nsSMILValue& aStartVal, double aUnitDistance, nsSMILValue& aResult) const { - NS_PRECONDITION(aStartVal.mType == aEndVal.mType, - "Trying to interpolate different types"); - NS_PRECONDITION(aStartVal.mType == this, - "Unexpected types for interpolation"); - NS_PRECONDITION(aResult.mType == this, "Unexpected result type"); + MOZ_ASSERT(aStartVal.mType == aEndVal.mType, + "Trying to interpolate different types"); + MOZ_ASSERT(aStartVal.mType == this, "Unexpected types for interpolation"); + MOZ_ASSERT(aResult.mType == this, "Unexpected result type"); double currentVal[2]; currentVal[0] = aStartVal.mU.mIntPair[0] + diff --git a/dom/svg/SVGLengthListSMILType.cpp b/dom/svg/SVGLengthListSMILType.cpp index 8664965a2516..0ea3a89799f8 100644 --- a/dom/svg/SVGLengthListSMILType.cpp +++ b/dom/svg/SVGLengthListSMILType.cpp @@ -36,7 +36,7 @@ SVGLengthListSMILType::Init(nsSMILValue &aValue) const void SVGLengthListSMILType::Destroy(nsSMILValue& aValue) const { - NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value type"); + MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value type"); delete static_cast(aValue.mU.mPtr); aValue.mU.mPtr = nullptr; aValue.mType = nsSMILNullType::Singleton(); @@ -46,8 +46,8 @@ nsresult SVGLengthListSMILType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const { - NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types"); - NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value"); + MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types"); + MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value"); const SVGLengthListAndInfo* src = static_cast(aSrc.mU.mPtr); @@ -61,8 +61,8 @@ bool SVGLengthListSMILType::IsEqual(const nsSMILValue& aLeft, const nsSMILValue& aRight) const { - NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types"); - NS_PRECONDITION(aLeft.mType == this, "Unexpected type for SMIL value"); + MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types"); + MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value"); return *static_cast(aLeft.mU.mPtr) == *static_cast(aRight.mU.mPtr); @@ -73,8 +73,8 @@ SVGLengthListSMILType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd, uint32_t aCount) const { - NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL type"); - NS_PRECONDITION(aValueToAdd.mType == this, "Incompatible SMIL type"); + MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL type"); + MOZ_ASSERT(aValueToAdd.mType == this, "Incompatible SMIL type"); SVGLengthListAndInfo& dest = *static_cast(aDest.mU.mPtr); @@ -161,8 +161,8 @@ SVGLengthListSMILType::ComputeDistance(const nsSMILValue& aFrom, const nsSMILValue& aTo, double& aDistance) const { - NS_PRECONDITION(aFrom.mType == this, "Unexpected SMIL type"); - NS_PRECONDITION(aTo.mType == this, "Incompatible SMIL type"); + MOZ_ASSERT(aFrom.mType == this, "Unexpected SMIL type"); + MOZ_ASSERT(aTo.mType == this, "Incompatible SMIL type"); const SVGLengthListAndInfo& from = *static_cast(aFrom.mU.mPtr); @@ -231,11 +231,10 @@ SVGLengthListSMILType::Interpolate(const nsSMILValue& aStartVal, double aUnitDistance, nsSMILValue& aResult) const { - NS_PRECONDITION(aStartVal.mType == aEndVal.mType, - "Trying to interpolate different types"); - NS_PRECONDITION(aStartVal.mType == this, - "Unexpected types for interpolation"); - NS_PRECONDITION(aResult.mType == this, "Unexpected result type"); + MOZ_ASSERT(aStartVal.mType == aEndVal.mType, + "Trying to interpolate different types"); + MOZ_ASSERT(aStartVal.mType == this, "Unexpected types for interpolation"); + MOZ_ASSERT(aResult.mType == this, "Unexpected result type"); const SVGLengthListAndInfo& start = *static_cast(aStartVal.mU.mPtr); diff --git a/dom/svg/SVGNumberListSMILType.cpp b/dom/svg/SVGNumberListSMILType.cpp index 51bc27a688ea..0d7b8b28cc70 100644 --- a/dom/svg/SVGNumberListSMILType.cpp +++ b/dom/svg/SVGNumberListSMILType.cpp @@ -49,7 +49,7 @@ SVGNumberListSMILType::Init(nsSMILValue &aValue) const void SVGNumberListSMILType::Destroy(nsSMILValue& aValue) const { - NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value type"); + MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value type"); delete static_cast(aValue.mU.mPtr); aValue.mU.mPtr = nullptr; aValue.mType = nsSMILNullType::Singleton(); @@ -59,8 +59,8 @@ nsresult SVGNumberListSMILType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const { - NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types"); - NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value"); + MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types"); + MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value"); const SVGNumberListAndInfo* src = static_cast(aSrc.mU.mPtr); @@ -74,8 +74,8 @@ bool SVGNumberListSMILType::IsEqual(const nsSMILValue& aLeft, const nsSMILValue& aRight) const { - NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types"); - NS_PRECONDITION(aLeft.mType == this, "Unexpected type for SMIL value"); + MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types"); + MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value"); return *static_cast(aLeft.mU.mPtr) == *static_cast(aRight.mU.mPtr); @@ -86,8 +86,8 @@ SVGNumberListSMILType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd, uint32_t aCount) const { - NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL type"); - NS_PRECONDITION(aValueToAdd.mType == this, "Incompatible SMIL type"); + MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL type"); + MOZ_ASSERT(aValueToAdd.mType == this, "Incompatible SMIL type"); SVGNumberListAndInfo& dest = *static_cast(aDest.mU.mPtr); @@ -133,8 +133,8 @@ SVGNumberListSMILType::ComputeDistance(const nsSMILValue& aFrom, const nsSMILValue& aTo, double& aDistance) const { - NS_PRECONDITION(aFrom.mType == this, "Unexpected SMIL type"); - NS_PRECONDITION(aTo.mType == this, "Incompatible SMIL type"); + MOZ_ASSERT(aFrom.mType == this, "Unexpected SMIL type"); + MOZ_ASSERT(aTo.mType == this, "Incompatible SMIL type"); const SVGNumberListAndInfo& from = *static_cast(aFrom.mU.mPtr); @@ -171,11 +171,10 @@ SVGNumberListSMILType::Interpolate(const nsSMILValue& aStartVal, double aUnitDistance, nsSMILValue& aResult) const { - NS_PRECONDITION(aStartVal.mType == aEndVal.mType, - "Trying to interpolate different types"); - NS_PRECONDITION(aStartVal.mType == this, - "Unexpected types for interpolation"); - NS_PRECONDITION(aResult.mType == this, "Unexpected result type"); + MOZ_ASSERT(aStartVal.mType == aEndVal.mType, + "Trying to interpolate different types"); + MOZ_ASSERT(aStartVal.mType == this, "Unexpected types for interpolation"); + MOZ_ASSERT(aResult.mType == this, "Unexpected result type"); const SVGNumberListAndInfo& start = *static_cast(aStartVal.mU.mPtr); diff --git a/dom/svg/SVGNumberPairSMILType.cpp b/dom/svg/SVGNumberPairSMILType.cpp index e314dfcf1d12..e5f03e9d2c87 100644 --- a/dom/svg/SVGNumberPairSMILType.cpp +++ b/dom/svg/SVGNumberPairSMILType.cpp @@ -26,7 +26,7 @@ SVGNumberPairSMILType::Init(nsSMILValue& aValue) const void SVGNumberPairSMILType::Destroy(nsSMILValue& aValue) const { - NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value"); + MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value"); aValue.mU.mNumberPair[0] = 0; aValue.mU.mNumberPair[1] = 0; aValue.mType = nsSMILNullType::Singleton(); @@ -35,8 +35,8 @@ SVGNumberPairSMILType::Destroy(nsSMILValue& aValue) const nsresult SVGNumberPairSMILType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const { - NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types"); - NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value"); + MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types"); + MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value"); aDest.mU.mNumberPair[0] = aSrc.mU.mNumberPair[0]; aDest.mU.mNumberPair[1] = aSrc.mU.mNumberPair[1]; @@ -47,8 +47,8 @@ bool SVGNumberPairSMILType::IsEqual(const nsSMILValue& aLeft, const nsSMILValue& aRight) const { - NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types"); - NS_PRECONDITION(aLeft.mType == this, "Unexpected type for SMIL value"); + MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types"); + MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value"); return aLeft.mU.mNumberPair[0] == aRight.mU.mNumberPair[0] && aLeft.mU.mNumberPair[1] == aRight.mU.mNumberPair[1]; @@ -58,9 +58,9 @@ nsresult SVGNumberPairSMILType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd, uint32_t aCount) const { - NS_PRECONDITION(aValueToAdd.mType == aDest.mType, + MOZ_ASSERT(aValueToAdd.mType == aDest.mType, "Trying to add invalid types"); - NS_PRECONDITION(aValueToAdd.mType == this, "Unexpected source type"); + MOZ_ASSERT(aValueToAdd.mType == this, "Unexpected source type"); aDest.mU.mNumberPair[0] += aValueToAdd.mU.mNumberPair[0] * aCount; aDest.mU.mNumberPair[1] += aValueToAdd.mU.mNumberPair[1] * aCount; @@ -73,8 +73,8 @@ SVGNumberPairSMILType::ComputeDistance(const nsSMILValue& aFrom, const nsSMILValue& aTo, double& aDistance) const { - NS_PRECONDITION(aFrom.mType == aTo.mType,"Trying to compare different types"); - NS_PRECONDITION(aFrom.mType == this, "Unexpected source type"); + MOZ_ASSERT(aFrom.mType == aTo.mType,"Trying to compare different types"); + MOZ_ASSERT(aFrom.mType == this, "Unexpected source type"); double delta[2]; delta[0] = aTo.mU.mNumberPair[0] - aFrom.mU.mNumberPair[0]; @@ -90,11 +90,10 @@ SVGNumberPairSMILType::Interpolate(const nsSMILValue& aStartVal, double aUnitDistance, nsSMILValue& aResult) const { - NS_PRECONDITION(aStartVal.mType == aEndVal.mType, - "Trying to interpolate different types"); - NS_PRECONDITION(aStartVal.mType == this, - "Unexpected types for interpolation"); - NS_PRECONDITION(aResult.mType == this, "Unexpected result type"); + MOZ_ASSERT(aStartVal.mType == aEndVal.mType, + "Trying to interpolate different types"); + MOZ_ASSERT(aStartVal.mType == this, "Unexpected types for interpolation"); + MOZ_ASSERT(aResult.mType == this, "Unexpected result type"); aResult.mU.mNumberPair[0] = float(aStartVal.mU.mNumberPair[0] + diff --git a/dom/svg/SVGOrientSMILType.cpp b/dom/svg/SVGOrientSMILType.cpp index e129c084eb47..408e1c63b3f9 100644 --- a/dom/svg/SVGOrientSMILType.cpp +++ b/dom/svg/SVGOrientSMILType.cpp @@ -32,7 +32,7 @@ SVGOrientSMILType::Init(nsSMILValue& aValue) const void SVGOrientSMILType::Destroy(nsSMILValue& aValue) const { - NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value."); + MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value."); aValue.mU.mPtr = nullptr; aValue.mType = nsSMILNullType::Singleton(); } @@ -40,8 +40,8 @@ SVGOrientSMILType::Destroy(nsSMILValue& aValue) const nsresult SVGOrientSMILType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const { - NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types."); - NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value."); + MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types."); + MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value."); aDest.mU.mOrient.mAngle = aSrc.mU.mOrient.mAngle; aDest.mU.mOrient.mUnit = aSrc.mU.mOrient.mUnit; @@ -53,8 +53,8 @@ bool SVGOrientSMILType::IsEqual(const nsSMILValue& aLeft, const nsSMILValue& aRight) const { - NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types"); - NS_PRECONDITION(aLeft.mType == this, "Unexpected type for SMIL value"); + MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types"); + MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value"); return aLeft.mU.mOrient.mAngle == aRight.mU.mOrient.mAngle && @@ -66,9 +66,9 @@ nsresult SVGOrientSMILType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd, uint32_t aCount) const { - NS_PRECONDITION(aValueToAdd.mType == aDest.mType, + MOZ_ASSERT(aValueToAdd.mType == aDest.mType, "Trying to add invalid types"); - NS_PRECONDITION(aValueToAdd.mType == this, "Unexpected source type"); + MOZ_ASSERT(aValueToAdd.mType == this, "Unexpected source type"); if (aDest.mU.mOrient.mOrientType != SVG_MARKER_ORIENT_ANGLE || aValueToAdd.mU.mOrient.mOrientType != SVG_MARKER_ORIENT_ANGLE) { @@ -98,8 +98,8 @@ SVGOrientSMILType::ComputeDistance(const nsSMILValue& aFrom, const nsSMILValue& aTo, double& aDistance) const { - NS_PRECONDITION(aFrom.mType == aTo.mType,"Trying to compare different types"); - NS_PRECONDITION(aFrom.mType == this, "Unexpected source type"); + MOZ_ASSERT(aFrom.mType == aTo.mType,"Trying to compare different types"); + MOZ_ASSERT(aFrom.mType == this, "Unexpected source type"); if (aFrom.mU.mOrient.mOrientType != SVG_MARKER_ORIENT_ANGLE || aTo.mU.mOrient.mOrientType != SVG_MARKER_ORIENT_ANGLE) { @@ -124,11 +124,10 @@ SVGOrientSMILType::Interpolate(const nsSMILValue& aStartVal, double aUnitDistance, nsSMILValue& aResult) const { - NS_PRECONDITION(aStartVal.mType == aEndVal.mType, - "Trying to interpolate different types"); - NS_PRECONDITION(aStartVal.mType == this, - "Unexpected types for interpolation."); - NS_PRECONDITION(aResult.mType == this, "Unexpected result type."); + MOZ_ASSERT(aStartVal.mType == aEndVal.mType, + "Trying to interpolate different types"); + MOZ_ASSERT(aStartVal.mType == this, "Unexpected types for interpolation."); + MOZ_ASSERT(aResult.mType == this, "Unexpected result type."); if (aStartVal.mU.mOrient.mOrientType != SVG_MARKER_ORIENT_ANGLE || aEndVal.mU.mOrient.mOrientType != SVG_MARKER_ORIENT_ANGLE) { diff --git a/dom/svg/SVGPathSegListSMILType.cpp b/dom/svg/SVGPathSegListSMILType.cpp index 0ddd7783c925..92469a5108fb 100644 --- a/dom/svg/SVGPathSegListSMILType.cpp +++ b/dom/svg/SVGPathSegListSMILType.cpp @@ -32,7 +32,7 @@ SVGPathSegListSMILType::Init(nsSMILValue &aValue) const void SVGPathSegListSMILType::Destroy(nsSMILValue& aValue) const { - NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value type"); + MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value type"); delete static_cast(aValue.mU.mPtr); aValue.mU.mPtr = nullptr; aValue.mType = nsSMILNullType::Singleton(); @@ -42,8 +42,8 @@ nsresult SVGPathSegListSMILType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const { - NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types"); - NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value"); + MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types"); + MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value"); const SVGPathDataAndInfo* src = static_cast(aSrc.mU.mPtr); @@ -57,8 +57,8 @@ bool SVGPathSegListSMILType::IsEqual(const nsSMILValue& aLeft, const nsSMILValue& aRight) const { - NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types"); - NS_PRECONDITION(aLeft.mType == this, "Unexpected type for SMIL value"); + MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types"); + MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value"); return *static_cast(aLeft.mU.mPtr) == *static_cast(aRight.mU.mPtr); @@ -400,8 +400,8 @@ SVGPathSegListSMILType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd, uint32_t aCount) const { - NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL type"); - NS_PRECONDITION(aValueToAdd.mType == this, "Incompatible SMIL type"); + MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL type"); + MOZ_ASSERT(aValueToAdd.mType == this, "Incompatible SMIL type"); SVGPathDataAndInfo& dest = *static_cast(aDest.mU.mPtr); @@ -440,8 +440,8 @@ SVGPathSegListSMILType::ComputeDistance(const nsSMILValue& aFrom, const nsSMILValue& aTo, double& aDistance) const { - NS_PRECONDITION(aFrom.mType == this, "Unexpected SMIL type"); - NS_PRECONDITION(aTo.mType == this, "Incompatible SMIL type"); + MOZ_ASSERT(aFrom.mType == this, "Unexpected SMIL type"); + MOZ_ASSERT(aTo.mType == this, "Incompatible SMIL type"); // See https://bugzilla.mozilla.org/show_bug.cgi?id=522306#c18 @@ -455,11 +455,10 @@ SVGPathSegListSMILType::Interpolate(const nsSMILValue& aStartVal, double aUnitDistance, nsSMILValue& aResult) const { - NS_PRECONDITION(aStartVal.mType == aEndVal.mType, - "Trying to interpolate different types"); - NS_PRECONDITION(aStartVal.mType == this, - "Unexpected types for interpolation"); - NS_PRECONDITION(aResult.mType == this, "Unexpected result type"); + MOZ_ASSERT(aStartVal.mType == aEndVal.mType, + "Trying to interpolate different types"); + MOZ_ASSERT(aStartVal.mType == this, "Unexpected types for interpolation"); + MOZ_ASSERT(aResult.mType == this, "Unexpected result type"); const SVGPathDataAndInfo& start = *static_cast(aStartVal.mU.mPtr); diff --git a/dom/svg/SVGPointListSMILType.cpp b/dom/svg/SVGPointListSMILType.cpp index 4b8c6abe71c4..9bcd2cc786cc 100644 --- a/dom/svg/SVGPointListSMILType.cpp +++ b/dom/svg/SVGPointListSMILType.cpp @@ -32,7 +32,7 @@ SVGPointListSMILType::Init(nsSMILValue &aValue) const void SVGPointListSMILType::Destroy(nsSMILValue& aValue) const { - NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value type"); + MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value type"); delete static_cast(aValue.mU.mPtr); aValue.mU.mPtr = nullptr; aValue.mType = nsSMILNullType::Singleton(); @@ -42,8 +42,8 @@ nsresult SVGPointListSMILType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const { - NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types"); - NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value"); + MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types"); + MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value"); const SVGPointListAndInfo* src = static_cast(aSrc.mU.mPtr); @@ -57,8 +57,8 @@ bool SVGPointListSMILType::IsEqual(const nsSMILValue& aLeft, const nsSMILValue& aRight) const { - NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types"); - NS_PRECONDITION(aLeft.mType == this, "Unexpected type for SMIL value"); + MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types"); + MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value"); return *static_cast(aLeft.mU.mPtr) == *static_cast(aRight.mU.mPtr); @@ -69,8 +69,8 @@ SVGPointListSMILType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd, uint32_t aCount) const { - NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL type"); - NS_PRECONDITION(aValueToAdd.mType == this, "Incompatible SMIL type"); + MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL type"); + MOZ_ASSERT(aValueToAdd.mType == this, "Incompatible SMIL type"); SVGPointListAndInfo& dest = *static_cast(aDest.mU.mPtr); @@ -112,8 +112,8 @@ SVGPointListSMILType::ComputeDistance(const nsSMILValue& aFrom, const nsSMILValue& aTo, double& aDistance) const { - NS_PRECONDITION(aFrom.mType == this, "Unexpected SMIL type"); - NS_PRECONDITION(aTo.mType == this, "Incompatible SMIL type"); + MOZ_ASSERT(aFrom.mType == this, "Unexpected SMIL type"); + MOZ_ASSERT(aTo.mType == this, "Incompatible SMIL type"); const SVGPointListAndInfo& from = *static_cast(aFrom.mU.mPtr); @@ -151,11 +151,10 @@ SVGPointListSMILType::Interpolate(const nsSMILValue& aStartVal, double aUnitDistance, nsSMILValue& aResult) const { - NS_PRECONDITION(aStartVal.mType == aEndVal.mType, - "Trying to interpolate different types"); - NS_PRECONDITION(aStartVal.mType == this, - "Unexpected types for interpolation"); - NS_PRECONDITION(aResult.mType == this, "Unexpected result type"); + MOZ_ASSERT(aStartVal.mType == aEndVal.mType, + "Trying to interpolate different types"); + MOZ_ASSERT(aStartVal.mType == this, "Unexpected types for interpolation"); + MOZ_ASSERT(aResult.mType == this, "Unexpected result type"); const SVGPointListAndInfo& start = *static_cast(aStartVal.mU.mPtr); diff --git a/dom/svg/SVGTransformListSMILType.cpp b/dom/svg/SVGTransformListSMILType.cpp index dd617a65e03c..16bbe87344e1 100644 --- a/dom/svg/SVGTransformListSMILType.cpp +++ b/dom/svg/SVGTransformListSMILType.cpp @@ -22,7 +22,7 @@ typedef FallibleTArray TransformArray; void SVGTransformListSMILType::Init(nsSMILValue &aValue) const { - NS_PRECONDITION(aValue.IsNull(), "Unexpected value type"); + MOZ_ASSERT(aValue.IsNull(), "Unexpected value type"); TransformArray* transforms = new TransformArray(1); aValue.mU.mPtr = transforms; @@ -32,7 +32,7 @@ SVGTransformListSMILType::Init(nsSMILValue &aValue) const void SVGTransformListSMILType::Destroy(nsSMILValue& aValue) const { - NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value type"); + MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value type"); TransformArray* params = static_cast(aValue.mU.mPtr); delete params; aValue.mU.mPtr = nullptr; @@ -43,8 +43,8 @@ nsresult SVGTransformListSMILType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const { - NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types"); - NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value"); + MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types"); + MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value"); const TransformArray* srcTransforms = static_cast(aSrc.mU.mPtr); @@ -60,8 +60,8 @@ bool SVGTransformListSMILType::IsEqual(const nsSMILValue& aLeft, const nsSMILValue& aRight) const { - NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types"); - NS_PRECONDITION(aLeft.mType == this, "Unexpected SMIL type"); + MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types"); + MOZ_ASSERT(aLeft.mType == this, "Unexpected SMIL type"); const TransformArray& leftArr (*static_cast(aLeft.mU.mPtr)); @@ -90,8 +90,8 @@ SVGTransformListSMILType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd, uint32_t aCount) const { - NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL type"); - NS_PRECONDITION(aDest.mType == aValueToAdd.mType, "Incompatible SMIL types"); + MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL type"); + MOZ_ASSERT(aDest.mType == aValueToAdd.mType, "Incompatible SMIL types"); TransformArray& dstTransforms(*static_cast(aDest.mU.mPtr)); const TransformArray& srcTransforms @@ -142,8 +142,8 @@ nsresult SVGTransformListSMILType::SandwichAdd(nsSMILValue& aDest, const nsSMILValue& aValueToAdd) const { - NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL type"); - NS_PRECONDITION(aDest.mType == aValueToAdd.mType, "Incompatible SMIL types"); + MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL type"); + MOZ_ASSERT(aDest.mType == aValueToAdd.mType, "Incompatible SMIL types"); // For a sandwich add means a matrix post-multiplication // which just means to put the additional transform on the end of the array @@ -180,9 +180,9 @@ SVGTransformListSMILType::ComputeDistance(const nsSMILValue& aFrom, const nsSMILValue& aTo, double& aDistance) const { - NS_PRECONDITION(aFrom.mType == aTo.mType, + MOZ_ASSERT(aFrom.mType == aTo.mType, "Can't compute difference between different SMIL types"); - NS_PRECONDITION(aFrom.mType == this, "Unexpected SMIL type"); + MOZ_ASSERT(aFrom.mType == this, "Unexpected SMIL type"); const TransformArray* fromTransforms = static_cast(aFrom.mU.mPtr); @@ -245,11 +245,10 @@ SVGTransformListSMILType::Interpolate(const nsSMILValue& aStartVal, double aUnitDistance, nsSMILValue& aResult) const { - NS_PRECONDITION(aStartVal.mType == aEndVal.mType, - "Can't interpolate between different SMIL types"); - NS_PRECONDITION(aStartVal.mType == this, - "Unexpected type for interpolation"); - NS_PRECONDITION(aResult.mType == this, "Unexpected result type"); + MOZ_ASSERT(aStartVal.mType == aEndVal.mType, + "Can't interpolate between different SMIL types"); + MOZ_ASSERT(aStartVal.mType == this, "Unexpected type for interpolation"); + MOZ_ASSERT(aResult.mType == this, "Unexpected result type"); const TransformArray& startTransforms = (*static_cast(aStartVal.mU.mPtr)); @@ -319,7 +318,7 @@ SVGTransformListSMILType::AppendTransform( const SVGTransformSMILData& aTransform, nsSMILValue& aValue) { - NS_PRECONDITION(aValue.mType == Singleton(), "Unexpected SMIL value type"); + MOZ_ASSERT(aValue.mType == Singleton(), "Unexpected SMIL value type"); TransformArray& transforms = *static_cast(aValue.mU.mPtr); return transforms.AppendElement(aTransform, fallible) ? @@ -331,7 +330,7 @@ bool SVGTransformListSMILType::AppendTransforms(const SVGTransformList& aList, nsSMILValue& aValue) { - NS_PRECONDITION(aValue.mType == Singleton(), "Unexpected SMIL value type"); + MOZ_ASSERT(aValue.mType == Singleton(), "Unexpected SMIL value type"); TransformArray& transforms = *static_cast(aValue.mU.mPtr); @@ -352,7 +351,7 @@ bool SVGTransformListSMILType::GetTransforms(const nsSMILValue& aValue, FallibleTArray& aTransforms) { - NS_PRECONDITION(aValue.mType == Singleton(), "Unexpected SMIL value type"); + MOZ_ASSERT(aValue.mType == Singleton(), "Unexpected SMIL value type"); const TransformArray& smilTransforms = *static_cast(aValue.mU.mPtr); diff --git a/dom/svg/SVGViewBoxSMILType.cpp b/dom/svg/SVGViewBoxSMILType.cpp index af85ed9410a7..deb3f7aa6fc2 100644 --- a/dom/svg/SVGViewBoxSMILType.cpp +++ b/dom/svg/SVGViewBoxSMILType.cpp @@ -26,7 +26,7 @@ SVGViewBoxSMILType::Init(nsSMILValue& aValue) const void SVGViewBoxSMILType::Destroy(nsSMILValue& aValue) const { - NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value"); + MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value"); delete static_cast(aValue.mU.mPtr); aValue.mU.mPtr = nullptr; aValue.mType = nsSMILNullType::Singleton(); @@ -35,8 +35,8 @@ SVGViewBoxSMILType::Destroy(nsSMILValue& aValue) const nsresult SVGViewBoxSMILType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const { - NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types"); - NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value"); + MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types"); + MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value"); const nsSVGViewBoxRect* src = static_cast(aSrc.mU.mPtr); nsSVGViewBoxRect* dst = static_cast(aDest.mU.mPtr); @@ -48,8 +48,8 @@ bool SVGViewBoxSMILType::IsEqual(const nsSMILValue& aLeft, const nsSMILValue& aRight) const { - NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types"); - NS_PRECONDITION(aLeft.mType == this, "Unexpected type for SMIL value"); + MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types"); + MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value"); const nsSVGViewBoxRect* leftBox = static_cast(aLeft.mU.mPtr); @@ -62,9 +62,9 @@ nsresult SVGViewBoxSMILType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd, uint32_t aCount) const { - NS_PRECONDITION(aValueToAdd.mType == aDest.mType, + MOZ_ASSERT(aValueToAdd.mType == aDest.mType, "Trying to add invalid types"); - NS_PRECONDITION(aValueToAdd.mType == this, "Unexpected source type"); + MOZ_ASSERT(aValueToAdd.mType == this, "Unexpected source type"); // See https://bugzilla.mozilla.org/show_bug.cgi?id=541884#c3 and the two // comments that follow that one for arguments for and against allowing @@ -78,8 +78,8 @@ SVGViewBoxSMILType::ComputeDistance(const nsSMILValue& aFrom, const nsSMILValue& aTo, double& aDistance) const { - NS_PRECONDITION(aFrom.mType == aTo.mType,"Trying to compare different types"); - NS_PRECONDITION(aFrom.mType == this, "Unexpected source type"); + MOZ_ASSERT(aFrom.mType == aTo.mType,"Trying to compare different types"); + MOZ_ASSERT(aFrom.mType == this, "Unexpected source type"); const nsSVGViewBoxRect* from = static_cast(aFrom.mU.mPtr); const nsSVGViewBoxRect* to = static_cast(aTo.mU.mPtr); @@ -110,11 +110,10 @@ SVGViewBoxSMILType::Interpolate(const nsSMILValue& aStartVal, double aUnitDistance, nsSMILValue& aResult) const { - NS_PRECONDITION(aStartVal.mType == aEndVal.mType, - "Trying to interpolate different types"); - NS_PRECONDITION(aStartVal.mType == this, - "Unexpected types for interpolation"); - NS_PRECONDITION(aResult.mType == this, "Unexpected result type"); + MOZ_ASSERT(aStartVal.mType == aEndVal.mType, + "Trying to interpolate different types"); + MOZ_ASSERT(aStartVal.mType == this, "Unexpected types for interpolation"); + MOZ_ASSERT(aResult.mType == this, "Unexpected result type"); const nsSVGViewBoxRect* start = static_cast(aStartVal.mU.mPtr); const nsSVGViewBoxRect* end = static_cast(aEndVal.mU.mPtr); diff --git a/dom/xbl/nsBindingManager.cpp b/dom/xbl/nsBindingManager.cpp index 4a0de1b540ed..44513a690ac2 100644 --- a/dom/xbl/nsBindingManager.cpp +++ b/dom/xbl/nsBindingManager.cpp @@ -202,7 +202,7 @@ nsBindingManager::RemovedFromDocumentInternal(nsIContent* aContent, nsIDocument* aOldDocument, DestructorHandling aDestructorHandling) { - NS_PRECONDITION(aOldDocument != nullptr, "no old document"); + MOZ_ASSERT(aOldDocument != nullptr, "no old document"); RefPtr binding = aContent->GetXBLBinding(); if (binding) { @@ -298,7 +298,7 @@ nsBindingManager::LoadBindingDocument(nsIDocument* aBoundDoc, nsIURI* aURL, nsIPrincipal* aOriginPrincipal) { - NS_PRECONDITION(aURL, "Must have a URI to load!"); + MOZ_ASSERT(aURL, "Must have a URI to load!"); // First we need to load our binding. nsXBLService* xblService = nsXBLService::GetInstance(); @@ -471,7 +471,7 @@ nsBindingManager::ExecuteDetachedHandlers() nsresult nsBindingManager::PutXBLDocumentInfo(nsXBLDocumentInfo* aDocumentInfo) { - NS_PRECONDITION(aDocumentInfo, "Must have a non-null documentinfo!"); + MOZ_ASSERT(aDocumentInfo, "Must have a non-null documentinfo!"); if (!mDocumentTable) { mDocumentTable = new nsRefPtrHashtable(); @@ -502,7 +502,7 @@ nsBindingManager::GetXBLDocumentInfo(nsIURI* aURL) nsresult nsBindingManager::PutLoadingDocListener(nsIURI* aURL, nsIStreamListener* aListener) { - NS_PRECONDITION(aListener, "Must have a non-null listener!"); + MOZ_ASSERT(aListener, "Must have a non-null listener!"); if (!mLoadingDocTable) { mLoadingDocTable = diff --git a/dom/xbl/nsXBLContentSink.cpp b/dom/xbl/nsXBLContentSink.cpp index a7640d260faf..ebf9c4826c35 100644 --- a/dom/xbl/nsXBLContentSink.cpp +++ b/dom/xbl/nsXBLContentSink.cpp @@ -170,7 +170,7 @@ nsXBLContentSink::ReportError(const char16_t* aErrorText, nsIScriptError *aError, bool *_retval) { - NS_PRECONDITION(aError && aSourceText && aErrorText, "Check arguments!!!"); + MOZ_ASSERT(aError && aSourceText && aErrorText, "Check arguments!!!"); // XXX FIXME This function overrides and calls on // nsXMLContentSink::ReportError, and probably should die. See bug 347826. diff --git a/dom/xbl/nsXBLProtoImplField.cpp b/dom/xbl/nsXBLProtoImplField.cpp index db5380c62bed..595e9309678b 100644 --- a/dom/xbl/nsXBLProtoImplField.cpp +++ b/dom/xbl/nsXBLProtoImplField.cpp @@ -375,9 +375,8 @@ nsXBLProtoImplField::InstallField(JS::Handle aBoundNode, const nsXBLPrototypeBinding& aProtoBinding, bool* aDidInstall) const { - NS_PRECONDITION(aBoundNode, - "uh-oh, bound node should NOT be null or bad things will " - "happen"); + MOZ_ASSERT(aBoundNode, + "uh-oh, bound node should NOT be null or bad things will happen"); *aDidInstall = false; diff --git a/dom/xbl/nsXBLProtoImplMethod.cpp b/dom/xbl/nsXBLProtoImplMethod.cpp index f0c58713c8de..0c52d0db6ac9 100644 --- a/dom/xbl/nsXBLProtoImplMethod.cpp +++ b/dom/xbl/nsXBLProtoImplMethod.cpp @@ -44,8 +44,8 @@ nsXBLProtoImplMethod::~nsXBLProtoImplMethod() void nsXBLProtoImplMethod::AppendBodyText(const nsAString& aText) { - NS_PRECONDITION(!IsCompiled(), - "Must not be compiled when accessing uncompiled method"); + MOZ_ASSERT(!IsCompiled(), + "Must not be compiled when accessing uncompiled method"); nsXBLUncompiledMethod* uncompiledMethod = GetUncompiledMethod(); if (!uncompiledMethod) { @@ -59,8 +59,8 @@ nsXBLProtoImplMethod::AppendBodyText(const nsAString& aText) void nsXBLProtoImplMethod::AddParameter(const nsAString& aText) { - NS_PRECONDITION(!IsCompiled(), - "Must not be compiled when accessing uncompiled method"); + MOZ_ASSERT(!IsCompiled(), + "Must not be compiled when accessing uncompiled method"); if (aText.IsEmpty()) { NS_WARNING("Empty name attribute in xbl:parameter!"); @@ -79,8 +79,8 @@ nsXBLProtoImplMethod::AddParameter(const nsAString& aText) void nsXBLProtoImplMethod::SetLineNumber(uint32_t aLineNumber) { - NS_PRECONDITION(!IsCompiled(), - "Must not be compiled when accessing uncompiled method"); + MOZ_ASSERT(!IsCompiled(), + "Must not be compiled when accessing uncompiled method"); nsXBLUncompiledMethod* uncompiledMethod = GetUncompiledMethod(); if (!uncompiledMethod) { @@ -95,7 +95,7 @@ nsresult nsXBLProtoImplMethod::InstallMember(JSContext* aCx, JS::Handle aTargetClassObject) { - NS_PRECONDITION(IsCompiled(), + MOZ_ASSERT(IsCompiled(), "Should not be installing an uncompiled method"); MOZ_ASSERT(js::IsObjectInContextCompartment(aTargetClassObject, aCx)); @@ -130,9 +130,9 @@ nsXBLProtoImplMethod::CompileMember(AutoJSAPI& jsapi, const nsString& aClassStr, JS::Handle aClassObject) { AssertInCompilationScope(); - NS_PRECONDITION(!IsCompiled(), + MOZ_ASSERT(!IsCompiled(), "Trying to compile an already-compiled method"); - NS_PRECONDITION(aClassObject, + MOZ_ASSERT(aClassObject, "Must have class object to compile"); nsXBLUncompiledMethod* uncompiledMethod = GetUncompiledMethod(); @@ -263,7 +263,7 @@ nsXBLProtoImplAnonymousMethod::Execute(nsIContent* aBoundElement, const nsXBLPrototypeBinding& aProtoBinding) { MOZ_ASSERT(aBoundElement->IsElement()); - NS_PRECONDITION(IsCompiled(), "Can't execute uncompiled method"); + MOZ_ASSERT(IsCompiled(), "Can't execute uncompiled method"); if (!GetCompiledMethod()) { // Nothing to do here diff --git a/dom/xbl/nsXBLProtoImplProperty.cpp b/dom/xbl/nsXBLProtoImplProperty.cpp index a953f67cf9c6..b05aa361bbc4 100644 --- a/dom/xbl/nsXBLProtoImplProperty.cpp +++ b/dom/xbl/nsXBLProtoImplProperty.cpp @@ -86,8 +86,7 @@ void nsXBLProtoImplProperty::EnsureUncompiledText(PropertyOp& aPropertyOp) void nsXBLProtoImplProperty::AppendGetterText(const nsAString& aText) { - NS_PRECONDITION(!mIsCompiled, - "Must not be compiled when accessing getter text"); + MOZ_ASSERT(!mIsCompiled, "Must not be compiled when accessing getter text"); EnsureUncompiledText(mGetter); mGetter.GetUncompiled()->AppendText(aText); } @@ -95,8 +94,7 @@ nsXBLProtoImplProperty::AppendGetterText(const nsAString& aText) void nsXBLProtoImplProperty::AppendSetterText(const nsAString& aText) { - NS_PRECONDITION(!mIsCompiled, - "Must not be compiled when accessing setter text"); + MOZ_ASSERT(!mIsCompiled, "Must not be compiled when accessing setter text"); EnsureUncompiledText(mSetter); mSetter.GetUncompiled()->AppendText(aText); } @@ -104,8 +102,7 @@ nsXBLProtoImplProperty::AppendSetterText(const nsAString& aText) void nsXBLProtoImplProperty::SetGetterLineNumber(uint32_t aLineNumber) { - NS_PRECONDITION(!mIsCompiled, - "Must not be compiled when accessing getter text"); + MOZ_ASSERT(!mIsCompiled, "Must not be compiled when accessing getter text"); EnsureUncompiledText(mGetter); mGetter.GetUncompiled()->SetLineNumber(aLineNumber); } @@ -113,8 +110,7 @@ nsXBLProtoImplProperty::SetGetterLineNumber(uint32_t aLineNumber) void nsXBLProtoImplProperty::SetSetterLineNumber(uint32_t aLineNumber) { - NS_PRECONDITION(!mIsCompiled, - "Must not be compiled when accessing setter text"); + MOZ_ASSERT(!mIsCompiled, "Must not be compiled when accessing setter text"); EnsureUncompiledText(mSetter); mSetter.GetUncompiled()->SetLineNumber(aLineNumber); } @@ -125,8 +121,7 @@ nsresult nsXBLProtoImplProperty::InstallMember(JSContext *aCx, JS::Handle aTargetClassObject) { - NS_PRECONDITION(mIsCompiled, - "Should not be installing an uncompiled property"); + MOZ_ASSERT(mIsCompiled, "Should not be installing an uncompiled property"); MOZ_ASSERT(mGetter.IsCompiled() && mSetter.IsCompiled()); MOZ_ASSERT(js::IsObjectInContextCompartment(aTargetClassObject, aCx)); @@ -169,10 +164,8 @@ nsXBLProtoImplProperty::CompileMember(AutoJSAPI& jsapi, const nsString& aClassSt JS::Handle aClassObject) { AssertInCompilationScope(); - NS_PRECONDITION(!mIsCompiled, - "Trying to compile an already-compiled property"); - NS_PRECONDITION(aClassObject, - "Must have class object to compile"); + MOZ_ASSERT(!mIsCompiled, "Trying to compile an already-compiled property"); + MOZ_ASSERT(aClassObject, "Must have class object to compile"); MOZ_ASSERT(!mGetter.IsCompiled() && !mSetter.IsCompiled()); JSContext *cx = jsapi.cx(); diff --git a/dom/xbl/nsXBLService.cpp b/dom/xbl/nsXBLService.cpp index 174abc0e1930..8886eeb73da2 100644 --- a/dom/xbl/nsXBLService.cpp +++ b/dom/xbl/nsXBLService.cpp @@ -480,7 +480,7 @@ nsXBLService::LoadBindings(Element* aElement, nsIURI* aURL, nsIPrincipal* aOriginPrincipal, nsXBLBinding** aBinding, bool* aResolveStyle) { - NS_PRECONDITION(aOriginPrincipal, "Must have an origin principal"); + MOZ_ASSERT(aOriginPrincipal, "Must have an origin principal"); *aBinding = nullptr; *aResolveStyle = false; @@ -900,9 +900,9 @@ nsXBLService::LoadBindingDocumentInfo(nsIContent* aBoundElement, bool aForceSyncLoad, nsXBLDocumentInfo** aResult) { - NS_PRECONDITION(aBindingURI, "Must have a binding URI"); - NS_PRECONDITION(!aOriginPrincipal || aBoundDocument, - "If we're doing a security check, we better have a document!"); + MOZ_ASSERT(aBindingURI, "Must have a binding URI"); + MOZ_ASSERT(!aOriginPrincipal || aBoundDocument, + "If we're doing a security check, we better have a document!"); *aResult = nullptr; // Allow XBL in unprivileged documents if it's specified in a privileged or diff --git a/dom/xhr/XMLHttpRequestMainThread.cpp b/dom/xhr/XMLHttpRequestMainThread.cpp index 520430779704..dac7fe21230e 100644 --- a/dom/xhr/XMLHttpRequestMainThread.cpp +++ b/dom/xhr/XMLHttpRequestMainThread.cpp @@ -3217,7 +3217,7 @@ XMLHttpRequestMainThread::AsyncOnChannelRedirect(nsIChannel *aOldChannel, uint32_t aFlags, nsIAsyncVerifyRedirectCallback *callback) { - NS_PRECONDITION(aNewChannel, "Redirect without a channel?"); + MOZ_ASSERT(aNewChannel, "Redirect without a channel?"); // Prepare to receive callback mRedirectCallback = callback; diff --git a/dom/xml/ProcessingInstruction.cpp b/dom/xml/ProcessingInstruction.cpp index e351cca11a13..b0c40f4a46c9 100644 --- a/dom/xml/ProcessingInstruction.cpp +++ b/dom/xml/ProcessingInstruction.cpp @@ -20,7 +20,7 @@ NS_NewXMLProcessingInstruction(nsNodeInfoManager *aNodeInfoManager, using mozilla::dom::ProcessingInstruction; using mozilla::dom::XMLStylesheetProcessingInstruction; - NS_PRECONDITION(aNodeInfoManager, "Missing nodeinfo manager"); + MOZ_ASSERT(aNodeInfoManager, "Missing nodeinfo manager"); RefPtr target = NS_Atomize(aTarget); MOZ_ASSERT(target); diff --git a/dom/xml/nsXMLContentSink.cpp b/dom/xml/nsXMLContentSink.cpp index 85ef66fc3a79..94ef995a0e20 100644 --- a/dom/xml/nsXMLContentSink.cpp +++ b/dom/xml/nsXMLContentSink.cpp @@ -79,7 +79,7 @@ NS_NewXMLContentSink(nsIXMLContentSink** aResult, nsISupports* aContainer, nsIChannel* aChannel) { - NS_PRECONDITION(nullptr != aResult, "null ptr"); + MOZ_ASSERT(nullptr != aResult, "null ptr"); if (nullptr == aResult) { return NS_ERROR_NULL_POINTER; } @@ -456,7 +456,7 @@ nsXMLContentSink::WillResume(void) NS_IMETHODIMP nsXMLContentSink::SetParser(nsParserBase* aParser) { - NS_PRECONDITION(aParser, "Should have a parser here!"); + MOZ_ASSERT(aParser, "Should have a parser here!"); mParser = aParser; return NS_OK; } @@ -844,7 +844,7 @@ nsXMLContentSink::GetCurrentStackNode() nsresult nsXMLContentSink::PushContent(nsIContent *aContent) { - NS_PRECONDITION(aContent, "Null content being pushed!"); + MOZ_ASSERT(aContent, "Null content being pushed!"); StackNode *sn = mContentStack.AppendElement(); NS_ENSURE_TRUE(sn, NS_ERROR_OUT_OF_MEMORY); @@ -973,7 +973,7 @@ nsXMLContentSink::HandleStartElement(const char16_t *aName, uint32_t aLineNumber, bool aInterruptable) { - NS_PRECONDITION(aAttsCount % 2 == 0, "incorrect aAttsCount"); + MOZ_ASSERT(aAttsCount % 2 == 0, "incorrect aAttsCount"); // Adjust aAttsCount so it's the actual number of attributes aAttsCount /= 2; @@ -1358,7 +1358,7 @@ nsXMLContentSink::ReportError(const char16_t* aErrorText, nsIScriptError *aError, bool *_retval) { - NS_PRECONDITION(aError && aSourceText && aErrorText, "Check arguments!!!"); + MOZ_ASSERT(aError && aSourceText && aErrorText, "Check arguments!!!"); nsresult rv = NS_OK; // The expat driver should report the error. We're just cleaning up the mess. diff --git a/dom/xml/nsXMLFragmentContentSink.cpp b/dom/xml/nsXMLFragmentContentSink.cpp index 1296e2fbc8aa..b3222be49869 100644 --- a/dom/xml/nsXMLFragmentContentSink.cpp +++ b/dom/xml/nsXMLFragmentContentSink.cpp @@ -296,7 +296,7 @@ nsXMLFragmentContentSink::ReportError(const char16_t* aErrorText, nsIScriptError *aError, bool *_retval) { - NS_PRECONDITION(aError && aSourceText && aErrorText, "Check arguments!!!"); + MOZ_ASSERT(aError && aSourceText && aErrorText, "Check arguments!!!"); // The expat driver should report the error. *_retval = true; diff --git a/dom/xslt/xpath/txXPathTreeWalker.h b/dom/xslt/xpath/txXPathTreeWalker.h index 5196a6df821a..8644c2f435a8 100644 --- a/dom/xslt/xpath/txXPathTreeWalker.h +++ b/dom/xslt/xpath/txXPathTreeWalker.h @@ -177,8 +177,7 @@ txXPathTreeWalker::isOnNode(const txXPathNode& aNode) const inline int32_t txXPathNodeUtils::getUniqueIdentifier(const txXPathNode& aNode) { - NS_PRECONDITION(!aNode.isAttribute(), - "Not implemented for attributes."); + MOZ_ASSERT(!aNode.isAttribute(), "Not implemented for attributes."); return NS_PTR_TO_INT32(aNode.mNode); } diff --git a/dom/xslt/xslt/txExecutionState.cpp b/dom/xslt/xslt/txExecutionState.cpp index 208494b6b52b..de06fe5fee58 100644 --- a/dom/xslt/xslt/txExecutionState.cpp +++ b/dom/xslt/xslt/txExecutionState.cpp @@ -395,7 +395,7 @@ txExecutionState::pushTemplateRule(txStylesheet::ImportFrame* aFrame, void txExecutionState::popTemplateRule() { - NS_PRECONDITION(!mTemplateRules.IsEmpty(), "No rules to pop"); + MOZ_ASSERT(!mTemplateRules.IsEmpty(), "No rules to pop"); mTemplateRules.RemoveLastElement(); } @@ -457,7 +457,7 @@ txExecutionState::getKeyNodes(const txExpandedName& aKeyName, txExecutionState::TemplateRule* txExecutionState::getCurrentTemplateRule() { - NS_PRECONDITION(!mTemplateRules.IsEmpty(), "No current rule!"); + MOZ_ASSERT(!mTemplateRules.IsEmpty(), "No current rule!"); return &mTemplateRules[mTemplateRules.Length() - 1]; } diff --git a/dom/xslt/xslt/txMozillaStylesheetCompiler.cpp b/dom/xslt/xslt/txMozillaStylesheetCompiler.cpp index 37c3703b399c..4a4095454ba3 100644 --- a/dom/xslt/xslt/txMozillaStylesheetCompiler.cpp +++ b/dom/xslt/xslt/txMozillaStylesheetCompiler.cpp @@ -125,7 +125,7 @@ txStylesheetSink::HandleStartElement(const char16_t *aName, uint32_t aAttsCount, uint32_t aLineNumber) { - NS_PRECONDITION(aAttsCount % 2 == 0, "incorrect aAttsCount"); + MOZ_ASSERT(aAttsCount % 2 == 0, "incorrect aAttsCount"); nsresult rv = mCompiler->startElement(aName, aAtts, aAttsCount / 2); @@ -208,7 +208,7 @@ txStylesheetSink::ReportError(const char16_t *aErrorText, nsIScriptError *aError, bool *_retval) { - NS_PRECONDITION(aError && aSourceText && aErrorText, "Check arguments!!!"); + MOZ_ASSERT(aError && aSourceText && aErrorText, "Check arguments!!!"); // The expat driver should report the error. *_retval = true; diff --git a/dom/xslt/xslt/txMozillaXMLOutput.cpp b/dom/xslt/xslt/txMozillaXMLOutput.cpp index 2dd66aa27c6c..d5e3fae811d6 100644 --- a/dom/xslt/xslt/txMozillaXMLOutput.cpp +++ b/dom/xslt/xslt/txMozillaXMLOutput.cpp @@ -432,8 +432,8 @@ txMozillaXMLOutput::startElement(nsAtom* aPrefix, nsAtom* aLocalName, nsAtom* aLowercaseLocalName, const int32_t aNsID) { - NS_PRECONDITION(aNsID != kNameSpaceID_None || !aPrefix, - "Can't have prefix without namespace"); + MOZ_ASSERT(aNsID != kNameSpaceID_None || !aPrefix, + "Can't have prefix without namespace"); if (mOutputFormat.mMethod == eHTMLOutput && aNsID == kNameSpaceID_None) { RefPtr owner; diff --git a/dom/xslt/xslt/txStylesheetCompiler.cpp b/dom/xslt/xslt/txStylesheetCompiler.cpp index 23ab8d32e78a..478ce60064ef 100644 --- a/dom/xslt/xslt/txStylesheetCompiler.cpp +++ b/dom/xslt/xslt/txStylesheetCompiler.cpp @@ -703,7 +703,7 @@ txStylesheetCompilerState::addToplevelItem(txToplevelItem* aItem) nsresult txStylesheetCompilerState::openInstructionContainer(txInstructionContainer* aContainer) { - NS_PRECONDITION(!mNextInstrPtr, "can't nest instruction-containers"); + MOZ_ASSERT(!mNextInstrPtr, "can't nest instruction-containers"); mNextInstrPtr = aContainer->mFirstInstruction.StartAssignment(); return NS_OK; @@ -720,7 +720,7 @@ txStylesheetCompilerState::closeInstructionContainer() nsresult txStylesheetCompilerState::addInstruction(nsAutoPtr&& aInstruction) { - NS_PRECONDITION(mNextInstrPtr, "adding instruction outside container"); + MOZ_ASSERT(mNextInstrPtr, "adding instruction outside container"); txInstruction* newInstr = aInstruction; diff --git a/dom/xul/XULDocument.cpp b/dom/xul/XULDocument.cpp index 874ef9baeb13..aa8cc175e4f6 100644 --- a/dom/xul/XULDocument.cpp +++ b/dom/xul/XULDocument.cpp @@ -219,7 +219,7 @@ XULDocument::~XULDocument() nsresult NS_NewXULDocument(nsIDocument** result) { - NS_PRECONDITION(result != nullptr, "null ptr"); + MOZ_ASSERT(result != nullptr, "null ptr"); if (! result) return NS_ERROR_NULL_POINTER; @@ -1622,7 +1622,7 @@ XULDocument::MatchAttribute(Element* aElement, nsAtom* aAttrName, void* aData) { - NS_PRECONDITION(aElement, "Must have content node to work with!"); + MOZ_ASSERT(aElement, "Must have content node to work with!"); nsString* attrValue = static_cast(aData); if (aNamespaceID != kNameSpaceID_Unknown && aNamespaceID != kNameSpaceID_Wildcard) { @@ -2048,8 +2048,8 @@ nsresult XULDocument::CreateAndInsertPI(const nsXULPrototypePI* aProtoPI, nsINode* aParent, nsINode* aBeforeThis) { - NS_PRECONDITION(aProtoPI, "null ptr"); - NS_PRECONDITION(aParent, "null ptr"); + MOZ_ASSERT(aProtoPI, "null ptr"); + MOZ_ASSERT(aParent, "null ptr"); RefPtr node = NS_NewXMLProcessingInstruction(mNodeInfoManager, aProtoPI->mTarget, @@ -2739,8 +2739,8 @@ XULDocument::GetXULWindowIfToplevelChrome() const nsresult XULDocument::DoneWalking() { - NS_PRECONDITION(mPendingSheets == 0, "there are sheets to be loaded"); - NS_PRECONDITION(!mStillWalking, "walk not done"); + MOZ_ASSERT(mPendingSheets == 0, "there are sheets to be loaded"); + MOZ_ASSERT(!mStillWalking, "walk not done"); // XXXldb This is where we should really be setting the chromehidden // attribute. @@ -2959,7 +2959,7 @@ XULDocument::EndUpdate(nsUpdateType aUpdateType) void XULDocument::ReportMissingOverlay(nsIURI* aURI) { - NS_PRECONDITION(aURI, "Must have a URI"); + MOZ_ASSERT(aURI, "Must have a URI"); NS_ConvertUTF8toUTF16 utfSpec(aURI->GetSpecOrDefault()); const char16_t* params[] = { utfSpec.get() }; @@ -3265,7 +3265,7 @@ XULDocument::OnScriptCompileComplete(JSScript* aScript, nsresult aStatus) nsresult XULDocument::ExecuteScript(nsXULPrototypeScript *aScript) { - NS_PRECONDITION(aScript != nullptr, "null ptr"); + MOZ_ASSERT(aScript != nullptr, "null ptr"); NS_ENSURE_TRUE(aScript, NS_ERROR_NULL_POINTER); NS_ENSURE_TRUE(mScriptGlobalObject, NS_ERROR_NOT_INITIALIZED); @@ -3306,7 +3306,7 @@ XULDocument::CreateElementFromPrototype(nsXULPrototypeElement* aPrototype, bool aIsRoot) { // Create a content model element from a prototype element. - NS_PRECONDITION(aPrototype != nullptr, "null ptr"); + MOZ_ASSERT(aPrototype != nullptr, "null ptr"); if (! aPrototype) return NS_ERROR_NULL_POINTER; diff --git a/dom/xul/nsXULCommandDispatcher.cpp b/dom/xul/nsXULCommandDispatcher.cpp index f2ae9a9a4fe0..ccdf818c1ce1 100644 --- a/dom/xul/nsXULCommandDispatcher.cpp +++ b/dom/xul/nsXULCommandDispatcher.cpp @@ -242,7 +242,7 @@ nsXULCommandDispatcher::AddCommandUpdater(Element* aElement, const nsAString& aEvents, const nsAString& aTargets) { - NS_PRECONDITION(aElement != nullptr, "null ptr"); + MOZ_ASSERT(aElement != nullptr, "null ptr"); if (! aElement) return NS_ERROR_NULL_POINTER; @@ -310,7 +310,7 @@ nsXULCommandDispatcher::AddCommandUpdater(Element* aElement, NS_IMETHODIMP nsXULCommandDispatcher::RemoveCommandUpdater(Element* aElement) { - NS_PRECONDITION(aElement != nullptr, "null ptr"); + MOZ_ASSERT(aElement != nullptr, "null ptr"); if (! aElement) return NS_ERROR_NULL_POINTER; diff --git a/dom/xul/nsXULContentSink.cpp b/dom/xul/nsXULContentSink.cpp index d4354fd44fe2..155cc3c48a90 100644 --- a/dom/xul/nsXULContentSink.cpp +++ b/dom/xul/nsXULContentSink.cpp @@ -274,7 +274,7 @@ nsresult XULContentSinkImpl::Init(nsIDocument* aDocument, nsXULPrototypeDocument* aPrototype) { - NS_PRECONDITION(aDocument != nullptr, "null ptr"); + MOZ_ASSERT(aDocument != nullptr, "null ptr"); if (! aDocument) return NS_ERROR_NULL_POINTER; @@ -406,7 +406,6 @@ XULContentSinkImpl::CreateElement(mozilla::dom::NodeInfo *aNodeInfo, /**** BEGIN NEW APIs ****/ - NS_IMETHODIMP XULContentSinkImpl::HandleStartElement(const char16_t *aName, const char16_t **aAtts, @@ -415,8 +414,9 @@ XULContentSinkImpl::HandleStartElement(const char16_t *aName, { // XXX Hopefully the parser will flag this before we get here. If // we're in the epilog, there should be no new elements - NS_PRECONDITION(mState != eInEpilog, "tag in XUL doc epilog"); - NS_PRECONDITION(aAttsCount % 2 == 0, "incorrect aAttsCount"); + MOZ_ASSERT(mState != eInEpilog, "tag in XUL doc epilog"); + MOZ_ASSERT(aAttsCount % 2 == 0, "incorrect aAttsCount"); + // Adjust aAttsCount so it's the actual number of attributes aAttsCount /= 2; @@ -629,7 +629,7 @@ XULContentSinkImpl::ReportError(const char16_t* aErrorText, nsIScriptError *aError, bool *_retval) { - NS_PRECONDITION(aError && aSourceText && aErrorText, "Check arguments!!!"); + MOZ_ASSERT(aError && aSourceText && aErrorText, "Check arguments!!!"); // The expat driver should report the error. *_retval = true; diff --git a/dom/xul/nsXULContentUtils.cpp b/dom/xul/nsXULContentUtils.cpp index 3f18d500c9f4..bb97f37cca7e 100644 --- a/dom/xul/nsXULContentUtils.cpp +++ b/dom/xul/nsXULContentUtils.cpp @@ -93,11 +93,11 @@ nsXULContentUtils::SetCommandUpdater(nsIDocument* aDocument, Element* aElement) // Deal with setting up a 'commandupdater'. Pulls the 'events' and // 'targets' attributes off of aElement, and adds it to the // document's command dispatcher. - NS_PRECONDITION(aDocument != nullptr, "null ptr"); + MOZ_ASSERT(aDocument != nullptr, "null ptr"); if (! aDocument) return NS_ERROR_NULL_POINTER; - NS_PRECONDITION(aElement != nullptr, "null ptr"); + MOZ_ASSERT(aElement != nullptr, "null ptr"); if (! aElement) return NS_ERROR_NULL_POINTER; diff --git a/dom/xul/nsXULControllers.cpp b/dom/xul/nsXULControllers.cpp index 9f4547572148..1880075c6587 100644 --- a/dom/xul/nsXULControllers.cpp +++ b/dom/xul/nsXULControllers.cpp @@ -45,7 +45,7 @@ nsXULControllers::DeleteControllers() nsresult NS_NewXULControllers(nsISupports* aOuter, REFNSIID aIID, void** aResult) { - NS_PRECONDITION(aOuter == nullptr, "no aggregation"); + MOZ_ASSERT(aOuter == nullptr, "no aggregation"); if (aOuter) return NS_ERROR_NO_AGGREGATION; diff --git a/dom/xul/nsXULElement.cpp b/dom/xul/nsXULElement.cpp index 57cfbc6ae47d..54359958d720 100644 --- a/dom/xul/nsXULElement.cpp +++ b/dom/xul/nsXULElement.cpp @@ -239,11 +239,11 @@ nsXULElement::CreateFromPrototype(nsXULPrototypeElement* aPrototype, Element** aResult) { // Create an nsXULElement from a prototype - NS_PRECONDITION(aPrototype != nullptr, "null ptr"); + MOZ_ASSERT(aPrototype != nullptr, "null ptr"); if (! aPrototype) return NS_ERROR_NULL_POINTER; - NS_PRECONDITION(aResult != nullptr, "null ptr"); + MOZ_ASSERT(aResult != nullptr, "null ptr"); if (! aResult) return NS_ERROR_NULL_POINTER; @@ -270,7 +270,7 @@ NS_NewXULElement(Element** aResult, already_AddRefed&& a { RefPtr nodeInfo = aNodeInfo; - NS_PRECONDITION(nodeInfo, "need nodeinfo for non-proto Create"); + MOZ_ASSERT(nodeInfo, "need nodeinfo for non-proto Create"); NS_ASSERTION(nodeInfo->NamespaceEquals(kNameSpaceID_XUL), "Trying to create XUL elements that don't have the XUL namespace"); @@ -288,7 +288,7 @@ NS_TrustedNewXULElement(Element** aResult, already_AddRefed&& aNodeInfo) { RefPtr ni = aNodeInfo; - NS_PRECONDITION(ni, "need nodeinfo for non-proto Create"); + MOZ_ASSERT(ni, "need nodeinfo for non-proto Create"); // Create an nsXULElement with the specified namespace and tag. NS_ADDREF(*aResult = nsXULElement::Construct(ni.forget())); @@ -2145,7 +2145,7 @@ nsXULPrototypeElement::Deserialize(nsIObjectInputStream* aStream, nsIURI* aDocumentURI, const nsTArray> *aNodeInfos) { - NS_PRECONDITION(aNodeInfos, "missing nodeinfo array"); + MOZ_ASSERT(aNodeInfos, "missing nodeinfo array"); // Read Node Info uint32_t number = 0; @@ -2272,7 +2272,7 @@ nsresult nsXULPrototypeElement::SetAttrAt(uint32_t aPos, const nsAString& aValue, nsIURI* aDocumentURI) { - NS_PRECONDITION(aPos < mNumAttributes, "out-of-bounds"); + MOZ_ASSERT(aPos < mNumAttributes, "out-of-bounds"); // WARNING!! // This code is largely duplicated in nsXULElement::SetAttr. diff --git a/dom/xul/nsXULPrototypeDocument.cpp b/dom/xul/nsXULPrototypeDocument.cpp index 345e2a0aede7..1a7e26ef1340 100644 --- a/dom/xul/nsXULPrototypeDocument.cpp +++ b/dom/xul/nsXULPrototypeDocument.cpp @@ -409,7 +409,7 @@ nsXULPrototypeDocument::SetRootElement(nsXULPrototypeElement* aElement) nsresult nsXULPrototypeDocument::AddProcessingInstruction(nsXULPrototypePI* aPI) { - NS_PRECONDITION(aPI, "null ptr"); + MOZ_ASSERT(aPI, "null ptr"); if (!mProcessingInstructions.AppendElement(aPI)) { return NS_ERROR_OUT_OF_MEMORY; } @@ -425,7 +425,7 @@ nsXULPrototypeDocument::GetProcessingInstructions() const void nsXULPrototypeDocument::AddStyleSheetReference(nsIURI* aURI) { - NS_PRECONDITION(aURI, "null ptr"); + MOZ_ASSERT(aURI, "null ptr"); if (!mStyleSheetReferences.AppendObject(aURI)) { NS_WARNING("mStyleSheetReferences->AppendElement() failed." "Stylesheet overlay dropped."); @@ -441,7 +441,7 @@ nsXULPrototypeDocument::GetStyleSheetReferences() const nsIPrincipal* nsXULPrototypeDocument::DocumentPrincipal() { - NS_PRECONDITION(mNodeInfoManager, "missing nodeInfoManager"); + MOZ_ASSERT(mNodeInfoManager, "missing nodeInfoManager"); return mNodeInfoManager->DocumentPrincipal(); } diff --git a/editor/libeditor/EditorBase.cpp b/editor/libeditor/EditorBase.cpp index 17e7f24cf9d0..290461309988 100644 --- a/editor/libeditor/EditorBase.cpp +++ b/editor/libeditor/EditorBase.cpp @@ -3549,9 +3549,9 @@ EditorBase::FindNextLeafNode(nsINode* aCurrentNode, bool bNoBlockCrossing) { // called only by GetPriorNode so we don't need to check params. - NS_PRECONDITION(IsDescendantOfEditorRoot(aCurrentNode) && - !IsEditorRoot(aCurrentNode), - "Bogus arguments"); + MOZ_ASSERT(IsDescendantOfEditorRoot(aCurrentNode) && + !IsEditorRoot(aCurrentNode), + "Bogus arguments"); nsINode* cur = aCurrentNode; for (;;) { @@ -4146,7 +4146,7 @@ EditorBase::JoinNodesDeepWithTransaction(nsIContent& aLeftNode, void EditorBase::BeginUpdateViewBatch() { - NS_PRECONDITION(mUpdateCount >= 0, "bad state"); + MOZ_ASSERT(mUpdateCount >= 0, "bad state"); if (!mUpdateCount) { // Turn off selection updates and notifications. @@ -4162,7 +4162,7 @@ EditorBase::BeginUpdateViewBatch() nsresult EditorBase::EndUpdateViewBatch() { - NS_PRECONDITION(mUpdateCount > 0, "bad state"); + MOZ_ASSERT(mUpdateCount > 0, "bad state"); if (mUpdateCount <= 0) { mUpdateCount = 0; diff --git a/editor/libeditor/EditorEventListener.cpp b/editor/libeditor/EditorEventListener.cpp index 1295fa4c0953..c5cdf0894c46 100644 --- a/editor/libeditor/EditorEventListener.cpp +++ b/editor/libeditor/EditorEventListener.cpp @@ -138,7 +138,7 @@ EditorEventListener::Connect(EditorBase* aEditorBase) nsresult EditorEventListener::InstallToEditor() { - NS_PRECONDITION(mEditorBase, "The caller must set mEditorBase"); + MOZ_ASSERT(mEditorBase, "The caller must set mEditorBase"); EventTarget* piTarget = mEditorBase->GetDOMEventTarget(); NS_ENSURE_TRUE(piTarget, NS_ERROR_FAILURE); diff --git a/editor/libeditor/HTMLEditor.cpp b/editor/libeditor/HTMLEditor.cpp index 7e56588d850d..70a9c23c7af2 100644 --- a/editor/libeditor/HTMLEditor.cpp +++ b/editor/libeditor/HTMLEditor.cpp @@ -391,8 +391,8 @@ HTMLEditor::FindSelectionRoot(nsINode* aNode) return nullptr; } - NS_PRECONDITION(aNode->IsDocument() || aNode->IsContent(), - "aNode must be content or document node"); + MOZ_ASSERT(aNode->IsDocument() || aNode->IsContent(), + "aNode must be content or document node"); nsCOMPtr doc = aNode->GetComposedDoc(); if (!doc) { @@ -3649,7 +3649,7 @@ HTMLEditor::GetEnclosingTable(nsINode* aNode) nsIDOMNode* HTMLEditor::GetEnclosingTable(nsIDOMNode* aNode) { - NS_PRECONDITION(aNode, "null node passed to HTMLEditor::GetEnclosingTable"); + MOZ_ASSERT(aNode, "null node passed to HTMLEditor::GetEnclosingTable"); nsCOMPtr node = do_QueryInterface(aNode); NS_ENSURE_TRUE(node, nullptr); nsCOMPtr table = GetEnclosingTable(node); diff --git a/editor/libeditor/TextEditRules.cpp b/editor/libeditor/TextEditRules.cpp index 288359208459..e1f2cdcd5f3b 100644 --- a/editor/libeditor/TextEditRules.cpp +++ b/editor/libeditor/TextEditRules.cpp @@ -230,7 +230,7 @@ TextEditRules::AfterEdit(EditAction aAction, AutoLockRulesSniffing lockIt(this); - NS_PRECONDITION(mActionNesting>0, "bad action nesting!"); + MOZ_ASSERT(mActionNesting>0, "bad action nesting!"); if (!--mActionNesting) { NS_ENSURE_STATE(mTextEditor); RefPtr selection = mTextEditor->GetSelection(); diff --git a/editor/libeditor/TextEditor.cpp b/editor/libeditor/TextEditor.cpp index eef5ceba236e..94e2119dd725 100644 --- a/editor/libeditor/TextEditor.cpp +++ b/editor/libeditor/TextEditor.cpp @@ -207,7 +207,7 @@ TextEditor::BeginEditorInit() nsresult TextEditor::EndEditorInit() { - NS_PRECONDITION(mInitTriggerCounter > 0, "ended editor init before we began?"); + MOZ_ASSERT(mInitTriggerCounter > 0, "ended editor init before we began?"); mInitTriggerCounter--; if (mInitTriggerCounter) { return NS_OK; diff --git a/extensions/spellcheck/src/mozInlineSpellChecker.cpp b/extensions/spellcheck/src/mozInlineSpellChecker.cpp index 69ad3ed99837..dc052c528ad8 100644 --- a/extensions/spellcheck/src/mozInlineSpellChecker.cpp +++ b/extensions/spellcheck/src/mozInlineSpellChecker.cpp @@ -1758,8 +1758,8 @@ bool // static ContentIsDescendantOf(nsINode* aPossibleDescendant, nsINode* aPossibleAncestor) { - NS_PRECONDITION(aPossibleDescendant, "The possible descendant is null!"); - NS_PRECONDITION(aPossibleAncestor, "The possible ancestor is null!"); + MOZ_ASSERT(aPossibleDescendant, "The possible descendant is null!"); + MOZ_ASSERT(aPossibleAncestor, "The possible ancestor is null!"); do { if (aPossibleDescendant == aPossibleAncestor) diff --git a/extensions/spellcheck/src/mozInlineSpellWordUtil.cpp b/extensions/spellcheck/src/mozInlineSpellWordUtil.cpp index bac63bb493d5..a6f7f2f12536 100644 --- a/extensions/spellcheck/src/mozInlineSpellWordUtil.cpp +++ b/extensions/spellcheck/src/mozInlineSpellWordUtil.cpp @@ -87,7 +87,7 @@ static nsINode* FindNextNode(nsINode* aNode, nsINode* aRoot, OnLeaveNodeFunPtr aOnLeaveNode, void* aClosure) { - NS_PRECONDITION(aNode, "Null starting node?"); + MOZ_ASSERT(aNode, "Null starting node?"); nsINode* next = aNode->GetFirstChild(); if (next) @@ -123,7 +123,7 @@ FindNextNode(nsINode* aNode, nsINode* aRoot, static nsINode* FindNextTextNode(nsINode* aNode, int32_t aOffset, nsINode* aRoot) { - NS_PRECONDITION(aNode, "Null starting node?"); + MOZ_ASSERT(aNode, "Null starting node?"); NS_ASSERTION(!IsSpellCheckingTextNode(aNode), "FindNextTextNode should start with a non-text node"); nsINode* checkNode; @@ -165,7 +165,7 @@ FindNextTextNode(nsINode* aNode, int32_t aOffset, nsINode* aRoot) nsresult mozInlineSpellWordUtil::SetEnd(nsINode* aEndNode, int32_t aEndOffset) { - NS_PRECONDITION(aEndNode, "Null end node?"); + MOZ_ASSERT(aEndNode, "Null end node?"); NS_ASSERTION(mRootNode, "Not initialized"); diff --git a/gfx/thebes/gfxDWriteCommon.cpp b/gfx/thebes/gfxDWriteCommon.cpp index d5fd4157060f..ef047e2e6be1 100644 --- a/gfx/thebes/gfxDWriteCommon.cpp +++ b/gfx/thebes/gfxDWriteCommon.cpp @@ -51,14 +51,14 @@ public: IFACEMETHOD_(ULONG, AddRef)() { - NS_PRECONDITION(int32_t(mRefCnt) >= 0, "illegal refcnt"); + MOZ_ASSERT(int32_t(mRefCnt) >= 0, "illegal refcnt"); ++mRefCnt; return mRefCnt; } IFACEMETHOD_(ULONG, Release)() { - NS_PRECONDITION(0 != mRefCnt, "dup release"); + MOZ_ASSERT(0 != mRefCnt, "dup release"); --mRefCnt; if (mRefCnt == 0) { delete this; diff --git a/gfx/thebes/gfxFT2FontBase.cpp b/gfx/thebes/gfxFT2FontBase.cpp index f3d61412d4bd..ffbc24dd20ed 100644 --- a/gfx/thebes/gfxFT2FontBase.cpp +++ b/gfx/thebes/gfxFT2FontBase.cpp @@ -107,7 +107,7 @@ gfxFT2FontBase::GetGlyph(uint32_t aCharCode) void gfxFT2FontBase::GetGlyphExtents(uint32_t aGlyph, cairo_text_extents_t* aExtents) { - NS_PRECONDITION(aExtents != nullptr, "aExtents must not be NULL"); + MOZ_ASSERT(aExtents != nullptr, "aExtents must not be NULL"); cairo_glyph_t glyphs[1]; glyphs[0].index = aGlyph; diff --git a/gfx/thebes/gfxFT2Utils.cpp b/gfx/thebes/gfxFT2Utils.cpp index 85f6a26c3490..cfc4b1723bc0 100644 --- a/gfx/thebes/gfxFT2Utils.cpp +++ b/gfx/thebes/gfxFT2Utils.cpp @@ -47,7 +47,7 @@ typedef FT_UInt (*GetCharVariantFunction)(FT_Face face, uint32_t gfxFT2LockedFace::GetUVSGlyph(uint32_t aCharCode, uint32_t aVariantSelector) { - NS_PRECONDITION(aVariantSelector, "aVariantSelector should not be NULL"); + MOZ_ASSERT(aVariantSelector, "aVariantSelector should not be NULL"); if (MOZ_UNLIKELY(!mFace)) return 0; diff --git a/gfx/thebes/gfxFont.cpp b/gfx/thebes/gfxFont.cpp index e16dacb453b4..8540c0295bf8 100644 --- a/gfx/thebes/gfxFont.cpp +++ b/gfx/thebes/gfxFont.cpp @@ -4191,9 +4191,9 @@ gfxFontStyle::Hash() const void gfxFontStyle::AdjustForSubSuperscript(int32_t aAppUnitsPerDevPixel) { - NS_PRECONDITION(variantSubSuper != NS_FONT_VARIANT_POSITION_NORMAL && - baselineOffset == 0, - "can't adjust this style for sub/superscript"); + MOZ_ASSERT(variantSubSuper != NS_FONT_VARIANT_POSITION_NORMAL && + baselineOffset == 0, + "can't adjust this style for sub/superscript"); // calculate the baseline offset (before changing the size) if (variantSubSuper == NS_FONT_VARIANT_POSITION_SUPER) { diff --git a/gfx/thebes/gfxFont.h b/gfx/thebes/gfxFont.h index cec23e25c9fe..cc40cc23ff1a 100644 --- a/gfx/thebes/gfxFont.h +++ b/gfx/thebes/gfxFont.h @@ -1465,7 +1465,7 @@ public: typedef mozilla::FontSlantStyle FontSlantStyle; nsrefcnt AddRef(void) { - NS_PRECONDITION(int32_t(mRefCnt) >= 0, "illegal refcnt"); + MOZ_ASSERT(int32_t(mRefCnt) >= 0, "illegal refcnt"); if (mExpirationState.IsTracked()) { gfxFontCache::GetCache()->RemoveObject(this); } @@ -1474,7 +1474,7 @@ public: return mRefCnt; } nsrefcnt Release(void) { - NS_PRECONDITION(0 != mRefCnt, "dup release"); + MOZ_ASSERT(0 != mRefCnt, "dup release"); --mRefCnt; NS_LOG_RELEASE(this, mRefCnt, "gfxFont"); if (mRefCnt == 0) { diff --git a/gfx/thebes/gfxFontEntry.h b/gfx/thebes/gfxFontEntry.h index 9fb21da1c90d..9c930c59d31c 100644 --- a/gfx/thebes/gfxFontEntry.h +++ b/gfx/thebes/gfxFontEntry.h @@ -50,14 +50,14 @@ class SVGContextPaint; class gfxCharacterMap : public gfxSparseBitSet { public: nsrefcnt AddRef() { - NS_PRECONDITION(int32_t(mRefCnt) >= 0, "illegal refcnt"); + MOZ_ASSERT(int32_t(mRefCnt) >= 0, "illegal refcnt"); ++mRefCnt; NS_LOG_ADDREF(this, mRefCnt, "gfxCharacterMap", sizeof(*this)); return mRefCnt; } nsrefcnt Release() { - NS_PRECONDITION(0 != mRefCnt, "dup release"); + MOZ_ASSERT(0 != mRefCnt, "dup release"); --mRefCnt; NS_LOG_RELEASE(this, mRefCnt, "gfxCharacterMap"); if (mRefCnt == 0) { diff --git a/gfx/thebes/gfxTextRun.cpp b/gfx/thebes/gfxTextRun.cpp index 4d373e7363a0..91a362f1617a 100644 --- a/gfx/thebes/gfxTextRun.cpp +++ b/gfx/thebes/gfxTextRun.cpp @@ -853,8 +853,8 @@ gfxTextRun::ClassifyAutoHyphenations(uint32_t aStart, Range aRange, nsTArray& aHyphenBuffer, HyphenationState* aWordState) { - NS_PRECONDITION(aRange.end - aStart <= aHyphenBuffer.Length() && - aRange.start >= aStart, "Range out of bounds"); + MOZ_ASSERT(aRange.end - aStart <= aHyphenBuffer.Length() && + aRange.start >= aStart, "Range out of bounds"); MOZ_ASSERT(aWordState->mostRecentBoundary >= aStart, "Unexpected aMostRecentWordBoundary!!"); diff --git a/gfx/thebes/gfxXlibSurface.cpp b/gfx/thebes/gfxXlibSurface.cpp index bf330d7cd81c..cefcedc76b90 100644 --- a/gfx/thebes/gfxXlibSurface.cpp +++ b/gfx/thebes/gfxXlibSurface.cpp @@ -71,8 +71,8 @@ gfxXlibSurface::gfxXlibSurface(cairo_surface_t *csurf) , mGLXPixmap(X11None) #endif { - NS_PRECONDITION(cairo_surface_status(csurf) == 0, - "Not expecting an error surface"); + MOZ_ASSERT(cairo_surface_status(csurf) == 0, + "Not expecting an error surface"); mDrawable = cairo_xlib_surface_get_drawable(csurf); mDisplay = cairo_xlib_surface_get_display(csurf); diff --git a/image/ImageURL.h b/image/ImageURL.h index 0beba6efa850..bced1fb00581 100644 --- a/image/ImageURL.h +++ b/image/ImageURL.h @@ -84,8 +84,8 @@ public: nsresult SchemeIs(const char* scheme, bool* result) { - NS_PRECONDITION(scheme, "scheme is null"); - NS_PRECONDITION(result, "result is null"); + MOZ_ASSERT(scheme, "scheme is null"); + MOZ_ASSERT(result, "result is null"); *result = mScheme.Equals(scheme); return NS_OK; diff --git a/image/decoders/icon/nsIconURI.cpp b/image/decoders/icon/nsIconURI.cpp index 83acfd3a34bf..3c9e07f67f09 100644 --- a/image/decoders/icon/nsIconURI.cpp +++ b/image/decoders/icon/nsIconURI.cpp @@ -471,7 +471,7 @@ nsMozIconURI::Equals(nsIURI* other, bool* result) { *result = false; NS_ENSURE_ARG_POINTER(other); - NS_PRECONDITION(result, "null pointer"); + MOZ_ASSERT(result, "null pointer"); nsAutoCString spec1; nsAutoCString spec2; diff --git a/image/imgLoader.h b/image/imgLoader.h index cce83d1dac92..ebd7f390638a 100644 --- a/image/imgLoader.h +++ b/image/imgLoader.h @@ -49,7 +49,7 @@ public: nsrefcnt AddRef() { - NS_PRECONDITION(int32_t(mRefCnt) >= 0, "illegal refcnt"); + MOZ_ASSERT(int32_t(mRefCnt) >= 0, "illegal refcnt"); NS_ASSERT_OWNINGTHREAD(imgCacheEntry); ++mRefCnt; NS_LOG_ADDREF(this, mRefCnt, "imgCacheEntry", sizeof(*this)); @@ -58,7 +58,7 @@ public: nsrefcnt Release() { - NS_PRECONDITION(0 != mRefCnt, "dup release"); + MOZ_ASSERT(0 != mRefCnt, "dup release"); NS_ASSERT_OWNINGTHREAD(imgCacheEntry); --mRefCnt; NS_LOG_RELEASE(this, mRefCnt, "imgCacheEntry"); diff --git a/image/imgRequest.cpp b/image/imgRequest.cpp index a915403b8539..a12e0c561078 100644 --- a/image/imgRequest.cpp +++ b/image/imgRequest.cpp @@ -214,7 +214,7 @@ imgRequest::ResetCacheEntry() void imgRequest::AddProxy(imgRequestProxy* proxy) { - NS_PRECONDITION(proxy, "null imgRequestProxy passed in"); + MOZ_ASSERT(proxy, "null imgRequestProxy passed in"); LOG_SCOPE_WITH_PARAM(gImgLog, "imgRequest::AddProxy", "proxy", proxy); if (!mFirstProxy) { diff --git a/image/imgRequestProxy.cpp b/image/imgRequestProxy.cpp index 12c7e1f69ea8..282ec11585d7 100644 --- a/image/imgRequestProxy.cpp +++ b/image/imgRequestProxy.cpp @@ -133,7 +133,7 @@ imgRequestProxy::imgRequestProxy() : imgRequestProxy::~imgRequestProxy() { /* destructor code */ - NS_PRECONDITION(!mListener, + MOZ_ASSERT(!mListener, "Someone forgot to properly cancel this request!"); // If we had a listener, that means we would have issued notifications. With @@ -184,8 +184,8 @@ imgRequestProxy::Init(imgRequest* aOwner, ImageURL* aURI, imgINotificationObserver* aObserver) { - NS_PRECONDITION(!GetOwner() && !mListener, - "imgRequestProxy is already initialized"); + MOZ_ASSERT(!GetOwner() && !mListener, + "imgRequestProxy is already initialized"); LOG_SCOPE_WITH_PARAM(gImgLog, "imgRequestProxy::Init", "request", aOwner); @@ -214,7 +214,7 @@ imgRequestProxy::Init(imgRequest* aOwner, nsresult imgRequestProxy::ChangeOwner(imgRequest* aNewOwner) { - NS_PRECONDITION(GetOwner(), + MOZ_ASSERT(GetOwner(), "Cannot ChangeOwner on a proxy without an owner!"); if (mCanceled) { @@ -863,7 +863,7 @@ imgRequestProxy::PerformClone(imgINotificationObserver* aObserver, bool aSyncNotify, imgRequestProxy** aClone) { - NS_PRECONDITION(aClone, "Null out param"); + MOZ_ASSERT(aClone, "Null out param"); LOG_SCOPE(gImgLog, "imgRequestProxy::Clone"); @@ -1137,7 +1137,7 @@ imgRequestProxy::OnLoadComplete(bool aLastPart) } if (mListenerIsStrongRef && aLastPart) { - NS_PRECONDITION(mListener, "How did that happen?"); + MOZ_ASSERT(mListener, "How did that happen?"); // Drop our strong ref to the listener now that we're done with // everything. Note that this can cancel us and other fun things // like that. Don't add anything in this method after this point. diff --git a/intl/lwbrk/WordBreaker.cpp b/intl/lwbrk/WordBreaker.cpp index 1704cfa68768..b22a341fa68a 100644 --- a/intl/lwbrk/WordBreaker.cpp +++ b/intl/lwbrk/WordBreaker.cpp @@ -17,13 +17,12 @@ WordBreaker::Create() return RefPtr(new WordBreaker()).forget(); } - bool WordBreaker::BreakInBetween( const char16_t* aText1 , uint32_t aTextLen1, const char16_t* aText2 , uint32_t aTextLen2) { - NS_PRECONDITION( nullptr != aText1, "null ptr"); - NS_PRECONDITION( nullptr != aText2, "null ptr"); + MOZ_ASSERT(nullptr != aText1, "null ptr"); + MOZ_ASSERT(nullptr != aText2, "null ptr"); if(!aText1 || !aText2 || (0 == aTextLen1) || (0 == aTextLen2)) return false; @@ -31,7 +30,6 @@ bool WordBreaker::BreakInBetween( return GetClass(aText1[aTextLen1-1]) != GetClass(aText2[0]); } - #define IS_ASCII(c) (0 == ( 0xFF80 & (c))) #define ASCII_IS_ALPHA(c) ((( 'a' <= (c)) && ((c) <= 'z')) || (( 'A' <= (c)) && ((c) <= 'Z'))) #define ASCII_IS_DIGIT(c) (( '0' <= (c)) && ((c) <= '9')) @@ -92,9 +90,9 @@ WordRange WordBreaker::FindWord( uint32_t aOffset) { WordRange range; - NS_PRECONDITION( nullptr != aText, "null ptr"); - NS_PRECONDITION( 0 != aTextLen, "len = 0"); - NS_PRECONDITION( aOffset <= aTextLen, "aOffset > aTextLen"); + MOZ_ASSERT(nullptr != aText, "null ptr"); + MOZ_ASSERT(0 != aTextLen, "len = 0"); + MOZ_ASSERT(aOffset <= aTextLen, "aOffset > aTextLen"); range.mBegin = aTextLen + 1; range.mEnd = aTextLen + 1; diff --git a/intl/uconv/nsConverterOutputStream.cpp b/intl/uconv/nsConverterOutputStream.cpp index 3fcd49837788..73d213715066 100644 --- a/intl/uconv/nsConverterOutputStream.cpp +++ b/intl/uconv/nsConverterOutputStream.cpp @@ -27,7 +27,7 @@ NS_IMETHODIMP nsConverterOutputStream::Init(nsIOutputStream* aOutStream, const char* aCharset) { - NS_PRECONDITION(aOutStream, "Null output stream!"); + MOZ_ASSERT(aOutStream, "Null output stream!"); const Encoding* encoding; if (!aCharset) { @@ -132,4 +132,3 @@ nsConverterOutputStream::Close() mConverter = nullptr; return NS_FAILED(rv1) ? rv1 : rv2; } - diff --git a/ipc/glue/MessageChannel.cpp b/ipc/glue/MessageChannel.cpp index 45e5aa172eb9..f10663baa176 100644 --- a/ipc/glue/MessageChannel.cpp +++ b/ipc/glue/MessageChannel.cpp @@ -776,7 +776,7 @@ MessageChannel::Clear() bool MessageChannel::Open(Transport* aTransport, MessageLoop* aIOLoop, Side aSide) { - NS_PRECONDITION(!mLink, "Open() called > once"); + MOZ_ASSERT(!mLink, "Open() called > once"); mMonitor = new RefCountedMonitor(); mWorkerLoop = MessageLoop::current(); @@ -808,8 +808,8 @@ MessageChannel::Open(MessageChannel *aTargetChan, nsIEventTarget *aEventTarget, // - meanwhile, on PB's worker loop, the work item is removed and: // - invokes PB->SlaveOpen(PA, ...): // - sets its state and that of PA to Connected - NS_PRECONDITION(aTargetChan, "Need a target channel"); - NS_PRECONDITION(ChannelClosed == mChannelState, "Not currently closed"); + MOZ_ASSERT(aTargetChan, "Need a target channel"); + MOZ_ASSERT(ChannelClosed == mChannelState, "Not currently closed"); CommonThreadOpenInit(aTargetChan, aSide); @@ -841,10 +841,9 @@ void MessageChannel::OnOpenAsSlave(MessageChannel *aTargetChan, Side aSide) { // Invoked when the other side has begun the open. - NS_PRECONDITION(ChannelClosed == mChannelState, - "Not currently closed"); - NS_PRECONDITION(ChannelOpening == aTargetChan->mChannelState, - "Target channel not in the process of opening"); + MOZ_ASSERT(ChannelClosed == mChannelState, "Not currently closed"); + MOZ_ASSERT(ChannelOpening == aTargetChan->mChannelState, + "Target channel not in the process of opening"); CommonThreadOpenInit(aTargetChan, aSide); mMonitor = aTargetChan->mMonitor; diff --git a/ipc/glue/MessageLink.cpp b/ipc/glue/MessageLink.cpp index b19673072a50..6aba7f06eafb 100644 --- a/ipc/glue/MessageLink.cpp +++ b/ipc/glue/MessageLink.cpp @@ -72,7 +72,7 @@ ProcessLink::Open(mozilla::ipc::Transport* aTransport, MessageLoop *aIOLoop, Sid { mChan->AssertWorkerThread(); - NS_PRECONDITION(aTransport, "need transport layer"); + MOZ_ASSERT(aTransport, "need transport layer"); // FIXME need to check for valid channel @@ -87,7 +87,7 @@ ProcessLink::Open(mozilla::ipc::Transport* aTransport, MessageLoop *aIOLoop, Sid needOpen = true; mChan->mSide = (aSide == UnknownSide) ? ChildSide : aSide; } else { - NS_PRECONDITION(aSide == UnknownSide, "expected default side arg"); + MOZ_ASSERT(aSide == UnknownSide, "expected default side arg"); // parent mChan->mSide = ParentSide; diff --git a/js/xpconnect/src/XPCConvert.cpp b/js/xpconnect/src/XPCConvert.cpp index fb5c43b359d3..0d1eae9e8b5a 100644 --- a/js/xpconnect/src/XPCConvert.cpp +++ b/js/xpconnect/src/XPCConvert.cpp @@ -101,7 +101,7 @@ bool XPCConvert::NativeData2JS(MutableHandleValue d, const void* s, const nsXPTType& type, const nsID* iid, nsresult* pErr) { - NS_PRECONDITION(s, "bad param"); + MOZ_ASSERT(s, "bad param"); AutoJSContext cx; if (pErr) @@ -404,7 +404,7 @@ XPCConvert::JSData2Native(void* d, HandleValue s, const nsID* iid, nsresult* pErr) { - NS_PRECONDITION(d, "bad param"); + MOZ_ASSERT(d, "bad param"); AutoJSContext cx; if (pErr) @@ -1242,7 +1242,7 @@ XPCConvert::NativeArray2JS(MutableHandleValue d, const void** s, const nsXPTType& type, const nsID* iid, uint32_t count, nsresult* pErr) { - NS_PRECONDITION(s, "bad param"); + MOZ_ASSERT(s, "bad param"); AutoJSContext cx; @@ -1639,7 +1639,7 @@ XPCConvert::NativeStringWithSize2JS(MutableHandleValue d, const void* s, uint32_t count, nsresult* pErr) { - NS_PRECONDITION(s, "bad param"); + MOZ_ASSERT(s, "bad param"); AutoJSContext cx; if (pErr) @@ -1681,8 +1681,8 @@ XPCConvert::JSStringWithSize2Native(void* d, HandleValue s, uint32_t count, const nsXPTType& type, nsresult* pErr) { - NS_PRECONDITION(!s.isNull(), "bad param"); - NS_PRECONDITION(d, "bad param"); + MOZ_ASSERT(!s.isNull(), "bad param"); + MOZ_ASSERT(d, "bad param"); AutoJSContext cx; uint32_t len; diff --git a/js/xpconnect/src/XPCMaps.h b/js/xpconnect/src/XPCMaps.h index 8919021ae4dd..4ec6290b7cb7 100644 --- a/js/xpconnect/src/XPCMaps.h +++ b/js/xpconnect/src/XPCMaps.h @@ -45,7 +45,7 @@ public: } inline nsXPCWrappedJS* Find(JSObject* Obj) { - NS_PRECONDITION(Obj,"bad param"); + MOZ_ASSERT(Obj,"bad param"); Map::Ptr p = mTable.lookup(Obj); return p ? p->value() : nullptr; } @@ -61,7 +61,7 @@ public: #endif inline nsXPCWrappedJS* Add(JSContext* cx, nsXPCWrappedJS* wrapper) { - NS_PRECONDITION(wrapper,"bad param"); + MOZ_ASSERT(wrapper,"bad param"); JSObject* obj = wrapper->GetJSObjectPreserveColor(); Map::AddPtr p = mTable.lookupForAdd(obj); if (p) @@ -72,7 +72,7 @@ public: } inline void Remove(nsXPCWrappedJS* wrapper) { - NS_PRECONDITION(wrapper,"bad param"); + MOZ_ASSERT(wrapper,"bad param"); mTable.remove(wrapper->GetJSObjectPreserveColor()); } @@ -114,14 +114,14 @@ public: inline XPCWrappedNative* Find(nsISupports* Obj) { - NS_PRECONDITION(Obj,"bad param"); + MOZ_ASSERT(Obj,"bad param"); auto entry = static_cast(mTable.Search(Obj)); return entry ? entry->value : nullptr; } inline XPCWrappedNative* Add(XPCWrappedNative* wrapper) { - NS_PRECONDITION(wrapper,"bad param"); + MOZ_ASSERT(wrapper,"bad param"); nsISupports* obj = wrapper->GetIdentityObject(); MOZ_ASSERT(!Find(obj), "wrapper already in new scope!"); auto entry = static_cast(mTable.Add(obj, mozilla::fallible)); @@ -136,7 +136,7 @@ public: inline void Remove(XPCWrappedNative* wrapper) { - NS_PRECONDITION(wrapper,"bad param"); + MOZ_ASSERT(wrapper,"bad param"); #ifdef DEBUG XPCWrappedNative* wrapperInMap = Find(wrapper->GetIdentityObject()); MOZ_ASSERT(!wrapperInMap || wrapperInMap == wrapper, @@ -186,7 +186,7 @@ public: inline nsXPCWrappedJSClass* Add(nsXPCWrappedJSClass* clazz) { - NS_PRECONDITION(clazz,"bad param"); + MOZ_ASSERT(clazz,"bad param"); const nsIID* iid = &clazz->GetIID(); auto entry = static_cast(mTable.Add(iid, mozilla::fallible)); if (!entry) @@ -200,7 +200,7 @@ public: inline void Remove(nsXPCWrappedJSClass* clazz) { - NS_PRECONDITION(clazz,"bad param"); + MOZ_ASSERT(clazz,"bad param"); mTable.Remove(&clazz->GetIID()); } @@ -240,7 +240,7 @@ public: inline XPCNativeInterface* Add(XPCNativeInterface* iface) { - NS_PRECONDITION(iface,"bad param"); + MOZ_ASSERT(iface,"bad param"); const nsIID* iid = iface->GetIID(); auto entry = static_cast(mTable.Add(iid, mozilla::fallible)); if (!entry) @@ -254,7 +254,7 @@ public: inline void Remove(XPCNativeInterface* iface) { - NS_PRECONDITION(iface,"bad param"); + MOZ_ASSERT(iface,"bad param"); mTable.Remove(iface->GetIID()); } @@ -298,7 +298,7 @@ public: inline XPCNativeSet* Add(nsIClassInfo* info, XPCNativeSet* set) { - NS_PRECONDITION(info,"bad param"); + MOZ_ASSERT(info,"bad param"); auto entry = static_cast(mTable.Add(info, mozilla::fallible)); if (!entry) return nullptr; @@ -311,7 +311,7 @@ public: inline void Remove(nsIClassInfo* info) { - NS_PRECONDITION(info,"bad param"); + MOZ_ASSERT(info,"bad param"); mTable.Remove(info); } @@ -351,7 +351,7 @@ public: inline XPCWrappedNativeProto* Add(nsIClassInfo* info, XPCWrappedNativeProto* proto) { - NS_PRECONDITION(info,"bad param"); + MOZ_ASSERT(info,"bad param"); auto entry = static_cast(mTable.Add(info, mozilla::fallible)); if (!entry) return nullptr; @@ -364,7 +364,7 @@ public: inline void Remove(nsIClassInfo* info) { - NS_PRECONDITION(info,"bad param"); + MOZ_ASSERT(info,"bad param"); mTable.Remove(info); } @@ -467,7 +467,7 @@ public: inline XPCWrappedNativeProto* Add(XPCWrappedNativeProto* proto) { - NS_PRECONDITION(proto,"bad param"); + MOZ_ASSERT(proto,"bad param"); auto entry = static_cast (mTable.Add(proto, mozilla::fallible)); if (!entry) @@ -480,7 +480,7 @@ public: inline void Remove(XPCWrappedNativeProto* proto) { - NS_PRECONDITION(proto,"bad param"); + MOZ_ASSERT(proto,"bad param"); mTable.Remove(proto); } @@ -517,7 +517,7 @@ public: } inline JSObject* Find(JSObject* key) { - NS_PRECONDITION(key, "bad param"); + MOZ_ASSERT(key, "bad param"); if (Map::Ptr p = mTable.lookup(key)) return p->value(); return nullptr; @@ -525,7 +525,7 @@ public: /* Note: If the entry already exists, return the old value. */ inline JSObject* Add(JSContext* cx, JSObject* key, JSObject* value) { - NS_PRECONDITION(key,"bad param"); + MOZ_ASSERT(key,"bad param"); Map::AddPtr p = mTable.lookupForAdd(key); if (p) return p->value(); @@ -536,7 +536,7 @@ public: } inline void Remove(JSObject* key) { - NS_PRECONDITION(key,"bad param"); + MOZ_ASSERT(key,"bad param"); mTable.remove(key); } diff --git a/js/xpconnect/src/XPCWrappedJS.cpp b/js/xpconnect/src/XPCWrappedJS.cpp index 70d3a79b194d..c4593eb7fd79 100644 --- a/js/xpconnect/src/XPCWrappedJS.cpp +++ b/js/xpconnect/src/XPCWrappedJS.cpp @@ -183,7 +183,7 @@ NS_IMETHODIMP nsXPCWrappedJS::QueryInterface(REFNSIID aIID, void** aInstancePtr) { if (nullptr == aInstancePtr) { - NS_PRECONDITION(false, "null pointer"); + MOZ_ASSERT(false, "null pointer"); return NS_ERROR_NULL_POINTER; } @@ -614,7 +614,7 @@ nsXPCWrappedJS::CallMethod(uint16_t methodIndex, NS_IMETHODIMP nsXPCWrappedJS::GetInterfaceIID(nsIID** iid) { - NS_PRECONDITION(iid, "bad param"); + MOZ_ASSERT(iid, "bad param"); *iid = GetIID().Clone(); return NS_OK; diff --git a/js/xpconnect/src/XPCWrappedJSClass.cpp b/js/xpconnect/src/XPCWrappedJSClass.cpp index 90a0ba878e33..b0eca70366f6 100644 --- a/js/xpconnect/src/XPCWrappedJSClass.cpp +++ b/js/xpconnect/src/XPCWrappedJSClass.cpp @@ -38,7 +38,7 @@ static uint32_t zero_methods_descriptor; bool AutoScriptEvaluate::StartEvaluating(HandleObject scope) { - NS_PRECONDITION(!mEvaluated, "AutoScriptEvaluate::Evaluate should only be called once"); + MOZ_ASSERT(!mEvaluated, "AutoScriptEvaluate::Evaluate should only be called once"); if (!mJSContext) return true; diff --git a/js/xpconnect/src/nsXPConnect.cpp b/js/xpconnect/src/nsXPConnect.cpp index 09ba0c437953..d53ba8e9e70a 100644 --- a/js/xpconnect/src/nsXPConnect.cpp +++ b/js/xpconnect/src/nsXPConnect.cpp @@ -667,7 +667,7 @@ nsXPConnect::JSValToVariant(JSContext* cx, HandleValue aJSVal, nsIVariant** aResult) { - NS_PRECONDITION(aResult, "bad param"); + MOZ_ASSERT(aResult, "bad param"); RefPtr variant = XPCVariant::newVariant(cx, aJSVal); variant.forget(aResult); @@ -879,9 +879,9 @@ NS_IMETHODIMP nsXPConnect::VariantToJS(JSContext* ctx, JSObject* scopeArg, nsIVariant* value, MutableHandleValue _retval) { - NS_PRECONDITION(ctx, "bad param"); - NS_PRECONDITION(scopeArg, "bad param"); - NS_PRECONDITION(value, "bad param"); + MOZ_ASSERT(ctx, "bad param"); + MOZ_ASSERT(scopeArg, "bad param"); + MOZ_ASSERT(value, "bad param"); RootedObject scope(ctx, scopeArg); MOZ_ASSERT(js::IsObjectInContextCompartment(scope, ctx)); @@ -899,8 +899,8 @@ nsXPConnect::VariantToJS(JSContext* ctx, JSObject* scopeArg, nsIVariant* value, NS_IMETHODIMP nsXPConnect::JSToVariant(JSContext* ctx, HandleValue value, nsIVariant** _retval) { - NS_PRECONDITION(ctx, "bad param"); - NS_PRECONDITION(_retval, "bad param"); + MOZ_ASSERT(ctx, "bad param"); + MOZ_ASSERT(_retval, "bad param"); RefPtr variant = XPCVariant::newVariant(ctx, value); variant.forget(_retval); diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp index de668b60b38f..92fc9d97985f 100644 --- a/layout/base/PresShell.cpp +++ b/layout/base/PresShell.cpp @@ -911,10 +911,10 @@ PresShell::Init(nsIDocument* aDocument, nsViewManager* aViewManager, UniquePtr aStyleSet) { - NS_PRECONDITION(aDocument, "null ptr"); - NS_PRECONDITION(aPresContext, "null ptr"); - NS_PRECONDITION(aViewManager, "null ptr"); - NS_PRECONDITION(!mDocument, "already initialized"); + MOZ_ASSERT(aDocument, "null ptr"); + MOZ_ASSERT(aPresContext, "null ptr"); + MOZ_ASSERT(aViewManager, "null ptr"); + MOZ_ASSERT(!mDocument, "already initialized"); if (!aDocument || !aPresContext || !aViewManager || mDocument) { return; @@ -1932,7 +1932,7 @@ PresShell::ResizeReflowIgnoreOverride(nscoord aWidth, nscoord aHeight, nscoord aOldWidth, nscoord aOldHeight, ResizeReflowOptions aOptions) { - NS_PRECONDITION(!mIsReflowing, "Shouldn't be in reflow here!"); + MOZ_ASSERT(!mIsReflowing, "Shouldn't be in reflow here!"); nsIFrame* rootFrame = mFrameConstructor->GetRootFrame(); if (!rootFrame) { @@ -2544,7 +2544,7 @@ void PresShell::EndUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType) { #ifdef DEBUG - NS_PRECONDITION(0 != mUpdateCount, "too many EndUpdate's"); + MOZ_ASSERT(0 != mUpdateCount, "too many EndUpdate's"); --mUpdateCount; #endif @@ -2604,7 +2604,7 @@ PresShell::BeginLoad(nsIDocument *aDocument) void PresShell::EndLoad(nsIDocument *aDocument) { - NS_PRECONDITION(aDocument == mDocument, "Wrong document"); + MOZ_ASSERT(aDocument == mDocument, "Wrong document"); RestoreRootScrollPosition(); @@ -2677,10 +2677,10 @@ PresShell::FrameNeedsReflow(nsIFrame *aFrame, IntrinsicDirty aIntrinsicDirty, nsFrameState aBitToAdd, ReflowRootHandling aRootHandling) { - NS_PRECONDITION(aBitToAdd == NS_FRAME_IS_DIRTY || - aBitToAdd == NS_FRAME_HAS_DIRTY_CHILDREN || - !aBitToAdd, - "Unexpected bits being added"); + MOZ_ASSERT(aBitToAdd == NS_FRAME_IS_DIRTY || + aBitToAdd == NS_FRAME_HAS_DIRTY_CHILDREN || + !aBitToAdd, + "Unexpected bits being added"); // FIXME bug 478135 NS_ASSERTION(!(aIntrinsicDirty == eStyleChange && @@ -2838,7 +2838,7 @@ void PresShell::FrameNeedsToContinueReflow(nsIFrame *aFrame) { NS_ASSERTION(mIsReflowing, "Must be in reflow when marking path dirty."); - NS_PRECONDITION(mCurrentReflowRoot, "Must have a current reflow root here"); + MOZ_ASSERT(mCurrentReflowRoot, "Must have a current reflow root here"); NS_ASSERTION(aFrame == mCurrentReflowRoot || nsLayoutUtils::IsProperAncestorFrame(mCurrentReflowRoot, aFrame), "Frame passed in is not the descendant of mCurrentReflowRoot"); @@ -3930,7 +3930,7 @@ nsIPresShell::ClearMouseCapture(nsIFrame* aFrame) nsresult PresShell::CaptureHistoryState(nsILayoutHistoryState** aState) { - NS_PRECONDITION(nullptr != aState, "null state pointer"); + MOZ_ASSERT(nullptr != aState, "null state pointer"); // We actually have to mess with the docshell here, since we want to // store the state back in it. @@ -4404,8 +4404,8 @@ void PresShell::CharacterDataChanged(nsIContent* aContent, const CharacterDataChangeInfo& aInfo) { - NS_PRECONDITION(!mIsDocumentGone, "Unexpected CharacterDataChanged"); - NS_PRECONDITION(aContent->OwnerDoc() == mDocument, "Unexpected document"); + MOZ_ASSERT(!mIsDocumentGone, "Unexpected CharacterDataChanged"); + MOZ_ASSERT(aContent->OwnerDoc() == mDocument, "Unexpected document"); nsAutoCauseReflowNotifier crNotifier(this); @@ -4418,8 +4418,8 @@ PresShell::ContentStateChanged(nsIDocument* aDocument, nsIContent* aContent, EventStates aStateMask) { - NS_PRECONDITION(!mIsDocumentGone, "Unexpected ContentStateChanged"); - NS_PRECONDITION(aDocument == mDocument, "Unexpected aDocument"); + MOZ_ASSERT(!mIsDocumentGone, "Unexpected ContentStateChanged"); + MOZ_ASSERT(aDocument == mDocument, "Unexpected aDocument"); if (mDidInitialize) { nsAutoCauseReflowNotifier crNotifier(this); @@ -4430,8 +4430,8 @@ PresShell::ContentStateChanged(nsIDocument* aDocument, void PresShell::DocumentStatesChanged(nsIDocument* aDocument, EventStates aStateMask) { - NS_PRECONDITION(!mIsDocumentGone, "Unexpected DocumentStatesChanged"); - NS_PRECONDITION(aDocument == mDocument, "Unexpected aDocument"); + MOZ_ASSERT(!mIsDocumentGone, "Unexpected DocumentStatesChanged"); + MOZ_ASSERT(aDocument == mDocument, "Unexpected aDocument"); MOZ_ASSERT(!aStateMask.IsEmpty()); if (mDidInitialize) { @@ -4452,8 +4452,8 @@ PresShell::AttributeWillChange(Element* aElement, int32_t aModType, const nsAttrValue* aNewValue) { - NS_PRECONDITION(!mIsDocumentGone, "Unexpected AttributeWillChange"); - NS_PRECONDITION(aElement->OwnerDoc() == mDocument, "Unexpected document"); + MOZ_ASSERT(!mIsDocumentGone, "Unexpected AttributeWillChange"); + MOZ_ASSERT(aElement->OwnerDoc() == mDocument, "Unexpected document"); // XXXwaterson it might be more elegant to wait until after the // initial reflow to begin observing the document. That would @@ -4473,8 +4473,8 @@ PresShell::AttributeChanged(Element* aElement, int32_t aModType, const nsAttrValue* aOldValue) { - NS_PRECONDITION(!mIsDocumentGone, "Unexpected AttributeChanged"); - NS_PRECONDITION(aElement->OwnerDoc() == mDocument, "Unexpected document"); + MOZ_ASSERT(!mIsDocumentGone, "Unexpected AttributeChanged"); + MOZ_ASSERT(aElement->OwnerDoc() == mDocument, "Unexpected document"); // XXXwaterson it might be more elegant to wait until after the // initial reflow to begin observing the document. That would @@ -4490,8 +4490,8 @@ PresShell::AttributeChanged(Element* aElement, void PresShell::ContentAppended(nsIContent* aFirstNewContent) { - NS_PRECONDITION(!mIsDocumentGone, "Unexpected ContentAppended"); - NS_PRECONDITION(aFirstNewContent->OwnerDoc() == mDocument, + MOZ_ASSERT(!mIsDocumentGone, "Unexpected ContentAppended"); + MOZ_ASSERT(aFirstNewContent->OwnerDoc() == mDocument, "Unexpected document"); // We never call ContentAppended with a document as the container, so we can @@ -4519,8 +4519,8 @@ PresShell::ContentAppended(nsIContent* aFirstNewContent) void PresShell::ContentInserted(nsIContent* aChild) { - NS_PRECONDITION(!mIsDocumentGone, "Unexpected ContentInserted"); - NS_PRECONDITION(aChild->OwnerDoc() == mDocument, "Unexpected document"); + MOZ_ASSERT(!mIsDocumentGone, "Unexpected ContentInserted"); + MOZ_ASSERT(aChild->OwnerDoc() == mDocument, "Unexpected document"); if (!mDidInitialize) { return; @@ -4542,8 +4542,8 @@ PresShell::ContentInserted(nsIContent* aChild) void PresShell::ContentRemoved(nsIContent* aChild, nsIContent* aPreviousSibling) { - NS_PRECONDITION(!mIsDocumentGone, "Unexpected ContentRemoved"); - NS_PRECONDITION(aChild->OwnerDoc() == mDocument, "Unexpected document"); + MOZ_ASSERT(!mIsDocumentGone, "Unexpected ContentRemoved"); + MOZ_ASSERT(aChild->OwnerDoc() == mDocument, "Unexpected document"); nsINode* container = aChild->GetParentNode(); // Notify the ESM that the content has been removed, so that @@ -4593,8 +4593,8 @@ PresShell::NotifyCounterStylesAreDirty() void PresShell::ReconstructFrames() { - NS_PRECONDITION(!mFrameConstructor->GetRootFrame() || mDidInitialize, - "Must not have root frame before initial reflow"); + MOZ_ASSERT(!mFrameConstructor->GetRootFrame() || mDidInitialize, + "Must not have root frame before initial reflow"); if (!mDidInitialize || mIsDestroying) { // Nothing to do here return; @@ -8848,7 +8848,7 @@ PresShell::sReflowContinueCallback(nsITimer* aTimer, void* aPresShell) { RefPtr self = static_cast(aPresShell); - NS_PRECONDITION(aTimer == self->mReflowContinueTimer, "Unexpected timer"); + MOZ_ASSERT(aTimer == self->mReflowContinueTimer, "Unexpected timer"); self->mReflowContinueTimer = nullptr; self->ScheduleReflow(); } @@ -8856,7 +8856,7 @@ PresShell::sReflowContinueCallback(nsITimer* aTimer, void* aPresShell) bool PresShell::ScheduleReflowOffTimer() { - NS_PRECONDITION(!mObservingLayoutFlushes, "Shouldn't get here"); + MOZ_ASSERT(!mObservingLayoutFlushes, "Shouldn't get here"); ASSERT_REFLOW_SCHEDULED_STATE(); if (!mReflowContinueTimer) { @@ -10442,7 +10442,7 @@ SetPluginIsActive(nsISupports* aSupports, void* aClosure) nsresult PresShell::SetIsActive(bool aIsActive) { - NS_PRECONDITION(mDocument, "should only be called with a document"); + MOZ_ASSERT(mDocument, "should only be called with a document"); mIsActive = aIsActive; diff --git a/layout/base/RestyleManager.cpp b/layout/base/RestyleManager.cpp index 680127878f5f..803b6b581ce2 100644 --- a/layout/base/RestyleManager.cpp +++ b/layout/base/RestyleManager.cpp @@ -991,8 +991,8 @@ static void DoApplyRenderingChangeToTree(nsIFrame* aFrame, nsChangeHint aChange) { - NS_PRECONDITION(gInApplyRenderingChangeToTree, - "should only be called within ApplyRenderingChangeToTree"); + MOZ_ASSERT(gInApplyRenderingChangeToTree, + "should only be called within ApplyRenderingChangeToTree"); for ( ; aFrame; aFrame = nsLayoutUtils::GetNextContinuationOrIBSplitSibling(aFrame)) { // Invalidate and sync views on all descendant frames, following placeholders. @@ -1091,8 +1091,9 @@ DoApplyRenderingChangeToTree(nsIFrame* aFrame, static void SyncViewsAndInvalidateDescendants(nsIFrame* aFrame, nsChangeHint aChange) { - NS_PRECONDITION(gInApplyRenderingChangeToTree, - "should only be called within ApplyRenderingChangeToTree"); + MOZ_ASSERT(gInApplyRenderingChangeToTree, + "should only be called within ApplyRenderingChangeToTree"); + NS_ASSERTION(nsChangeHint_size_t(aChange) == (aChange & (nsChangeHint_RepaintFrame | nsChangeHint_SyncFrameView | diff --git a/layout/base/nsBidiPresUtils.cpp b/layout/base/nsBidiPresUtils.cpp index f76b90b50a85..5443517d2f7d 100644 --- a/layout/base/nsBidiPresUtils.cpp +++ b/layout/base/nsBidiPresUtils.cpp @@ -627,8 +627,8 @@ CreateContinuation(nsIFrame* aFrame, nsIFrame** aNewFrame, bool aIsFluid) { - NS_PRECONDITION(aNewFrame, "null OUT ptr"); - NS_PRECONDITION(aFrame, "null ptr"); + MOZ_ASSERT(aNewFrame, "null OUT ptr"); + MOZ_ASSERT(aFrame, "null ptr"); *aNewFrame = nullptr; @@ -1867,8 +1867,8 @@ nsBidiPresUtils::EnsureBidiContinuation(nsIFrame* aFrame, int32_t aStart, int32_t aEnd) { - NS_PRECONDITION(aNewFrame, "null OUT ptr"); - NS_PRECONDITION(aFrame, "aFrame is null"); + MOZ_ASSERT(aNewFrame, "null OUT ptr"); + MOZ_ASSERT(aFrame, "aFrame is null"); aFrame->AdjustOffsetsForBidi(aStart, aEnd); return CreateContinuation(aFrame, aNewFrame, false); diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 6fa511a65547..40e501ad25f3 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -545,7 +545,7 @@ IsFramePartOfIBSplit(nsIFrame* aFrame) static nsContainerFrame* GetIBSplitSibling(nsIFrame* aFrame) { - NS_PRECONDITION(IsFramePartOfIBSplit(aFrame), "Shouldn't call this"); + MOZ_ASSERT(IsFramePartOfIBSplit(aFrame), "Shouldn't call this"); // We only store the "ib-split sibling" annotation with the first // frame in the continuation chain. Walk back to find that frame now. @@ -555,7 +555,7 @@ static nsContainerFrame* GetIBSplitSibling(nsIFrame* aFrame) static nsContainerFrame* GetIBSplitPrevSibling(nsIFrame* aFrame) { - NS_PRECONDITION(IsFramePartOfIBSplit(aFrame), "Shouldn't call this"); + MOZ_ASSERT(IsFramePartOfIBSplit(aFrame), "Shouldn't call this"); // We only store the ib-split sibling annotation with the first // frame in the continuation chain. Walk back to find that frame now. @@ -579,7 +579,7 @@ GetLastIBSplitSibling(nsIFrame* aFrame) static void SetFrameIsIBSplit(nsContainerFrame* aFrame, nsContainerFrame* aIBSplitSibling) { - NS_PRECONDITION(aFrame, "bad args!"); + MOZ_ASSERT(aFrame, "bad args!"); // We should be the only continuation NS_ASSERTION(!aFrame->GetPrevContinuation(), @@ -606,8 +606,8 @@ SetFrameIsIBSplit(nsContainerFrame* aFrame, nsContainerFrame* aIBSplitSibling) static nsIFrame* GetIBContainingBlockFor(nsIFrame* aFrame) { - NS_PRECONDITION(IsFramePartOfIBSplit(aFrame), - "GetIBContainingBlockFor() should only be called on known IB frames"); + MOZ_ASSERT(IsFramePartOfIBSplit(aFrame), + "GetIBContainingBlockFor() should only be called on known IB frames"); // Get the first "normal" ancestor of the target frame. nsIFrame* parentFrame; @@ -691,7 +691,7 @@ FindFirstNonBlock(const nsFrameList& aList) inline void SetInitialSingleChild(nsContainerFrame* aParent, nsIFrame* aFrame) { - NS_PRECONDITION(!aFrame->GetNextSibling(), "Should be using a frame list"); + MOZ_ASSERT(!aFrame->GetNextSibling(), "Should be using a frame list"); nsFrameList temp(aFrame, aFrame); aParent->SetInitialChildList(kPrincipalList, temp); } @@ -708,7 +708,7 @@ struct nsFrameItems : public nsFrameList void nsFrameItems::AddChild(nsIFrame* aChild) { - NS_PRECONDITION(aChild, "nsFrameItems::AddChild"); + MOZ_ASSERT(aChild, "nsFrameItems::AddChild"); // It'd be really nice if we could just AppendFrames(kPrincipalList, aChild) here, // but some of our callers put frames that have different @@ -1148,9 +1148,9 @@ void nsFrameConstructorState::PushFloatContainingBlock(nsContainerFrame* aNewFloatContainingBlock, nsFrameConstructorSaveState& aSaveState) { - NS_PRECONDITION(!aNewFloatContainingBlock || - aNewFloatContainingBlock->IsFloatContainingBlock(), - "Please push a real float containing block!"); + MOZ_ASSERT(!aNewFloatContainingBlock || + aNewFloatContainingBlock->IsFloatContainingBlock(), + "Please push a real float containing block!"); NS_ASSERTION(!aNewFloatContainingBlock || !ShouldSuppressFloatingOfDescendants(aNewFloatContainingBlock), "We should not push a frame that is supposed to _suppress_ " @@ -1166,7 +1166,7 @@ nsContainerFrame* nsFrameConstructorState::GetGeometricParent(const nsStyleDisplay* aStyleDisplay, nsContainerFrame* aContentParentFrame) const { - NS_PRECONDITION(aStyleDisplay, "Must have display struct!"); + MOZ_ASSERT(aStyleDisplay, "Must have display struct!"); // If there is no container for a fixed, absolute, or floating root // frame, we will ignore the positioning. This hack is originally @@ -1313,7 +1313,7 @@ nsFrameConstructorState::AddChild(nsIFrame* aNewFrame, bool aInsertAfter, nsIFrame* aInsertAfterFrame) { - NS_PRECONDITION(!aNewFrame->GetNextSibling(), "Shouldn't happen"); + MOZ_ASSERT(!aNewFrame->GetNextSibling(), "Shouldn't happen"); nsFrameState placeholderType; nsAbsoluteItems* outOfFlowFrameItems = @@ -1379,13 +1379,13 @@ nsFrameConstructorState::ProcessFrameInsertions(nsAbsoluteItems& aFrameItems, &aFrameItems == &mTopLayerFixedItems) && \ aChildListID == nsIFrame::kFixedList) #ifdef MOZ_XUL - NS_PRECONDITION(NS_NONXUL_LIST_TEST || - (&aFrameItems == &mPopupItems && - aChildListID == nsIFrame::kPopupList), - "Unexpected aFrameItems/aChildListID combination"); + MOZ_ASSERT(NS_NONXUL_LIST_TEST || + (&aFrameItems == &mPopupItems && + aChildListID == nsIFrame::kPopupList), + "Unexpected aFrameItems/aChildListID combination"); #else - NS_PRECONDITION(NS_NONXUL_LIST_TEST, - "Unexpected aFrameItems/aChildListID combination"); + MOZ_ASSERT(NS_NONXUL_LIST_TEST, + "Unexpected aFrameItems/aChildListID combination"); #endif if (aFrameItems.IsEmpty()) { @@ -2045,8 +2045,8 @@ nsCSSFrameConstructor::AdjustParentFrame(nsContainerFrame** aParentFra const FrameConstructionData* aFCData, ComputedStyle* aComputedStyle) { - NS_PRECONDITION(aComputedStyle, "Must have child's style"); - NS_PRECONDITION(aFCData, "Must have frame construction data"); + MOZ_ASSERT(aComputedStyle, "Must have child's style"); + MOZ_ASSERT(aFCData, "Must have frame construction data"); bool tablePart = ((aFCData->mBits & FCDATA_IS_TABLE_PART) != 0); @@ -2083,9 +2083,9 @@ nsCSSFrameConstructor::ConstructTable(nsFrameConstructorState& aState, const nsStyleDisplay* aDisplay, nsFrameItems& aFrameItems) { - NS_PRECONDITION(aDisplay->mDisplay == StyleDisplay::Table || - aDisplay->mDisplay == StyleDisplay::InlineTable, - "Unexpected call"); + MOZ_ASSERT(aDisplay->mDisplay == StyleDisplay::Table || + aDisplay->mDisplay == StyleDisplay::InlineTable, + "Unexpected call"); nsIContent* const content = aItem.mContent; ComputedStyle* const computedStyle = aItem.mComputedStyle; @@ -2376,10 +2376,10 @@ NeedFrameFor(const nsFrameConstructorState& aState, { // XXX the GetContent() != aChildContent check is needed due to bug 135040. // Remove it once that's fixed. - NS_PRECONDITION(!aChildContent->GetPrimaryFrame() || - aState.mCreatingExtraFrames || - aChildContent->GetPrimaryFrame()->GetContent() != aChildContent, - "Why did we get called?"); + MOZ_ASSERT(!aChildContent->GetPrimaryFrame() || + aState.mCreatingExtraFrames || + aChildContent->GetPrimaryFrame()->GetContent() != aChildContent, + "Why did we get called?"); // don't create a whitespace frame if aParentFrame doesn't want it. // always create frames for children in generated content. counter(), @@ -2729,10 +2729,10 @@ nsCSSFrameConstructor::ConstructRootFrame() void nsCSSFrameConstructor::SetUpDocElementContainingBlock(nsIContent* aDocElement) { - NS_PRECONDITION(aDocElement, "No element?"); - NS_PRECONDITION(!aDocElement->GetParent(), "Not root content?"); - NS_PRECONDITION(aDocElement->GetUncomposedDoc(), "Not in a document?"); - NS_PRECONDITION(aDocElement->GetUncomposedDoc()->GetRootElement() == + MOZ_ASSERT(aDocElement, "No element?"); + MOZ_ASSERT(!aDocElement->GetParent(), "Not root content?"); + MOZ_ASSERT(aDocElement->GetUncomposedDoc(), "Not in a document?"); + MOZ_ASSERT(aDocElement->GetUncomposedDoc()->GetRootElement() == aDocElement, "Not the root of the document?"); /* @@ -3057,8 +3057,9 @@ nsCSSFrameConstructor::CreatePlaceholderFrameFor(nsIPresShell* aPresShell, static inline void ClearLazyBits(nsIContent* aStartContent, nsIContent* aEndContent) { - NS_PRECONDITION(aStartContent || !aEndContent, - "Must have start child if we have an end child"); + MOZ_ASSERT(aStartContent || !aEndContent, + "Must have start child if we have an end child"); + for (nsIContent* cur = aStartContent; cur != aEndContent; cur = cur->GetNextSibling()) { cur->UnsetFlags(NODE_DESCENDANTS_NEED_FRAMES | NODE_NEEDS_FRAME); @@ -3473,7 +3474,7 @@ nsCSSFrameConstructor::ConstructTextFrame(const FrameConstructionData* aData, ComputedStyle* aComputedStyle, nsFrameItems& aFrameItems) { - NS_PRECONDITION(aData, "Must have frame construction data"); + MOZ_ASSERT(aData, "Must have frame construction data"); nsIFrame* newFrame = (*aData->mFunc.mCreationFunc)(mPresShell, aComputedStyle); @@ -5652,8 +5653,8 @@ nsCSSFrameConstructor::AddFrameConstructionItemsInternal(nsFrameConstructorState nsTArray* aAnonChildren, FrameConstructionItemList& aItems) { - NS_PRECONDITION(aContent->IsText() || aContent->IsElement(), - "Shouldn't get anything else here!"); + MOZ_ASSERT(aContent->IsText() || aContent->IsElement(), + "Shouldn't get anything else here!"); MOZ_ASSERT(aContent->IsInComposedDoc()); MOZ_ASSERT(!aContent->GetPrimaryFrame() || aState.mCreatingExtraFrames || aContent->NodeInfo()->NameAtom() == nsGkAtoms::area); @@ -6276,12 +6277,12 @@ nsCSSFrameConstructor::AppendFramesToParent(nsFrameConstructorState& aStat nsIFrame* aPrevSibling, bool aIsRecursiveCall) { - NS_PRECONDITION(!IsFramePartOfIBSplit(aParentFrame) || - !GetIBSplitSibling(aParentFrame) || - !GetIBSplitSibling(aParentFrame)->PrincipalChildList().FirstChild(), - "aParentFrame has a ib-split sibling with kids?"); - NS_PRECONDITION(!aPrevSibling || aPrevSibling->GetParent() == aParentFrame, - "Parent and prevsibling don't match"); + MOZ_ASSERT(!IsFramePartOfIBSplit(aParentFrame) || + !GetIBSplitSibling(aParentFrame) || + !GetIBSplitSibling(aParentFrame)->PrincipalChildList().FirstChild(), + "aParentFrame has a ib-split sibling with kids?"); + MOZ_ASSERT(!aPrevSibling || aPrevSibling->GetParent() == aParentFrame, + "Parent and prevsibling don't match"); nsIFrame* nextSibling = ::GetInsertNextSibling(aParentFrame, aPrevSibling); @@ -6604,8 +6605,7 @@ static nsContainerFrame* GetAdjustedParentFrame(nsContainerFrame* aParentFrame, nsIContent* aChildContent) { - NS_PRECONDITION(!aParentFrame->IsTableWrapperFrame(), - "Shouldn't be happening!"); + MOZ_ASSERT(!aParentFrame->IsTableWrapperFrame(), "Shouldn't be happening!"); nsContainerFrame* newParent = nullptr; @@ -6627,7 +6627,7 @@ nsCSSFrameConstructor::GetInsertionPrevSibling(InsertionPoint* aInsertion, nsIContent* aStartSkipChild, nsIContent* aEndSkipChild) { - NS_PRECONDITION(aInsertion->mParentFrame, "Must have parent frame to start with"); + MOZ_ASSERT(aInsertion->mParentFrame, "Must have parent frame to start with"); *aIsAppend = false; @@ -6738,7 +6738,7 @@ nsCSSFrameConstructor::AddTextItemIfNeeded(nsFrameConstructorState& aState, nsIContent* aPossibleTextContent, FrameConstructionItemList& aItems) { - NS_PRECONDITION(aPossibleTextContent, "Must have node"); + MOZ_ASSERT(aPossibleTextContent, "Must have node"); if (!aPossibleTextContent->IsText() || !aPossibleTextContent->HasFlag(NS_CREATE_FRAME_IF_NON_WHITESPACE) || aPossibleTextContent->HasFlag(NODE_NEEDS_FRAME)) { @@ -7416,7 +7416,7 @@ nsCSSFrameConstructor::ContentRangeInserted(nsIContent* aStartChild, AUTO_LAYOUT_PHASE_ENTRY_POINT(mPresShell->GetPresContext(), FrameC); - NS_PRECONDITION(aStartChild, "must always pass a child"); + MOZ_ASSERT(aStartChild, "must always pass a child"); #ifdef DEBUG if (gNoisyContentUpdates) { @@ -8211,8 +8211,8 @@ nsCSSFrameConstructor::ContentRemoved(nsIContent* aChild, static void InvalidateCanvasIfNeeded(nsIPresShell* presShell, nsIContent* node) { - NS_PRECONDITION(presShell->GetRootFrame(), "What happened here?"); - NS_PRECONDITION(presShell->GetPresContext(), "Say what?"); + MOZ_ASSERT(presShell->GetRootFrame(), "What happened here?"); + MOZ_ASSERT(presShell->GetPresContext(), "Say what?"); // Note that both in ContentRemoved and ContentInserted the content node // will still have the right parent pointer, so looking at that is ok. @@ -8856,10 +8856,10 @@ FindPreviousNonWhitespaceSibling(nsIFrame* aFrame) bool nsCSSFrameConstructor::MaybeRecreateContainerForFrameRemoval(nsIFrame* aFrame) { - NS_PRECONDITION(aFrame, "Must have a frame"); - NS_PRECONDITION(aFrame->GetParent(), "Frame shouldn't be root"); - NS_PRECONDITION(aFrame == aFrame->FirstContinuation(), - "aFrame not the result of GetPrimaryFrame()?"); + MOZ_ASSERT(aFrame, "Must have a frame"); + MOZ_ASSERT(aFrame->GetParent(), "Frame shouldn't be root"); + MOZ_ASSERT(aFrame == aFrame->FirstContinuation(), + "aFrame not the result of GetPrimaryFrame()?"); if (IsFramePartOfIBSplit(aFrame)) { // The removal functions can't handle removal of an {ib} split directly; we @@ -9281,7 +9281,7 @@ nsCSSFrameConstructor::ShouldHaveFirstLetterStyle(nsIContent* aContent, bool nsCSSFrameConstructor::HasFirstLetterStyle(nsIFrame* aBlockFrame) { - NS_PRECONDITION(aBlockFrame, "Need a frame"); + MOZ_ASSERT(aBlockFrame, "Need a frame"); NS_ASSERTION(nsLayoutUtils::GetAsBlock(aBlockFrame), "Not a block frame?"); @@ -10206,10 +10206,11 @@ nsCSSFrameConstructor::ProcessChildren(nsFrameConstructorState& aState, PendingBinding* aPendingBinding, nsIFrame* aPossiblyLeafFrame) { - NS_PRECONDITION(aFrame, "Must have parent frame here"); - NS_PRECONDITION(aFrame->GetContentInsertionFrame() == aFrame, - "Parent frame in ProcessChildren should be its own " - "content insertion frame"); + MOZ_ASSERT(aFrame, "Must have parent frame here"); + MOZ_ASSERT(aFrame->GetContentInsertionFrame() == aFrame, + "Parent frame in ProcessChildren should be its own " + "content insertion frame"); + const uint32_t kMaxDepth = 2 * MAX_REFLOW_DEPTH; static_assert(kMaxDepth <= UINT16_MAX, "mCurrentDepth type is too narrow"); AutoRestore savedDepth(mCurrentDepth); @@ -10599,7 +10600,7 @@ FirstLetterCount(const nsTextFragment* aFragment) static bool NeedFirstLetterContinuation(nsIContent* aContent) { - NS_PRECONDITION(aContent, "null ptr"); + MOZ_ASSERT(aContent, "null ptr"); bool result = false; if (aContent) { @@ -10702,7 +10703,7 @@ nsCSSFrameConstructor::CreateLetterFrame(nsContainerFrame* aBlockFrame, nsContainerFrame* aParentFrame, nsFrameItems& aResult) { - NS_PRECONDITION(aTextContent->IsText(), "aTextContent isn't text"); + MOZ_ASSERT(aTextContent->IsText(), "aTextContent isn't text"); NS_ASSERTION(nsLayoutUtils::GetAsBlock(aBlockFrame), "Not a block frame?"); @@ -11427,9 +11428,9 @@ nsCSSFrameConstructor::CreateIBSiblings(nsFrameConstructorState& aState, do { // On entry to this loop aChildItems is not empty and the first frame in it // is block-level. - NS_PRECONDITION(aChildItems.NotEmpty(), "Should have child items"); - NS_PRECONDITION(!aChildItems.FirstChild()->IsInlineOutside(), - "Must have list starting with block"); + MOZ_ASSERT(aChildItems.NotEmpty(), "Should have child items"); + MOZ_ASSERT(!aChildItems.FirstChild()->IsInlineOutside(), + "Must have list starting with block"); // The initial run of blocks belongs to an anonymous block that we create // right now. The anonymous block will be the parent of these block @@ -11547,8 +11548,8 @@ nsCSSFrameConstructor::BuildInlineChildItems(nsFrameConstructorState& aState, static bool IsSafeToAppendToIBSplitInline(nsIFrame* aParentFrame, nsIFrame* aNextSibling) { - NS_PRECONDITION(IsInlineFrame(aParentFrame), - "Must have an inline parent here"); + MOZ_ASSERT(IsInlineFrame(aParentFrame), "Must have an inline parent here"); + do { NS_ASSERTION(IsFramePartOfIBSplit(aParentFrame), "How is this not part of an ib-split?"); @@ -12012,8 +12013,8 @@ bool nsCSSFrameConstructor:: FrameConstructionItem::IsWhitespace(nsFrameConstructorState& aState) const { - NS_PRECONDITION(aState.mCreatingExtraFrames || - !mContent->GetPrimaryFrame(), "How did that happen?"); + MOZ_ASSERT(aState.mCreatingExtraFrames || + !mContent->GetPrimaryFrame(), "How did that happen?"); if (!mIsText) { return false; } @@ -12029,7 +12030,7 @@ void nsCSSFrameConstructor::FrameConstructionItemList:: AdjustCountsForItem(FrameConstructionItem* aItem, int32_t aDelta) { - NS_PRECONDITION(aDelta == 1 || aDelta == -1, "Unexpected delta"); + MOZ_ASSERT(aDelta == 1 || aDelta == -1, "Unexpected delta"); mItemCount += aDelta; if (aItem->mIsAllInline) { mInlineCount += aDelta; @@ -12050,7 +12051,7 @@ inline bool nsCSSFrameConstructor::FrameConstructionItemList:: Iterator::SkipItemsWantingParentType(ParentType aParentType) { - NS_PRECONDITION(!IsDone(), "Shouldn't be done yet"); + MOZ_ASSERT(!IsDone(), "Shouldn't be done yet"); while (item().DesiredParentType() == aParentType) { Next(); if (IsDone()) { @@ -12064,7 +12065,7 @@ inline bool nsCSSFrameConstructor::FrameConstructionItemList:: Iterator::SkipItemsNotWantingParentType(ParentType aParentType) { - NS_PRECONDITION(!IsDone(), "Shouldn't be done yet"); + MOZ_ASSERT(!IsDone(), "Shouldn't be done yet"); while (item().DesiredParentType() != aParentType) { Next(); if (IsDone()) { @@ -12115,7 +12116,7 @@ Iterator::SkipItemsThatNeedAnonFlexOrGridItem( const nsFrameConstructorState& aState, bool aIsLegacyBox) { - NS_PRECONDITION(!IsDone(), "Shouldn't be done yet"); + MOZ_ASSERT(!IsDone(), "Shouldn't be done yet"); while (item().NeedsAnonFlexOrGridItem(aState, aIsLegacyBox)) { Next(); if (IsDone()) { @@ -12131,7 +12132,7 @@ Iterator::SkipItemsThatDontNeedAnonFlexOrGridItem( const nsFrameConstructorState& aState, bool aIsLegacyBox) { - NS_PRECONDITION(!IsDone(), "Shouldn't be done yet"); + MOZ_ASSERT(!IsDone(), "Shouldn't be done yet"); while (!(item().NeedsAnonFlexOrGridItem(aState, aIsLegacyBox))) { Next(); if (IsDone()) { @@ -12145,7 +12146,7 @@ inline bool nsCSSFrameConstructor::FrameConstructionItemList:: Iterator::SkipItemsNotWantingRubyParent() { - NS_PRECONDITION(!IsDone(), "Shouldn't be done yet"); + MOZ_ASSERT(!IsDone(), "Shouldn't be done yet"); while (!IsRubyParentType(item().DesiredParentType())) { Next(); if (IsDone()) { @@ -12159,8 +12160,8 @@ inline bool nsCSSFrameConstructor::FrameConstructionItemList:: Iterator::SkipWhitespace(nsFrameConstructorState& aState) { - NS_PRECONDITION(!IsDone(), "Shouldn't be done yet"); - NS_PRECONDITION(item().IsWhitespace(aState), "Not pointing to whitespace?"); + MOZ_ASSERT(!IsDone(), "Shouldn't be done yet"); + MOZ_ASSERT(item().IsWhitespace(aState), "Not pointing to whitespace?"); do { Next(); if (IsDone()) { @@ -12176,7 +12177,7 @@ nsCSSFrameConstructor::FrameConstructionItemList:: Iterator::AppendItemToList(FrameConstructionItemList& aTargetList) { NS_ASSERTION(&aTargetList != &mList, "Unexpected call"); - NS_PRECONDITION(!IsDone(), "should not be done"); + MOZ_ASSERT(!IsDone(), "should not be done"); FrameConstructionItem* item = mCurrent; Next(); @@ -12193,7 +12194,7 @@ Iterator::AppendItemsToList(nsCSSFrameConstructor* aFCtor, const Iterator& aEnd, FrameConstructionItemList& aTargetList) { NS_ASSERTION(&aTargetList != &mList, "Unexpected call"); - NS_PRECONDITION(&mList == &aEnd.mList, "End iterator for some other list?"); + MOZ_ASSERT(&mList == &aEnd.mList, "End iterator for some other list?"); // We can't just move our guts to the other list if it already has // some information or if we're not moving our entire list. @@ -12242,8 +12243,8 @@ void nsCSSFrameConstructor::FrameConstructionItemList:: Iterator::DeleteItemsTo(nsCSSFrameConstructor* aFCtor, const Iterator& aEnd) { - NS_PRECONDITION(&mList == &aEnd.mList, "End iterator for some other list?"); - NS_PRECONDITION(*this != aEnd, "Shouldn't be at aEnd yet"); + MOZ_ASSERT(&mList == &aEnd.mList, "End iterator for some other list?"); + MOZ_ASSERT(*this != aEnd, "Shouldn't be at aEnd yet"); do { NS_ASSERTION(!IsDone(), "Ran off end of list?"); diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp index f53aa837bbda..c95a0fe8b2dc 100644 --- a/layout/base/nsDocumentViewer.cpp +++ b/layout/base/nsDocumentViewer.cpp @@ -2586,9 +2586,9 @@ nsDocumentViewer::FindContainerView() nsresult nsDocumentViewer::CreateDeviceContext(nsView* aContainerView) { - NS_PRECONDITION(!mPresShell && !mWindow, - "This will screw up our existing presentation"); - NS_PRECONDITION(mDocument, "Gotta have a document here"); + MOZ_ASSERT(!mPresShell && !mWindow, + "This will screw up our existing presentation"); + MOZ_ASSERT(mDocument, "Gotta have a document here"); nsIDocument* doc = mDocument->GetDisplayDocument(); if (doc) { diff --git a/layout/base/nsFrameManager.cpp b/layout/base/nsFrameManager.cpp index e43114197488..566ec96fa905 100644 --- a/layout/base/nsFrameManager.cpp +++ b/layout/base/nsFrameManager.cpp @@ -84,10 +84,10 @@ nsFrameManager::InsertFrames(nsContainerFrame* aParentFrame, nsIFrame* aPrevFrame, nsFrameList& aFrameList) { - NS_PRECONDITION(!aPrevFrame || (!aPrevFrame->GetNextContinuation() - || (((aPrevFrame->GetNextContinuation()->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER)) - && !(aPrevFrame->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER))), - "aPrevFrame must be the last continuation in its chain!"); + MOZ_ASSERT(!aPrevFrame || (!aPrevFrame->GetNextContinuation() + || (((aPrevFrame->GetNextContinuation()->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER)) + && !(aPrevFrame->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER))), + "aPrevFrame must be the last continuation in its chain!"); if (aParentFrame->IsAbsoluteContainer() && aListID == aParentFrame->GetAbsoluteListID()) { @@ -170,7 +170,7 @@ void nsFrameManager::CaptureFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState) { - NS_PRECONDITION(nullptr != aFrame && nullptr != aState, "null parameters passed in"); + MOZ_ASSERT(nullptr != aFrame && nullptr != aState, "null parameters passed in"); CaptureFrameStateFor(aFrame, aState); @@ -245,7 +245,7 @@ void nsFrameManager::RestoreFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState) { - NS_PRECONDITION(nullptr != aFrame && nullptr != aState, "null parameters passed in"); + MOZ_ASSERT(nullptr != aFrame && nullptr != aState, "null parameters passed in"); RestoreFrameStateFor(aFrame, aState); diff --git a/layout/base/nsLayoutDebugger.cpp b/layout/base/nsLayoutDebugger.cpp index 6488280371b3..fd2019b8c662 100644 --- a/layout/base/nsLayoutDebugger.cpp +++ b/layout/base/nsLayoutDebugger.cpp @@ -44,7 +44,7 @@ protected: nsresult NS_NewLayoutDebugger(nsILayoutDebugger** aResult) { - NS_PRECONDITION(aResult, "null OUT ptr"); + MOZ_ASSERT(aResult, "null OUT ptr"); if (!aResult) { return NS_ERROR_NULL_POINTER; } diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 968265a1a117..6267a799d860 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -1380,7 +1380,7 @@ nsLayoutUtils::RemoveDisplayPort(nsIContent* aContent) nsContainerFrame* nsLayoutUtils::LastContinuationWithChild(nsContainerFrame* aFrame) { - NS_PRECONDITION(aFrame, "NULL frame pointer"); + MOZ_ASSERT(aFrame, "NULL frame pointer"); nsIFrame* f = aFrame->LastContinuation(); while (!f->PrincipalChildList().FirstChild() && f->GetPrevContinuation()) { f = f->GetPrevContinuation(); @@ -1623,8 +1623,8 @@ nsLayoutUtils::DoCompareTreePosition(nsIContent* aContent1, int32_t aIf2Ancestor, const nsIContent* aCommonAncestor) { - NS_PRECONDITION(aContent1, "aContent1 must not be null"); - NS_PRECONDITION(aContent2, "aContent2 must not be null"); + MOZ_ASSERT(aContent1, "aContent1 must not be null"); + MOZ_ASSERT(aContent2, "aContent2 must not be null"); AutoTArray content1Ancestors; nsINode* c1; @@ -1728,8 +1728,8 @@ nsLayoutUtils::DoCompareTreePosition(nsIFrame* aFrame1, int32_t aIf2Ancestor, nsIFrame* aCommonAncestor) { - NS_PRECONDITION(aFrame1, "aFrame1 must not be null"); - NS_PRECONDITION(aFrame2, "aFrame2 must not be null"); + MOZ_ASSERT(aFrame1, "aFrame1 must not be null"); + MOZ_ASSERT(aFrame2, "aFrame2 must not be null"); AutoTArray frame2Ancestors; nsIFrame* nonCommonAncestor = @@ -1749,8 +1749,8 @@ nsLayoutUtils::DoCompareTreePosition(nsIFrame* aFrame1, int32_t aIf2Ancestor, nsIFrame* aCommonAncestor) { - NS_PRECONDITION(aFrame1, "aFrame1 must not be null"); - NS_PRECONDITION(aFrame2, "aFrame2 must not be null"); + MOZ_ASSERT(aFrame1, "aFrame1 must not be null"); + MOZ_ASSERT(aFrame2, "aFrame2 must not be null"); nsPresContext* presContext = aFrame1->PresContext(); if (presContext != aFrame2->PresContext()) { @@ -2082,7 +2082,7 @@ nsLayoutUtils::HasPseudoStyle(nsIContent* aContent, CSSPseudoElementType aPseudoElement, nsPresContext* aPresContext) { - NS_PRECONDITION(aPresContext, "Must have a prescontext"); + MOZ_ASSERT(aPresContext, "Must have a prescontext"); RefPtr pseudoContext; if (aContent) { @@ -4990,8 +4990,9 @@ GetIntrinsicCoord(const nsStyleCoord& aStyle, eWidthProperty aProperty, nscoord& aResult) { - NS_PRECONDITION(aProperty == PROP_WIDTH || aProperty == PROP_MAX_WIDTH || - aProperty == PROP_MIN_WIDTH, "unexpected property"); + MOZ_ASSERT(aProperty == PROP_WIDTH || aProperty == PROP_MAX_WIDTH || + aProperty == PROP_MIN_WIDTH, "unexpected property"); + if (aStyle.GetUnit() != eStyleUnit_Enumerated) return false; int32_t val = aStyle.GetIntValue(); @@ -5212,10 +5213,10 @@ nsLayoutUtils::IntrinsicForAxis(PhysicalAxis aAxis, uint32_t aFlags, nscoord aMarginBoxMinSizeClamp) { - NS_PRECONDITION(aFrame, "null frame"); - NS_PRECONDITION(aFrame->GetParent(), - "IntrinsicForAxis called on frame not in tree"); - NS_PRECONDITION(aType == MIN_ISIZE || aType == PREF_ISIZE, "bad type"); + MOZ_ASSERT(aFrame, "null frame"); + MOZ_ASSERT(aFrame->GetParent(), + "IntrinsicForAxis called on frame not in tree"); + MOZ_ASSERT(aType == MIN_ISIZE || aType == PREF_ISIZE, "bad type"); MOZ_ASSERT(aFrame->GetParent()->Type() != LayoutFrameType::GridContainer || aPercentageBasis.isSome(), "grid layout should always pass a percentage basis"); @@ -5595,9 +5596,9 @@ nsLayoutUtils::ComputeBSizeDependentValue( // the unit conditions. // XXXldb Many callers pass a non-'auto' containing block height when // according to CSS2.1 they should be passing 'auto'. - NS_PRECONDITION(NS_AUTOHEIGHT != aContainingBlockBSize || - !aCoord.HasPercent(), - "unexpected containing block block-size"); + MOZ_ASSERT(NS_AUTOHEIGHT != aContainingBlockBSize || + !aCoord.HasPercent(), + "unexpected containing block block-size"); if (aCoord.IsCoordPercentCalcUnit()) { return aCoord.ComputeCoordPercentCalc(aContainingBlockBSize); @@ -6304,7 +6305,7 @@ nsLayoutUtils::GetLastLineBaseline(WritingMode aWM, static nscoord CalculateBlockContentBEnd(WritingMode aWM, nsBlockFrame* aFrame) { - NS_PRECONDITION(aFrame, "null ptr"); + MOZ_ASSERT(aFrame, "null ptr"); nscoord contentBEnd = 0; @@ -6330,7 +6331,7 @@ CalculateBlockContentBEnd(WritingMode aWM, nsBlockFrame* aFrame) /* static */ nscoord nsLayoutUtils::CalculateContentBEnd(WritingMode aWM, nsIFrame* aFrame) { - NS_PRECONDITION(aFrame, "null ptr"); + MOZ_ASSERT(aFrame, "null ptr"); nscoord contentBEnd = aFrame->BSize(aWM); @@ -7836,7 +7837,7 @@ GetFontFacesForFramesInner(nsIFrame* aFrame, nsLayoutUtils::UsedFontFaceTable& aFontFaces, uint32_t aMaxRanges) { - NS_PRECONDITION(aFrame, "NULL frame pointer"); + MOZ_ASSERT(aFrame, "NULL frame pointer"); if (aFrame->IsTextFrame()) { if (!aFrame->GetPrevContinuation()) { @@ -7863,7 +7864,7 @@ nsLayoutUtils::GetFontFacesForFrames(nsIFrame* aFrame, UsedFontFaceTable& aFontFaces, uint32_t aMaxRanges) { - NS_PRECONDITION(aFrame, "NULL frame pointer"); + MOZ_ASSERT(aFrame, "NULL frame pointer"); while (aFrame) { GetFontFacesForFramesInner(aFrame, aFontFaces, aMaxRanges); @@ -7939,7 +7940,7 @@ nsLayoutUtils::GetFontFacesForText(nsIFrame* aFrame, UsedFontFaceTable& aFontFaces, uint32_t aMaxRanges) { - NS_PRECONDITION(aFrame, "NULL frame pointer"); + MOZ_ASSERT(aFrame, "NULL frame pointer"); if (!aFrame->IsTextFrame()) { return; @@ -7991,7 +7992,7 @@ nsLayoutUtils::SizeOfTextRunsForFrames(nsIFrame* aFrame, MallocSizeOf aMallocSizeOf, bool clear) { - NS_PRECONDITION(aFrame, "NULL frame pointer"); + MOZ_ASSERT(aFrame, "NULL frame pointer"); size_t total = 0; diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp index 54a19a629c2f..305ae885a640 100644 --- a/layout/base/nsPresContext.cpp +++ b/layout/base/nsPresContext.cpp @@ -357,7 +357,7 @@ nsPresContext::Destroy() nsPresContext::~nsPresContext() { - NS_PRECONDITION(!mShell, "Presshell forgot to clear our mShell pointer"); + MOZ_ASSERT(!mShell, "Presshell forgot to clear our mShell pointer"); DetachShell(); Destroy(); @@ -2854,7 +2854,7 @@ nsPresContext::CheckForInterrupt(nsIFrame* aFrame) nsIFrame* nsPresContext::GetPrimaryFrameFor(nsIContent* aContent) { - NS_PRECONDITION(aContent, "Don't do that"); + MOZ_ASSERT(aContent, "Don't do that"); if (GetPresShell() && GetPresShell()->GetDocument() == aContent->GetComposedDoc()) { return aContent->GetPrimaryFrame(); diff --git a/layout/base/nsRefreshDriver.cpp b/layout/base/nsRefreshDriver.cpp index 1769e94f4f04..24024e015e2c 100644 --- a/layout/base/nsRefreshDriver.cpp +++ b/layout/base/nsRefreshDriver.cpp @@ -1511,10 +1511,10 @@ nsRefreshDriver::ArrayFor(FlushType aFlushType) void nsRefreshDriver::DoTick() { - NS_PRECONDITION(!IsFrozen(), "Why are we notified while frozen?"); - NS_PRECONDITION(mPresContext, "Why are we notified after disconnection?"); - NS_PRECONDITION(!nsContentUtils::GetCurrentJSContext(), - "Shouldn't have a JSContext on the stack"); + MOZ_ASSERT(!IsFrozen(), "Why are we notified while frozen?"); + MOZ_ASSERT(mPresContext, "Why are we notified after disconnection?"); + MOZ_ASSERT(!nsContentUtils::GetCurrentJSContext(), + "Shouldn't have a JSContext on the stack"); if (mTestControllingRefreshes) { Tick(mMostRecentRefreshEpochTime, mMostRecentRefresh); @@ -1782,8 +1782,8 @@ nsRefreshDriver::CancelIdleRunnable(nsIRunnable* aRunnable) void nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime) { - NS_PRECONDITION(!nsContentUtils::GetCurrentJSContext(), - "Shouldn't have a JSContext on the stack"); + MOZ_ASSERT(!nsContentUtils::GetCurrentJSContext(), + "Shouldn't have a JSContext on the stack"); if (nsNPAPIPluginInstance::InPluginCallUnsafeForReentry()) { NS_ERROR("Refresh driver should not run during plugin call!"); diff --git a/layout/base/nsStyleSheetService.cpp b/layout/base/nsStyleSheetService.cpp index 2debac212d5d..0e379477584a 100644 --- a/layout/base/nsStyleSheetService.cpp +++ b/layout/base/nsStyleSheetService.cpp @@ -246,7 +246,7 @@ nsStyleSheetService::SheetRegistered(nsIURI *sheetURI, aSheetType == USER_SHEET || aSheetType == AUTHOR_SHEET); NS_ENSURE_ARG_POINTER(sheetURI); - NS_PRECONDITION(_retval, "Null out param"); + MOZ_ASSERT(_retval, "Null out param"); // Check to see if we have the sheet. *_retval = (FindSheetByURI(aSheetType, sheetURI) >= 0); @@ -280,7 +280,7 @@ NS_IMETHODIMP nsStyleSheetService::PreloadSheet(nsIURI* aSheetURI, uint32_t aSheetType, nsIPreloadedStyleSheet** aSheet) { - NS_PRECONDITION(aSheet, "Null out param"); + MOZ_ASSERT(aSheet, "Null out param"); NS_ENSURE_ARG_POINTER(aSheetURI); css::SheetParsingMode parsingMode; diff --git a/layout/build/nsContentDLF.cpp b/layout/build/nsContentDLF.cpp index e879dab5dc3b..b0ed9ebb10dc 100644 --- a/layout/build/nsContentDLF.cpp +++ b/layout/build/nsContentDLF.cpp @@ -94,7 +94,7 @@ IsTypeInList(const nsACString& aType, const char* const aList[]) nsresult NS_NewContentDocumentLoaderFactory(nsIDocumentLoaderFactory** aResult) { - NS_PRECONDITION(aResult, "null OUT ptr"); + MOZ_ASSERT(aResult, "null OUT ptr"); if (!aResult) { return NS_ERROR_NULL_POINTER; } diff --git a/layout/build/nsLayoutModule.cpp b/layout/build/nsLayoutModule.cpp index 76f2e647aa8b..416cda00e9e6 100644 --- a/layout/build/nsLayoutModule.cpp +++ b/layout/build/nsLayoutModule.cpp @@ -285,7 +285,7 @@ Initialize() void Shutdown() { - NS_PRECONDITION(gInitialized, "module not initialized"); + MOZ_ASSERT(gInitialized, "module not initialized"); if (!gInitialized) return; diff --git a/layout/forms/nsComboboxControlFrame.cpp b/layout/forms/nsComboboxControlFrame.cpp index 9489749acfa7..8a55cc35f5f5 100644 --- a/layout/forms/nsComboboxControlFrame.cpp +++ b/layout/forms/nsComboboxControlFrame.cpp @@ -1061,7 +1061,7 @@ nsComboboxControlFrame::HandleRedisplayTextEvent() // Redirect frame insertions during this method (see GetContentInsertionFrame()) // so that any reframing that the frame constructor forces upon us is inserted // into the correct parent (mDisplayFrame). See bug 282607. - NS_PRECONDITION(!mInRedisplayText, "Nested RedisplayText"); + MOZ_ASSERT(!mInRedisplayText, "Nested RedisplayText"); mInRedisplayText = true; mRedisplayTextEvent.Forget(); diff --git a/layout/forms/nsFieldSetFrame.cpp b/layout/forms/nsFieldSetFrame.cpp index 9260c81c2d6a..b88319604534 100644 --- a/layout/forms/nsFieldSetFrame.cpp +++ b/layout/forms/nsFieldSetFrame.cpp @@ -365,8 +365,8 @@ nsFieldSetFrame::Reflow(nsPresContext* aPresContext, DO_GLOBAL_REFLOW_COUNT("nsFieldSetFrame"); DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus); MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!"); - NS_PRECONDITION(aReflowInput.ComputedISize() != NS_INTRINSICSIZE, - "Should have a precomputed inline-size!"); + MOZ_ASSERT(aReflowInput.ComputedISize() != NS_INTRINSICSIZE, + "Should have a precomputed inline-size!"); nsOverflowAreas ocBounds; nsReflowStatus ocStatus; @@ -706,4 +706,3 @@ nsFieldSetFrame::AppendDirectlyOwnedAnonBoxes(nsTArray& aResult) aResult.AppendElement(OwnedAnonBox(kid)); } } - diff --git a/layout/forms/nsListControlFrame.cpp b/layout/forms/nsListControlFrame.cpp index 79edd0a4e9d4..3e3410a1fce3 100644 --- a/layout/forms/nsListControlFrame.cpp +++ b/layout/forms/nsListControlFrame.cpp @@ -368,8 +368,8 @@ nsListControlFrame::Reflow(nsPresContext* aPresContext, nsReflowStatus& aStatus) { MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!"); - NS_PRECONDITION(aReflowInput.ComputedISize() != NS_UNCONSTRAINEDSIZE, - "Must have a computed inline size"); + MOZ_ASSERT(aReflowInput.ComputedISize() != NS_UNCONSTRAINEDSIZE, + "Must have a computed inline size"); SchedulePaint(); @@ -503,8 +503,8 @@ nsListControlFrame::ReflowAsDropdown(nsPresContext* aPresContext, const ReflowInput& aReflowInput, nsReflowStatus& aStatus) { - NS_PRECONDITION(aReflowInput.ComputedBSize() == NS_UNCONSTRAINEDSIZE, - "We should not have a computed block size here!"); + MOZ_ASSERT(aReflowInput.ComputedBSize() == NS_UNCONSTRAINEDSIZE, + "We should not have a computed block size here!"); mMightNeedSecondPass = NS_SUBTREE_DIRTY(this) || aReflowInput.ShouldReflowAllKids(); @@ -1243,7 +1243,7 @@ DecrementAndClamp(int32_t aSelectionIndex, int32_t aLength) NS_IMETHODIMP nsListControlFrame::RemoveOption(int32_t aIndex) { - NS_PRECONDITION(aIndex >= 0, "negative

+ * + * Note that the sink will acquire a strong reference to the + * observer, so care should be taken to avoid cyclical references + * that cannot be released (i.e., if the observer holds a + * reference to the sink, it should be sure that it eventually + * clears the reference). + * + * @param aObserver the observer to add to the sink's set of + * load observers. + */ + void addXMLSinkObserver(in nsIRDFXMLSinkObserver aObserver); + + /** + * Remove an observer from the sink's set of observers. + * @param aObserver the observer to remove. + */ + void removeXMLSinkObserver(in nsIRDFXMLSinkObserver aObserver); +}; + diff --git a/rdf/base/nsIRDFXMLSource.idl b/rdf/base/nsIRDFXMLSource.idl new file mode 100644 index 000000000000..794d8b66269b --- /dev/null +++ b/rdf/base/nsIRDFXMLSource.idl @@ -0,0 +1,20 @@ +/* -*- 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/. */ + +#include "nsISupports.idl" +#include "nsIOutputStream.idl" + +[scriptable, uuid(4DA56F10-99FE-11d2-8EBB-00805F29F370)] +interface nsIRDFXMLSource : nsISupports +{ + /** + * Serialize the contents of the datasource to aStream. + * @param aStream the output stream the will receive the + * RDF/XML. Currently, the output stream need only + * implement the |write()| method. + */ + void Serialize(in nsIOutputStream aStream); +}; + diff --git a/rdf/base/nsInMemoryDataSource.cpp b/rdf/base/nsInMemoryDataSource.cpp new file mode 100644 index 000000000000..fe2d3199bf7e --- /dev/null +++ b/rdf/base/nsInMemoryDataSource.cpp @@ -0,0 +1,1938 @@ +/* -*- 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/. */ + +/* + + Implementation for an in-memory RDF data store. + + TO DO + + 1) Instrument this code to gather space and time performance + characteristics. + + 2) Optimize lookups for datasources which have a small number + of properties + fanning out to a large number of targets. + + 3) Complete implementation of thread-safety; specifically, make + assertions be reference counted objects (so that a cursor can + still refer to an assertion that gets removed from the graph). + + */ + +#include "nsAgg.h" +#include "nsCOMPtr.h" +#include "nscore.h" +#include "nsArrayEnumerator.h" +#include "nsIOutputStream.h" +#include "nsIRDFDataSource.h" +#include "nsIRDFLiteral.h" +#include "nsIRDFNode.h" +#include "nsIRDFObserver.h" +#include "nsIRDFInMemoryDataSource.h" +#include "nsIRDFPropagatableDataSource.h" +#include "nsIRDFPurgeableDataSource.h" +#include "nsIRDFService.h" +#include "nsIServiceManager.h" +#include "nsCOMArray.h" +#include "nsEnumeratorUtils.h" +#include "nsTArray.h" +#include "nsCRT.h" +#include "nsRDFCID.h" +#include "nsRDFBaseDataSources.h" +#include "nsString.h" +#include "nsReadableUtils.h" +#include "nsString.h" +#include "rdfutil.h" +#include "PLDHashTable.h" +#include "plstr.h" +#include "mozilla/Logging.h" +#include "rdf.h" + +#include "rdfIDataSource.h" +#include "rdfITripleVisitor.h" + +using mozilla::LogLevel; + +// This struct is used as the slot value in the forward and reverse +// arcs hash tables. +// +// Assertion objects are reference counted, because each Assertion's +// ownership is shared between the datasource and any enumerators that +// are currently iterating over the datasource. +// +class Assertion +{ +public: + Assertion(nsIRDFResource* aSource, // normal assertion + nsIRDFResource* aProperty, + nsIRDFNode* aTarget, + bool aTruthValue); + explicit Assertion(nsIRDFResource* aSource); // PLDHashTable assertion variant + +private: + ~Assertion(); + +public: + void AddRef() { + if (mRefCnt == UINT16_MAX) { + NS_WARNING("refcount overflow, leaking Assertion"); + return; + } + ++mRefCnt; + } + + void Release() { + if (mRefCnt == UINT16_MAX) { + NS_WARNING("refcount overflow, leaking Assertion"); + return; + } + if (--mRefCnt == 0) + delete this; + } + + // For nsIRDFPurgeableDataSource + inline void Mark() { u.as.mMarked = true; } + inline bool IsMarked() { return u.as.mMarked; } + inline void Unmark() { u.as.mMarked = false; } + + // public for now, because I'm too lazy to go thru and clean this up. + + // These are shared between hash/as (see the union below) + nsIRDFResource* mSource; + Assertion* mNext; + + union + { + struct hash + { + PLDHashTable* mPropertyHash; + } hash; + struct as + { + nsIRDFResource* mProperty; + nsIRDFNode* mTarget; + Assertion* mInvNext; + // make sure bool are final elements + bool mTruthValue; + bool mMarked; + } as; + } u; + + // also shared between hash/as (see the union above) + // but placed after union definition to ensure that + // all 32-bit entries are long aligned + uint16_t mRefCnt; + bool mHashEntry; +}; + + +struct Entry : PLDHashEntryHdr { + nsIRDFNode* mNode; + Assertion* mAssertions; +}; + + +Assertion::Assertion(nsIRDFResource* aSource) + : mSource(aSource), + mNext(nullptr), + mRefCnt(0), + mHashEntry(true) +{ + MOZ_COUNT_CTOR(Assertion); + + NS_ADDREF(mSource); + + u.hash.mPropertyHash = + new PLDHashTable(PLDHashTable::StubOps(), sizeof(Entry)); +} + +Assertion::Assertion(nsIRDFResource* aSource, + nsIRDFResource* aProperty, + nsIRDFNode* aTarget, + bool aTruthValue) + : mSource(aSource), + mNext(nullptr), + mRefCnt(0), + mHashEntry(false) +{ + MOZ_COUNT_CTOR(Assertion); + + u.as.mProperty = aProperty; + u.as.mTarget = aTarget; + + NS_ADDREF(mSource); + NS_ADDREF(u.as.mProperty); + NS_ADDREF(u.as.mTarget); + + u.as.mInvNext = nullptr; + u.as.mTruthValue = aTruthValue; + u.as.mMarked = false; +} + +Assertion::~Assertion() +{ + if (mHashEntry && u.hash.mPropertyHash) { + for (auto i = u.hash.mPropertyHash->Iter(); !i.Done(); i.Next()) { + auto entry = static_cast(i.Get()); + Assertion* as = entry->mAssertions; + while (as) { + Assertion* doomed = as; + as = as->mNext; + + // Unlink, and release the datasource's reference. + doomed->mNext = doomed->u.as.mInvNext = nullptr; + doomed->Release(); + } + } + delete u.hash.mPropertyHash; + u.hash.mPropertyHash = nullptr; + } + + MOZ_COUNT_DTOR(Assertion); +#ifdef DEBUG_REFS + --gInstanceCount; + fprintf(stdout, "%d - RDF: Assertion\n", gInstanceCount); +#endif + + NS_RELEASE(mSource); + if (!mHashEntry) + { + NS_RELEASE(u.as.mProperty); + NS_RELEASE(u.as.mTarget); + } +} + +//////////////////////////////////////////////////////////////////////// +// InMemoryDataSource +class InMemoryArcsEnumeratorImpl; +class InMemoryAssertionEnumeratorImpl; +class InMemoryResourceEnumeratorImpl; + +class InMemoryDataSource : public nsIRDFDataSource, + public nsIRDFInMemoryDataSource, + public nsIRDFPropagatableDataSource, + public nsIRDFPurgeableDataSource, + public rdfIDataSource +{ +protected: + // These hash tables are keyed on pointers to nsIRDFResource + // objects (the nsIRDFService ensures that there is only ever one + // nsIRDFResource object per unique URI). The value of an entry is + // an Assertion struct, which is a linked list of (subject + // predicate object) triples. + PLDHashTable mForwardArcs; + PLDHashTable mReverseArcs; + + nsCOMArray mObservers; + uint32_t mNumObservers; + + // VisitFoo needs to block writes, [Un]Assert only allowed + // during mReadCount == 0 + uint32_t mReadCount; + + friend class InMemoryArcsEnumeratorImpl; + friend class InMemoryAssertionEnumeratorImpl; + friend class InMemoryResourceEnumeratorImpl; // b/c it needs to enumerate mForwardArcs + + // Thread-safe writer implementation methods. + nsresult + LockedAssert(nsIRDFResource* source, + nsIRDFResource* property, + nsIRDFNode* target, + bool tv); + + nsresult + LockedUnassert(nsIRDFResource* source, + nsIRDFResource* property, + nsIRDFNode* target); + + explicit InMemoryDataSource(nsISupports* aOuter); + virtual ~InMemoryDataSource(); + + friend nsresult + NS_NewRDFInMemoryDataSource(nsISupports* aOuter, const nsIID& aIID, void** aResult); + +public: + NS_DECL_CYCLE_COLLECTING_AGGREGATED + NS_DECL_AGGREGATED_CYCLE_COLLECTION_CLASS(InMemoryDataSource) + + // nsIRDFDataSource methods + NS_DECL_NSIRDFDATASOURCE + + // nsIRDFInMemoryDataSource methods + NS_DECL_NSIRDFINMEMORYDATASOURCE + + // nsIRDFPropagatableDataSource methods + NS_DECL_NSIRDFPROPAGATABLEDATASOURCE + + // nsIRDFPurgeableDataSource methods + NS_DECL_NSIRDFPURGEABLEDATASOURCE + + // rdfIDataSource methods + NS_DECL_RDFIDATASOURCE + +protected: + struct SweepInfo { + Assertion* mUnassertList; + PLDHashTable* mReverseArcs; + }; + + static void + SweepForwardArcsEntries(PLDHashTable* aTable, SweepInfo* aArg); + +public: + // Implementation methods + Assertion* + GetForwardArcs(nsIRDFResource* u) { + PLDHashEntryHdr* hdr = mForwardArcs.Search(u); + return hdr ? static_cast(hdr)->mAssertions : nullptr; + } + + Assertion* + GetReverseArcs(nsIRDFNode* v) { + PLDHashEntryHdr* hdr = mReverseArcs.Search(v); + return hdr ? static_cast(hdr)->mAssertions : nullptr; + } + + void + SetForwardArcs(nsIRDFResource* u, Assertion* as) { + if (as) { + auto entry = + static_cast(mForwardArcs.Add(u, mozilla::fallible)); + if (entry) { + entry->mNode = u; + entry->mAssertions = as; + } + } + else { + mForwardArcs.Remove(u); + } + } + + void + SetReverseArcs(nsIRDFNode* v, Assertion* as) { + if (as) { + auto entry = + static_cast(mReverseArcs.Add(v, mozilla::fallible)); + if (entry) { + entry->mNode = v; + entry->mAssertions = as; + } + } + else { + mReverseArcs.Remove(v); + } + } + + void + LogOperation(const char* aOperation, + nsIRDFResource* asource, + nsIRDFResource* aProperty, + nsIRDFNode* aTarget, + bool aTruthValue = true); + + bool mPropagateChanges; + +private: + static mozilla::LazyLogModule gLog; +}; + +mozilla::LazyLogModule InMemoryDataSource::gLog("InMemoryDataSource"); + +//---------------------------------------------------------------------- +// +// InMemoryAssertionEnumeratorImpl +// + +/** + * InMemoryAssertionEnumeratorImpl + */ +class InMemoryAssertionEnumeratorImpl : public nsISimpleEnumerator +{ +private: + InMemoryDataSource* mDataSource; + nsIRDFResource* mSource; + nsIRDFResource* mProperty; + nsIRDFNode* mTarget; + nsIRDFNode* mValue; + bool mTruthValue; + Assertion* mNextAssertion; + + virtual ~InMemoryAssertionEnumeratorImpl(); + +public: + InMemoryAssertionEnumeratorImpl(InMemoryDataSource* aDataSource, + nsIRDFResource* aSource, + nsIRDFResource* aProperty, + nsIRDFNode* aTarget, + bool aTruthValue); + + // nsISupports interface + NS_DECL_ISUPPORTS + + // nsISimpleEnumerator interface + NS_DECL_NSISIMPLEENUMERATOR +}; + +//////////////////////////////////////////////////////////////////////// + + +InMemoryAssertionEnumeratorImpl::InMemoryAssertionEnumeratorImpl( + InMemoryDataSource* aDataSource, + nsIRDFResource* aSource, + nsIRDFResource* aProperty, + nsIRDFNode* aTarget, + bool aTruthValue) + : mDataSource(aDataSource), + mSource(aSource), + mProperty(aProperty), + mTarget(aTarget), + mValue(nullptr), + mTruthValue(aTruthValue), + mNextAssertion(nullptr) +{ + NS_ADDREF(mDataSource); + NS_IF_ADDREF(mSource); + NS_ADDREF(mProperty); + NS_IF_ADDREF(mTarget); + + if (mSource) { + mNextAssertion = mDataSource->GetForwardArcs(mSource); + + if (mNextAssertion && mNextAssertion->mHashEntry) { + // its our magical HASH_ENTRY forward hash for assertions + PLDHashEntryHdr* hdr = + mNextAssertion->u.hash.mPropertyHash->Search(aProperty); + mNextAssertion = + hdr ? static_cast(hdr)->mAssertions : nullptr; + } + } + else { + mNextAssertion = mDataSource->GetReverseArcs(mTarget); + } + + // Add an owning reference from the enumerator + if (mNextAssertion) + mNextAssertion->AddRef(); +} + +InMemoryAssertionEnumeratorImpl::~InMemoryAssertionEnumeratorImpl() +{ +#ifdef DEBUG_REFS + --gInstanceCount; + fprintf(stdout, "%d - RDF: InMemoryAssertionEnumeratorImpl\n", gInstanceCount); +#endif + + if (mNextAssertion) + mNextAssertion->Release(); + + NS_IF_RELEASE(mDataSource); + NS_IF_RELEASE(mSource); + NS_IF_RELEASE(mProperty); + NS_IF_RELEASE(mTarget); + NS_IF_RELEASE(mValue); +} + +NS_IMPL_ADDREF(InMemoryAssertionEnumeratorImpl) +NS_IMPL_RELEASE(InMemoryAssertionEnumeratorImpl) +NS_IMPL_QUERY_INTERFACE(InMemoryAssertionEnumeratorImpl, nsISimpleEnumerator) + +NS_IMETHODIMP +InMemoryAssertionEnumeratorImpl::HasMoreElements(bool* aResult) +{ + if (mValue) { + *aResult = true; + return NS_OK; + } + + while (mNextAssertion) { + bool foundIt = false; + if ((mProperty == mNextAssertion->u.as.mProperty) && + (mTruthValue == mNextAssertion->u.as.mTruthValue)) { + if (mSource) { + mValue = mNextAssertion->u.as.mTarget; + NS_ADDREF(mValue); + } + else { + mValue = mNextAssertion->mSource; + NS_ADDREF(mValue); + } + foundIt = true; + } + + // Remember the last assertion we were holding on to + Assertion* as = mNextAssertion; + + // iterate + mNextAssertion = (mSource) ? mNextAssertion->mNext : mNextAssertion->u.as.mInvNext; + + // grab an owning reference from the enumerator to the next assertion + if (mNextAssertion) + mNextAssertion->AddRef(); + + // ...and release the reference from the enumerator to the old one. + as->Release(); + + if (foundIt) { + *aResult = true; + return NS_OK; + } + } + + *aResult = false; + return NS_OK; +} + + +NS_IMETHODIMP +InMemoryAssertionEnumeratorImpl::GetNext(nsISupports** aResult) +{ + nsresult rv; + + bool hasMore; + rv = HasMoreElements(&hasMore); + if (NS_FAILED(rv)) return rv; + + if (! hasMore) + return NS_ERROR_UNEXPECTED; + + // Don't AddRef: we "transfer" ownership to the caller + *aResult = mValue; + mValue = nullptr; + + return NS_OK; +} + +//////////////////////////////////////////////////////////////////////// +// + +/** + * This class is a little bit bizarre in that it implements both the + * nsIRDFArcsOutCursor and nsIRDFArcsInCursor interfaces. + * Because the structure of the in-memory graph is pretty flexible, it's + * fairly easy to parameterize this class. The only funky thing to watch + * out for is the multiple inheritance clashes. + */ + +class InMemoryArcsEnumeratorImpl : public nsISimpleEnumerator +{ +private: + InMemoryDataSource* mDataSource; + nsIRDFResource* mSource; + nsIRDFNode* mTarget; + AutoTArray, 8> mAlreadyReturned; + nsIRDFResource* mCurrent; + Assertion* mAssertion; + nsCOMArray* mHashArcs; + + virtual ~InMemoryArcsEnumeratorImpl(); + +public: + InMemoryArcsEnumeratorImpl(InMemoryDataSource* aDataSource, + nsIRDFResource* aSource, + nsIRDFNode* aTarget); + + // nsISupports interface + NS_DECL_ISUPPORTS + + // nsISimpleEnumerator interface + NS_DECL_NSISIMPLEENUMERATOR +}; + + +InMemoryArcsEnumeratorImpl::InMemoryArcsEnumeratorImpl(InMemoryDataSource* aDataSource, + nsIRDFResource* aSource, + nsIRDFNode* aTarget) + : mDataSource(aDataSource), + mSource(aSource), + mTarget(aTarget), + mCurrent(nullptr), + mHashArcs(nullptr) +{ + NS_ADDREF(mDataSource); + NS_IF_ADDREF(mSource); + NS_IF_ADDREF(mTarget); + + if (mSource) { + // cast okay because it's a closed system + mAssertion = mDataSource->GetForwardArcs(mSource); + + if (mAssertion && mAssertion->mHashEntry) { + // its our magical HASH_ENTRY forward hash for assertions + mHashArcs = new nsCOMArray(); + for (auto i = mAssertion->u.hash.mPropertyHash->Iter(); + !i.Done(); + i.Next()) { + auto entry = static_cast(i.Get()); + mHashArcs->AppendElement(entry->mNode); + } + mAssertion = nullptr; + } + } + else { + mAssertion = mDataSource->GetReverseArcs(mTarget); + } +} + +InMemoryArcsEnumeratorImpl::~InMemoryArcsEnumeratorImpl() +{ +#ifdef DEBUG_REFS + --gInstanceCount; + fprintf(stdout, "%d - RDF: InMemoryArcsEnumeratorImpl\n", gInstanceCount); +#endif + + NS_RELEASE(mDataSource); + NS_IF_RELEASE(mSource); + NS_IF_RELEASE(mTarget); + NS_IF_RELEASE(mCurrent); + delete mHashArcs; +} + +NS_IMPL_ADDREF(InMemoryArcsEnumeratorImpl) +NS_IMPL_RELEASE(InMemoryArcsEnumeratorImpl) +NS_IMPL_QUERY_INTERFACE(InMemoryArcsEnumeratorImpl, nsISimpleEnumerator) + +NS_IMETHODIMP +InMemoryArcsEnumeratorImpl::HasMoreElements(bool* aResult) +{ + NS_PRECONDITION(aResult != nullptr, "null ptr"); + if (! aResult) + return NS_ERROR_NULL_POINTER; + + if (mCurrent) { + *aResult = true; + return NS_OK; + } + + if (mHashArcs) { + if (!mHashArcs->IsEmpty()) { + const uint32_t last = mHashArcs->Length() - 1; + nsCOMPtr tmp(do_QueryInterface(mHashArcs->ObjectAt(last))); + tmp.forget(&mCurrent); + mHashArcs->RemoveElementAt(last); + *aResult = true; + return NS_OK; + } + } + else + while (mAssertion) { + nsIRDFResource* next = mAssertion->u.as.mProperty; + + // "next" is the property arc we are tentatively going to return + // in a subsequent GetNext() call. It is important to do two + // things, however, before that can happen: + // 1) Make sure it's not an arc we've already returned. + // 2) Make sure that |mAssertion| is not left pointing to + // another assertion that has the same property as this one. + // The first is a practical concern; the second a defense against + // an obscure crash and other erratic behavior. To ensure the + // second condition, skip down the chain until we find the next + // assertion with a property that doesn't match the current one. + // (All these assertions would be skipped via mAlreadyReturned + // checks anyways; this is even a bit faster.) + + do { + mAssertion = (mSource ? mAssertion->mNext : + mAssertion->u.as.mInvNext); + } + while (mAssertion && (next == mAssertion->u.as.mProperty)); + + bool alreadyReturned = false; + for (int32_t i = mAlreadyReturned.Length() - 1; i >= 0; --i) { + if (mAlreadyReturned[i] == next) { + alreadyReturned = true; + break; + } + } + + if (! alreadyReturned) { + mCurrent = next; + NS_ADDREF(mCurrent); + *aResult = true; + return NS_OK; + } + } + + *aResult = false; + return NS_OK; +} + + +NS_IMETHODIMP +InMemoryArcsEnumeratorImpl::GetNext(nsISupports** aResult) +{ + nsresult rv; + + bool hasMore; + rv = HasMoreElements(&hasMore); + if (NS_FAILED(rv)) return rv; + + if (! hasMore) + return NS_ERROR_UNEXPECTED; + + // Add this to the set of things we've already returned so that we + // can ensure uniqueness + mAlreadyReturned.AppendElement(mCurrent); + + // Don't AddRef: we "transfer" ownership to the caller + *aResult = mCurrent; + mCurrent = nullptr; + + return NS_OK; +} + + +//////////////////////////////////////////////////////////////////////// +// InMemoryDataSource + +nsresult +NS_NewRDFInMemoryDataSource(nsISupports* aOuter, const nsIID& aIID, void** aResult) +{ + NS_PRECONDITION(aResult != nullptr, "null ptr"); + if (! aResult) + return NS_ERROR_NULL_POINTER; + *aResult = nullptr; + + if (aOuter && !aIID.Equals(NS_GET_IID(nsISupports))) { + NS_ERROR("aggregation requires nsISupports"); + return NS_ERROR_ILLEGAL_VALUE; + } + + InMemoryDataSource* datasource = new InMemoryDataSource(aOuter); + NS_ADDREF(datasource); + + datasource->fAggregated.AddRef(); + nsresult rv = datasource->AggregatedQueryInterface(aIID, aResult); // This'll AddRef() + datasource->fAggregated.Release(); + + NS_RELEASE(datasource); + return rv; +} + + +InMemoryDataSource::InMemoryDataSource(nsISupports* aOuter) + : mForwardArcs(PLDHashTable::StubOps(), sizeof(Entry)) + , mReverseArcs(PLDHashTable::StubOps(), sizeof(Entry)) + , mNumObservers(0) + , mReadCount(0) +{ + NS_INIT_AGGREGATED(aOuter); + + mPropagateChanges = true; +} + + +InMemoryDataSource::~InMemoryDataSource() +{ +#ifdef DEBUG_REFS + --gInstanceCount; + fprintf(stdout, "%d - RDF: InMemoryDataSource\n", gInstanceCount); +#endif + + if (mForwardArcs.EntryCount() > 0) { + // This'll release all of the Assertion objects that are + // associated with this data source. We only need to do this + // for the forward arcs, because the reverse arcs table + // indexes the exact same set of resources. + for (auto iter = mForwardArcs.Iter(); !iter.Done(); iter.Next()) { + auto entry = static_cast(iter.Get()); + Assertion* as = entry->mAssertions; + while (as) { + Assertion* doomed = as; + as = as->mNext; + + // Unlink, and release the datasource's reference. + doomed->mNext = doomed->u.as.mInvNext = nullptr; + doomed->Release(); + } + } + } + + MOZ_LOG(gLog, LogLevel::Debug, + ("InMemoryDataSource(%p): destroyed.", this)); +} + + +//////////////////////////////////////////////////////////////////////// + +NS_IMPL_CYCLE_COLLECTION_CLASS(InMemoryDataSource) + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(InMemoryDataSource) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mObservers) +NS_IMPL_CYCLE_COLLECTION_UNLINK_END +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_AGGREGATED(InMemoryDataSource) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mObservers) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + +NS_IMPL_CYCLE_COLLECTING_AGGREGATED(InMemoryDataSource) +NS_INTERFACE_MAP_BEGIN_AGGREGATED(InMemoryDataSource) + NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION_AGGREGATED(InMemoryDataSource) + NS_INTERFACE_MAP_ENTRY(nsIRDFDataSource) + NS_INTERFACE_MAP_ENTRY(nsIRDFInMemoryDataSource) + NS_INTERFACE_MAP_ENTRY(nsIRDFPropagatableDataSource) + NS_INTERFACE_MAP_ENTRY(nsIRDFPurgeableDataSource) + NS_INTERFACE_MAP_ENTRY(rdfIDataSource) +NS_INTERFACE_MAP_END + +//////////////////////////////////////////////////////////////////////// + + +void +InMemoryDataSource::LogOperation(const char* aOperation, + nsIRDFResource* aSource, + nsIRDFResource* aProperty, + nsIRDFNode* aTarget, + bool aTruthValue) +{ + if (! MOZ_LOG_TEST(gLog, LogLevel::Debug)) + return; + + nsCString uri; + aSource->GetValue(getter_Copies(uri)); + MOZ_LOG(gLog, LogLevel::Debug, + ("InMemoryDataSource(%p): %s", this, aOperation)); + + MOZ_LOG(gLog, LogLevel::Debug, + (" [(%p)%s]--", aSource, uri.get())); + + aProperty->GetValue(getter_Copies(uri)); + + char tv = (aTruthValue ? '-' : '!'); + MOZ_LOG(gLog, LogLevel::Debug, + (" --%c[(%p)%s]--", tv, aProperty, uri.get())); + + nsCOMPtr resource; + nsCOMPtr literal; + + if ((resource = do_QueryInterface(aTarget)) != nullptr) { + resource->GetValue(getter_Copies(uri)); + MOZ_LOG(gLog, LogLevel::Debug, + (" -->[(%p)%s]", aTarget, uri.get())); + } + else if ((literal = do_QueryInterface(aTarget)) != nullptr) { + nsString value; + literal->GetValue(getter_Copies(value)); + MOZ_LOG(gLog, LogLevel::Debug, + (" -->(\"%s\")\n", NS_ConvertUTF16toUTF8(value).get())); + } + else { + MOZ_LOG(gLog, LogLevel::Debug, + (" -->(unknown-type)\n")); + } +} + + +NS_IMETHODIMP +InMemoryDataSource::GetURI(nsACString& aURI) +{ + aURI.SetIsVoid(true); + return NS_OK; +} + +NS_IMETHODIMP +InMemoryDataSource::GetSource(nsIRDFResource* property, + nsIRDFNode* target, + bool tv, + nsIRDFResource** source) +{ + NS_PRECONDITION(source != nullptr, "null ptr"); + if (! source) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(property != nullptr, "null ptr"); + if (! property) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(target != nullptr, "null ptr"); + if (! target) + return NS_ERROR_NULL_POINTER; + + for (Assertion* as = GetReverseArcs(target); as; as = as->u.as.mInvNext) { + if ((property == as->u.as.mProperty) && (tv == as->u.as.mTruthValue)) { + *source = as->mSource; + NS_ADDREF(*source); + return NS_OK; + } + } + *source = nullptr; + return NS_RDF_NO_VALUE; +} + +NS_IMETHODIMP +InMemoryDataSource::GetTarget(nsIRDFResource* source, + nsIRDFResource* property, + bool tv, + nsIRDFNode** target) +{ + NS_PRECONDITION(source != nullptr, "null ptr"); + if (! source) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(property != nullptr, "null ptr"); + if (! property) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(target != nullptr, "null ptr"); + if (! target) + return NS_ERROR_NULL_POINTER; + + Assertion *as = GetForwardArcs(source); + if (as && as->mHashEntry) { + PLDHashEntryHdr* hdr = as->u.hash.mPropertyHash->Search(property); + Assertion* val = hdr ? static_cast(hdr)->mAssertions : nullptr; + while (val) { + if (tv == val->u.as.mTruthValue) { + *target = val->u.as.mTarget; + NS_IF_ADDREF(*target); + return NS_OK; + } + val = val->mNext; + } + } + else + for (; as != nullptr; as = as->mNext) { + if ((property == as->u.as.mProperty) && (tv == (as->u.as.mTruthValue))) { + *target = as->u.as.mTarget; + NS_ADDREF(*target); + return NS_OK; + } + } + + // If we get here, then there was no target with for the specified + // property & truth value. + *target = nullptr; + return NS_RDF_NO_VALUE; +} + +NS_IMETHODIMP +InMemoryDataSource::HasAssertion(nsIRDFResource* source, + nsIRDFResource* property, + nsIRDFNode* target, + bool tv, + bool* hasAssertion) +{ + if (! source) + return NS_ERROR_NULL_POINTER; + + if (! property) + return NS_ERROR_NULL_POINTER; + + if (! target) + return NS_ERROR_NULL_POINTER; + + Assertion *as = GetForwardArcs(source); + if (as && as->mHashEntry) { + PLDHashEntryHdr* hdr = as->u.hash.mPropertyHash->Search(property); + Assertion* val = hdr ? static_cast(hdr)->mAssertions : nullptr; + while (val) { + if ((val->u.as.mTarget == target) && (tv == (val->u.as.mTruthValue))) { + *hasAssertion = true; + return NS_OK; + } + val = val->mNext; + } + } + else + for (; as != nullptr; as = as->mNext) { + // check target first as its most unique + if (target != as->u.as.mTarget) + continue; + + if (property != as->u.as.mProperty) + continue; + + if (tv != (as->u.as.mTruthValue)) + continue; + + // found it! + *hasAssertion = true; + return NS_OK; + } + + // If we get here, we couldn't find the assertion + *hasAssertion = false; + return NS_OK; +} + +NS_IMETHODIMP +InMemoryDataSource::GetSources(nsIRDFResource* aProperty, + nsIRDFNode* aTarget, + bool aTruthValue, + nsISimpleEnumerator** aResult) +{ + NS_PRECONDITION(aProperty != nullptr, "null ptr"); + if (! aProperty) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(aTarget != nullptr, "null ptr"); + if (! aTarget) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(aResult != nullptr, "null ptr"); + if (! aResult) + return NS_ERROR_NULL_POINTER; + + InMemoryAssertionEnumeratorImpl* result = + new InMemoryAssertionEnumeratorImpl(this, nullptr, aProperty, + aTarget, aTruthValue); + + if (! result) + return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(result); + *aResult = result; + + return NS_OK; +} + +NS_IMETHODIMP +InMemoryDataSource::GetTargets(nsIRDFResource* aSource, + nsIRDFResource* aProperty, + bool aTruthValue, + nsISimpleEnumerator** aResult) +{ + NS_PRECONDITION(aSource != nullptr, "null ptr"); + if (! aSource) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(aProperty != nullptr, "null ptr"); + if (! aProperty) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(aResult != nullptr, "null ptr"); + if (! aResult) + return NS_ERROR_NULL_POINTER; + + InMemoryAssertionEnumeratorImpl* result = + new InMemoryAssertionEnumeratorImpl(this, aSource, aProperty, + nullptr, aTruthValue); + + if (! result) + return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(result); + *aResult = result; + + return NS_OK; +} + + +nsresult +InMemoryDataSource::LockedAssert(nsIRDFResource* aSource, + nsIRDFResource* aProperty, + nsIRDFNode* aTarget, + bool aTruthValue) +{ + LogOperation("ASSERT", aSource, aProperty, aTarget, aTruthValue); + + Assertion* next = GetForwardArcs(aSource); + Assertion* prev = next; + Assertion* as = nullptr; + + bool haveHash = (next) ? next->mHashEntry : false; + if (haveHash) { + PLDHashEntryHdr* hdr = next->u.hash.mPropertyHash->Search(aProperty); + Assertion* val = hdr ? static_cast(hdr)->mAssertions : nullptr; + while (val) { + if (val->u.as.mTarget == aTarget) { + // Wow, we already had the assertion. Make sure that the + // truth values are correct and bail. + val->u.as.mTruthValue = aTruthValue; + return NS_OK; + } + val = val->mNext; + } + } + else + { + while (next) { + // check target first as its most unique + if (aTarget == next->u.as.mTarget) { + if (aProperty == next->u.as.mProperty) { + // Wow, we already had the assertion. Make sure that the + // truth values are correct and bail. + next->u.as.mTruthValue = aTruthValue; + return NS_OK; + } + } + + prev = next; + next = next->mNext; + } + } + + as = new Assertion(aSource, aProperty, aTarget, aTruthValue); + if (! as) + return NS_ERROR_OUT_OF_MEMORY; + + // Add the datasource's owning reference. + as->AddRef(); + + if (haveHash) + { + PLDHashEntryHdr* hdr = next->u.hash.mPropertyHash->Search(aProperty); + Assertion *asRef = + hdr ? static_cast(hdr)->mAssertions : nullptr; + if (asRef) + { + as->mNext = asRef->mNext; + asRef->mNext = as; + } + else + { + hdr = next->u.hash.mPropertyHash->Add(aProperty, mozilla::fallible); + if (hdr) + { + Entry* entry = static_cast(hdr); + entry->mNode = aProperty; + entry->mAssertions = as; + } + } + } + else + { + // Link it in to the "forward arcs" table + if (!prev) { + SetForwardArcs(aSource, as); + } else { + prev->mNext = as; + } + } + + // Link it in to the "reverse arcs" table + + next = GetReverseArcs(aTarget); + as->u.as.mInvNext = next; + next = as; + SetReverseArcs(aTarget, next); + + return NS_OK; +} + +NS_IMETHODIMP +InMemoryDataSource::Assert(nsIRDFResource* aSource, + nsIRDFResource* aProperty, + nsIRDFNode* aTarget, + bool aTruthValue) +{ + NS_PRECONDITION(aSource != nullptr, "null ptr"); + if (! aSource) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(aProperty != nullptr, "null ptr"); + if (! aProperty) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(aTarget != nullptr, "null ptr"); + if (! aTarget) + return NS_ERROR_NULL_POINTER; + + if (mReadCount) { + NS_WARNING("Writing to InMemoryDataSource during read\n"); + return NS_RDF_ASSERTION_REJECTED; + } + + nsresult rv; + rv = LockedAssert(aSource, aProperty, aTarget, aTruthValue); + if (NS_FAILED(rv)) return rv; + + // notify observers + for (int32_t i = (int32_t)mNumObservers - 1; mPropagateChanges && i >= 0; --i) { + nsIRDFObserver* obs = mObservers[i]; + + // XXX this should never happen, but it does, and we can't figure out why. + NS_ASSERTION(obs, "observer array corrupted!"); + if (! obs) + continue; + + obs->OnAssert(this, aSource, aProperty, aTarget); + // XXX ignore return value? + } + + return NS_RDF_ASSERTION_ACCEPTED; +} + + +nsresult +InMemoryDataSource::LockedUnassert(nsIRDFResource* aSource, + nsIRDFResource* aProperty, + nsIRDFNode* aTarget) +{ + LogOperation("UNASSERT", aSource, aProperty, aTarget); + + Assertion* next = GetForwardArcs(aSource); + Assertion* prev = next; + Assertion* root = next; + Assertion* as = nullptr; + + bool haveHash = (next) ? next->mHashEntry : false; + if (haveHash) { + PLDHashEntryHdr* hdr = next->u.hash.mPropertyHash->Search(aProperty); + prev = next = hdr ? static_cast(hdr)->mAssertions : nullptr; + bool first = true; + while (next) { + if (aTarget == next->u.as.mTarget) { + break; + } + first = false; + prev = next; + next = next->mNext; + } + // We don't even have the assertion, so just bail. + if (!next) + return NS_OK; + + as = next; + + if (first) { + root->u.hash.mPropertyHash->RawRemove(hdr); + + if (next && next->mNext) { + PLDHashEntryHdr* hdr = + root->u.hash.mPropertyHash->Add(aProperty, + mozilla::fallible); + if (hdr) { + Entry* entry = static_cast(hdr); + entry->mNode = aProperty; + entry->mAssertions = next->mNext; + } + } + else { + // If this second-level hash empties out, clean it up. + if (!root->u.hash.mPropertyHash->EntryCount()) { + root->Release(); + SetForwardArcs(aSource, nullptr); + } + } + } + else { + prev->mNext = next->mNext; + } + } + else + { + while (next) { + // check target first as its most unique + if (aTarget == next->u.as.mTarget) { + if (aProperty == next->u.as.mProperty) { + if (prev == next) { + SetForwardArcs(aSource, next->mNext); + } else { + prev->mNext = next->mNext; + } + as = next; + break; + } + } + + prev = next; + next = next->mNext; + } + } + // We don't even have the assertion, so just bail. + if (!as) + return NS_OK; + +#ifdef DEBUG + bool foundReverseArc = false; +#endif + + next = prev = GetReverseArcs(aTarget); + while (next) { + if (next == as) { + if (prev == next) { + SetReverseArcs(aTarget, next->u.as.mInvNext); + } else { + prev->u.as.mInvNext = next->u.as.mInvNext; + } +#ifdef DEBUG + foundReverseArc = true; +#endif + break; + } + prev = next; + next = next->u.as.mInvNext; + } + +#ifdef DEBUG + NS_ASSERTION(foundReverseArc, "in-memory db corrupted: unable to find reverse arc"); +#endif + + // Unlink, and release the datasource's reference + as->mNext = as->u.as.mInvNext = nullptr; + as->Release(); + + return NS_OK; +} + +NS_IMETHODIMP +InMemoryDataSource::Unassert(nsIRDFResource* aSource, + nsIRDFResource* aProperty, + nsIRDFNode* aTarget) +{ + NS_PRECONDITION(aSource != nullptr, "null ptr"); + if (! aSource) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(aProperty != nullptr, "null ptr"); + if (! aProperty) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(aTarget != nullptr, "null ptr"); + if (! aTarget) + return NS_ERROR_NULL_POINTER; + + if (mReadCount) { + NS_WARNING("Writing to InMemoryDataSource during read\n"); + return NS_RDF_ASSERTION_REJECTED; + } + + nsresult rv; + + rv = LockedUnassert(aSource, aProperty, aTarget); + if (NS_FAILED(rv)) return rv; + + // Notify the world + for (int32_t i = int32_t(mNumObservers) - 1; mPropagateChanges && i >= 0; --i) { + nsIRDFObserver* obs = mObservers[i]; + + // XXX this should never happen, but it does, and we can't figure out why. + NS_ASSERTION(obs, "observer array corrupted!"); + if (! obs) + continue; + + obs->OnUnassert(this, aSource, aProperty, aTarget); + // XXX ignore return value? + } + + return NS_RDF_ASSERTION_ACCEPTED; +} + + +NS_IMETHODIMP +InMemoryDataSource::Change(nsIRDFResource* aSource, + nsIRDFResource* aProperty, + nsIRDFNode* aOldTarget, + nsIRDFNode* aNewTarget) +{ + NS_PRECONDITION(aSource != nullptr, "null ptr"); + if (! aSource) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(aProperty != nullptr, "null ptr"); + if (! aProperty) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(aOldTarget != nullptr, "null ptr"); + if (! aOldTarget) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(aNewTarget != nullptr, "null ptr"); + if (! aNewTarget) + return NS_ERROR_NULL_POINTER; + + if (mReadCount) { + NS_WARNING("Writing to InMemoryDataSource during read\n"); + return NS_RDF_ASSERTION_REJECTED; + } + + nsresult rv; + + // XXX We can implement LockedChange() if we decide that this + // is a performance bottleneck. + + rv = LockedUnassert(aSource, aProperty, aOldTarget); + if (NS_FAILED(rv)) return rv; + + rv = LockedAssert(aSource, aProperty, aNewTarget, true); + if (NS_FAILED(rv)) return rv; + + // Notify the world + for (int32_t i = int32_t(mNumObservers) - 1; mPropagateChanges && i >= 0; --i) { + nsIRDFObserver* obs = mObservers[i]; + + // XXX this should never happen, but it does, and we can't figure out why. + NS_ASSERTION(obs, "observer array corrupted!"); + if (! obs) + continue; + + obs->OnChange(this, aSource, aProperty, aOldTarget, aNewTarget); + // XXX ignore return value? + } + + return NS_RDF_ASSERTION_ACCEPTED; +} + + +NS_IMETHODIMP +InMemoryDataSource::Move(nsIRDFResource* aOldSource, + nsIRDFResource* aNewSource, + nsIRDFResource* aProperty, + nsIRDFNode* aTarget) +{ + NS_PRECONDITION(aOldSource != nullptr, "null ptr"); + if (! aOldSource) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(aNewSource != nullptr, "null ptr"); + if (! aNewSource) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(aProperty != nullptr, "null ptr"); + if (! aProperty) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(aTarget != nullptr, "null ptr"); + if (! aTarget) + return NS_ERROR_NULL_POINTER; + + if (mReadCount) { + NS_WARNING("Writing to InMemoryDataSource during read\n"); + return NS_RDF_ASSERTION_REJECTED; + } + + nsresult rv; + + // XXX We can implement LockedMove() if we decide that this + // is a performance bottleneck. + + rv = LockedUnassert(aOldSource, aProperty, aTarget); + if (NS_FAILED(rv)) return rv; + + rv = LockedAssert(aNewSource, aProperty, aTarget, true); + if (NS_FAILED(rv)) return rv; + + // Notify the world + for (int32_t i = int32_t(mNumObservers) - 1; mPropagateChanges && i >= 0; --i) { + nsIRDFObserver* obs = mObservers[i]; + + // XXX this should never happen, but it does, and we can't figure out why. + NS_ASSERTION(obs, "observer array corrupted!"); + if (! obs) + continue; + + obs->OnMove(this, aOldSource, aNewSource, aProperty, aTarget); + // XXX ignore return value? + } + + return NS_RDF_ASSERTION_ACCEPTED; +} + + +NS_IMETHODIMP +InMemoryDataSource::AddObserver(nsIRDFObserver* aObserver) +{ + NS_PRECONDITION(aObserver != nullptr, "null ptr"); + if (! aObserver) + return NS_ERROR_NULL_POINTER; + + mObservers.AppendObject(aObserver); + mNumObservers = mObservers.Count(); + + return NS_OK; +} + +NS_IMETHODIMP +InMemoryDataSource::RemoveObserver(nsIRDFObserver* aObserver) +{ + NS_PRECONDITION(aObserver != nullptr, "null ptr"); + if (! aObserver) + return NS_ERROR_NULL_POINTER; + + mObservers.RemoveObject(aObserver); + // note: use Count() instead of just decrementing + // in case aObserver wasn't in list, for example + mNumObservers = mObservers.Count(); + + return NS_OK; +} + +NS_IMETHODIMP +InMemoryDataSource::HasArcIn(nsIRDFNode *aNode, nsIRDFResource *aArc, bool *result) +{ + Assertion* ass = GetReverseArcs(aNode); + while (ass) { + nsIRDFResource* elbow = ass->u.as.mProperty; + if (elbow == aArc) { + *result = true; + return NS_OK; + } + ass = ass->u.as.mInvNext; + } + *result = false; + return NS_OK; +} + +NS_IMETHODIMP +InMemoryDataSource::HasArcOut(nsIRDFResource *aSource, nsIRDFResource *aArc, bool *result) +{ + Assertion* ass = GetForwardArcs(aSource); + if (ass && ass->mHashEntry) { + PLDHashEntryHdr* hdr = ass->u.hash.mPropertyHash->Search(aArc); + Assertion* val = hdr ? static_cast(hdr)->mAssertions : nullptr; + if (val) { + *result = true; + return NS_OK; + } + ass = ass->mNext; + } + while (ass) { + nsIRDFResource* elbow = ass->u.as.mProperty; + if (elbow == aArc) { + *result = true; + return NS_OK; + } + ass = ass->mNext; + } + *result = false; + return NS_OK; +} + +NS_IMETHODIMP +InMemoryDataSource::ArcLabelsIn(nsIRDFNode* aTarget, nsISimpleEnumerator** aResult) +{ + NS_PRECONDITION(aTarget != nullptr, "null ptr"); + if (! aTarget) + return NS_ERROR_NULL_POINTER; + + InMemoryArcsEnumeratorImpl* result = + new InMemoryArcsEnumeratorImpl(this, nullptr, aTarget); + + if (! result) + return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(result); + *aResult = result; + + return NS_OK; +} + +NS_IMETHODIMP +InMemoryDataSource::ArcLabelsOut(nsIRDFResource* aSource, nsISimpleEnumerator** aResult) +{ + NS_PRECONDITION(aSource != nullptr, "null ptr"); + if (! aSource) + return NS_ERROR_NULL_POINTER; + + InMemoryArcsEnumeratorImpl* result = + new InMemoryArcsEnumeratorImpl(this, aSource, nullptr); + + if (! result) + return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(result); + *aResult = result; + + return NS_OK; +} + + +NS_IMETHODIMP +InMemoryDataSource::GetAllResources(nsISimpleEnumerator** aResult) +{ + nsCOMArray nodes; + nodes.SetCapacity(mForwardArcs.EntryCount()); + + // Get all of our entries into an nsCOMArray + for (auto iter = mForwardArcs.Iter(); !iter.Done(); iter.Next()) { + auto entry = static_cast(iter.Get()); + nodes.AppendObject(entry->mNode); + } + return NS_NewArrayEnumerator(aResult, nodes); +} + +NS_IMETHODIMP +InMemoryDataSource::GetAllCmds(nsIRDFResource* source, + nsISimpleEnumerator/**/** commands) +{ + return(NS_NewEmptyEnumerator(commands)); +} + +NS_IMETHODIMP +InMemoryDataSource::IsCommandEnabled(nsISupports* aSources, + nsIRDFResource* aCommand, + nsISupports* aArguments, + bool* aResult) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +InMemoryDataSource::DoCommand(nsISupports* aSources, + nsIRDFResource* aCommand, + nsISupports* aArguments) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +InMemoryDataSource::BeginUpdateBatch() +{ + for (int32_t i = int32_t(mNumObservers) - 1; mPropagateChanges && i >= 0; --i) { + nsIRDFObserver* obs = mObservers[i]; + obs->OnBeginUpdateBatch(this); + } + return NS_OK; +} + +NS_IMETHODIMP +InMemoryDataSource::EndUpdateBatch() +{ + for (int32_t i = int32_t(mNumObservers) - 1; mPropagateChanges && i >= 0; --i) { + nsIRDFObserver* obs = mObservers[i]; + obs->OnEndUpdateBatch(this); + } + return NS_OK; +} + + + +//////////////////////////////////////////////////////////////////////// +// nsIRDFInMemoryDataSource methods + +NS_IMETHODIMP +InMemoryDataSource::EnsureFastContainment(nsIRDFResource* aSource) +{ + Assertion *as = GetForwardArcs(aSource); + bool haveHash = (as) ? as->mHashEntry : false; + + // if its already a hash, then nothing to do + if (haveHash) return(NS_OK); + + // convert aSource in forward hash into a hash + Assertion *hashAssertion = new Assertion(aSource); + NS_ASSERTION(hashAssertion, "unable to create Assertion"); + if (!hashAssertion) return(NS_ERROR_OUT_OF_MEMORY); + + // Add the datasource's owning reference. + hashAssertion->AddRef(); + + Assertion *first = GetForwardArcs(aSource); + SetForwardArcs(aSource, hashAssertion); + + // mutate references of existing forward assertions into this hash + PLDHashTable *table = hashAssertion->u.hash.mPropertyHash; + Assertion *nextRef; + while(first) { + nextRef = first->mNext; + nsIRDFResource *prop = first->u.as.mProperty; + + PLDHashEntryHdr* hdr = table->Search(prop); + Assertion* val = hdr ? static_cast(hdr)->mAssertions : nullptr; + if (val) { + first->mNext = val->mNext; + val->mNext = first; + } + else { + PLDHashEntryHdr* hdr = table->Add(prop, mozilla::fallible); + if (hdr) { + Entry* entry = static_cast(hdr); + entry->mNode = prop; + entry->mAssertions = first; + first->mNext = nullptr; + } + } + first = nextRef; + } + return(NS_OK); +} + + +//////////////////////////////////////////////////////////////////////// +// nsIRDFPropagatableDataSource methods +NS_IMETHODIMP +InMemoryDataSource::GetPropagateChanges(bool* aPropagateChanges) +{ + *aPropagateChanges = mPropagateChanges; + return NS_OK; +} + +NS_IMETHODIMP +InMemoryDataSource::SetPropagateChanges(bool aPropagateChanges) +{ + mPropagateChanges = aPropagateChanges; + return NS_OK; +} + + +//////////////////////////////////////////////////////////////////////// +// nsIRDFPurgeableDataSource methods + +NS_IMETHODIMP +InMemoryDataSource::Mark(nsIRDFResource* aSource, + nsIRDFResource* aProperty, + nsIRDFNode* aTarget, + bool aTruthValue, + bool* aDidMark) +{ + NS_PRECONDITION(aSource != nullptr, "null ptr"); + if (! aSource) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(aProperty != nullptr, "null ptr"); + if (! aProperty) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(aTarget != nullptr, "null ptr"); + if (! aTarget) + return NS_ERROR_NULL_POINTER; + + Assertion *as = GetForwardArcs(aSource); + if (as && as->mHashEntry) { + PLDHashEntryHdr* hdr = as->u.hash.mPropertyHash->Search(aProperty); + Assertion* val = hdr ? static_cast(hdr)->mAssertions : nullptr; + while (val) { + if ((val->u.as.mTarget == aTarget) && + (aTruthValue == (val->u.as.mTruthValue))) { + + // found it! so mark it. + as->Mark(); + *aDidMark = true; + + LogOperation("MARK", aSource, aProperty, aTarget, aTruthValue); + + return NS_OK; + } + val = val->mNext; + } + } + else for (; as != nullptr; as = as->mNext) { + // check target first as its most unique + if (aTarget != as->u.as.mTarget) + continue; + + if (aProperty != as->u.as.mProperty) + continue; + + if (aTruthValue != (as->u.as.mTruthValue)) + continue; + + // found it! so mark it. + as->Mark(); + *aDidMark = true; + + LogOperation("MARK", aSource, aProperty, aTarget, aTruthValue); + + return NS_OK; + } + + // If we get here, we couldn't find the assertion + *aDidMark = false; + return NS_OK; +} + +NS_IMETHODIMP +InMemoryDataSource::Sweep() +{ + SweepInfo info = { nullptr, &mReverseArcs }; + + // Remove all the assertions, but don't notify anyone. + SweepForwardArcsEntries(&mForwardArcs, &info); + + // Now do the notification. + Assertion* as = info.mUnassertList; + while (as) { + LogOperation("SWEEP", as->mSource, as->u.as.mProperty, as->u.as.mTarget, as->u.as.mTruthValue); + if (!(as->mHashEntry)) + { + for (int32_t i = int32_t(mNumObservers) - 1; mPropagateChanges && i >= 0; --i) { + nsIRDFObserver* obs = mObservers[i]; + // XXXbz other loops over mObservers null-check |obs| here! + obs->OnUnassert(this, as->mSource, as->u.as.mProperty, as->u.as.mTarget); + // XXX ignore return value? + } + } + + Assertion* doomed = as; + as = as->mNext; + + // Unlink, and release the datasource's reference + doomed->mNext = doomed->u.as.mInvNext = nullptr; + doomed->Release(); + } + + return NS_OK; +} + + +void +InMemoryDataSource::SweepForwardArcsEntries(PLDHashTable* aTable, + SweepInfo* aInfo) +{ + for (auto iter = aTable->Iter(); !iter.Done(); iter.Next()) { + auto entry = static_cast(iter.Get()); + + Assertion* as = entry->mAssertions; + if (as && (as->mHashEntry)) { + // Stuff in sub-hashes must be swept recursively (max depth: 1) + SweepForwardArcsEntries(as->u.hash.mPropertyHash, aInfo); + + // If the sub-hash is now empty, clean it up. + if (!as->u.hash.mPropertyHash->EntryCount()) { + as->Release(); + iter.Remove(); + } + continue; + } + + Assertion* prev = nullptr; + while (as) { + if (as->IsMarked()) { + prev = as; + as->Unmark(); + as = as->mNext; + } + else { + // remove from the list of assertions in the datasource + Assertion* next = as->mNext; + if (prev) { + prev->mNext = next; + } + else { + // it's the first one. update the hashtable entry. + entry->mAssertions = next; + } + + // remove from the reverse arcs + PLDHashEntryHdr* hdr = + aInfo->mReverseArcs->Search(as->u.as.mTarget); + NS_ASSERTION(hdr, "no assertion in reverse arcs"); + + Entry* rentry = static_cast(hdr); + Assertion* ras = rentry->mAssertions; + Assertion* rprev = nullptr; + while (ras) { + if (ras == as) { + if (rprev) { + rprev->u.as.mInvNext = ras->u.as.mInvNext; + } + else { + // it's the first one. update the hashtable entry. + rentry->mAssertions = ras->u.as.mInvNext; + } + as->u.as.mInvNext = nullptr; // for my sanity. + break; + } + rprev = ras; + ras = ras->u.as.mInvNext; + } + + // Wow, it was the _only_ one. Unhash it. + if (! rentry->mAssertions) { + aInfo->mReverseArcs->RawRemove(hdr); + } + + // add to the list of assertions to unassert + as->mNext = aInfo->mUnassertList; + aInfo->mUnassertList = as; + + // Advance to the next assertion + as = next; + } + } + + // if no more assertions exist for this resource, then unhash it. + if (! entry->mAssertions) { + iter.Remove(); + } + } +} + +//////////////////////////////////////////////////////////////////////// +// rdfIDataSource methods + +NS_IMETHODIMP +InMemoryDataSource::VisitAllSubjects(rdfITripleVisitor *aVisitor) +{ + // Lock datasource against writes + ++mReadCount; + + // Enumerate all of our entries. + nsresult rv = NS_OK; + for (auto iter = mForwardArcs.Iter(); !iter.Done(); iter.Next()) { + auto entry = static_cast(iter.Get()); + nsresult rv2; + nsCOMPtr subject = do_QueryInterface(entry->mNode, &rv2); + if (NS_FAILED(rv2)) { + NS_WARNING("QI to nsIRDFNode failed"); + continue; + } + rv = aVisitor->Visit(subject, nullptr, nullptr, true); + if (NS_FAILED(rv) || rv == NS_RDF_STOP_VISIT) { + break; + } + } + + // Unlock datasource + --mReadCount; + + return rv; +} + +NS_IMETHODIMP +InMemoryDataSource::VisitAllTriples(rdfITripleVisitor *aVisitor) +{ + // Lock datasource against writes + ++mReadCount; + + // Enumerate all of our entries. + nsresult rv = NS_OK; + for (auto iter = mForwardArcs.Iter(); !iter.Done(); iter.Next()) { + auto entry = static_cast(iter.Get()); + + nsresult rv2; + nsCOMPtr subject = do_QueryInterface(entry->mNode, &rv2); + if (NS_FAILED(rv2)) { + NS_WARNING("QI to nsIRDFNode failed"); + + } else if (entry->mAssertions->mHashEntry) { + for (auto iter = entry->mAssertions->u.hash.mPropertyHash->Iter(); + !iter.Done(); + iter.Next()) { + auto entry = static_cast(iter.Get()); + Assertion* assertion = entry->mAssertions; + while (assertion) { + NS_ASSERTION(!assertion->mHashEntry, "shouldn't have to hashes"); + rv = aVisitor->Visit(subject, assertion->u.as.mProperty, + assertion->u.as.mTarget, + assertion->u.as.mTruthValue); + if (NS_FAILED(rv)) { + goto end; + } + if (rv == NS_RDF_STOP_VISIT) { + goto inner_end; + } + assertion = assertion->mNext; + } + } + + } else { + Assertion* assertion = entry->mAssertions; + while (assertion) { + NS_ASSERTION(!assertion->mHashEntry, "shouldn't have to hashes"); + rv = aVisitor->Visit(subject, assertion->u.as.mProperty, + assertion->u.as.mTarget, + assertion->u.as.mTruthValue); + if (NS_FAILED(rv) || rv == NS_RDF_STOP_VISIT) { + goto end; + } + assertion = assertion->mNext; + } + } + + inner_end: + (void) 0; + } + + end: + // Unlock datasource + --mReadCount; + + return rv; +} + +//////////////////////////////////////////////////////////////////////// + diff --git a/rdf/base/nsNameSpaceMap.cpp b/rdf/base/nsNameSpaceMap.cpp new file mode 100644 index 000000000000..4ddf945c6f54 --- /dev/null +++ b/rdf/base/nsNameSpaceMap.cpp @@ -0,0 +1,64 @@ +/* -*- 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/. */ + +#include "nsNameSpaceMap.h" +#include "nsReadableUtils.h" + +nsNameSpaceMap::nsNameSpaceMap() + : mEntries(nullptr) +{ + MOZ_COUNT_CTOR(nsNameSpaceMap); +} + +nsNameSpaceMap::~nsNameSpaceMap() +{ + MOZ_COUNT_DTOR(nsNameSpaceMap); + + while (mEntries) { + Entry* doomed = mEntries; + mEntries = mEntries->mNext; + delete doomed; + } +} + +nsresult +nsNameSpaceMap::Put(const nsAString& aURI, nsAtom* aPrefix) +{ + nsCString uriUTF8; + AppendUTF16toUTF8(aURI, uriUTF8); + return Put(uriUTF8, aPrefix); +} + +nsresult +nsNameSpaceMap::Put(const nsACString& aURI, nsAtom* aPrefix) +{ + Entry* entry; + + // Make sure we're not adding a duplicate + for (entry = mEntries; entry != nullptr; entry = entry->mNext) { + if (entry->mURI == aURI || entry->mPrefix == aPrefix) + return NS_ERROR_FAILURE; + } + + entry = new Entry(aURI, aPrefix); + if (! entry) + return NS_ERROR_OUT_OF_MEMORY; + + entry->mNext = mEntries; + mEntries = entry; + return NS_OK; +} + +nsNameSpaceMap::const_iterator +nsNameSpaceMap::GetNameSpaceOf(const nsACString& aURI) const +{ + for (Entry* entry = mEntries; entry != nullptr; entry = entry->mNext) { + if (StringBeginsWith(aURI, entry->mURI)) + return const_iterator(entry); + } + + return last(); +} diff --git a/rdf/base/nsNameSpaceMap.h b/rdf/base/nsNameSpaceMap.h new file mode 100644 index 000000000000..96a80fd13f13 --- /dev/null +++ b/rdf/base/nsNameSpaceMap.h @@ -0,0 +1,98 @@ +/* -*- 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/. */ + +#ifndef nsNameSpaceMap_h__ +#define nsNameSpaceMap_h__ + +#include "nsCOMPtr.h" +#include "nsString.h" +#include "nsAtom.h" + +class nsNameSpaceMap +{ +public: + class Entry { + public: + Entry(const nsACString& aURI, nsAtom* aPrefix) + : mURI(aURI), mPrefix(aPrefix), mNext(nullptr) { + MOZ_COUNT_CTOR(nsNameSpaceMap::Entry); } + + ~Entry() { MOZ_COUNT_DTOR(nsNameSpaceMap::Entry); } + + nsCString mURI; + RefPtr mPrefix; + + Entry* mNext; + }; + + nsNameSpaceMap(); + ~nsNameSpaceMap(); + + nsresult + Put(const nsAString& aURI, nsAtom* aPrefix); + + nsresult + Put(const nsACString& aURI, nsAtom* aPrefix); + + class const_iterator { + protected: + friend class nsNameSpaceMap; + + explicit const_iterator(const Entry* aCurrent) + : mCurrent(aCurrent) {} + + const Entry* mCurrent; + + public: + const_iterator() + : mCurrent(nullptr) {} + + const_iterator(const const_iterator& iter) + : mCurrent(iter.mCurrent) {} + + const_iterator& + operator=(const const_iterator& iter) { + mCurrent = iter.mCurrent; + return *this; } + + const_iterator& + operator++() { + mCurrent = mCurrent->mNext; + return *this; } + + const_iterator + operator++(int) { + const_iterator tmp(*this); + mCurrent = mCurrent->mNext; + return tmp; } + + const Entry* operator->() const { return mCurrent; } + + const Entry& operator*() const { return *mCurrent; } + + bool + operator==(const const_iterator& iter) const { + return mCurrent == iter.mCurrent; } + + bool + operator!=(const const_iterator& iter) const { + return ! iter.operator==(*this); } + }; + + const_iterator first() const { + return const_iterator(mEntries); } + + const_iterator last() const { + return const_iterator(nullptr); } + + const_iterator GetNameSpaceOf(const nsACString& aURI) const; + +protected: + Entry* mEntries; +}; + + +#endif // nsNameSpaceMap_h__ diff --git a/rdf/base/nsRDFBaseDataSources.h b/rdf/base/nsRDFBaseDataSources.h new file mode 100644 index 000000000000..0243e1359559 --- /dev/null +++ b/rdf/base/nsRDFBaseDataSources.h @@ -0,0 +1,32 @@ +/* -*- 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 header file just contains prototypes for the factory methods + for "builtin" data sources that are included in rdf.dll. + + Each of these data sources is exposed to the external world via its + CID in ../include/nsRDFCID.h. + +*/ + +#ifndef nsBaseDataSources_h__ +#define nsBaseDataSources_h__ + +#include "nsError.h" +class nsIRDFDataSource; + +// in nsInMemoryDataSource.cpp +nsresult +NS_NewRDFInMemoryDataSource(nsISupports* aOuter, const nsIID& aIID, void** aResult); + +// in nsRDFXMLDataSource.cpp +extern nsresult +NS_NewRDFXMLDataSource(nsIRDFDataSource** aResult); + +#endif // nsBaseDataSources_h__ + + diff --git a/rdf/base/nsRDFContainer.cpp b/rdf/base/nsRDFContainer.cpp new file mode 100644 index 000000000000..1ef97ab0f0d3 --- /dev/null +++ b/rdf/base/nsRDFContainer.cpp @@ -0,0 +1,724 @@ +/* -*- 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/. */ + +/* + + Implementation for the RDF container. + + Notes + ----- + + 1. RDF containers are one-indexed. This means that a lot of the loops + that you'd normally think you'd write like this: + + for (i = 0; i < count; ++i) {} + + You've gotta write like this: + + for (i = 1; i <= count; ++i) {} + + "Sure, right, yeah, of course.", you say. Well maybe I'm just + thick, but it's easy to slip up. + + 2. The RDF:nextVal property on the container is an + implementation-level hack that is used to quickly compute the + next value for appending to the container. It will no doubt + become royally screwed up in the case of aggregation. + + 3. The RDF:nextVal property is also used to retrieve the count of + elements in the container. + + */ + + +#include "nsCOMPtr.h" +#include "nsIRDFContainer.h" +#include "nsIRDFContainerUtils.h" +#include "nsIRDFInMemoryDataSource.h" +#include "nsIRDFPropagatableDataSource.h" +#include "nsIRDFService.h" +#include "nsIServiceManager.h" +#include "nsRDFCID.h" +#include "nsString.h" +#include "rdf.h" + +#define RDF_SEQ_LIST_LIMIT 8 + +class RDFContainerImpl : public nsIRDFContainer +{ +public: + + // nsISupports interface + NS_DECL_ISUPPORTS + + // nsIRDFContainer interface + NS_DECL_NSIRDFCONTAINER + +private: + friend nsresult NS_NewRDFContainer(nsIRDFContainer** aResult); + + RDFContainerImpl(); + virtual ~RDFContainerImpl(); + + nsresult Init(); + + nsresult Renumber(int32_t aStartIndex, int32_t aIncrement); + nsresult SetNextValue(int32_t aIndex); + nsresult GetNextValue(nsIRDFResource** aResult); + + nsIRDFDataSource* mDataSource; + nsIRDFResource* mContainer; + + // pseudo constants + static int32_t gRefCnt; + static nsIRDFService* gRDFService; + static nsIRDFContainerUtils* gRDFContainerUtils; + static nsIRDFResource* kRDF_nextVal; +}; + + +int32_t RDFContainerImpl::gRefCnt = 0; +nsIRDFService* RDFContainerImpl::gRDFService; +nsIRDFContainerUtils* RDFContainerImpl::gRDFContainerUtils; +nsIRDFResource* RDFContainerImpl::kRDF_nextVal; + +//////////////////////////////////////////////////////////////////////// +// nsISupports interface + +NS_IMPL_ISUPPORTS(RDFContainerImpl, nsIRDFContainer) + + + +//////////////////////////////////////////////////////////////////////// +// nsIRDFContainer interface + +NS_IMETHODIMP +RDFContainerImpl::GetDataSource(nsIRDFDataSource** _retval) +{ + *_retval = mDataSource; + NS_IF_ADDREF(*_retval); + return NS_OK; +} + + +NS_IMETHODIMP +RDFContainerImpl::GetResource(nsIRDFResource** _retval) +{ + *_retval = mContainer; + NS_IF_ADDREF(*_retval); + return NS_OK; +} + + +NS_IMETHODIMP +RDFContainerImpl::Init(nsIRDFDataSource *aDataSource, nsIRDFResource *aContainer) +{ + NS_PRECONDITION(aDataSource != nullptr, "null ptr"); + if (! aDataSource) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(aContainer != nullptr, "null ptr"); + if (! aContainer) + return NS_ERROR_NULL_POINTER; + + nsresult rv; + bool isContainer; + rv = gRDFContainerUtils->IsContainer(aDataSource, aContainer, &isContainer); + if (NS_FAILED(rv)) return rv; + + // ``throw'' if we can't create a container on the specified + // datasource/resource combination. + if (! isContainer) + return NS_ERROR_FAILURE; + + NS_IF_RELEASE(mDataSource); + mDataSource = aDataSource; + NS_ADDREF(mDataSource); + + NS_IF_RELEASE(mContainer); + mContainer = aContainer; + NS_ADDREF(mContainer); + + return NS_OK; +} + + +NS_IMETHODIMP +RDFContainerImpl::GetCount(int32_t *aCount) +{ + if (!mDataSource || !mContainer) + return NS_ERROR_NOT_INITIALIZED; + + nsresult rv; + + // Get the next value, which hangs off of the bag via the + // RDF:nextVal property. This is the _next value_ that will get + // assigned in a one-indexed array. So, it's actually _one more_ + // than the actual count of elements in the container. + // + // XXX To handle aggregation, this should probably be a + // GetTargets() that enumerates all of the values and picks the + // largest one. + nsCOMPtr nextValNode; + rv = mDataSource->GetTarget(mContainer, kRDF_nextVal, true, getter_AddRefs(nextValNode)); + if (NS_FAILED(rv)) return rv; + + if (rv == NS_RDF_NO_VALUE) + return NS_ERROR_UNEXPECTED; + + nsCOMPtr nextValLiteral; + rv = nextValNode->QueryInterface(NS_GET_IID(nsIRDFLiteral), getter_AddRefs(nextValLiteral)); + if (NS_FAILED(rv)) return rv; + + const char16_t *s; + rv = nextValLiteral->GetValueConst( &s ); + if (NS_FAILED(rv)) return rv; + + nsAutoString nextValStr(s); + + int32_t nextVal; + nsresult err; + nextVal = nextValStr.ToInteger(&err); + if (NS_FAILED(err)) + return NS_ERROR_UNEXPECTED; + + *aCount = nextVal - 1; + return NS_OK; +} + + +NS_IMETHODIMP +RDFContainerImpl::GetElements(nsISimpleEnumerator **_retval) +{ + if (!mDataSource || !mContainer) + return NS_ERROR_NOT_INITIALIZED; + + return NS_NewContainerEnumerator(mDataSource, mContainer, _retval); +} + + +NS_IMETHODIMP +RDFContainerImpl::AppendElement(nsIRDFNode *aElement) +{ + if (!mDataSource || !mContainer) + return NS_ERROR_NOT_INITIALIZED; + + NS_PRECONDITION(aElement != nullptr, "null ptr"); + if (! aElement) + return NS_ERROR_NULL_POINTER; + + nsresult rv; + + nsCOMPtr nextVal; + rv = GetNextValue(getter_AddRefs(nextVal)); + if (NS_FAILED(rv)) return rv; + + rv = mDataSource->Assert(mContainer, nextVal, aElement, true); + if (NS_FAILED(rv)) return rv; + + return NS_OK; +} + + +NS_IMETHODIMP +RDFContainerImpl::RemoveElement(nsIRDFNode *aElement, bool aRenumber) +{ + if (!mDataSource || !mContainer) + return NS_ERROR_NOT_INITIALIZED; + + NS_PRECONDITION(aElement != nullptr, "null ptr"); + if (! aElement) + return NS_ERROR_NULL_POINTER; + + nsresult rv; + + int32_t idx; + rv = IndexOf(aElement, &idx); + if (NS_FAILED(rv)) return rv; + + if (idx < 0) + return NS_OK; + + // Remove the element. + nsCOMPtr ordinal; + rv = gRDFContainerUtils->IndexToOrdinalResource(idx, + getter_AddRefs(ordinal)); + if (NS_FAILED(rv)) return rv; + + rv = mDataSource->Unassert(mContainer, ordinal, aElement); + if (NS_FAILED(rv)) return rv; + + if (aRenumber) { + // Now slide the rest of the collection backwards to fill in + // the gap. This will have the side effect of completely + // renumber the container from index to the end. + rv = Renumber(idx + 1, -1); + if (NS_FAILED(rv)) return rv; + } + + return NS_OK; +} + + +NS_IMETHODIMP +RDFContainerImpl::InsertElementAt(nsIRDFNode *aElement, int32_t aIndex, bool aRenumber) +{ + if (!mDataSource || !mContainer) + return NS_ERROR_NOT_INITIALIZED; + + NS_PRECONDITION(aElement != nullptr, "null ptr"); + if (! aElement) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(aIndex >= 1, "illegal value"); + if (aIndex < 1) + return NS_ERROR_ILLEGAL_VALUE; + + nsresult rv; + + int32_t count; + rv = GetCount(&count); + if (NS_FAILED(rv)) return rv; + + NS_ASSERTION(aIndex <= count + 1, "illegal value"); + if (aIndex > count + 1) + return NS_ERROR_ILLEGAL_VALUE; + + if (aRenumber) { + // Make a hole for the element. This will have the side effect of + // completely renumbering the container from 'aIndex' to 'count', + // and will spew assertions. + rv = Renumber(aIndex, +1); + if (NS_FAILED(rv)) return rv; + } + + nsCOMPtr ordinal; + rv = gRDFContainerUtils->IndexToOrdinalResource(aIndex, getter_AddRefs(ordinal)); + if (NS_FAILED(rv)) return rv; + + rv = mDataSource->Assert(mContainer, ordinal, aElement, true); + if (NS_FAILED(rv)) return rv; + + return NS_OK; +} + +NS_IMETHODIMP +RDFContainerImpl::RemoveElementAt(int32_t aIndex, bool aRenumber, nsIRDFNode** _retval) +{ + if (!mDataSource || !mContainer) + return NS_ERROR_NOT_INITIALIZED; + + *_retval = nullptr; + + if (aIndex< 1) + return NS_ERROR_ILLEGAL_VALUE; + + nsresult rv; + + int32_t count; + rv = GetCount(&count); + if (NS_FAILED(rv)) return rv; + + if (aIndex > count) + return NS_ERROR_ILLEGAL_VALUE; + + nsCOMPtr ordinal; + rv = gRDFContainerUtils->IndexToOrdinalResource(aIndex, getter_AddRefs(ordinal)); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr old; + rv = mDataSource->GetTarget(mContainer, ordinal, true, getter_AddRefs(old)); + if (NS_FAILED(rv)) return rv; + + if (rv == NS_OK) { + rv = mDataSource->Unassert(mContainer, ordinal, old); + if (NS_FAILED(rv)) return rv; + + if (aRenumber) { + // Now slide the rest of the collection backwards to fill in + // the gap. This will have the side effect of completely + // renumber the container from index to the end. + rv = Renumber(aIndex + 1, -1); + if (NS_FAILED(rv)) return rv; + } + } + + old.swap(*_retval); + + return NS_OK; +} + +NS_IMETHODIMP +RDFContainerImpl::IndexOf(nsIRDFNode *aElement, int32_t *aIndex) +{ + if (!mDataSource || !mContainer) + return NS_ERROR_NOT_INITIALIZED; + + return gRDFContainerUtils->IndexOf(mDataSource, mContainer, + aElement, aIndex); +} + + +//////////////////////////////////////////////////////////////////////// + + +RDFContainerImpl::RDFContainerImpl() + : mDataSource(nullptr), mContainer(nullptr) +{ +} + + +nsresult +RDFContainerImpl::Init() +{ + if (gRefCnt++ == 0) { + nsresult rv; + + NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); + rv = CallGetService(kRDFServiceCID, &gRDFService); + if (NS_FAILED(rv)) { + NS_ERROR("unable to get RDF service"); + return rv; + } + + rv = gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "nextVal"), + &kRDF_nextVal); + if (NS_FAILED(rv)) return rv; + + NS_DEFINE_CID(kRDFContainerUtilsCID, NS_RDFCONTAINERUTILS_CID); + rv = CallGetService(kRDFContainerUtilsCID, &gRDFContainerUtils); + if (NS_FAILED(rv)) { + NS_ERROR("unable to get RDF container utils service"); + return rv; + } + } + + return NS_OK; +} + + +RDFContainerImpl::~RDFContainerImpl() +{ +#ifdef DEBUG_REFS + --gInstanceCount; + fprintf(stdout, "%d - RDF: RDFContainerImpl\n", gInstanceCount); +#endif + + NS_IF_RELEASE(mContainer); + NS_IF_RELEASE(mDataSource); + + if (--gRefCnt == 0) { + NS_IF_RELEASE(gRDFContainerUtils); + NS_IF_RELEASE(gRDFService); + NS_IF_RELEASE(kRDF_nextVal); + } +} + + +nsresult +NS_NewRDFContainer(nsIRDFContainer** aResult) +{ + RDFContainerImpl* result = new RDFContainerImpl(); + if (! result) + return NS_ERROR_OUT_OF_MEMORY; + + nsresult rv; + rv = result->Init(); + if (NS_FAILED(rv)) { + delete result; + return rv; + } + + NS_ADDREF(result); + *aResult = result; + return NS_OK; +} + + +nsresult +NS_NewRDFContainer(nsIRDFDataSource* aDataSource, + nsIRDFResource* aResource, + nsIRDFContainer** aResult) +{ + nsresult rv; + rv = NS_NewRDFContainer(aResult); + if (NS_FAILED(rv)) return rv; + + rv = (*aResult)->Init(aDataSource, aResource); + if (NS_FAILED(rv)) { + NS_RELEASE(*aResult); + } + return rv; +} + + +nsresult +RDFContainerImpl::Renumber(int32_t aStartIndex, int32_t aIncrement) +{ + if (!mDataSource || !mContainer) + return NS_ERROR_NOT_INITIALIZED; + + // Renumber the elements in the container starting with + // aStartIndex, updating each element's index by aIncrement. For + // example, + // + // (1:a 2:b 3:c) + // Renumber(2, +1); + // (1:a 3:b 4:c) + // Renumber(3, -1); + // (1:a 2:b 3:c) + // + nsresult rv; + + if (! aIncrement) + return NS_OK; + + int32_t count; + rv = GetCount(&count); + if (NS_FAILED(rv)) return rv; + + if (aIncrement > 0) { + // Update the container's nextVal to reflect the + // renumbering. We do this now if aIncrement > 0 because we'll + // want to be able to acknowledge that new elements are in the + // container. + rv = SetNextValue(count + aIncrement + 1); + if (NS_FAILED(rv)) return rv; + } + + int32_t i; + if (aIncrement < 0) { + i = aStartIndex; + } + else { + i = count; // we're one-indexed. + } + + // Note: once we disable notifications, don't exit this method until + // enabling notifications + nsCOMPtr propagatable = + do_QueryInterface(mDataSource); + if (propagatable) { + propagatable->SetPropagateChanges(false); + } + + bool err = false; + while (!err && ((aIncrement < 0) ? (i <= count) : (i >= aStartIndex))) + { + nsCOMPtr oldOrdinal; + rv = gRDFContainerUtils->IndexToOrdinalResource(i, getter_AddRefs(oldOrdinal)); + if (NS_FAILED(rv)) + { + err = true; + continue; + } + + nsCOMPtr newOrdinal; + rv = gRDFContainerUtils->IndexToOrdinalResource(i + aIncrement, getter_AddRefs(newOrdinal)); + if (NS_FAILED(rv)) + { + err = true; + continue; + } + + // Because of aggregation, we need to be paranoid about the + // possibility that >1 element may be present per ordinal. If + // there _is_ in fact more than one element, they'll all get + // assigned to the same new ordinal; i.e., we don't make any + // attempt to "clean up" the duplicate numbering. (Doing so + // would require two passes.) + nsCOMPtr targets; + rv = mDataSource->GetTargets(mContainer, oldOrdinal, true, getter_AddRefs(targets)); + if (NS_FAILED(rv)) + { + err = true; + continue; + } + + while (1) { + bool hasMore; + rv = targets->HasMoreElements(&hasMore); + if (NS_FAILED(rv)) + { + err = true; + break; + } + + if (! hasMore) + break; + + nsCOMPtr isupports; + rv = targets->GetNext(getter_AddRefs(isupports)); + if (NS_FAILED(rv)) + { + err = true; + break; + } + + nsCOMPtr element( do_QueryInterface(isupports) ); + NS_ASSERTION(element != nullptr, "something funky in the enumerator"); + if (! element) + { + err = true; + rv = NS_ERROR_UNEXPECTED; + break; + } + + rv = mDataSource->Unassert(mContainer, oldOrdinal, element); + if (NS_FAILED(rv)) + { + err = true; + break; + } + + rv = mDataSource->Assert(mContainer, newOrdinal, element, true); + if (NS_FAILED(rv)) + { + err = true; + break; + } + } + + i -= aIncrement; + } + + if (!err && (aIncrement < 0)) + { + // Update the container's nextVal to reflect the + // renumbering. We do this now if aIncrement < 0 because, up + // until this point, we'll want people to be able to find + // things that are still "at the end". + rv = SetNextValue(count + aIncrement + 1); + if (NS_FAILED(rv)) + { + err = true; + } + } + + // Note: MUST enable notifications before exiting this method + if (propagatable) { + propagatable->SetPropagateChanges(true); + } + + if (err) return(rv); + + return NS_OK; +} + + + +nsresult +RDFContainerImpl::SetNextValue(int32_t aIndex) +{ + if (!mDataSource || !mContainer) + return NS_ERROR_NOT_INITIALIZED; + + nsresult rv; + + // Remove the current value of nextVal, if there is one. + nsCOMPtr nextValNode; + if (NS_SUCCEEDED(rv = mDataSource->GetTarget(mContainer, + kRDF_nextVal, + true, + getter_AddRefs(nextValNode)))) { + if (NS_FAILED(rv = mDataSource->Unassert(mContainer, kRDF_nextVal, nextValNode))) { + NS_ERROR("unable to update nextVal"); + return rv; + } + } + + nsAutoString s; + s.AppendInt(aIndex, 10); + + nsCOMPtr nextVal; + if (NS_FAILED(rv = gRDFService->GetLiteral(s.get(), getter_AddRefs(nextVal)))) { + NS_ERROR("unable to get nextVal literal"); + return rv; + } + + rv = mDataSource->Assert(mContainer, kRDF_nextVal, nextVal, true); + if (rv != NS_RDF_ASSERTION_ACCEPTED) { + NS_ERROR("unable to update nextVal"); + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + + +nsresult +RDFContainerImpl::GetNextValue(nsIRDFResource** aResult) +{ + if (!mDataSource || !mContainer) + return NS_ERROR_NOT_INITIALIZED; + + nsresult rv; + + // Get the next value, which hangs off of the bag via the + // RDF:nextVal property. + nsCOMPtr nextValNode; + rv = mDataSource->GetTarget(mContainer, kRDF_nextVal, true, getter_AddRefs(nextValNode)); + if (NS_FAILED(rv)) return rv; + + if (rv == NS_RDF_NO_VALUE) + return NS_ERROR_UNEXPECTED; + + nsCOMPtr nextValLiteral; + rv = nextValNode->QueryInterface(NS_GET_IID(nsIRDFLiteral), getter_AddRefs(nextValLiteral)); + if (NS_FAILED(rv)) return rv; + + const char16_t* s; + rv = nextValLiteral->GetValueConst(&s); + if (NS_FAILED(rv)) return rv; + + int32_t nextVal = 0; + { + for (const char16_t* p = s; *p != 0; ++p) { + NS_ASSERTION(*p >= '0' && *p <= '9', "not a digit"); + if (*p < '0' || *p > '9') + break; + + nextVal *= 10; + nextVal += *p - '0'; + } + } + + static const char kRDFNameSpaceURI[] = RDF_NAMESPACE_URI; + nsAutoCStringN nextValStr; + nextValStr = kRDFNameSpaceURI; + nextValStr.Append('_'); + nextValStr.AppendInt(nextVal, 10); + + rv = gRDFService->GetResource(nextValStr, aResult); + if (NS_FAILED(rv)) return rv; + + // Now increment the RDF:nextVal property. + rv = mDataSource->Unassert(mContainer, kRDF_nextVal, nextValLiteral); + if (NS_FAILED(rv)) return rv; + + ++nextVal; + nextValStr.Truncate(); + nextValStr.AppendInt(nextVal, 10); + + rv = gRDFService->GetLiteral(NS_ConvertASCIItoUTF16(nextValStr).get(), getter_AddRefs(nextValLiteral)); + if (NS_FAILED(rv)) return rv; + + rv = mDataSource->Assert(mContainer, kRDF_nextVal, nextValLiteral, true); + if (NS_FAILED(rv)) return rv; + + if (RDF_SEQ_LIST_LIMIT == nextVal) + { + // focal point for RDF container mutation; + // basically, provide a hint to allow for fast access + nsCOMPtr inMem = do_QueryInterface(mDataSource); + if (inMem) + { + // ignore error; failure just means slower access + (void)inMem->EnsureFastContainment(mContainer); + } + } + + return NS_OK; +} diff --git a/rdf/base/nsRDFContainerUtils.cpp b/rdf/base/nsRDFContainerUtils.cpp new file mode 100644 index 000000000000..d92f00c3e8a9 --- /dev/null +++ b/rdf/base/nsRDFContainerUtils.cpp @@ -0,0 +1,513 @@ +/* -*- 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/. */ + +/* + + Implementation for the RDF container utils. + + */ + + +#include "nsCOMPtr.h" +#include "nsIServiceManager.h" +#include "nsIRDFContainer.h" +#include "nsIRDFContainerUtils.h" +#include "nsIRDFService.h" +#include "nsRDFCID.h" +#include "nsString.h" +#include "plstr.h" +#include "rdf.h" +#include "rdfutil.h" + +class RDFContainerUtilsImpl : public nsIRDFContainerUtils +{ +public: + // nsISupports interface + NS_DECL_ISUPPORTS + + // nsIRDFContainerUtils interface + NS_DECL_NSIRDFCONTAINERUTILS + +private: + friend nsresult NS_NewRDFContainerUtils(nsIRDFContainerUtils** aResult); + + RDFContainerUtilsImpl(); + virtual ~RDFContainerUtilsImpl(); + + nsresult MakeContainer(nsIRDFDataSource* aDataSource, + nsIRDFResource* aResource, + nsIRDFResource* aType, + nsIRDFContainer** aResult); + + bool IsA(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource, nsIRDFResource* aType); + + // pseudo constants + static int32_t gRefCnt; + static nsIRDFService* gRDFService; + static nsIRDFResource* kRDF_instanceOf; + static nsIRDFResource* kRDF_nextVal; + static nsIRDFResource* kRDF_Bag; + static nsIRDFResource* kRDF_Seq; + static nsIRDFResource* kRDF_Alt; + static nsIRDFLiteral* kOne; + static const char kRDFNameSpaceURI[]; +}; + +int32_t RDFContainerUtilsImpl::gRefCnt = 0; +nsIRDFService* RDFContainerUtilsImpl::gRDFService; +nsIRDFResource* RDFContainerUtilsImpl::kRDF_instanceOf; +nsIRDFResource* RDFContainerUtilsImpl::kRDF_nextVal; +nsIRDFResource* RDFContainerUtilsImpl::kRDF_Bag; +nsIRDFResource* RDFContainerUtilsImpl::kRDF_Seq; +nsIRDFResource* RDFContainerUtilsImpl::kRDF_Alt; +nsIRDFLiteral* RDFContainerUtilsImpl::kOne; +const char RDFContainerUtilsImpl::kRDFNameSpaceURI[] = RDF_NAMESPACE_URI; + +//////////////////////////////////////////////////////////////////////// +// nsISupports interface + +NS_IMPL_ISUPPORTS(RDFContainerUtilsImpl, nsIRDFContainerUtils) + +//////////////////////////////////////////////////////////////////////// +// nsIRDFContainerUtils interface + +NS_IMETHODIMP +RDFContainerUtilsImpl::IsOrdinalProperty(nsIRDFResource *aProperty, bool *_retval) +{ + NS_PRECONDITION(aProperty != nullptr, "null ptr"); + if (! aProperty) + return NS_ERROR_NULL_POINTER; + + nsresult rv; + + const char *propertyStr; + rv = aProperty->GetValueConst( &propertyStr ); + if (NS_FAILED(rv)) return rv; + + if (PL_strncmp(propertyStr, kRDFNameSpaceURI, sizeof(kRDFNameSpaceURI) - 1) != 0) { + *_retval = false; + return NS_OK; + } + + const char* s = propertyStr; + s += sizeof(kRDFNameSpaceURI) - 1; + if (*s != '_') { + *_retval = false; + return NS_OK; + } + + ++s; + while (*s) { + if (*s < '0' || *s > '9') { + *_retval = false; + return NS_OK; + } + + ++s; + } + + *_retval = true; + return NS_OK; +} + + +NS_IMETHODIMP +RDFContainerUtilsImpl::IndexToOrdinalResource(int32_t aIndex, nsIRDFResource **aOrdinal) +{ + NS_PRECONDITION(aIndex > 0, "illegal value"); + if (aIndex <= 0) + return NS_ERROR_ILLEGAL_VALUE; + + nsAutoCString uri(kRDFNameSpaceURI); + uri.Append('_'); + uri.AppendInt(aIndex); + + nsresult rv = gRDFService->GetResource(uri, aOrdinal); + NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get ordinal resource"); + if (NS_FAILED(rv)) return rv; + + return NS_OK; +} + + +NS_IMETHODIMP +RDFContainerUtilsImpl::OrdinalResourceToIndex(nsIRDFResource *aOrdinal, int32_t *aIndex) +{ + NS_PRECONDITION(aOrdinal != nullptr, "null ptr"); + if (! aOrdinal) + return NS_ERROR_NULL_POINTER; + + const char *ordinalStr; + if (NS_FAILED(aOrdinal->GetValueConst( &ordinalStr ))) + return NS_ERROR_FAILURE; + + const char* s = ordinalStr; + if (PL_strncmp(s, kRDFNameSpaceURI, sizeof(kRDFNameSpaceURI) - 1) != 0) { + NS_ERROR("not an ordinal"); + return NS_ERROR_UNEXPECTED; + } + + s += sizeof(kRDFNameSpaceURI) - 1; + if (*s != '_') { + NS_ERROR("not an ordinal"); + return NS_ERROR_UNEXPECTED; + } + + int32_t idx = 0; + + ++s; + while (*s) { + if (*s < '0' || *s > '9') { + NS_ERROR("not an ordinal"); + return NS_ERROR_UNEXPECTED; + } + + idx *= 10; + idx += (*s - '0'); + + ++s; + } + + *aIndex = idx; + return NS_OK; +} + +NS_IMETHODIMP +RDFContainerUtilsImpl::IsContainer(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, bool *_retval) +{ + NS_PRECONDITION(aDataSource != nullptr, "null ptr"); + if (! aDataSource) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(aResource != nullptr, "null ptr"); + if (! aResource) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(_retval != nullptr, "null ptr"); + if (! _retval) + return NS_ERROR_NULL_POINTER; + + if (IsA(aDataSource, aResource, kRDF_Seq) || + IsA(aDataSource, aResource, kRDF_Bag) || + IsA(aDataSource, aResource, kRDF_Alt)) { + *_retval = true; + } + else { + *_retval = false; + } + return NS_OK; +} + + +NS_IMETHODIMP +RDFContainerUtilsImpl::IsEmpty(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource, bool* _retval) +{ + if (! aDataSource) + return NS_ERROR_NULL_POINTER; + + nsresult rv; + + // By default, say that we're an empty container. Even if we're not + // really even a container. + *_retval = true; + + nsCOMPtr nextValNode; + rv = aDataSource->GetTarget(aResource, kRDF_nextVal, true, getter_AddRefs(nextValNode)); + if (NS_FAILED(rv)) return rv; + + if (rv == NS_RDF_NO_VALUE) + return NS_OK; + + nsCOMPtr nextValLiteral; + rv = nextValNode->QueryInterface(NS_GET_IID(nsIRDFLiteral), getter_AddRefs(nextValLiteral)); + if (NS_FAILED(rv)) return rv; + + if (nextValLiteral.get() != kOne) + *_retval = false; + + return NS_OK; +} + + +NS_IMETHODIMP +RDFContainerUtilsImpl::IsBag(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, bool *_retval) +{ + NS_PRECONDITION(aDataSource != nullptr, "null ptr"); + if (! aDataSource) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(aResource != nullptr, "null ptr"); + if (! aResource) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(_retval != nullptr, "null ptr"); + if (! _retval) + return NS_ERROR_NULL_POINTER; + + *_retval = IsA(aDataSource, aResource, kRDF_Bag); + return NS_OK; +} + + +NS_IMETHODIMP +RDFContainerUtilsImpl::IsSeq(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, bool *_retval) +{ + NS_PRECONDITION(aDataSource != nullptr, "null ptr"); + if (! aDataSource) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(aResource != nullptr, "null ptr"); + if (! aResource) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(_retval != nullptr, "null ptr"); + if (! _retval) + return NS_ERROR_NULL_POINTER; + + *_retval = IsA(aDataSource, aResource, kRDF_Seq); + return NS_OK; +} + + +NS_IMETHODIMP +RDFContainerUtilsImpl::IsAlt(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, bool *_retval) +{ + NS_PRECONDITION(aDataSource != nullptr, "null ptr"); + if (! aDataSource) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(aResource != nullptr, "null ptr"); + if (! aResource) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(_retval != nullptr, "null ptr"); + if (! _retval) + return NS_ERROR_NULL_POINTER; + + *_retval = IsA(aDataSource, aResource, kRDF_Alt); + return NS_OK; +} + + +NS_IMETHODIMP +RDFContainerUtilsImpl::MakeBag(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, nsIRDFContainer **_retval) +{ + return MakeContainer(aDataSource, aResource, kRDF_Bag, _retval); +} + + +NS_IMETHODIMP +RDFContainerUtilsImpl::MakeSeq(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, nsIRDFContainer **_retval) +{ + return MakeContainer(aDataSource, aResource, kRDF_Seq, _retval); +} + + +NS_IMETHODIMP +RDFContainerUtilsImpl::MakeAlt(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, nsIRDFContainer **_retval) +{ + return MakeContainer(aDataSource, aResource, kRDF_Alt, _retval); +} + + + +//////////////////////////////////////////////////////////////////////// + + +RDFContainerUtilsImpl::RDFContainerUtilsImpl() +{ + if (gRefCnt++ == 0) { + nsresult rv; + + NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); + rv = CallGetService(kRDFServiceCID, &gRDFService); + + NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get RDF service"); + if (NS_SUCCEEDED(rv)) { + gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "instanceOf"), + &kRDF_instanceOf); + gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "nextVal"), + &kRDF_nextVal); + gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "Bag"), + &kRDF_Bag); + gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "Seq"), + &kRDF_Seq); + gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "Alt"), + &kRDF_Alt); + gRDFService->GetLiteral(u"1", &kOne); + } + } +} + + +RDFContainerUtilsImpl::~RDFContainerUtilsImpl() +{ +#ifdef DEBUG_REFS + --gInstanceCount; + fprintf(stdout, "%d - RDF: RDFContainerUtilsImpl\n", gInstanceCount); +#endif + + if (--gRefCnt == 0) { + NS_IF_RELEASE(gRDFService); + NS_IF_RELEASE(kRDF_instanceOf); + NS_IF_RELEASE(kRDF_nextVal); + NS_IF_RELEASE(kRDF_Bag); + NS_IF_RELEASE(kRDF_Seq); + NS_IF_RELEASE(kRDF_Alt); + NS_IF_RELEASE(kOne); + } +} + + + +nsresult +NS_NewRDFContainerUtils(nsIRDFContainerUtils** aResult) +{ + NS_PRECONDITION(aResult != nullptr, "null ptr"); + if (! aResult) + return NS_ERROR_NULL_POINTER; + + RDFContainerUtilsImpl* result = + new RDFContainerUtilsImpl(); + + if (! result) + return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(result); + *aResult = result; + return NS_OK; +} + + +nsresult +RDFContainerUtilsImpl::MakeContainer(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource, nsIRDFResource* aType, nsIRDFContainer** aResult) +{ + NS_PRECONDITION(aDataSource != nullptr, "null ptr"); + if (! aDataSource) return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(aResource != nullptr, "null ptr"); + if (! aResource) return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(aType != nullptr, "null ptr"); + if (! aType) return NS_ERROR_NULL_POINTER; + + if (aResult) *aResult = nullptr; + + nsresult rv; + + // Check to see if somebody has already turned it into a container; if so + // don't try to do it again. + bool isContainer; + rv = IsContainer(aDataSource, aResource, &isContainer); + if (NS_FAILED(rv)) return rv; + + if (!isContainer) + { + rv = aDataSource->Assert(aResource, kRDF_instanceOf, aType, true); + if (NS_FAILED(rv)) return rv; + + rv = aDataSource->Assert(aResource, kRDF_nextVal, kOne, true); + if (NS_FAILED(rv)) return rv; + } + + if (aResult) { + rv = NS_NewRDFContainer(aResult); + if (NS_FAILED(rv)) return rv; + + rv = (*aResult)->Init(aDataSource, aResource); + if (NS_FAILED(rv)) return rv; + } + + return NS_OK; +} + +bool +RDFContainerUtilsImpl::IsA(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource, nsIRDFResource* aType) +{ + if (!aDataSource || !aResource || !aType) { + NS_WARNING("Unexpected null argument"); + return false; + } + + nsresult rv; + + bool result; + rv = aDataSource->HasAssertion(aResource, kRDF_instanceOf, aType, true, &result); + if (NS_FAILED(rv)) + return false; + + return result; +} + +NS_IMETHODIMP +RDFContainerUtilsImpl::IndexOf(nsIRDFDataSource* aDataSource, nsIRDFResource* aContainer, nsIRDFNode* aElement, int32_t* aIndex) +{ + if (!aDataSource || !aContainer) + return NS_ERROR_NULL_POINTER; + + // Assume we can't find it. + *aIndex = -1; + + // If the resource is null, bail quietly + if (! aElement) + return NS_OK; + + // We'll assume that fan-out is much higher than fan-in, so grovel + // through the inbound arcs, look for an ordinal resource, and + // decode it. + nsCOMPtr arcsIn; + aDataSource->ArcLabelsIn(aElement, getter_AddRefs(arcsIn)); + if (! arcsIn) + return NS_OK; + + while (1) { + bool hasMoreArcs = false; + arcsIn->HasMoreElements(&hasMoreArcs); + if (! hasMoreArcs) + break; + + nsCOMPtr isupports; + arcsIn->GetNext(getter_AddRefs(isupports)); + if (! isupports) + break; + + nsCOMPtr property = + do_QueryInterface(isupports); + + if (! property) + continue; + + bool isOrdinal; + IsOrdinalProperty(property, &isOrdinal); + if (! isOrdinal) + continue; + + nsCOMPtr sources; + aDataSource->GetSources(property, aElement, true, getter_AddRefs(sources)); + if (! sources) + continue; + + while (1) { + bool hasMoreSources = false; + sources->HasMoreElements(&hasMoreSources); + if (! hasMoreSources) + break; + + nsCOMPtr isupports2; + sources->GetNext(getter_AddRefs(isupports2)); + if (! isupports2) + break; + + nsCOMPtr source = + do_QueryInterface(isupports2); + + if (source == aContainer) + // Found it. + return OrdinalResourceToIndex(property, aIndex); + } + } + + return NS_OK; +} diff --git a/rdf/base/nsRDFContentSink.cpp b/rdf/base/nsRDFContentSink.cpp new file mode 100644 index 000000000000..3557e817baff --- /dev/null +++ b/rdf/base/nsRDFContentSink.cpp @@ -0,0 +1,1444 @@ +/* -*- 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/. */ + +/* + + An implementation for an NGLayout-style content sink that knows how + to build an RDF content model from XML-serialized RDF. + + For more information on the RDF/XML syntax, + see http://www.w3.org/TR/REC-rdf-syntax/ + + This code is based on the final W3C Recommendation, + http://www.w3.org/TR/1999/REC-rdf-syntax-19990222. + + Open Issues ------------------ + + 1) factoring code with nsXMLContentSink - There's some amount of + common code between this and the HTML content sink. This will + increase as we support more and more HTML elements. How can code + from XML/HTML be factored? + + 2) We don't support the `parseType' attribute on the Description + tag; therefore, it is impossible to "inline" raw XML in this + implemenation. + + 3) We don't build the reifications at parse time due to the + footprint overhead it would incur for large RDF documents. (It + may be possible to attach a "reification" wrapper datasource that + would present this information at query-time.) Because of this, + the `bagID' attribute is not processed correctly. + + 4) No attempt is made to `resolve URIs' to a canonical form (the + specification hints that an implementation should do this). This + is omitted for the obvious reason that we can ill afford to + resolve each URI reference. + +*/ + +#include "nsCOMPtr.h" +#include "nsInterfaceHashtable.h" +#include "nsIContentSink.h" +#include "nsIRDFContainer.h" +#include "nsIRDFContainerUtils.h" +#include "nsIRDFContentSink.h" +#include "nsIRDFNode.h" +#include "nsIRDFService.h" +#include "nsIRDFXMLSink.h" +#include "nsIServiceManager.h" +#include "nsIURL.h" +#include "nsIXMLContentSink.h" +#include "nsRDFCID.h" +#include "nsTArray.h" +#include "nsString.h" +#include "mozilla/Logging.h" +#include "rdf.h" +#include "rdfutil.h" +#include "nsReadableUtils.h" +#include "nsIExpatSink.h" +#include "nsCRT.h" +#include "nsAtom.h" +#include "nsGkAtoms.h" +#include "nsIScriptError.h" +#include "nsIDTD.h" + +using namespace mozilla; + +/////////////////////////////////////////////////////////////////////// + +enum RDFContentSinkState { + eRDFContentSinkState_InProlog, + eRDFContentSinkState_InDocumentElement, + eRDFContentSinkState_InDescriptionElement, + eRDFContentSinkState_InContainerElement, + eRDFContentSinkState_InPropertyElement, + eRDFContentSinkState_InMemberElement, + eRDFContentSinkState_InEpilog +}; + +enum RDFContentSinkParseMode { + eRDFContentSinkParseMode_Resource, + eRDFContentSinkParseMode_Literal, + eRDFContentSinkParseMode_Int, + eRDFContentSinkParseMode_Date +}; + +typedef decltype(&nsIRDFContainerUtils::IsAlt) nsContainerTestFn; +typedef decltype(&nsIRDFContainerUtils::MakeAlt) nsMakeContainerFn; + +class RDFContentSinkImpl : public nsIRDFContentSink, + public nsIExpatSink +{ +public: + RDFContentSinkImpl(); + + // nsISupports + NS_DECL_ISUPPORTS + NS_DECL_NSIEXPATSINK + + // nsIContentSink + NS_IMETHOD WillParse(void) override; + NS_IMETHOD WillBuildModel(nsDTDMode aDTDMode) override; + NS_IMETHOD DidBuildModel(bool aTerminated) override; + NS_IMETHOD WillInterrupt(void) override; + NS_IMETHOD WillResume(void) override; + NS_IMETHOD SetParser(nsParserBase* aParser) override; + virtual void FlushPendingNotifications(mozilla::FlushType aType) override { } + virtual void SetDocumentCharset(NotNull aEncoding) + override { } + virtual nsISupports *GetTarget() override { return nullptr; } + + // nsIRDFContentSink + NS_IMETHOD Init(nsIURI* aURL) override; + NS_IMETHOD SetDataSource(nsIRDFDataSource* aDataSource) override; + NS_IMETHOD GetDataSource(nsIRDFDataSource*& aDataSource) override; + + // pseudo constants + static int32_t gRefCnt; + static nsIRDFService* gRDFService; + static nsIRDFContainerUtils* gRDFContainerUtils; + static nsIRDFResource* kRDF_type; + static nsIRDFResource* kRDF_instanceOf; // XXX should be RDF:type + static nsIRDFResource* kRDF_Alt; + static nsIRDFResource* kRDF_Bag; + static nsIRDFResource* kRDF_Seq; + static nsIRDFResource* kRDF_nextVal; + + typedef struct ContainerInfo { + nsIRDFResource** mType; + nsContainerTestFn mTestFn; + nsMakeContainerFn mMakeFn; + } ContainerInfo; + +protected: + virtual ~RDFContentSinkImpl(); + + // Text management + void ParseText(nsIRDFNode **aResult); + + nsresult FlushText(); + nsresult AddText(const char16_t* aText, int32_t aLength); + + // RDF-specific parsing + nsresult OpenRDF(const char16_t* aName); + nsresult OpenObject(const char16_t* aName ,const char16_t** aAttributes); + nsresult OpenProperty(const char16_t* aName, const char16_t** aAttributes); + nsresult OpenMember(const char16_t* aName, const char16_t** aAttributes); + nsresult OpenValue(const char16_t* aName, const char16_t** aAttributes); + + nsresult GetIdAboutAttribute(const char16_t** aAttributes, nsIRDFResource** aResource, bool* aIsAnonymous = nullptr); + nsresult GetResourceAttribute(const char16_t** aAttributes, nsIRDFResource** aResource); + nsresult AddProperties(const char16_t** aAttributes, nsIRDFResource* aSubject, int32_t* aCount = nullptr); + void SetParseMode(const char16_t **aAttributes); + + char16_t* mText; + int32_t mTextLength; + int32_t mTextSize; + + /** + * 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. + */ + void RegisterNamespaces(const char16_t **aAttributes); + + /** + * 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. + */ + const nsDependentSubstring SplitExpatName(const char16_t *aExpatName, + nsAtom **aLocalName); + + enum eContainerType { eBag, eSeq, eAlt }; + nsresult InitContainer(nsIRDFResource* aContainerType, nsIRDFResource* aContainer); + nsresult ReinitContainer(nsIRDFResource* aContainerType, nsIRDFResource* aContainer); + + // The datasource in which we're assigning assertions + nsCOMPtr mDataSource; + + // A hash of all the node IDs referred to + nsInterfaceHashtable mNodeIDMap; + + // The current state of the content sink + RDFContentSinkState mState; + RDFContentSinkParseMode mParseMode; + + // content stack management + int32_t + PushContext(nsIRDFResource *aContext, + RDFContentSinkState aState, + RDFContentSinkParseMode aParseMode); + + nsresult + PopContext(nsIRDFResource *&aContext, + RDFContentSinkState &aState, + RDFContentSinkParseMode &aParseMode); + + nsIRDFResource* GetContextElement(int32_t ancestor = 0); + + + struct RDFContextStackElement { + nsCOMPtr mResource; + RDFContentSinkState mState; + RDFContentSinkParseMode mParseMode; + }; + + AutoTArray* mContextStack; + + nsCOMPtr mDocumentURL; + +private: + static mozilla::LazyLogModule gLog; +}; + +int32_t RDFContentSinkImpl::gRefCnt = 0; +nsIRDFService* RDFContentSinkImpl::gRDFService; +nsIRDFContainerUtils* RDFContentSinkImpl::gRDFContainerUtils; +nsIRDFResource* RDFContentSinkImpl::kRDF_type; +nsIRDFResource* RDFContentSinkImpl::kRDF_instanceOf; +nsIRDFResource* RDFContentSinkImpl::kRDF_Alt; +nsIRDFResource* RDFContentSinkImpl::kRDF_Bag; +nsIRDFResource* RDFContentSinkImpl::kRDF_Seq; +nsIRDFResource* RDFContentSinkImpl::kRDF_nextVal; + +mozilla::LazyLogModule RDFContentSinkImpl::gLog("nsRDFContentSink"); + +//////////////////////////////////////////////////////////////////////// + +RDFContentSinkImpl::RDFContentSinkImpl() + : mText(nullptr), + mTextLength(0), + mTextSize(0), + mState(eRDFContentSinkState_InProlog), + mParseMode(eRDFContentSinkParseMode_Literal), + mContextStack(nullptr) +{ + if (gRefCnt++ == 0) { + NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); + nsresult rv = CallGetService(kRDFServiceCID, &gRDFService); + + NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get RDF service"); + if (NS_SUCCEEDED(rv)) { + rv = gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "type"), + &kRDF_type); + rv = gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "instanceOf"), + &kRDF_instanceOf); + rv = gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "Alt"), + &kRDF_Alt); + rv = gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "Bag"), + &kRDF_Bag); + rv = gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "Seq"), + &kRDF_Seq); + rv = gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "nextVal"), + &kRDF_nextVal); + } + + NS_DEFINE_CID(kRDFContainerUtilsCID, NS_RDFCONTAINERUTILS_CID); + rv = CallGetService(kRDFContainerUtilsCID, &gRDFContainerUtils); + } +} + + +RDFContentSinkImpl::~RDFContentSinkImpl() +{ +#ifdef DEBUG_REFS + --gInstanceCount; + fprintf(stdout, "%d - RDF: RDFContentSinkImpl\n", gInstanceCount); +#endif + + if (mContextStack) { + MOZ_LOG(gLog, LogLevel::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. + int32_t i = mContextStack->Length(); + while (0 < i--) { + nsIRDFResource* resource = nullptr; + RDFContentSinkState state; + RDFContentSinkParseMode parseMode; + PopContext(resource, state, parseMode); + + // 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 && MOZ_LOG_TEST(gLog, LogLevel::Debug)) { + nsCString uri; + resource->GetValue(getter_Copies(uri)); + MOZ_LOG(gLog, LogLevel::Debug, + ("rdfxml: uri=%s", uri.get())); + } + + NS_IF_RELEASE(resource); + } + + delete mContextStack; + } + free(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); + } +} + +//////////////////////////////////////////////////////////////////////// +// nsISupports interface + +NS_IMPL_ADDREF(RDFContentSinkImpl) +NS_IMPL_RELEASE(RDFContentSinkImpl) + +NS_IMETHODIMP +RDFContentSinkImpl::QueryInterface(REFNSIID iid, void** result) +{ + NS_PRECONDITION(result, "null ptr"); + if (! result) + return NS_ERROR_NULL_POINTER; + + NS_DEFINE_IID(kIContentSinkIID, NS_ICONTENT_SINK_IID); + NS_DEFINE_IID(kIExpatSinkIID, NS_IEXPATSINK_IID); + NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); + NS_DEFINE_IID(kIXMLContentSinkIID, NS_IXMLCONTENT_SINK_IID); + NS_DEFINE_IID(kIRDFContentSinkIID, NS_IRDFCONTENTSINK_IID); + + *result = nullptr; + if (iid.Equals(kIRDFContentSinkIID) || + iid.Equals(kIXMLContentSinkIID) || + iid.Equals(kIContentSinkIID) || + iid.Equals(kISupportsIID)) { + *result = static_cast(this); + AddRef(); + return NS_OK; + } + else if (iid.Equals(kIExpatSinkIID)) { + *result = static_cast(this); + AddRef(); + return NS_OK; + } + return NS_NOINTERFACE; +} + +NS_IMETHODIMP +RDFContentSinkImpl::HandleStartElement(const char16_t *aName, + const char16_t **aAtts, + uint32_t aAttsCount, + uint32_t aLineNumber) +{ + FlushText(); + + nsresult rv = NS_ERROR_UNEXPECTED; // XXX + + RegisterNamespaces(aAtts); + + switch (mState) { + case eRDFContentSinkState_InProlog: + rv = OpenRDF(aName); + break; + + case eRDFContentSinkState_InDocumentElement: + rv = OpenObject(aName,aAtts); + break; + + case eRDFContentSinkState_InDescriptionElement: + rv = OpenProperty(aName,aAtts); + break; + + case eRDFContentSinkState_InContainerElement: + rv = OpenMember(aName,aAtts); + break; + + case eRDFContentSinkState_InPropertyElement: + case eRDFContentSinkState_InMemberElement: + rv = OpenValue(aName,aAtts); + break; + + case eRDFContentSinkState_InEpilog: + MOZ_LOG(gLog, LogLevel::Warning, + ("rdfxml: unexpected content in epilog at line %d", + aLineNumber)); + break; + } + + return rv; +} + +NS_IMETHODIMP +RDFContentSinkImpl::HandleEndElement(const char16_t *aName) +{ + FlushText(); + + nsIRDFResource* resource; + if (NS_FAILED(PopContext(resource, mState, mParseMode))) { + // XXX parser didn't catch unmatched tags? + if (MOZ_LOG_TEST(gLog, LogLevel::Warning)) { + nsAutoString tagStr(aName); + char* tagCStr = ToNewCString(tagStr); + + MOZ_LOG(gLog, LogLevel::Warning, + ("rdfxml: extra close tag '%s' at line %d", + tagCStr, 0/*XXX fix me */)); + + free(tagCStr); + } + + return NS_ERROR_UNEXPECTED; // XXX + } + + // If we've just popped a member or property element, _now_ is the + // time to add that element to the graph. + switch (mState) { + case eRDFContentSinkState_InMemberElement: + { + nsCOMPtr container; + NS_NewRDFContainer(getter_AddRefs(container)); + container->Init(mDataSource, GetContextElement(1)); + container->AppendElement(resource); + } + break; + + case eRDFContentSinkState_InPropertyElement: + { + mDataSource->Assert(GetContextElement(1), GetContextElement(0), resource, true); + } break; + default: + break; + } + + if (mContextStack->IsEmpty()) + mState = eRDFContentSinkState_InEpilog; + + NS_IF_RELEASE(resource); + return NS_OK; +} + +NS_IMETHODIMP +RDFContentSinkImpl::HandleComment(const char16_t *aName) +{ + return NS_OK; +} + +NS_IMETHODIMP +RDFContentSinkImpl::HandleCDataSection(const char16_t *aData, + uint32_t aLength) +{ + return aData ? AddText(aData, aLength) : NS_OK; +} + +NS_IMETHODIMP +RDFContentSinkImpl::HandleDoctypeDecl(const nsAString & aSubset, + const nsAString & aName, + const nsAString & aSystemId, + const nsAString & aPublicId, + nsISupports* aCatalogData) +{ + return NS_OK; +} + +NS_IMETHODIMP +RDFContentSinkImpl::HandleCharacterData(const char16_t *aData, + uint32_t aLength) +{ + return aData ? AddText(aData, aLength) : NS_OK; +} + +NS_IMETHODIMP +RDFContentSinkImpl::HandleProcessingInstruction(const char16_t *aTarget, + const char16_t *aData) +{ + return NS_OK; +} + +NS_IMETHODIMP +RDFContentSinkImpl::HandleXMLDeclaration(const char16_t *aVersion, + const char16_t *aEncoding, + int32_t aStandalone) +{ + return NS_OK; +} + +NS_IMETHODIMP +RDFContentSinkImpl::ReportError(const char16_t* aErrorText, + const char16_t* aSourceText, + nsIScriptError *aError, + bool *_retval) +{ + NS_PRECONDITION(aError && aSourceText && aErrorText, "Check arguments!!!"); + + // The expat driver should report the error. + *_retval = true; + return NS_OK; +} + +//////////////////////////////////////////////////////////////////////// +// nsIContentSink interface + +NS_IMETHODIMP +RDFContentSinkImpl::WillParse(void) +{ + return NS_OK; +} + + +NS_IMETHODIMP +RDFContentSinkImpl::WillBuildModel(nsDTDMode) +{ + if (mDataSource) { + nsCOMPtr sink = do_QueryInterface(mDataSource); + if (sink) + return sink->BeginLoad(); + } + return NS_OK; +} + +NS_IMETHODIMP +RDFContentSinkImpl::DidBuildModel(bool aTerminated) +{ + if (mDataSource) { + nsCOMPtr sink = do_QueryInterface(mDataSource); + if (sink) + return sink->EndLoad(); + } + return NS_OK; +} + +NS_IMETHODIMP +RDFContentSinkImpl::WillInterrupt(void) +{ + if (mDataSource) { + nsCOMPtr sink = do_QueryInterface(mDataSource); + if (sink) + return sink->Interrupt(); + } + return NS_OK; +} + +NS_IMETHODIMP +RDFContentSinkImpl::WillResume(void) +{ + if (mDataSource) { + nsCOMPtr sink = do_QueryInterface(mDataSource); + if (sink) + return sink->Resume(); + } + return NS_OK; +} + +NS_IMETHODIMP +RDFContentSinkImpl::SetParser(nsParserBase* aParser) +{ + return NS_OK; +} + +//////////////////////////////////////////////////////////////////////// +// nsIRDFContentSink interface + +NS_IMETHODIMP +RDFContentSinkImpl::Init(nsIURI* aURL) +{ + NS_PRECONDITION(aURL != nullptr, "null ptr"); + if (! aURL) + return NS_ERROR_NULL_POINTER; + + mDocumentURL = aURL; + mState = eRDFContentSinkState_InProlog; + return NS_OK; +} + +NS_IMETHODIMP +RDFContentSinkImpl::SetDataSource(nsIRDFDataSource* aDataSource) +{ + NS_PRECONDITION(aDataSource != nullptr, "SetDataSource null ptr"); + mDataSource = aDataSource; + NS_ASSERTION(mDataSource != nullptr,"Couldn't QI RDF DataSource"); + return NS_OK; +} + + +NS_IMETHODIMP +RDFContentSinkImpl::GetDataSource(nsIRDFDataSource*& aDataSource) +{ + aDataSource = mDataSource; + NS_IF_ADDREF(aDataSource); + return NS_OK; +} + +//////////////////////////////////////////////////////////////////////// +// Text buffering + +static bool +rdf_IsDataInBuffer(char16_t* buffer, int32_t length) +{ + for (int32_t i = 0; i < length; ++i) { + if (buffer[i] == ' ' || + buffer[i] == '\t' || + buffer[i] == '\n' || + buffer[i] == '\r') + continue; + + return true; + } + return false; +} + +void +RDFContentSinkImpl::ParseText(nsIRDFNode **aResult) +{ + // 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: + { + nsresult err; + int32_t i = value.ToInteger(&err); + nsIRDFInt *result; + gRDFService->GetIntLiteral(i, &result); + *aResult = result; + } + break; + + case eRDFContentSinkParseMode_Date: + { + PRTime t = rdf_ParseDate(nsDependentCString(NS_LossyConvertUTF16toASCII(value).get(), value.Length())); + nsIRDFDate *result; + gRDFService->GetDateLiteral(t, &result); + *aResult = result; + } + break; + + default: + NS_NOTREACHED("unknown parse type"); + break; + } +} + +nsresult +RDFContentSinkImpl::FlushText() +{ + nsresult rv = NS_OK; + if (0 != mTextLength) { + if (rdf_IsDataInBuffer(mText, mTextLength)) { + // XXX if there's anything but whitespace, then we'll + // create a text node. + + switch (mState) { + case eRDFContentSinkState_InMemberElement: { + nsCOMPtr node; + ParseText(getter_AddRefs(node)); + + nsCOMPtr container; + NS_NewRDFContainer(getter_AddRefs(container)); + container->Init(mDataSource, GetContextElement(1)); + + container->AppendElement(node); + } break; + + case eRDFContentSinkState_InPropertyElement: { + nsCOMPtr node; + ParseText(getter_AddRefs(node)); + + mDataSource->Assert(GetContextElement(1), GetContextElement(0), node, true); + } break; + + default: + // just ignore it + break; + } + } + mTextLength = 0; + } + return rv; +} + + +nsresult +RDFContentSinkImpl::AddText(const char16_t* aText, int32_t aLength) +{ + // Create buffer when we first need it + if (0 == mTextSize) { + mText = (char16_t *) malloc(sizeof(char16_t) * 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. + int32_t amount = mTextSize - mTextLength; + if (amount < aLength) { + // Grow the buffer by at least a factor of two to prevent thrashing. + // Since realloc() will leave mText intact if the call fails, + // don't clobber mText or mTextSize until the new mem is allocated. + int32_t newSize = (2 * mTextSize > (mTextSize + aLength)) ? + (2 * mTextSize) : (mTextSize + aLength); + char16_t* newText = + (char16_t *) realloc(mText, sizeof(char16_t) * newSize); + if (!newText) + return NS_ERROR_OUT_OF_MEMORY; + mTextSize = newSize; + mText = newText; + } + memcpy(&mText[mTextLength], aText, sizeof(char16_t) * aLength); + mTextLength += aLength; + + return NS_OK; +} + +bool +rdf_RequiresAbsoluteURI(const nsString& uri) +{ + // cheap shot at figuring out if this requires an absolute url translation + return !(StringBeginsWith(uri, NS_LITERAL_STRING("urn:")) || + StringBeginsWith(uri, NS_LITERAL_STRING("chrome:"))); +} + +nsresult +RDFContentSinkImpl::GetIdAboutAttribute(const char16_t** aAttributes, + nsIRDFResource** aResource, + bool* aIsAnonymous) +{ + // This corresponds to the dirty work of production [6.5] + nsresult rv = NS_OK; + + nsAutoString nodeID; + + RefPtr 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 == nsGkAtoms::about) { + if (aIsAnonymous) + *aIsAnonymous = false; + + nsAutoString relURI(aAttributes[1]); + if (rdf_RequiresAbsoluteURI(relURI)) { + nsAutoCString uri; + rv = mDocumentURL->Resolve(NS_ConvertUTF16toUTF8(aAttributes[1]), uri); + if (NS_FAILED(rv)) return rv; + + return gRDFService->GetResource(uri, + aResource); + } + return gRDFService->GetResource(NS_ConvertUTF16toUTF8(aAttributes[1]), + aResource); + } + else if (localName == nsGkAtoms::ID) { + if (aIsAnonymous) + *aIsAnonymous = false; + // 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. + nsAutoCString name; + nsAutoCString ref('#'); + AppendUTF16toUTF8(aAttributes[1], ref); + + rv = mDocumentURL->Resolve(ref, name); + if (NS_FAILED(rv)) return rv; + + return gRDFService->GetResource(name, aResource); + } + else if (localName == nsGkAtoms::nodeID) { + nodeID.Assign(aAttributes[1]); + } + else if (localName == nsGkAtoms::about) { + // XXX we don't deal with aboutEach... + //MOZ_LOG(gLog, LogLevel::Warning, + // ("rdfxml: ignoring aboutEach at line %d", + // aNode.GetSourceLineNumber())); + } + } + + // Otherwise, we couldn't find anything, so just gensym one... + if (aIsAnonymous) + *aIsAnonymous = 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; +} + +nsresult +RDFContentSinkImpl::GetResourceAttribute(const char16_t** aAttributes, + nsIRDFResource** aResource) +{ + RefPtr 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 == nsGkAtoms::resource) { + // XXX Take the URI and make it fully qualified by + // sticking it into the document's URL. This may not be + // appropriate... + nsAutoString relURI(aAttributes[1]); + if (rdf_RequiresAbsoluteURI(relURI)) { + nsresult rv; + nsAutoCString uri; + + rv = mDocumentURL->Resolve(NS_ConvertUTF16toUTF8(aAttributes[1]), uri); + if (NS_FAILED(rv)) return rv; + + return gRDFService->GetResource(uri, aResource); + } + return gRDFService->GetResource(NS_ConvertUTF16toUTF8(aAttributes[1]), + aResource); + } + else if (localName == nsGkAtoms::nodeID) { + 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) { + nsresult rv; + rv = gRDFService->GetAnonymousResource(aResource); + if (NS_FAILED(rv)) { + return rv; + } + mNodeIDMap.Put(nodeID,*aResource); + } + return NS_OK; + } + + return NS_ERROR_FAILURE; +} + +nsresult +RDFContentSinkImpl::AddProperties(const char16_t** aAttributes, + nsIRDFResource* aSubject, + int32_t* aCount) +{ + if (aCount) + *aCount = 0; + + RefPtr 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 == nsGkAtoms::about || localName == nsGkAtoms::ID || + localName == nsGkAtoms::resource || localName == nsGkAtoms::nodeID) { + 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 == nsGkAtoms::parseType) { + if (nameSpaceURI.IsEmpty() || + nameSpaceURI.EqualsLiteral(RDF_NAMESPACE_URI) || + nameSpaceURI.EqualsLiteral(NC_NAMESPACE_URI)) { + continue; + } + } + + NS_ConvertUTF16toUTF8 propertyStr(nameSpaceURI); + propertyStr.Append(nsAtomCString(localName)); + + // Add the assertion to RDF + nsCOMPtr property; + gRDFService->GetResource(propertyStr, getter_AddRefs(property)); + + nsCOMPtr target; + gRDFService->GetLiteral(aAttributes[1], + getter_AddRefs(target)); + + mDataSource->Assert(aSubject, property, target, true); + } + return NS_OK; +} + +void +RDFContentSinkImpl::SetParseMode(const char16_t **aAttributes) +{ + RefPtr localName; + for (; *aAttributes; aAttributes += 2) { + const nsDependentSubstring& nameSpaceURI = + SplitExpatName(aAttributes[0], getter_AddRefs(localName)); + + if (localName == nsGkAtoms::parseType) { + nsDependentString v(aAttributes[1]); + + 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; + } + } + } +} + +//////////////////////////////////////////////////////////////////////// +// RDF-specific routines used to build the model + +nsresult +RDFContentSinkImpl::OpenRDF(const char16_t* aName) +{ + // ensure that we're actually reading RDF by making sure that the + // opening tag is , where "rdf:" corresponds to whatever + // they've declared the standard RDF namespace to be. + RefPtr localName; + const nsDependentSubstring& nameSpaceURI = + SplitExpatName(aName, getter_AddRefs(localName)); + + if (!nameSpaceURI.EqualsLiteral(RDF_NAMESPACE_URI) || + localName != nsGkAtoms::RDF) { + // MOZ_LOG(gLog, LogLevel::Info, + // ("rdfxml: expected RDF:RDF at line %d", + // aNode.GetSourceLineNumber())); + + return NS_ERROR_UNEXPECTED; + } + + PushContext(nullptr, mState, mParseMode); + mState = eRDFContentSinkState_InDocumentElement; + return NS_OK; +} + +nsresult +RDFContentSinkImpl::OpenObject(const char16_t* aName, + const char16_t** aAttributes) +{ + // an "object" non-terminal is either a "description", a "typed + // node", or a "container", so this change the content sink's + // state appropriately. + RefPtr localName; + const nsDependentSubstring& nameSpaceURI = + SplitExpatName(aName, getter_AddRefs(localName)); + + // Figure out the URI of this object, and create an RDF node for it. + nsCOMPtr 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. + bool isaTypedNode = true; + + if (nameSpaceURI.EqualsLiteral(RDF_NAMESPACE_URI)) { + isaTypedNode = false; + + if (localName == nsGkAtoms::Description) { + // it's a description + mState = eRDFContentSinkState_InDescriptionElement; + } + else if (localName == nsGkAtoms::Bag) { + // it's a bag container + InitContainer(kRDF_Bag, source); + mState = eRDFContentSinkState_InContainerElement; + } + else if (localName == nsGkAtoms::Seq) { + // it's a seq container + InitContainer(kRDF_Seq, source); + mState = eRDFContentSinkState_InContainerElement; + } + else if (localName == nsGkAtoms::Alt) { + // 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 = true; + } + } + + if (isaTypedNode) { + NS_ConvertUTF16toUTF8 typeStr(nameSpaceURI); + typeStr.Append(nsAtomCString(localName)); + + nsCOMPtr type; + nsresult rv = gRDFService->GetResource(typeStr, getter_AddRefs(type)); + if (NS_FAILED(rv)) return rv; + + rv = mDataSource->Assert(source, kRDF_type, type, true); + if (NS_FAILED(rv)) return rv; + + mState = eRDFContentSinkState_InDescriptionElement; + } + + AddProperties(aAttributes, source); + return NS_OK; +} + +nsresult +RDFContentSinkImpl::OpenProperty(const char16_t* aName, const char16_t** aAttributes) +{ + 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. + RefPtr localName; + const nsDependentSubstring& nameSpaceURI = + SplitExpatName(aName, getter_AddRefs(localName)); + + NS_ConvertUTF16toUTF8 propertyStr(nameSpaceURI); + propertyStr.Append(nsAtomCString(localName)); + + nsCOMPtr 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 target; + GetResourceAttribute(aAttributes, getter_AddRefs(target)); + + bool isAnonymous = 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. + int32_t 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, 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; +} + +nsresult +RDFContentSinkImpl::OpenMember(const char16_t* aName, + const char16_t** aAttributes) +{ + // ensure that we're actually reading a member element by making + // sure that the opening tag is , where "rdf:" corresponds + // to whatever they've declared the standard RDF namespace to be. + nsresult rv; + + RefPtr localName; + const nsDependentSubstring& nameSpaceURI = + SplitExpatName(aName, getter_AddRefs(localName)); + + if (!nameSpaceURI.EqualsLiteral(RDF_NAMESPACE_URI) || + localName != nsGkAtoms::li) { + MOZ_LOG(gLog, LogLevel::Error, + ("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 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(nullptr, mState, mParseMode); + mState = eRDFContentSinkState_InMemberElement; + SetParseMode(aAttributes); + + return NS_OK; +} + + +nsresult +RDFContentSinkImpl::OpenValue(const char16_t* aName, const char16_t** aAttributes) +{ + // 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); +} + +//////////////////////////////////////////////////////////////////////// +// namespace resolution +void +RDFContentSinkImpl::RegisterNamespaces(const char16_t **aAttributes) +{ + nsCOMPtr 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 char16_t* attr = aAttributes[0]; + const char16_t* 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 char16_t* endLocal = ++attr; + while (*endLocal && *endLocal != 0xFFFF) { + ++endLocal; + } + nsDependentSubstring lname(attr, endLocal); + RefPtr preferred = NS_Atomize(lname); + if (preferred == nsGkAtoms::xmlns) { + preferred = nullptr; + } + sink->AddNameSpace(preferred, nsDependentString(aAttributes[1])); + } +} + +//////////////////////////////////////////////////////////////////////// +// Qualified name resolution + +const nsDependentSubstring +RDFContentSinkImpl::SplitExpatName(const char16_t *aExpatName, + nsAtom **aLocalName) +{ + /** + * Expat can send the following: + * localName + * namespaceURIlocalName + * namespaceURIlocalNameprefix + * + * and we use 0xFFFF for the . + * + */ + + const char16_t *uriEnd = aExpatName; + const char16_t *nameStart = aExpatName; + const char16_t *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_Atomize(Substring(nameStart, pos)).take(); + return nameSpaceURI; +} + +nsresult +RDFContentSinkImpl::InitContainer(nsIRDFResource* aContainerType, nsIRDFResource* aContainer) +{ + // 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; + + bool isContainer; + rv = (gRDFContainerUtils->*(info->mTestFn))(mDataSource, aContainer, &isContainer); + if (isContainer) { + rv = ReinitContainer(aContainerType, aContainer); + } + else { + rv = (gRDFContainerUtils->*(info->mMakeFn))(mDataSource, aContainer, nullptr); + } + return rv; + } + + NS_NOTREACHED("not an RDF container type"); + return NS_ERROR_FAILURE; +} + + + +nsresult +RDFContentSinkImpl::ReinitContainer(nsIRDFResource* aContainerType, nsIRDFResource* aContainer) +{ + // 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 one; + rv = gRDFService->GetLiteral(u"1", getter_AddRefs(one)); + if (NS_FAILED(rv)) return rv; + + // Re-initialize the 'nextval' property + nsCOMPtr nextval; + rv = mDataSource->GetTarget(aContainer, kRDF_nextVal, 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, true); + NS_ASSERTION(NS_SUCCEEDED(rv), "unable to mark container as such"); + if (NS_FAILED(rv)) return rv; + + return NS_OK; +} + +//////////////////////////////////////////////////////////////////////// +// Content stack management + +nsIRDFResource* +RDFContentSinkImpl::GetContextElement(int32_t ancestor /* = 0 */) +{ + if ((nullptr == mContextStack) || + (uint32_t(ancestor) >= mContextStack->Length())) { + return nullptr; + } + + return mContextStack->ElementAt( + mContextStack->Length()-ancestor-1).mResource; +} + +int32_t +RDFContentSinkImpl::PushContext(nsIRDFResource *aResource, + RDFContentSinkState aState, + RDFContentSinkParseMode aParseMode) +{ + if (! mContextStack) { + mContextStack = new AutoTArray(); + if (! mContextStack) + return 0; + } + + RDFContextStackElement* e = mContextStack->AppendElement(); + if (! e) + return mContextStack->Length(); + + e->mResource = aResource; + e->mState = aState; + e->mParseMode = aParseMode; + + return mContextStack->Length(); +} + +nsresult +RDFContentSinkImpl::PopContext(nsIRDFResource *&aResource, + RDFContentSinkState &aState, + RDFContentSinkParseMode &aParseMode) +{ + if ((nullptr == mContextStack) || + (mContextStack->IsEmpty())) { + return NS_ERROR_NULL_POINTER; + } + + uint32_t i = mContextStack->Length() - 1; + RDFContextStackElement &e = mContextStack->ElementAt(i); + + aResource = e.mResource; + NS_IF_ADDREF(aResource); + aState = e.mState; + aParseMode = e.mParseMode; + + mContextStack->RemoveElementAt(i); + return NS_OK; +} + + +//////////////////////////////////////////////////////////////////////// + +nsresult +NS_NewRDFContentSink(nsIRDFContentSink** aResult) +{ + NS_PRECONDITION(aResult != nullptr, "null ptr"); + if (! aResult) + return NS_ERROR_NULL_POINTER; + + RDFContentSinkImpl* sink = new RDFContentSinkImpl(); + if (! sink) + return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(sink); + *aResult = sink; + return NS_OK; +} diff --git a/rdf/base/nsRDFResource.cpp b/rdf/base/nsRDFResource.cpp new file mode 100644 index 000000000000..46e078a4cc13 --- /dev/null +++ b/rdf/base/nsRDFResource.cpp @@ -0,0 +1,220 @@ +/* -*- Mode: C++; tab-width: 2; 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/. */ + +#include "nsRDFResource.h" +#include "nsIServiceManager.h" +#include "nsIRDFDelegateFactory.h" +#include "nsIRDFService.h" +#include "nsRDFCID.h" +#include "mozilla/Logging.h" +#include "nsComponentManagerUtils.h" +#include "nsServiceManagerUtils.h" + +static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); + +nsIRDFService* nsRDFResource::gRDFService = nullptr; +nsrefcnt nsRDFResource::gRDFServiceRefCnt = 0; + +//////////////////////////////////////////////////////////////////////////////// + +nsRDFResource::nsRDFResource(void) + : mDelegates(nullptr) +{ +} + +nsRDFResource::~nsRDFResource(void) +{ + // Release all of the delegate objects + while (mDelegates) { + DelegateEntry* doomed = mDelegates; + mDelegates = mDelegates->mNext; + delete doomed; + } + + if (!gRDFService) + return; + + gRDFService->UnregisterResource(this); + + if (--gRDFServiceRefCnt == 0) + NS_RELEASE(gRDFService); +} + +NS_IMPL_ISUPPORTS(nsRDFResource, nsIRDFResource, nsIRDFNode) + +//////////////////////////////////////////////////////////////////////////////// +// nsIRDFNode methods: + +NS_IMETHODIMP +nsRDFResource::EqualsNode(nsIRDFNode* aNode, bool* aResult) +{ + NS_PRECONDITION(aNode != nullptr, "null ptr"); + if (! aNode) + return NS_ERROR_NULL_POINTER; + + nsresult rv; + nsIRDFResource* resource; + rv = aNode->QueryInterface(NS_GET_IID(nsIRDFResource), (void**)&resource); + if (NS_SUCCEEDED(rv)) { + *aResult = (static_cast(this) == resource); + NS_RELEASE(resource); + return NS_OK; + } + if (rv == NS_NOINTERFACE) { + *aResult = false; + return NS_OK; + } + + return rv; +} + +//////////////////////////////////////////////////////////////////////////////// +// nsIRDFResource methods: + +NS_IMETHODIMP +nsRDFResource::Init(const char* aURI) +{ + NS_PRECONDITION(aURI != nullptr, "null ptr"); + if (! aURI) + return NS_ERROR_NULL_POINTER; + + mURI = aURI; + + if (gRDFServiceRefCnt++ == 0) { + nsresult rv = CallGetService(kRDFServiceCID, &gRDFService); + if (NS_FAILED(rv)) return rv; + } + + // don't replace an existing resource with the same URI automatically + return gRDFService->RegisterResource(this, true); +} + +NS_IMETHODIMP +nsRDFResource::GetValue(char* *aURI) +{ + NS_ASSERTION(aURI, "Null out param."); + + *aURI = ToNewCString(mURI); + + if (!*aURI) + return NS_ERROR_OUT_OF_MEMORY; + + return NS_OK; +} + +NS_IMETHODIMP +nsRDFResource::GetValueUTF8(nsACString& aResult) +{ + aResult = mURI; + return NS_OK; +} + +NS_IMETHODIMP +nsRDFResource::GetValueConst(const char** aURI) +{ + *aURI = mURI.get(); + return NS_OK; +} + +NS_IMETHODIMP +nsRDFResource::EqualsString(const char* aURI, bool* aResult) +{ + NS_PRECONDITION(aURI != nullptr, "null ptr"); + if (! aURI) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(aResult, "null ptr"); + + *aResult = mURI.Equals(aURI); + return NS_OK; +} + +NS_IMETHODIMP +nsRDFResource::GetDelegate(const char* aKey, REFNSIID aIID, void** aResult) +{ + NS_PRECONDITION(aKey != nullptr, "null ptr"); + if (! aKey) + return NS_ERROR_NULL_POINTER; + + nsresult rv; + *aResult = nullptr; + + DelegateEntry* entry = mDelegates; + while (entry) { + if (entry->mKey.Equals(aKey)) { + rv = entry->mDelegate->QueryInterface(aIID, aResult); + return rv; + } + + entry = entry->mNext; + } + + // Construct a ContractID of the form "@mozilla.org/rdf/delegate/[key]/[scheme];1 + nsAutoCString contractID(NS_RDF_DELEGATEFACTORY_CONTRACTID_PREFIX); + contractID.Append(aKey); + contractID.AppendLiteral("&scheme="); + + int32_t i = mURI.FindChar(':'); + contractID += StringHead(mURI, i); + + nsCOMPtr delegateFactory = + do_CreateInstance(contractID.get(), &rv); + if (NS_FAILED(rv)) return rv; + + rv = delegateFactory->CreateDelegate(this, aKey, aIID, aResult); + if (NS_FAILED(rv)) return rv; + + // Okay, we've successfully created a delegate. Let's remember it. + entry = new DelegateEntry; + if (! entry) { + NS_RELEASE(*reinterpret_cast(aResult)); + return NS_ERROR_OUT_OF_MEMORY; + } + + entry->mKey = aKey; + entry->mDelegate = do_QueryInterface(*reinterpret_cast(aResult), &rv); + if (NS_FAILED(rv)) { + NS_ERROR("nsRDFResource::GetDelegate(): can't QI to nsISupports!"); + + delete entry; + NS_RELEASE(*reinterpret_cast(aResult)); + return NS_ERROR_FAILURE; + } + + entry->mNext = mDelegates; + + mDelegates = entry; + + return NS_OK; +} + +NS_IMETHODIMP +nsRDFResource::ReleaseDelegate(const char* aKey) +{ + NS_PRECONDITION(aKey != nullptr, "null ptr"); + if (! aKey) + return NS_ERROR_NULL_POINTER; + + DelegateEntry* entry = mDelegates; + DelegateEntry** link = &mDelegates; + + while (entry) { + if (entry->mKey.Equals(aKey)) { + *link = entry->mNext; + delete entry; + return NS_OK; + } + + link = &(entry->mNext); + entry = entry->mNext; + } + + NS_WARNING("nsRDFResource::ReleaseDelegate() no delegate found"); + return NS_OK; +} + + + +//////////////////////////////////////////////////////////////////////////////// diff --git a/rdf/base/nsRDFResource.h b/rdf/base/nsRDFResource.h new file mode 100644 index 000000000000..ace7060eb04e --- /dev/null +++ b/rdf/base/nsRDFResource.h @@ -0,0 +1,59 @@ +/* -*- Mode: C++; tab-width: 2; 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/. */ + +#ifndef nsRDFResource_h__ +#define nsRDFResource_h__ + +#include "nsCOMPtr.h" +#include "nsIRDFNode.h" +#include "nsIRDFResource.h" +#include "nscore.h" +#include "nsString.h" +#include "rdf.h" + +class nsIRDFService; + +/** + * This simple base class implements nsIRDFResource, and can be used as a + * superclass for more sophisticated resource implementations. + */ +class nsRDFResource : public nsIRDFResource { +public: + + NS_DECL_THREADSAFE_ISUPPORTS + + // nsIRDFNode methods: + NS_IMETHOD EqualsNode(nsIRDFNode* aNode, bool* aResult) override; + + // nsIRDFResource methods: + NS_IMETHOD Init(const char* aURI) override; + NS_IMETHOD GetValue(char* *aURI) override; + NS_IMETHOD GetValueUTF8(nsACString& aResult) override; + NS_IMETHOD GetValueConst(const char** aURI) override; + NS_IMETHOD EqualsString(const char* aURI, bool* aResult) override; + NS_IMETHOD GetDelegate(const char* aKey, REFNSIID aIID, void** aResult) override; + NS_IMETHOD ReleaseDelegate(const char* aKey) override; + + // nsRDFResource methods: + nsRDFResource(void); + +protected: + virtual ~nsRDFResource(void); + static nsIRDFService* gRDFService; + static nsrefcnt gRDFServiceRefCnt; + +protected: + nsCString mURI; + + struct DelegateEntry { + nsCString mKey; + nsCOMPtr mDelegate; + DelegateEntry* mNext; + }; + + DelegateEntry* mDelegates; +}; + +#endif // nsRDFResource_h__ diff --git a/rdf/base/nsRDFService.cpp b/rdf/base/nsRDFService.cpp new file mode 100644 index 000000000000..842b5eb10de0 --- /dev/null +++ b/rdf/base/nsRDFService.cpp @@ -0,0 +1,1540 @@ +/* -*- 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 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 "nsAtom.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 "nsNetUtil.h" +#include "nsIURI.h" +#include "PLDHashTable.h" +#include "plhash.h" +#include "plstr.h" +#include "mozilla/Logging.h" +#include "prprf.h" +#include "rdf.h" +#include "nsCRT.h" +#include "nsCRTGlue.h" +#include "mozilla/HashFunctions.h" +#include "mozilla/IntegerPrintfMacros.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 malloc(size); +} + +static void +DataSourceFreeTable(void *pool, void *item) +{ + free(item); +} + +static PLHashEntry * +DataSourceAllocEntry(void *pool, const void *key) +{ + return (PLHashEntry*) malloc(sizeof(PLHashEntry)); +} + +static void +DataSourceFreeEntry(void *pool, PLHashEntry *he, unsigned flag) +{ + if (flag == HT_FREE_ENTRY) { + PL_strfree((char*) he->key); + 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(key)); + } + + static bool + MatchEntry(const PLDHashEntryHdr *hdr, const void *key) + { + const ResourceHashEntry *entry = + static_cast(hdr); + + return 0 == nsCRT::strcmp(static_cast(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(key)); + } + + static bool + MatchEntry(const PLDHashEntryHdr *hdr, const void *key) + { + const LiteralHashEntry *entry = + static_cast(hdr); + + return 0 == nsCRT::strcmp(static_cast(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(key)); + } + + static bool + MatchEntry(const PLDHashEntryHdr *hdr, const void *key) + { + const IntHashEntry *entry = + static_cast(hdr); + + return *static_cast(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(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(hdr); + + return *static_cast(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 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(key); + return HashBytes(data->mBytes, data->mLength); + } + + static bool + MatchEntry(const PLDHashEntryHdr *hdr, const void *key) + { + const BlobHashEntry *entry = + static_cast(hdr); + + const BlobImpl::Data *left = &entry->mBlob->mData; + + const BlobImpl::Data *right = + static_cast(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(reinterpret_cast(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::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(static_cast(objectPtr) + objectSize); + nsCharTraits::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(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(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(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(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 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 nsCString& 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(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 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(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(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(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(aBytes) }; + + PLDHashEntryHdr *hdr = mBlobs.Search(&key); + if (hdr) { + BlobHashEntry *entry = static_cast(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(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(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; + + nsAutoCString uri; + rv = aDataSource->GetURI(uri); + if (NS_FAILED(rv)) return rv; + + PLHashEntry** hep = + PL_HashTableRawLookup(mNamedDataSources, + (*mNamedDataSources->keyHash)(uri.get()), + uri.get()); + + 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, uri.get())); + + (*hep)->value = aDataSource; + } + else { + const char* key = PL_strdup(uri.get()); + if (! key) + return NS_ERROR_OUT_OF_MEMORY; + + PL_HashTableAdd(mNamedDataSources, key, aDataSource); + + MOZ_LOG(gLog, LogLevel::Debug, + ("rdfserv register-datasource [%p] %s", + aDataSource, uri.get())); + + // 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; + + nsAutoCString uri; + rv = aDataSource->GetURI(uri); + if (NS_FAILED(rv)) return rv; + + //NS_ASSERTION(uri != nullptr, "datasource has no URI"); + if (uri.IsVoid()) + return NS_ERROR_UNEXPECTED; + + PLHashEntry** hep = + PL_HashTableRawLookup(mNamedDataSources, + (*mNamedDataSources->keyHash)(uri.get()), + uri.get()); + + // 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, uri.get())); + + 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 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(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 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 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 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(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, NS_ConvertUTF16toUTF8(value).get())); + + 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, NS_ConvertUTF16toUTF8(value).get())); + + 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(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(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] %" PRId64, + 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] %" PRId64, + 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(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; +} diff --git a/rdf/base/nsRDFService.h b/rdf/base/nsRDFService.h new file mode 100644 index 000000000000..19ef355edb00 --- /dev/null +++ b/rdf/base/nsRDFService.h @@ -0,0 +1,66 @@ +/* -*- 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/. */ + +#ifndef nsRDFService_h__ +#define nsRDFService_h__ + +#include "nsIRDFService.h" +#include "nsWeakReference.h" +#include "nsIFactory.h" +#include "nsCOMPtr.h" +#include "PLDHashTable.h" +#include "nsString.h" + +struct PLHashTable; +class nsIRDFLiteral; +class nsIRDFInt; +class nsIRDFDate; +class BlobImpl; + +class RDFServiceImpl final : public nsIRDFService, + public nsSupportsWeakReference +{ +protected: + PLHashTable* mNamedDataSources; + PLDHashTable mResources; + PLDHashTable mLiterals; + PLDHashTable mInts; + PLDHashTable mDates; + PLDHashTable mBlobs; + + nsCString mLastURIPrefix; + nsCOMPtr mLastFactory; + nsCOMPtr mDefaultResourceFactory; + + RDFServiceImpl(); + nsresult Init(); + virtual ~RDFServiceImpl(); + +public: + static RDFServiceImpl *gRDFService NS_VISIBILITY_HIDDEN; + static nsresult CreateSingleton(nsISupports* aOuter, + const nsIID& aIID, void **aResult); + + // nsISupports + NS_DECL_ISUPPORTS + + // nsIRDFService + NS_DECL_NSIRDFSERVICE + + // Implementation methods + nsresult RegisterLiteral(nsIRDFLiteral* aLiteral); + nsresult UnregisterLiteral(nsIRDFLiteral* aLiteral); + nsresult RegisterInt(nsIRDFInt* aInt); + nsresult UnregisterInt(nsIRDFInt* aInt); + nsresult RegisterDate(nsIRDFDate* aDate); + nsresult UnregisterDate(nsIRDFDate* aDate); + nsresult RegisterBlob(BlobImpl* aBlob); + nsresult UnregisterBlob(BlobImpl* aBlob); + + nsresult GetDataSource(const char *aURI, bool aBlock, nsIRDFDataSource **aDataSource ); +}; + +#endif // nsRDFService_h__ diff --git a/rdf/base/nsRDFXMLDataSource.cpp b/rdf/base/nsRDFXMLDataSource.cpp new file mode 100644 index 000000000000..5d4200a049ad --- /dev/null +++ b/rdf/base/nsRDFXMLDataSource.cpp @@ -0,0 +1,1173 @@ +/* -*- 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/. */ + +/* + + A data source that can read itself from and write itself to an + RDF/XML stream. + + For more information on the RDF/XML syntax, + see http://www.w3.org/TR/REC-rdf-syntax/. + + This code is based on the final W3C Recommendation, + http://www.w3.org/TR/1999/REC-rdf-syntax-19990222. + + + TO DO + ----- + + 1) Right now, the only kind of stream data sources that are _really_ + writable are "file:" URIs. (In fact, _all_ "file:" URIs are + writable, modulo file system permissions; this may lead to some + surprising behavior.) Eventually, it'd be great if we could open + an arbitrary nsIOutputStream on *any* URL, and Netlib could just + do the magic. + + 2) Implement a more terse output for "typed" nodes; that is, instead + of "RDF:Description type='ns:foo'", just output "ns:foo". + + 3) When re-serializing, we "cheat" for Descriptions that talk about + inline resources (i.e.., using the `ID' attribute specified in + [6.21]). Instead of writing an `ID="foo"' for the first instance, + and then `about="#foo"' for each subsequent instance, we just + _always_ write `about="#foo"'. + + We do this so that we can handle the case where an RDF container + has been assigned arbitrary properties: the spec says we can't + dangle the attributes directly off the container, so we need to + refer to it. Of course, with a little cleverness, we could fix + this. But who cares? + + 4) When re-serializing containers. We have to cheat on some + containers, and use an illegal "about=" construct. We do this to + handle containers that have been assigned URIs outside of the + local document. + + + Logging + ------- + + To turn on logging for this module, set + + MOZ_LOG=nsRDFXMLDataSource:5 + + */ + +#include "nsIFileStreams.h" +#include "nsIOutputStream.h" +#include "nsIFile.h" +#include "nsIFileChannel.h" +#include "nsIDTD.h" +#include "nsIRDFPurgeableDataSource.h" +#include "nsIInputStream.h" +#include "nsIOutputStream.h" +#include "nsIRDFContainerUtils.h" +#include "nsIRDFNode.h" +#include "nsIRDFRemoteDataSource.h" +#include "nsIRDFService.h" +#include "nsIRDFXMLParser.h" +#include "nsIRDFXMLSerializer.h" +#include "nsIRDFXMLSink.h" +#include "nsIRDFXMLSource.h" +#include "nsISafeOutputStream.h" +#include "nsIServiceManager.h" +#include "nsIStreamListener.h" +#include "nsIURL.h" +#include "nsIFileURL.h" +#include "nsISafeOutputStream.h" +#include "nsIChannel.h" +#include "nsRDFCID.h" +#include "nsRDFBaseDataSources.h" +#include "nsCOMArray.h" +#include "nsString.h" +#include "plstr.h" +#include "prio.h" +#include "prthread.h" +#include "rdf.h" +#include "rdfutil.h" +#include "mozilla/Logging.h" +#include "nsNameSpaceMap.h" +#include "nsCRT.h" +#include "nsCycleCollectionParticipant.h" +#include "nsIScriptSecurityManager.h" +#include "nsIChannelEventSink.h" +#include "nsIAsyncVerifyRedirectCallback.h" +#include "nsNetUtil.h" +#include "nsIContentPolicy.h" +#include "nsContentUtils.h" + +#include "rdfIDataSource.h" + +//---------------------------------------------------------------------- +// +// RDFXMLDataSourceImpl +// + +class RDFXMLDataSourceImpl : public nsIRDFDataSource, + public nsIRDFRemoteDataSource, + public nsIRDFXMLSink, + public nsIRDFXMLSource, + public nsIStreamListener, + public rdfIDataSource, + public nsIInterfaceRequestor, + public nsIChannelEventSink +{ +protected: + enum LoadState { + eLoadState_Unloaded, + eLoadState_Pending, + eLoadState_Loading, + eLoadState_Loaded + }; + + nsCOMPtr mInner; + bool mIsWritable; // true if the document can be written back + bool mIsDirty; // true if the document should be written back + LoadState mLoadState; // what we're doing now + nsCOMArray mObservers; + nsCOMPtr mURL; + nsCOMPtr mListener; + nsNameSpaceMap mNameSpaces; + + // pseudo-constants + static int32_t gRefCnt; + static nsIRDFService* gRDFService; + + static mozilla::LazyLogModule gLog; + + nsresult Init(); + RDFXMLDataSourceImpl(void); + virtual ~RDFXMLDataSourceImpl(void); + nsresult rdfXMLFlush(nsIURI *aURI); + + friend nsresult + NS_NewRDFXMLDataSource(nsIRDFDataSource** aResult); + + inline bool IsLoading() { + return (mLoadState == eLoadState_Pending) || + (mLoadState == eLoadState_Loading); + } + +public: + // nsISupports + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(RDFXMLDataSourceImpl, + nsIRDFDataSource) + + // nsIRDFDataSource + NS_IMETHOD GetURI(nsACString& aURI) override; + + NS_IMETHOD GetSource(nsIRDFResource* property, + nsIRDFNode* target, + bool tv, + nsIRDFResource** source) override { + return mInner->GetSource(property, target, tv, source); + } + + NS_IMETHOD GetSources(nsIRDFResource* property, + nsIRDFNode* target, + bool tv, + nsISimpleEnumerator** sources) override { + return mInner->GetSources(property, target, tv, sources); + } + + NS_IMETHOD GetTarget(nsIRDFResource* source, + nsIRDFResource* property, + bool tv, + nsIRDFNode** target) override { + return mInner->GetTarget(source, property, tv, target); + } + + NS_IMETHOD GetTargets(nsIRDFResource* source, + nsIRDFResource* property, + bool tv, + nsISimpleEnumerator** targets) override { + return mInner->GetTargets(source, property, tv, targets); + } + + NS_IMETHOD Assert(nsIRDFResource* aSource, + nsIRDFResource* aProperty, + nsIRDFNode* aTarget, + bool tv) override; + + NS_IMETHOD Unassert(nsIRDFResource* source, + nsIRDFResource* property, + nsIRDFNode* target) override; + + NS_IMETHOD Change(nsIRDFResource* aSource, + nsIRDFResource* aProperty, + nsIRDFNode* aOldTarget, + nsIRDFNode* aNewTarget) override; + + NS_IMETHOD Move(nsIRDFResource* aOldSource, + nsIRDFResource* aNewSource, + nsIRDFResource* aProperty, + nsIRDFNode* aTarget) override; + + NS_IMETHOD HasAssertion(nsIRDFResource* source, + nsIRDFResource* property, + nsIRDFNode* target, + bool tv, + bool* hasAssertion) override { + return mInner->HasAssertion(source, property, target, tv, hasAssertion); + } + + NS_IMETHOD AddObserver(nsIRDFObserver* aObserver) override { + return mInner->AddObserver(aObserver); + } + + NS_IMETHOD RemoveObserver(nsIRDFObserver* aObserver) override { + return mInner->RemoveObserver(aObserver); + } + + NS_IMETHOD HasArcIn(nsIRDFNode *aNode, nsIRDFResource *aArc, bool *_retval) override { + return mInner->HasArcIn(aNode, aArc, _retval); + } + + NS_IMETHOD HasArcOut(nsIRDFResource *aSource, nsIRDFResource *aArc, bool *_retval) override { + return mInner->HasArcOut(aSource, aArc, _retval); + } + + NS_IMETHOD ArcLabelsIn(nsIRDFNode* node, + nsISimpleEnumerator** labels) override { + return mInner->ArcLabelsIn(node, labels); + } + + NS_IMETHOD ArcLabelsOut(nsIRDFResource* source, + nsISimpleEnumerator** labels) override { + return mInner->ArcLabelsOut(source, labels); + } + + NS_IMETHOD GetAllResources(nsISimpleEnumerator** aResult) override { + return mInner->GetAllResources(aResult); + } + + NS_IMETHOD GetAllCmds(nsIRDFResource* source, + nsISimpleEnumerator/**/** commands) override { + return mInner->GetAllCmds(source, commands); + } + + NS_IMETHOD IsCommandEnabled(nsISupports* aSources, + nsIRDFResource* aCommand, + nsISupports* aArguments, + bool* aResult) override { + return NS_ERROR_NOT_IMPLEMENTED; + } + + NS_IMETHOD DoCommand(nsISupports* aSources, + nsIRDFResource* aCommand, + nsISupports* aArguments) override { + return NS_ERROR_NOT_IMPLEMENTED; + } + + NS_IMETHOD BeginUpdateBatch() override { + return mInner->BeginUpdateBatch(); + } + + NS_IMETHOD EndUpdateBatch() override { + return mInner->EndUpdateBatch(); + } + + // nsIRDFRemoteDataSource interface + NS_DECL_NSIRDFREMOTEDATASOURCE + + // nsIRDFXMLSink interface + NS_DECL_NSIRDFXMLSINK + + // nsIRDFXMLSource interface + NS_DECL_NSIRDFXMLSOURCE + + // nsIRequestObserver + NS_DECL_NSIREQUESTOBSERVER + + // nsIStreamListener + NS_DECL_NSISTREAMLISTENER + + // nsIInterfaceRequestor + NS_DECL_NSIINTERFACEREQUESTOR + + // nsIChannelEventSink + NS_DECL_NSICHANNELEVENTSINK + + // rdfIDataSource + NS_IMETHOD VisitAllSubjects(rdfITripleVisitor *aVisitor) override { + nsresult rv; + nsCOMPtr rdfds = do_QueryInterface(mInner, &rv); + if (NS_FAILED(rv)) return rv; + return rdfds->VisitAllSubjects(aVisitor); + } + + NS_IMETHOD VisitAllTriples(rdfITripleVisitor *aVisitor) override { + nsresult rv; + nsCOMPtr rdfds = do_QueryInterface(mInner, &rv); + if (NS_FAILED(rv)) return rv; + return rdfds->VisitAllTriples(aVisitor); + } + + // Implementation methods + bool + MakeQName(nsIRDFResource* aResource, + nsString& property, + nsString& nameSpacePrefix, + nsString& nameSpaceURI); + + nsresult + SerializeAssertion(nsIOutputStream* aStream, + nsIRDFResource* aResource, + nsIRDFResource* aProperty, + nsIRDFNode* aValue); + + nsresult + SerializeProperty(nsIOutputStream* aStream, + nsIRDFResource* aResource, + nsIRDFResource* aProperty); + + bool + IsContainerProperty(nsIRDFResource* aProperty); + + nsresult + SerializeDescription(nsIOutputStream* aStream, + nsIRDFResource* aResource); + + nsresult + SerializeMember(nsIOutputStream* aStream, + nsIRDFResource* aContainer, + nsIRDFNode* aMember); + + nsresult + SerializeContainer(nsIOutputStream* aStream, + nsIRDFResource* aContainer); + + nsresult + SerializePrologue(nsIOutputStream* aStream); + + nsresult + SerializeEpilogue(nsIOutputStream* aStream); + + bool + IsA(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource, nsIRDFResource* aType); + +protected: + nsresult + BlockingParse(nsIURI* aURL, nsIStreamListener* aConsumer); +}; + +int32_t RDFXMLDataSourceImpl::gRefCnt = 0; +nsIRDFService* RDFXMLDataSourceImpl::gRDFService; + +mozilla::LazyLogModule RDFXMLDataSourceImpl::gLog("nsRDFXMLDataSource"); + +static const char kFileURIPrefix[] = "file:"; +static const char kResourceURIPrefix[] = "resource:"; + + +//---------------------------------------------------------------------- + +nsresult +NS_NewRDFXMLDataSource(nsIRDFDataSource** aResult) +{ + NS_PRECONDITION(aResult != nullptr, "null ptr"); + if (! aResult) + return NS_ERROR_NULL_POINTER; + + RDFXMLDataSourceImpl* datasource = new RDFXMLDataSourceImpl(); + if (! datasource) + return NS_ERROR_OUT_OF_MEMORY; + + nsresult rv; + rv = datasource->Init(); + + if (NS_FAILED(rv)) { + delete datasource; + return rv; + } + + NS_ADDREF(datasource); + *aResult = datasource; + return NS_OK; +} + + +RDFXMLDataSourceImpl::RDFXMLDataSourceImpl(void) + : mIsWritable(true), + mIsDirty(false), + mLoadState(eLoadState_Unloaded) +{ +} + + +nsresult +RDFXMLDataSourceImpl::Init() +{ + nsresult rv; + NS_DEFINE_CID(kRDFInMemoryDataSourceCID, NS_RDFINMEMORYDATASOURCE_CID); + mInner = do_CreateInstance(kRDFInMemoryDataSourceCID, &rv); + if (NS_FAILED(rv)) return rv; + + if (gRefCnt++ == 0) { + NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); + rv = CallGetService(kRDFServiceCID, &gRDFService); + + NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get RDF service"); + if (NS_FAILED(rv)) return rv; + } + + return NS_OK; +} + + +RDFXMLDataSourceImpl::~RDFXMLDataSourceImpl(void) +{ + // Unregister first so that nobody else tries to get us. + (void) gRDFService->UnregisterDataSource(this); + + // Now flush contents + (void) Flush(); + + // Release RDF/XML sink observers + mObservers.Clear(); + + if (--gRefCnt == 0) + NS_IF_RELEASE(gRDFService); +} + +NS_IMPL_CYCLE_COLLECTION_CLASS(RDFXMLDataSourceImpl) + +NS_IMPL_CYCLE_COLLECTION_UNLINK_0(RDFXMLDataSourceImpl) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(RDFXMLDataSourceImpl) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mInner) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + +NS_IMPL_CYCLE_COLLECTING_ADDREF(RDFXMLDataSourceImpl) +NS_IMPL_CYCLE_COLLECTING_RELEASE(RDFXMLDataSourceImpl) + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(RDFXMLDataSourceImpl) + NS_INTERFACE_MAP_ENTRY(nsIRDFDataSource) + NS_INTERFACE_MAP_ENTRY(nsIRDFRemoteDataSource) + NS_INTERFACE_MAP_ENTRY(nsIRDFXMLSink) + NS_INTERFACE_MAP_ENTRY(nsIRDFXMLSource) + NS_INTERFACE_MAP_ENTRY(nsIRequestObserver) + NS_INTERFACE_MAP_ENTRY(nsIStreamListener) + NS_INTERFACE_MAP_ENTRY(rdfIDataSource) + NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor) + NS_INTERFACE_MAP_ENTRY(nsIChannelEventSink) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRDFDataSource) +NS_INTERFACE_MAP_END + +// nsIInterfaceRequestor +NS_IMETHODIMP +RDFXMLDataSourceImpl::GetInterface(const nsIID& aIID, void** aSink) +{ + return QueryInterface(aIID, aSink); +} + +nsresult +RDFXMLDataSourceImpl::BlockingParse(nsIURI* aURL, nsIStreamListener* aConsumer) +{ + nsresult rv; + + // XXX I really hate the way that we're spoon-feeding this stuff + // to the parser: it seems like this is something that netlib + // should be able to do by itself. + + nsCOMPtr channel; + + // Null LoadGroup ? + rv = NS_NewChannel(getter_AddRefs(channel), + aURL, + nsContentUtils::GetSystemPrincipal(), + nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, + nsIContentPolicy::TYPE_OTHER); + + if (NS_FAILED(rv)) return rv; + nsCOMPtr in; + rv = channel->Open2(getter_AddRefs(in)); + + // Report success if the file doesn't exist, but propagate other errors. + if (rv == NS_ERROR_FILE_NOT_FOUND) return NS_OK; + if (NS_FAILED(rv)) return rv; + + if (! in) { + NS_ERROR("no input stream"); + return NS_ERROR_FAILURE; + } + + // Wrap the channel's input stream in a buffered stream to ensure that + // ReadSegments is implemented (which OnDataAvailable expects). + nsCOMPtr bufStream; + rv = NS_NewBufferedInputStream(getter_AddRefs(bufStream), in.forget(), + 4096 /* buffer size */); + if (NS_FAILED(rv)) return rv; + + // Notify load observers + int32_t i; + for (i = mObservers.Count() - 1; i >= 0; --i) { + // Make sure to hold a strong reference to the observer so + // that it doesn't go away in this call if it removes itself + // as an observer + nsCOMPtr obs = mObservers[i]; + + if (obs) { + obs->OnBeginLoad(this); + } + } + + rv = aConsumer->OnStartRequest(channel, nullptr); + + uint64_t offset = 0; + while (NS_SUCCEEDED(rv)) { + // Skip ODA if the channel is canceled + channel->GetStatus(&rv); + if (NS_FAILED(rv)) + break; + + uint64_t avail; + if (NS_FAILED(rv = bufStream->Available(&avail))) + break; // error + + if (avail == 0) + break; // eof + + if (avail > UINT32_MAX) + avail = UINT32_MAX; + + rv = aConsumer->OnDataAvailable(channel, nullptr, bufStream, offset, (uint32_t)avail); + if (NS_SUCCEEDED(rv)) + offset += avail; + } + + if (NS_FAILED(rv)) + channel->Cancel(rv); + + channel->GetStatus(&rv); + aConsumer->OnStopRequest(channel, nullptr, rv); + + // Notify load observers + for (i = mObservers.Count() - 1; i >= 0; --i) { + // Make sure to hold a strong reference to the observer so + // that it doesn't go away in this call if it removes itself + // as an observer + nsCOMPtr obs = mObservers[i]; + + if (obs) { + if (NS_FAILED(rv)) + obs->OnError(this, rv, nullptr); + + obs->OnEndLoad(this); + } + } + + return rv; +} + +NS_IMETHODIMP +RDFXMLDataSourceImpl::GetLoaded(bool* _result) +{ + *_result = (mLoadState == eLoadState_Loaded); + return NS_OK; +} + +NS_IMETHODIMP +RDFXMLDataSourceImpl::Init(const char* uri) +{ + NS_PRECONDITION(mInner != nullptr, "not initialized"); + if (! mInner) + return NS_ERROR_OUT_OF_MEMORY; + + nsresult rv; + + rv = NS_NewURI(getter_AddRefs(mURL), nsDependentCString(uri)); + if (NS_FAILED(rv)) return rv; + + // XXX this is a hack: any "file:" URI is considered writable. All + // others are considered read-only. + if ((PL_strncmp(uri, kFileURIPrefix, sizeof(kFileURIPrefix) - 1) != 0) && + (PL_strncmp(uri, kResourceURIPrefix, sizeof(kResourceURIPrefix) - 1) != 0)) { + mIsWritable = false; + } + + rv = gRDFService->RegisterDataSource(this, false); + if (NS_FAILED(rv)) return rv; + + return NS_OK; +} + + +NS_IMETHODIMP +RDFXMLDataSourceImpl::GetURI(nsACString& aURI) +{ + if (!mURL) { + aURI.SetIsVoid(true); + return NS_OK; + } + + return mURL->GetSpec(aURI); +} + +NS_IMETHODIMP +RDFXMLDataSourceImpl::Assert(nsIRDFResource* aSource, + nsIRDFResource* aProperty, + nsIRDFNode* aTarget, + bool aTruthValue) +{ + // We don't accept assertions unless we're writable (except in the + // case that we're actually _reading_ the datasource in). + nsresult rv; + + if (IsLoading()) { + bool hasAssertion = false; + + nsCOMPtr gcable = do_QueryInterface(mInner); + if (gcable) { + rv = gcable->Mark(aSource, aProperty, aTarget, aTruthValue, &hasAssertion); + if (NS_FAILED(rv)) return rv; + } + + rv = NS_RDF_ASSERTION_ACCEPTED; + + if (! hasAssertion) { + rv = mInner->Assert(aSource, aProperty, aTarget, aTruthValue); + + if (NS_SUCCEEDED(rv) && gcable) { + // Now mark the new assertion, so it doesn't get + // removed when we sweep. Ignore rv, because we want + // to return what mInner->Assert() gave us. + bool didMark; + (void) gcable->Mark(aSource, aProperty, aTarget, aTruthValue, &didMark); + } + + if (NS_FAILED(rv)) return rv; + } + + return rv; + } + else if (mIsWritable) { + rv = mInner->Assert(aSource, aProperty, aTarget, aTruthValue); + + if (rv == NS_RDF_ASSERTION_ACCEPTED) + mIsDirty = true; + + return rv; + } + else { + return NS_RDF_ASSERTION_REJECTED; + } +} + + +NS_IMETHODIMP +RDFXMLDataSourceImpl::Unassert(nsIRDFResource* source, + nsIRDFResource* property, + nsIRDFNode* target) +{ + // We don't accept assertions unless we're writable (except in the + // case that we're actually _reading_ the datasource in). + nsresult rv; + + if (IsLoading() || mIsWritable) { + rv = mInner->Unassert(source, property, target); + if (!IsLoading() && rv == NS_RDF_ASSERTION_ACCEPTED) + mIsDirty = true; + } + else { + rv = NS_RDF_ASSERTION_REJECTED; + } + + return rv; +} + +NS_IMETHODIMP +RDFXMLDataSourceImpl::Change(nsIRDFResource* aSource, + nsIRDFResource* aProperty, + nsIRDFNode* aOldTarget, + nsIRDFNode* aNewTarget) +{ + nsresult rv; + + if (IsLoading() || mIsWritable) { + rv = mInner->Change(aSource, aProperty, aOldTarget, aNewTarget); + + if (!IsLoading() && rv == NS_RDF_ASSERTION_ACCEPTED) + mIsDirty = true; + } + else { + rv = NS_RDF_ASSERTION_REJECTED; + } + + return rv; +} + +NS_IMETHODIMP +RDFXMLDataSourceImpl::Move(nsIRDFResource* aOldSource, + nsIRDFResource* aNewSource, + nsIRDFResource* aProperty, + nsIRDFNode* aTarget) +{ + nsresult rv; + + if (IsLoading() || mIsWritable) { + rv = mInner->Move(aOldSource, aNewSource, aProperty, aTarget); + if (!IsLoading() && rv == NS_RDF_ASSERTION_ACCEPTED) + mIsDirty = true; + } + else { + rv = NS_RDF_ASSERTION_REJECTED; + } + + return rv; +} + + +nsresult +RDFXMLDataSourceImpl::rdfXMLFlush(nsIURI *aURI) +{ + + nsresult rv; + + { + // Quick and dirty check to see if we're in XPCOM shutdown. If + // we are, we're screwed: it's too late to serialize because + // many of the services that we'll need to acquire to properly + // write the file will be unaquirable. + NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); + nsCOMPtr dummy = do_GetService(kRDFServiceCID, &rv); + if (NS_FAILED(rv)) { + NS_WARNING("unable to Flush() dirty datasource during XPCOM shutdown"); + return rv; + } + } + + // Is it a file? If so, we can write to it. Some day, it'd be nice + // if we didn't care what kind of stream this was... + nsCOMPtr fileURL = do_QueryInterface(aURI); + + if (fileURL) { + nsCOMPtr file; + fileURL->GetFile(getter_AddRefs(file)); + if (file) { + // get a safe output stream, so we don't clobber the datasource file unless + // all the writes succeeded. + nsCOMPtr out; + rv = NS_NewSafeLocalFileOutputStream(getter_AddRefs(out), + file, + PR_WRONLY | PR_CREATE_FILE, + /*octal*/ 0666, + 0); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr bufferedOut; + rv = NS_NewBufferedOutputStream(getter_AddRefs(bufferedOut), + out.forget(), 4096); + if (NS_FAILED(rv)) return rv; + + rv = Serialize(bufferedOut); + if (NS_FAILED(rv)) return rv; + + // All went ok. Maybe except for problems in Write(), but the stream detects + // that for us + nsCOMPtr safeStream = do_QueryInterface(bufferedOut, &rv); + if (NS_FAILED(rv)) return rv; + + rv = safeStream->Finish(); + if (NS_FAILED(rv)) { + NS_WARNING("failed to save datasource file! possible dataloss"); + return rv; + } + } + } + + return NS_OK; +} + + +NS_IMETHODIMP +RDFXMLDataSourceImpl::FlushTo(const char *aURI) +{ + NS_PRECONDITION(aURI != nullptr, "not initialized"); + if (!aURI) + return NS_ERROR_NULL_POINTER; + + // XXX this is a hack: any "file:" URI is considered writable. All + // others are considered read-only. + if ((PL_strncmp(aURI, kFileURIPrefix, sizeof(kFileURIPrefix) - 1) != 0) && + (PL_strncmp(aURI, kResourceURIPrefix, sizeof(kResourceURIPrefix) - 1) != 0)) + { + return NS_ERROR_ILLEGAL_VALUE; + } + + nsCOMPtr url; + nsresult rv = NS_NewURI(getter_AddRefs(url), aURI); + if (NS_FAILED(rv)) + return rv; + rv = rdfXMLFlush(url); + return rv; +} + + +NS_IMETHODIMP +RDFXMLDataSourceImpl::Flush(void) +{ + if (!mIsWritable || !mIsDirty) + return NS_OK; + + // while it is not fatal if mURL is not set, + // indicate failure since we can't flush back to an unknown origin + if (! mURL) + return NS_ERROR_NOT_INITIALIZED; + + if (MOZ_LOG_TEST(gLog, LogLevel::Debug)) { + MOZ_LOG(gLog, LogLevel::Debug, + ("rdfxml[%p] flush(%s)", this, mURL->GetSpecOrDefault().get())); + } + + nsresult rv; + if (NS_SUCCEEDED(rv = rdfXMLFlush(mURL))) + { + mIsDirty = false; + } + return rv; +} + + +//---------------------------------------------------------------------- +// +// nsIRDFXMLDataSource methods +// + +NS_IMETHODIMP +RDFXMLDataSourceImpl::GetReadOnly(bool* aIsReadOnly) +{ + *aIsReadOnly = !mIsWritable; + return NS_OK; +} + + +NS_IMETHODIMP +RDFXMLDataSourceImpl::SetReadOnly(bool aIsReadOnly) +{ + if (mIsWritable && aIsReadOnly) + mIsWritable = false; + + return NS_OK; +} + +// nsIChannelEventSink + +// This code is copied from nsSameOriginChecker::OnChannelRedirect. See +// bug 475940 on providing this code in a shared location. +NS_IMETHODIMP +RDFXMLDataSourceImpl::AsyncOnChannelRedirect(nsIChannel *aOldChannel, + nsIChannel *aNewChannel, + uint32_t aFlags, + nsIAsyncVerifyRedirectCallback *cb) +{ + NS_PRECONDITION(aNewChannel, "Redirecting to null channel?"); + + nsresult rv; + nsCOMPtr secMan = + do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr oldPrincipal; + secMan->GetChannelResultPrincipal(aOldChannel, getter_AddRefs(oldPrincipal)); + + nsCOMPtr newURI; + aNewChannel->GetURI(getter_AddRefs(newURI)); + nsCOMPtr newOriginalURI; + aNewChannel->GetOriginalURI(getter_AddRefs(newOriginalURI)); + + NS_ENSURE_STATE(oldPrincipal && newURI && newOriginalURI); + + rv = oldPrincipal->CheckMayLoad(newURI, false, false); + if (NS_SUCCEEDED(rv) && newOriginalURI != newURI) { + rv = oldPrincipal->CheckMayLoad(newOriginalURI, false, false); + } + + if (NS_FAILED(rv)) + return rv; + + cb->OnRedirectVerifyCallback(NS_OK); + return NS_OK; +} + +NS_IMETHODIMP +RDFXMLDataSourceImpl::Refresh(bool aBlocking) +{ + nsAutoCString spec; + if (mURL) { + spec = mURL->GetSpecOrDefault(); + } + MOZ_LOG(gLog, LogLevel::Debug, + ("rdfxml[%p] refresh(%s) %sblocking", this, spec.get(), (aBlocking ? "" : "non"))); + + // If an asynchronous load is already pending, then just let it do + // the honors. + if (IsLoading()) { + MOZ_LOG(gLog, LogLevel::Debug, + ("rdfxml[%p] refresh(%s) a load was pending", this, spec.get())); + + if (aBlocking) { + NS_WARNING("blocking load requested when async load pending"); + return NS_ERROR_FAILURE; + } + else { + return NS_OK; + } + } + + if (! mURL) + return NS_ERROR_FAILURE; + nsCOMPtr parser = do_CreateInstance("@mozilla.org/rdf/xml-parser;1"); + if (! parser) + return NS_ERROR_FAILURE; + + nsresult rv = parser->ParseAsync(this, mURL, getter_AddRefs(mListener)); + if (NS_FAILED(rv)) return rv; + + if (aBlocking) { + rv = BlockingParse(mURL, this); + + mListener = nullptr; // release the parser + + if (NS_FAILED(rv)) return rv; + } + else { + // Null LoadGroup ? + nsCOMPtr channel; + rv = NS_NewChannel(getter_AddRefs(channel), + mURL, + nsContentUtils::GetSystemPrincipal(), + nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, + nsIContentPolicy::TYPE_OTHER, + nullptr, // aPerformanceStorage + nullptr, // aLoadGroup + this); // aCallbacks + NS_ENSURE_SUCCESS(rv, rv); + rv = channel->AsyncOpen2(this); + NS_ENSURE_SUCCESS(rv, rv); + + // So we don't try to issue two asynchronous loads at once. + mLoadState = eLoadState_Pending; + } + + return NS_OK; +} + +NS_IMETHODIMP +RDFXMLDataSourceImpl::BeginLoad(void) +{ + if (MOZ_LOG_TEST(gLog, LogLevel::Debug)) { + MOZ_LOG(gLog, LogLevel::Debug, + ("rdfxml[%p] begin-load(%s)", this, + mURL ? mURL->GetSpecOrDefault().get() : "")); + } + + mLoadState = eLoadState_Loading; + for (int32_t i = mObservers.Count() - 1; i >= 0; --i) { + // Make sure to hold a strong reference to the observer so + // that it doesn't go away in this call if it removes itself + // as an observer + nsCOMPtr obs = mObservers[i]; + + if (obs) { + obs->OnBeginLoad(this); + } + } + return NS_OK; +} + +NS_IMETHODIMP +RDFXMLDataSourceImpl::Interrupt(void) +{ + if (MOZ_LOG_TEST(gLog, LogLevel::Debug)) { + MOZ_LOG(gLog, LogLevel::Debug, + ("rdfxml[%p] interrupt(%s)", this, + mURL ? mURL->GetSpecOrDefault().get() : "")); + } + + for (int32_t i = mObservers.Count() - 1; i >= 0; --i) { + // Make sure to hold a strong reference to the observer so + // that it doesn't go away in this call if it removes itself + // as an observer + nsCOMPtr obs = mObservers[i]; + + if (obs) { + obs->OnInterrupt(this); + } + } + return NS_OK; +} + +NS_IMETHODIMP +RDFXMLDataSourceImpl::Resume(void) +{ + if (MOZ_LOG_TEST(gLog, LogLevel::Debug)) { + MOZ_LOG(gLog, LogLevel::Debug, + ("rdfxml[%p] resume(%s)", this, + mURL ? mURL->GetSpecOrDefault().get() : "")); + } + + for (int32_t i = mObservers.Count() - 1; i >= 0; --i) { + // Make sure to hold a strong reference to the observer so + // that it doesn't go away in this call if it removes itself + // as an observer + nsCOMPtr obs = mObservers[i]; + + if (obs) { + obs->OnResume(this); + } + } + return NS_OK; +} + +NS_IMETHODIMP +RDFXMLDataSourceImpl::EndLoad(void) +{ + if (MOZ_LOG_TEST(gLog, LogLevel::Debug)) { + MOZ_LOG(gLog, LogLevel::Debug, + ("rdfxml[%p] end-load(%s)", this, + mURL ? mURL->GetSpecOrDefault().get() : "")); + } + + mLoadState = eLoadState_Loaded; + + // Clear out any unmarked assertions from the datasource. + nsCOMPtr gcable = do_QueryInterface(mInner); + if (gcable) { + gcable->Sweep(); + } + + // Notify load observers + for (int32_t i = mObservers.Count() - 1; i >= 0; --i) { + // Make sure to hold a strong reference to the observer so + // that it doesn't go away in this call if it removes itself + // as an observer + nsCOMPtr obs = mObservers[i]; + + if (obs) { + obs->OnEndLoad(this); + } + } + return NS_OK; +} + +NS_IMETHODIMP +RDFXMLDataSourceImpl::AddNameSpace(nsAtom* aPrefix, const nsString& aURI) +{ + mNameSpaces.Put(aURI, aPrefix); + return NS_OK; +} + + +NS_IMETHODIMP +RDFXMLDataSourceImpl::AddXMLSinkObserver(nsIRDFXMLSinkObserver* aObserver) +{ + if (! aObserver) + return NS_ERROR_NULL_POINTER; + + mObservers.AppendObject(aObserver); + return NS_OK; +} + +NS_IMETHODIMP +RDFXMLDataSourceImpl::RemoveXMLSinkObserver(nsIRDFXMLSinkObserver* aObserver) +{ + if (! aObserver) + return NS_ERROR_NULL_POINTER; + + mObservers.RemoveObject(aObserver); + + return NS_OK; +} + + +//---------------------------------------------------------------------- +// +// nsIRequestObserver +// + +NS_IMETHODIMP +RDFXMLDataSourceImpl::OnStartRequest(nsIRequest *request, nsISupports *ctxt) +{ + return mListener->OnStartRequest(request, ctxt); +} + +NS_IMETHODIMP +RDFXMLDataSourceImpl::OnStopRequest(nsIRequest *request, + nsISupports *ctxt, + nsresult status) +{ + if (NS_FAILED(status)) { + for (int32_t i = mObservers.Count() - 1; i >= 0; --i) { + // Make sure to hold a strong reference to the observer so + // that it doesn't go away in this call if it removes + // itself as an observer + nsCOMPtr obs = mObservers[i]; + + if (obs) { + obs->OnError(this, status, nullptr); + } + } + } + + nsresult rv; + rv = mListener->OnStopRequest(request, ctxt, status); + + mListener = nullptr; // release the parser + + return rv; +} + +//---------------------------------------------------------------------- +// +// nsIStreamListener +// + +NS_IMETHODIMP +RDFXMLDataSourceImpl::OnDataAvailable(nsIRequest *request, + nsISupports *ctxt, + nsIInputStream *inStr, + uint64_t sourceOffset, + uint32_t count) +{ + return mListener->OnDataAvailable(request, ctxt, inStr, sourceOffset, count); +} + +//---------------------------------------------------------------------- +// +// nsIRDFXMLSource +// + +NS_IMETHODIMP +RDFXMLDataSourceImpl::Serialize(nsIOutputStream* aStream) +{ + nsresult rv; + nsCOMPtr serializer + = do_CreateInstance("@mozilla.org/rdf/xml-serializer;1", &rv); + + if (! serializer) + return rv; + + rv = serializer->Init(this); + if (NS_FAILED(rv)) return rv; + + // Add any namespace information that we picked up when reading + // the RDF/XML + nsNameSpaceMap::const_iterator last = mNameSpaces.last(); + for (nsNameSpaceMap::const_iterator iter = mNameSpaces.first(); + iter != last; ++iter) { + // We might wanna change nsIRDFXMLSerializer to nsACString and + // use a heap allocated buffer here in the future. + NS_ConvertUTF8toUTF16 uri(iter->mURI); + serializer->AddNameSpace(iter->mPrefix, uri); + } + + // Serialize! + nsCOMPtr source = do_QueryInterface(serializer); + if (! source) + return NS_ERROR_FAILURE; + + return source->Serialize(aStream); +} diff --git a/rdf/base/nsRDFXMLParser.cpp b/rdf/base/nsRDFXMLParser.cpp new file mode 100644 index 000000000000..819e53d702bb --- /dev/null +++ b/rdf/base/nsRDFXMLParser.cpp @@ -0,0 +1,137 @@ +/* -*- 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/. */ + +#include "nsRDFXMLParser.h" + +#include "mozilla/Encoding.h" +#include "nsIComponentManager.h" +#include "nsIParser.h" +#include "nsCharsetSource.h" +#include "nsIRDFContentSink.h" +#include "nsParserCIID.h" +#include "nsStringStream.h" +#include "nsNetUtil.h" +#include "NullPrincipal.h" + +static NS_DEFINE_CID(kParserCID, NS_PARSER_CID); + +NS_IMPL_ISUPPORTS(nsRDFXMLParser, nsIRDFXMLParser) + +nsresult +nsRDFXMLParser::Create(nsISupports* aOuter, REFNSIID aIID, void** aResult) +{ + if (aOuter) + return NS_ERROR_NO_AGGREGATION; + + nsRDFXMLParser* result = new nsRDFXMLParser(); + if (! result) + return NS_ERROR_OUT_OF_MEMORY; + + nsresult rv; + NS_ADDREF(result); + rv = result->QueryInterface(aIID, aResult); + NS_RELEASE(result); + return rv; +} + +nsRDFXMLParser::nsRDFXMLParser() +{ +} + +nsRDFXMLParser::~nsRDFXMLParser() +{ +} + +NS_IMETHODIMP +nsRDFXMLParser::ParseAsync(nsIRDFDataSource* aSink, nsIURI* aBaseURI, nsIStreamListener** aResult) +{ + nsresult rv; + + nsCOMPtr sink = + do_CreateInstance("@mozilla.org/rdf/content-sink;1", &rv); + + if (NS_FAILED(rv)) return rv; + + rv = sink->Init(aBaseURI); + if (NS_FAILED(rv)) return rv; + + // We set the content sink's data source directly to our in-memory + // store. This allows the initial content to be generated "directly". + rv = sink->SetDataSource(aSink); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr parser = do_CreateInstance(kParserCID, &rv); + if (NS_FAILED(rv)) return rv; + + parser->SetDocumentCharset(UTF_8_ENCODING, + kCharsetFromDocTypeDefault); + parser->SetContentSink(sink); + + rv = parser->Parse(aBaseURI); + if (NS_FAILED(rv)) return rv; + + return CallQueryInterface(parser, aResult); +} + +NS_IMETHODIMP +nsRDFXMLParser::ParseString(nsIRDFDataSource* aSink, nsIURI* aBaseURI, const nsACString& aString) +{ + nsresult rv; + + nsCOMPtr sink = + do_CreateInstance("@mozilla.org/rdf/content-sink;1", &rv); + + if (NS_FAILED(rv)) return rv; + + rv = sink->Init(aBaseURI); + if (NS_FAILED(rv)) return rv; + + // We set the content sink's data source directly to our in-memory + // store. This allows the initial content to be generated "directly". + rv = sink->SetDataSource(aSink); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr parser = do_CreateInstance(kParserCID, &rv); + if (NS_FAILED(rv)) return rv; + + parser->SetDocumentCharset(UTF_8_ENCODING, + kCharsetFromOtherComponent); + parser->SetContentSink(sink); + + rv = parser->Parse(aBaseURI); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr listener = + do_QueryInterface(parser); + + if (! listener) + return NS_ERROR_FAILURE; + + nsCOMPtr stream; + rv = NS_NewCStringInputStream(getter_AddRefs(stream), aString); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr nullPrincipal = NullPrincipal::CreateWithoutOriginAttributes(); + + // The following channel is never openend, so it does not matter what + // securityFlags we pass; let's follow the principle of least privilege. + nsCOMPtr channel; + nsCOMPtr tmpStream = stream; + rv = NS_NewInputStreamChannel(getter_AddRefs(channel), + aBaseURI, + tmpStream.forget(), + nullPrincipal, + nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED, + nsIContentPolicy::TYPE_OTHER, + NS_LITERAL_CSTRING("text/xml")); + if (NS_FAILED(rv)) return rv; + + listener->OnStartRequest(channel, nullptr); + listener->OnDataAvailable(channel, nullptr, stream, 0, aString.Length()); + listener->OnStopRequest(channel, nullptr, NS_OK); + + return NS_OK; +} diff --git a/rdf/base/nsRDFXMLParser.h b/rdf/base/nsRDFXMLParser.h new file mode 100644 index 000000000000..d35c873fbecf --- /dev/null +++ b/rdf/base/nsRDFXMLParser.h @@ -0,0 +1,31 @@ +/* -*- 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/. */ + +#ifndef nsRDFParser_h__ +#define nsRDFParser_h__ + +#include "nsCOMPtr.h" +#include "nsString.h" +#include "nsIRDFXMLParser.h" +#include "nsIRDFDataSource.h" + +/** + * A helper class that is used to parse RDF/XML. + */ +class nsRDFXMLParser : public nsIRDFXMLParser { +public: + static nsresult + Create(nsISupports* aOuter, REFNSIID aIID, void** aResult); + + NS_DECL_ISUPPORTS + NS_DECL_NSIRDFXMLPARSER + +protected: + nsRDFXMLParser(); + virtual ~nsRDFXMLParser(); +}; + +#endif // nsRDFParser_h__ diff --git a/rdf/base/nsRDFXMLSerializer.cpp b/rdf/base/nsRDFXMLSerializer.cpp new file mode 100644 index 000000000000..c93307c9da72 --- /dev/null +++ b/rdf/base/nsRDFXMLSerializer.cpp @@ -0,0 +1,1123 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=4 sw=4 et tw=80: + * + * 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/. */ + +#include "nsRDFXMLSerializer.h" + +#include "nsAtom.h" +#include "nsIOutputStream.h" +#include "nsIRDFService.h" +#include "nsIRDFContainerUtils.h" +#include "nsIServiceManager.h" +#include "nsString.h" +#include "nsTArray.h" +#include "rdf.h" +#include "rdfutil.h" +#include "mozilla/Attributes.h" + +#include "rdfIDataSource.h" + +int32_t nsRDFXMLSerializer::gRefCnt = 0; +nsIRDFContainerUtils* nsRDFXMLSerializer::gRDFC; +nsIRDFResource* nsRDFXMLSerializer::kRDF_instanceOf; +nsIRDFResource* nsRDFXMLSerializer::kRDF_type; +nsIRDFResource* nsRDFXMLSerializer::kRDF_nextVal; +nsIRDFResource* nsRDFXMLSerializer::kRDF_Bag; +nsIRDFResource* nsRDFXMLSerializer::kRDF_Seq; +nsIRDFResource* nsRDFXMLSerializer::kRDF_Alt; + +static const char kRDFDescriptionOpen[] = " \n"; +static const char kRDFParseTypeInteger[] = " NC:parseType=\"Integer\">"; +static const char kRDFParseTypeDate[] = " NC:parseType=\"Date\">"; +static const char kRDFUnknown[] = ">"; + +nsresult +nsRDFXMLSerializer::Create(nsISupports* aOuter, REFNSIID aIID, void** aResult) +{ + if (aOuter) + return NS_ERROR_NO_AGGREGATION; + + nsCOMPtr result = new nsRDFXMLSerializer(); + if (! result) + return NS_ERROR_OUT_OF_MEMORY; + // The serializer object is here, addref gRefCnt so that the + // destructor can safely release it. + gRefCnt++; + + nsresult rv; + rv = result->QueryInterface(aIID, aResult); + + if (NS_FAILED(rv)) return rv; + + if (gRefCnt == 1) do { + nsCOMPtr rdf = do_GetService("@mozilla.org/rdf/rdf-service;1", &rv); + if (NS_FAILED(rv)) break; + + rv = rdf->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "instanceOf"), + &kRDF_instanceOf); + if (NS_FAILED(rv)) break; + + rv = rdf->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "type"), + &kRDF_type); + if (NS_FAILED(rv)) break; + + rv = rdf->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "nextVal"), + &kRDF_nextVal); + if (NS_FAILED(rv)) break; + + rv = rdf->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "Bag"), + &kRDF_Bag); + if (NS_FAILED(rv)) break; + + rv = rdf->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "Seq"), + &kRDF_Seq); + if (NS_FAILED(rv)) break; + + rv = rdf->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "Alt"), + &kRDF_Alt); + if (NS_FAILED(rv)) break; + + rv = CallGetService("@mozilla.org/rdf/container-utils;1", &gRDFC); + if (NS_FAILED(rv)) break; + } while (0); + + return rv; +} + +nsRDFXMLSerializer::nsRDFXMLSerializer() +{ +} + +nsRDFXMLSerializer::~nsRDFXMLSerializer() +{ + if (--gRefCnt == 0) { + NS_IF_RELEASE(kRDF_Bag); + NS_IF_RELEASE(kRDF_Seq); + NS_IF_RELEASE(kRDF_Alt); + NS_IF_RELEASE(kRDF_instanceOf); + NS_IF_RELEASE(kRDF_type); + NS_IF_RELEASE(kRDF_nextVal); + NS_IF_RELEASE(gRDFC); + } +} + +NS_IMPL_ISUPPORTS(nsRDFXMLSerializer, nsIRDFXMLSerializer, nsIRDFXMLSource) + +NS_IMETHODIMP +nsRDFXMLSerializer::Init(nsIRDFDataSource* aDataSource) +{ + if (! aDataSource) + return NS_ERROR_NULL_POINTER; + + mDataSource = aDataSource; + mDataSource->GetURI(mBaseURLSpec); + + // Add the ``RDF'' prefix, by default. + RefPtr prefix; + + prefix = NS_Atomize("RDF"); + AddNameSpace(prefix, NS_LITERAL_STRING("http://www.w3.org/1999/02/22-rdf-syntax-ns#")); + + prefix = NS_Atomize("NC"); + AddNameSpace(prefix, NS_LITERAL_STRING("http://home.netscape.com/NC-rdf#")); + + mPrefixID = 0; + + return NS_OK; +} + +NS_IMETHODIMP +nsRDFXMLSerializer::AddNameSpace(nsAtom* aPrefix, const nsAString& aURI) +{ + RefPtr prefix = aPrefix; + if (!prefix) { + // Make up a prefix, we don't want default namespaces, so + // that we can use QNames for elements and attributes alike. + prefix = EnsureNewPrefix(); + } + mNameSpaces.Put(aURI, prefix); + return NS_OK; +} + +static nsresult +rdf_BlockingWrite(nsIOutputStream* stream, const char* buf, uint32_t size) +{ + uint32_t written = 0; + uint32_t remaining = size; + while (remaining > 0) { + nsresult rv; + uint32_t cb; + + if (NS_FAILED(rv = stream->Write(buf + written, remaining, &cb))) + return rv; + + written += cb; + remaining -= cb; + } + return NS_OK; +} + +static nsresult +rdf_BlockingWrite(nsIOutputStream* stream, const nsACString& s) +{ + return rdf_BlockingWrite(stream, s.BeginReading(), s.Length()); +} + +static nsresult +rdf_BlockingWrite(nsIOutputStream* stream, const nsAString& s) +{ + NS_ConvertUTF16toUTF8 utf8(s); + return rdf_BlockingWrite(stream, utf8.get(), utf8.Length()); +} + +already_AddRefed +nsRDFXMLSerializer::EnsureNewPrefix() +{ + nsAutoString qname; + RefPtr prefix; + bool isNewPrefix; + do { + isNewPrefix = true; + qname.AssignLiteral("NS"); + qname.AppendInt(++mPrefixID, 10); + prefix = NS_Atomize(qname); + nsNameSpaceMap::const_iterator iter = mNameSpaces.first(); + while (iter != mNameSpaces.last() && isNewPrefix) { + isNewPrefix = (iter->mPrefix != prefix); + ++iter; + } + } while (!isNewPrefix); + return prefix.forget(); +} + +// This converts a property resource (like +// "http://www.w3.org/TR/WD-rdf-syntax#Description") into a QName +// ("RDF:Description"), and registers the namespace, if it's made up. + +nsresult +nsRDFXMLSerializer::RegisterQName(nsIRDFResource* aResource) +{ + nsAutoCString uri, qname; + aResource->GetValueUTF8(uri); + + nsNameSpaceMap::const_iterator iter = mNameSpaces.GetNameSpaceOf(uri); + if (iter != mNameSpaces.last()) { + NS_ENSURE_TRUE(iter->mPrefix, NS_ERROR_UNEXPECTED); + iter->mPrefix->ToUTF8String(qname); + qname.Append(':'); + qname += StringTail(uri, uri.Length() - iter->mURI.Length()); + mQNames.Put(aResource, qname); + return NS_OK; + } + + // Okay, so we don't have it in our map. Try to make one up. This + // is very bogus. + int32_t i = uri.RFindChar('#'); // first try a '#' + if (i == -1) { + i = uri.RFindChar('/'); + if (i == -1) { + // Okay, just punt and assume there is _no_ namespace on + // this thing... + mQNames.Put(aResource, uri); + return NS_OK; + } + } + + // Take whatever is to the right of the '#' or '/' and call it the + // local name, make up a prefix. + RefPtr prefix = EnsureNewPrefix(); + mNameSpaces.Put(StringHead(uri, i+1), prefix); + prefix->ToUTF8String(qname); + qname.Append(':'); + qname += StringTail(uri, uri.Length() - (i + 1)); + + mQNames.Put(aResource, qname); + return NS_OK; +} + +nsresult +nsRDFXMLSerializer::GetQName(nsIRDFResource* aResource, nsCString& aQName) +{ + return mQNames.Get(aResource, &aQName) ? NS_OK : NS_ERROR_UNEXPECTED; +} + +bool +nsRDFXMLSerializer::IsContainerProperty(nsIRDFResource* aProperty) +{ + // Return `true' if the property is an internal property related + // to being a container. + if (aProperty == kRDF_instanceOf) + return true; + + if (aProperty == kRDF_nextVal) + return true; + + bool isOrdinal = false; + gRDFC->IsOrdinalProperty(aProperty, &isOrdinal); + if (isOrdinal) + return true; + + return false; +} + + +// convert '&', '<', and '>' into "&", "<", and ">", respectively. +static const char amp[] = "&"; +static const char lt[] = "<"; +static const char gt[] = ">"; +static const char quot[] = """; + +static void +rdf_EscapeAmpersandsAndAngleBrackets(nsCString& s) +{ + uint32_t newLength, origLength; + newLength = origLength = s.Length(); + + // Compute the length of the result string. + const char* start = s.BeginReading(); + const char* end = s.EndReading(); + const char* c = start; + while (c != end) { + switch (*c) { + case '&' : + newLength += sizeof(amp) - 2; + break; + case '<': + case '>': + newLength += sizeof(gt) - 2; + break; + default: + break; + } + ++c; + } + if (newLength == origLength) { + // nothing to escape + return; + } + + // escape the chars from the end back to the front. + s.SetLength(newLength); + + // Buffer might have changed, get the pointers again + start = s.BeginReading(); // begin of string + c = start + origLength - 1; // last char in original string + char* w = s.EndWriting() - 1; // last char in grown buffer + while (c >= start) { + switch (*c) { + case '&' : + w -= 4; + nsCharTraits::copy(w, amp, sizeof(amp) - 1); + break; + case '<': + w -= 3; + nsCharTraits::copy(w, lt, sizeof(lt) - 1); + break; + case '>': + w -= 3; + nsCharTraits::copy(w, gt, sizeof(gt) - 1); + break; + default: + *w = *c; + } + --w; + --c; + } +} + +// convert '"' to """ +static void +rdf_EscapeQuotes(nsCString& s) +{ + int32_t i = 0; + while ((i = s.FindChar('"', i)) != -1) { + s.Replace(i, 1, quot, sizeof(quot) - 1); + i += sizeof(quot) - 2; + } +} + +static void +rdf_EscapeAttributeValue(nsCString& s) +{ + rdf_EscapeAmpersandsAndAngleBrackets(s); + rdf_EscapeQuotes(s); +} + + +nsresult +nsRDFXMLSerializer::SerializeInlineAssertion(nsIOutputStream* aStream, + nsIRDFResource* aResource, + nsIRDFResource* aProperty, + nsIRDFLiteral* aValue) +{ + nsresult rv; + nsCString qname; + rv = GetQName(aProperty, qname); + NS_ENSURE_SUCCESS(rv, rv); + + rv = rdf_BlockingWrite(aStream, + NS_LITERAL_CSTRING("\n ")); + if (NS_FAILED(rv)) return rv; + + const char16_t* value; + aValue->GetValueConst(&value); + NS_ConvertUTF16toUTF8 s(value); + + rdf_EscapeAttributeValue(s); + + rv = rdf_BlockingWrite(aStream, qname); + if (NS_FAILED(rv)) return rv; + rv = rdf_BlockingWrite(aStream, "=\"", 2); + if (NS_FAILED(rv)) return rv; + s.Append('"'); + return rdf_BlockingWrite(aStream, s); +} + +nsresult +nsRDFXMLSerializer::SerializeChildAssertion(nsIOutputStream* aStream, + nsIRDFResource* aResource, + nsIRDFResource* aProperty, + nsIRDFNode* aValue) +{ + nsCString qname; + nsresult rv = GetQName(aProperty, qname); + NS_ENSURE_SUCCESS(rv, rv); + + rv = rdf_BlockingWrite(aStream, " <", 5); + if (NS_FAILED(rv)) return rv; + rv = rdf_BlockingWrite(aStream, qname); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr resource; + nsCOMPtr literal; + nsCOMPtr number; + nsCOMPtr date; + + if ((resource = do_QueryInterface(aValue)) != nullptr) { + nsAutoCString uri; + resource->GetValueUTF8(uri); + + rdf_MakeRelativeRef(mBaseURLSpec, uri); + rdf_EscapeAttributeValue(uri); + + rv = rdf_BlockingWrite(aStream, kRDFResource1, + sizeof(kRDFResource1) - 1); + if (NS_FAILED(rv)) return rv; + rv = rdf_BlockingWrite(aStream, uri); + if (NS_FAILED(rv)) return rv; + rv = rdf_BlockingWrite(aStream, kRDFResource2, + sizeof(kRDFResource2) - 1); + if (NS_FAILED(rv)) return rv; + + goto no_close_tag; + } + else if ((literal = do_QueryInterface(aValue)) != nullptr) { + const char16_t *value; + literal->GetValueConst(&value); + NS_ConvertUTF16toUTF8 s(value); + + rdf_EscapeAmpersandsAndAngleBrackets(s); + + rv = rdf_BlockingWrite(aStream, ">", 1); + if (NS_FAILED(rv)) return rv; + rv = rdf_BlockingWrite(aStream, s); + if (NS_FAILED(rv)) return rv; + } + else if ((number = do_QueryInterface(aValue)) != nullptr) { + int32_t value; + number->GetValue(&value); + + nsAutoCString n; + n.AppendInt(value); + + rv = rdf_BlockingWrite(aStream, kRDFParseTypeInteger, + sizeof(kRDFParseTypeInteger) - 1); + if (NS_FAILED(rv)) return rv; + rv = rdf_BlockingWrite(aStream, n); + if (NS_FAILED(rv)) return rv; + } + else if ((date = do_QueryInterface(aValue)) != nullptr) { + PRTime value; + date->GetValue(&value); + + nsAutoCString s; + rdf_FormatDate(value, s); + + rv = rdf_BlockingWrite(aStream, kRDFParseTypeDate, + sizeof(kRDFParseTypeDate) - 1); + if (NS_FAILED(rv)) return rv; + rv = rdf_BlockingWrite(aStream, s); + if (NS_FAILED(rv)) return rv; + } + else { + // XXX it doesn't support nsIRDFResource _or_ nsIRDFLiteral??? + // We should serialize nsIRDFInt, nsIRDFDate, etc... + NS_WARNING("unknown RDF node type"); + + rv = rdf_BlockingWrite(aStream, kRDFUnknown, sizeof(kRDFUnknown) - 1); + if (NS_FAILED(rv)) return rv; + } + + rv = rdf_BlockingWrite(aStream, "\n", 2); + + no_close_tag: + return NS_OK; +} + +nsresult +nsRDFXMLSerializer::SerializeProperty(nsIOutputStream* aStream, + nsIRDFResource* aResource, + nsIRDFResource* aProperty, + bool aInline, + int32_t* aSkipped) +{ + nsresult rv = NS_OK; + + int32_t skipped = 0; + + nsCOMPtr assertions; + mDataSource->GetTargets(aResource, aProperty, true, getter_AddRefs(assertions)); + if (! assertions) + return NS_ERROR_FAILURE; + + // Serializing the assertion inline is ok as long as the property has + // only one target value, and it is a literal that doesn't include line + // breaks. + bool needsChild = false; + + while (1) { + bool hasMore = false; + assertions->HasMoreElements(&hasMore); + if (! hasMore) + break; + + nsCOMPtr isupports; + assertions->GetNext(getter_AddRefs(isupports)); + nsCOMPtr literal = do_QueryInterface(isupports); + needsChild |= (!literal); + + if (!needsChild) { + assertions->HasMoreElements(&needsChild); + if (!needsChild) { + const char16_t* literalVal = nullptr; + literal->GetValueConst(&literalVal); + if (literalVal) { + for (; *literalVal; literalVal++) { + if (*literalVal == char16_t('\n') || + *literalVal == char16_t('\r')) { + needsChild = true; + break; + } + } + } + } + } + + if (aInline && !needsChild) { + rv = SerializeInlineAssertion(aStream, aResource, aProperty, literal); + } + else if (!aInline && needsChild) { + nsCOMPtr value = do_QueryInterface(isupports); + rv = SerializeChildAssertion(aStream, aResource, aProperty, value); + } + else { + ++skipped; + rv = NS_OK; + } + + if (NS_FAILED(rv)) + break; + } + + *aSkipped += skipped; + return rv; +} + + +nsresult +nsRDFXMLSerializer::SerializeDescription(nsIOutputStream* aStream, + nsIRDFResource* aResource) +{ + nsresult rv; + + bool isTypedNode = false; + nsCString typeQName; + + nsCOMPtr typeNode; + mDataSource->GetTarget(aResource, kRDF_type, true, getter_AddRefs(typeNode)); + if (typeNode) { + nsCOMPtr type = do_QueryInterface(typeNode, &rv); + if (type) { + // Try to get a namespace prefix. If none is available, + // just treat the description as if it weren't a typed node + // after all and emit rdf:type as a normal property. This + // seems preferable to using a bogus (invented) prefix. + isTypedNode = NS_SUCCEEDED(GetQName(type, typeQName)); + } + } + + nsAutoCString uri; + rv = aResource->GetValueUTF8(uri); + if (NS_FAILED(rv)) return rv; + + rdf_MakeRelativeRef(mBaseURLSpec, uri); + rdf_EscapeAttributeValue(uri); + + // Emit an open tag and the subject + if (isTypedNode) { + rv = rdf_BlockingWrite(aStream, NS_LITERAL_STRING(" <")); + if (NS_FAILED(rv)) return rv; + // Watch out for the default namespace! + rv = rdf_BlockingWrite(aStream, typeQName); + if (NS_FAILED(rv)) return rv; + } + else { + rv = rdf_BlockingWrite(aStream, kRDFDescriptionOpen, + sizeof(kRDFDescriptionOpen) - 1); + if (NS_FAILED(rv)) return rv; + } + if (uri[0] == char16_t('#')) { + uri.Cut(0, 1); + rv = rdf_BlockingWrite(aStream, kIDAttr, sizeof(kIDAttr) - 1); + } + else { + rv = rdf_BlockingWrite(aStream, kAboutAttr, sizeof(kAboutAttr) - 1); + } + if (NS_FAILED(rv)) return rv; + + uri.Append('"'); + rv = rdf_BlockingWrite(aStream, uri); + if (NS_FAILED(rv)) return rv; + + // Any value that's a literal we can write out as an inline + // attribute on the RDF:Description + AutoTArray visited; + int32_t skipped = 0; + + nsCOMPtr arcs; + mDataSource->ArcLabelsOut(aResource, getter_AddRefs(arcs)); + + if (arcs) { + // Don't re-serialize rdf:type later on + if (isTypedNode) + visited.AppendElement(kRDF_type); + + while (1) { + bool hasMore = false; + arcs->HasMoreElements(&hasMore); + if (! hasMore) + break; + + nsCOMPtr isupports; + arcs->GetNext(getter_AddRefs(isupports)); + + nsCOMPtr property = do_QueryInterface(isupports); + if (! property) + continue; + + // Ignore properties that pertain to containers; we may be + // called from SerializeContainer() if the container resource + // has been assigned non-container properties. + if (IsContainerProperty(property)) + continue; + + // Only serialize values for the property once. + if (visited.Contains(property.get())) + continue; + + visited.AppendElement(property.get()); + + SerializeProperty(aStream, aResource, property, true, &skipped); + } + } + + if (skipped) { + // Close the RDF:Description tag. + rv = rdf_BlockingWrite(aStream, NS_LITERAL_CSTRING(">\n")); + if (NS_FAILED(rv)) return rv; + + // Now write out resources (which might have their own + // substructure) as children. + mDataSource->ArcLabelsOut(aResource, getter_AddRefs(arcs)); + + if (arcs) { + // Forget that we've visited anything + visited.Clear(); + // ... except for rdf:type + if (isTypedNode) + visited.AppendElement(kRDF_type); + + while (1) { + bool hasMore = false; + arcs->HasMoreElements(&hasMore); + if (! hasMore) + break; + + nsCOMPtr isupports; + arcs->GetNext(getter_AddRefs(isupports)); + + nsCOMPtr property = do_QueryInterface(isupports); + if (! property) + continue; + + // Ignore properties that pertain to containers; we may be + // called from SerializeContainer() if the container + // resource has been assigned non-container properties. + if (IsContainerProperty(property)) + continue; + + // have we already seen this property? If so, don't write it + // out again; serialize property will write each instance. + if (visited.Contains(property.get())) + continue; + + visited.AppendElement(property.get()); + + SerializeProperty(aStream, aResource, property, false, &skipped); + } + } + + // Emit a proper close-tag. + if (isTypedNode) { + rv = rdf_BlockingWrite(aStream, NS_LITERAL_CSTRING(" \n", 2); + if (NS_FAILED(rv)) return rv; + } + else { + rv = rdf_BlockingWrite(aStream, kRDFDescriptionClose, + sizeof(kRDFDescriptionClose) - 1); + if (NS_FAILED(rv)) return rv; + } + } + else { + // If we saw _no_ child properties, then we can don't need a + // close-tag. + rv = rdf_BlockingWrite(aStream, NS_LITERAL_CSTRING(" />\n")); + if (NS_FAILED(rv)) return rv; + } + + return NS_OK; +} + +nsresult +nsRDFXMLSerializer::SerializeMember(nsIOutputStream* aStream, + nsIRDFResource* aContainer, + nsIRDFNode* aMember) +{ + // If it's a resource, then output a "" + // tag, because we'll be dumping the resource separately. (We + // iterate thru all the resources in the datasource, + // remember?) Otherwise, output the literal value. + + nsCOMPtr resource; + nsCOMPtr literal; + nsCOMPtr number; + nsCOMPtr date; + +static const char kRDFLIOpen[] = " GetValueUTF8(uri); + + rdf_MakeRelativeRef(mBaseURLSpec, uri); + rdf_EscapeAttributeValue(uri); + + rv = rdf_BlockingWrite(aStream, kRDFResource1, + sizeof(kRDFResource1) - 1); + if (NS_FAILED(rv)) return rv; + rv = rdf_BlockingWrite(aStream, uri); + if (NS_FAILED(rv)) return rv; + rv = rdf_BlockingWrite(aStream, kRDFResource2, + sizeof(kRDFResource2) - 1); + if (NS_FAILED(rv)) return rv; + + goto no_close_tag; + } + else if ((literal = do_QueryInterface(aMember)) != nullptr) { + const char16_t *value; + literal->GetValueConst(&value); +static const char kRDFLIOpenGT[] = ">"; + // close the 'GetValue(&value); + + nsAutoCString n; + n.AppendInt(value); + + rv = rdf_BlockingWrite(aStream, kRDFParseTypeInteger, + sizeof(kRDFParseTypeInteger) - 1); + if (NS_FAILED(rv)) return rv; + rv = rdf_BlockingWrite(aStream, n); + if (NS_FAILED(rv)) return rv; + } + else if ((date = do_QueryInterface(aMember)) != nullptr) { + PRTime value; + date->GetValue(&value); + + nsAutoCString s; + rdf_FormatDate(value, s); + + rv = rdf_BlockingWrite(aStream, kRDFParseTypeDate, + sizeof(kRDFParseTypeDate) - 1); + if (NS_FAILED(rv)) return rv; + rv = rdf_BlockingWrite(aStream, s); + if (NS_FAILED(rv)) return rv; + } + else { + // XXX it doesn't support nsIRDFResource _or_ nsIRDFLiteral??? + // We should serialize nsIRDFInt, nsIRDFDate, etc... + NS_WARNING("unknown RDF node type"); + + rv = rdf_BlockingWrite(aStream, kRDFUnknown, sizeof(kRDFUnknown) - 1); + if (NS_FAILED(rv)) return rv; + } + + { +static const char kRDFLIClose[] = "\n"; + rv = rdf_BlockingWrite(aStream, kRDFLIClose, sizeof(kRDFLIClose) - 1); + if (NS_FAILED(rv)) return rv; + } + + no_close_tag: + return NS_OK; +} + + +nsresult +nsRDFXMLSerializer::SerializeContainer(nsIOutputStream* aStream, + nsIRDFResource* aContainer) +{ + nsresult rv; + nsAutoCString tag; + + // Decide if it's a sequence, bag, or alternation, and print the + // appropriate tag-open sequence + + if (IsA(mDataSource, aContainer, kRDF_Bag)) { + tag.AssignLiteral("RDF:Bag"); + } + else if (IsA(mDataSource, aContainer, kRDF_Seq)) { + tag.AssignLiteral("RDF:Seq"); + } + else if (IsA(mDataSource, aContainer, kRDF_Alt)) { + tag.AssignLiteral("RDF:Alt"); + } + else { + NS_ASSERTION(false, "huh? this is _not_ a container."); + return NS_ERROR_UNEXPECTED; + } + + rv = rdf_BlockingWrite(aStream, " <", 3); + if (NS_FAILED(rv)) return rv; + rv = rdf_BlockingWrite(aStream, tag); + if (NS_FAILED(rv)) return rv; + + + // Unfortunately, we always need to print out the identity of the + // resource, even if was constructed "anonymously". We need to do + // this because we never really know who else might be referring + // to it... + + nsAutoCString uri; + if (NS_SUCCEEDED(aContainer->GetValueUTF8(uri))) { + rdf_MakeRelativeRef(mBaseURLSpec, uri); + + rdf_EscapeAttributeValue(uri); + + if (uri.First() == '#') { + // Okay, it's actually identified as an element in the + // current document, not trying to decorate some absolute + // URI. We can use the 'ID=' attribute... + + uri.Cut(0, 1); // chop the '#' + rv = rdf_BlockingWrite(aStream, kIDAttr, sizeof(kIDAttr) - 1); + if (NS_FAILED(rv)) return rv; + } + else { + // We need to cheat and spit out an illegal 'about=' on + // the sequence. + rv = rdf_BlockingWrite(aStream, kAboutAttr, + sizeof(kAboutAttr) - 1); + if (NS_FAILED(rv)) return rv; + } + + rv = rdf_BlockingWrite(aStream, uri); + if (NS_FAILED(rv)) return rv; + rv = rdf_BlockingWrite(aStream, "\"", 1); + if (NS_FAILED(rv)) return rv; + } + + rv = rdf_BlockingWrite(aStream, ">\n", 2); + if (NS_FAILED(rv)) return rv; + + // First iterate through each of the ordinal elements (the RDF/XML + // syntax doesn't allow us to place properties on RDF container + // elements). + nsCOMPtr elements; + rv = NS_NewContainerEnumerator(mDataSource, aContainer, getter_AddRefs(elements)); + + if (NS_SUCCEEDED(rv)) { + while (1) { + bool hasMore; + rv = elements->HasMoreElements(&hasMore); + if (NS_FAILED(rv)) break; + + if (! hasMore) + break; + + nsCOMPtr isupports; + elements->GetNext(getter_AddRefs(isupports)); + + nsCOMPtr element = do_QueryInterface(isupports); + NS_ASSERTION(element != nullptr, "not an nsIRDFNode"); + if (! element) + continue; + + SerializeMember(aStream, aContainer, element); + } + } + + // close the container tag + rv = rdf_BlockingWrite(aStream, " \n", 2); + rv = rdf_BlockingWrite(aStream, tag); + if (NS_FAILED(rv)) return rv; + + // Now, we iterate through _all_ of the arcs, in case someone has + // applied properties to the bag itself. These'll be placed in a + // separate RDF:Description element. + nsCOMPtr arcs; + mDataSource->ArcLabelsOut(aContainer, getter_AddRefs(arcs)); + + bool wroteDescription = false; + while (! wroteDescription) { + bool hasMore = false; + rv = arcs->HasMoreElements(&hasMore); + if (NS_FAILED(rv)) break; + + if (! hasMore) + break; + + nsIRDFResource* property; + rv = arcs->GetNext((nsISupports**) &property); + if (NS_FAILED(rv)) break; + + // If it's a membership property, then output a "LI" + // tag. Otherwise, output a property. + if (! IsContainerProperty(property)) { + rv = SerializeDescription(aStream, aContainer); + wroteDescription = true; + } + + NS_RELEASE(property); + if (NS_FAILED(rv)) + break; + } + + return NS_OK; +} + + +nsresult +nsRDFXMLSerializer::SerializePrologue(nsIOutputStream* aStream) +{ +static const char kXMLVersion[] = "\n"; + + nsresult rv; + rv = rdf_BlockingWrite(aStream, kXMLVersion, sizeof(kXMLVersion) - 1); + if (NS_FAILED(rv)) return rv; + + // global name space declarations + rv = rdf_BlockingWrite(aStream, NS_LITERAL_CSTRING("mPrefix) { + rv = rdf_BlockingWrite(aStream, NS_LITERAL_CSTRING(":")); + if (NS_FAILED(rv)) return rv; + nsAutoCString prefix; + entry->mPrefix->ToUTF8String(prefix); + rv = rdf_BlockingWrite(aStream, prefix); + if (NS_FAILED(rv)) return rv; + } + + rv = rdf_BlockingWrite(aStream, NS_LITERAL_CSTRING("=\"")); + if (NS_FAILED(rv)) return rv; + nsAutoCString uri(entry->mURI); + rdf_EscapeAttributeValue(uri); + rv = rdf_BlockingWrite(aStream, uri); + if (NS_FAILED(rv)) return rv; + rv = rdf_BlockingWrite(aStream, NS_LITERAL_CSTRING("\"")); + if (NS_FAILED(rv)) return rv; + } + + return rdf_BlockingWrite(aStream, NS_LITERAL_CSTRING(">\n")); +} + + +nsresult +nsRDFXMLSerializer::SerializeEpilogue(nsIOutputStream* aStream) +{ + return rdf_BlockingWrite(aStream, NS_LITERAL_CSTRING("\n")); +} + +class QNameCollector final : public rdfITripleVisitor { +public: + NS_DECL_ISUPPORTS + NS_DECL_RDFITRIPLEVISITOR + explicit QNameCollector(nsRDFXMLSerializer* aParent) + : mParent(aParent){} +private: + ~QNameCollector() {} + nsRDFXMLSerializer* mParent; +}; + +NS_IMPL_ISUPPORTS(QNameCollector, rdfITripleVisitor) +nsresult +QNameCollector::Visit(nsIRDFNode* aSubject, nsIRDFResource* aPredicate, + nsIRDFNode* aObject, bool aTruthValue) +{ + if (aPredicate == nsRDFXMLSerializer::kRDF_type) { + // try to get a type QName for aObject, should be a resource + nsCOMPtr resType = do_QueryInterface(aObject); + if (!resType) { + // ignore error + return NS_OK; + } + if (mParent->mQNames.Get(resType, nullptr)) { + return NS_OK; + } + mParent->RegisterQName(resType); + return NS_OK; + } + + if (mParent->mQNames.Get(aPredicate, nullptr)) { + return NS_OK; + } + if (aPredicate == nsRDFXMLSerializer::kRDF_instanceOf || + aPredicate == nsRDFXMLSerializer::kRDF_nextVal) + return NS_OK; + bool isOrdinal = false; + nsRDFXMLSerializer::gRDFC->IsOrdinalProperty(aPredicate, &isOrdinal); + if (isOrdinal) + return NS_OK; + + mParent->RegisterQName(aPredicate); + + return NS_OK; +} + +nsresult +nsRDFXMLSerializer::CollectNamespaces() +{ + // Iterate over all Triples to get namespaces for subject resource types + // and Predicates and cache all the QNames we want to use. + nsCOMPtr collector = + new QNameCollector(this); + nsCOMPtr ds = do_QueryInterface(mDataSource); // XXX API + NS_ENSURE_TRUE(collector && ds, NS_ERROR_FAILURE); + return ds->VisitAllTriples(collector); +} + +//---------------------------------------------------------------------- + +NS_IMETHODIMP +nsRDFXMLSerializer::Serialize(nsIOutputStream* aStream) +{ + nsresult rv; + + rv = CollectNamespaces(); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr resources; + rv = mDataSource->GetAllResources(getter_AddRefs(resources)); + if (NS_FAILED(rv)) return rv; + + rv = SerializePrologue(aStream); + if (NS_FAILED(rv)) + return rv; + + while (1) { + bool hasMore = false; + resources->HasMoreElements(&hasMore); + if (! hasMore) + break; + + nsCOMPtr isupports; + resources->GetNext(getter_AddRefs(isupports)); + + nsCOMPtr resource = do_QueryInterface(isupports); + if (! resource) + continue; + + if (IsA(mDataSource, resource, kRDF_Bag) || + IsA(mDataSource, resource, kRDF_Seq) || + IsA(mDataSource, resource, kRDF_Alt)) { + rv = SerializeContainer(aStream, resource); + } + else { + rv = SerializeDescription(aStream, resource); + } + + if (NS_FAILED(rv)) + break; + } + + rv = SerializeEpilogue(aStream); + + return rv; +} + + +bool +nsRDFXMLSerializer::IsA(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource, nsIRDFResource* aType) +{ + nsresult rv; + + bool result; + rv = aDataSource->HasAssertion(aResource, kRDF_instanceOf, aType, true, &result); + if (NS_FAILED(rv)) return false; + + return result; +} diff --git a/rdf/base/nsRDFXMLSerializer.h b/rdf/base/nsRDFXMLSerializer.h new file mode 100644 index 000000000000..235753eb24d6 --- /dev/null +++ b/rdf/base/nsRDFXMLSerializer.h @@ -0,0 +1,117 @@ +/* -*- 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/. */ + +#ifndef nsRDFXMLSerializer_h__ +#define nsRDFXMLSerializer_h__ + +#include "nsIRDFLiteral.h" +#include "nsIRDFXMLSerializer.h" +#include "nsIRDFXMLSource.h" +#include "nsNameSpaceMap.h" +#include "nsString.h" + +#include "nsDataHashtable.h" +#include "rdfITripleVisitor.h" + +class nsIOutputStream; +class nsIRDFContainerUtils; + +/** + * A helper class that can serialize RDF/XML from a + * datasource. Implements both nsIRDFXMLSerializer and + * nsIRDFXMLSource. + */ +class nsRDFXMLSerializer : public nsIRDFXMLSerializer, + public nsIRDFXMLSource +{ +public: + static nsresult + Create(nsISupports* aOuter, REFNSIID aIID, void** aResult); + + NS_DECL_ISUPPORTS + NS_DECL_NSIRDFXMLSERIALIZER + NS_DECL_NSIRDFXMLSOURCE + +protected: + nsRDFXMLSerializer(); + virtual ~nsRDFXMLSerializer(); + + // Implementation methods + nsresult + RegisterQName(nsIRDFResource* aResource); + nsresult + GetQName(nsIRDFResource* aResource, nsCString& aQName); + already_AddRefed + EnsureNewPrefix(); + + nsresult + SerializeInlineAssertion(nsIOutputStream* aStream, + nsIRDFResource* aResource, + nsIRDFResource* aProperty, + nsIRDFLiteral* aValue); + + nsresult + SerializeChildAssertion(nsIOutputStream* aStream, + nsIRDFResource* aResource, + nsIRDFResource* aProperty, + nsIRDFNode* aValue); + + nsresult + SerializeProperty(nsIOutputStream* aStream, + nsIRDFResource* aResource, + nsIRDFResource* aProperty, + bool aInline, + int32_t* aSkipped); + + bool + IsContainerProperty(nsIRDFResource* aProperty); + + nsresult + SerializeDescription(nsIOutputStream* aStream, + nsIRDFResource* aResource); + + nsresult + SerializeMember(nsIOutputStream* aStream, + nsIRDFResource* aContainer, + nsIRDFNode* aMember); + + nsresult + SerializeContainer(nsIOutputStream* aStream, + nsIRDFResource* aContainer); + + nsresult + SerializePrologue(nsIOutputStream* aStream); + + nsresult + SerializeEpilogue(nsIOutputStream* aStream); + + nsresult + CollectNamespaces(); + + bool + IsA(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource, nsIRDFResource* aType); + + nsCOMPtr mDataSource; + nsNameSpaceMap mNameSpaces; + nsCString mBaseURLSpec; + + // hash mapping resources to utf8-encoded QNames + nsDataHashtable mQNames; + friend class QNameCollector; + + uint32_t mPrefixID; + + static int32_t gRefCnt; + static nsIRDFResource* kRDF_instanceOf; + static nsIRDFResource* kRDF_type; + static nsIRDFResource* kRDF_nextVal; + static nsIRDFResource* kRDF_Bag; + static nsIRDFResource* kRDF_Seq; + static nsIRDFResource* kRDF_Alt; + static nsIRDFContainerUtils* gRDFC; +}; + +#endif // nsRDFXMLSerializer_h__ diff --git a/rdf/base/rdf.h b/rdf/base/rdf.h new file mode 100644 index 000000000000..65087cee5174 --- /dev/null +++ b/rdf/base/rdf.h @@ -0,0 +1,57 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +/* + + A catch-all header file for miscellaneous RDF stuff. Currently + contains error codes and vocabulary macros. + + */ + +#ifndef rdf_h___ +#define rdf_h___ + +#include "nsError.h" + +/** + * The following macros are to aid in vocabulary definition. They + * creates const char*'s for "kURI[prefix]_[name]", appropriate + * complete namespace qualification on the URI, e.g., + * + * #define RDF_NAMESPACE_URI "http://www.w3.org/TR/WD-rdf-syntax#" + * DEFINE_RDF_ELEMENT(RDF_NAMESPACE_URI, RDF, ID); + * + * will define: + * + * kURIRDF_ID to be "http://www.w3.org/TR/WD-rdf-syntax#ID" + */ + +#define DEFINE_RDF_VOCAB(ns, prefix, name) \ +static const char kURI##prefix##_##name[] = ns #name + +/** + * Core RDF vocabularies that we use to define semantics + */ + +#define RDF_NAMESPACE_URI "http://www.w3.org/1999/02/22-rdf-syntax-ns#" +#define WEB_NAMESPACE_URI "http://home.netscape.com/WEB-rdf#" +#define NC_NAMESPACE_URI "http://home.netscape.com/NC-rdf#" + +/* ContractID prefixes for RDF DLL registration. */ +#define NS_RDF_CONTRACTID "@mozilla.org/rdf" +#define NS_RDF_DATASOURCE_CONTRACTID NS_RDF_CONTRACTID "/datasource;1" +#define NS_RDF_DATASOURCE_CONTRACTID_PREFIX NS_RDF_DATASOURCE_CONTRACTID "?name=" +#define NS_RDF_RESOURCE_FACTORY_CONTRACTID "@mozilla.org/rdf/resource-factory;1" +#define NS_RDF_RESOURCE_FACTORY_CONTRACTID_PREFIX NS_RDF_RESOURCE_FACTORY_CONTRACTID "?name=" +#define NS_RDF_INFER_DATASOURCE_CONTRACTID_PREFIX NS_RDF_CONTRACTID "/infer-datasource;1?engine=" + +// contract ID is in the form +// @mozilla.org/rdf/delegate-factory;1?key=&scheme= +#define NS_RDF_DELEGATEFACTORY_CONTRACTID "@mozilla.org/rdf/delegate-factory;1" +#define NS_RDF_DELEGATEFACTORY_CONTRACTID_PREFIX NS_RDF_DELEGATEFACTORY_CONTRACTID "?key=" + +/*@}*/ + +#endif /* rdf_h___ */ diff --git a/rdf/base/rdfIDataSource.idl b/rdf/base/rdfIDataSource.idl new file mode 100644 index 000000000000..848cbca117d7 --- /dev/null +++ b/rdf/base/rdfIDataSource.idl @@ -0,0 +1,38 @@ +/* -*- Mode: IDL; 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/. */ + +#include "nsISupports.idl" + +interface rdfITripleVisitor; + +/** + * Interface used in RDF to describe data sources. + * + * @status PLASMA + */ + +[scriptable, uuid(ebce86bd-1568-4a34-a808-9ccf9cde8087)] +interface rdfIDataSource : nsISupports +{ + /** + * Visit all the subject resources in the datasource. The order is + * intederminate and may change from one invocation to the next. + * The subjects will be in the aSubject argument in calls into + * aVisitor, aPredicate and aObject will be null. + * @note Implementations may throw NS_ERROR_NOT_IMPLEMENTED for + * this method, but in this case RDF serializations of this + * datasource will not be possible. + */ + void visitAllSubjects(in rdfITripleVisitor aVisitor); + + /** + * Visit all the triples in the datasource. The order is + * intederminate and may change from one invocation to the next. + * @note Implementations may throw NS_ERROR_NOT_IMPLEMENTED for + * this method, but in this case RDF serializations of this + * datasource will not be possible. + */ + void visitAllTriples(in rdfITripleVisitor aVisitor); +}; diff --git a/rdf/base/rdfITripleVisitor.idl b/rdf/base/rdfITripleVisitor.idl new file mode 100644 index 000000000000..ecac14871567 --- /dev/null +++ b/rdf/base/rdfITripleVisitor.idl @@ -0,0 +1,31 @@ +/* -*- Mode: IDL; 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/. */ + +#include "nsISupports.idl" + +interface nsIRDFResource; +interface nsIRDFNode; + +/** + * Interface used in RDF to enumerate triples. + * Also used by rdfIDataSource::getAllSubjects, then aPredicate, + * aObject and aTruthValue are ignored. + * + * @status PLASMA + */ + +[scriptable, function, uuid(aafea151-c271-4505-9978-a100d292800c)] +interface rdfITripleVisitor : nsISupports +{ + /** + * Callback function for returning query results. + * + * @param aSubject, aPredicate, aObject describe the (sub-)arc + * @returnCode NS_RDF_STOP_VISIT to stop iterating over the query result. + * Any error code will stop the iteration as well. + */ + void visit(in nsIRDFNode aSubject, in nsIRDFResource aPredicate, + in nsIRDFNode aObject, in boolean aTruthValue); +}; diff --git a/rdf/base/rdfutil.cpp b/rdf/base/rdfutil.cpp new file mode 100644 index 000000000000..191ee68d1a26 --- /dev/null +++ b/rdf/base/rdfutil.cpp @@ -0,0 +1,110 @@ +/* -*- 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/. */ + +/* + + Implementations for a bunch of useful RDF utility routines. Many of + these will eventually be exported outside of RDF.DLL via the + nsIRDFService interface. + + TO DO + + 1) Make this so that it doesn't permanently leak the RDF service + object. + + 2) Make container functions thread-safe. They currently don't ensure + that the RDF:nextVal property is maintained safely. + + */ + +#include "nsCOMPtr.h" +#include "nsIRDFDataSource.h" +#include "nsIRDFNode.h" +#include "nsIRDFService.h" +#include "nsIServiceManager.h" +#include "nsIURL.h" +#include "nsIIOService.h" +#include "nsIURL.h" +#include "nsRDFCID.h" +#include "nsString.h" +#include "nsUnicharUtils.h" +#include "rdfutil.h" +#include "prtime.h" + +//////////////////////////////////////////////////////////////////////// + +nsresult +rdf_MakeRelativeRef(const nsACString& aBaseURI, nsCString& aURI) +{ + // This implementation is extremely simple: e.g., it can't compute + // relative paths, or anything fancy like that. If the context URI + // is not a prefix of the URI in question, we'll just bail. + uint32_t prefixLen = aBaseURI.Length(); + if (prefixLen != 0 && StringBeginsWith(aURI, aBaseURI)) { + if (prefixLen < aURI.Length() && aURI.CharAt(prefixLen) == '/') + ++prefixLen; // chop the leading slash so it's not `absolute' + + aURI.Cut(0, prefixLen); + } + + return NS_OK; +} + +void +rdf_FormatDate(PRTime aTime, nsACString &aResult) +{ + // Outputs Unixish date in GMT plus usecs; e.g., + // Wed Jan 9 19:15:13 2002 +002441 + // + PRExplodedTime t; + PR_ExplodeTime(aTime, PR_GMTParameters, &t); + + char buf[256]; + PR_FormatTimeUSEnglish(buf, sizeof buf, "%a %b %d %H:%M:%S %Y", &t); + aResult.Append(buf); + + // usecs + aResult.AppendLiteral(" +"); + int32_t usec = t.tm_usec; + for (int32_t digit = 100000; digit > 1; digit /= 10) { + aResult.Append(char('0' + (usec / digit))); + usec %= digit; + } + aResult.Append(char('0' + usec)); +} + +PRTime +rdf_ParseDate(const nsACString &aTime) +{ + PRTime t; + PR_ParseTimeString(PromiseFlatCString(aTime).get(), true, &t); + + int32_t usec = 0; + + nsACString::const_iterator begin, digit, end; + aTime.BeginReading(begin); + aTime.EndReading(end); + + // Walk backwards until we find a `+', run out of string, or a + // non-numeric character. + digit = end; + while (--digit != begin && *digit != '+') { + if (*digit < '0' || *digit > '9') + break; + } + + if (digit != begin && *digit == '+') { + // There's a usec field specified (or, at least, something + // that looks close enough. Parse it, and add it to the time. + while (++digit != end) { + usec *= 10; + usec += *digit - '0'; + } + + t += usec; + } + + return t; +} diff --git a/rdf/base/rdfutil.h b/rdf/base/rdfutil.h new file mode 100644 index 000000000000..70f9b656437f --- /dev/null +++ b/rdf/base/rdfutil.h @@ -0,0 +1,38 @@ +/* -*- 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/. */ + + +/* + + A bunch of useful RDF utility routines. Many of these will + eventually be exported outside of RDF.DLL via the nsIRDFService + interface. + + TO DO + + 1) Move the anonymous resource stuff to nsIRDFService? + + 2) All that's left is rdf_PossiblyMakeRelative() and + -Absolute(). Maybe those go on nsIRDFService, too. + + */ + +#ifndef rdfutil_h__ +#define rdfutil_h__ + +#include "nsStringFwd.h" + +nsresult +rdf_MakeRelativeRef(const nsACString& aBaseURI, nsCString& aURI); + +void +rdf_FormatDate(PRTime aTime, nsACString &aResult); + +PRTime +rdf_ParseDate(const nsACString &aTime); + +#endif // rdfutil_h__ + + diff --git a/rdf/build/moz.build b/rdf/build/moz.build new file mode 100644 index 000000000000..d7be68954dcd --- /dev/null +++ b/rdf/build/moz.build @@ -0,0 +1,20 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +EXPORTS += [ + 'nsRDFCID.h', +] + +SOURCES += [ + 'nsRDFModule.cpp', +] + +FINAL_LIBRARY = 'xul' + +LOCAL_INCLUDES += [ + '/rdf/base', + '/rdf/datasource', +] diff --git a/rdf/build/nsRDFCID.h b/rdf/build/nsRDFCID.h new file mode 100644 index 000000000000..18d47aed5211 --- /dev/null +++ b/rdf/build/nsRDFCID.h @@ -0,0 +1,76 @@ +/* -*- 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/. */ + +/* + + XPCOM Class IDs for RDF objects that can be constructed via the RDF + factory. + + */ + +#ifndef nsRDFCID_h__ +#define nsRDFCID_h__ + +// {0F78DA56-8321-11d2-8EAC-00805F29F370} +#define NS_RDFDEFAULTRESOURCE_CID \ +{ 0xf78da56, 0x8321, 0x11d2, { 0x8e, 0xac, 0x0, 0x80, 0x5f, 0x29, 0xf3, 0x70 } } + +// {BFD05264-834C-11d2-8EAC-00805F29F370} +#define NS_RDFSERVICE_CID \ +{ 0xbfd05264, 0x834c, 0x11d2, { 0x8e, 0xac, 0x0, 0x80, 0x5f, 0x29, 0xf3, 0x70 } } + +// {BFD0526D-834C-11d2-8EAC-00805F29F370} +#define NS_RDFINMEMORYDATASOURCE_CID \ +{ 0xbfd0526d, 0x834c, 0x11d2, { 0x8e, 0xac, 0x0, 0x80, 0x5f, 0x29, 0xf3, 0x70 } } + +// {E638D760-8687-11d2-B530-000000000001} +#define NS_RDFFILESYSTEMDATASOURCE_CID \ +{ 0xe638d760, 0x8687, 0x11d2, { 0xb5, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x01 } } + +// {6bd1d807-1c67-11d3-9820-ed1b357eb3c4} +#define NS_RDFSEARCHDATASOURCE_CID \ +{ 0x6bd1d807, 0x1c67, 0x11d3, { 0x98, 0x20, 0xed, 0x1b, 0x35, 0x7e, 0xb3, 0xc4 } } + +// {E638D760-8687-11d2-B530-000000000002} +#define NS_RDFFINDDATASOURCE_CID \ +{ 0xe638d760, 0x8687, 0x11d2, { 0xb5, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x02 } } + +// {E638D761-8687-11d2-B530-000000000000} +#define NS_RDFCOMPOSITEDATASOURCE_CID \ +{ 0xe638d761, 0x8687, 0x11d2, { 0xb5, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } } + +// {7BAF62E0-8E61-11d2-8EB1-00805F29F370} +#define NS_RDFXMLDATASOURCE_CID \ +{ 0x7baf62e0, 0x8e61, 0x11d2, { 0x8e, 0xb1, 0x0, 0x80, 0x5f, 0x29, 0xf3, 0x70 } } + +// {0958B101-9ADA-11d2-8EBC-00805F29F370} +#define NS_RDFCONTENTSINK_CID \ +{ 0x958b101, 0x9ada, 0x11d2, { 0x8e, 0xbc, 0x0, 0x80, 0x5f, 0x29, 0xf3, 0x70 } } + +// {1EAAFD60-D596-11d2-80BE-006097B76B8E} +#define NS_RDFHISTORYDATASOURCE_CID \ +{ 0x1eaafd60, 0xd596, 0x11d2, { 0x80, 0xbe, 0x0, 0x60, 0x97, 0xb7, 0x6b, 0x8e } } + +// {D4214E92-FB94-11d2-BDD8-00104BDE6048} +#define NS_RDFCONTAINERUTILS_CID \ +{ 0xd4214e92, 0xfb94, 0x11d2, { 0xbd, 0xd8, 0x0, 0x10, 0x4b, 0xde, 0x60, 0x48 } } + +// {D4214E93-FB94-11d2-BDD8-00104BDE6048} +#define NS_RDFCONTAINER_CID \ +{ 0xd4214e93, 0xfb94, 0x11d2, { 0xbd, 0xd8, 0x0, 0x10, 0x4b, 0xde, 0x60, 0x48 } } + +// {0032d852-1dd2-11b2-95f7-e0a1910ed2da} +#define NS_RDFXMLSERIALIZER_CID \ +{ 0x0032d852, 0x1dd2, 0x11b2, { 0x95, 0xf7, 0xe0, 0xa1, 0x91, 0x0e, 0xd2, 0xda } } + +// {a4048e94-1dd1-11b2-a676-8a06c086cc7d} +#define NS_RDFXMLPARSER_CID \ +{ 0xa4048e94, 0x1dd1, 0x11b2, { 0xa6, 0x76, 0x8a, 0x06, 0xc0, 0x86, 0xcc, 0x7d } } + +// {0a5cd734-eb65-4d14-88a0-9f0bb2aba206} +#define NS_RDFNTRIPLES_SERIALIZER_CID \ +{ 0x0a5cd734, 0xeb65, 0x4d14, { 0x88, 0xa0, 0x9f, 0x0b, 0xb2, 0xab, 0xa2, 0x06 } } + +#endif // nsRDFCID_h__ diff --git a/rdf/build/nsRDFModule.cpp b/rdf/build/nsRDFModule.cpp new file mode 100644 index 000000000000..3828fdd50bc7 --- /dev/null +++ b/rdf/build/nsRDFModule.cpp @@ -0,0 +1,120 @@ +/* -*- 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/. */ +#include "nsCOMPtr.h" +#include "mozilla/ModuleUtils.h" + +#include "nsIFactory.h" +#include "nsRDFService.h" +#include "nsIRDFContainer.h" +#include "nsIRDFContainerUtils.h" +#include "nsIRDFCompositeDataSource.h" +#include "nsIRDFContentSink.h" +#include "nsISupports.h" +#include "nsRDFBaseDataSources.h" +#include "nsRDFBuiltInDataSources.h" +#include "nsRDFCID.h" +#include "nsIComponentManager.h" +#include "rdf.h" +#include "nsIServiceManager.h" +#include "nsILocalStore.h" +#include "nsRDFXMLParser.h" +#include "nsRDFXMLSerializer.h" + +//---------------------------------------------------------------------- + +// Functions used to create new instances of a given object by the +// generic factory. + +#define MAKE_CTOR(_func,_new,_ifname) \ +static nsresult \ +CreateNew##_func(nsISupports* aOuter, REFNSIID aIID, void **aResult) \ +{ \ + if (!aResult) { \ + return NS_ERROR_INVALID_POINTER; \ + } \ + if (aOuter) { \ + *aResult = nullptr; \ + return NS_ERROR_NO_AGGREGATION; \ + } \ + nsI##_ifname* inst; \ + nsresult rv = NS_New##_new(&inst); \ + if (NS_FAILED(rv)) { \ + *aResult = nullptr; \ + return rv; \ + } \ + rv = inst->QueryInterface(aIID, aResult); \ + if (NS_FAILED(rv)) { \ + *aResult = nullptr; \ + } \ + NS_RELEASE(inst); /* get rid of extra refcnt */ \ + return rv; \ +} + +extern nsresult +NS_NewDefaultResource(nsIRDFResource** aResult); + +MAKE_CTOR(RDFXMLDataSource,RDFXMLDataSource,RDFDataSource) +MAKE_CTOR(RDFCompositeDataSource,RDFCompositeDataSource,RDFCompositeDataSource) +MAKE_CTOR(RDFContainer,RDFContainer,RDFContainer) + +MAKE_CTOR(RDFContainerUtils,RDFContainerUtils,RDFContainerUtils) + +MAKE_CTOR(RDFContentSink,RDFContentSink,RDFContentSink) +MAKE_CTOR(RDFDefaultResource,DefaultResource,RDFResource) + +NS_DEFINE_NAMED_CID(NS_RDFCOMPOSITEDATASOURCE_CID); +NS_DEFINE_NAMED_CID(NS_RDFINMEMORYDATASOURCE_CID); +NS_DEFINE_NAMED_CID(NS_RDFXMLDATASOURCE_CID); +NS_DEFINE_NAMED_CID(NS_RDFDEFAULTRESOURCE_CID); +NS_DEFINE_NAMED_CID(NS_RDFCONTENTSINK_CID); +NS_DEFINE_NAMED_CID(NS_RDFCONTAINER_CID); +NS_DEFINE_NAMED_CID(NS_RDFCONTAINERUTILS_CID); +NS_DEFINE_NAMED_CID(NS_RDFSERVICE_CID); +NS_DEFINE_NAMED_CID(NS_RDFXMLPARSER_CID); +NS_DEFINE_NAMED_CID(NS_RDFXMLSERIALIZER_CID); +NS_DEFINE_NAMED_CID(NS_LOCALSTORE_CID); + + +static const mozilla::Module::CIDEntry kRDFCIDs[] = { + { &kNS_RDFCOMPOSITEDATASOURCE_CID, false, nullptr, CreateNewRDFCompositeDataSource }, + { &kNS_RDFINMEMORYDATASOURCE_CID, false, nullptr, NS_NewRDFInMemoryDataSource }, + { &kNS_RDFXMLDATASOURCE_CID, false, nullptr, CreateNewRDFXMLDataSource }, + { &kNS_RDFDEFAULTRESOURCE_CID, false, nullptr, CreateNewRDFDefaultResource }, + { &kNS_RDFCONTENTSINK_CID, false, nullptr, CreateNewRDFContentSink }, + { &kNS_RDFCONTAINER_CID, false, nullptr, CreateNewRDFContainer }, + { &kNS_RDFCONTAINERUTILS_CID, false, nullptr, CreateNewRDFContainerUtils }, + { &kNS_RDFSERVICE_CID, false, nullptr, RDFServiceImpl::CreateSingleton }, + { &kNS_RDFXMLPARSER_CID, false, nullptr, nsRDFXMLParser::Create }, + { &kNS_RDFXMLSERIALIZER_CID, false, nullptr, nsRDFXMLSerializer::Create }, + { &kNS_LOCALSTORE_CID, false, nullptr, NS_NewLocalStore }, + { nullptr } +}; + +static const mozilla::Module::ContractIDEntry kRDFContracts[] = { + { NS_RDF_DATASOURCE_CONTRACTID_PREFIX "composite-datasource", &kNS_RDFCOMPOSITEDATASOURCE_CID }, + { NS_RDF_DATASOURCE_CONTRACTID_PREFIX "in-memory-datasource", &kNS_RDFINMEMORYDATASOURCE_CID }, + { NS_RDF_DATASOURCE_CONTRACTID_PREFIX "xml-datasource", &kNS_RDFXMLDATASOURCE_CID }, + { NS_RDF_RESOURCE_FACTORY_CONTRACTID, &kNS_RDFDEFAULTRESOURCE_CID }, + { NS_RDF_CONTRACTID "/content-sink;1", &kNS_RDFCONTENTSINK_CID }, + { NS_RDF_CONTRACTID "/container;1", &kNS_RDFCONTAINER_CID }, + { NS_RDF_CONTRACTID "/container-utils;1", &kNS_RDFCONTAINERUTILS_CID }, + { NS_RDF_CONTRACTID "/rdf-service;1", &kNS_RDFSERVICE_CID }, + { NS_RDF_CONTRACTID "/xml-parser;1", &kNS_RDFXMLPARSER_CID }, + { NS_RDF_CONTRACTID "/xml-serializer;1", &kNS_RDFXMLSERIALIZER_CID }, + { NS_LOCALSTORE_CONTRACTID, &kNS_LOCALSTORE_CID }, + { nullptr } +}; + +static const mozilla::Module kRDFModule = { + mozilla::Module::kVersion, + kRDFCIDs, + kRDFContracts, + nullptr, + nullptr, + nullptr, + nullptr +}; + +NSMODULE_DEFN(nsRDFModule) = &kRDFModule; diff --git a/rdf/datasource/moz.build b/rdf/datasource/moz.build new file mode 100644 index 000000000000..8267d67e2289 --- /dev/null +++ b/rdf/datasource/moz.build @@ -0,0 +1,21 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +EXPORTS += [ + 'nsILocalStore.h', +] + +UNIFIED_SOURCES += [ + 'nsLocalStore.cpp', +] + +FINAL_LIBRARY = 'xul' + +# "This is a dependency on rdfutil.h: it'll go away once that becomes +# a first-class XPCOM interface." +LOCAL_INCLUDES += [ + '/rdf/base', +] diff --git a/rdf/datasource/nsILocalStore.h b/rdf/datasource/nsILocalStore.h new file mode 100644 index 000000000000..b4122659376c --- /dev/null +++ b/rdf/datasource/nsILocalStore.h @@ -0,0 +1,34 @@ +/* -*- 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/. */ + +#ifndef nsILocalStore_h__ +#define nsILocalStore_h__ + +#include "rdf.h" +#include "nsISupports.h" + +// {DF71C6F1-EC53-11d2-BDCA-000064657374} +#define NS_ILOCALSTORE_IID \ +{ 0xdf71c6f1, 0xec53, 0x11d2, { 0xbd, 0xca, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } } + +// {DF71C6F0-EC53-11d2-BDCA-000064657374} +#define NS_LOCALSTORE_CID \ +{ 0xdf71c6f0, 0xec53, 0x11d2, { 0xbd, 0xca, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } } + +#define NS_LOCALSTORE_CONTRACTID NS_RDF_DATASOURCE_CONTRACTID_PREFIX "local-store" + +class nsILocalStore : public nsISupports +{ +public: + NS_DECLARE_STATIC_IID_ACCESSOR(NS_ILOCALSTORE_IID) +}; + +NS_DEFINE_STATIC_IID_ACCESSOR(nsILocalStore, NS_ILOCALSTORE_IID) + +extern nsresult +NS_NewLocalStore(nsISupports* aOuter, REFNSIID aIID, void** aResult); + + +#endif // nsILocalStore_h__ diff --git a/rdf/datasource/nsIRDFFTP.h b/rdf/datasource/nsIRDFFTP.h new file mode 100644 index 000000000000..8965b4a3825a --- /dev/null +++ b/rdf/datasource/nsIRDFFTP.h @@ -0,0 +1,33 @@ +/* -*- 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/. */ + +#ifndef nsIRDFFTP_h__ +#define nsIRDFFTP_h__ + +#include "nscore.h" +#include "nsISupports.h" +#include "nsIRDFNode.h" + + + +#define NS_IRDFFTPDATAOURCE_IID \ +{ 0x1222e6f0, 0xa5e3, 0x11d2, { 0x8b, 0x7c, 0x00, 0x80, 0x5f, 0x8a, 0x7d, 0xb7 } } + +class nsIRDFFTPDataSource : public nsIRDFDataSource +{ +public: +}; + + +#define NS_IRDFFTPDATASOURCECALLBACK_IID \ +{ 0x204a1a00, 0xa5e4, 0x11d2, { 0x8b, 0x7c, 0x00, 0x80, 0x5f, 0x8a, 0x7d, 0xb8 } } + +class nsIRDFFTPDataSourceCallback : public nsIStreamListener +{ +public: +}; + + +#endif // nsIRDFFTP_h__ diff --git a/rdf/datasource/nsLocalStore.cpp b/rdf/datasource/nsLocalStore.cpp new file mode 100644 index 000000000000..25ad3e0ccee0 --- /dev/null +++ b/rdf/datasource/nsLocalStore.cpp @@ -0,0 +1,474 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* vim: set cindent tabstop=4 expandtab shiftwidth=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/. */ + +/* + + Implementation for the local store + + */ + +#include "nsNetUtil.h" +#include "nsIFile.h" +#include "nsIURI.h" +#include "nsIIOService.h" +#include "nsIOutputStream.h" +#include "nsIComponentManager.h" +#include "nsILocalStore.h" +#include "nsIRDFDataSource.h" +#include "nsIRDFRemoteDataSource.h" +#include "nsIRDFService.h" +#include "nsIServiceManager.h" +#include "nsRDFCID.h" +#include "nsString.h" +#include "plstr.h" +#include "rdf.h" +#include "nsCOMPtr.h" +#include "nsWeakPtr.h" +#include "nsAppDirectoryServiceDefs.h" +#include "nsIObserver.h" +#include "nsIObserverService.h" +#include "nsWeakReference.h" +#include "nsCRTGlue.h" +#include "nsCRT.h" +#include "nsEnumeratorUtils.h" +#include "nsCycleCollectionParticipant.h" + +//////////////////////////////////////////////////////////////////////// + +class LocalStoreImpl : public nsILocalStore, + public nsIRDFDataSource, + public nsIRDFRemoteDataSource, + public nsIObserver, + public nsSupportsWeakReference +{ +protected: + nsCOMPtr mInner; + + LocalStoreImpl(); + virtual ~LocalStoreImpl(); + nsresult Init(); + nsresult CreateLocalStore(nsIFile* aFile); + nsresult LoadData(); + + friend nsresult + NS_NewLocalStore(nsISupports* aOuter, REFNSIID aIID, void** aResult); + + nsCOMPtr mRDFService; + +public: + // nsISupports interface + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(LocalStoreImpl, nsILocalStore) + + // nsILocalStore interface + + // nsIRDFDataSource interface. Most of these are just delegated to + // the inner, in-memory datasource. + NS_IMETHOD GetURI(nsACString& aURI) override; + + NS_IMETHOD GetSource(nsIRDFResource* aProperty, + nsIRDFNode* aTarget, + bool aTruthValue, + nsIRDFResource** aSource) override { + return mInner->GetSource(aProperty, aTarget, aTruthValue, aSource); + } + + NS_IMETHOD GetSources(nsIRDFResource* aProperty, + nsIRDFNode* aTarget, + bool aTruthValue, + nsISimpleEnumerator** aSources) override { + return mInner->GetSources(aProperty, aTarget, aTruthValue, aSources); + } + + NS_IMETHOD GetTarget(nsIRDFResource* aSource, + nsIRDFResource* aProperty, + bool aTruthValue, + nsIRDFNode** aTarget) override { + return mInner->GetTarget(aSource, aProperty, aTruthValue, aTarget); + } + + NS_IMETHOD GetTargets(nsIRDFResource* aSource, + nsIRDFResource* aProperty, + bool aTruthValue, + nsISimpleEnumerator** aTargets) override { + return mInner->GetTargets(aSource, aProperty, aTruthValue, aTargets); + } + + NS_IMETHOD Assert(nsIRDFResource* aSource, + nsIRDFResource* aProperty, + nsIRDFNode* aTarget, + bool aTruthValue) override { + return mInner->Assert(aSource, aProperty, aTarget, aTruthValue); + } + + NS_IMETHOD Unassert(nsIRDFResource* aSource, + nsIRDFResource* aProperty, + nsIRDFNode* aTarget) override { + return mInner->Unassert(aSource, aProperty, aTarget); + } + + NS_IMETHOD Change(nsIRDFResource* aSource, + nsIRDFResource* aProperty, + nsIRDFNode* aOldTarget, + nsIRDFNode* aNewTarget) override { + return mInner->Change(aSource, aProperty, aOldTarget, aNewTarget); + } + + NS_IMETHOD Move(nsIRDFResource* aOldSource, + nsIRDFResource* aNewSource, + nsIRDFResource* aProperty, + nsIRDFNode* aTarget) override { + return mInner->Move(aOldSource, aNewSource, aProperty, aTarget); + } + + NS_IMETHOD HasAssertion(nsIRDFResource* aSource, + nsIRDFResource* aProperty, + nsIRDFNode* aTarget, + bool aTruthValue, + bool* hasAssertion) override { + return mInner->HasAssertion(aSource, aProperty, aTarget, aTruthValue, hasAssertion); + } + + NS_IMETHOD AddObserver(nsIRDFObserver* aObserver) override { + return NS_ERROR_NOT_IMPLEMENTED; + } + + NS_IMETHOD RemoveObserver(nsIRDFObserver* aObserver) override { + return NS_ERROR_NOT_IMPLEMENTED; + } + + NS_IMETHOD HasArcIn(nsIRDFNode *aNode, nsIRDFResource *aArc, bool *_retval) override { + return mInner->HasArcIn(aNode, aArc, _retval); + } + + NS_IMETHOD HasArcOut(nsIRDFResource *aSource, nsIRDFResource *aArc, bool *_retval) override { + return mInner->HasArcOut(aSource, aArc, _retval); + } + + NS_IMETHOD ArcLabelsIn(nsIRDFNode* aNode, + nsISimpleEnumerator** aLabels) override { + return mInner->ArcLabelsIn(aNode, aLabels); + } + + NS_IMETHOD ArcLabelsOut(nsIRDFResource* aSource, + nsISimpleEnumerator** aLabels) override { + return mInner->ArcLabelsOut(aSource, aLabels); + } + + NS_IMETHOD GetAllResources(nsISimpleEnumerator** aResult) override { + return mInner->GetAllResources(aResult); + } + + NS_IMETHOD GetAllCmds(nsIRDFResource* aSource, + nsISimpleEnumerator/**/** aCommands) override; + + NS_IMETHOD IsCommandEnabled(nsISupports* aSources, + nsIRDFResource* aCommand, + nsISupports* aArguments, + bool* aResult) override; + + NS_IMETHOD DoCommand(nsISupports* aSources, + nsIRDFResource* aCommand, + nsISupports* aArguments) override; + + NS_IMETHOD BeginUpdateBatch() override { + return mInner->BeginUpdateBatch(); + } + + NS_IMETHOD EndUpdateBatch() override { + return mInner->EndUpdateBatch(); + } + + NS_IMETHOD GetLoaded(bool* _result) override; + NS_IMETHOD Init(const char *uri) override; + NS_IMETHOD Flush() override; + NS_IMETHOD FlushTo(const char *aURI) override; + NS_IMETHOD Refresh(bool sync) override; + + // nsIObserver + NS_DECL_NSIOBSERVER +}; + +//////////////////////////////////////////////////////////////////////// + + +LocalStoreImpl::LocalStoreImpl(void) +{ +} + +LocalStoreImpl::~LocalStoreImpl(void) +{ + if (mRDFService) + mRDFService->UnregisterDataSource(this); +} + + +nsresult +NS_NewLocalStore(nsISupports* aOuter, REFNSIID aIID, void** aResult) +{ + NS_PRECONDITION(aOuter == nullptr, "no aggregation"); + if (aOuter) + return NS_ERROR_NO_AGGREGATION; + + NS_PRECONDITION(aResult != nullptr, "null ptr"); + if (! aResult) + return NS_ERROR_NULL_POINTER; + + LocalStoreImpl* impl = new LocalStoreImpl(); + if (! impl) + return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(impl); + + nsresult rv; + rv = impl->Init(); + if (NS_SUCCEEDED(rv)) { + // Set up the result pointer + rv = impl->QueryInterface(aIID, aResult); + } + + NS_RELEASE(impl); + return rv; +} + +NS_IMPL_CYCLE_COLLECTION(LocalStoreImpl, mInner) +NS_IMPL_CYCLE_COLLECTING_ADDREF(LocalStoreImpl) +NS_IMPL_CYCLE_COLLECTING_RELEASE(LocalStoreImpl) + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(LocalStoreImpl) + NS_INTERFACE_MAP_ENTRY(nsILocalStore) + NS_INTERFACE_MAP_ENTRY(nsIRDFDataSource) + NS_INTERFACE_MAP_ENTRY(nsIRDFRemoteDataSource) + NS_INTERFACE_MAP_ENTRY(nsIObserver) + NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsILocalStore) +NS_INTERFACE_MAP_END + +// nsILocalStore interface + +// nsIRDFDataSource interface + +NS_IMETHODIMP +LocalStoreImpl::GetLoaded(bool* _result) +{ + nsCOMPtr remote = do_QueryInterface(mInner); + NS_ASSERTION(remote != nullptr, "not an nsIRDFRemoteDataSource"); + if (! remote) + return NS_ERROR_UNEXPECTED; + + return remote->GetLoaded(_result); +} + + +NS_IMETHODIMP +LocalStoreImpl::Init(const char *uri) +{ + return(NS_OK); +} + +NS_IMETHODIMP +LocalStoreImpl::Flush() +{ + nsCOMPtr remote = do_QueryInterface(mInner); + // FIXME Bug 340242: Temporarily make this a warning rather than an + // assertion until we sort out the ordering of how we write + // everything to the localstore, flush it, and disconnect it when + // we're getting profile-change notifications. + NS_WARNING_ASSERTION(remote != nullptr, "not an nsIRDFRemoteDataSource"); + if (! remote) + return NS_ERROR_UNEXPECTED; + + return remote->Flush(); +} + +NS_IMETHODIMP +LocalStoreImpl::FlushTo(const char *aURI) +{ + // Do not ever implement this (security) + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +LocalStoreImpl::Refresh(bool sync) +{ + nsCOMPtr remote = do_QueryInterface(mInner); + NS_ASSERTION(remote != nullptr, "not an nsIRDFRemoteDataSource"); + if (! remote) + return NS_ERROR_UNEXPECTED; + + return remote->Refresh(sync); +} + +nsresult +LocalStoreImpl::Init() +{ + nsresult rv; + + rv = LoadData(); + if (NS_FAILED(rv)) return rv; + + // register this as a named data source with the RDF service + mRDFService = do_GetService(NS_RDF_CONTRACTID "/rdf-service;1", &rv); + if (NS_FAILED(rv)) return rv; + + mRDFService->RegisterDataSource(this, false); + + // Register as an observer of profile changes + nsCOMPtr obs = + do_GetService("@mozilla.org/observer-service;1"); + + if (obs) { + obs->AddObserver(this, "profile-before-change", true); + obs->AddObserver(this, "profile-do-change", true); + } + + return NS_OK; +} + +nsresult +LocalStoreImpl::CreateLocalStore(nsIFile* aFile) +{ + nsresult rv; + + rv = aFile->Create(nsIFile::NORMAL_FILE_TYPE, 0666); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr outStream; + rv = NS_NewLocalFileOutputStream(getter_AddRefs(outStream), aFile); + if (NS_FAILED(rv)) return rv; + + const char defaultRDF[] = + "\n" \ + "\n" \ + " \n" \ + "\n"; + + uint32_t count; + rv = outStream->Write(defaultRDF, sizeof(defaultRDF)-1, &count); + if (NS_FAILED(rv)) return rv; + + if (count != sizeof(defaultRDF)-1) + return NS_ERROR_UNEXPECTED; + + // Okay, now see if the file exists _for real_. If it's still + // not there, it could be that the profile service gave us + // back a read-only directory. Whatever. + bool fileExistsFlag = false; + aFile->Exists(&fileExistsFlag); + if (!fileExistsFlag) + return NS_ERROR_UNEXPECTED; + + return NS_OK; +} + +nsresult +LocalStoreImpl::LoadData() +{ + nsresult rv; + + // Look for localstore.rdf in the current profile + // directory. Bomb if we can't find it. + + nsCOMPtr aFile; + rv = NS_GetSpecialDirectory(NS_APP_LOCALSTORE_50_FILE, getter_AddRefs(aFile)); + if (NS_FAILED(rv)) return rv; + + bool fileExistsFlag = false; + (void)aFile->Exists(&fileExistsFlag); + if (!fileExistsFlag) { + // if file doesn't exist, create it + rv = CreateLocalStore(aFile); + if (NS_FAILED(rv)) return rv; + } + + mInner = do_CreateInstance(NS_RDF_DATASOURCE_CONTRACTID_PREFIX "xml-datasource", &rv); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr remote = do_QueryInterface(mInner, &rv); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr aURI; + rv = NS_NewFileURI(getter_AddRefs(aURI), aFile); + if (NS_FAILED(rv)) return rv; + + nsAutoCString spec; + rv = aURI->GetSpec(spec); + if (NS_FAILED(rv)) return rv; + + rv = remote->Init(spec.get()); + if (NS_FAILED(rv)) return rv; + + // Read the datasource synchronously. + rv = remote->Refresh(true); + + if (NS_FAILED(rv)) { + // Load failed, delete and recreate a fresh localstore + aFile->Remove(true); + rv = CreateLocalStore(aFile); + if (NS_FAILED(rv)) return rv; + + rv = remote->Refresh(true); + } + + return rv; +} + + +NS_IMETHODIMP +LocalStoreImpl::GetURI(nsACString& aURI) +{ + aURI.AssignLiteral("rdf:local-store"); + return NS_OK; +} + + +NS_IMETHODIMP +LocalStoreImpl::GetAllCmds(nsIRDFResource* aSource, + nsISimpleEnumerator/**/** aCommands) +{ + return(NS_NewEmptyEnumerator(aCommands)); +} + +NS_IMETHODIMP +LocalStoreImpl::IsCommandEnabled(nsISupports* aSources, + nsIRDFResource* aCommand, + nsISupports* aArguments, + bool* aResult) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +LocalStoreImpl::DoCommand(nsISupports* aSources, + nsIRDFResource* aCommand, + nsISupports* aArguments) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +LocalStoreImpl::Observe(nsISupports *aSubject, const char *aTopic, const char16_t *someData) +{ + nsresult rv = NS_OK; + + if (!nsCRT::strcmp(aTopic, "profile-before-change")) { + // Write out the old datasource's contents. + if (mInner) { + nsCOMPtr remote = do_QueryInterface(mInner); + if (remote) + remote->Flush(); + } + + // Create an in-memory datasource for use while we're + // profile-less. + mInner = do_CreateInstance(NS_RDF_DATASOURCE_CONTRACTID_PREFIX "in-memory-datasource"); + } + else if (!nsCRT::strcmp(aTopic, "profile-do-change")) { + rv = LoadData(); + } + return rv; +} diff --git a/rdf/datasource/nsRDFBuiltInDataSources.h b/rdf/datasource/nsRDFBuiltInDataSources.h new file mode 100644 index 000000000000..297fe71640dd --- /dev/null +++ b/rdf/datasource/nsRDFBuiltInDataSources.h @@ -0,0 +1,27 @@ +/* -*- 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 header file just contains prototypes for the factory methods + for "builtin" data sources that are included in rdf.dll. + + Each of these data sources is exposed to the external world via its + CID in ../include/nsRDFCID.h. + + */ + +#ifndef nsBuiltinDataSources_h__ +#define nsBuiltinDataSources_h__ + +#include "nsError.h" + +class nsIRDFDataSource; + +// in nsFileSystemDataSource.cpp +nsresult NS_NewRDFFileSystemDataSource(nsIRDFDataSource** result); + +#endif // nsBuiltinDataSources_h__ + diff --git a/rdf/moz.build b/rdf/moz.build new file mode 100644 index 000000000000..6f678fed085b --- /dev/null +++ b/rdf/moz.build @@ -0,0 +1,12 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +with Files('**'): + BUG_COMPONENT = ('Core', 'RDF') + +DIRS += ['base', 'datasource', 'build'] +TEST_DIRS += ['tests'] + diff --git a/rdf/tests/moz.build b/rdf/tests/moz.build new file mode 100644 index 000000000000..d8fb7519d5da --- /dev/null +++ b/rdf/tests/moz.build @@ -0,0 +1,7 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +XPCSHELL_TESTS_MANIFESTS += ['unit/xpcshell.ini'] diff --git a/rdf/tests/unit/sample.rdf b/rdf/tests/unit/sample.rdf new file mode 100755 index 000000000000..42de8cd08b9f --- /dev/null +++ b/rdf/tests/unit/sample.rdf @@ -0,0 +1,9 @@ + + + + + + + diff --git a/rdf/tests/unit/test_rdfredirect.js b/rdf/tests/unit/test_rdfredirect.js new file mode 100644 index 000000000000..f3c076ba7a61 --- /dev/null +++ b/rdf/tests/unit/test_rdfredirect.js @@ -0,0 +1,92 @@ +ChromeUtils.import("resource://testing-common/httpd.js"); + +function getRDFService() +{ + return Cc["@mozilla.org/rdf/rdf-service;1"]. + getService(Ci.nsIRDFService); +} + +var server1, server2; + +function run_test() +{ + var samplefile = do_get_file('sample.rdf'); + + server1 = new HttpServer(); + server1.registerPathHandler("/sample-xs.rdf", xsRedirect); + server1.registerPathHandler("/sample-local.rdf", localRedirect); + server1.registerFile('/sample.rdf', samplefile); + server1.start(4444); + + server2 = new HttpServer(); + server2.registerFile('/sample.rdf', samplefile); + server2.start(4445); + + do_test_pending(); + + new rdfLoadObserver('http://localhost:4444/sample.rdf', true); + new rdfLoadObserver('http://localhost:4445/sample.rdf', true); + new rdfLoadObserver('http://localhost:4444/sample-xs.rdf', false); + new rdfLoadObserver('http://localhost:4444/sample-local.rdf', true); +} + +var gPending = 0; + +function rdfLoadObserver(uri, shouldPass) +{ + this.shouldPass = shouldPass; + this.uri = uri; + + ++gPending; + + var rdfService = getRDFService(); + this.ds = rdfService.GetDataSource(uri). + QueryInterface(Ci.nsIRDFXMLSink); + this.ds.addXMLSinkObserver(this); +} + +rdfLoadObserver.prototype = +{ + onBeginLoad : function() { }, + onInterrupt : function() { }, + onResume : function() { }, + onEndLoad : function() { + print("Testing results of loading " + this.uri); + + var rdfs = getRDFService(); + var res = rdfs.GetResource("urn:mozilla:sample-data"); + var arc = rdfs.GetResource("http://purl.org/dc/elements/1.1/title"); + var answer = this.ds.GetTarget(res, arc, true); + if (answer !== null) { + Assert.ok(this.shouldPass); + Assert.ok(answer instanceof Ci.nsIRDFLiteral); + Assert.equal(answer.Value, "Sample"); + } + else { + Assert.ok(!this.shouldPass); + } + + gPending -= 1; + + this.ds.removeXMLSinkObserver(this); + + if (gPending == 0) { + do_test_pending(); + server1.stop(do_test_finished); + server2.stop(do_test_finished); + } + }, + onError : function() { } +} + +function xsRedirect(metadata, response) +{ + response.setStatusLine(metadata.httpVersion, 301, "Moved Permanently"); + response.setHeader("Location", "http://localhost:4445/sample.rdf", false); +} + +function localRedirect(metadata, response) +{ + response.setStatusLine(metadata.httpVersion, 301, "Moved Permanently"); + response.setHeader("Location", "http://localhost:4444/sample.rdf", false); +} diff --git a/rdf/tests/unit/xpcshell.ini b/rdf/tests/unit/xpcshell.ini new file mode 100644 index 000000000000..4cea6cc1421e --- /dev/null +++ b/rdf/tests/unit/xpcshell.ini @@ -0,0 +1,5 @@ +[DEFAULT] +head = +support-files = sample.rdf + +[test_rdfredirect.js] diff --git a/toolkit/components/build/nsToolkitCompsModule.cpp b/toolkit/components/build/nsToolkitCompsModule.cpp index 6d6fad377756..ed0bc38b663e 100644 --- a/toolkit/components/build/nsToolkitCompsModule.cpp +++ b/toolkit/components/build/nsToolkitCompsModule.cpp @@ -20,6 +20,7 @@ #include "nsAlertsService.h" #include "DownloadPlatform.h" +#include "rdf.h" #include "nsTypeAheadFind.h" diff --git a/toolkit/components/utils/simpleServices.js b/toolkit/components/utils/simpleServices.js index 75bb9a02508e..90cee5272ee1 100644 --- a/toolkit/components/utils/simpleServices.js +++ b/toolkit/components/utils/simpleServices.js @@ -21,11 +21,6 @@ ChromeUtils.defineModuleGetter(this, "NetUtil", ChromeUtils.defineModuleGetter(this, "Services", "resource://gre/modules/Services.jsm"); -XPCOMUtils.defineLazyServiceGetter(this, "catMan", "@mozilla.org/categorymanager;1", - "nsICategoryManager"); -XPCOMUtils.defineLazyServiceGetter(this, "streamConv", "@mozilla.org/streamConverters;1", - "nsIStreamConverterService"); - /* * This class provides a stream filter for locale messages in CSS files served * by the moz-extension: protocol handler. @@ -116,32 +111,4 @@ AddonLocalizationConverter.prototype = { }, }; -function HttpIndexViewer() { -} - -HttpIndexViewer.prototype = { - classID: Components.ID("{742ad274-34c5-43d1-a8b7-293eaf8962d6}"), - QueryInterface: ChromeUtils.generateQI([Ci.nsIDocumentLoaderFactory]), - - createInstance(aCommand, aChannel, aLoadGroup, aContentType, aContainer, - aExtraInfo, aDocListenerResult) { - aChannel.contentType = "text/html"; - - let contract = catMan.getCategoryEntry("Gecko-Content-Viewers", "text/html"); - let factory = Cc[contract].getService(Ci.nsIDocumentLoaderFactory); - - let listener = {}; - let res = factory.createInstance("view", aChannel, aLoadGroup, - "text/html", aContainer, aExtraInfo, - listener); - - aDocListenerResult.value = - streamConv.asyncConvertData("application/http-index-format", - "text/html", listener.value, null); - - return res; - }, -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([AddonLocalizationConverter, - HttpIndexViewer]); +this.NSGetFactory = XPCOMUtils.generateNSGetFactory([AddonLocalizationConverter]); diff --git a/toolkit/components/utils/utils.manifest b/toolkit/components/utils/utils.manifest index fa266f7322d2..cd45ff07d8a6 100644 --- a/toolkit/components/utils/utils.manifest +++ b/toolkit/components/utils/utils.manifest @@ -2,7 +2,3 @@ component {dfd07380-6083-11e4-9803-0800200c9a66} simpleServices.js contract @mozilla.org/addons/remote-tag-service;1 {dfd07380-6083-11e4-9803-0800200c9a66} component {ded150e3-c92e-4077-a396-0dba9953e39f} simpleServices.js contract @mozilla.org/streamconv;1?from=application/vnd.mozilla.webext.unlocalized&to=text/css {ded150e3-c92e-4077-a396-0dba9953e39f} - -component {742ad274-34c5-43d1-a8b7-293eaf8962d6} simpleServices.js -contract @mozilla.org/content-viewsers/http-index-format {742ad274-34c5-43d1-a8b7-293eaf8962d6} -category Gecko-Content-Viewers application/http-index-format @mozilla.org/content-viewsers/http-index-format diff --git a/toolkit/toolkit.mozbuild b/toolkit/toolkit.mozbuild index d6e171025d8d..8162a0d81a25 100644 --- a/toolkit/toolkit.mozbuild +++ b/toolkit/toolkit.mozbuild @@ -88,6 +88,10 @@ DIRS += [ '/extensions/permissions', ] +DIRS += [ + '/rdf', +] + if CONFIG['MOZ_WEBRTC'] and CONFIG['COMPILE_ENVIRONMENT']: DIRS += [ '/media/webrtc', @@ -131,6 +135,7 @@ DIRS += [ '/tools/code-coverage', '/tools/power', '/tools/profiler', + '/xpfe/components', ] if CONFIG['MOZ_ENABLE_XREMOTE']: diff --git a/xpfe/components/build/moz.build b/xpfe/components/build/moz.build new file mode 100644 index 000000000000..c8f67f9e7884 --- /dev/null +++ b/xpfe/components/build/moz.build @@ -0,0 +1,18 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +with Files("**"): + BUG_COMPONENT = ("Core", "Window Management") + +SOURCES += [ + 'nsModule.cpp', +] + +FINAL_LIBRARY = 'xul' + +LOCAL_INCLUDES += [ + '../directory', +] diff --git a/xpfe/components/build/nsModule.cpp b/xpfe/components/build/nsModule.cpp new file mode 100644 index 000000000000..43966f94d1f2 --- /dev/null +++ b/xpfe/components/build/nsModule.cpp @@ -0,0 +1,44 @@ +/* -*- 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/. */ + +#include "mozilla/ModuleUtils.h" +#include "nsDirectoryViewer.h" +#include "rdf.h" +#include "nsRDFCID.h" +#include "nsCURILoader.h" + +// Factory constructors +NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsHTTPIndex, Init) +NS_GENERIC_FACTORY_CONSTRUCTOR(nsDirectoryViewerFactory) + +NS_DEFINE_NAMED_CID(NS_DIRECTORYVIEWERFACTORY_CID); +NS_DEFINE_NAMED_CID(NS_HTTPINDEX_SERVICE_CID); + +static const mozilla::Module::CIDEntry kXPFECIDs[] = { + { &kNS_DIRECTORYVIEWERFACTORY_CID, false, nullptr, nsDirectoryViewerFactoryConstructor }, + { &kNS_HTTPINDEX_SERVICE_CID, false, nullptr, nsHTTPIndexConstructor }, + { nullptr } +}; + +static const mozilla::Module::ContractIDEntry kXPFEContracts[] = { + { "@mozilla.org/xpfe/http-index-format-factory-constructor", &kNS_DIRECTORYVIEWERFACTORY_CID }, + { NS_HTTPINDEX_SERVICE_CONTRACTID, &kNS_HTTPINDEX_SERVICE_CID }, + { NS_HTTPINDEX_DATASOURCE_CONTRACTID, &kNS_HTTPINDEX_SERVICE_CID }, + { nullptr } +}; + +static const mozilla::Module::CategoryEntry kXPFECategories[] = { + { "Gecko-Content-Viewers", "application/http-index-format", "@mozilla.org/xpfe/http-index-format-factory-constructor" }, + { nullptr } +}; + +static const mozilla::Module kXPFEModule = { + mozilla::Module::kVersion, + kXPFECIDs, + kXPFEContracts, + kXPFECategories +}; + +NSMODULE_DEFN(application) = &kXPFEModule; diff --git a/xpfe/components/directory/moz.build b/xpfe/components/directory/moz.build new file mode 100644 index 000000000000..980001ecd0c6 --- /dev/null +++ b/xpfe/components/directory/moz.build @@ -0,0 +1,23 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +with Files("**"): + BUG_COMPONENT = ("Core", "Window Management") + +XPIDL_SOURCES += [ + 'nsIHTTPIndex.idl', +] + +XPIDL_MODULE = 'directory' + +SOURCES += [ + 'nsDirectoryViewer.cpp', +] + +FINAL_LIBRARY = 'xul' + +if CONFIG['CC_TYPE'] in ('clang', 'gcc'): + CXXFLAGS += ['-Wno-error=shadow'] diff --git a/xpfe/components/directory/nsDirectoryViewer.cpp b/xpfe/components/directory/nsDirectoryViewer.cpp new file mode 100644 index 000000000000..272c2a05499e --- /dev/null +++ b/xpfe/components/directory/nsDirectoryViewer.cpp @@ -0,0 +1,1376 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +/* + + A directory viewer object. Parses "application/http-index-format" + per Lou Montulli's original spec: + + http://www.mozilla.org/projects/netlib/dirindexformat.html + + One added change is for a description entry, for when the + target does not match the filename + +*/ + +#include "nsDirectoryViewer.h" +#include "nsArray.h" +#include "nsArrayUtils.h" +#include "nsIDirIndex.h" +#include "nsIDocShell.h" +#include "jsapi.h" +#include "nsCOMPtr.h" +#include "nsEnumeratorUtils.h" +#include "nsEscape.h" +#include "nsIRDFService.h" +#include "nsRDFCID.h" +#include "rdf.h" +#include "nsIServiceManager.h" +#include "nsIXPConnect.h" +#include "nsEnumeratorUtils.h" +#include "nsString.h" +#include "nsReadableUtils.h" +#include "nsITextToSubURI.h" +#include "nsIInterfaceRequestor.h" +#include "nsIInterfaceRequestorUtils.h" +#include "nsIFTPChannel.h" +#include "nsIWindowWatcher.h" +#include "nsIPrompt.h" +#include "nsIAuthPrompt.h" +#include "nsIProgressEventSink.h" +#include "nsIDOMWindow.h" +#include "nsIStreamConverterService.h" +#include "nsICategoryManager.h" +#include "nsXPCOMCID.h" +#include "nsIDocument.h" +#include "mozilla/Preferences.h" +#include "mozilla/dom/ScriptSettings.h" +#include "nsContentUtils.h" +#include "nsIURI.h" +#include "nsNetUtil.h" + +using namespace mozilla; + +static const int FORMAT_XUL = 3; + +//---------------------------------------------------------------------- +// +// Common CIDs +// + +static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); + +// Various protocols we have to special case +static const char kFTPProtocol[] = "ftp://"; + +//---------------------------------------------------------------------- +// +// nsHTTPIndex +// + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsHTTPIndex) + NS_INTERFACE_MAP_ENTRY(nsIHTTPIndex) + NS_INTERFACE_MAP_ENTRY(nsIRDFDataSource) + NS_INTERFACE_MAP_ENTRY(nsIStreamListener) + NS_INTERFACE_MAP_ENTRY(nsIDirIndexListener) + NS_INTERFACE_MAP_ENTRY(nsIRequestObserver) + NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor) + NS_INTERFACE_MAP_ENTRY(nsIFTPEventSink) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIHTTPIndex) +NS_INTERFACE_MAP_END + +NS_IMPL_CYCLE_COLLECTION(nsHTTPIndex, mInner) +NS_IMPL_CYCLE_COLLECTING_ADDREF(nsHTTPIndex) +NS_IMPL_CYCLE_COLLECTING_RELEASE(nsHTTPIndex) + +NS_IMETHODIMP +nsHTTPIndex::GetInterface(const nsIID &anIID, void **aResult ) +{ + if (anIID.Equals(NS_GET_IID(nsIFTPEventSink))) { + // If we don't have a container to store the logged data + // then don't report ourselves back to the caller + + if (!mRequestor) + return NS_ERROR_NO_INTERFACE; + *aResult = static_cast(this); + NS_ADDREF(this); + return NS_OK; + } + + if (anIID.Equals(NS_GET_IID(nsIPrompt))) { + + if (!mRequestor) + return NS_ERROR_NO_INTERFACE; + + nsCOMPtr aDOMWindow = do_GetInterface(mRequestor); + if (!aDOMWindow) + return NS_ERROR_NO_INTERFACE; + + nsCOMPtr wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID)); + + return wwatch->GetNewPrompter(aDOMWindow, (nsIPrompt**)aResult); + } + + if (anIID.Equals(NS_GET_IID(nsIAuthPrompt))) { + + if (!mRequestor) + return NS_ERROR_NO_INTERFACE; + + nsCOMPtr aDOMWindow = do_GetInterface(mRequestor); + if (!aDOMWindow) + return NS_ERROR_NO_INTERFACE; + + nsCOMPtr wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID)); + + return wwatch->GetNewAuthPrompter(aDOMWindow, (nsIAuthPrompt**)aResult); + } + + if (anIID.Equals(NS_GET_IID(nsIProgressEventSink))) { + + if (!mRequestor) + return NS_ERROR_NO_INTERFACE; + + nsCOMPtr sink = do_GetInterface(mRequestor); + if (!sink) + return NS_ERROR_NO_INTERFACE; + + *aResult = sink; + NS_ADDREF((nsISupports*)*aResult); + return NS_OK; + } + + return NS_ERROR_NO_INTERFACE; +} + +NS_IMETHODIMP +nsHTTPIndex::OnFTPControlLog(bool server, const char *msg) +{ + NS_ENSURE_TRUE(mRequestor, NS_OK); + + nsCOMPtr globalObject = do_GetInterface(mRequestor); + NS_ENSURE_TRUE(globalObject, NS_OK); + + // We're going to run script via JS_CallFunctionName, so we need an + // AutoEntryScript. This is Gecko specific and not in any spec. + dom::AutoEntryScript aes(globalObject, + "nsHTTPIndex OnFTPControlLog"); + JSContext* cx = aes.cx(); + + JS::Rooted global(cx, JS::CurrentGlobalOrNull(cx)); + NS_ENSURE_TRUE(global, NS_OK); + + nsString unicodeMsg; + CopyASCIItoUTF16(msg, unicodeMsg); + JSString* jsMsgStr = JS_NewUCStringCopyZ(cx, unicodeMsg.get()); + NS_ENSURE_TRUE(jsMsgStr, NS_ERROR_OUT_OF_MEMORY); + + JS::AutoValueArray<2> params(cx); + params[0].setBoolean(server); + params[1].setString(jsMsgStr); + + JS::Rooted val(cx); + JS_CallFunctionName(cx, + global, + "OnFTPControlLog", + params, + &val); + return NS_OK; +} + +NS_IMETHODIMP +nsHTTPIndex::SetEncoding(const char *encoding) +{ + mEncoding = encoding; + return(NS_OK); +} + +NS_IMETHODIMP +nsHTTPIndex::GetEncoding(char **encoding) +{ + NS_PRECONDITION(encoding, "null ptr"); + if (! encoding) + return(NS_ERROR_NULL_POINTER); + + *encoding = ToNewCString(mEncoding); + if (!*encoding) + return(NS_ERROR_OUT_OF_MEMORY); + + return(NS_OK); +} + +NS_IMETHODIMP +nsHTTPIndex::OnStartRequest(nsIRequest *request, nsISupports* aContext) +{ + nsresult rv; + + mParser = do_CreateInstance(NS_DIRINDEXPARSER_CONTRACTID, &rv); + if (NS_FAILED(rv)) return rv; + + rv = mParser->SetEncoding(mEncoding.get()); + if (NS_FAILED(rv)) return rv; + + rv = mParser->SetListener(this); + if (NS_FAILED(rv)) return rv; + + rv = mParser->OnStartRequest(request,aContext); + if (NS_FAILED(rv)) return rv; + + // This should only run once... + // Unless we don't have a container to start with + // (ie called from bookmarks as an rdf datasource) + if (mBindToGlobalObject && mRequestor) { + mBindToGlobalObject = false; + + nsCOMPtr globalObject = do_GetInterface(mRequestor); + NS_ENSURE_TRUE(globalObject, NS_ERROR_FAILURE); + + // We might run script via JS_SetProperty, so we need an AutoEntryScript. + // This is Gecko specific and not in any spec. + dom::AutoEntryScript aes(globalObject, + "nsHTTPIndex set HTTPIndex property"); + JSContext* cx = aes.cx(); + + JS::Rooted global(cx, JS::CurrentGlobalOrNull(cx)); + + // Using XPConnect, wrap the HTTP index object... + static NS_DEFINE_CID(kXPConnectCID, NS_XPCONNECT_CID); + nsCOMPtr xpc(do_GetService(kXPConnectCID, &rv)); + if (NS_FAILED(rv)) return rv; + + JS::Rooted jsobj(cx); + rv = xpc->WrapNative(cx, + global, + static_cast(this), + NS_GET_IID(nsIHTTPIndex), + jsobj.address()); + + NS_ASSERTION(NS_SUCCEEDED(rv), "unable to xpconnect-wrap http-index"); + if (NS_FAILED(rv)) return rv; + + NS_ASSERTION(jsobj, + "unable to get jsobj from xpconnect wrapper"); + if (!jsobj) return NS_ERROR_UNEXPECTED; + + JS::Rooted jslistener(cx, JS::ObjectValue(*jsobj)); + + // ...and stuff it into the global context + bool ok = JS_SetProperty(cx, global, "HTTPIndex", jslistener); + NS_ASSERTION(ok, "unable to set Listener property"); + if (!ok) + return NS_ERROR_FAILURE; + } + + if (!aContext) { + nsCOMPtr channel(do_QueryInterface(request)); + NS_ASSERTION(channel, "request should be a channel"); + + // lets hijack the notifications: + channel->SetNotificationCallbacks(this); + + // now create the top most resource + nsCOMPtr uri; + channel->GetURI(getter_AddRefs(uri)); + + nsAutoCString entryuriC; + rv = uri->GetSpec(entryuriC); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr entry; + rv = mDirRDF->GetResource(entryuriC, getter_AddRefs(entry)); + + NS_ConvertUTF8toUTF16 uriUnicode(entryuriC); + + nsCOMPtr URLVal; + rv = mDirRDF->GetLiteral(uriUnicode.get(), getter_AddRefs(URLVal)); + + Assert(entry, kNC_URL, URLVal, true); + mDirectory = do_QueryInterface(entry); + } + else + { + // Get the directory from the context + mDirectory = do_QueryInterface(aContext); + } + + if (!mDirectory) { + request->Cancel(NS_BINDING_ABORTED); + return NS_BINDING_ABORTED; + } + + // Mark the directory as "loading" + rv = Assert(mDirectory, kNC_Loading, + kTrueLiteral, true); + if (NS_FAILED(rv)) return rv; + + return NS_OK; +} + + +NS_IMETHODIMP +nsHTTPIndex::OnStopRequest(nsIRequest *request, + nsISupports* aContext, + nsresult aStatus) +{ + // If mDirectory isn't set, then we should just bail. Either an + // error occurred and OnStartRequest() never got called, or + // something exploded in OnStartRequest(). + if (! mDirectory) + return NS_BINDING_ABORTED; + + mParser->OnStopRequest(request,aContext,aStatus); + + nsresult rv; + + nsCString commentStr; + mParser->GetComment(getter_Copies(commentStr)); + + nsCOMPtr comment; + rv = mDirRDF->GetLiteral(NS_ConvertASCIItoUTF16(commentStr).get(), getter_AddRefs(comment)); + if (NS_FAILED(rv)) return rv; + + rv = Assert(mDirectory, kNC_Comment, comment, true); + if (NS_FAILED(rv)) return rv; + + // hack: Remove the 'loading' annotation (ignore errors) + AddElement(mDirectory, kNC_Loading, kTrueLiteral); + + return NS_OK; +} + + +NS_IMETHODIMP +nsHTTPIndex::OnDataAvailable(nsIRequest *request, + nsISupports* aContext, + nsIInputStream* aStream, + uint64_t aSourceOffset, + uint32_t aCount) +{ + // If mDirectory isn't set, then we should just bail. Either an + // error occurred and OnStartRequest() never got called, or + // something exploded in OnStartRequest(). + if (! mDirectory) + return NS_BINDING_ABORTED; + + return mParser->OnDataAvailable(request, mDirectory, aStream, aSourceOffset, aCount); +} + + +nsresult +nsHTTPIndex::OnIndexAvailable(nsIRequest* aRequest, nsISupports *aContext, + nsIDirIndex* aIndex) +{ + nsCOMPtr parentRes = do_QueryInterface(aContext); + if (!parentRes) { + NS_ERROR("Could not obtain parent resource"); + return(NS_ERROR_UNEXPECTED); + } + + const char* baseStr; + parentRes->GetValueConst(&baseStr); + if (! baseStr) { + NS_ERROR("Could not reconstruct base uri"); + return NS_ERROR_UNEXPECTED; + } + + // we found the filename; construct a resource for its entry + nsAutoCString entryuriC(baseStr); + + nsCString filename; + nsresult rv = aIndex->GetLocation(getter_Copies(filename)); + if (NS_FAILED(rv)) return rv; + entryuriC.Append(filename); + + // if its a directory, make sure it ends with a trailing slash. + uint32_t type; + rv = aIndex->GetType(&type); + if (NS_FAILED(rv)) + return rv; + + bool isDirType = (type == nsIDirIndex::TYPE_DIRECTORY); + if (isDirType && entryuriC.Last() != '/') { + entryuriC.Append('/'); + } + + nsCOMPtr entry; + rv = mDirRDF->GetResource(entryuriC, getter_AddRefs(entry)); + + // At this point, we'll (hopefully) have found the filename and + // constructed a resource for it, stored in entry. So now take a + // second pass through the values and add as statements to the RDF + // datasource. + + if (entry && NS_SUCCEEDED(rv)) { + nsCOMPtr lit; + nsString str; + + CopyASCIItoUTF16(entryuriC, str); + + rv = mDirRDF->GetLiteral(str.get(), getter_AddRefs(lit)); + + if (NS_SUCCEEDED(rv)) { + rv = Assert(entry, kNC_URL, lit, true); + if (NS_FAILED(rv)) return rv; + + nsString xpstr; + + // description + rv = aIndex->GetDescription(getter_Copies(xpstr)); + if (NS_FAILED(rv)) return rv; + if (xpstr.Last() == '/') + xpstr.Truncate(xpstr.Length() - 1); + + rv = mDirRDF->GetLiteral(xpstr.get(), getter_AddRefs(lit)); + if (NS_FAILED(rv)) return rv; + rv = Assert(entry, kNC_Description, lit, true); + if (NS_FAILED(rv)) return rv; + + // contentlength + int64_t size; + rv = aIndex->GetSize(&size); + if (NS_FAILED(rv)) return rv; + int64_t minus1 = UINT64_MAX; + if (size != minus1) { + int32_t intSize = int32_t(size); + // XXX RDF should support 64 bit integers (bug 240160) + nsCOMPtr val; + rv = mDirRDF->GetIntLiteral(intSize, getter_AddRefs(val)); + if (NS_FAILED(rv)) return rv; + rv = Assert(entry, kNC_ContentLength, val, true); + if (NS_FAILED(rv)) return rv; + } + + // lastmodified + PRTime tm; + rv = aIndex->GetLastModified(&tm); + if (NS_FAILED(rv)) return rv; + if (tm != -1) { + nsCOMPtr val; + rv = mDirRDF->GetDateLiteral(tm, getter_AddRefs(val)); + if (NS_FAILED(rv)) return rv; + rv = Assert(entry, kNC_LastModified, val, true); + } + + // filetype + uint32_t type; + rv = aIndex->GetType(&type); + switch (type) { + case nsIDirIndex::TYPE_UNKNOWN: + rv = mDirRDF->GetLiteral(u"UNKNOWN", getter_AddRefs(lit)); + break; + case nsIDirIndex::TYPE_DIRECTORY: + rv = mDirRDF->GetLiteral(u"DIRECTORY", getter_AddRefs(lit)); + break; + case nsIDirIndex::TYPE_FILE: + rv = mDirRDF->GetLiteral(u"FILE", getter_AddRefs(lit)); + break; + case nsIDirIndex::TYPE_SYMLINK: + rv = mDirRDF->GetLiteral(u"SYMLINK", getter_AddRefs(lit)); + break; + } + + if (NS_FAILED(rv)) return rv; + rv = Assert(entry, kNC_FileType, lit, true); + if (NS_FAILED(rv)) return rv; + } + + // Since the definition of a directory depends on the protocol, we would have + // to do string comparisons all the time. + // But we're told if we're a container right here - so save that fact + if (isDirType) + Assert(entry, kNC_IsContainer, kTrueLiteral, true); + else + Assert(entry, kNC_IsContainer, kFalseLiteral, true); + +// instead of +// rv = Assert(parentRes, kNC_Child, entry, true); +// if (NS_FAILED(rv)) return rv; +// defer insertion onto a timer so that the UI isn't starved + AddElement(parentRes, kNC_Child, entry); + } + + return rv; +} + +nsresult +nsHTTPIndex::OnInformationAvailable(nsIRequest *aRequest, + nsISupports *aCtxt, + const nsAString& aInfo) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +//---------------------------------------------------------------------- +// +// nsHTTPIndex implementation +// + +nsHTTPIndex::nsHTTPIndex() + : mBindToGlobalObject(true), + mRequestor(nullptr) +{ +} + + +nsHTTPIndex::nsHTTPIndex(nsIInterfaceRequestor* aRequestor) + : mBindToGlobalObject(true), + mRequestor(aRequestor) +{ +} + + +nsHTTPIndex::~nsHTTPIndex() +{ + // note: these are NOT statics due to the native of nsHTTPIndex + // where it may or may not be treated as a singleton + + if (mTimer) + { + // be sure to cancel the timer, as it holds a + // weak reference back to nsHTTPIndex + mTimer->Cancel(); + mTimer = nullptr; + } + + mConnectionList = nullptr; + mNodeList = nullptr; + + if (mDirRDF) + { + // UnregisterDataSource() may fail; just ignore errors + mDirRDF->UnregisterDataSource(this); + } +} + + + +nsresult +nsHTTPIndex::CommonInit() +{ + nsresult rv = NS_OK; + + // set initial/default encoding to windows-1252 (not UTF-8) + mEncoding = "windows-1252"; + + mDirRDF = do_GetService(kRDFServiceCID, &rv); + NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get RDF service"); + if (NS_FAILED(rv)) { + return(rv); + } + + mInner = do_CreateInstance("@mozilla.org/rdf/datasource;1?name=in-memory-datasource", &rv); + + if (NS_FAILED(rv)) + return rv; + + mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "child"), + getter_AddRefs(kNC_Child)); + mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "loading"), + getter_AddRefs(kNC_Loading)); + mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "Comment"), + getter_AddRefs(kNC_Comment)); + mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "URL"), + getter_AddRefs(kNC_URL)); + mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "Name"), + getter_AddRefs(kNC_Description)); + mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "Content-Length"), + getter_AddRefs(kNC_ContentLength)); + mDirRDF->GetResource(NS_LITERAL_CSTRING(WEB_NAMESPACE_URI "LastModifiedDate"), + getter_AddRefs(kNC_LastModified)); + mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "Content-Type"), + getter_AddRefs(kNC_ContentType)); + mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "File-Type"), + getter_AddRefs(kNC_FileType)); + mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "IsContainer"), + getter_AddRefs(kNC_IsContainer)); + + rv = mDirRDF->GetLiteral(u"true", getter_AddRefs(kTrueLiteral)); + if (NS_FAILED(rv)) return(rv); + rv = mDirRDF->GetLiteral(u"false", getter_AddRefs(kFalseLiteral)); + if (NS_FAILED(rv)) return(rv); + + mConnectionList = nsArray::Create(); + + // note: don't register DS here + return rv; +} + + +nsresult +nsHTTPIndex::Init() +{ + nsresult rv; + + // set initial/default encoding to windows-1252 (not UTF-8) + mEncoding = "windows-1252"; + + rv = CommonInit(); + if (NS_FAILED(rv)) return(rv); + + // (do this last) register this as a named data source with the RDF service + rv = mDirRDF->RegisterDataSource(this, false); + if (NS_FAILED(rv)) return(rv); + + return(NS_OK); +} + + + +nsresult +nsHTTPIndex::Init(nsIURI* aBaseURL) +{ + NS_PRECONDITION(aBaseURL != nullptr, "null ptr"); + if (! aBaseURL) + return NS_ERROR_NULL_POINTER; + + nsresult rv; + + rv = CommonInit(); + if (NS_FAILED(rv)) return(rv); + + // note: don't register DS here (singleton case) + + rv = aBaseURL->GetSpec(mBaseURL); + if (NS_FAILED(rv)) return rv; + + // Mark the base url as a container + nsCOMPtr baseRes; + mDirRDF->GetResource(mBaseURL, getter_AddRefs(baseRes)); + Assert(baseRes, kNC_IsContainer, kTrueLiteral, true); + + return NS_OK; +} + + + +nsresult +nsHTTPIndex::Create(nsIURI* aBaseURL, nsIInterfaceRequestor* aRequestor, + nsIHTTPIndex** aResult) +{ + *aResult = nullptr; + + nsHTTPIndex* result = new nsHTTPIndex(aRequestor); + nsresult rv = result->Init(aBaseURL); + if (NS_SUCCEEDED(rv)) + { + NS_ADDREF(result); + *aResult = result; + } + else + { + delete result; + } + return rv; +} + +NS_IMETHODIMP +nsHTTPIndex::GetBaseURL(char** _result) +{ + *_result = ToNewCString(mBaseURL); + if (! *_result) + return NS_ERROR_OUT_OF_MEMORY; + + return NS_OK; +} + +NS_IMETHODIMP +nsHTTPIndex::GetDataSource(nsIRDFDataSource** _result) +{ + NS_ADDREF(*_result = this); + return NS_OK; +} + +// This function finds the destination when following a given nsIRDFResource +// If the resource has a URL attribute, we use that. If not, just use +// the uri. +// +// Do NOT try to get the destination of a uri in any other way +void nsHTTPIndex::GetDestination(nsIRDFResource* r, nsACString& dest) { + // First try the URL attribute + nsCOMPtr node; + + GetTarget(r, kNC_URL, true, getter_AddRefs(node)); + nsCOMPtr url; + + if (node) + url = do_QueryInterface(node); + + if (!url) { + const char* temp; + r->GetValueConst(&temp); + dest.Adopt(temp ? strdup(temp) : 0); + } else { + const char16_t* uri; + url->GetValueConst(&uri); + dest.Adopt(ToNewUTF8String(nsDependentString(uri))); + } +} + +// rjc: isWellknownContainerURI() decides whether a URI is a container for which, +// when asked (say, by the template builder), we'll make a network connection +// to get its contents. For the moment, all we speak is ftp:// URLs, even though +// a) we can get "http-index" mimetypes for really anything +// b) we could easily handle file:// URLs here +// Q: Why don't we? +// A: The file system datasource ("rdf:file"); at some point, the two +// should be perhaps united. Until then, we can't aggregate both +// "rdf:file" and "http-index" (such as with bookmarks) because we'd +// get double the # of answers we really want... also, "rdf:file" is +// less expensive in terms of both memory usage as well as speed + + + +// We use an rdf attribute to mark if this is a container or not. +// Note that we still have to do string comparisons as a fallback +// because stuff like the personal toolbar and bookmarks check whether +// a URL is a container, and we have no attribute in that case. +bool +nsHTTPIndex::isWellknownContainerURI(nsIRDFResource *r) +{ + nsCOMPtr node; + GetTarget(r, kNC_IsContainer, true, getter_AddRefs(node)); + if (node) { + bool isContainerFlag; + if (NS_SUCCEEDED(node->EqualsNode(kTrueLiteral, &isContainerFlag))) + return isContainerFlag; + } + + nsCString uri; + GetDestination(r, uri); + return StringBeginsWith(uri, nsDependentCString(kFTPProtocol)) && + (uri.Last() == '/'); +} + + +NS_IMETHODIMP +nsHTTPIndex::GetURI(nsACString& aURI) +{ + aURI.AssignLiteral("rdf:httpindex"); + return NS_OK; +} + +NS_IMETHODIMP +nsHTTPIndex::GetSource(nsIRDFResource *aProperty, nsIRDFNode *aTarget, bool aTruthValue, + nsIRDFResource **_retval) +{ + nsresult rv = NS_ERROR_UNEXPECTED; + + *_retval = nullptr; + + if (mInner) + { + rv = mInner->GetSource(aProperty, aTarget, aTruthValue, _retval); + } + return(rv); +} + +NS_IMETHODIMP +nsHTTPIndex::GetSources(nsIRDFResource *aProperty, nsIRDFNode *aTarget, bool aTruthValue, + nsISimpleEnumerator **_retval) +{ + nsresult rv = NS_ERROR_UNEXPECTED; + + if (mInner) + { + rv = mInner->GetSources(aProperty, aTarget, aTruthValue, _retval); + } + else + { + rv = NS_NewEmptyEnumerator(_retval); + } + return(rv); +} + +NS_IMETHODIMP +nsHTTPIndex::GetTarget(nsIRDFResource *aSource, nsIRDFResource *aProperty, bool aTruthValue, + nsIRDFNode **_retval) +{ + nsresult rv = NS_ERROR_UNEXPECTED; + + *_retval = nullptr; + + if ((aTruthValue) && (aProperty == kNC_Child) && isWellknownContainerURI(aSource)) + { + // fake out the generic builder (i.e. return anything in this case) + // so that search containers never appear to be empty + NS_IF_ADDREF(aSource); + *_retval = aSource; + return(NS_OK); + } + + if (mInner) + { + rv = mInner->GetTarget(aSource, aProperty, aTruthValue, _retval); + } + return(rv); +} + +NS_IMETHODIMP +nsHTTPIndex::GetTargets(nsIRDFResource *aSource, nsIRDFResource *aProperty, bool aTruthValue, + nsISimpleEnumerator **_retval) +{ + nsresult rv = NS_ERROR_UNEXPECTED; + + if (mInner) + { + rv = mInner->GetTargets(aSource, aProperty, aTruthValue, _retval); + } + else + { + rv = NS_NewEmptyEnumerator(_retval); + } + + if ((aProperty == kNC_Child) && isWellknownContainerURI(aSource)) + { + bool doNetworkRequest = true; + if (NS_SUCCEEDED(rv) && (_retval)) + { + // check and see if we already have data for the search in question; + // if we do, don't bother doing the search again + bool hasResults; + if (NS_SUCCEEDED((*_retval)->HasMoreElements(&hasResults)) && + hasResults) + doNetworkRequest = false; + } + + // Note: if we need to do a network request, do it out-of-band + // (because the XUL template builder isn't re-entrant) + // by using a global connection list and an immediately-firing timer + if (doNetworkRequest && mConnectionList) + { + uint32_t connectionIndex; + nsresult idx_rv = mConnectionList->IndexOf(0, aSource, &connectionIndex); + if (NS_FAILED(idx_rv)) + { + // add aSource into list of connections to make + mConnectionList->AppendElement(aSource); + + // if we don't have a timer about to fire, create one + // which should fire as soon as possible (out-of-band) + if (!mTimer) + { + rv = NS_NewTimerWithFuncCallback(getter_AddRefs(mTimer), + nsHTTPIndex::FireTimer, + this, + 1, + nsITimer::TYPE_ONE_SHOT, + "nsHTTPIndex::GetTargets"); + // Note: don't addref "this" as we'll cancel the + // timer in the httpIndex destructor + NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create a timer"); + } + } + } + } + + return(rv); +} + + +nsresult +nsHTTPIndex::AddElement(nsIRDFResource *parent, nsIRDFResource *prop, nsIRDFNode *child) +{ + + if (!mNodeList) + { + mNodeList = nsArray::Create(); + } + + // order required: parent, prop, then child + mNodeList->AppendElement(parent); + mNodeList->AppendElement(prop); + mNodeList->AppendElement(child); + + if (!mTimer) + { + return NS_NewTimerWithFuncCallback(getter_AddRefs(mTimer), + nsHTTPIndex::FireTimer, + this, + 1, + nsITimer::TYPE_ONE_SHOT, + "nsHTTPIndex::AddElement"); + // Note: don't addref "this" as we'll cancel the + // timer in the httpIndex destructor + } + + return(NS_OK); +} + +void +nsHTTPIndex::FireTimer(nsITimer* aTimer, void* aClosure) +{ + nsHTTPIndex *httpIndex = static_cast(aClosure); + if (!httpIndex) + return; + + // don't return out of this loop as mTimer may need to be cancelled afterwards + uint32_t numItems = 0; + if (httpIndex->mConnectionList) + { + httpIndex->mConnectionList->GetLength(&numItems); + if (numItems > 0) + { + nsCOMPtr source = + do_QueryElementAt(httpIndex->mConnectionList, 0); + httpIndex->mConnectionList->RemoveElementAt(0); + + nsCString uri = VoidCString(); + if (source) { + httpIndex->GetDestination(source, uri); + } + + if (uri.IsVoid()) { + NS_ERROR("Could not reconstruct uri"); + return; + } + + nsresult rv = NS_OK; + nsCOMPtr url; + + rv = NS_NewURI(getter_AddRefs(url), uri.get()); + nsCOMPtr channel; + if (NS_SUCCEEDED(rv) && (url)) { + rv = NS_NewChannel(getter_AddRefs(channel), + url, + nsContentUtils::GetSystemPrincipal(), + nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, + nsIContentPolicy::TYPE_OTHER); + } + if (NS_SUCCEEDED(rv) && (channel)) { + channel->SetNotificationCallbacks(httpIndex); + rv = channel->AsyncOpen2(httpIndex); + } + } + } + + if (httpIndex->mNodeList) + { + httpIndex->mNodeList->GetLength(&numItems); + if (numItems > 0) + { + // account for order required: src, prop, then target + numItems /=3; + if (numItems > 10) + numItems = 10; + + int32_t loop; + for (loop=0; loop<(int32_t)numItems; loop++) + { + nsCOMPtr src = do_QueryElementAt(httpIndex->mNodeList, 0); + httpIndex->mNodeList->RemoveElementAt(0); + + nsCOMPtr prop = do_QueryElementAt(httpIndex->mNodeList, 0); + httpIndex->mNodeList->RemoveElementAt(0); + + nsCOMPtr target = do_QueryElementAt(httpIndex->mNodeList, 0); + httpIndex->mNodeList->RemoveElementAt(0); + + if (src && prop && target) + { + if (prop.get() == httpIndex->kNC_Loading) + { + httpIndex->Unassert(src, prop, target); + } + else + { + httpIndex->Assert(src, prop, target, true); + } + } + } + } + } + + bool refireTimer = false; + // check both lists to see if the timer needs to continue firing + if (httpIndex->mConnectionList) + { + httpIndex->mConnectionList->GetLength(&numItems); + if (numItems > 0) + { + refireTimer = true; + } + else + { + httpIndex->mConnectionList->Clear(); + } + } + + if (httpIndex->mNodeList) + { + httpIndex->mNodeList->GetLength(&numItems); + if (numItems > 0) + { + refireTimer = true; + } + else + { + httpIndex->mNodeList->Clear(); + } + } + + // be sure to cancel the timer, as it holds a + // weak reference back to nsHTTPIndex + httpIndex->mTimer->Cancel(); + httpIndex->mTimer = nullptr; + + // after firing off any/all of the connections be sure + // to cancel the timer if we don't need to refire it + if (refireTimer) + { + NS_NewTimerWithFuncCallback(getter_AddRefs(httpIndex->mTimer), + nsHTTPIndex::FireTimer, + aClosure, + 10, + nsITimer::TYPE_ONE_SHOT, + "nsHTTPIndex::FireTimer"); + // Note: don't addref "this" as we'll cancel the + // timer in the httpIndex destructor + } +} + +NS_IMETHODIMP +nsHTTPIndex::Assert(nsIRDFResource *aSource, nsIRDFResource *aProperty, nsIRDFNode *aTarget, + bool aTruthValue) +{ + nsresult rv = NS_ERROR_UNEXPECTED; + if (mInner) + { + rv = mInner->Assert(aSource, aProperty, aTarget, aTruthValue); + } + return(rv); +} + +NS_IMETHODIMP +nsHTTPIndex::Unassert(nsIRDFResource *aSource, nsIRDFResource *aProperty, nsIRDFNode *aTarget) +{ + nsresult rv = NS_ERROR_UNEXPECTED; + if (mInner) + { + rv = mInner->Unassert(aSource, aProperty, aTarget); + } + return(rv); +} + +NS_IMETHODIMP +nsHTTPIndex::Change(nsIRDFResource *aSource, nsIRDFResource *aProperty, + nsIRDFNode *aOldTarget, nsIRDFNode *aNewTarget) +{ + nsresult rv = NS_ERROR_UNEXPECTED; + if (mInner) + { + rv = mInner->Change(aSource, aProperty, aOldTarget, aNewTarget); + } + return(rv); +} + +NS_IMETHODIMP +nsHTTPIndex::Move(nsIRDFResource *aOldSource, nsIRDFResource *aNewSource, + nsIRDFResource *aProperty, nsIRDFNode *aTarget) +{ + nsresult rv = NS_ERROR_UNEXPECTED; + if (mInner) + { + rv = mInner->Move(aOldSource, aNewSource, aProperty, aTarget); + } + return(rv); +} + +NS_IMETHODIMP +nsHTTPIndex::HasAssertion(nsIRDFResource *aSource, nsIRDFResource *aProperty, + nsIRDFNode *aTarget, bool aTruthValue, bool *_retval) +{ + nsresult rv = NS_ERROR_UNEXPECTED; + if (mInner) + { + rv = mInner->HasAssertion(aSource, aProperty, aTarget, aTruthValue, _retval); + } + return(rv); +} + +NS_IMETHODIMP +nsHTTPIndex::AddObserver(nsIRDFObserver *aObserver) +{ + nsresult rv = NS_ERROR_UNEXPECTED; + if (mInner) + { + rv = mInner->AddObserver(aObserver); + } + return(rv); +} + +NS_IMETHODIMP +nsHTTPIndex::RemoveObserver(nsIRDFObserver *aObserver) +{ + nsresult rv = NS_ERROR_UNEXPECTED; + if (mInner) + { + rv = mInner->RemoveObserver(aObserver); + } + return(rv); +} + +NS_IMETHODIMP +nsHTTPIndex::HasArcIn(nsIRDFNode *aNode, nsIRDFResource *aArc, bool *result) +{ + if (!mInner) { + *result = false; + return NS_OK; + } + return mInner->HasArcIn(aNode, aArc, result); +} + +NS_IMETHODIMP +nsHTTPIndex::HasArcOut(nsIRDFResource *aSource, nsIRDFResource *aArc, bool *result) +{ + if (aArc == kNC_Child && isWellknownContainerURI(aSource)) { + *result = true; + return NS_OK; + } + + if (mInner) { + return mInner->HasArcOut(aSource, aArc, result); + } + + *result = false; + return NS_OK; +} + +NS_IMETHODIMP +nsHTTPIndex::ArcLabelsIn(nsIRDFNode *aNode, nsISimpleEnumerator **_retval) +{ + nsresult rv = NS_ERROR_UNEXPECTED; + if (mInner) + { + rv = mInner->ArcLabelsIn(aNode, _retval); + } + return(rv); +} + +NS_IMETHODIMP +nsHTTPIndex::ArcLabelsOut(nsIRDFResource *aSource, nsISimpleEnumerator **_retval) +{ + *_retval = nullptr; + + nsCOMPtr child, anonArcs; + if (isWellknownContainerURI(aSource)) + { + NS_NewSingletonEnumerator(getter_AddRefs(child), kNC_Child); + } + + if (mInner) + { + mInner->ArcLabelsOut(aSource, getter_AddRefs(anonArcs)); + } + + return NS_NewUnionEnumerator(_retval, child, anonArcs); +} + +NS_IMETHODIMP +nsHTTPIndex::GetAllResources(nsISimpleEnumerator **_retval) +{ + nsresult rv = NS_ERROR_UNEXPECTED; + if (mInner) + { + rv = mInner->GetAllResources(_retval); + } + return(rv); +} + +NS_IMETHODIMP +nsHTTPIndex::IsCommandEnabled(nsISupports *aSources, nsIRDFResource *aCommand, + nsISupports *aArguments, bool *_retval) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsHTTPIndex::DoCommand(nsISupports *aSources, nsIRDFResource *aCommand, + nsISupports *aArguments) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsHTTPIndex::BeginUpdateBatch() +{ + return mInner->BeginUpdateBatch(); +} + +NS_IMETHODIMP +nsHTTPIndex::EndUpdateBatch() +{ + return mInner->EndUpdateBatch(); +} + +NS_IMETHODIMP +nsHTTPIndex::GetAllCmds(nsIRDFResource *aSource, nsISimpleEnumerator **_retval) +{ + nsresult rv = NS_ERROR_UNEXPECTED; + if (mInner) + { + rv = mInner->GetAllCmds(aSource, _retval); + } + return(rv); +} + + +//---------------------------------------------------------------------- +// +// nsDirectoryViewerFactory +// +nsDirectoryViewerFactory::nsDirectoryViewerFactory() +{ +} + + + +nsDirectoryViewerFactory::~nsDirectoryViewerFactory() +{ +} + + +NS_IMPL_ISUPPORTS(nsDirectoryViewerFactory, nsIDocumentLoaderFactory) + + + +NS_IMETHODIMP +nsDirectoryViewerFactory::CreateInstance(const char *aCommand, + nsIChannel* aChannel, + nsILoadGroup* aLoadGroup, + const nsACString& aContentType, + nsIDocShell* aContainer, + nsISupports* aExtraInfo, + nsIStreamListener** aDocListenerResult, + nsIContentViewer** aDocViewerResult) +{ + nsresult rv; + + bool viewSource = FindInReadable(NS_LITERAL_CSTRING("view-source"), + aContentType); + + if (!viewSource && + Preferences::GetInt("network.dir.format", FORMAT_XUL) == FORMAT_XUL) { + // ... and setup the original channel's content type + (void)aChannel->SetContentType(NS_LITERAL_CSTRING("application/vnd.mozilla.xul+xml")); + + // This is where we shunt the HTTP/Index stream into our datasource, + // and open the directory viewer XUL file as the content stream to + // load in its place. + + // Create a dummy loader that will load a stub XUL document. + nsCOMPtr catMan(do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv)); + if (NS_FAILED(rv)) + return rv; + nsCString contractID; + rv = catMan->GetCategoryEntry("Gecko-Content-Viewers", "application/vnd.mozilla.xul+xml", + getter_Copies(contractID)); + if (NS_FAILED(rv)) + return rv; + + nsCOMPtr + factory(do_GetService(contractID.get(), &rv)); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr uri; + rv = NS_NewURI(getter_AddRefs(uri), "chrome://communicator/content/directory/directory.xul"); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr channel; + rv = NS_NewChannel(getter_AddRefs(channel), + uri, + nsContentUtils::GetSystemPrincipal(), + nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, + nsIContentPolicy::TYPE_OTHER, + nullptr, // PerformanceStorage + aLoadGroup); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr listener; + rv = factory->CreateInstance(aCommand, channel, aLoadGroup, + NS_LITERAL_CSTRING("application/vnd.mozilla.xul+xml"), + aContainer, aExtraInfo, getter_AddRefs(listener), + aDocViewerResult); + if (NS_FAILED(rv)) return rv; + + rv = channel->AsyncOpen2(listener); + if (NS_FAILED(rv)) return rv; + + // Create an HTTPIndex object so that we can stuff it into the script context + nsCOMPtr baseuri; + rv = aChannel->GetURI(getter_AddRefs(baseuri)); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr requestor = do_QueryInterface(aContainer,&rv); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr httpindex; + rv = nsHTTPIndex::Create(baseuri, requestor, getter_AddRefs(httpindex)); + if (NS_FAILED(rv)) return rv; + + // Now shanghai the stream into our http-index parsing datasource + // wrapper beastie. + listener = do_QueryInterface(httpindex,&rv); + *aDocListenerResult = listener.get(); + NS_ADDREF(*aDocListenerResult); + + return NS_OK; + } + + // setup the original channel's content type + (void)aChannel->SetContentType(NS_LITERAL_CSTRING("text/html")); + + // Otherwise, lets use the html listing + nsCOMPtr catMan(do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv)); + if (NS_FAILED(rv)) + return rv; + nsCString contractID; + rv = catMan->GetCategoryEntry("Gecko-Content-Viewers", "text/html", + getter_Copies(contractID)); + if (NS_FAILED(rv)) + return rv; + + nsCOMPtr + factory(do_GetService(contractID.get(), &rv)); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr listener; + + if (viewSource) { + rv = factory->CreateInstance("view-source", aChannel, aLoadGroup, + NS_LITERAL_CSTRING("text/html; x-view-type=view-source"), + aContainer, aExtraInfo, getter_AddRefs(listener), + aDocViewerResult); + } else { + rv = factory->CreateInstance("view", aChannel, aLoadGroup, + NS_LITERAL_CSTRING("text/html"), + aContainer, aExtraInfo, getter_AddRefs(listener), + aDocViewerResult); + } + + if (NS_FAILED(rv)) return rv; + + nsCOMPtr scs = do_GetService("@mozilla.org/streamConverters;1", &rv); + if (NS_FAILED(rv)) return rv; + + rv = scs->AsyncConvertData("application/http-index-format", + "text/html", + listener, + nullptr, + aDocListenerResult); + + if (NS_FAILED(rv)) return rv; + + return NS_OK; +} + + + +NS_IMETHODIMP +nsDirectoryViewerFactory::CreateInstanceForDocument(nsISupports* aContainer, + nsIDocument* aDocument, + const char *aCommand, + nsIContentViewer** aDocViewerResult) +{ + MOZ_ASSERT_UNREACHABLE("didn't expect to get here"); + return NS_ERROR_NOT_IMPLEMENTED; +} diff --git a/xpfe/components/directory/nsDirectoryViewer.h b/xpfe/components/directory/nsDirectoryViewer.h new file mode 100644 index 000000000000..ecb32b0a1404 --- /dev/null +++ b/xpfe/components/directory/nsDirectoryViewer.h @@ -0,0 +1,126 @@ +/* -*- 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/. */ + +#ifndef nsdirectoryviewer__h____ +#define nsdirectoryviewer__h____ + +#include "nsCOMPtr.h" +#include "nsIStreamListener.h" +#include "nsIContentViewer.h" +#include "nsIHTTPIndex.h" +#include "nsIRDFService.h" +#include "nsIRDFDataSource.h" +#include "nsIRDFLiteral.h" +#include "nsIDocumentLoaderFactory.h" +#include "nsITimer.h" +#include "nsString.h" +#include "nsIDirIndexListener.h" +#include "nsIFTPChannel.h" +#include "nsCycleCollectionParticipant.h" +#include "nsIInterfaceRequestor.h" +#include "nsIURI.h" + +class nsIMutableArray; + +class nsDirectoryViewerFactory : public nsIDocumentLoaderFactory +{ +public: + nsDirectoryViewerFactory(); + + // nsISupports interface + NS_DECL_ISUPPORTS + NS_DECL_NSIDOCUMENTLOADERFACTORY + +protected: + virtual ~nsDirectoryViewerFactory(); +}; + +class nsHTTPIndex final : public nsIHTTPIndex, + public nsIRDFDataSource, + public nsIStreamListener, + public nsIDirIndexListener, + public nsIInterfaceRequestor, + public nsIFTPEventSink +{ +private: + + // note: these are NOT statics due to the native of nsHTTPIndex + // where it may or may not be treated as a singleton + + nsCOMPtr kNC_Child; + nsCOMPtr kNC_Comment; + nsCOMPtr kNC_Loading; + nsCOMPtr kNC_URL; + nsCOMPtr kNC_Description; + nsCOMPtr kNC_ContentLength; + nsCOMPtr kNC_LastModified; + nsCOMPtr kNC_ContentType; + nsCOMPtr kNC_FileType; + nsCOMPtr kNC_IsContainer; + nsCOMPtr kTrueLiteral; + nsCOMPtr kFalseLiteral; + + nsCOMPtr mDirRDF; + +protected: + // We grab a reference to the content viewer container (which + // indirectly owns us) so that we can insert ourselves as a global + // in the script context _after_ the XUL doc has been embedded into + // content viewer. We'll know that this has happened once we receive + // an OnStartRequest() notification + + nsCOMPtr mInner; + nsCOMPtr mConnectionList; + nsCOMPtr mNodeList; + nsCOMPtr mTimer; + nsCOMPtr mParser; + nsCString mBaseURL; + nsCString mEncoding; + bool mBindToGlobalObject; + nsIInterfaceRequestor* mRequestor; // WEAK + nsCOMPtr mDirectory; + + explicit nsHTTPIndex(nsIInterfaceRequestor* aRequestor); + nsresult CommonInit(void); + nsresult Init(nsIURI* aBaseURL); + void GetDestination(nsIRDFResource* r, nsACString& dest); + bool isWellknownContainerURI(nsIRDFResource *r); + nsresult AddElement(nsIRDFResource *parent, nsIRDFResource *prop, + nsIRDFNode *child); + + static void FireTimer(nsITimer* aTimer, void* aClosure); + + virtual ~nsHTTPIndex(); + +public: + nsHTTPIndex(); + nsresult Init(void); + + static nsresult Create(nsIURI* aBaseURI, nsIInterfaceRequestor* aContainer, + nsIHTTPIndex** aResult); + + // nsIHTTPIndex interface + NS_DECL_NSIHTTPINDEX + + // NSIRDFDataSource interface + NS_DECL_NSIRDFDATASOURCE + + NS_DECL_NSIREQUESTOBSERVER + NS_DECL_NSISTREAMLISTENER + + NS_DECL_NSIDIRINDEXLISTENER + NS_DECL_NSIINTERFACEREQUESTOR + NS_DECL_NSIFTPEVENTSINK + + // nsISupports interface + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsHTTPIndex, nsIHTTPIndex) +}; + +// {82776710-5690-11d3-BE36-00104BDE6048} +#define NS_DIRECTORYVIEWERFACTORY_CID \ +{ 0x82776710, 0x5690, 0x11d3, { 0xbe, 0x36, 0x0, 0x10, 0x4b, 0xde, 0x60, 0x48 } } + +#endif // nsdirectoryviewer__h____ diff --git a/xpfe/components/directory/nsIHTTPIndex.idl b/xpfe/components/directory/nsIHTTPIndex.idl new file mode 100644 index 000000000000..47697172bcc5 --- /dev/null +++ b/xpfe/components/directory/nsIHTTPIndex.idl @@ -0,0 +1,50 @@ +/* -*- 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/. */ + +/* + + The interface to an HTTP index + +*/ + +#include "nsISupports.idl" + +interface nsIStreamListener; +interface nsIRDFDataSource; +interface nsIRDFNode; +interface nsIRDFResource; + +[scriptable, uuid(6F2BDBD0-58C3-11d3-BE36-00104BDE6048)] +interface nsIHTTPIndex : nsISupports +{ + /** + * The base URL of the HTTP index + */ + readonly attribute string BaseURL; + + /** + * The RDF datasource that contains the HTTP index information. + */ + readonly attribute nsIRDFDataSource DataSource; + + /** + * The charset to use for decoding FTP filenames + */ + attribute string encoding; +}; + +%{C++ + +// {{2587e382-1324-11d4-a652-eadbb2be3484} +#define NS_HTTPINDEX_SERVICE_CID \ +{ 0x2587e382, 0x1324, 0x11d4, { 0xa6, 0x52, 0xea, 0xdb, 0xb2, 0xbe, 0x34, 0x84 } } + +#define NS_HTTPINDEX_SERVICE_CONTRACTID \ + "@mozilla.org/browser/httpindex-service;1" + +#define NS_HTTPINDEX_DATASOURCE_CONTRACTID \ + "@mozilla.org/rdf/datasource;1?name=httpindex" + +%} diff --git a/xpfe/components/moz.build b/xpfe/components/moz.build new file mode 100644 index 000000000000..d85bd09e2750 --- /dev/null +++ b/xpfe/components/moz.build @@ -0,0 +1,14 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +with Files("**"): + BUG_COMPONENT = ("Core", "Window Management") + +DIRS += [ + 'directory', + 'build', +] + From beb8372c2d7af4e32e943dfccbcd951372c6cc55 Mon Sep 17 00:00:00 2001 From: Dorel Luca Date: Tue, 8 May 2018 13:49:37 +0300 Subject: [PATCH 23/34] Backed out 4 changesets (bug 1457749) for making T-e10s(o) hang Backed out changeset e640d678c988 (bug 1457749) Backed out changeset 292cf80054b4 (bug 1457749) Backed out changeset 7f657f4d3088 (bug 1457749) Backed out changeset bef795f8c45c (bug 1457749) --HG-- rename : toolkit/mozapps/extensions/internal/RDFManifestConverter.jsm => toolkit/mozapps/extensions/internal/UpdateRDFConverter.jsm --- .../talos/talos/tests/tabpaint/install.rdf | 4 +- .../extensions/internal/AddonTestUtils.jsm | 22 +- .../internal/AddonUpdateChecker.jsm | 2 +- .../extensions/internal/RDFDataSource.jsm | 1515 ----------------- .../internal/RDFManifestConverter.jsm | 214 --- .../internal/UpdateRDFConverter.jsm | 159 ++ .../extensions/internal/XPIInstall.jsm | 150 +- toolkit/mozapps/extensions/internal/moz.build | 3 +- .../test_delay_update_complete_v2/install.rdf | 1 - .../test_delay_update_defer_v2/install.rdf | 1 - .../test/xpcshell/test_update_rdf.js | 3 +- 11 files changed, 300 insertions(+), 1774 deletions(-) delete mode 100644 toolkit/mozapps/extensions/internal/RDFDataSource.jsm delete mode 100644 toolkit/mozapps/extensions/internal/RDFManifestConverter.jsm create mode 100644 toolkit/mozapps/extensions/internal/UpdateRDFConverter.jsm diff --git a/testing/talos/talos/tests/tabpaint/install.rdf b/testing/talos/talos/tests/tabpaint/install.rdf index d719ad613394..64ede760879e 100644 --- a/testing/talos/talos/tests/tabpaint/install.rdf +++ b/testing/talos/talos/tests/tabpaint/install.rdf @@ -18,7 +18,7 @@ * - https://wiki.mozilla.org/Buildbot/Talos/Tests - https://wiki.mozilla.org/Buildbot/Talos/Tests + https://wiki.mozilla.org/Buildbot/Talos/Tests + https://wiki.mozilla.org/Buildbot/Talos/Tests diff --git a/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm b/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm index 3d31b9771533..bb418f390c42 100644 --- a/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm +++ b/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm @@ -34,14 +34,13 @@ ChromeUtils.defineModuleGetter(this, "FileTestUtils", "resource://testing-common/FileTestUtils.jsm"); ChromeUtils.defineModuleGetter(this, "HttpServer", "resource://testing-common/httpd.js"); -ChromeUtils.defineModuleGetter(this, "InstallRDF", - "resource://gre/modules/addons/RDFManifestConverter.jsm"); ChromeUtils.defineModuleGetter(this, "MockRegistrar", "resource://testing-common/MockRegistrar.jsm"); XPCOMUtils.defineLazyServiceGetters(this, { aomStartup: ["@mozilla.org/addons/addon-manager-startup;1", "amIAddonManagerStartup"], proxyService: ["@mozilla.org/network/protocol-proxy-service;1", "nsIProtocolProxyService"], + rdfService: ["@mozilla.org/rdf/rdf-service;1", "nsIRDFService"], uuidGen: ["@mozilla.org/uuid-generator;1", "nsIUUIDGenerator"], }); @@ -62,6 +61,14 @@ const nsFile = Components.Constructor( "@mozilla.org/file/local;1", "nsIFile", "initWithPath"); +const RDFXMLParser = Components.Constructor( + "@mozilla.org/rdf/xml-parser;1", + "nsIRDFXMLParser", "parseString"); + +const RDFDataSource = Components.Constructor( + "@mozilla.org/rdf/datasource;1?name=in-memory-datasource", + "nsIRDFDataSource"); + const ZipReader = Components.Constructor( "@mozilla.org/libjar/zip-reader;1", "nsIZipReader", "open"); @@ -606,8 +613,15 @@ var AddonTestUtils = { let body = await fetch(manifestURI.spec); if (manifestURI.spec.endsWith(".rdf")) { - let manifest = InstallRDF.loadFromBuffer(await body.arrayBuffer()).decode(); - return manifest.id; + let data = await body.text(); + + let ds = new RDFDataSource(); + new RDFXMLParser(ds, manifestURI, data); + + let rdfID = ds.GetTarget(rdfService.GetResource("urn:mozilla:install-manifest"), + rdfService.GetResource("http://www.mozilla.org/2004/em-rdf#id"), + true); + return rdfID.QueryInterface(Ci.nsIRDFLiteral).Value; } let manifest = await body.json(); diff --git a/toolkit/mozapps/extensions/internal/AddonUpdateChecker.jsm b/toolkit/mozapps/extensions/internal/AddonUpdateChecker.jsm index 62fe10142778..a3ccb42e40ad 100644 --- a/toolkit/mozapps/extensions/internal/AddonUpdateChecker.jsm +++ b/toolkit/mozapps/extensions/internal/AddonUpdateChecker.jsm @@ -32,7 +32,7 @@ ChromeUtils.defineModuleGetter(this, "CertUtils", ChromeUtils.defineModuleGetter(this, "ServiceRequest", "resource://gre/modules/ServiceRequest.jsm"); ChromeUtils.defineModuleGetter(this, "UpdateRDFConverter", - "resource://gre/modules/addons/RDFManifestConverter.jsm"); + "resource://gre/modules/addons/UpdateRDFConverter.jsm"); ChromeUtils.import("resource://gre/modules/Log.jsm"); const LOGGER_ID = "addons.update-checker"; diff --git a/toolkit/mozapps/extensions/internal/RDFDataSource.jsm b/toolkit/mozapps/extensions/internal/RDFDataSource.jsm deleted file mode 100644 index 7de69acba705..000000000000 --- a/toolkit/mozapps/extensions/internal/RDFDataSource.jsm +++ /dev/null @@ -1,1515 +0,0 @@ - /* 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 module creates a new API for accessing and modifying RDF graphs. The - * goal is to be able to serialise the graph in a human readable form. Also - * if the graph was originally loaded from an RDF/XML the serialisation should - * closely match the original with any new data closely following the existing - * layout. The output should always be compatible with Mozilla's RDF parser. - * - * This is all achieved by using a DOM Document to hold the current state of the - * graph in XML form. This can be initially loaded and parsed from disk or - * a blank document used for an empty graph. As assertions are added to the - * graph, appropriate DOM nodes are added to the document to represent them - * along with any necessary whitespace to properly layout the XML. - * - * In general the order of adding assertions to the graph will impact the form - * the serialisation takes. If a resource is first added as the object of an - * assertion then it will eventually be serialised inside the assertion's - * property element. If a resource is first added as the subject of an assertion - * then it will be serialised at the top level of the XML. - */ - -const NS_XML = "http://www.w3.org/XML/1998/namespace"; -const NS_XMLNS = "http://www.w3.org/2000/xmlns/"; -const NS_RDF = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"; -const NS_NC = "http://home.netscape.com/NC-rdf#"; - -/* eslint prefer-template: 1 */ - -function raw(strings) { - return strings.raw[0].replace(/\s+/, ""); -} - -// Copied from http://www.w3.org/TR/2000/REC-xml-20001006#CharClasses -const XML_LETTER = raw` - \u0041-\u005A\u0061-\u007A\u00C0-\u00D6\u00D8-\u00F6 - \u00F8-\u00FF\u0100-\u0131\u0134-\u013E\u0141-\u0148 - \u014A-\u017E\u0180-\u01C3\u01CD-\u01F0\u01F4-\u01F5 - \u01FA-\u0217\u0250-\u02A8\u02BB-\u02C1\u0386\u0388-\u038A - \u038C\u038E-\u03A1\u03A3-\u03CE\u03D0-\u03D6\u03DA\u03DC - \u03DE\u03E0\u03E2-\u03F3\u0401-\u040C\u040E-\u044F - \u0451-\u045C\u045E-\u0481\u0490-\u04C4\u04C7-\u04C8 - \u04CB-\u04CC\u04D0-\u04EB\u04EE-\u04F5\u04F8-\u04F9 - \u0531-\u0556\u0559\u0561-\u0586\u05D0-\u05EA\u05F0-\u05F2 - \u0621-\u063A\u0641-\u064A\u0671-\u06B7\u06BA-\u06BE - \u06C0-\u06CE\u06D0-\u06D3\u06D5\u06E5-\u06E6\u0905-\u0939 - \u093D\u0958-\u0961\u0985-\u098C\u098F-\u0990\u0993-\u09A8 - \u09AA-\u09B0\u09B2\u09B6-\u09B9\u09DC-\u09DD\u09DF-\u09E1 - \u09F0-\u09F1\u0A05-\u0A0A\u0A0F-\u0A10\u0A13-\u0A28 - \u0A2A-\u0A30\u0A32-\u0A33\u0A35-\u0A36\u0A38-\u0A39 - \u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8B\u0A8D - \u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2-\u0AB3 - \u0AB5-\u0AB9\u0ABD\u0AE0\u0B05-\u0B0C\u0B0F-\u0B10 - \u0B13-\u0B28\u0B2A-\u0B30\u0B32-\u0B33\u0B36-\u0B39 - \u0B3D\u0B5C-\u0B5D\u0B5F-\u0B61\u0B85-\u0B8A\u0B8E-\u0B90 - \u0B92-\u0B95\u0B99-\u0B9A\u0B9C\u0B9E-\u0B9F\u0BA3-\u0BA4 - \u0BA8-\u0BAA\u0BAE-\u0BB5\u0BB7-\u0BB9\u0C05-\u0C0C - \u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39 - \u0C60-\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8 - \u0CAA-\u0CB3\u0CB5-\u0CB9\u0CDE\u0CE0-\u0CE1\u0D05-\u0D0C - \u0D0E-\u0D10\u0D12-\u0D28\u0D2A-\u0D39\u0D60-\u0D61 - \u0E01-\u0E2E\u0E30\u0E32-\u0E33\u0E40-\u0E45\u0E81-\u0E82 - \u0E84\u0E87-\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F - \u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA-\u0EAB\u0EAD-\u0EAE\u0EB0 - \u0EB2-\u0EB3\u0EBD\u0EC0-\u0EC4\u0F40-\u0F47\u0F49-\u0F69 - \u10A0-\u10C5\u10D0-\u10F6\u1100\u1102-\u1103\u1105-\u1107 - \u1109\u110B-\u110C\u110E-\u1112\u113C\u113E\u1140\u114C - \u114E\u1150\u1154-\u1155\u1159\u115F-\u1161\u1163\u1165 - \u1167\u1169\u116D-\u116E\u1172-\u1173\u1175\u119E\u11A8 - \u11AB\u11AE-\u11AF\u11B7-\u11B8\u11BA\u11BC-\u11C2\u11EB - \u11F0\u11F9\u1E00-\u1E9B\u1EA0-\u1EF9\u1F00-\u1F15 - \u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57 - \u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC - \u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB - \u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2126\u212A-\u212B - \u212E\u2180-\u2182\u3041-\u3094\u30A1-\u30FA\u3105-\u312C - \uAC00-\uD7A3\u4E00-\u9FA5\u3007\u3021-\u3029 -`; -const XML_DIGIT = raw` - \u0030-\u0039\u0660-\u0669\u06F0-\u06F9\u0966-\u096F - \u09E6-\u09EF\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F - \u0BE7-\u0BEF\u0C66-\u0C6F\u0CE6-\u0CEF\u0D66-\u0D6F - \u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F29 -`; -const XML_COMBINING = raw` - \u0300-\u0345\u0360-\u0361\u0483-\u0486\u0591-\u05A1 - \u05A3-\u05B9\u05BB-\u05BD\u05BF\u05C1-\u05C2\u05C4 - \u064B-\u0652\u0670\u06D6-\u06DC\u06DD-\u06DF\u06E0-\u06E4 - \u06E7-\u06E8\u06EA-\u06ED\u0901-\u0903\u093C\u093E-\u094C - \u094D\u0951-\u0954\u0962-\u0963\u0981-\u0983\u09BC\u09BE - \u09BF\u09C0-\u09C4\u09C7-\u09C8\u09CB-\u09CD\u09D7 - \u09E2-\u09E3\u0A02\u0A3C\u0A3E\u0A3F\u0A40-\u0A42 - \u0A47-\u0A48\u0A4B-\u0A4D\u0A70-\u0A71\u0A81-\u0A83 - \u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0B01-\u0B03 - \u0B3C\u0B3E-\u0B43\u0B47-\u0B48\u0B4B-\u0B4D\u0B56-\u0B57 - \u0B82-\u0B83\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7 - \u0C01-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D - \u0C55-\u0C56\u0C82-\u0C83\u0CBE-\u0CC4\u0CC6-\u0CC8 - \u0CCA-\u0CCD\u0CD5-\u0CD6\u0D02-\u0D03\u0D3E-\u0D43 - \u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0E31\u0E34-\u0E3A - \u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB-\u0EBC\u0EC8-\u0ECD - \u0F18-\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84 - \u0F86-\u0F8B\u0F90-\u0F95\u0F97\u0F99-\u0FAD\u0FB1-\u0FB7 - \u0FB9\u20D0-\u20DC\u20E1\u302A-\u302F\u3099\u309A -`; -const XML_EXTENDER = raw` - \u00B7\u02D0\u02D1\u0387\u0640\u0E46\u0EC6\u3005 - \u3031-\u3035\u309D-\u309E\u30FC-\u30FE -`; -const XML_NCNAMECHAR = String.raw`${XML_LETTER}${XML_DIGIT}\.\-_${XML_COMBINING}${XML_EXTENDER}`; -const XML_NCNAME = new RegExp(`^[${XML_LETTER}_][${XML_NCNAMECHAR}]*$`); - -const URI_SUFFIX = /[A-Za-z_][0-9A-Za-z\.\-_]*$/; -const INDENT = /\n([ \t]*)$/; -const RDF_LISTITEM = /^http:\/\/www.w3.org\/1999\/02\/22-rdf-syntax-ns#_\d+$/; - -const RDF_NODE_INVALID_TYPES = - ["RDF", "ID", "about", "bagID", "parseType", "resource", "nodeID", - "li", "aboutEach", "aboutEachPrefix"]; -const RDF_PROPERTY_INVALID_TYPES = - ["Description", "RDF", "ID", "about", "bagID", "parseType", "resource", - "nodeID", "aboutEach", "aboutEachPrefix"]; - -/** - * Whether to use properly namespaces attributes for rdf:about etc... - * When on this produces poor output in the event that the rdf namespace is the - * default namespace, and the parser recognises unnamespaced attributes and - * most of our rdf examples are unnamespaced so leaving off for the time being. - */ -const USE_RDFNS_ATTR = false; - -var EXPORTED_SYMBOLS = ["RDFLiteral", "RDFIntLiteral", "RDFDateLiteral", - "RDFBlankNode", "RDFResource", "RDFDataSource"]; - -Cu.importGlobalProperties(["DOMParser", "Element", "XMLSerializer", "fetch"]); - -ChromeUtils.defineModuleGetter(this, "OS", - "resource://gre/modules/osfile.jsm"); -ChromeUtils.defineModuleGetter(this, "Services", - "resource://gre/modules/Services.jsm"); - -function isAttr(obj) { - return obj && typeof obj == "object" && ChromeUtils.getClassName(obj) == "Attr"; -} -function isDocument(obj) { - return obj && typeof obj == "object" && obj.nodeType == Element.DOCUMENT_NODE; -} -function isElement(obj) { - return Element.isInstance(obj); -} -function isText(obj) { - return obj && typeof obj == "object" && ChromeUtils.getClassName(obj) == "Text"; -} - -/** - * Logs an error message to the error console - */ -function ERROR(str) { - Cu.reportError(str); -} - -function RDF_R(name) { - return NS_RDF + name; -} - -function renameNode(domnode, namespaceURI, qname) { - if (isElement(domnode)) { - var newdomnode = domnode.ownerDocument.createElementNS(namespaceURI, qname); - if ("listCounter" in domnode) - newdomnode.listCounter = domnode.listCounter; - domnode.replaceWith(newdomnode); - while (domnode.firstChild) - newdomnode.appendChild(domnode.firstChild); - for (let attr of domnode.attributes) { - domnode.removeAttributeNode(attr); - newdomnode.setAttributeNode(attr); - } - return newdomnode; - } else if (isAttr(domnode)) { - if (domnode.ownerElement.hasAttribute(namespaceURI, qname)) - throw new Error("attribute already exists"); - var attr = domnode.ownerDocument.createAttributeNS(namespaceURI, qname); - attr.value = domnode.value; - domnode.ownerElement.setAttributeNode(attr); - domnode.ownerElement.removeAttributeNode(domnode); - return attr; - } - throw new Error("cannot rename node of this type"); -} - -function predicateOrder(a, b) { - return a.getPredicate().localeCompare(b.getPredicate()); -} - -/** - * Returns either an rdf namespaced attribute or an un-namespaced attribute - * value. Returns null if neither exists, - */ -function getRDFAttribute(element, name) { - if (element.hasAttributeNS(NS_RDF, name)) - return element.getAttributeNS(NS_RDF, name); - if (element.hasAttribute(name)) - return element.getAttribute(name); - return undefined; -} - -/** - * Represents an assertion in the datasource - */ -class RDFAssertion { - constructor(subject, predicate, object) { - if (!(subject instanceof RDFSubject)) - throw new Error("subject must be an RDFSubject"); - - if (typeof(predicate) != "string") - throw new Error("predicate must be a string URI"); - - if (!(object instanceof RDFLiteral) && !(object instanceof RDFSubject)) - throw new Error("object must be a concrete RDFNode"); - - if (object instanceof RDFSubject && object._ds != subject._ds) - throw new Error("object must be from the same datasource as subject"); - - // The subject on this assertion, an RDFSubject - this._subject = subject; - // The predicate, a string - this._predicate = predicate; - // The object, an RDFNode - this._object = object; - // The datasource this assertion exists in - this._ds = this._subject._ds; - // Marks that _DOMnode is the subject's element - this._isSubjectElement = false; - // The DOM node that represents this assertion. Could be a property element, - // a property attribute or the subject's element for rdf:type - this._DOMNode = null; - } - - /** - * Adds content to _DOMnode to store this assertion in the DOM document. - */ - _applyToDOMNode() { - if (this._object instanceof RDFLiteral) - this._object._applyToDOMNode(this._ds, this._DOMnode); - else - this._object._addReferenceToElement(this._DOMnode); - } - - /** - * Returns the DOM Element linked to the subject that this assertion is - * attached to. - */ - _getSubjectElement() { - if (isAttr(this._DOMnode)) - return this._DOMnode.ownerElement; - if (this._isSubjectElement) - return this._DOMnode; - return this._DOMnode.parentNode; - } - - getSubject() { - return this._subject; - } - - getPredicate() { - return this._predicate; - } - - getObject() { - return this._object; - } -} - -class RDFNode { - equals(rdfnode) { - return (rdfnode.constructor === this.constructor && - rdfnode._value == this._value); - } -} - -/** - * A simple literal value - */ -class RDFLiteral extends RDFNode { - constructor(value) { - super(); - this._value = value; - } - - /** - * This stores the value of the literal in the given DOM node - */ - _applyToDOMNode(ds, domnode) { - if (isElement(domnode)) - domnode.textContent = this._value; - else if (isAttr(domnode)) - domnode.value = this._value; - else - throw new Error("cannot use this node for a literal"); - } - - getValue() { - return this._value; - } -} - -/** - * A literal that is integer typed. - */ -class RDFIntLiteral extends RDFLiteral { - constructor(value) { - super(parseInt(value)); - } - - /** - * This stores the value of the literal in the given DOM node - */ - _applyToDOMNode(ds, domnode) { - if (!isElement(domnode)) - throw new Error("cannot use this node for a literal"); - - RDFLiteral.prototype._applyToDOMNode.call(this, ds, domnode); - var prefix = ds._resolvePrefix(domnode, `${NS_NC}parseType`); - domnode.setAttributeNS(prefix.namespaceURI, prefix.qname, "Integer"); - } -} - -/** - * A literal that represents a date. - */ -class RDFDateLiteral extends RDFLiteral { - constructor(value) { - if (!(value instanceof Date)) - throw new Error("RDFDateLiteral must be constructed with a Date object"); - - super(value); - } - - /** - * This stores the value of the literal in the given DOM node - */ - _applyToDOMNode(ds, domnode) { - if (!isElement(domnode)) - throw new Error("cannot use this node for a literal"); - - domnode.textContent = this._value.getTime(); - var prefix = ds._resolvePrefix(domnode, `${NS_NC}parseType`); - domnode.setAttributeNS(prefix.namespaceURI, prefix.qname, "Date"); - } -} - -/** - * This is an RDF node that can be a subject so a resource or a blank node - */ -class RDFSubject extends RDFNode { - constructor(ds) { - super(); - // A lookup of the assertions with this as the subject. Keyed on predicate - this._assertions = {}; - // A lookup of the assertions with this as the object. Keyed on predicate - this._backwards = {}; - // The datasource this subject belongs to - this._ds = ds; - // The DOM elements in the document that represent this subject. Array of Element - this._elements = []; - } - - /** - * Creates a new Element in the document for holding assertions about this - * subject. The URI controls what tagname to use. - */ - _createElement(uri) { - // Seek an appropriate reference to this node to add this node under - var parent = null; - for (var p in this._backwards) { - for (let back of this._backwards[p]) { - // Don't add under an rdf:type - if (back.getPredicate() == RDF_R("type")) - continue; - // The assertion already has a child node, probably one of ours - if (back._DOMnode.firstChild) - continue; - parent = back._DOMnode; - var element = this._ds._addElement(parent, uri); - this._removeReferenceFromElement(parent); - break; - } - if (parent) - break; - } - - // No back assertions that are sensible to use - if (!parent) - element = this._ds._addElement(this._ds._document.documentElement, uri); - - element.listCounter = 1; - this._applyToElement(element); - this._elements.push(element); - return element; - } - - /** - * When a DOM node representing this subject is removed from the document - * we must remove the node and recreate any child assertions elsewhere. - */ - _removeElement(element) { - var pos = this._elements.indexOf(element); - if (pos < 0) - throw new Error("invalid element"); - this._elements.splice(pos, 1); - if (element.parentNode != element.ownerDocument.documentElement) - this._addReferenceToElement(element.parentNode); - this._ds._removeElement(element); - - // Find all the assertions that are represented here and create new - // nodes for them. - for (var predicate in this._assertions) { - for (let assertion of this._assertions[predicate]) { - if (assertion._getSubjectElement() == element) - this._createDOMNodeForAssertion(assertion); - } - } - } - - /** - * Creates a DOM node to represent the assertion in the document. If the - * assertion has rdf:type as the predicate then an attempt will be made to - * create a typed subject Element, otherwise a new property Element is - * created. For list items an attempt is made to find an appropriate container - * that an rdf:li element can be added to. - */ - _createDOMNodeForAssertion(assertion) { - let elements; - if (RDF_LISTITEM.test(assertion.getPredicate())) { - // Find all the containers - elements = this._elements.filter(function(element) { - return (element.namespaceURI == NS_RDF && (element.localName == "Seq" || - element.localName == "Bag" || - element.localName == "Alt")); - }); - if (elements.length > 0) { - // Look for one whose listCounter matches the item we want to add - var item = parseInt(assertion.getPredicate().substring(NS_RDF.length + 1)); - for (let element of elements) { - if (element.listCounter == item) { - assertion._DOMnode = this._ds._addElement(element, RDF_R("li")); - assertion._applyToDOMNode(); - element.listCounter++; - return; - } - } - // No good container to add to, shove in the first real container - assertion._DOMnode = this._ds._addElement(elements[0], assertion.getPredicate()); - assertion._applyToDOMNode(); - return; - } - // TODO No containers, this will end up in a non-container for now - } else if (assertion.getPredicate() == RDF_R("type")) { - // Try renaming an existing rdf:Description - for (let element of this.elements) { - if (element.namespaceURI == NS_RDF && - element.localName == "Description") { - try { - var prefix = this._ds._resolvePrefix(element.parentNode, assertion.getObject().getURI()); - element = renameNode(element, prefix.namespaceURI, prefix.qname); - assertion._DOMnode = element; - assertion._isSubjectElement = true; - return; - } catch (e) { - // If the type cannot be sensibly turned into a prefix then just set - // as a regular property - } - } - } - } - - // Filter out all the containers - elements = this._elements.filter(function(element) { - return (element.namespaceURI != NS_RDF || (element.localName != "Seq" && - element.localName != "Bag" && - element.localName != "Alt")); - }); - if (elements.length == 0) { - // Create a new node of the right type - if (assertion.getPredicate() == RDF_R("type")) { - try { - assertion._DOMnode = this._createElement(assertion.getObject().getURI()); - assertion._isSubjectElement = true; - return; - } catch (e) { - // If the type cannot be sensibly turned into a prefix then just set - // as a regular property - } - } - elements[0] = this._createElement(RDF_R("Description")); - } - assertion._DOMnode = this._ds._addElement(elements[0], assertion.getPredicate()); - assertion._applyToDOMNode(); - } - - /** - * Removes the DOM node representing the assertion. - */ - _removeDOMNodeForAssertion(assertion) { - if (isAttr(assertion._DOMnode)) { - var parent = assertion._DOMnode.ownerElement; - parent.removeAttributeNode(assertion._DOMnode); - } else if (assertion._isSubjectElement) { - var domnode = renameNode(assertion._DOMnode, NS_RDF, "Description"); - if (domnode != assertion._DOMnode) { - var pos = this._elements.indexOf(assertion._DOMnode); - this._elements.splice(pos, 1, domnode); - } - parent = domnode; - } else { - var object = assertion.getObject(); - if (object instanceof RDFSubject && assertion._DOMnode.firstChild) { - // Object is a subject that has an Element inside this assertion's node. - for (let element of object._elements) { - if (element.parentNode == assertion._DOMnode) { - object._removeElement(element); - break; - } - } - } - parent = assertion._DOMnode.parentNode; - if (assertion._DOMnode.namespaceURI == NS_RDF && - assertion._DOMnode.localName == "li") - parent.listCounter--; - this._ds._removeElement(assertion._DOMnode); - } - - // If there are no assertions left using the assertion's containing dom node - // then remove it from the document. - // TODO could do with a quick lookup list for assertions attached to a node - for (var p in this._assertions) { - for (let assertion of this._assertions[p]) { - if (assertion._getSubjectElement() == parent) - return; - } - } - // No assertions left in this element. - this._removeElement(parent); - } - - /** - * Parses the given Element from the DOM document - */ - _parseElement(element) { - this._elements.push(element); - - // There might be an inferred rdf:type assertion in the element name - if (element.namespaceURI != NS_RDF || - element.localName != "Description") { - if (element.namespaceURI == NS_RDF && element.localName == "li") - throw new Error("rdf:li is not a valid type for a subject node"); - var assertion = new RDFAssertion(this, RDF_R("type"), - this._ds.getResource(element.namespaceURI + element.localName)); - assertion._DOMnode = element; - assertion._isSubjectElement = true; - this._addAssertion(assertion); - } - - // Certain attributes can be literal properties - for (let attr of element.attributes) { - if (attr.namespaceURI == NS_XML || attr.namespaceURI == NS_XMLNS || - attr.nodeName == "xmlns") - continue; - if ((attr.namespaceURI == NS_RDF || !attr.namespaceURI) && - (["nodeID", "about", "resource", "ID", "parseType"].includes(attr.localName))) - continue; - var object = null; - if (attr.namespaceURI == NS_RDF) { - if (attr.localName == "type") - object = this._ds.getResource(attr.nodeValue); - else if (attr.localName == "li") - throw new Error("rdf:li is not allowed as a property attribute"); - else if (attr.localName == "aboutEach") - throw new Error("rdf:aboutEach is deprecated"); - else if (attr.localName == "aboutEachPrefix") - throw new Error("rdf:aboutEachPrefix is deprecated"); - else if (attr.localName == "aboutEach") - throw new Error("rdf:aboutEach is deprecated"); - else if (attr.localName == "bagID") - throw new Error("rdf:bagID is deprecated"); - } - if (!object) - object = new RDFLiteral(attr.nodeValue); - assertion = new RDFAssertion(this, attr.namespaceURI + attr.localName, object); - assertion._DOMnode = attr; - this._addAssertion(assertion); - } - - var child = element.firstChild; - element.listCounter = 1; - while (child) { - if (isText(child) && /\S/.test(child.nodeValue)) { - ERROR(`Text ${child.nodeValue} is not allowed in a subject node`); - throw new Error("subject nodes cannot contain text content"); - } else if (isElement(child)) { - object = null; - var predicate = child.namespaceURI + child.localName; - if (child.namespaceURI == NS_RDF) { - if (RDF_PROPERTY_INVALID_TYPES.includes(child.localName) && - !child.localName.match(/^_\d+$/)) - throw new Error(`${child.nodeName} is an invalid property`); - if (child.localName == "li") { - predicate = RDF_R(`_${element.listCounter}`); - element.listCounter++; - } - } - - // Check for and bail out on unknown attributes on the property element - for (let attr of child.attributes) { - // Ignore XML namespaced attributes - if (attr.namespaceURI == NS_XML) - continue; - // These are reserved by XML for future use - if (attr.localName.substring(0, 3).toLowerCase() == "xml") - continue; - // We can handle these RDF attributes - if ((!attr.namespaceURI || attr.namespaceURI == NS_RDF) && - ["resource", "nodeID"].includes(attr.localName)) - continue; - // This is a special attribute we handle for compatibility with Mozilla RDF - if (attr.namespaceURI == NS_NC && - attr.localName == "parseType") - continue; - throw new Error(`Attribute ${attr.nodeName} is not supported`); - } - - var parseType = child.getAttributeNS(NS_NC, "parseType"); - if (parseType && parseType != "Date" && parseType != "Integer") { - ERROR(`parseType ${parseType} is not supported`); - throw new Error("unsupported parseType"); - } - - var resource = getRDFAttribute(child, "resource"); - var nodeID = getRDFAttribute(child, "nodeID"); - if ((resource && (nodeID || parseType)) || - (nodeID && (resource || parseType))) { - ERROR("Cannot use more than one of parseType, resource and nodeID on a single node"); - throw new Error("Invalid rdf assertion"); - } - - if (resource !== undefined) { - var base = Services.io.newURI(element.baseURI); - object = this._ds.getResource(base.resolve(resource)); - } else if (nodeID !== undefined) { - if (!nodeID.match(XML_NCNAME)) - throw new Error("rdf:nodeID must be a valid XML name"); - object = this._ds.getBlankNode(nodeID); - } else { - var hasText = false; - var childElement = null; - var subchild = child.firstChild; - while (subchild) { - if (isText(subchild) && /\S/.test(subchild.nodeValue)) { - hasText = true; - } else if (isElement(subchild)) { - if (childElement) { - new Error(`Multiple object elements found in ${child.nodeName}`); - } - childElement = subchild; - } - subchild = subchild.nextSibling; - } - - if ((resource || nodeID) && (hasText || childElement)) { - ERROR("Assertion references a resource so should not contain additional contents"); - throw new Error("assertion cannot contain multiple objects"); - } - - if (hasText && childElement) { - ERROR(`Both literal and resource objects found in ${child.nodeName}`); - throw new Error("assertion cannot contain multiple objects"); - } - - if (childElement) { - if (parseType) { - ERROR("Cannot specify a parseType for an assertion with resource object"); - throw new Error("parseType is not valid in this context"); - } - object = this._ds._getSubjectForElement(childElement); - object._parseElement(childElement); - } else if (parseType == "Integer") - object = new RDFIntLiteral(child.textContent); - else if (parseType == "Date") - object = new RDFDateLiteral(new Date(child.textContent)); - else - object = new RDFLiteral(child.textContent); - } - - assertion = new RDFAssertion(this, predicate, object); - this._addAssertion(assertion); - assertion._DOMnode = child; - } - child = child.nextSibling; - } - } - - /** - * Adds a new assertion to the internal hashes. Should be called for every - * new assertion parsed or created programmatically. - */ - _addAssertion(assertion) { - var predicate = assertion.getPredicate(); - if (predicate in this._assertions) - this._assertions[predicate].push(assertion); - else - this._assertions[predicate] = [ assertion ]; - - var object = assertion.getObject(); - if (object instanceof RDFSubject) { - // Create reverse assertion - if (predicate in object._backwards) - object._backwards[predicate].push(assertion); - else - object._backwards[predicate] = [ assertion ]; - } - } - - /** - * Removes an assertion from the internal hashes. Should be called for all - * assertions that are programatically deleted. - */ - _removeAssertion(assertion) { - var predicate = assertion.getPredicate(); - if (predicate in this._assertions) { - var pos = this._assertions[predicate].indexOf(assertion); - if (pos >= 0) - this._assertions[predicate].splice(pos, 1); - if (this._assertions[predicate].length == 0) - delete this._assertions[predicate]; - } - - var object = assertion.getObject(); - if (object instanceof RDFSubject) { - // Delete reverse assertion - if (predicate in object._backwards) { - pos = object._backwards[predicate].indexOf(assertion); - if (pos >= 0) - object._backwards[predicate].splice(pos, 1); - if (object._backwards[predicate].length == 0) - delete object._backwards[predicate]; - } - } - } - - /** - * Returns the ordinal assertions from this subject in order. - */ - _getChildAssertions() { - var assertions = []; - for (var i in this._assertions) { - if (RDF_LISTITEM.test(i)) - assertions.push(...this._assertions[i]); - } - assertions.sort(predicateOrder); - return assertions; - } - - /** - * Compares this to another rdf node - */ - equals(rdfnode) { - // subjects are created by the datasource so no two objects ever correspond - // to the same one. - return this === rdfnode; - } - - /** - * Adds a new assertion with this as the subject - */ - assert(predicate, object) { - if (predicate == RDF_R("type") && !(object instanceof RDFResource)) - throw new Error("rdf:type must be an RDFResource"); - - var assertion = new RDFAssertion(this, predicate, object); - this._createDOMNodeForAssertion(assertion); - this._addAssertion(assertion); - } - - /** - * Removes an assertion matching the predicate and node given, if such an - * assertion exists. - */ - unassert(predicate, object) { - if (!(predicate in this._assertions)) - return; - - for (let assertion of this._assertions[predicate]) { - if (assertion.getObject().equals(object)) { - this._removeAssertion(assertion); - this._removeDOMNodeForAssertion(assertion); - return; - } - } - } - - /** - * Returns an array of all the predicates that exist in assertions from this - * subject. - */ - getPredicates() { - return Object.keys(this._assertions); - } - - /** - * Returns all objects in assertions with this subject and the given predicate. - */ - getObjects(predicate) { - if (predicate in this._assertions) - return Array.from(this._assertions[predicate], - i => i.getObject()); - - return []; - } - - /** - * Returns all of the ordinal children of this subject in order. - */ - getChildren() { - return Array.from(this._getChildAssertions(), - i => i.getObject()); - } - - /** - * Removes the child at the given index. This is the index based on the - * children returned from getChildren. Forces a reordering of the later - * children. - */ - removeChildAt(pos) { - if (pos < 0) - throw new Error("no such child"); - var assertions = this._getChildAssertions(); - if (pos >= assertions.length) - throw new Error("no such child"); - for (var i = pos; i < assertions.length; i++) { - this._removeAssertion(assertions[i]); - this._removeDOMNodeForAssertion(assertions[i]); - } - var index = 1; - if (pos > 0) - index = parseInt(assertions[pos - 1].getPredicate().substring(NS_RDF.length + 1)) + 1; - for (let i = pos + 1; i < assertions.length; i++) { - assertions[i]._predicate = RDF_R(`_${index}`); - this._addAssertion(assertions[i]); - this._createDOMNodeForAssertion(assertions[i]); - index++; - } - } - - /** - * Removes the child with the given object. It is unspecified which child is - * removed if the object features more than once. - */ - removeChild(object) { - var assertions = this._getChildAssertions(); - for (var pos = 0; pos < assertions.length; pos++) { - if (assertions[pos].getObject().equals(object)) { - for (var i = pos; i < assertions.length; i++) { - this._removeAssertion(assertions[i]); - this._removeDOMNodeForAssertion(assertions[i]); - } - var index = 1; - if (pos > 0) - index = parseInt(assertions[pos - 1].getPredicate().substring(NS_RDF.length + 1)) + 1; - for (let i = pos + 1; i < assertions.length; i++) { - assertions[i]._predicate = RDF_R(`_${index}`); - this._addAssertion(assertions[i]); - this._createDOMNodeForAssertion(assertions[i]); - index++; - } - return; - } - } - throw new Error("no such child"); - } - - /** - * Adds a new ordinal child to this subject. - */ - addChild(object) { - var max = 0; - for (var i in this._assertions) { - if (RDF_LISTITEM.test(i)) - max = Math.max(max, parseInt(i.substring(NS_RDF.length + 1))); - } - max++; - this.assert(RDF_R(`_${max}`), object); - } - - /** - * This reorders the child assertions to remove duplicates and gaps in the - * sequence. Generally this will move all children to be under the same - * container element and all represented as an rdf:li - */ - reorderChildren() { - var assertions = this._getChildAssertions(); - for (let assertion of assertions) { - this._removeAssertion(assertion); - this._removeDOMNodeForAssertion(assertion); - } - var index = 1; - for (let assertion of assertions) { - assertion._predicate = RDF_R(`_${index}`); - this._addAssertion(assertion); - this._createDOMNodeForAssertion(assertion); - index++; - } - } - - /** - * Returns the type of this subject or null if there is no specified type. - */ - getType() { - var type = this.getProperty(RDF_R("type")); - if (type && type instanceof RDFResource) - return type.getURI(); - return null; - } - - /** - * Tests if a property exists for the given predicate. - */ - hasProperty(predicate) { - return (predicate in this._assertions); - } - - /** - * Retrieves the first property value for the given predicate. - */ - getProperty(predicate) { - if (predicate in this._assertions) - return this._assertions[predicate][0].getObject(); - return null; - } - - /** - * Sets the property value for the given predicate, clearing any existing - * values. - */ - setProperty(predicate, object) { - // TODO optimise by replacing the first assertion and clearing the rest - this.clearProperty(predicate); - this.assert(predicate, object); - } - - /** - * Clears any existing properties for the given predicate. - */ - clearProperty(predicate) { - if (!(predicate in this._assertions)) - return; - - var assertions = this._assertions[predicate]; - while (assertions.length > 0) { - var assertion = assertions[0]; - this._removeAssertion(assertion); - this._removeDOMNodeForAssertion(assertion); - } - } -} - -/** - * Creates a new RDFResource for the datasource. Private. - */ -class RDFResource extends RDFSubject { - constructor(ds, uri) { - if (!(ds instanceof RDFDataSource)) - throw new Error("datasource must be an RDFDataSource"); - - if (!uri) - throw new Error("An RDFResource requires a non-null uri"); - - super(ds); - // This is the uri that the resource represents. - this._uri = uri; - } - - /** - * Sets attributes on the DOM element to mark it as representing this resource - */ - _applyToElement(element) { - if (USE_RDFNS_ATTR) { - var prefix = this._ds._resolvePrefix(element, RDF_R("about")); - element.setAttributeNS(prefix.namespaceURI, prefix.qname, this._uri); - } else { - element.setAttribute("about", this._uri); - } - } - - /** - * Adds a reference to this resource to the given property Element. - */ - _addReferenceToElement(element) { - if (USE_RDFNS_ATTR) { - var prefix = this._ds._resolvePrefix(element, RDF_R("resource")); - element.setAttributeNS(prefix.namespaceURI, prefix.qname, this._uri); - } else { - element.setAttribute("resource", this._uri); - } - } - - /** - * Removes any reference to this resource from the given property Element. - */ - _removeReferenceFromElement(element) { - if (element.hasAttributeNS(NS_RDF, "resource")) - element.removeAttributeNS(NS_RDF, "resource"); - if (element.hasAttribute("resource")) - element.removeAttribute("resource"); - } - - getURI() { - return this._uri; - } -} - -/** - * Creates a new blank node. Private. - */ -class RDFBlankNode extends RDFSubject { - constructor(ds, nodeID) { - if (!(ds instanceof RDFDataSource)) - throw new Error("datasource must be an RDFDataSource"); - - super(ds); - // The nodeID of this node. May be null if there is no ID. - this._nodeID = nodeID; - } - - /** - * Sets attributes on the DOM element to mark it as representing this node - */ - _applyToElement(element) { - if (!this._nodeID) - return; - if (USE_RDFNS_ATTR) { - var prefix = this._ds._resolvePrefix(element, RDF_R("nodeID")); - element.setAttributeNS(prefix.namespaceURI, prefix.qname, this._nodeID); - } else { - element.setAttribute("nodeID", this._nodeID); - } - } - - /** - * Creates a new Element in the document for holding assertions about this - * subject. The URI controls what tagname to use. - */ - _createNewElement(uri) { - // If there are already nodes representing this in the document then we need - // a nodeID to match them - if (!this._nodeID && this._elements.length > 0) { - this._ds._createNodeID(this); - for (let element of this._elements) - this._applyToElement(element); - } - - return super._createNewElement.call(uri); - } - - /** - * Adds a reference to this node to the given property Element. - */ - _addReferenceToElement(element) { - if (this._elements.length > 0 && !this._nodeID) { - // In document elsewhere already - // Create a node ID and update the other nodes referencing - this._ds._createNodeID(this); - for (let element of this._elements) - this._applyToElement(element); - } - - if (this._nodeID) { - if (USE_RDFNS_ATTR) { - let prefix = this._ds._resolvePrefix(element, RDF_R("nodeID")); - element.setAttributeNS(prefix.namespaceURI, prefix.qname, this._nodeID); - } else { - element.setAttribute("nodeID", this._nodeID); - } - } else { - // Add the empty blank node, this is generally right since further - // assertions will be added to fill this out - var newelement = this._ds._addElement(element, RDF_R("Description")); - newelement.listCounter = 1; - this._elements.push(newelement); - } - } - - /** - * Removes any reference to this node from the given property Element. - */ - _removeReferenceFromElement(element) { - if (element.hasAttributeNS(NS_RDF, "nodeID")) - element.removeAttributeNS(NS_RDF, "nodeID"); - if (element.hasAttribute("nodeID")) - element.removeAttribute("nodeID"); - } - - getNodeID() { - return this._nodeID; - } -} - -/** - * Creates a new RDFDataSource from the given document. The document will be - * changed as assertions are added and removed to the RDF. Pass a null document - * to start with an empty graph. - */ -class RDFDataSource { - constructor(document) { - // All known resources, indexed on URI - this._resources = {}; - // All blank nodes - this._allBlankNodes = []; - // All blank nodes with IDs, indexed on ID - this._blankNodes = {}; - // Suggested prefixes to use for namespaces, index is prefix, value is namespaceURI. - this._prefixes = { - rdf: NS_RDF, - NC: NS_NC - }; - - if (!document) { - // Creating a document through xpcom leaves out the xml prolog so just parse - // something small - var parser = Cc["@mozilla.org/xmlextras/domparser;1"]. - createInstance(Ci.nsIDOMParser); - var doctext = `\n\n`; - document = parser.parseFromString(doctext, "text/xml"); - } - // The underlying DOM document for this datasource - this._document = document; - this._parseDocument(); - } - - static loadFromString(text) { - let parser = new DOMParser(); - let document = parser.parseFromString(text, "application/xml"); - - return new this(document); - } - - static loadFromBuffer(buffer) { - let parser = new DOMParser(); - let document = parser.parseFromBuffer(new Uint8Array(buffer), "application/xml"); - - return new this(document); - } - - static async loadFromFile(uri) { - if (uri instanceof Ci.nsIFile) - uri = Services.io.newFileURI(uri); - else if (typeof(uri) == "string") - uri = Services.io.newURI(uri); - - let resp = await fetch(uri.spec); - return this.loadFromBuffer(await resp.arrayBuffer()); - } - - get uri() { - return this._document.documentURI; - } - - /** - * Creates a new nodeID for an unnamed blank node. Just node. - */ - _createNodeID(blanknode) { - var i = 1; - while (`node${i}` in this._blankNodes) - i++; - blanknode._nodeID = `node${i}`; - this._blankNodes[blanknode._nodeID] = blanknode; - } - - /** - * Returns an rdf subject for the given DOM Element. If the subject has not - * been seen before a new one is created. - */ - _getSubjectForElement(element) { - if (element.namespaceURI == NS_RDF && - RDF_NODE_INVALID_TYPES.includes(element.localName)) - throw new Error(`${element.nodeName} is not a valid class for a subject node`); - - var about = getRDFAttribute(element, "about"); - var id = getRDFAttribute(element, "ID"); - var nodeID = getRDFAttribute(element, "nodeID"); - - if ((about && (id || nodeID)) || - (nodeID && (id || about))) { - ERROR("More than one of about, ID and nodeID present on the same subject"); - throw new Error("invalid subject in rdf"); - } - - if (about !== undefined) { - let base = Services.io.newURI(element.baseURI); - return this.getResource(base.resolve(about)); - } - if (id !== undefined) { - if (!id.match(XML_NCNAME)) - throw new Error("rdf:ID must be a valid XML name"); - let base = Services.io.newURI(element.baseURI); - return this.getResource(base.resolve(`#${id}`)); - } - if (nodeID !== undefined) - return this.getBlankNode(nodeID); - return this.getBlankNode(null); - } - - /** - * Parses the document for subjects at the top level. - */ - _parseDocument() { - if (!this._document.documentElement) { - ERROR("No document element in document"); - throw new Error("document contains no root element"); - } - - if (this._document.documentElement.namespaceURI != NS_RDF || - this._document.documentElement.localName != "RDF") { - ERROR(`${this._document.documentElement.nodeName} is not rdf:RDF`); - throw new Error("document does not appear to be RDF"); - } - - var domnode = this._document.documentElement.firstChild; - while (domnode) { - if (isText(domnode) && /\S/.test(domnode.nodeValue)) { - ERROR("RDF does not allow for text in the root of the document"); - throw new Error("invalid markup in document"); - } else if (isElement(domnode)) { - var subject = this._getSubjectForElement(domnode); - subject._parseElement(domnode); - } - domnode = domnode.nextSibling; - } - } - - /** - * Works out a sensible namespace prefix to use for the given uri. node should - * be the parent of where the element is to be inserted, or the node that an - * attribute is to be added to. This will recursively walk to the top of the - * document finding an already registered prefix that matches for the uri. - * If none is found a new prefix is registered. - * This returns an object with keys namespaceURI, prefix, localName and qname. - * Pass null or undefined for badPrefixes for the first call. - */ - _resolvePrefix(domnode, uri, badPrefixes) { - if (!badPrefixes) - badPrefixes = []; - - // No known prefix, try to create one from the lookup list - if (!domnode || isDocument(domnode)) { - for (let i in this._prefixes) { - if (badPrefixes.includes(i)) - continue; - if (this._prefixes[i] == uri.substring(0, this._prefixes[i].length)) { - var local = uri.substring(this._prefixes[i].length); - var test = URI_SUFFIX.exec(local); - // Remaining part of uri is a good XML Name - if (test && test[0] == local) { - this._document.documentElement.setAttributeNS(NS_XMLNS, `xmlns:${i}`, this._prefixes[i]); - return { - namespaceURI: this._prefixes[i], - prefix: i, - localName: local, - qname: i ? `${i}:${local}` : local - }; - } - } - } - - // No match, make something up - test = URI_SUFFIX.exec(uri); - if (test) { - var namespaceURI = uri.substring(0, uri.length - test[0].length); - local = test[0]; - let i = 1; - while (badPrefixes.includes(`NS${i}`)) - i++; - this._document.documentElement.setAttributeNS(NS_XMLNS, `xmlns:NS${i}`, namespaceURI); - return { - namespaceURI, - prefix: `NS${i}`, - localName: local, - qname: `NS${i}:${local}`, - }; - } - // There is no end part of this URI that is an XML Name - throw new Error(`invalid node name: ${uri}`); - } - - for (let attr of domnode.attributes) { - // Not a namespace declaration, ignore this attribute - if (attr.namespaceURI != NS_XMLNS && attr.nodeName != "xmlns") - continue; - - var prefix = attr.prefix ? attr.localName : ""; - // Seen this prefix before, cannot use it - if (badPrefixes.includes(prefix)) - continue; - - // Namespace matches the start of the uri - if (attr.value == uri.substring(0, attr.value.length)) { - local = uri.substring(attr.value.length); - test = URI_SUFFIX.exec(local); - // Remaining part of uri is a good XML Name - if (test && test[0] == local) { - return { - namespaceURI: attr.value, - prefix, - localName: local, - qname: prefix ? `${prefix}:${local}` : local - }; - } - } - - badPrefixes.push(prefix); - } - - // No prefix found here, move up the document - return this._resolvePrefix(domnode.parentNode, uri, badPrefixes); - } - - /** - * Guess the indent level within the given Element. The method looks for - * elements that are preceeded by whitespace including a newline. The - * whitespace following the newline is presumed to be the indentation for the - * element. - * If the indentation cannot be guessed then it recurses up the document - * hierarchy until it can guess the indent or until the Document is reached. - */ - _guessIndent(element) { - // The indent at document level is 0 - if (!element || isDocument(element)) - return ""; - - // Check the text immediately preceeding each child node. One could be - // a valid indent - var pretext = ""; - var child = element.firstChild; - while (child) { - if (isText(child)) { - pretext += child.nodeValue; - } else if (isElement(child)) { - var result = INDENT.exec(pretext); - if (result) - return result[1]; - pretext = ""; - } - child = child.nextSibling; - } - - // pretext now contains any trailing text in the element. This can be - // the indent of the end tag. If so add a little to it. - result = INDENT.exec(pretext); - if (result) - return `${result[1]} `; - - // Check the text immediately before this node - pretext = ""; - var sibling = element.previousSibling; - while (sibling && isText(sibling)) { - pretext += sibling.nodeValue; - sibling = sibling.previousSibling; - } - - // If there is a sensible indent then just add to it. - result = INDENT.exec(pretext); - if (result) - return `${result[1]} `; - - // Last chance, get the indent level for the tag above and add to it - return `${this._guessIndent(element.parentNode)} `; - } - - _addElement(parent, uri) { - var prefix = this._resolvePrefix(parent, uri); - var element = this._document.createElementNS(prefix.namespaceURI, prefix.qname); - - if (parent.lastChild) { - // We want to insert immediately after the last child element - var last = parent.lastChild; - while (last && isText(last)) - last = last.previousSibling; - // No child elements so insert at the start - if (!last) - last = parent.firstChild; - else - last = last.nextSibling; - - let indent = this._guessIndent(parent); - parent.insertBefore(this._document.createTextNode(`\n${indent}`), last); - parent.insertBefore(element, last); - } else { - // No children, must indent our element and the end tag - let indent = this._guessIndent(parent.parentNode); - parent.append(`\n${indent} `, element, `\n${indent}`); - } - return element; - } - - /** - * Removes the element from its parent. Should also remove surrounding - * white space as appropriate. - */ - _removeElement(element) { - var parent = element.parentNode; - var sibling = element.previousSibling; - // Drop any text nodes immediately preceeding the element - while (sibling && isText(sibling)) { - var temp = sibling; - sibling = sibling.previousSibling; - parent.removeChild(temp); - } - - sibling = element.nextSibling; - // Drop the element - parent.removeChild(element); - - // If the next node after element is now the first child then element was - // the first child. If there are no other child elements then remove the - // remaining child nodes. - if (parent.firstChild == sibling) { - while (sibling && isText(sibling)) - sibling = sibling.nextSibling; - if (!sibling) { - // No other child elements - while (parent.lastChild) - parent.removeChild(parent.lastChild); - } - } - } - - /** - * Requests that a given prefix be used for the namespace where possible. - * This must be called before any assertions are made using the namespace - * and the registration will not override any existing prefix used in the - * document. - */ - registerPrefix(prefix, namespaceURI) { - this._prefixes[prefix] = namespaceURI; - } - - /** - * Gets a blank node. nodeID may be null and if so a new blank node is created. - * If a nodeID is given then the blank node with that ID is returned or created. - */ - getBlankNode(nodeID) { - if (nodeID && nodeID in this._blankNodes) - return this._blankNodes[nodeID]; - - if (nodeID && !nodeID.match(XML_NCNAME)) - throw new Error("rdf:nodeID must be a valid XML name"); - - var rdfnode = new RDFBlankNode(this, nodeID); - this._allBlankNodes.push(rdfnode); - if (nodeID) - this._blankNodes[nodeID] = rdfnode; - return rdfnode; - } - - /** - * Gets all blank nodes - */ - getAllBlankNodes() { - return this._allBlankNodes.slice(); - } - - /** - * Gets the resource for the URI. The resource is created if it has not been - * used already. - */ - getResource(uri) { - if (uri in this._resources) - return this._resources[uri]; - - var resource = new RDFResource(this, uri); - this._resources[uri] = resource; - return resource; - } - - /** - * Gets all resources that have been used. - */ - getAllResources() { - return Object.values(this._resources); - } - - /** - * Returns all blank nodes and resources - */ - getAllSubjects() { - return [...Object.values(this._resources), - ...this._allBlankNodes]; - } - - /** - * Saves the RDF/XML to a string. - */ - serializeToString() { - var serializer = new XMLSerializer(); - return serializer.serializeToString(this._document); - } - - /** - * Saves the RDF/XML to a file. - */ - async saveToFile(file) { - return OS.File.writeAtomic(file, new TextEncoder().encode(this.serializeToString())); - } -} diff --git a/toolkit/mozapps/extensions/internal/RDFManifestConverter.jsm b/toolkit/mozapps/extensions/internal/RDFManifestConverter.jsm deleted file mode 100644 index 9430299f920a..000000000000 --- a/toolkit/mozapps/extensions/internal/RDFManifestConverter.jsm +++ /dev/null @@ -1,214 +0,0 @@ - /* 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/. */ -"use strict"; - -var EXPORTED_SYMBOLS = ["InstallRDF", "UpdateRDFConverter"]; - -ChromeUtils.defineModuleGetter(this, "RDFDataSource", - "resource://gre/modules/addons/RDFDataSource.jsm"); -ChromeUtils.defineModuleGetter(this, "Services", - "resource://gre/modules/Services.jsm"); - -const PREFIX_ITEM = "urn:mozilla:item:"; -const PREFIX_EXTENSION = "urn:mozilla:extension:"; -const PREFIX_THEME = "urn:mozilla:theme:"; - -const TOOLKIT_ID = "toolkit@mozilla.org"; - -const RDFURI_INSTALL_MANIFEST_ROOT = "urn:mozilla:install-manifest"; - -function EM_R(aProperty) { - return `http://www.mozilla.org/2004/em-rdf#${aProperty}`; -} - -function getValue(literal) { - return literal && literal.getValue(); -} - -function getProperty(resource, property) { - return getValue(resource.getProperty(EM_R(property))); -} - -function getBoolProperty(resource, property) { - return getValue(resource.getProperty(EM_R(property))) == "true"; -} - -class Manifest { - constructor(ds) { - this.ds = ds; - } - - static loadFromString(text) { - return new this(RDFDataSource.loadFromString(text)); - } - - static loadFromBuffer(buffer) { - return new this(RDFDataSource.loadFromBuffer(buffer)); - } - - static async loadFromFile(uri) { - return new this(await RDFDataSource.loadFromFile(uri)); - } -} - -class InstallRDF extends Manifest { - _readProps(source, obj, props) { - for (let prop of props) { - let val = getProperty(source, prop); - if (val != null) { - obj[prop] = val; - } - } - } - - _readArrayProp(source, obj, prop, target, decode = getValue) { - let result = Array.from(source.getObjects(EM_R(prop)), - target => decode(target)); - if (result.length) { - obj[target] = result; - } - } - - _readArrayProps(source, obj, props, decode = getValue) { - for (let [prop, target] of Object.entries(props)) { - this._readArrayProp(source, obj, prop, target, decode); - } - } - - _readLocaleStrings(source, obj) { - this._readProps(source, obj, ["name", "description", "creator", "homepageURL"]); - this._readArrayProps(source, obj, { - locale: "locales", - developer: "developers", - translator: "translators", - contributor: "contributors", - }); - } - - decode() { - let root = this.ds.getResource(RDFURI_INSTALL_MANIFEST_ROOT); - let result = {}; - - let props = ["id", "version", "type", "updateURL", "optionsURL", - "optionsType", "aboutURL", "iconURL", "icon64URL", - "bootstrap", "unpack", "strictCompatibility", - "hasEmbeddedWebExtension"]; - this._readProps(root, result, props); - - let decodeTargetApplication = source => { - let app = {}; - this._readProps(source, app, ["id", "minVersion", "maxVersion"]); - return app; - }; - - let decodeLocale = source => { - let localized = {}; - this._readLocaleStrings(source, localized); - return localized; - }; - - this._readLocaleStrings(root, result); - - this._readArrayProps(root, result, {"targetPlatform": "targetPlatforms"}); - this._readArrayProps(root, result, {"targetApplication": "targetApplications"}, - decodeTargetApplication); - this._readArrayProps(root, result, {"localized": "localized"}, - decodeLocale); - this._readArrayProps(root, result, {"dependency": "dependencies"}, - source => getProperty(source, "id")); - - return result; - } -} - -class UpdateRDF extends Manifest { - decode() { - let addons = {}; - let result = {addons}; - - for (let resource of this.ds.getAllResources()) { - let id; - let uri = resource.getURI(); - for (let prefix of [PREFIX_EXTENSION, PREFIX_THEME, PREFIX_ITEM]) { - if (uri.startsWith(prefix)) { - id = uri.substr(prefix.length); - break; - } - } - if (!id) { - continue; - } - - let addon = {}; - addons[id] = addon; - - let updatesProp = resource.getProperty(EM_R("updates")); - if (!updatesProp || !updatesProp.getChildren) { - continue; - } - - let updates = []; - addon.updates = updates; - - for (let item of updatesProp.getChildren()) { - let version = getProperty(item, "version"); - - for (let targetApp of item.getObjects(EM_R("targetApplication"))) { - let appEntry = {}; - - let minVersion = getProperty(targetApp, "minVersion"); - if (minVersion) { - appEntry.strict_min_version = minVersion; - } - - let maxVersion = getProperty(targetApp, "maxVersion"); - if (maxVersion) { - if (getBoolProperty(targetApp, "strictCompatibility")) { - appEntry.strict_max_version = maxVersion; - } else { - appEntry.advisory_max_version = maxVersion; - } - } - - let appId = getProperty(targetApp, "id"); - if (!appId) { - continue; - } - if (appId === TOOLKIT_ID || appId === Services.appinfo.ID) { - appId = "gecko"; - } - - let update = { - applications: {[appId]: appEntry}, - }; - if (version) { - update.version = version; - } - let updateLink = getProperty(targetApp, "updateLink"); - if (updateLink) { - update.update_link = updateLink; - } - let updateInfoURL = getProperty(targetApp, "updateInfoURL"); - if (updateInfoURL) { - update.update_info_url = updateInfoURL; - } - let updateHash = getProperty(targetApp, "updateHash"); - if (updateHash) { - update.update_hash = updateHash; - } - - updates.push(update); - } - } - } - - return result; - } -} - -var UpdateRDFConverter = { - convertToJSON(request) { - return UpdateRDF.loadFromString(request.responseText).decode(); - }, -}; diff --git a/toolkit/mozapps/extensions/internal/UpdateRDFConverter.jsm b/toolkit/mozapps/extensions/internal/UpdateRDFConverter.jsm new file mode 100644 index 000000000000..af1af0decdbe --- /dev/null +++ b/toolkit/mozapps/extensions/internal/UpdateRDFConverter.jsm @@ -0,0 +1,159 @@ +/* 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/. */ +"use strict"; + +var EXPORTED_SYMBOLS = ["UpdateRDFConverter"]; + +const PREFIX_NS_EM = "http://www.mozilla.org/2004/em-rdf#"; +const PREFIX_ITEM = "urn:mozilla:item:"; +const PREFIX_EXTENSION = "urn:mozilla:extension:"; +const PREFIX_THEME = "urn:mozilla:theme:"; + +const TOOLKIT_ID = "toolkit@mozilla.org"; + +ChromeUtils.import("resource://gre/modules/Services.jsm"); +ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); + +XPCOMUtils.defineLazyServiceGetters(this, { + gRDF: ["@mozilla.org/rdf/rdf-service;1", "nsIRDFService"], + containerUtils: ["@mozilla.org/rdf/container-utils;1", "nsIRDFContainerUtils"], +}); + +const RDFContainer = Components.Constructor( + "@mozilla.org/rdf/container;1", "nsIRDFContainer", "Init"); +const RDFDataSource = Components.Constructor( + "@mozilla.org/rdf/datasource;1?name=in-memory-datasource", "nsIRDFDataSource"); +const RDFParser = Components.Constructor( + "@mozilla.org/rdf/xml-parser;1", "nsIRDFXMLParser"); + +/** + * Parses an RDF style update manifest into a JSON-style update + * manifest. + * + * @param {XMLHttpRequest> aRequest + * The XMLHttpRequest that has retrieved the update manifest + * @returns {object} a JSON update manifest. + */ +function parseRDFManifest(aRequest) { + function EM_R(aProp) { + return gRDF.GetResource(PREFIX_NS_EM + aProp); + } + + function getValue(aLiteral) { + if (aLiteral instanceof Ci.nsIRDFLiteral) + return aLiteral.Value; + if (aLiteral instanceof Ci.nsIRDFResource) + return aLiteral.Value; + if (aLiteral instanceof Ci.nsIRDFInt) + return aLiteral.Value; + return null; + } + + function getProperty(aDs, aSource, aProperty) { + return getValue(aDs.GetTarget(aSource, EM_R(aProperty), true)); + } + + function getBooleanProperty(aDs, aSource, aProperty) { + let propValue = aDs.GetTarget(aSource, EM_R(aProperty), true); + if (!propValue) + return undefined; + return getValue(propValue) == "true"; + } + + let rdfParser = new RDFParser(); + let ds = new RDFDataSource(); + rdfParser.parseString(ds, aRequest.channel.URI, aRequest.responseText); + + let addons = {}; + let result = {addons}; + + for (let addonRes of XPCOMUtils.IterSimpleEnumerator(ds.GetAllResources(), Ci.nsIRDFResource)) { + let value = addonRes.ValueUTF8; + let id; + for (let prefix of [PREFIX_EXTENSION, PREFIX_THEME, PREFIX_ITEM]) { + if (value.startsWith(prefix)) { + id = value.substr(prefix.length); + break; + } + } + if (!id) { + continue; + } + + let addon = {}; + addons[id] = addon; + + let updatesTarget = ds.GetTarget(addonRes, EM_R("updates"), true); + if (!(updatesTarget instanceof Ci.nsIRDFResource) || + !containerUtils.IsContainer(ds, updatesTarget)) { + continue; + } + + let updates = []; + addon.updates = updates; + + let ctr = new RDFContainer(ds, updatesTarget); + for (let item of XPCOMUtils.IterSimpleEnumerator(ctr.GetElements(), + Ci.nsIRDFResource)) { + let version = getProperty(ds, item, "version"); + + let targetApps = ds.GetTargets(item, EM_R("targetApplication"), true); + for (let targetApp of XPCOMUtils.IterSimpleEnumerator(targetApps, + Ci.nsIRDFResource)) { + let appEntry = {}; + + let minVersion = getProperty(ds, targetApp, "minVersion"); + if (minVersion) { + appEntry.strict_min_version = minVersion; + } + + let maxVersion = getProperty(ds, targetApp, "maxVersion"); + if (maxVersion) { + if (getBooleanProperty(ds, targetApp, "strictCompatibility")) { + appEntry.strict_max_version = maxVersion; + } else { + appEntry.advisory_max_version = maxVersion; + } + } + + let appId = getProperty(ds, targetApp, "id"); + if (!appId) { + continue; + } + if (appId === TOOLKIT_ID || appId === Services.appinfo.ID) { + appId = "gecko"; + } + + let update = { + applications: {[appId]: appEntry}, + }; + if (version) { + update.version = version; + } + let updateLink = getProperty(ds, targetApp, "updateLink"); + if (updateLink) { + update.update_link = updateLink; + } + let updateInfoURL = getProperty(ds, targetApp, "updateInfoURL"); + if (updateInfoURL) { + update.update_info_url = updateInfoURL; + } + let updateHash = getProperty(ds, targetApp, "updateHash"); + if (updateHash) { + update.update_hash = updateHash; + } + + updates.push(update); + } + } + } + + return result; +} + +var UpdateRDFConverter = { + convertToJSON(request) { + return parseRDFManifest(request); + }, +}; diff --git a/toolkit/mozapps/extensions/internal/XPIInstall.jsm b/toolkit/mozapps/extensions/internal/XPIInstall.jsm index 7bab287c55d0..0f931be618fe 100644 --- a/toolkit/mozapps/extensions/internal/XPIInstall.jsm +++ b/toolkit/mozapps/extensions/internal/XPIInstall.jsm @@ -45,7 +45,6 @@ XPCOMUtils.defineLazyModuleGetters(this, { ZipUtils: "resource://gre/modules/ZipUtils.jsm", AddonInternal: "resource://gre/modules/addons/XPIDatabase.jsm", - InstallRDF: "resource://gre/modules/addons/RDFManifestConverter.jsm", XPIDatabase: "resource://gre/modules/addons/XPIDatabase.jsm", XPIInternal: "resource://gre/modules/addons/XPIProvider.jsm", XPIProvider: "resource://gre/modules/addons/XPIProvider.jsm", @@ -69,11 +68,16 @@ const FileOutputStream = Components.Constructor("@mozilla.org/network/file-outpu const ZipReader = Components.Constructor("@mozilla.org/libjar/zip-reader;1", "nsIZipReader", "open"); +const RDFDataSource = Components.Constructor( + "@mozilla.org/rdf/datasource;1?name=in-memory-datasource", "nsIRDFDataSource"); +const parseRDFString = Components.Constructor( + "@mozilla.org/rdf/xml-parser;1", "nsIRDFXMLParser", "parseString"); + XPCOMUtils.defineLazyServiceGetters(this, { gCertDB: ["@mozilla.org/security/x509certdb;1", "nsIX509CertDB"], + gRDF: ["@mozilla.org/rdf/rdf-service;1", "nsIRDFService"], }); -const hasOwnProperty = Function.call.bind(Object.prototype.hasOwnProperty); const PREF_ALLOW_NON_RESTARTLESS = "extensions.legacy.non-restartless.enabled"; const PREF_DISTRO_ADDONS_PERMS = "extensions.distroAddons.promptForPermissions"; @@ -161,12 +165,16 @@ const KEY_APP_PROFILE = "app-profile"; const DIR_STAGE = "staged"; const DIR_TRASH = "trash"; +const RDFURI_INSTALL_MANIFEST_ROOT = "urn:mozilla:install-manifest"; +const PREFIX_NS_EM = "http://www.mozilla.org/2004/em-rdf#"; + // Properties that exist in the install manifest const PROP_METADATA = ["id", "version", "type", "internalName", "updateURL", "optionsURL", "optionsType", "aboutURL", "iconURL", "icon64URL"]; const PROP_LOCALE_SINGLE = ["name", "description", "creator", "homepageURL"]; const PROP_LOCALE_MULTI = ["developers", "translators", "contributors"]; +const PROP_TARGETAPP = ["id", "minVersion", "maxVersion"]; // Map new string type identifiers to old style nsIUpdateItem types. // Retired values: @@ -440,6 +448,44 @@ function waitForAllPromises(promises) { }); } +function EM_R(aProperty) { + return gRDF.GetResource(PREFIX_NS_EM + aProperty); +} + +/** + * Converts an RDF literal, resource or integer into a string. + * + * @param {nsISupports} aLiteral + * The RDF object to convert + * @returns {string?} + * A string if the object could be converted or null + */ +function getRDFValue(aLiteral) { + if (aLiteral instanceof Ci.nsIRDFLiteral) + return aLiteral.Value; + if (aLiteral instanceof Ci.nsIRDFResource) + return aLiteral.Value; + if (aLiteral instanceof Ci.nsIRDFInt) + return aLiteral.Value; + return null; +} + +/** + * Gets an RDF property as a string + * + * @param {nsIRDFDataSource} aDs + * The RDF datasource to read the property from + * @param {nsIRDFResource} aResource + * The RDF resource to read the property from + * @param {string} aProperty + * The property to read + * @returns {string?} + * A string if the property existed or null + */ +function getRDFProperty(aDs, aResource, aProperty) { + return getRDFValue(aDs.GetTarget(aResource, EM_R(aProperty), true)); +} + /** * Reads an AddonInternal object from a manifest stream. * @@ -582,12 +628,23 @@ async function loadManifestFromWebManifest(aUri) { * be read */ async function loadManifestFromRDF(aUri, aData) { + function getPropertyArray(aDs, aSource, aProperty) { + let values = []; + let targets = aDs.GetTargets(aSource, EM_R(aProperty), true); + while (targets.hasMoreElements()) + values.push(getRDFValue(targets.getNext())); + + return values; + } + /** * Reads locale properties from either the main install manifest root or * an em:localized section in the install manifest. * - * @param {Object} aSource - * The resource to read the properties from. + * @param {nsIRDFDataSource} aDs + * The datasource to read from. + * @param {nsIRDFResource} aSource + * The resource to read the properties from. * @param {boolean} isDefault * True if the locale is to be read from the main install manifest * root @@ -598,11 +655,13 @@ async function loadManifestFromRDF(aUri, aData) { * @returns {Object} * an object containing the locale properties */ - function readLocale(aSource, isDefault, aSeenLocales) { - let locale = {}; + function readLocale(aDs, aSource, isDefault, aSeenLocales) { + let locale = { }; if (!isDefault) { locale.locales = []; - for (let localeName of aSource.locales || []) { + let targets = ds.GetTargets(aSource, EM_R("locale"), true); + while (targets.hasMoreElements()) { + let localeName = getRDFValue(targets.getNext()); if (!localeName) { logger.warn("Ignoring empty locale in localized properties"); continue; @@ -621,26 +680,32 @@ async function loadManifestFromRDF(aUri, aData) { } } - for (let prop of [...PROP_LOCALE_SINGLE, ...PROP_LOCALE_MULTI]) { - if (hasOwnProperty(aSource, prop)) { - locale[prop] = aSource[prop]; - } + for (let prop of PROP_LOCALE_SINGLE) { + locale[prop] = getRDFProperty(aDs, aSource, prop); + } + + for (let prop of PROP_LOCALE_MULTI) { + // Don't store empty arrays + let props = getPropertyArray(aDs, aSource, + prop.substring(0, prop.length - 1)); + if (props.length > 0) + locale[prop] = props; } return locale; } - let manifest = InstallRDF.loadFromString(aData).decode(); + let ds = new RDFDataSource(); + parseRDFString(ds, aUri, aData); + let root = gRDF.GetResource(RDFURI_INSTALL_MANIFEST_ROOT); let addon = new AddonInternal(); for (let prop of PROP_METADATA) { - if (hasOwnProperty(manifest, prop)) { - addon[prop] = manifest[prop]; - } + addon[prop] = getRDFProperty(ds, root, prop); } if (!addon.type) { - addon.type = "extension"; + addon.type = addon.internalName ? "theme" : "extension"; } else { let type = addon.type; addon.type = null; @@ -662,16 +727,16 @@ async function loadManifestFromRDF(aUri, aData) { if (!addon.version) throw new Error("No version in install manifest"); - addon.strictCompatibility = (!(addon.type in COMPATIBLE_BY_DEFAULT_TYPES) || - manifest.strictCompatibility == "true"); + addon.strictCompatibility = !(addon.type in COMPATIBLE_BY_DEFAULT_TYPES) || + getRDFProperty(ds, root, "strictCompatibility") == "true"; // Only read these properties for extensions. if (addon.type == "extension") { - addon.bootstrap = manifest.bootstrap == "true"; + addon.bootstrap = getRDFProperty(ds, root, "bootstrap") == "true"; if (!addon.bootstrap && !Services.prefs.getBoolPref(PREF_ALLOW_NON_RESTARTLESS, false)) throw new Error(`Non-restartless extensions no longer supported`); - addon.hasEmbeddedWebExtension = manifest.hasEmbeddedWebExtension == "true"; + addon.hasEmbeddedWebExtension = getRDFProperty(ds, root, "hasEmbeddedWebExtension") == "true"; if (addon.optionsType && addon.optionsType != AddonManager.OPTIONS_INLINE_BROWSER && @@ -703,42 +768,63 @@ async function loadManifestFromRDF(aUri, aData) { addon.optionsBrowserStyle = null; addon.optionsType = null; addon.optionsURL = null; + + if (addon.type == "theme") { + if (!addon.internalName) + throw new Error("Themes must include an internalName property"); + addon.skinnable = getRDFProperty(ds, root, "skinnable") == "true"; + } } - addon.defaultLocale = readLocale(manifest, true); + addon.defaultLocale = readLocale(ds, root, true); let seenLocales = []; addon.locales = []; - for (let localeData of manifest.localized || []) { - let locale = readLocale(localeData, false, seenLocales); + let targets = ds.GetTargets(root, EM_R("localized"), true); + while (targets.hasMoreElements()) { + let target = targets.getNext().QueryInterface(Ci.nsIRDFResource); + let locale = readLocale(ds, target, false, seenLocales); if (locale) addon.locales.push(locale); } - let dependencies = new Set(manifest.dependencies); + let dependencies = new Set(); + targets = ds.GetTargets(root, EM_R("dependency"), true); + while (targets.hasMoreElements()) { + let target = targets.getNext().QueryInterface(Ci.nsIRDFResource); + let id = getRDFProperty(ds, target, "id"); + dependencies.add(id); + } addon.dependencies = Object.freeze(Array.from(dependencies)); let seenApplications = []; addon.targetApplications = []; - for (let targetApp of manifest.targetApplications || []) { - if (!targetApp.id || !targetApp.minVersion || - !targetApp.maxVersion) { + targets = ds.GetTargets(root, EM_R("targetApplication"), true); + while (targets.hasMoreElements()) { + let target = targets.getNext().QueryInterface(Ci.nsIRDFResource); + let targetAppInfo = {}; + for (let prop of PROP_TARGETAPP) { + targetAppInfo[prop] = getRDFProperty(ds, target, prop); + } + if (!targetAppInfo.id || !targetAppInfo.minVersion || + !targetAppInfo.maxVersion) { logger.warn("Ignoring invalid targetApplication entry in install manifest"); continue; } - if (seenApplications.includes(targetApp.id)) { - logger.warn("Ignoring duplicate targetApplication entry for " + targetApp.id + + if (seenApplications.includes(targetAppInfo.id)) { + logger.warn("Ignoring duplicate targetApplication entry for " + targetAppInfo.id + " in install manifest"); continue; } - seenApplications.push(targetApp.id); - addon.targetApplications.push(targetApp); + seenApplications.push(targetAppInfo.id); + addon.targetApplications.push(targetAppInfo); } // Note that we don't need to check for duplicate targetPlatform entries since // the RDF service coalesces them for us. + let targetPlatforms = getPropertyArray(ds, root, "targetPlatform"); addon.targetPlatforms = []; - for (let targetPlatform of manifest.targetPlatforms || []) { + for (let targetPlatform of targetPlatforms) { let platform = { os: null, abi: null diff --git a/toolkit/mozapps/extensions/internal/moz.build b/toolkit/mozapps/extensions/internal/moz.build index 5068dfc1f1c4..18c728197137 100644 --- a/toolkit/mozapps/extensions/internal/moz.build +++ b/toolkit/mozapps/extensions/internal/moz.build @@ -12,9 +12,8 @@ EXTRA_JS_MODULES.addons += [ 'GMPProvider.jsm', 'LightweightThemeImageOptimizer.jsm', 'ProductAddonChecker.jsm', - 'RDFDataSource.jsm', - 'RDFManifestConverter.jsm', 'SpellCheckDictionaryBootstrap.js', + 'UpdateRDFConverter.jsm', 'XPIDatabase.jsm', 'XPIInstall.jsm', 'XPIProvider.jsm', diff --git a/toolkit/mozapps/extensions/test/addons/test_delay_update_complete_v2/install.rdf b/toolkit/mozapps/extensions/test/addons/test_delay_update_complete_v2/install.rdf index b3d9719f78f1..3ebbe16b07a0 100644 --- a/toolkit/mozapps/extensions/test/addons/test_delay_update_complete_v2/install.rdf +++ b/toolkit/mozapps/extensions/test/addons/test_delay_update_complete_v2/install.rdf @@ -25,4 +25,3 @@ - diff --git a/toolkit/mozapps/extensions/test/addons/test_delay_update_defer_v2/install.rdf b/toolkit/mozapps/extensions/test/addons/test_delay_update_defer_v2/install.rdf index aec47ebc5631..75c7666bbaf7 100644 --- a/toolkit/mozapps/extensions/test/addons/test_delay_update_defer_v2/install.rdf +++ b/toolkit/mozapps/extensions/test/addons/test_delay_update_defer_v2/install.rdf @@ -25,4 +25,3 @@ - diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_update_rdf.js b/toolkit/mozapps/extensions/test/xpcshell/test_update_rdf.js index 21fd37defa8e..99c75f516289 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_update_rdf.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_update_rdf.js @@ -3,8 +3,7 @@ // Tests the update RDF to JSON converter. ChromeUtils.import("resource://gre/modules/addons/AddonUpdateChecker.jsm"); -ChromeUtils.defineModuleGetter(this, "UpdateRDFConverter", - "resource://gre/modules/addons/RDFManifestConverter.jsm"); +ChromeUtils.import("resource://gre/modules/addons/UpdateRDFConverter.jsm"); var testserver = AddonTestUtils.createHttpServer({hosts: ["example.com"]}); From 2b4e62518634ea1bbfefc4769a1115dcbe6a6355 Mon Sep 17 00:00:00 2001 From: Dorel Luca Date: Tue, 8 May 2018 14:49:35 +0300 Subject: [PATCH 24/34] Backed out changeset b57df5aa1534 (bug 1457813) for conflict after bug 833098 got backed out. CLOSED TREE --- editor/libeditor/HTMLEditUtils.cpp | 2 +- tools/coverity/model.cpp | 2 ++ xpcom/base/nsDebug.h | 5 +++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/editor/libeditor/HTMLEditUtils.cpp b/editor/libeditor/HTMLEditUtils.cpp index bfbb12f10b15..fd022aac6dbd 100644 --- a/editor/libeditor/HTMLEditUtils.cpp +++ b/editor/libeditor/HTMLEditUtils.cpp @@ -13,7 +13,7 @@ #include "nsAString.h" // for nsAString::IsEmpty #include "nsCOMPtr.h" // for nsCOMPtr, operator==, etc. #include "nsCaseTreatment.h" -#include "nsDebug.h" // for NS_ASSERTION, etc. +#include "nsDebug.h" // for NS_PRECONDITION, etc. #include "nsError.h" // for NS_SUCCEEDED #include "nsGkAtoms.h" // for nsGkAtoms, nsGkAtoms::a, etc. #include "nsHTMLTags.h" diff --git a/tools/coverity/model.cpp b/tools/coverity/model.cpp index 34b5a4a61db6..8c9f5f5a91b7 100644 --- a/tools/coverity/model.cpp +++ b/tools/coverity/model.cpp @@ -50,6 +50,8 @@ MOZ_ReportCrash(const char* aStr, const char* aFilename, int aLine) #define PR_ASSERT(expr) assert(!!(expr)) +#define NS_PRECONDITION(expr, msg) assert(!!(expr)) + // Kills Structurally dead code (UNREACHABLE) #define NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(_class) \ NS_IMETHODIMP_(bool) \ diff --git a/xpcom/base/nsDebug.h b/xpcom/base/nsDebug.h index b9de7ab56012..f364a4a9451e 100644 --- a/xpcom/base/nsDebug.h +++ b/xpcom/base/nsDebug.h @@ -105,6 +105,11 @@ inline void MOZ_PretendNoReturn() #define NS_ASSERTION(expr, str) do { /* nothing */ } while(0) #endif +/** + * NS_PRECONDITION is a synonym for NS_ASSERTION. + */ +#define NS_PRECONDITION(expr, str) NS_ASSERTION(expr, str) + /** * This macros triggers a program failure if executed. It indicates that * an attempt was made to execute a codepath which should not be reachable. From be1d10ec538c23b1ed0facc52597679fc0759ebe Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Tue, 8 May 2018 15:05:41 +0200 Subject: [PATCH 25/34] Bug 1459258 - Improve InlineMap OOM testing and fix some issues. r=jonco --- js/public/AllocPolicy.h | 4 ++-- js/src/ds/InlineTable.h | 9 +++++++-- js/src/frontend/BytecodeEmitter.cpp | 4 +++- js/src/frontend/BytecodeEmitter.h | 4 +++- js/src/jit-test/tests/basic/bug1459258.js | 8 ++++++++ js/src/jsapi.h | 2 +- 6 files changed, 24 insertions(+), 7 deletions(-) create mode 100644 js/src/jit-test/tests/basic/bug1459258.js diff --git a/js/public/AllocPolicy.h b/js/public/AllocPolicy.h index a505cbce3f4e..9a59df1f1c9b 100644 --- a/js/public/AllocPolicy.h +++ b/js/public/AllocPolicy.h @@ -17,7 +17,7 @@ #include "js/TypeDecls.h" #include "js/Utility.h" -extern JS_PUBLIC_API(void) JS_ReportOutOfMemory(JSContext* cx); +extern MOZ_COLD JS_PUBLIC_API(void) JS_ReportOutOfMemory(JSContext* cx); namespace js { @@ -47,7 +47,7 @@ class SystemAllocPolicy } }; -JS_FRIEND_API(void) ReportOutOfMemory(JSContext* cx); +MOZ_COLD JS_FRIEND_API(void) ReportOutOfMemory(JSContext* cx); /* * Allocation policy that calls the system memory functions and reports errors diff --git a/js/src/ds/InlineTable.h b/js/src/ds/InlineTable.h index e92f09914740..acd4c9d8f06d 100644 --- a/js/src/ds/InlineTable.h +++ b/js/src/ds/InlineTable.h @@ -22,7 +22,7 @@ template -class InlineTable +class InlineTable : private AllocPolicy { private: using TablePtr = typename Table::Ptr; @@ -102,7 +102,8 @@ class InlineTable static const size_t SizeOfInlineEntries = sizeof(InlineEntry) * InlineEntries; explicit InlineTable(AllocPolicy a = AllocPolicy()) - : inlNext_(0), + : AllocPolicy(a), + inlNext_(0), inlCount_(0), table_(a) { } @@ -303,6 +304,10 @@ class InlineTable MOZ_ASSERT(!p.found()); MOZ_ASSERT(uintptr_t(inlineEnd()) == uintptr_t(p.inlAddPtr_)); + + if (!this->checkSimulatedOOM()) + return false; + addPtr->update(mozilla::Forward(key), mozilla::Forward(args)...); ++inlCount_; diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp index 76bff40bd3ab..cbbe66a44cad 100644 --- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -1496,8 +1496,10 @@ BytecodeEmitter::TDZCheckCache::noteTDZCheck(BytecodeEmitter* bce, JSAtom* name, MOZ_ASSERT(!check, "TDZ only needs to be checked once per binding per basic block."); p->value() = check; } else { - if (!cache_->add(p, name, check)) + if (!cache_->add(p, name, check)) { + ReportOutOfMemory(bce->cx); return false; + } } return true; diff --git a/js/src/frontend/BytecodeEmitter.h b/js/src/frontend/BytecodeEmitter.h index e5ce7dad5bfa..efffafb06aa0 100644 --- a/js/src/frontend/BytecodeEmitter.h +++ b/js/src/frontend/BytecodeEmitter.h @@ -401,8 +401,10 @@ struct MOZ_STACK_CLASS BytecodeEmitter } uint32_t index = atomIndices->count(); - if (!atomIndices->add(p, atom, index)) + if (!atomIndices->add(p, atom, index)) { + ReportOutOfMemory(cx); return false; + } *indexp = index; return true; diff --git a/js/src/jit-test/tests/basic/bug1459258.js b/js/src/jit-test/tests/basic/bug1459258.js new file mode 100644 index 000000000000..48dc7b34859a --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1459258.js @@ -0,0 +1,8 @@ +if (!('oomTest' in this)) + quit(); +oomTest(function() { + return [0, Math.PI, NaN, Infinity, true, false, Symbol(), Math.tan, + Reflect, Proxy, print, assertEq, Array, String, Boolean, Number, parseInt, + parseFloat, Math.sin, Math.cos, Math.abs, Math.pow, Math.sqrt, + Uint8Array, Int8Array, Int32Array, Int16Array, Uint16Array]; +}); diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 567c6fc9e141..42f75a5301c6 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -5321,7 +5321,7 @@ JS_ReportErrorFlagsAndNumberUC(JSContext* cx, unsigned flags, /** * Complain when out of memory. */ -extern JS_PUBLIC_API(void) +extern MOZ_COLD JS_PUBLIC_API(void) JS_ReportOutOfMemory(JSContext* cx); /** From 8494c265632b5babbc2e0d68743e3dd97b02e2c4 Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Tue, 8 May 2018 15:06:53 +0200 Subject: [PATCH 26/34] Bug 1459225 - Add a gc() call to wasm/atomic.js test so TSan builds don't OOM. r=lth --- js/src/jit-test/tests/wasm/atomic.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/js/src/jit-test/tests/wasm/atomic.js b/js/src/jit-test/tests/wasm/atomic.js index 8ac807300a15..23be9da9dae5 100644 --- a/js/src/jit-test/tests/wasm/atomic.js +++ b/js/src/jit-test/tests/wasm/atomic.js @@ -513,6 +513,9 @@ var BoundsAndAlignment = for ( let i=1 ; i < size ; i++ ) addrs.push([65536, i, unaligned]); + // GC to prevent TSan builds from running out of memory. + gc(); + for ( let [ base, offset, re ] of addrs ) { assertErrorMessage(() => this.loadModule(type, ext, offset)(base), RuntimeError, re); From 56396c3a4d979424ff32dde604890d83e9e3e592 Mon Sep 17 00:00:00 2001 From: Geoff Brown Date: Tue, 8 May 2018 07:38:52 -0600 Subject: [PATCH 27/34] Bug 1459732 - Do not kill compiz before running android emulator tests; r=jmaher --- testing/mozharness/scripts/android_emulator_unittest.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/testing/mozharness/scripts/android_emulator_unittest.py b/testing/mozharness/scripts/android_emulator_unittest.py index 913729f2de43..aa098b2ecab0 100644 --- a/testing/mozharness/scripts/android_emulator_unittest.py +++ b/testing/mozharness/scripts/android_emulator_unittest.py @@ -572,8 +572,6 @@ class AndroidEmulatorTest(TestingMixin, EmulatorMixin, BaseScript, MozbaseMixin, self._restart_adbd() if not self.config.get("developer_mode"): - # We kill compiz because it sometimes prevents us from starting the emulator - self._kill_processes("compiz") self._kill_processes("xpcshell") # We add a symlink for libGL.so because the emulator dlopen()s it by that name From ec356d3b70b8d5c8171833c1828a84eaa5a66692 Mon Sep 17 00:00:00 2001 From: Geoff Brown Date: Tue, 8 May 2018 07:38:55 -0600 Subject: [PATCH 28/34] Bug 1459351 - Warn when 'mach android-emulator' tries to start an x86 emulator without kvm; r=jmaher --- .../mozrunner/devices/android_device.py | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/testing/mozbase/mozrunner/mozrunner/devices/android_device.py b/testing/mozbase/mozrunner/mozrunner/devices/android_device.py index 49a3e71e8688..a9ee459fc86b 100644 --- a/testing/mozbase/mozrunner/mozrunner/devices/android_device.py +++ b/testing/mozbase/mozrunner/mozrunner/devices/android_device.py @@ -499,6 +499,8 @@ class AndroidEmulator(object): """ Launch the emulator. """ + if self.avd_info.x86 and 'linux' in _get_host_platform(): + _verify_kvm(self.substs) if os.path.exists(EMULATOR_AUTH_FILE): os.remove(EMULATOR_AUTH_FILE) _log_debug("deleted %s" % EMULATOR_AUTH_FILE) @@ -890,3 +892,26 @@ def _update_gdbinit(substs, path): f.write("python feninit.default.objdir = '%s'\n" % substs['MOZ_BUILD_ROOT']) if substs and 'top_srcdir' in substs: f.write("python feninit.default.srcroot = '%s'\n" % substs['top_srcdir']) + + +def _verify_kvm(substs): + # 'emulator -accel-check' should produce output like: + # accel: + # 0 + # KVM (version 12) is installed and usable + # accel + emulator_path = _find_sdk_exe(substs, 'emulator', True) + if not emulator_path: + emulator_path = 'emulator' + command = [emulator_path, '-accel-check'] + try: + p = ProcessHandler(command, storeOutput=True) + p.run() + p.wait() + out = p.output + if 'is installed and usable' in ''.join(out): + return + except Exception as e: + _log_warning(str(e)) + _log_warning("Unable to verify kvm acceleration!") + _log_warning("The x86 emulator may fail to start without kvm.") From 6151d7e69a48ef12a631c0a508ae4280586d846e Mon Sep 17 00:00:00 2001 From: Kris Maglione Date: Mon, 7 May 2018 19:35:51 -0700 Subject: [PATCH 29/34] Bug 1457749: Part 1 - Import RDFDataSource from McCoy and modernize. r=Mossop MozReview-Commit-ID: 7y7kGE2kF9E --HG-- extra : source : bef795f8c45c7cb33ab59c02348ad40e35660195 --- .../extensions/internal/RDFDataSource.jsm | 1515 +++++++++++++++++ toolkit/mozapps/extensions/internal/moz.build | 1 + 2 files changed, 1516 insertions(+) create mode 100644 toolkit/mozapps/extensions/internal/RDFDataSource.jsm diff --git a/toolkit/mozapps/extensions/internal/RDFDataSource.jsm b/toolkit/mozapps/extensions/internal/RDFDataSource.jsm new file mode 100644 index 000000000000..7de69acba705 --- /dev/null +++ b/toolkit/mozapps/extensions/internal/RDFDataSource.jsm @@ -0,0 +1,1515 @@ + /* 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 module creates a new API for accessing and modifying RDF graphs. The + * goal is to be able to serialise the graph in a human readable form. Also + * if the graph was originally loaded from an RDF/XML the serialisation should + * closely match the original with any new data closely following the existing + * layout. The output should always be compatible with Mozilla's RDF parser. + * + * This is all achieved by using a DOM Document to hold the current state of the + * graph in XML form. This can be initially loaded and parsed from disk or + * a blank document used for an empty graph. As assertions are added to the + * graph, appropriate DOM nodes are added to the document to represent them + * along with any necessary whitespace to properly layout the XML. + * + * In general the order of adding assertions to the graph will impact the form + * the serialisation takes. If a resource is first added as the object of an + * assertion then it will eventually be serialised inside the assertion's + * property element. If a resource is first added as the subject of an assertion + * then it will be serialised at the top level of the XML. + */ + +const NS_XML = "http://www.w3.org/XML/1998/namespace"; +const NS_XMLNS = "http://www.w3.org/2000/xmlns/"; +const NS_RDF = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"; +const NS_NC = "http://home.netscape.com/NC-rdf#"; + +/* eslint prefer-template: 1 */ + +function raw(strings) { + return strings.raw[0].replace(/\s+/, ""); +} + +// Copied from http://www.w3.org/TR/2000/REC-xml-20001006#CharClasses +const XML_LETTER = raw` + \u0041-\u005A\u0061-\u007A\u00C0-\u00D6\u00D8-\u00F6 + \u00F8-\u00FF\u0100-\u0131\u0134-\u013E\u0141-\u0148 + \u014A-\u017E\u0180-\u01C3\u01CD-\u01F0\u01F4-\u01F5 + \u01FA-\u0217\u0250-\u02A8\u02BB-\u02C1\u0386\u0388-\u038A + \u038C\u038E-\u03A1\u03A3-\u03CE\u03D0-\u03D6\u03DA\u03DC + \u03DE\u03E0\u03E2-\u03F3\u0401-\u040C\u040E-\u044F + \u0451-\u045C\u045E-\u0481\u0490-\u04C4\u04C7-\u04C8 + \u04CB-\u04CC\u04D0-\u04EB\u04EE-\u04F5\u04F8-\u04F9 + \u0531-\u0556\u0559\u0561-\u0586\u05D0-\u05EA\u05F0-\u05F2 + \u0621-\u063A\u0641-\u064A\u0671-\u06B7\u06BA-\u06BE + \u06C0-\u06CE\u06D0-\u06D3\u06D5\u06E5-\u06E6\u0905-\u0939 + \u093D\u0958-\u0961\u0985-\u098C\u098F-\u0990\u0993-\u09A8 + \u09AA-\u09B0\u09B2\u09B6-\u09B9\u09DC-\u09DD\u09DF-\u09E1 + \u09F0-\u09F1\u0A05-\u0A0A\u0A0F-\u0A10\u0A13-\u0A28 + \u0A2A-\u0A30\u0A32-\u0A33\u0A35-\u0A36\u0A38-\u0A39 + \u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8B\u0A8D + \u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2-\u0AB3 + \u0AB5-\u0AB9\u0ABD\u0AE0\u0B05-\u0B0C\u0B0F-\u0B10 + \u0B13-\u0B28\u0B2A-\u0B30\u0B32-\u0B33\u0B36-\u0B39 + \u0B3D\u0B5C-\u0B5D\u0B5F-\u0B61\u0B85-\u0B8A\u0B8E-\u0B90 + \u0B92-\u0B95\u0B99-\u0B9A\u0B9C\u0B9E-\u0B9F\u0BA3-\u0BA4 + \u0BA8-\u0BAA\u0BAE-\u0BB5\u0BB7-\u0BB9\u0C05-\u0C0C + \u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39 + \u0C60-\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8 + \u0CAA-\u0CB3\u0CB5-\u0CB9\u0CDE\u0CE0-\u0CE1\u0D05-\u0D0C + \u0D0E-\u0D10\u0D12-\u0D28\u0D2A-\u0D39\u0D60-\u0D61 + \u0E01-\u0E2E\u0E30\u0E32-\u0E33\u0E40-\u0E45\u0E81-\u0E82 + \u0E84\u0E87-\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F + \u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA-\u0EAB\u0EAD-\u0EAE\u0EB0 + \u0EB2-\u0EB3\u0EBD\u0EC0-\u0EC4\u0F40-\u0F47\u0F49-\u0F69 + \u10A0-\u10C5\u10D0-\u10F6\u1100\u1102-\u1103\u1105-\u1107 + \u1109\u110B-\u110C\u110E-\u1112\u113C\u113E\u1140\u114C + \u114E\u1150\u1154-\u1155\u1159\u115F-\u1161\u1163\u1165 + \u1167\u1169\u116D-\u116E\u1172-\u1173\u1175\u119E\u11A8 + \u11AB\u11AE-\u11AF\u11B7-\u11B8\u11BA\u11BC-\u11C2\u11EB + \u11F0\u11F9\u1E00-\u1E9B\u1EA0-\u1EF9\u1F00-\u1F15 + \u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57 + \u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC + \u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB + \u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2126\u212A-\u212B + \u212E\u2180-\u2182\u3041-\u3094\u30A1-\u30FA\u3105-\u312C + \uAC00-\uD7A3\u4E00-\u9FA5\u3007\u3021-\u3029 +`; +const XML_DIGIT = raw` + \u0030-\u0039\u0660-\u0669\u06F0-\u06F9\u0966-\u096F + \u09E6-\u09EF\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F + \u0BE7-\u0BEF\u0C66-\u0C6F\u0CE6-\u0CEF\u0D66-\u0D6F + \u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F29 +`; +const XML_COMBINING = raw` + \u0300-\u0345\u0360-\u0361\u0483-\u0486\u0591-\u05A1 + \u05A3-\u05B9\u05BB-\u05BD\u05BF\u05C1-\u05C2\u05C4 + \u064B-\u0652\u0670\u06D6-\u06DC\u06DD-\u06DF\u06E0-\u06E4 + \u06E7-\u06E8\u06EA-\u06ED\u0901-\u0903\u093C\u093E-\u094C + \u094D\u0951-\u0954\u0962-\u0963\u0981-\u0983\u09BC\u09BE + \u09BF\u09C0-\u09C4\u09C7-\u09C8\u09CB-\u09CD\u09D7 + \u09E2-\u09E3\u0A02\u0A3C\u0A3E\u0A3F\u0A40-\u0A42 + \u0A47-\u0A48\u0A4B-\u0A4D\u0A70-\u0A71\u0A81-\u0A83 + \u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0B01-\u0B03 + \u0B3C\u0B3E-\u0B43\u0B47-\u0B48\u0B4B-\u0B4D\u0B56-\u0B57 + \u0B82-\u0B83\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7 + \u0C01-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D + \u0C55-\u0C56\u0C82-\u0C83\u0CBE-\u0CC4\u0CC6-\u0CC8 + \u0CCA-\u0CCD\u0CD5-\u0CD6\u0D02-\u0D03\u0D3E-\u0D43 + \u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0E31\u0E34-\u0E3A + \u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB-\u0EBC\u0EC8-\u0ECD + \u0F18-\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84 + \u0F86-\u0F8B\u0F90-\u0F95\u0F97\u0F99-\u0FAD\u0FB1-\u0FB7 + \u0FB9\u20D0-\u20DC\u20E1\u302A-\u302F\u3099\u309A +`; +const XML_EXTENDER = raw` + \u00B7\u02D0\u02D1\u0387\u0640\u0E46\u0EC6\u3005 + \u3031-\u3035\u309D-\u309E\u30FC-\u30FE +`; +const XML_NCNAMECHAR = String.raw`${XML_LETTER}${XML_DIGIT}\.\-_${XML_COMBINING}${XML_EXTENDER}`; +const XML_NCNAME = new RegExp(`^[${XML_LETTER}_][${XML_NCNAMECHAR}]*$`); + +const URI_SUFFIX = /[A-Za-z_][0-9A-Za-z\.\-_]*$/; +const INDENT = /\n([ \t]*)$/; +const RDF_LISTITEM = /^http:\/\/www.w3.org\/1999\/02\/22-rdf-syntax-ns#_\d+$/; + +const RDF_NODE_INVALID_TYPES = + ["RDF", "ID", "about", "bagID", "parseType", "resource", "nodeID", + "li", "aboutEach", "aboutEachPrefix"]; +const RDF_PROPERTY_INVALID_TYPES = + ["Description", "RDF", "ID", "about", "bagID", "parseType", "resource", + "nodeID", "aboutEach", "aboutEachPrefix"]; + +/** + * Whether to use properly namespaces attributes for rdf:about etc... + * When on this produces poor output in the event that the rdf namespace is the + * default namespace, and the parser recognises unnamespaced attributes and + * most of our rdf examples are unnamespaced so leaving off for the time being. + */ +const USE_RDFNS_ATTR = false; + +var EXPORTED_SYMBOLS = ["RDFLiteral", "RDFIntLiteral", "RDFDateLiteral", + "RDFBlankNode", "RDFResource", "RDFDataSource"]; + +Cu.importGlobalProperties(["DOMParser", "Element", "XMLSerializer", "fetch"]); + +ChromeUtils.defineModuleGetter(this, "OS", + "resource://gre/modules/osfile.jsm"); +ChromeUtils.defineModuleGetter(this, "Services", + "resource://gre/modules/Services.jsm"); + +function isAttr(obj) { + return obj && typeof obj == "object" && ChromeUtils.getClassName(obj) == "Attr"; +} +function isDocument(obj) { + return obj && typeof obj == "object" && obj.nodeType == Element.DOCUMENT_NODE; +} +function isElement(obj) { + return Element.isInstance(obj); +} +function isText(obj) { + return obj && typeof obj == "object" && ChromeUtils.getClassName(obj) == "Text"; +} + +/** + * Logs an error message to the error console + */ +function ERROR(str) { + Cu.reportError(str); +} + +function RDF_R(name) { + return NS_RDF + name; +} + +function renameNode(domnode, namespaceURI, qname) { + if (isElement(domnode)) { + var newdomnode = domnode.ownerDocument.createElementNS(namespaceURI, qname); + if ("listCounter" in domnode) + newdomnode.listCounter = domnode.listCounter; + domnode.replaceWith(newdomnode); + while (domnode.firstChild) + newdomnode.appendChild(domnode.firstChild); + for (let attr of domnode.attributes) { + domnode.removeAttributeNode(attr); + newdomnode.setAttributeNode(attr); + } + return newdomnode; + } else if (isAttr(domnode)) { + if (domnode.ownerElement.hasAttribute(namespaceURI, qname)) + throw new Error("attribute already exists"); + var attr = domnode.ownerDocument.createAttributeNS(namespaceURI, qname); + attr.value = domnode.value; + domnode.ownerElement.setAttributeNode(attr); + domnode.ownerElement.removeAttributeNode(domnode); + return attr; + } + throw new Error("cannot rename node of this type"); +} + +function predicateOrder(a, b) { + return a.getPredicate().localeCompare(b.getPredicate()); +} + +/** + * Returns either an rdf namespaced attribute or an un-namespaced attribute + * value. Returns null if neither exists, + */ +function getRDFAttribute(element, name) { + if (element.hasAttributeNS(NS_RDF, name)) + return element.getAttributeNS(NS_RDF, name); + if (element.hasAttribute(name)) + return element.getAttribute(name); + return undefined; +} + +/** + * Represents an assertion in the datasource + */ +class RDFAssertion { + constructor(subject, predicate, object) { + if (!(subject instanceof RDFSubject)) + throw new Error("subject must be an RDFSubject"); + + if (typeof(predicate) != "string") + throw new Error("predicate must be a string URI"); + + if (!(object instanceof RDFLiteral) && !(object instanceof RDFSubject)) + throw new Error("object must be a concrete RDFNode"); + + if (object instanceof RDFSubject && object._ds != subject._ds) + throw new Error("object must be from the same datasource as subject"); + + // The subject on this assertion, an RDFSubject + this._subject = subject; + // The predicate, a string + this._predicate = predicate; + // The object, an RDFNode + this._object = object; + // The datasource this assertion exists in + this._ds = this._subject._ds; + // Marks that _DOMnode is the subject's element + this._isSubjectElement = false; + // The DOM node that represents this assertion. Could be a property element, + // a property attribute or the subject's element for rdf:type + this._DOMNode = null; + } + + /** + * Adds content to _DOMnode to store this assertion in the DOM document. + */ + _applyToDOMNode() { + if (this._object instanceof RDFLiteral) + this._object._applyToDOMNode(this._ds, this._DOMnode); + else + this._object._addReferenceToElement(this._DOMnode); + } + + /** + * Returns the DOM Element linked to the subject that this assertion is + * attached to. + */ + _getSubjectElement() { + if (isAttr(this._DOMnode)) + return this._DOMnode.ownerElement; + if (this._isSubjectElement) + return this._DOMnode; + return this._DOMnode.parentNode; + } + + getSubject() { + return this._subject; + } + + getPredicate() { + return this._predicate; + } + + getObject() { + return this._object; + } +} + +class RDFNode { + equals(rdfnode) { + return (rdfnode.constructor === this.constructor && + rdfnode._value == this._value); + } +} + +/** + * A simple literal value + */ +class RDFLiteral extends RDFNode { + constructor(value) { + super(); + this._value = value; + } + + /** + * This stores the value of the literal in the given DOM node + */ + _applyToDOMNode(ds, domnode) { + if (isElement(domnode)) + domnode.textContent = this._value; + else if (isAttr(domnode)) + domnode.value = this._value; + else + throw new Error("cannot use this node for a literal"); + } + + getValue() { + return this._value; + } +} + +/** + * A literal that is integer typed. + */ +class RDFIntLiteral extends RDFLiteral { + constructor(value) { + super(parseInt(value)); + } + + /** + * This stores the value of the literal in the given DOM node + */ + _applyToDOMNode(ds, domnode) { + if (!isElement(domnode)) + throw new Error("cannot use this node for a literal"); + + RDFLiteral.prototype._applyToDOMNode.call(this, ds, domnode); + var prefix = ds._resolvePrefix(domnode, `${NS_NC}parseType`); + domnode.setAttributeNS(prefix.namespaceURI, prefix.qname, "Integer"); + } +} + +/** + * A literal that represents a date. + */ +class RDFDateLiteral extends RDFLiteral { + constructor(value) { + if (!(value instanceof Date)) + throw new Error("RDFDateLiteral must be constructed with a Date object"); + + super(value); + } + + /** + * This stores the value of the literal in the given DOM node + */ + _applyToDOMNode(ds, domnode) { + if (!isElement(domnode)) + throw new Error("cannot use this node for a literal"); + + domnode.textContent = this._value.getTime(); + var prefix = ds._resolvePrefix(domnode, `${NS_NC}parseType`); + domnode.setAttributeNS(prefix.namespaceURI, prefix.qname, "Date"); + } +} + +/** + * This is an RDF node that can be a subject so a resource or a blank node + */ +class RDFSubject extends RDFNode { + constructor(ds) { + super(); + // A lookup of the assertions with this as the subject. Keyed on predicate + this._assertions = {}; + // A lookup of the assertions with this as the object. Keyed on predicate + this._backwards = {}; + // The datasource this subject belongs to + this._ds = ds; + // The DOM elements in the document that represent this subject. Array of Element + this._elements = []; + } + + /** + * Creates a new Element in the document for holding assertions about this + * subject. The URI controls what tagname to use. + */ + _createElement(uri) { + // Seek an appropriate reference to this node to add this node under + var parent = null; + for (var p in this._backwards) { + for (let back of this._backwards[p]) { + // Don't add under an rdf:type + if (back.getPredicate() == RDF_R("type")) + continue; + // The assertion already has a child node, probably one of ours + if (back._DOMnode.firstChild) + continue; + parent = back._DOMnode; + var element = this._ds._addElement(parent, uri); + this._removeReferenceFromElement(parent); + break; + } + if (parent) + break; + } + + // No back assertions that are sensible to use + if (!parent) + element = this._ds._addElement(this._ds._document.documentElement, uri); + + element.listCounter = 1; + this._applyToElement(element); + this._elements.push(element); + return element; + } + + /** + * When a DOM node representing this subject is removed from the document + * we must remove the node and recreate any child assertions elsewhere. + */ + _removeElement(element) { + var pos = this._elements.indexOf(element); + if (pos < 0) + throw new Error("invalid element"); + this._elements.splice(pos, 1); + if (element.parentNode != element.ownerDocument.documentElement) + this._addReferenceToElement(element.parentNode); + this._ds._removeElement(element); + + // Find all the assertions that are represented here and create new + // nodes for them. + for (var predicate in this._assertions) { + for (let assertion of this._assertions[predicate]) { + if (assertion._getSubjectElement() == element) + this._createDOMNodeForAssertion(assertion); + } + } + } + + /** + * Creates a DOM node to represent the assertion in the document. If the + * assertion has rdf:type as the predicate then an attempt will be made to + * create a typed subject Element, otherwise a new property Element is + * created. For list items an attempt is made to find an appropriate container + * that an rdf:li element can be added to. + */ + _createDOMNodeForAssertion(assertion) { + let elements; + if (RDF_LISTITEM.test(assertion.getPredicate())) { + // Find all the containers + elements = this._elements.filter(function(element) { + return (element.namespaceURI == NS_RDF && (element.localName == "Seq" || + element.localName == "Bag" || + element.localName == "Alt")); + }); + if (elements.length > 0) { + // Look for one whose listCounter matches the item we want to add + var item = parseInt(assertion.getPredicate().substring(NS_RDF.length + 1)); + for (let element of elements) { + if (element.listCounter == item) { + assertion._DOMnode = this._ds._addElement(element, RDF_R("li")); + assertion._applyToDOMNode(); + element.listCounter++; + return; + } + } + // No good container to add to, shove in the first real container + assertion._DOMnode = this._ds._addElement(elements[0], assertion.getPredicate()); + assertion._applyToDOMNode(); + return; + } + // TODO No containers, this will end up in a non-container for now + } else if (assertion.getPredicate() == RDF_R("type")) { + // Try renaming an existing rdf:Description + for (let element of this.elements) { + if (element.namespaceURI == NS_RDF && + element.localName == "Description") { + try { + var prefix = this._ds._resolvePrefix(element.parentNode, assertion.getObject().getURI()); + element = renameNode(element, prefix.namespaceURI, prefix.qname); + assertion._DOMnode = element; + assertion._isSubjectElement = true; + return; + } catch (e) { + // If the type cannot be sensibly turned into a prefix then just set + // as a regular property + } + } + } + } + + // Filter out all the containers + elements = this._elements.filter(function(element) { + return (element.namespaceURI != NS_RDF || (element.localName != "Seq" && + element.localName != "Bag" && + element.localName != "Alt")); + }); + if (elements.length == 0) { + // Create a new node of the right type + if (assertion.getPredicate() == RDF_R("type")) { + try { + assertion._DOMnode = this._createElement(assertion.getObject().getURI()); + assertion._isSubjectElement = true; + return; + } catch (e) { + // If the type cannot be sensibly turned into a prefix then just set + // as a regular property + } + } + elements[0] = this._createElement(RDF_R("Description")); + } + assertion._DOMnode = this._ds._addElement(elements[0], assertion.getPredicate()); + assertion._applyToDOMNode(); + } + + /** + * Removes the DOM node representing the assertion. + */ + _removeDOMNodeForAssertion(assertion) { + if (isAttr(assertion._DOMnode)) { + var parent = assertion._DOMnode.ownerElement; + parent.removeAttributeNode(assertion._DOMnode); + } else if (assertion._isSubjectElement) { + var domnode = renameNode(assertion._DOMnode, NS_RDF, "Description"); + if (domnode != assertion._DOMnode) { + var pos = this._elements.indexOf(assertion._DOMnode); + this._elements.splice(pos, 1, domnode); + } + parent = domnode; + } else { + var object = assertion.getObject(); + if (object instanceof RDFSubject && assertion._DOMnode.firstChild) { + // Object is a subject that has an Element inside this assertion's node. + for (let element of object._elements) { + if (element.parentNode == assertion._DOMnode) { + object._removeElement(element); + break; + } + } + } + parent = assertion._DOMnode.parentNode; + if (assertion._DOMnode.namespaceURI == NS_RDF && + assertion._DOMnode.localName == "li") + parent.listCounter--; + this._ds._removeElement(assertion._DOMnode); + } + + // If there are no assertions left using the assertion's containing dom node + // then remove it from the document. + // TODO could do with a quick lookup list for assertions attached to a node + for (var p in this._assertions) { + for (let assertion of this._assertions[p]) { + if (assertion._getSubjectElement() == parent) + return; + } + } + // No assertions left in this element. + this._removeElement(parent); + } + + /** + * Parses the given Element from the DOM document + */ + _parseElement(element) { + this._elements.push(element); + + // There might be an inferred rdf:type assertion in the element name + if (element.namespaceURI != NS_RDF || + element.localName != "Description") { + if (element.namespaceURI == NS_RDF && element.localName == "li") + throw new Error("rdf:li is not a valid type for a subject node"); + var assertion = new RDFAssertion(this, RDF_R("type"), + this._ds.getResource(element.namespaceURI + element.localName)); + assertion._DOMnode = element; + assertion._isSubjectElement = true; + this._addAssertion(assertion); + } + + // Certain attributes can be literal properties + for (let attr of element.attributes) { + if (attr.namespaceURI == NS_XML || attr.namespaceURI == NS_XMLNS || + attr.nodeName == "xmlns") + continue; + if ((attr.namespaceURI == NS_RDF || !attr.namespaceURI) && + (["nodeID", "about", "resource", "ID", "parseType"].includes(attr.localName))) + continue; + var object = null; + if (attr.namespaceURI == NS_RDF) { + if (attr.localName == "type") + object = this._ds.getResource(attr.nodeValue); + else if (attr.localName == "li") + throw new Error("rdf:li is not allowed as a property attribute"); + else if (attr.localName == "aboutEach") + throw new Error("rdf:aboutEach is deprecated"); + else if (attr.localName == "aboutEachPrefix") + throw new Error("rdf:aboutEachPrefix is deprecated"); + else if (attr.localName == "aboutEach") + throw new Error("rdf:aboutEach is deprecated"); + else if (attr.localName == "bagID") + throw new Error("rdf:bagID is deprecated"); + } + if (!object) + object = new RDFLiteral(attr.nodeValue); + assertion = new RDFAssertion(this, attr.namespaceURI + attr.localName, object); + assertion._DOMnode = attr; + this._addAssertion(assertion); + } + + var child = element.firstChild; + element.listCounter = 1; + while (child) { + if (isText(child) && /\S/.test(child.nodeValue)) { + ERROR(`Text ${child.nodeValue} is not allowed in a subject node`); + throw new Error("subject nodes cannot contain text content"); + } else if (isElement(child)) { + object = null; + var predicate = child.namespaceURI + child.localName; + if (child.namespaceURI == NS_RDF) { + if (RDF_PROPERTY_INVALID_TYPES.includes(child.localName) && + !child.localName.match(/^_\d+$/)) + throw new Error(`${child.nodeName} is an invalid property`); + if (child.localName == "li") { + predicate = RDF_R(`_${element.listCounter}`); + element.listCounter++; + } + } + + // Check for and bail out on unknown attributes on the property element + for (let attr of child.attributes) { + // Ignore XML namespaced attributes + if (attr.namespaceURI == NS_XML) + continue; + // These are reserved by XML for future use + if (attr.localName.substring(0, 3).toLowerCase() == "xml") + continue; + // We can handle these RDF attributes + if ((!attr.namespaceURI || attr.namespaceURI == NS_RDF) && + ["resource", "nodeID"].includes(attr.localName)) + continue; + // This is a special attribute we handle for compatibility with Mozilla RDF + if (attr.namespaceURI == NS_NC && + attr.localName == "parseType") + continue; + throw new Error(`Attribute ${attr.nodeName} is not supported`); + } + + var parseType = child.getAttributeNS(NS_NC, "parseType"); + if (parseType && parseType != "Date" && parseType != "Integer") { + ERROR(`parseType ${parseType} is not supported`); + throw new Error("unsupported parseType"); + } + + var resource = getRDFAttribute(child, "resource"); + var nodeID = getRDFAttribute(child, "nodeID"); + if ((resource && (nodeID || parseType)) || + (nodeID && (resource || parseType))) { + ERROR("Cannot use more than one of parseType, resource and nodeID on a single node"); + throw new Error("Invalid rdf assertion"); + } + + if (resource !== undefined) { + var base = Services.io.newURI(element.baseURI); + object = this._ds.getResource(base.resolve(resource)); + } else if (nodeID !== undefined) { + if (!nodeID.match(XML_NCNAME)) + throw new Error("rdf:nodeID must be a valid XML name"); + object = this._ds.getBlankNode(nodeID); + } else { + var hasText = false; + var childElement = null; + var subchild = child.firstChild; + while (subchild) { + if (isText(subchild) && /\S/.test(subchild.nodeValue)) { + hasText = true; + } else if (isElement(subchild)) { + if (childElement) { + new Error(`Multiple object elements found in ${child.nodeName}`); + } + childElement = subchild; + } + subchild = subchild.nextSibling; + } + + if ((resource || nodeID) && (hasText || childElement)) { + ERROR("Assertion references a resource so should not contain additional contents"); + throw new Error("assertion cannot contain multiple objects"); + } + + if (hasText && childElement) { + ERROR(`Both literal and resource objects found in ${child.nodeName}`); + throw new Error("assertion cannot contain multiple objects"); + } + + if (childElement) { + if (parseType) { + ERROR("Cannot specify a parseType for an assertion with resource object"); + throw new Error("parseType is not valid in this context"); + } + object = this._ds._getSubjectForElement(childElement); + object._parseElement(childElement); + } else if (parseType == "Integer") + object = new RDFIntLiteral(child.textContent); + else if (parseType == "Date") + object = new RDFDateLiteral(new Date(child.textContent)); + else + object = new RDFLiteral(child.textContent); + } + + assertion = new RDFAssertion(this, predicate, object); + this._addAssertion(assertion); + assertion._DOMnode = child; + } + child = child.nextSibling; + } + } + + /** + * Adds a new assertion to the internal hashes. Should be called for every + * new assertion parsed or created programmatically. + */ + _addAssertion(assertion) { + var predicate = assertion.getPredicate(); + if (predicate in this._assertions) + this._assertions[predicate].push(assertion); + else + this._assertions[predicate] = [ assertion ]; + + var object = assertion.getObject(); + if (object instanceof RDFSubject) { + // Create reverse assertion + if (predicate in object._backwards) + object._backwards[predicate].push(assertion); + else + object._backwards[predicate] = [ assertion ]; + } + } + + /** + * Removes an assertion from the internal hashes. Should be called for all + * assertions that are programatically deleted. + */ + _removeAssertion(assertion) { + var predicate = assertion.getPredicate(); + if (predicate in this._assertions) { + var pos = this._assertions[predicate].indexOf(assertion); + if (pos >= 0) + this._assertions[predicate].splice(pos, 1); + if (this._assertions[predicate].length == 0) + delete this._assertions[predicate]; + } + + var object = assertion.getObject(); + if (object instanceof RDFSubject) { + // Delete reverse assertion + if (predicate in object._backwards) { + pos = object._backwards[predicate].indexOf(assertion); + if (pos >= 0) + object._backwards[predicate].splice(pos, 1); + if (object._backwards[predicate].length == 0) + delete object._backwards[predicate]; + } + } + } + + /** + * Returns the ordinal assertions from this subject in order. + */ + _getChildAssertions() { + var assertions = []; + for (var i in this._assertions) { + if (RDF_LISTITEM.test(i)) + assertions.push(...this._assertions[i]); + } + assertions.sort(predicateOrder); + return assertions; + } + + /** + * Compares this to another rdf node + */ + equals(rdfnode) { + // subjects are created by the datasource so no two objects ever correspond + // to the same one. + return this === rdfnode; + } + + /** + * Adds a new assertion with this as the subject + */ + assert(predicate, object) { + if (predicate == RDF_R("type") && !(object instanceof RDFResource)) + throw new Error("rdf:type must be an RDFResource"); + + var assertion = new RDFAssertion(this, predicate, object); + this._createDOMNodeForAssertion(assertion); + this._addAssertion(assertion); + } + + /** + * Removes an assertion matching the predicate and node given, if such an + * assertion exists. + */ + unassert(predicate, object) { + if (!(predicate in this._assertions)) + return; + + for (let assertion of this._assertions[predicate]) { + if (assertion.getObject().equals(object)) { + this._removeAssertion(assertion); + this._removeDOMNodeForAssertion(assertion); + return; + } + } + } + + /** + * Returns an array of all the predicates that exist in assertions from this + * subject. + */ + getPredicates() { + return Object.keys(this._assertions); + } + + /** + * Returns all objects in assertions with this subject and the given predicate. + */ + getObjects(predicate) { + if (predicate in this._assertions) + return Array.from(this._assertions[predicate], + i => i.getObject()); + + return []; + } + + /** + * Returns all of the ordinal children of this subject in order. + */ + getChildren() { + return Array.from(this._getChildAssertions(), + i => i.getObject()); + } + + /** + * Removes the child at the given index. This is the index based on the + * children returned from getChildren. Forces a reordering of the later + * children. + */ + removeChildAt(pos) { + if (pos < 0) + throw new Error("no such child"); + var assertions = this._getChildAssertions(); + if (pos >= assertions.length) + throw new Error("no such child"); + for (var i = pos; i < assertions.length; i++) { + this._removeAssertion(assertions[i]); + this._removeDOMNodeForAssertion(assertions[i]); + } + var index = 1; + if (pos > 0) + index = parseInt(assertions[pos - 1].getPredicate().substring(NS_RDF.length + 1)) + 1; + for (let i = pos + 1; i < assertions.length; i++) { + assertions[i]._predicate = RDF_R(`_${index}`); + this._addAssertion(assertions[i]); + this._createDOMNodeForAssertion(assertions[i]); + index++; + } + } + + /** + * Removes the child with the given object. It is unspecified which child is + * removed if the object features more than once. + */ + removeChild(object) { + var assertions = this._getChildAssertions(); + for (var pos = 0; pos < assertions.length; pos++) { + if (assertions[pos].getObject().equals(object)) { + for (var i = pos; i < assertions.length; i++) { + this._removeAssertion(assertions[i]); + this._removeDOMNodeForAssertion(assertions[i]); + } + var index = 1; + if (pos > 0) + index = parseInt(assertions[pos - 1].getPredicate().substring(NS_RDF.length + 1)) + 1; + for (let i = pos + 1; i < assertions.length; i++) { + assertions[i]._predicate = RDF_R(`_${index}`); + this._addAssertion(assertions[i]); + this._createDOMNodeForAssertion(assertions[i]); + index++; + } + return; + } + } + throw new Error("no such child"); + } + + /** + * Adds a new ordinal child to this subject. + */ + addChild(object) { + var max = 0; + for (var i in this._assertions) { + if (RDF_LISTITEM.test(i)) + max = Math.max(max, parseInt(i.substring(NS_RDF.length + 1))); + } + max++; + this.assert(RDF_R(`_${max}`), object); + } + + /** + * This reorders the child assertions to remove duplicates and gaps in the + * sequence. Generally this will move all children to be under the same + * container element and all represented as an rdf:li + */ + reorderChildren() { + var assertions = this._getChildAssertions(); + for (let assertion of assertions) { + this._removeAssertion(assertion); + this._removeDOMNodeForAssertion(assertion); + } + var index = 1; + for (let assertion of assertions) { + assertion._predicate = RDF_R(`_${index}`); + this._addAssertion(assertion); + this._createDOMNodeForAssertion(assertion); + index++; + } + } + + /** + * Returns the type of this subject or null if there is no specified type. + */ + getType() { + var type = this.getProperty(RDF_R("type")); + if (type && type instanceof RDFResource) + return type.getURI(); + return null; + } + + /** + * Tests if a property exists for the given predicate. + */ + hasProperty(predicate) { + return (predicate in this._assertions); + } + + /** + * Retrieves the first property value for the given predicate. + */ + getProperty(predicate) { + if (predicate in this._assertions) + return this._assertions[predicate][0].getObject(); + return null; + } + + /** + * Sets the property value for the given predicate, clearing any existing + * values. + */ + setProperty(predicate, object) { + // TODO optimise by replacing the first assertion and clearing the rest + this.clearProperty(predicate); + this.assert(predicate, object); + } + + /** + * Clears any existing properties for the given predicate. + */ + clearProperty(predicate) { + if (!(predicate in this._assertions)) + return; + + var assertions = this._assertions[predicate]; + while (assertions.length > 0) { + var assertion = assertions[0]; + this._removeAssertion(assertion); + this._removeDOMNodeForAssertion(assertion); + } + } +} + +/** + * Creates a new RDFResource for the datasource. Private. + */ +class RDFResource extends RDFSubject { + constructor(ds, uri) { + if (!(ds instanceof RDFDataSource)) + throw new Error("datasource must be an RDFDataSource"); + + if (!uri) + throw new Error("An RDFResource requires a non-null uri"); + + super(ds); + // This is the uri that the resource represents. + this._uri = uri; + } + + /** + * Sets attributes on the DOM element to mark it as representing this resource + */ + _applyToElement(element) { + if (USE_RDFNS_ATTR) { + var prefix = this._ds._resolvePrefix(element, RDF_R("about")); + element.setAttributeNS(prefix.namespaceURI, prefix.qname, this._uri); + } else { + element.setAttribute("about", this._uri); + } + } + + /** + * Adds a reference to this resource to the given property Element. + */ + _addReferenceToElement(element) { + if (USE_RDFNS_ATTR) { + var prefix = this._ds._resolvePrefix(element, RDF_R("resource")); + element.setAttributeNS(prefix.namespaceURI, prefix.qname, this._uri); + } else { + element.setAttribute("resource", this._uri); + } + } + + /** + * Removes any reference to this resource from the given property Element. + */ + _removeReferenceFromElement(element) { + if (element.hasAttributeNS(NS_RDF, "resource")) + element.removeAttributeNS(NS_RDF, "resource"); + if (element.hasAttribute("resource")) + element.removeAttribute("resource"); + } + + getURI() { + return this._uri; + } +} + +/** + * Creates a new blank node. Private. + */ +class RDFBlankNode extends RDFSubject { + constructor(ds, nodeID) { + if (!(ds instanceof RDFDataSource)) + throw new Error("datasource must be an RDFDataSource"); + + super(ds); + // The nodeID of this node. May be null if there is no ID. + this._nodeID = nodeID; + } + + /** + * Sets attributes on the DOM element to mark it as representing this node + */ + _applyToElement(element) { + if (!this._nodeID) + return; + if (USE_RDFNS_ATTR) { + var prefix = this._ds._resolvePrefix(element, RDF_R("nodeID")); + element.setAttributeNS(prefix.namespaceURI, prefix.qname, this._nodeID); + } else { + element.setAttribute("nodeID", this._nodeID); + } + } + + /** + * Creates a new Element in the document for holding assertions about this + * subject. The URI controls what tagname to use. + */ + _createNewElement(uri) { + // If there are already nodes representing this in the document then we need + // a nodeID to match them + if (!this._nodeID && this._elements.length > 0) { + this._ds._createNodeID(this); + for (let element of this._elements) + this._applyToElement(element); + } + + return super._createNewElement.call(uri); + } + + /** + * Adds a reference to this node to the given property Element. + */ + _addReferenceToElement(element) { + if (this._elements.length > 0 && !this._nodeID) { + // In document elsewhere already + // Create a node ID and update the other nodes referencing + this._ds._createNodeID(this); + for (let element of this._elements) + this._applyToElement(element); + } + + if (this._nodeID) { + if (USE_RDFNS_ATTR) { + let prefix = this._ds._resolvePrefix(element, RDF_R("nodeID")); + element.setAttributeNS(prefix.namespaceURI, prefix.qname, this._nodeID); + } else { + element.setAttribute("nodeID", this._nodeID); + } + } else { + // Add the empty blank node, this is generally right since further + // assertions will be added to fill this out + var newelement = this._ds._addElement(element, RDF_R("Description")); + newelement.listCounter = 1; + this._elements.push(newelement); + } + } + + /** + * Removes any reference to this node from the given property Element. + */ + _removeReferenceFromElement(element) { + if (element.hasAttributeNS(NS_RDF, "nodeID")) + element.removeAttributeNS(NS_RDF, "nodeID"); + if (element.hasAttribute("nodeID")) + element.removeAttribute("nodeID"); + } + + getNodeID() { + return this._nodeID; + } +} + +/** + * Creates a new RDFDataSource from the given document. The document will be + * changed as assertions are added and removed to the RDF. Pass a null document + * to start with an empty graph. + */ +class RDFDataSource { + constructor(document) { + // All known resources, indexed on URI + this._resources = {}; + // All blank nodes + this._allBlankNodes = []; + // All blank nodes with IDs, indexed on ID + this._blankNodes = {}; + // Suggested prefixes to use for namespaces, index is prefix, value is namespaceURI. + this._prefixes = { + rdf: NS_RDF, + NC: NS_NC + }; + + if (!document) { + // Creating a document through xpcom leaves out the xml prolog so just parse + // something small + var parser = Cc["@mozilla.org/xmlextras/domparser;1"]. + createInstance(Ci.nsIDOMParser); + var doctext = `\n\n`; + document = parser.parseFromString(doctext, "text/xml"); + } + // The underlying DOM document for this datasource + this._document = document; + this._parseDocument(); + } + + static loadFromString(text) { + let parser = new DOMParser(); + let document = parser.parseFromString(text, "application/xml"); + + return new this(document); + } + + static loadFromBuffer(buffer) { + let parser = new DOMParser(); + let document = parser.parseFromBuffer(new Uint8Array(buffer), "application/xml"); + + return new this(document); + } + + static async loadFromFile(uri) { + if (uri instanceof Ci.nsIFile) + uri = Services.io.newFileURI(uri); + else if (typeof(uri) == "string") + uri = Services.io.newURI(uri); + + let resp = await fetch(uri.spec); + return this.loadFromBuffer(await resp.arrayBuffer()); + } + + get uri() { + return this._document.documentURI; + } + + /** + * Creates a new nodeID for an unnamed blank node. Just node. + */ + _createNodeID(blanknode) { + var i = 1; + while (`node${i}` in this._blankNodes) + i++; + blanknode._nodeID = `node${i}`; + this._blankNodes[blanknode._nodeID] = blanknode; + } + + /** + * Returns an rdf subject for the given DOM Element. If the subject has not + * been seen before a new one is created. + */ + _getSubjectForElement(element) { + if (element.namespaceURI == NS_RDF && + RDF_NODE_INVALID_TYPES.includes(element.localName)) + throw new Error(`${element.nodeName} is not a valid class for a subject node`); + + var about = getRDFAttribute(element, "about"); + var id = getRDFAttribute(element, "ID"); + var nodeID = getRDFAttribute(element, "nodeID"); + + if ((about && (id || nodeID)) || + (nodeID && (id || about))) { + ERROR("More than one of about, ID and nodeID present on the same subject"); + throw new Error("invalid subject in rdf"); + } + + if (about !== undefined) { + let base = Services.io.newURI(element.baseURI); + return this.getResource(base.resolve(about)); + } + if (id !== undefined) { + if (!id.match(XML_NCNAME)) + throw new Error("rdf:ID must be a valid XML name"); + let base = Services.io.newURI(element.baseURI); + return this.getResource(base.resolve(`#${id}`)); + } + if (nodeID !== undefined) + return this.getBlankNode(nodeID); + return this.getBlankNode(null); + } + + /** + * Parses the document for subjects at the top level. + */ + _parseDocument() { + if (!this._document.documentElement) { + ERROR("No document element in document"); + throw new Error("document contains no root element"); + } + + if (this._document.documentElement.namespaceURI != NS_RDF || + this._document.documentElement.localName != "RDF") { + ERROR(`${this._document.documentElement.nodeName} is not rdf:RDF`); + throw new Error("document does not appear to be RDF"); + } + + var domnode = this._document.documentElement.firstChild; + while (domnode) { + if (isText(domnode) && /\S/.test(domnode.nodeValue)) { + ERROR("RDF does not allow for text in the root of the document"); + throw new Error("invalid markup in document"); + } else if (isElement(domnode)) { + var subject = this._getSubjectForElement(domnode); + subject._parseElement(domnode); + } + domnode = domnode.nextSibling; + } + } + + /** + * Works out a sensible namespace prefix to use for the given uri. node should + * be the parent of where the element is to be inserted, or the node that an + * attribute is to be added to. This will recursively walk to the top of the + * document finding an already registered prefix that matches for the uri. + * If none is found a new prefix is registered. + * This returns an object with keys namespaceURI, prefix, localName and qname. + * Pass null or undefined for badPrefixes for the first call. + */ + _resolvePrefix(domnode, uri, badPrefixes) { + if (!badPrefixes) + badPrefixes = []; + + // No known prefix, try to create one from the lookup list + if (!domnode || isDocument(domnode)) { + for (let i in this._prefixes) { + if (badPrefixes.includes(i)) + continue; + if (this._prefixes[i] == uri.substring(0, this._prefixes[i].length)) { + var local = uri.substring(this._prefixes[i].length); + var test = URI_SUFFIX.exec(local); + // Remaining part of uri is a good XML Name + if (test && test[0] == local) { + this._document.documentElement.setAttributeNS(NS_XMLNS, `xmlns:${i}`, this._prefixes[i]); + return { + namespaceURI: this._prefixes[i], + prefix: i, + localName: local, + qname: i ? `${i}:${local}` : local + }; + } + } + } + + // No match, make something up + test = URI_SUFFIX.exec(uri); + if (test) { + var namespaceURI = uri.substring(0, uri.length - test[0].length); + local = test[0]; + let i = 1; + while (badPrefixes.includes(`NS${i}`)) + i++; + this._document.documentElement.setAttributeNS(NS_XMLNS, `xmlns:NS${i}`, namespaceURI); + return { + namespaceURI, + prefix: `NS${i}`, + localName: local, + qname: `NS${i}:${local}`, + }; + } + // There is no end part of this URI that is an XML Name + throw new Error(`invalid node name: ${uri}`); + } + + for (let attr of domnode.attributes) { + // Not a namespace declaration, ignore this attribute + if (attr.namespaceURI != NS_XMLNS && attr.nodeName != "xmlns") + continue; + + var prefix = attr.prefix ? attr.localName : ""; + // Seen this prefix before, cannot use it + if (badPrefixes.includes(prefix)) + continue; + + // Namespace matches the start of the uri + if (attr.value == uri.substring(0, attr.value.length)) { + local = uri.substring(attr.value.length); + test = URI_SUFFIX.exec(local); + // Remaining part of uri is a good XML Name + if (test && test[0] == local) { + return { + namespaceURI: attr.value, + prefix, + localName: local, + qname: prefix ? `${prefix}:${local}` : local + }; + } + } + + badPrefixes.push(prefix); + } + + // No prefix found here, move up the document + return this._resolvePrefix(domnode.parentNode, uri, badPrefixes); + } + + /** + * Guess the indent level within the given Element. The method looks for + * elements that are preceeded by whitespace including a newline. The + * whitespace following the newline is presumed to be the indentation for the + * element. + * If the indentation cannot be guessed then it recurses up the document + * hierarchy until it can guess the indent or until the Document is reached. + */ + _guessIndent(element) { + // The indent at document level is 0 + if (!element || isDocument(element)) + return ""; + + // Check the text immediately preceeding each child node. One could be + // a valid indent + var pretext = ""; + var child = element.firstChild; + while (child) { + if (isText(child)) { + pretext += child.nodeValue; + } else if (isElement(child)) { + var result = INDENT.exec(pretext); + if (result) + return result[1]; + pretext = ""; + } + child = child.nextSibling; + } + + // pretext now contains any trailing text in the element. This can be + // the indent of the end tag. If so add a little to it. + result = INDENT.exec(pretext); + if (result) + return `${result[1]} `; + + // Check the text immediately before this node + pretext = ""; + var sibling = element.previousSibling; + while (sibling && isText(sibling)) { + pretext += sibling.nodeValue; + sibling = sibling.previousSibling; + } + + // If there is a sensible indent then just add to it. + result = INDENT.exec(pretext); + if (result) + return `${result[1]} `; + + // Last chance, get the indent level for the tag above and add to it + return `${this._guessIndent(element.parentNode)} `; + } + + _addElement(parent, uri) { + var prefix = this._resolvePrefix(parent, uri); + var element = this._document.createElementNS(prefix.namespaceURI, prefix.qname); + + if (parent.lastChild) { + // We want to insert immediately after the last child element + var last = parent.lastChild; + while (last && isText(last)) + last = last.previousSibling; + // No child elements so insert at the start + if (!last) + last = parent.firstChild; + else + last = last.nextSibling; + + let indent = this._guessIndent(parent); + parent.insertBefore(this._document.createTextNode(`\n${indent}`), last); + parent.insertBefore(element, last); + } else { + // No children, must indent our element and the end tag + let indent = this._guessIndent(parent.parentNode); + parent.append(`\n${indent} `, element, `\n${indent}`); + } + return element; + } + + /** + * Removes the element from its parent. Should also remove surrounding + * white space as appropriate. + */ + _removeElement(element) { + var parent = element.parentNode; + var sibling = element.previousSibling; + // Drop any text nodes immediately preceeding the element + while (sibling && isText(sibling)) { + var temp = sibling; + sibling = sibling.previousSibling; + parent.removeChild(temp); + } + + sibling = element.nextSibling; + // Drop the element + parent.removeChild(element); + + // If the next node after element is now the first child then element was + // the first child. If there are no other child elements then remove the + // remaining child nodes. + if (parent.firstChild == sibling) { + while (sibling && isText(sibling)) + sibling = sibling.nextSibling; + if (!sibling) { + // No other child elements + while (parent.lastChild) + parent.removeChild(parent.lastChild); + } + } + } + + /** + * Requests that a given prefix be used for the namespace where possible. + * This must be called before any assertions are made using the namespace + * and the registration will not override any existing prefix used in the + * document. + */ + registerPrefix(prefix, namespaceURI) { + this._prefixes[prefix] = namespaceURI; + } + + /** + * Gets a blank node. nodeID may be null and if so a new blank node is created. + * If a nodeID is given then the blank node with that ID is returned or created. + */ + getBlankNode(nodeID) { + if (nodeID && nodeID in this._blankNodes) + return this._blankNodes[nodeID]; + + if (nodeID && !nodeID.match(XML_NCNAME)) + throw new Error("rdf:nodeID must be a valid XML name"); + + var rdfnode = new RDFBlankNode(this, nodeID); + this._allBlankNodes.push(rdfnode); + if (nodeID) + this._blankNodes[nodeID] = rdfnode; + return rdfnode; + } + + /** + * Gets all blank nodes + */ + getAllBlankNodes() { + return this._allBlankNodes.slice(); + } + + /** + * Gets the resource for the URI. The resource is created if it has not been + * used already. + */ + getResource(uri) { + if (uri in this._resources) + return this._resources[uri]; + + var resource = new RDFResource(this, uri); + this._resources[uri] = resource; + return resource; + } + + /** + * Gets all resources that have been used. + */ + getAllResources() { + return Object.values(this._resources); + } + + /** + * Returns all blank nodes and resources + */ + getAllSubjects() { + return [...Object.values(this._resources), + ...this._allBlankNodes]; + } + + /** + * Saves the RDF/XML to a string. + */ + serializeToString() { + var serializer = new XMLSerializer(); + return serializer.serializeToString(this._document); + } + + /** + * Saves the RDF/XML to a file. + */ + async saveToFile(file) { + return OS.File.writeAtomic(file, new TextEncoder().encode(this.serializeToString())); + } +} diff --git a/toolkit/mozapps/extensions/internal/moz.build b/toolkit/mozapps/extensions/internal/moz.build index 18c728197137..3d96f33d31f2 100644 --- a/toolkit/mozapps/extensions/internal/moz.build +++ b/toolkit/mozapps/extensions/internal/moz.build @@ -12,6 +12,7 @@ EXTRA_JS_MODULES.addons += [ 'GMPProvider.jsm', 'LightweightThemeImageOptimizer.jsm', 'ProductAddonChecker.jsm', + 'RDFDataSource.jsm', 'SpellCheckDictionaryBootstrap.js', 'UpdateRDFConverter.jsm', 'XPIDatabase.jsm', From 03efd881e77e476e6d81ef65477e8dc15ad663f4 Mon Sep 17 00:00:00 2001 From: Kris Maglione Date: Sat, 28 Apr 2018 19:20:38 -0700 Subject: [PATCH 30/34] Bug 1457749: Part 2 - Update UpdateRDFConverter to use RDFDataSource.jsm. r=Mossop MozReview-Commit-ID: HbJ3vBSBXH2 --HG-- extra : source : 7f657f4d30880395e20f990c5c97ece275a61de2 --- .../internal/UpdateRDFConverter.jsm | 221 ++++++++---------- 1 file changed, 102 insertions(+), 119 deletions(-) diff --git a/toolkit/mozapps/extensions/internal/UpdateRDFConverter.jsm b/toolkit/mozapps/extensions/internal/UpdateRDFConverter.jsm index af1af0decdbe..30396552765c 100644 --- a/toolkit/mozapps/extensions/internal/UpdateRDFConverter.jsm +++ b/toolkit/mozapps/extensions/internal/UpdateRDFConverter.jsm @@ -5,155 +5,138 @@ var EXPORTED_SYMBOLS = ["UpdateRDFConverter"]; -const PREFIX_NS_EM = "http://www.mozilla.org/2004/em-rdf#"; +ChromeUtils.defineModuleGetter(this, "RDFDataSource", + "resource://gre/modules/addons/RDFDataSource.jsm"); +ChromeUtils.defineModuleGetter(this, "Services", + "resource://gre/modules/Services.jsm"); + const PREFIX_ITEM = "urn:mozilla:item:"; const PREFIX_EXTENSION = "urn:mozilla:extension:"; const PREFIX_THEME = "urn:mozilla:theme:"; const TOOLKIT_ID = "toolkit@mozilla.org"; -ChromeUtils.import("resource://gre/modules/Services.jsm"); -ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); +function EM_R(aProperty) { + return `http://www.mozilla.org/2004/em-rdf#${aProperty}`; +} -XPCOMUtils.defineLazyServiceGetters(this, { - gRDF: ["@mozilla.org/rdf/rdf-service;1", "nsIRDFService"], - containerUtils: ["@mozilla.org/rdf/container-utils;1", "nsIRDFContainerUtils"], -}); +function getValue(literal) { + return literal && literal.getValue(); +} -const RDFContainer = Components.Constructor( - "@mozilla.org/rdf/container;1", "nsIRDFContainer", "Init"); -const RDFDataSource = Components.Constructor( - "@mozilla.org/rdf/datasource;1?name=in-memory-datasource", "nsIRDFDataSource"); -const RDFParser = Components.Constructor( - "@mozilla.org/rdf/xml-parser;1", "nsIRDFXMLParser"); +function getProperty(resource, property) { + return getValue(resource.getProperty(EM_R(property))); +} -/** - * Parses an RDF style update manifest into a JSON-style update - * manifest. - * - * @param {XMLHttpRequest> aRequest - * The XMLHttpRequest that has retrieved the update manifest - * @returns {object} a JSON update manifest. - */ -function parseRDFManifest(aRequest) { - function EM_R(aProp) { - return gRDF.GetResource(PREFIX_NS_EM + aProp); +function getBoolProperty(resource, property) { + return getValue(resource.getProperty(EM_R(property))) == "true"; +} + +class Manifest { + constructor(ds) { + this.ds = ds; } - function getValue(aLiteral) { - if (aLiteral instanceof Ci.nsIRDFLiteral) - return aLiteral.Value; - if (aLiteral instanceof Ci.nsIRDFResource) - return aLiteral.Value; - if (aLiteral instanceof Ci.nsIRDFInt) - return aLiteral.Value; - return null; + static loadFromString(text) { + return new this(RDFDataSource.loadFromString(text)); } - function getProperty(aDs, aSource, aProperty) { - return getValue(aDs.GetTarget(aSource, EM_R(aProperty), true)); + static loadFromBuffer(buffer) { + return new this(RDFDataSource.loadFromBuffer(buffer)); } - function getBooleanProperty(aDs, aSource, aProperty) { - let propValue = aDs.GetTarget(aSource, EM_R(aProperty), true); - if (!propValue) - return undefined; - return getValue(propValue) == "true"; + static async loadFromFile(uri) { + return new this(await RDFDataSource.loadFromFile(uri)); } +} - let rdfParser = new RDFParser(); - let ds = new RDFDataSource(); - rdfParser.parseString(ds, aRequest.channel.URI, aRequest.responseText); +class UpdateRDF extends Manifest { + decode() { + let addons = {}; + let result = {addons}; - let addons = {}; - let result = {addons}; - - for (let addonRes of XPCOMUtils.IterSimpleEnumerator(ds.GetAllResources(), Ci.nsIRDFResource)) { - let value = addonRes.ValueUTF8; - let id; - for (let prefix of [PREFIX_EXTENSION, PREFIX_THEME, PREFIX_ITEM]) { - if (value.startsWith(prefix)) { - id = value.substr(prefix.length); - break; - } - } - if (!id) { - continue; - } - - let addon = {}; - addons[id] = addon; - - let updatesTarget = ds.GetTarget(addonRes, EM_R("updates"), true); - if (!(updatesTarget instanceof Ci.nsIRDFResource) || - !containerUtils.IsContainer(ds, updatesTarget)) { - continue; - } - - let updates = []; - addon.updates = updates; - - let ctr = new RDFContainer(ds, updatesTarget); - for (let item of XPCOMUtils.IterSimpleEnumerator(ctr.GetElements(), - Ci.nsIRDFResource)) { - let version = getProperty(ds, item, "version"); - - let targetApps = ds.GetTargets(item, EM_R("targetApplication"), true); - for (let targetApp of XPCOMUtils.IterSimpleEnumerator(targetApps, - Ci.nsIRDFResource)) { - let appEntry = {}; - - let minVersion = getProperty(ds, targetApp, "minVersion"); - if (minVersion) { - appEntry.strict_min_version = minVersion; + for (let resource of this.ds.getAllResources()) { + let id; + let uri = resource.getURI(); + for (let prefix of [PREFIX_EXTENSION, PREFIX_THEME, PREFIX_ITEM]) { + if (uri.startsWith(prefix)) { + id = uri.substr(prefix.length); + break; } + } + if (!id) { + continue; + } - let maxVersion = getProperty(ds, targetApp, "maxVersion"); - if (maxVersion) { - if (getBooleanProperty(ds, targetApp, "strictCompatibility")) { - appEntry.strict_max_version = maxVersion; - } else { - appEntry.advisory_max_version = maxVersion; + let addon = {}; + addons[id] = addon; + + let updatesProp = resource.getProperty(EM_R("updates")); + if (!updatesProp || !updatesProp.getChildren) { + continue; + } + + let updates = []; + addon.updates = updates; + + for (let item of updatesProp.getChildren()) { + let version = getProperty(item, "version"); + + for (let targetApp of item.getObjects(EM_R("targetApplication"))) { + let appEntry = {}; + + let minVersion = getProperty(targetApp, "minVersion"); + if (minVersion) { + appEntry.strict_min_version = minVersion; } - } - let appId = getProperty(ds, targetApp, "id"); - if (!appId) { - continue; - } - if (appId === TOOLKIT_ID || appId === Services.appinfo.ID) { - appId = "gecko"; - } + let maxVersion = getProperty(targetApp, "maxVersion"); + if (maxVersion) { + if (getBoolProperty(targetApp, "strictCompatibility")) { + appEntry.strict_max_version = maxVersion; + } else { + appEntry.advisory_max_version = maxVersion; + } + } - let update = { - applications: {[appId]: appEntry}, - }; - if (version) { - update.version = version; - } - let updateLink = getProperty(ds, targetApp, "updateLink"); - if (updateLink) { - update.update_link = updateLink; - } - let updateInfoURL = getProperty(ds, targetApp, "updateInfoURL"); - if (updateInfoURL) { - update.update_info_url = updateInfoURL; - } - let updateHash = getProperty(ds, targetApp, "updateHash"); - if (updateHash) { - update.update_hash = updateHash; - } + let appId = getProperty(targetApp, "id"); + if (!appId) { + continue; + } + if (appId === TOOLKIT_ID || appId === Services.appinfo.ID) { + appId = "gecko"; + } - updates.push(update); + let update = { + applications: {[appId]: appEntry}, + }; + if (version) { + update.version = version; + } + let updateLink = getProperty(targetApp, "updateLink"); + if (updateLink) { + update.update_link = updateLink; + } + let updateInfoURL = getProperty(targetApp, "updateInfoURL"); + if (updateInfoURL) { + update.update_info_url = updateInfoURL; + } + let updateHash = getProperty(targetApp, "updateHash"); + if (updateHash) { + update.update_hash = updateHash; + } + + updates.push(update); + } } } - } - return result; + return result; + } } var UpdateRDFConverter = { convertToJSON(request) { - return parseRDFManifest(request); + return UpdateRDF.loadFromString(request.responseText).decode(); }, }; From c9334a34edfe349e57c497aee1b53609c895a2ab Mon Sep 17 00:00:00 2001 From: Kris Maglione Date: Sat, 28 Apr 2018 19:27:33 -0700 Subject: [PATCH 31/34] Bug 1457749: Part 3 - Migrate install.rdf parser to use RDFDataSource.jsm. r=Mossop This is based on a script I'd already created to migrate test extensions to the JSON format we use to generate fixture add-ons. The delay update add-ons used invalid XML in their manifests, which the built-in parser ignored but the new parser doesn't accept, so I had to fix those, too. MozReview-Commit-ID: BnuxZiBhhJL --HG-- rename : toolkit/mozapps/extensions/internal/UpdateRDFConverter.jsm => toolkit/mozapps/extensions/internal/RDFManifestConverter.jsm extra : source : 292cf80054b4734a0d7c84e987f68e229f2ccc24 extra : histedit_source : 1072def8a28149a9f9882825f73435336b205072%2C2c72e58aa973fe24867868d06dcc63235dd68da2 --- .../talos/talos/tests/cpstartup/install.rdf | 4 +- .../talos/talos/tests/tabpaint/install.rdf | 4 +- .../extensions/internal/AddonTestUtils.jsm | 22 +-- .../internal/AddonUpdateChecker.jsm | 2 +- ...Converter.jsm => RDFManifestConverter.jsm} | 76 ++++++++- .../extensions/internal/XPIInstall.jsm | 150 ++++-------------- toolkit/mozapps/extensions/internal/moz.build | 2 +- .../test_delay_update_complete_v2/install.rdf | 1 + .../test_delay_update_defer_v2/install.rdf | 1 + .../test/xpcshell/test_update_rdf.js | 3 +- 10 files changed, 120 insertions(+), 145 deletions(-) rename toolkit/mozapps/extensions/internal/{UpdateRDFConverter.jsm => RDFManifestConverter.jsm} (61%) diff --git a/testing/talos/talos/tests/cpstartup/install.rdf b/testing/talos/talos/tests/cpstartup/install.rdf index e594dad4cdf1..fd6c24de11f1 100644 --- a/testing/talos/talos/tests/cpstartup/install.rdf +++ b/testing/talos/talos/tests/cpstartup/install.rdf @@ -18,7 +18,7 @@ * + https://wiki.mozilla.org/Buildbot/Talos/Tests + https://wiki.mozilla.org/Buildbot/Talos/Tests - https://wiki.mozilla.org/Buildbot/Talos/Tests - https://wiki.mozilla.org/Buildbot/Talos/Tests diff --git a/testing/talos/talos/tests/tabpaint/install.rdf b/testing/talos/talos/tests/tabpaint/install.rdf index 64ede760879e..d719ad613394 100644 --- a/testing/talos/talos/tests/tabpaint/install.rdf +++ b/testing/talos/talos/tests/tabpaint/install.rdf @@ -18,7 +18,7 @@ * + https://wiki.mozilla.org/Buildbot/Talos/Tests + https://wiki.mozilla.org/Buildbot/Talos/Tests - https://wiki.mozilla.org/Buildbot/Talos/Tests - https://wiki.mozilla.org/Buildbot/Talos/Tests diff --git a/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm b/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm index bb418f390c42..3d31b9771533 100644 --- a/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm +++ b/toolkit/mozapps/extensions/internal/AddonTestUtils.jsm @@ -34,13 +34,14 @@ ChromeUtils.defineModuleGetter(this, "FileTestUtils", "resource://testing-common/FileTestUtils.jsm"); ChromeUtils.defineModuleGetter(this, "HttpServer", "resource://testing-common/httpd.js"); +ChromeUtils.defineModuleGetter(this, "InstallRDF", + "resource://gre/modules/addons/RDFManifestConverter.jsm"); ChromeUtils.defineModuleGetter(this, "MockRegistrar", "resource://testing-common/MockRegistrar.jsm"); XPCOMUtils.defineLazyServiceGetters(this, { aomStartup: ["@mozilla.org/addons/addon-manager-startup;1", "amIAddonManagerStartup"], proxyService: ["@mozilla.org/network/protocol-proxy-service;1", "nsIProtocolProxyService"], - rdfService: ["@mozilla.org/rdf/rdf-service;1", "nsIRDFService"], uuidGen: ["@mozilla.org/uuid-generator;1", "nsIUUIDGenerator"], }); @@ -61,14 +62,6 @@ const nsFile = Components.Constructor( "@mozilla.org/file/local;1", "nsIFile", "initWithPath"); -const RDFXMLParser = Components.Constructor( - "@mozilla.org/rdf/xml-parser;1", - "nsIRDFXMLParser", "parseString"); - -const RDFDataSource = Components.Constructor( - "@mozilla.org/rdf/datasource;1?name=in-memory-datasource", - "nsIRDFDataSource"); - const ZipReader = Components.Constructor( "@mozilla.org/libjar/zip-reader;1", "nsIZipReader", "open"); @@ -613,15 +606,8 @@ var AddonTestUtils = { let body = await fetch(manifestURI.spec); if (manifestURI.spec.endsWith(".rdf")) { - let data = await body.text(); - - let ds = new RDFDataSource(); - new RDFXMLParser(ds, manifestURI, data); - - let rdfID = ds.GetTarget(rdfService.GetResource("urn:mozilla:install-manifest"), - rdfService.GetResource("http://www.mozilla.org/2004/em-rdf#id"), - true); - return rdfID.QueryInterface(Ci.nsIRDFLiteral).Value; + let manifest = InstallRDF.loadFromBuffer(await body.arrayBuffer()).decode(); + return manifest.id; } let manifest = await body.json(); diff --git a/toolkit/mozapps/extensions/internal/AddonUpdateChecker.jsm b/toolkit/mozapps/extensions/internal/AddonUpdateChecker.jsm index a3ccb42e40ad..62fe10142778 100644 --- a/toolkit/mozapps/extensions/internal/AddonUpdateChecker.jsm +++ b/toolkit/mozapps/extensions/internal/AddonUpdateChecker.jsm @@ -32,7 +32,7 @@ ChromeUtils.defineModuleGetter(this, "CertUtils", ChromeUtils.defineModuleGetter(this, "ServiceRequest", "resource://gre/modules/ServiceRequest.jsm"); ChromeUtils.defineModuleGetter(this, "UpdateRDFConverter", - "resource://gre/modules/addons/UpdateRDFConverter.jsm"); + "resource://gre/modules/addons/RDFManifestConverter.jsm"); ChromeUtils.import("resource://gre/modules/Log.jsm"); const LOGGER_ID = "addons.update-checker"; diff --git a/toolkit/mozapps/extensions/internal/UpdateRDFConverter.jsm b/toolkit/mozapps/extensions/internal/RDFManifestConverter.jsm similarity index 61% rename from toolkit/mozapps/extensions/internal/UpdateRDFConverter.jsm rename to toolkit/mozapps/extensions/internal/RDFManifestConverter.jsm index 30396552765c..9430299f920a 100644 --- a/toolkit/mozapps/extensions/internal/UpdateRDFConverter.jsm +++ b/toolkit/mozapps/extensions/internal/RDFManifestConverter.jsm @@ -1,9 +1,9 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public + /* 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/. */ "use strict"; -var EXPORTED_SYMBOLS = ["UpdateRDFConverter"]; +var EXPORTED_SYMBOLS = ["InstallRDF", "UpdateRDFConverter"]; ChromeUtils.defineModuleGetter(this, "RDFDataSource", "resource://gre/modules/addons/RDFDataSource.jsm"); @@ -16,6 +16,8 @@ const PREFIX_THEME = "urn:mozilla:theme:"; const TOOLKIT_ID = "toolkit@mozilla.org"; +const RDFURI_INSTALL_MANIFEST_ROOT = "urn:mozilla:install-manifest"; + function EM_R(aProperty) { return `http://www.mozilla.org/2004/em-rdf#${aProperty}`; } @@ -50,6 +52,76 @@ class Manifest { } } +class InstallRDF extends Manifest { + _readProps(source, obj, props) { + for (let prop of props) { + let val = getProperty(source, prop); + if (val != null) { + obj[prop] = val; + } + } + } + + _readArrayProp(source, obj, prop, target, decode = getValue) { + let result = Array.from(source.getObjects(EM_R(prop)), + target => decode(target)); + if (result.length) { + obj[target] = result; + } + } + + _readArrayProps(source, obj, props, decode = getValue) { + for (let [prop, target] of Object.entries(props)) { + this._readArrayProp(source, obj, prop, target, decode); + } + } + + _readLocaleStrings(source, obj) { + this._readProps(source, obj, ["name", "description", "creator", "homepageURL"]); + this._readArrayProps(source, obj, { + locale: "locales", + developer: "developers", + translator: "translators", + contributor: "contributors", + }); + } + + decode() { + let root = this.ds.getResource(RDFURI_INSTALL_MANIFEST_ROOT); + let result = {}; + + let props = ["id", "version", "type", "updateURL", "optionsURL", + "optionsType", "aboutURL", "iconURL", "icon64URL", + "bootstrap", "unpack", "strictCompatibility", + "hasEmbeddedWebExtension"]; + this._readProps(root, result, props); + + let decodeTargetApplication = source => { + let app = {}; + this._readProps(source, app, ["id", "minVersion", "maxVersion"]); + return app; + }; + + let decodeLocale = source => { + let localized = {}; + this._readLocaleStrings(source, localized); + return localized; + }; + + this._readLocaleStrings(root, result); + + this._readArrayProps(root, result, {"targetPlatform": "targetPlatforms"}); + this._readArrayProps(root, result, {"targetApplication": "targetApplications"}, + decodeTargetApplication); + this._readArrayProps(root, result, {"localized": "localized"}, + decodeLocale); + this._readArrayProps(root, result, {"dependency": "dependencies"}, + source => getProperty(source, "id")); + + return result; + } +} + class UpdateRDF extends Manifest { decode() { let addons = {}; diff --git a/toolkit/mozapps/extensions/internal/XPIInstall.jsm b/toolkit/mozapps/extensions/internal/XPIInstall.jsm index 0f931be618fe..7bab287c55d0 100644 --- a/toolkit/mozapps/extensions/internal/XPIInstall.jsm +++ b/toolkit/mozapps/extensions/internal/XPIInstall.jsm @@ -45,6 +45,7 @@ XPCOMUtils.defineLazyModuleGetters(this, { ZipUtils: "resource://gre/modules/ZipUtils.jsm", AddonInternal: "resource://gre/modules/addons/XPIDatabase.jsm", + InstallRDF: "resource://gre/modules/addons/RDFManifestConverter.jsm", XPIDatabase: "resource://gre/modules/addons/XPIDatabase.jsm", XPIInternal: "resource://gre/modules/addons/XPIProvider.jsm", XPIProvider: "resource://gre/modules/addons/XPIProvider.jsm", @@ -68,16 +69,11 @@ const FileOutputStream = Components.Constructor("@mozilla.org/network/file-outpu const ZipReader = Components.Constructor("@mozilla.org/libjar/zip-reader;1", "nsIZipReader", "open"); -const RDFDataSource = Components.Constructor( - "@mozilla.org/rdf/datasource;1?name=in-memory-datasource", "nsIRDFDataSource"); -const parseRDFString = Components.Constructor( - "@mozilla.org/rdf/xml-parser;1", "nsIRDFXMLParser", "parseString"); - XPCOMUtils.defineLazyServiceGetters(this, { gCertDB: ["@mozilla.org/security/x509certdb;1", "nsIX509CertDB"], - gRDF: ["@mozilla.org/rdf/rdf-service;1", "nsIRDFService"], }); +const hasOwnProperty = Function.call.bind(Object.prototype.hasOwnProperty); const PREF_ALLOW_NON_RESTARTLESS = "extensions.legacy.non-restartless.enabled"; const PREF_DISTRO_ADDONS_PERMS = "extensions.distroAddons.promptForPermissions"; @@ -165,16 +161,12 @@ const KEY_APP_PROFILE = "app-profile"; const DIR_STAGE = "staged"; const DIR_TRASH = "trash"; -const RDFURI_INSTALL_MANIFEST_ROOT = "urn:mozilla:install-manifest"; -const PREFIX_NS_EM = "http://www.mozilla.org/2004/em-rdf#"; - // Properties that exist in the install manifest const PROP_METADATA = ["id", "version", "type", "internalName", "updateURL", "optionsURL", "optionsType", "aboutURL", "iconURL", "icon64URL"]; const PROP_LOCALE_SINGLE = ["name", "description", "creator", "homepageURL"]; const PROP_LOCALE_MULTI = ["developers", "translators", "contributors"]; -const PROP_TARGETAPP = ["id", "minVersion", "maxVersion"]; // Map new string type identifiers to old style nsIUpdateItem types. // Retired values: @@ -448,44 +440,6 @@ function waitForAllPromises(promises) { }); } -function EM_R(aProperty) { - return gRDF.GetResource(PREFIX_NS_EM + aProperty); -} - -/** - * Converts an RDF literal, resource or integer into a string. - * - * @param {nsISupports} aLiteral - * The RDF object to convert - * @returns {string?} - * A string if the object could be converted or null - */ -function getRDFValue(aLiteral) { - if (aLiteral instanceof Ci.nsIRDFLiteral) - return aLiteral.Value; - if (aLiteral instanceof Ci.nsIRDFResource) - return aLiteral.Value; - if (aLiteral instanceof Ci.nsIRDFInt) - return aLiteral.Value; - return null; -} - -/** - * Gets an RDF property as a string - * - * @param {nsIRDFDataSource} aDs - * The RDF datasource to read the property from - * @param {nsIRDFResource} aResource - * The RDF resource to read the property from - * @param {string} aProperty - * The property to read - * @returns {string?} - * A string if the property existed or null - */ -function getRDFProperty(aDs, aResource, aProperty) { - return getRDFValue(aDs.GetTarget(aResource, EM_R(aProperty), true)); -} - /** * Reads an AddonInternal object from a manifest stream. * @@ -628,23 +582,12 @@ async function loadManifestFromWebManifest(aUri) { * be read */ async function loadManifestFromRDF(aUri, aData) { - function getPropertyArray(aDs, aSource, aProperty) { - let values = []; - let targets = aDs.GetTargets(aSource, EM_R(aProperty), true); - while (targets.hasMoreElements()) - values.push(getRDFValue(targets.getNext())); - - return values; - } - /** * Reads locale properties from either the main install manifest root or * an em:localized section in the install manifest. * - * @param {nsIRDFDataSource} aDs - * The datasource to read from. - * @param {nsIRDFResource} aSource - * The resource to read the properties from. + * @param {Object} aSource + * The resource to read the properties from. * @param {boolean} isDefault * True if the locale is to be read from the main install manifest * root @@ -655,13 +598,11 @@ async function loadManifestFromRDF(aUri, aData) { * @returns {Object} * an object containing the locale properties */ - function readLocale(aDs, aSource, isDefault, aSeenLocales) { - let locale = { }; + function readLocale(aSource, isDefault, aSeenLocales) { + let locale = {}; if (!isDefault) { locale.locales = []; - let targets = ds.GetTargets(aSource, EM_R("locale"), true); - while (targets.hasMoreElements()) { - let localeName = getRDFValue(targets.getNext()); + for (let localeName of aSource.locales || []) { if (!localeName) { logger.warn("Ignoring empty locale in localized properties"); continue; @@ -680,32 +621,26 @@ async function loadManifestFromRDF(aUri, aData) { } } - for (let prop of PROP_LOCALE_SINGLE) { - locale[prop] = getRDFProperty(aDs, aSource, prop); - } - - for (let prop of PROP_LOCALE_MULTI) { - // Don't store empty arrays - let props = getPropertyArray(aDs, aSource, - prop.substring(0, prop.length - 1)); - if (props.length > 0) - locale[prop] = props; + for (let prop of [...PROP_LOCALE_SINGLE, ...PROP_LOCALE_MULTI]) { + if (hasOwnProperty(aSource, prop)) { + locale[prop] = aSource[prop]; + } } return locale; } - let ds = new RDFDataSource(); - parseRDFString(ds, aUri, aData); + let manifest = InstallRDF.loadFromString(aData).decode(); - let root = gRDF.GetResource(RDFURI_INSTALL_MANIFEST_ROOT); let addon = new AddonInternal(); for (let prop of PROP_METADATA) { - addon[prop] = getRDFProperty(ds, root, prop); + if (hasOwnProperty(manifest, prop)) { + addon[prop] = manifest[prop]; + } } if (!addon.type) { - addon.type = addon.internalName ? "theme" : "extension"; + addon.type = "extension"; } else { let type = addon.type; addon.type = null; @@ -727,16 +662,16 @@ async function loadManifestFromRDF(aUri, aData) { if (!addon.version) throw new Error("No version in install manifest"); - addon.strictCompatibility = !(addon.type in COMPATIBLE_BY_DEFAULT_TYPES) || - getRDFProperty(ds, root, "strictCompatibility") == "true"; + addon.strictCompatibility = (!(addon.type in COMPATIBLE_BY_DEFAULT_TYPES) || + manifest.strictCompatibility == "true"); // Only read these properties for extensions. if (addon.type == "extension") { - addon.bootstrap = getRDFProperty(ds, root, "bootstrap") == "true"; + addon.bootstrap = manifest.bootstrap == "true"; if (!addon.bootstrap && !Services.prefs.getBoolPref(PREF_ALLOW_NON_RESTARTLESS, false)) throw new Error(`Non-restartless extensions no longer supported`); - addon.hasEmbeddedWebExtension = getRDFProperty(ds, root, "hasEmbeddedWebExtension") == "true"; + addon.hasEmbeddedWebExtension = manifest.hasEmbeddedWebExtension == "true"; if (addon.optionsType && addon.optionsType != AddonManager.OPTIONS_INLINE_BROWSER && @@ -768,63 +703,42 @@ async function loadManifestFromRDF(aUri, aData) { addon.optionsBrowserStyle = null; addon.optionsType = null; addon.optionsURL = null; - - if (addon.type == "theme") { - if (!addon.internalName) - throw new Error("Themes must include an internalName property"); - addon.skinnable = getRDFProperty(ds, root, "skinnable") == "true"; - } } - addon.defaultLocale = readLocale(ds, root, true); + addon.defaultLocale = readLocale(manifest, true); let seenLocales = []; addon.locales = []; - let targets = ds.GetTargets(root, EM_R("localized"), true); - while (targets.hasMoreElements()) { - let target = targets.getNext().QueryInterface(Ci.nsIRDFResource); - let locale = readLocale(ds, target, false, seenLocales); + for (let localeData of manifest.localized || []) { + let locale = readLocale(localeData, false, seenLocales); if (locale) addon.locales.push(locale); } - let dependencies = new Set(); - targets = ds.GetTargets(root, EM_R("dependency"), true); - while (targets.hasMoreElements()) { - let target = targets.getNext().QueryInterface(Ci.nsIRDFResource); - let id = getRDFProperty(ds, target, "id"); - dependencies.add(id); - } + let dependencies = new Set(manifest.dependencies); addon.dependencies = Object.freeze(Array.from(dependencies)); let seenApplications = []; addon.targetApplications = []; - targets = ds.GetTargets(root, EM_R("targetApplication"), true); - while (targets.hasMoreElements()) { - let target = targets.getNext().QueryInterface(Ci.nsIRDFResource); - let targetAppInfo = {}; - for (let prop of PROP_TARGETAPP) { - targetAppInfo[prop] = getRDFProperty(ds, target, prop); - } - if (!targetAppInfo.id || !targetAppInfo.minVersion || - !targetAppInfo.maxVersion) { + for (let targetApp of manifest.targetApplications || []) { + if (!targetApp.id || !targetApp.minVersion || + !targetApp.maxVersion) { logger.warn("Ignoring invalid targetApplication entry in install manifest"); continue; } - if (seenApplications.includes(targetAppInfo.id)) { - logger.warn("Ignoring duplicate targetApplication entry for " + targetAppInfo.id + + if (seenApplications.includes(targetApp.id)) { + logger.warn("Ignoring duplicate targetApplication entry for " + targetApp.id + " in install manifest"); continue; } - seenApplications.push(targetAppInfo.id); - addon.targetApplications.push(targetAppInfo); + seenApplications.push(targetApp.id); + addon.targetApplications.push(targetApp); } // Note that we don't need to check for duplicate targetPlatform entries since // the RDF service coalesces them for us. - let targetPlatforms = getPropertyArray(ds, root, "targetPlatform"); addon.targetPlatforms = []; - for (let targetPlatform of targetPlatforms) { + for (let targetPlatform of manifest.targetPlatforms || []) { let platform = { os: null, abi: null diff --git a/toolkit/mozapps/extensions/internal/moz.build b/toolkit/mozapps/extensions/internal/moz.build index 3d96f33d31f2..5068dfc1f1c4 100644 --- a/toolkit/mozapps/extensions/internal/moz.build +++ b/toolkit/mozapps/extensions/internal/moz.build @@ -13,8 +13,8 @@ EXTRA_JS_MODULES.addons += [ 'LightweightThemeImageOptimizer.jsm', 'ProductAddonChecker.jsm', 'RDFDataSource.jsm', + 'RDFManifestConverter.jsm', 'SpellCheckDictionaryBootstrap.js', - 'UpdateRDFConverter.jsm', 'XPIDatabase.jsm', 'XPIInstall.jsm', 'XPIProvider.jsm', diff --git a/toolkit/mozapps/extensions/test/addons/test_delay_update_complete_v2/install.rdf b/toolkit/mozapps/extensions/test/addons/test_delay_update_complete_v2/install.rdf index 3ebbe16b07a0..b3d9719f78f1 100644 --- a/toolkit/mozapps/extensions/test/addons/test_delay_update_complete_v2/install.rdf +++ b/toolkit/mozapps/extensions/test/addons/test_delay_update_complete_v2/install.rdf @@ -25,3 +25,4 @@ + diff --git a/toolkit/mozapps/extensions/test/addons/test_delay_update_defer_v2/install.rdf b/toolkit/mozapps/extensions/test/addons/test_delay_update_defer_v2/install.rdf index 75c7666bbaf7..aec47ebc5631 100644 --- a/toolkit/mozapps/extensions/test/addons/test_delay_update_defer_v2/install.rdf +++ b/toolkit/mozapps/extensions/test/addons/test_delay_update_defer_v2/install.rdf @@ -25,3 +25,4 @@ + diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_update_rdf.js b/toolkit/mozapps/extensions/test/xpcshell/test_update_rdf.js index 99c75f516289..21fd37defa8e 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_update_rdf.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_update_rdf.js @@ -3,7 +3,8 @@ // Tests the update RDF to JSON converter. ChromeUtils.import("resource://gre/modules/addons/AddonUpdateChecker.jsm"); -ChromeUtils.import("resource://gre/modules/addons/UpdateRDFConverter.jsm"); +ChromeUtils.defineModuleGetter(this, "UpdateRDFConverter", + "resource://gre/modules/addons/RDFManifestConverter.jsm"); var testserver = AddonTestUtils.createHttpServer({hosts: ["example.com"]}); From 53c3d346c35a1c7daf1c4bde65bcea189690c0a1 Mon Sep 17 00:00:00 2001 From: Kris Maglione Date: Sat, 28 Apr 2018 21:28:03 -0700 Subject: [PATCH 32/34] Bug 833098: Part 1 - Remove dead code in xpfe directory viewer. r=Mossop Most of this module is dead code, intended to convert directory listings into RDF data sources for a XUL front-end which no longer exists. Rather than keep the remaining code which still has any effect, I opted to just replace it with a JS stub, which winds up being much simpler. MozReview-Commit-ID: CiBpV0mrOo0 --HG-- extra : source : 2ea9f1f5269ed5291275a174a633b23dc92667de extra : histedit_source : fdc195bff4684a84f610b90c0d9820b860c5ff40 --- modules/libpref/init/all.js | 6 - toolkit/components/utils/simpleServices.js | 35 +- toolkit/components/utils/utils.manifest | 4 + toolkit/toolkit.mozbuild | 1 - xpfe/components/build/moz.build | 18 - xpfe/components/build/nsModule.cpp | 44 - xpfe/components/directory/moz.build | 23 - .../directory/nsDirectoryViewer.cpp | 1376 ----------------- xpfe/components/directory/nsDirectoryViewer.h | 126 -- xpfe/components/directory/nsIHTTPIndex.idl | 50 - xpfe/components/moz.build | 14 - 11 files changed, 38 insertions(+), 1659 deletions(-) delete mode 100644 xpfe/components/build/moz.build delete mode 100644 xpfe/components/build/nsModule.cpp delete mode 100644 xpfe/components/directory/moz.build delete mode 100644 xpfe/components/directory/nsDirectoryViewer.cpp delete mode 100644 xpfe/components/directory/nsDirectoryViewer.h delete mode 100644 xpfe/components/directory/nsIHTTPIndex.idl delete mode 100644 xpfe/components/moz.build diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 9f2f62d50b2c..149604bdde8d 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -2020,12 +2020,6 @@ pref("network.standard-url.punycode-host", true); // Idle timeout for ftp control connections - 5 minute default pref("network.ftp.idleConnectionTimeout", 300); -// directory listing format -// 2: HTML -// 3: XUL directory viewer -// all other values are treated like 2 -pref("network.dir.format", 2); - // enables the prefetch service (i.e., prefetching of and // URLs). pref("network.prefetch-next", true); diff --git a/toolkit/components/utils/simpleServices.js b/toolkit/components/utils/simpleServices.js index 90cee5272ee1..75bb9a02508e 100644 --- a/toolkit/components/utils/simpleServices.js +++ b/toolkit/components/utils/simpleServices.js @@ -21,6 +21,11 @@ ChromeUtils.defineModuleGetter(this, "NetUtil", ChromeUtils.defineModuleGetter(this, "Services", "resource://gre/modules/Services.jsm"); +XPCOMUtils.defineLazyServiceGetter(this, "catMan", "@mozilla.org/categorymanager;1", + "nsICategoryManager"); +XPCOMUtils.defineLazyServiceGetter(this, "streamConv", "@mozilla.org/streamConverters;1", + "nsIStreamConverterService"); + /* * This class provides a stream filter for locale messages in CSS files served * by the moz-extension: protocol handler. @@ -111,4 +116,32 @@ AddonLocalizationConverter.prototype = { }, }; -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([AddonLocalizationConverter]); +function HttpIndexViewer() { +} + +HttpIndexViewer.prototype = { + classID: Components.ID("{742ad274-34c5-43d1-a8b7-293eaf8962d6}"), + QueryInterface: ChromeUtils.generateQI([Ci.nsIDocumentLoaderFactory]), + + createInstance(aCommand, aChannel, aLoadGroup, aContentType, aContainer, + aExtraInfo, aDocListenerResult) { + aChannel.contentType = "text/html"; + + let contract = catMan.getCategoryEntry("Gecko-Content-Viewers", "text/html"); + let factory = Cc[contract].getService(Ci.nsIDocumentLoaderFactory); + + let listener = {}; + let res = factory.createInstance("view", aChannel, aLoadGroup, + "text/html", aContainer, aExtraInfo, + listener); + + aDocListenerResult.value = + streamConv.asyncConvertData("application/http-index-format", + "text/html", listener.value, null); + + return res; + }, +}; + +this.NSGetFactory = XPCOMUtils.generateNSGetFactory([AddonLocalizationConverter, + HttpIndexViewer]); diff --git a/toolkit/components/utils/utils.manifest b/toolkit/components/utils/utils.manifest index cd45ff07d8a6..fa266f7322d2 100644 --- a/toolkit/components/utils/utils.manifest +++ b/toolkit/components/utils/utils.manifest @@ -2,3 +2,7 @@ component {dfd07380-6083-11e4-9803-0800200c9a66} simpleServices.js contract @mozilla.org/addons/remote-tag-service;1 {dfd07380-6083-11e4-9803-0800200c9a66} component {ded150e3-c92e-4077-a396-0dba9953e39f} simpleServices.js contract @mozilla.org/streamconv;1?from=application/vnd.mozilla.webext.unlocalized&to=text/css {ded150e3-c92e-4077-a396-0dba9953e39f} + +component {742ad274-34c5-43d1-a8b7-293eaf8962d6} simpleServices.js +contract @mozilla.org/content-viewsers/http-index-format {742ad274-34c5-43d1-a8b7-293eaf8962d6} +category Gecko-Content-Viewers application/http-index-format @mozilla.org/content-viewsers/http-index-format diff --git a/toolkit/toolkit.mozbuild b/toolkit/toolkit.mozbuild index dd8403e425ab..4e033764a578 100644 --- a/toolkit/toolkit.mozbuild +++ b/toolkit/toolkit.mozbuild @@ -135,7 +135,6 @@ DIRS += [ '/tools/code-coverage', '/tools/power', '/tools/profiler', - '/xpfe/components', ] if CONFIG['MOZ_ENABLE_XREMOTE']: diff --git a/xpfe/components/build/moz.build b/xpfe/components/build/moz.build deleted file mode 100644 index c8f67f9e7884..000000000000 --- a/xpfe/components/build/moz.build +++ /dev/null @@ -1,18 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -with Files("**"): - BUG_COMPONENT = ("Core", "Window Management") - -SOURCES += [ - 'nsModule.cpp', -] - -FINAL_LIBRARY = 'xul' - -LOCAL_INCLUDES += [ - '../directory', -] diff --git a/xpfe/components/build/nsModule.cpp b/xpfe/components/build/nsModule.cpp deleted file mode 100644 index 43966f94d1f2..000000000000 --- a/xpfe/components/build/nsModule.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* -*- 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/. */ - -#include "mozilla/ModuleUtils.h" -#include "nsDirectoryViewer.h" -#include "rdf.h" -#include "nsRDFCID.h" -#include "nsCURILoader.h" - -// Factory constructors -NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsHTTPIndex, Init) -NS_GENERIC_FACTORY_CONSTRUCTOR(nsDirectoryViewerFactory) - -NS_DEFINE_NAMED_CID(NS_DIRECTORYVIEWERFACTORY_CID); -NS_DEFINE_NAMED_CID(NS_HTTPINDEX_SERVICE_CID); - -static const mozilla::Module::CIDEntry kXPFECIDs[] = { - { &kNS_DIRECTORYVIEWERFACTORY_CID, false, nullptr, nsDirectoryViewerFactoryConstructor }, - { &kNS_HTTPINDEX_SERVICE_CID, false, nullptr, nsHTTPIndexConstructor }, - { nullptr } -}; - -static const mozilla::Module::ContractIDEntry kXPFEContracts[] = { - { "@mozilla.org/xpfe/http-index-format-factory-constructor", &kNS_DIRECTORYVIEWERFACTORY_CID }, - { NS_HTTPINDEX_SERVICE_CONTRACTID, &kNS_HTTPINDEX_SERVICE_CID }, - { NS_HTTPINDEX_DATASOURCE_CONTRACTID, &kNS_HTTPINDEX_SERVICE_CID }, - { nullptr } -}; - -static const mozilla::Module::CategoryEntry kXPFECategories[] = { - { "Gecko-Content-Viewers", "application/http-index-format", "@mozilla.org/xpfe/http-index-format-factory-constructor" }, - { nullptr } -}; - -static const mozilla::Module kXPFEModule = { - mozilla::Module::kVersion, - kXPFECIDs, - kXPFEContracts, - kXPFECategories -}; - -NSMODULE_DEFN(application) = &kXPFEModule; diff --git a/xpfe/components/directory/moz.build b/xpfe/components/directory/moz.build deleted file mode 100644 index 980001ecd0c6..000000000000 --- a/xpfe/components/directory/moz.build +++ /dev/null @@ -1,23 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -with Files("**"): - BUG_COMPONENT = ("Core", "Window Management") - -XPIDL_SOURCES += [ - 'nsIHTTPIndex.idl', -] - -XPIDL_MODULE = 'directory' - -SOURCES += [ - 'nsDirectoryViewer.cpp', -] - -FINAL_LIBRARY = 'xul' - -if CONFIG['CC_TYPE'] in ('clang', 'gcc'): - CXXFLAGS += ['-Wno-error=shadow'] diff --git a/xpfe/components/directory/nsDirectoryViewer.cpp b/xpfe/components/directory/nsDirectoryViewer.cpp deleted file mode 100644 index 272c2a05499e..000000000000 --- a/xpfe/components/directory/nsDirectoryViewer.cpp +++ /dev/null @@ -1,1376 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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/. */ - -/* - - A directory viewer object. Parses "application/http-index-format" - per Lou Montulli's original spec: - - http://www.mozilla.org/projects/netlib/dirindexformat.html - - One added change is for a description entry, for when the - target does not match the filename - -*/ - -#include "nsDirectoryViewer.h" -#include "nsArray.h" -#include "nsArrayUtils.h" -#include "nsIDirIndex.h" -#include "nsIDocShell.h" -#include "jsapi.h" -#include "nsCOMPtr.h" -#include "nsEnumeratorUtils.h" -#include "nsEscape.h" -#include "nsIRDFService.h" -#include "nsRDFCID.h" -#include "rdf.h" -#include "nsIServiceManager.h" -#include "nsIXPConnect.h" -#include "nsEnumeratorUtils.h" -#include "nsString.h" -#include "nsReadableUtils.h" -#include "nsITextToSubURI.h" -#include "nsIInterfaceRequestor.h" -#include "nsIInterfaceRequestorUtils.h" -#include "nsIFTPChannel.h" -#include "nsIWindowWatcher.h" -#include "nsIPrompt.h" -#include "nsIAuthPrompt.h" -#include "nsIProgressEventSink.h" -#include "nsIDOMWindow.h" -#include "nsIStreamConverterService.h" -#include "nsICategoryManager.h" -#include "nsXPCOMCID.h" -#include "nsIDocument.h" -#include "mozilla/Preferences.h" -#include "mozilla/dom/ScriptSettings.h" -#include "nsContentUtils.h" -#include "nsIURI.h" -#include "nsNetUtil.h" - -using namespace mozilla; - -static const int FORMAT_XUL = 3; - -//---------------------------------------------------------------------- -// -// Common CIDs -// - -static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); - -// Various protocols we have to special case -static const char kFTPProtocol[] = "ftp://"; - -//---------------------------------------------------------------------- -// -// nsHTTPIndex -// - -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsHTTPIndex) - NS_INTERFACE_MAP_ENTRY(nsIHTTPIndex) - NS_INTERFACE_MAP_ENTRY(nsIRDFDataSource) - NS_INTERFACE_MAP_ENTRY(nsIStreamListener) - NS_INTERFACE_MAP_ENTRY(nsIDirIndexListener) - NS_INTERFACE_MAP_ENTRY(nsIRequestObserver) - NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor) - NS_INTERFACE_MAP_ENTRY(nsIFTPEventSink) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIHTTPIndex) -NS_INTERFACE_MAP_END - -NS_IMPL_CYCLE_COLLECTION(nsHTTPIndex, mInner) -NS_IMPL_CYCLE_COLLECTING_ADDREF(nsHTTPIndex) -NS_IMPL_CYCLE_COLLECTING_RELEASE(nsHTTPIndex) - -NS_IMETHODIMP -nsHTTPIndex::GetInterface(const nsIID &anIID, void **aResult ) -{ - if (anIID.Equals(NS_GET_IID(nsIFTPEventSink))) { - // If we don't have a container to store the logged data - // then don't report ourselves back to the caller - - if (!mRequestor) - return NS_ERROR_NO_INTERFACE; - *aResult = static_cast(this); - NS_ADDREF(this); - return NS_OK; - } - - if (anIID.Equals(NS_GET_IID(nsIPrompt))) { - - if (!mRequestor) - return NS_ERROR_NO_INTERFACE; - - nsCOMPtr aDOMWindow = do_GetInterface(mRequestor); - if (!aDOMWindow) - return NS_ERROR_NO_INTERFACE; - - nsCOMPtr wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID)); - - return wwatch->GetNewPrompter(aDOMWindow, (nsIPrompt**)aResult); - } - - if (anIID.Equals(NS_GET_IID(nsIAuthPrompt))) { - - if (!mRequestor) - return NS_ERROR_NO_INTERFACE; - - nsCOMPtr aDOMWindow = do_GetInterface(mRequestor); - if (!aDOMWindow) - return NS_ERROR_NO_INTERFACE; - - nsCOMPtr wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID)); - - return wwatch->GetNewAuthPrompter(aDOMWindow, (nsIAuthPrompt**)aResult); - } - - if (anIID.Equals(NS_GET_IID(nsIProgressEventSink))) { - - if (!mRequestor) - return NS_ERROR_NO_INTERFACE; - - nsCOMPtr sink = do_GetInterface(mRequestor); - if (!sink) - return NS_ERROR_NO_INTERFACE; - - *aResult = sink; - NS_ADDREF((nsISupports*)*aResult); - return NS_OK; - } - - return NS_ERROR_NO_INTERFACE; -} - -NS_IMETHODIMP -nsHTTPIndex::OnFTPControlLog(bool server, const char *msg) -{ - NS_ENSURE_TRUE(mRequestor, NS_OK); - - nsCOMPtr globalObject = do_GetInterface(mRequestor); - NS_ENSURE_TRUE(globalObject, NS_OK); - - // We're going to run script via JS_CallFunctionName, so we need an - // AutoEntryScript. This is Gecko specific and not in any spec. - dom::AutoEntryScript aes(globalObject, - "nsHTTPIndex OnFTPControlLog"); - JSContext* cx = aes.cx(); - - JS::Rooted global(cx, JS::CurrentGlobalOrNull(cx)); - NS_ENSURE_TRUE(global, NS_OK); - - nsString unicodeMsg; - CopyASCIItoUTF16(msg, unicodeMsg); - JSString* jsMsgStr = JS_NewUCStringCopyZ(cx, unicodeMsg.get()); - NS_ENSURE_TRUE(jsMsgStr, NS_ERROR_OUT_OF_MEMORY); - - JS::AutoValueArray<2> params(cx); - params[0].setBoolean(server); - params[1].setString(jsMsgStr); - - JS::Rooted val(cx); - JS_CallFunctionName(cx, - global, - "OnFTPControlLog", - params, - &val); - return NS_OK; -} - -NS_IMETHODIMP -nsHTTPIndex::SetEncoding(const char *encoding) -{ - mEncoding = encoding; - return(NS_OK); -} - -NS_IMETHODIMP -nsHTTPIndex::GetEncoding(char **encoding) -{ - NS_PRECONDITION(encoding, "null ptr"); - if (! encoding) - return(NS_ERROR_NULL_POINTER); - - *encoding = ToNewCString(mEncoding); - if (!*encoding) - return(NS_ERROR_OUT_OF_MEMORY); - - return(NS_OK); -} - -NS_IMETHODIMP -nsHTTPIndex::OnStartRequest(nsIRequest *request, nsISupports* aContext) -{ - nsresult rv; - - mParser = do_CreateInstance(NS_DIRINDEXPARSER_CONTRACTID, &rv); - if (NS_FAILED(rv)) return rv; - - rv = mParser->SetEncoding(mEncoding.get()); - if (NS_FAILED(rv)) return rv; - - rv = mParser->SetListener(this); - if (NS_FAILED(rv)) return rv; - - rv = mParser->OnStartRequest(request,aContext); - if (NS_FAILED(rv)) return rv; - - // This should only run once... - // Unless we don't have a container to start with - // (ie called from bookmarks as an rdf datasource) - if (mBindToGlobalObject && mRequestor) { - mBindToGlobalObject = false; - - nsCOMPtr globalObject = do_GetInterface(mRequestor); - NS_ENSURE_TRUE(globalObject, NS_ERROR_FAILURE); - - // We might run script via JS_SetProperty, so we need an AutoEntryScript. - // This is Gecko specific and not in any spec. - dom::AutoEntryScript aes(globalObject, - "nsHTTPIndex set HTTPIndex property"); - JSContext* cx = aes.cx(); - - JS::Rooted global(cx, JS::CurrentGlobalOrNull(cx)); - - // Using XPConnect, wrap the HTTP index object... - static NS_DEFINE_CID(kXPConnectCID, NS_XPCONNECT_CID); - nsCOMPtr xpc(do_GetService(kXPConnectCID, &rv)); - if (NS_FAILED(rv)) return rv; - - JS::Rooted jsobj(cx); - rv = xpc->WrapNative(cx, - global, - static_cast(this), - NS_GET_IID(nsIHTTPIndex), - jsobj.address()); - - NS_ASSERTION(NS_SUCCEEDED(rv), "unable to xpconnect-wrap http-index"); - if (NS_FAILED(rv)) return rv; - - NS_ASSERTION(jsobj, - "unable to get jsobj from xpconnect wrapper"); - if (!jsobj) return NS_ERROR_UNEXPECTED; - - JS::Rooted jslistener(cx, JS::ObjectValue(*jsobj)); - - // ...and stuff it into the global context - bool ok = JS_SetProperty(cx, global, "HTTPIndex", jslistener); - NS_ASSERTION(ok, "unable to set Listener property"); - if (!ok) - return NS_ERROR_FAILURE; - } - - if (!aContext) { - nsCOMPtr channel(do_QueryInterface(request)); - NS_ASSERTION(channel, "request should be a channel"); - - // lets hijack the notifications: - channel->SetNotificationCallbacks(this); - - // now create the top most resource - nsCOMPtr uri; - channel->GetURI(getter_AddRefs(uri)); - - nsAutoCString entryuriC; - rv = uri->GetSpec(entryuriC); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr entry; - rv = mDirRDF->GetResource(entryuriC, getter_AddRefs(entry)); - - NS_ConvertUTF8toUTF16 uriUnicode(entryuriC); - - nsCOMPtr URLVal; - rv = mDirRDF->GetLiteral(uriUnicode.get(), getter_AddRefs(URLVal)); - - Assert(entry, kNC_URL, URLVal, true); - mDirectory = do_QueryInterface(entry); - } - else - { - // Get the directory from the context - mDirectory = do_QueryInterface(aContext); - } - - if (!mDirectory) { - request->Cancel(NS_BINDING_ABORTED); - return NS_BINDING_ABORTED; - } - - // Mark the directory as "loading" - rv = Assert(mDirectory, kNC_Loading, - kTrueLiteral, true); - if (NS_FAILED(rv)) return rv; - - return NS_OK; -} - - -NS_IMETHODIMP -nsHTTPIndex::OnStopRequest(nsIRequest *request, - nsISupports* aContext, - nsresult aStatus) -{ - // If mDirectory isn't set, then we should just bail. Either an - // error occurred and OnStartRequest() never got called, or - // something exploded in OnStartRequest(). - if (! mDirectory) - return NS_BINDING_ABORTED; - - mParser->OnStopRequest(request,aContext,aStatus); - - nsresult rv; - - nsCString commentStr; - mParser->GetComment(getter_Copies(commentStr)); - - nsCOMPtr comment; - rv = mDirRDF->GetLiteral(NS_ConvertASCIItoUTF16(commentStr).get(), getter_AddRefs(comment)); - if (NS_FAILED(rv)) return rv; - - rv = Assert(mDirectory, kNC_Comment, comment, true); - if (NS_FAILED(rv)) return rv; - - // hack: Remove the 'loading' annotation (ignore errors) - AddElement(mDirectory, kNC_Loading, kTrueLiteral); - - return NS_OK; -} - - -NS_IMETHODIMP -nsHTTPIndex::OnDataAvailable(nsIRequest *request, - nsISupports* aContext, - nsIInputStream* aStream, - uint64_t aSourceOffset, - uint32_t aCount) -{ - // If mDirectory isn't set, then we should just bail. Either an - // error occurred and OnStartRequest() never got called, or - // something exploded in OnStartRequest(). - if (! mDirectory) - return NS_BINDING_ABORTED; - - return mParser->OnDataAvailable(request, mDirectory, aStream, aSourceOffset, aCount); -} - - -nsresult -nsHTTPIndex::OnIndexAvailable(nsIRequest* aRequest, nsISupports *aContext, - nsIDirIndex* aIndex) -{ - nsCOMPtr parentRes = do_QueryInterface(aContext); - if (!parentRes) { - NS_ERROR("Could not obtain parent resource"); - return(NS_ERROR_UNEXPECTED); - } - - const char* baseStr; - parentRes->GetValueConst(&baseStr); - if (! baseStr) { - NS_ERROR("Could not reconstruct base uri"); - return NS_ERROR_UNEXPECTED; - } - - // we found the filename; construct a resource for its entry - nsAutoCString entryuriC(baseStr); - - nsCString filename; - nsresult rv = aIndex->GetLocation(getter_Copies(filename)); - if (NS_FAILED(rv)) return rv; - entryuriC.Append(filename); - - // if its a directory, make sure it ends with a trailing slash. - uint32_t type; - rv = aIndex->GetType(&type); - if (NS_FAILED(rv)) - return rv; - - bool isDirType = (type == nsIDirIndex::TYPE_DIRECTORY); - if (isDirType && entryuriC.Last() != '/') { - entryuriC.Append('/'); - } - - nsCOMPtr entry; - rv = mDirRDF->GetResource(entryuriC, getter_AddRefs(entry)); - - // At this point, we'll (hopefully) have found the filename and - // constructed a resource for it, stored in entry. So now take a - // second pass through the values and add as statements to the RDF - // datasource. - - if (entry && NS_SUCCEEDED(rv)) { - nsCOMPtr lit; - nsString str; - - CopyASCIItoUTF16(entryuriC, str); - - rv = mDirRDF->GetLiteral(str.get(), getter_AddRefs(lit)); - - if (NS_SUCCEEDED(rv)) { - rv = Assert(entry, kNC_URL, lit, true); - if (NS_FAILED(rv)) return rv; - - nsString xpstr; - - // description - rv = aIndex->GetDescription(getter_Copies(xpstr)); - if (NS_FAILED(rv)) return rv; - if (xpstr.Last() == '/') - xpstr.Truncate(xpstr.Length() - 1); - - rv = mDirRDF->GetLiteral(xpstr.get(), getter_AddRefs(lit)); - if (NS_FAILED(rv)) return rv; - rv = Assert(entry, kNC_Description, lit, true); - if (NS_FAILED(rv)) return rv; - - // contentlength - int64_t size; - rv = aIndex->GetSize(&size); - if (NS_FAILED(rv)) return rv; - int64_t minus1 = UINT64_MAX; - if (size != minus1) { - int32_t intSize = int32_t(size); - // XXX RDF should support 64 bit integers (bug 240160) - nsCOMPtr val; - rv = mDirRDF->GetIntLiteral(intSize, getter_AddRefs(val)); - if (NS_FAILED(rv)) return rv; - rv = Assert(entry, kNC_ContentLength, val, true); - if (NS_FAILED(rv)) return rv; - } - - // lastmodified - PRTime tm; - rv = aIndex->GetLastModified(&tm); - if (NS_FAILED(rv)) return rv; - if (tm != -1) { - nsCOMPtr val; - rv = mDirRDF->GetDateLiteral(tm, getter_AddRefs(val)); - if (NS_FAILED(rv)) return rv; - rv = Assert(entry, kNC_LastModified, val, true); - } - - // filetype - uint32_t type; - rv = aIndex->GetType(&type); - switch (type) { - case nsIDirIndex::TYPE_UNKNOWN: - rv = mDirRDF->GetLiteral(u"UNKNOWN", getter_AddRefs(lit)); - break; - case nsIDirIndex::TYPE_DIRECTORY: - rv = mDirRDF->GetLiteral(u"DIRECTORY", getter_AddRefs(lit)); - break; - case nsIDirIndex::TYPE_FILE: - rv = mDirRDF->GetLiteral(u"FILE", getter_AddRefs(lit)); - break; - case nsIDirIndex::TYPE_SYMLINK: - rv = mDirRDF->GetLiteral(u"SYMLINK", getter_AddRefs(lit)); - break; - } - - if (NS_FAILED(rv)) return rv; - rv = Assert(entry, kNC_FileType, lit, true); - if (NS_FAILED(rv)) return rv; - } - - // Since the definition of a directory depends on the protocol, we would have - // to do string comparisons all the time. - // But we're told if we're a container right here - so save that fact - if (isDirType) - Assert(entry, kNC_IsContainer, kTrueLiteral, true); - else - Assert(entry, kNC_IsContainer, kFalseLiteral, true); - -// instead of -// rv = Assert(parentRes, kNC_Child, entry, true); -// if (NS_FAILED(rv)) return rv; -// defer insertion onto a timer so that the UI isn't starved - AddElement(parentRes, kNC_Child, entry); - } - - return rv; -} - -nsresult -nsHTTPIndex::OnInformationAvailable(nsIRequest *aRequest, - nsISupports *aCtxt, - const nsAString& aInfo) { - return NS_ERROR_NOT_IMPLEMENTED; -} - -//---------------------------------------------------------------------- -// -// nsHTTPIndex implementation -// - -nsHTTPIndex::nsHTTPIndex() - : mBindToGlobalObject(true), - mRequestor(nullptr) -{ -} - - -nsHTTPIndex::nsHTTPIndex(nsIInterfaceRequestor* aRequestor) - : mBindToGlobalObject(true), - mRequestor(aRequestor) -{ -} - - -nsHTTPIndex::~nsHTTPIndex() -{ - // note: these are NOT statics due to the native of nsHTTPIndex - // where it may or may not be treated as a singleton - - if (mTimer) - { - // be sure to cancel the timer, as it holds a - // weak reference back to nsHTTPIndex - mTimer->Cancel(); - mTimer = nullptr; - } - - mConnectionList = nullptr; - mNodeList = nullptr; - - if (mDirRDF) - { - // UnregisterDataSource() may fail; just ignore errors - mDirRDF->UnregisterDataSource(this); - } -} - - - -nsresult -nsHTTPIndex::CommonInit() -{ - nsresult rv = NS_OK; - - // set initial/default encoding to windows-1252 (not UTF-8) - mEncoding = "windows-1252"; - - mDirRDF = do_GetService(kRDFServiceCID, &rv); - NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get RDF service"); - if (NS_FAILED(rv)) { - return(rv); - } - - mInner = do_CreateInstance("@mozilla.org/rdf/datasource;1?name=in-memory-datasource", &rv); - - if (NS_FAILED(rv)) - return rv; - - mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "child"), - getter_AddRefs(kNC_Child)); - mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "loading"), - getter_AddRefs(kNC_Loading)); - mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "Comment"), - getter_AddRefs(kNC_Comment)); - mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "URL"), - getter_AddRefs(kNC_URL)); - mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "Name"), - getter_AddRefs(kNC_Description)); - mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "Content-Length"), - getter_AddRefs(kNC_ContentLength)); - mDirRDF->GetResource(NS_LITERAL_CSTRING(WEB_NAMESPACE_URI "LastModifiedDate"), - getter_AddRefs(kNC_LastModified)); - mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "Content-Type"), - getter_AddRefs(kNC_ContentType)); - mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "File-Type"), - getter_AddRefs(kNC_FileType)); - mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "IsContainer"), - getter_AddRefs(kNC_IsContainer)); - - rv = mDirRDF->GetLiteral(u"true", getter_AddRefs(kTrueLiteral)); - if (NS_FAILED(rv)) return(rv); - rv = mDirRDF->GetLiteral(u"false", getter_AddRefs(kFalseLiteral)); - if (NS_FAILED(rv)) return(rv); - - mConnectionList = nsArray::Create(); - - // note: don't register DS here - return rv; -} - - -nsresult -nsHTTPIndex::Init() -{ - nsresult rv; - - // set initial/default encoding to windows-1252 (not UTF-8) - mEncoding = "windows-1252"; - - rv = CommonInit(); - if (NS_FAILED(rv)) return(rv); - - // (do this last) register this as a named data source with the RDF service - rv = mDirRDF->RegisterDataSource(this, false); - if (NS_FAILED(rv)) return(rv); - - return(NS_OK); -} - - - -nsresult -nsHTTPIndex::Init(nsIURI* aBaseURL) -{ - NS_PRECONDITION(aBaseURL != nullptr, "null ptr"); - if (! aBaseURL) - return NS_ERROR_NULL_POINTER; - - nsresult rv; - - rv = CommonInit(); - if (NS_FAILED(rv)) return(rv); - - // note: don't register DS here (singleton case) - - rv = aBaseURL->GetSpec(mBaseURL); - if (NS_FAILED(rv)) return rv; - - // Mark the base url as a container - nsCOMPtr baseRes; - mDirRDF->GetResource(mBaseURL, getter_AddRefs(baseRes)); - Assert(baseRes, kNC_IsContainer, kTrueLiteral, true); - - return NS_OK; -} - - - -nsresult -nsHTTPIndex::Create(nsIURI* aBaseURL, nsIInterfaceRequestor* aRequestor, - nsIHTTPIndex** aResult) -{ - *aResult = nullptr; - - nsHTTPIndex* result = new nsHTTPIndex(aRequestor); - nsresult rv = result->Init(aBaseURL); - if (NS_SUCCEEDED(rv)) - { - NS_ADDREF(result); - *aResult = result; - } - else - { - delete result; - } - return rv; -} - -NS_IMETHODIMP -nsHTTPIndex::GetBaseURL(char** _result) -{ - *_result = ToNewCString(mBaseURL); - if (! *_result) - return NS_ERROR_OUT_OF_MEMORY; - - return NS_OK; -} - -NS_IMETHODIMP -nsHTTPIndex::GetDataSource(nsIRDFDataSource** _result) -{ - NS_ADDREF(*_result = this); - return NS_OK; -} - -// This function finds the destination when following a given nsIRDFResource -// If the resource has a URL attribute, we use that. If not, just use -// the uri. -// -// Do NOT try to get the destination of a uri in any other way -void nsHTTPIndex::GetDestination(nsIRDFResource* r, nsACString& dest) { - // First try the URL attribute - nsCOMPtr node; - - GetTarget(r, kNC_URL, true, getter_AddRefs(node)); - nsCOMPtr url; - - if (node) - url = do_QueryInterface(node); - - if (!url) { - const char* temp; - r->GetValueConst(&temp); - dest.Adopt(temp ? strdup(temp) : 0); - } else { - const char16_t* uri; - url->GetValueConst(&uri); - dest.Adopt(ToNewUTF8String(nsDependentString(uri))); - } -} - -// rjc: isWellknownContainerURI() decides whether a URI is a container for which, -// when asked (say, by the template builder), we'll make a network connection -// to get its contents. For the moment, all we speak is ftp:// URLs, even though -// a) we can get "http-index" mimetypes for really anything -// b) we could easily handle file:// URLs here -// Q: Why don't we? -// A: The file system datasource ("rdf:file"); at some point, the two -// should be perhaps united. Until then, we can't aggregate both -// "rdf:file" and "http-index" (such as with bookmarks) because we'd -// get double the # of answers we really want... also, "rdf:file" is -// less expensive in terms of both memory usage as well as speed - - - -// We use an rdf attribute to mark if this is a container or not. -// Note that we still have to do string comparisons as a fallback -// because stuff like the personal toolbar and bookmarks check whether -// a URL is a container, and we have no attribute in that case. -bool -nsHTTPIndex::isWellknownContainerURI(nsIRDFResource *r) -{ - nsCOMPtr node; - GetTarget(r, kNC_IsContainer, true, getter_AddRefs(node)); - if (node) { - bool isContainerFlag; - if (NS_SUCCEEDED(node->EqualsNode(kTrueLiteral, &isContainerFlag))) - return isContainerFlag; - } - - nsCString uri; - GetDestination(r, uri); - return StringBeginsWith(uri, nsDependentCString(kFTPProtocol)) && - (uri.Last() == '/'); -} - - -NS_IMETHODIMP -nsHTTPIndex::GetURI(nsACString& aURI) -{ - aURI.AssignLiteral("rdf:httpindex"); - return NS_OK; -} - -NS_IMETHODIMP -nsHTTPIndex::GetSource(nsIRDFResource *aProperty, nsIRDFNode *aTarget, bool aTruthValue, - nsIRDFResource **_retval) -{ - nsresult rv = NS_ERROR_UNEXPECTED; - - *_retval = nullptr; - - if (mInner) - { - rv = mInner->GetSource(aProperty, aTarget, aTruthValue, _retval); - } - return(rv); -} - -NS_IMETHODIMP -nsHTTPIndex::GetSources(nsIRDFResource *aProperty, nsIRDFNode *aTarget, bool aTruthValue, - nsISimpleEnumerator **_retval) -{ - nsresult rv = NS_ERROR_UNEXPECTED; - - if (mInner) - { - rv = mInner->GetSources(aProperty, aTarget, aTruthValue, _retval); - } - else - { - rv = NS_NewEmptyEnumerator(_retval); - } - return(rv); -} - -NS_IMETHODIMP -nsHTTPIndex::GetTarget(nsIRDFResource *aSource, nsIRDFResource *aProperty, bool aTruthValue, - nsIRDFNode **_retval) -{ - nsresult rv = NS_ERROR_UNEXPECTED; - - *_retval = nullptr; - - if ((aTruthValue) && (aProperty == kNC_Child) && isWellknownContainerURI(aSource)) - { - // fake out the generic builder (i.e. return anything in this case) - // so that search containers never appear to be empty - NS_IF_ADDREF(aSource); - *_retval = aSource; - return(NS_OK); - } - - if (mInner) - { - rv = mInner->GetTarget(aSource, aProperty, aTruthValue, _retval); - } - return(rv); -} - -NS_IMETHODIMP -nsHTTPIndex::GetTargets(nsIRDFResource *aSource, nsIRDFResource *aProperty, bool aTruthValue, - nsISimpleEnumerator **_retval) -{ - nsresult rv = NS_ERROR_UNEXPECTED; - - if (mInner) - { - rv = mInner->GetTargets(aSource, aProperty, aTruthValue, _retval); - } - else - { - rv = NS_NewEmptyEnumerator(_retval); - } - - if ((aProperty == kNC_Child) && isWellknownContainerURI(aSource)) - { - bool doNetworkRequest = true; - if (NS_SUCCEEDED(rv) && (_retval)) - { - // check and see if we already have data for the search in question; - // if we do, don't bother doing the search again - bool hasResults; - if (NS_SUCCEEDED((*_retval)->HasMoreElements(&hasResults)) && - hasResults) - doNetworkRequest = false; - } - - // Note: if we need to do a network request, do it out-of-band - // (because the XUL template builder isn't re-entrant) - // by using a global connection list and an immediately-firing timer - if (doNetworkRequest && mConnectionList) - { - uint32_t connectionIndex; - nsresult idx_rv = mConnectionList->IndexOf(0, aSource, &connectionIndex); - if (NS_FAILED(idx_rv)) - { - // add aSource into list of connections to make - mConnectionList->AppendElement(aSource); - - // if we don't have a timer about to fire, create one - // which should fire as soon as possible (out-of-band) - if (!mTimer) - { - rv = NS_NewTimerWithFuncCallback(getter_AddRefs(mTimer), - nsHTTPIndex::FireTimer, - this, - 1, - nsITimer::TYPE_ONE_SHOT, - "nsHTTPIndex::GetTargets"); - // Note: don't addref "this" as we'll cancel the - // timer in the httpIndex destructor - NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create a timer"); - } - } - } - } - - return(rv); -} - - -nsresult -nsHTTPIndex::AddElement(nsIRDFResource *parent, nsIRDFResource *prop, nsIRDFNode *child) -{ - - if (!mNodeList) - { - mNodeList = nsArray::Create(); - } - - // order required: parent, prop, then child - mNodeList->AppendElement(parent); - mNodeList->AppendElement(prop); - mNodeList->AppendElement(child); - - if (!mTimer) - { - return NS_NewTimerWithFuncCallback(getter_AddRefs(mTimer), - nsHTTPIndex::FireTimer, - this, - 1, - nsITimer::TYPE_ONE_SHOT, - "nsHTTPIndex::AddElement"); - // Note: don't addref "this" as we'll cancel the - // timer in the httpIndex destructor - } - - return(NS_OK); -} - -void -nsHTTPIndex::FireTimer(nsITimer* aTimer, void* aClosure) -{ - nsHTTPIndex *httpIndex = static_cast(aClosure); - if (!httpIndex) - return; - - // don't return out of this loop as mTimer may need to be cancelled afterwards - uint32_t numItems = 0; - if (httpIndex->mConnectionList) - { - httpIndex->mConnectionList->GetLength(&numItems); - if (numItems > 0) - { - nsCOMPtr source = - do_QueryElementAt(httpIndex->mConnectionList, 0); - httpIndex->mConnectionList->RemoveElementAt(0); - - nsCString uri = VoidCString(); - if (source) { - httpIndex->GetDestination(source, uri); - } - - if (uri.IsVoid()) { - NS_ERROR("Could not reconstruct uri"); - return; - } - - nsresult rv = NS_OK; - nsCOMPtr url; - - rv = NS_NewURI(getter_AddRefs(url), uri.get()); - nsCOMPtr channel; - if (NS_SUCCEEDED(rv) && (url)) { - rv = NS_NewChannel(getter_AddRefs(channel), - url, - nsContentUtils::GetSystemPrincipal(), - nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, - nsIContentPolicy::TYPE_OTHER); - } - if (NS_SUCCEEDED(rv) && (channel)) { - channel->SetNotificationCallbacks(httpIndex); - rv = channel->AsyncOpen2(httpIndex); - } - } - } - - if (httpIndex->mNodeList) - { - httpIndex->mNodeList->GetLength(&numItems); - if (numItems > 0) - { - // account for order required: src, prop, then target - numItems /=3; - if (numItems > 10) - numItems = 10; - - int32_t loop; - for (loop=0; loop<(int32_t)numItems; loop++) - { - nsCOMPtr src = do_QueryElementAt(httpIndex->mNodeList, 0); - httpIndex->mNodeList->RemoveElementAt(0); - - nsCOMPtr prop = do_QueryElementAt(httpIndex->mNodeList, 0); - httpIndex->mNodeList->RemoveElementAt(0); - - nsCOMPtr target = do_QueryElementAt(httpIndex->mNodeList, 0); - httpIndex->mNodeList->RemoveElementAt(0); - - if (src && prop && target) - { - if (prop.get() == httpIndex->kNC_Loading) - { - httpIndex->Unassert(src, prop, target); - } - else - { - httpIndex->Assert(src, prop, target, true); - } - } - } - } - } - - bool refireTimer = false; - // check both lists to see if the timer needs to continue firing - if (httpIndex->mConnectionList) - { - httpIndex->mConnectionList->GetLength(&numItems); - if (numItems > 0) - { - refireTimer = true; - } - else - { - httpIndex->mConnectionList->Clear(); - } - } - - if (httpIndex->mNodeList) - { - httpIndex->mNodeList->GetLength(&numItems); - if (numItems > 0) - { - refireTimer = true; - } - else - { - httpIndex->mNodeList->Clear(); - } - } - - // be sure to cancel the timer, as it holds a - // weak reference back to nsHTTPIndex - httpIndex->mTimer->Cancel(); - httpIndex->mTimer = nullptr; - - // after firing off any/all of the connections be sure - // to cancel the timer if we don't need to refire it - if (refireTimer) - { - NS_NewTimerWithFuncCallback(getter_AddRefs(httpIndex->mTimer), - nsHTTPIndex::FireTimer, - aClosure, - 10, - nsITimer::TYPE_ONE_SHOT, - "nsHTTPIndex::FireTimer"); - // Note: don't addref "this" as we'll cancel the - // timer in the httpIndex destructor - } -} - -NS_IMETHODIMP -nsHTTPIndex::Assert(nsIRDFResource *aSource, nsIRDFResource *aProperty, nsIRDFNode *aTarget, - bool aTruthValue) -{ - nsresult rv = NS_ERROR_UNEXPECTED; - if (mInner) - { - rv = mInner->Assert(aSource, aProperty, aTarget, aTruthValue); - } - return(rv); -} - -NS_IMETHODIMP -nsHTTPIndex::Unassert(nsIRDFResource *aSource, nsIRDFResource *aProperty, nsIRDFNode *aTarget) -{ - nsresult rv = NS_ERROR_UNEXPECTED; - if (mInner) - { - rv = mInner->Unassert(aSource, aProperty, aTarget); - } - return(rv); -} - -NS_IMETHODIMP -nsHTTPIndex::Change(nsIRDFResource *aSource, nsIRDFResource *aProperty, - nsIRDFNode *aOldTarget, nsIRDFNode *aNewTarget) -{ - nsresult rv = NS_ERROR_UNEXPECTED; - if (mInner) - { - rv = mInner->Change(aSource, aProperty, aOldTarget, aNewTarget); - } - return(rv); -} - -NS_IMETHODIMP -nsHTTPIndex::Move(nsIRDFResource *aOldSource, nsIRDFResource *aNewSource, - nsIRDFResource *aProperty, nsIRDFNode *aTarget) -{ - nsresult rv = NS_ERROR_UNEXPECTED; - if (mInner) - { - rv = mInner->Move(aOldSource, aNewSource, aProperty, aTarget); - } - return(rv); -} - -NS_IMETHODIMP -nsHTTPIndex::HasAssertion(nsIRDFResource *aSource, nsIRDFResource *aProperty, - nsIRDFNode *aTarget, bool aTruthValue, bool *_retval) -{ - nsresult rv = NS_ERROR_UNEXPECTED; - if (mInner) - { - rv = mInner->HasAssertion(aSource, aProperty, aTarget, aTruthValue, _retval); - } - return(rv); -} - -NS_IMETHODIMP -nsHTTPIndex::AddObserver(nsIRDFObserver *aObserver) -{ - nsresult rv = NS_ERROR_UNEXPECTED; - if (mInner) - { - rv = mInner->AddObserver(aObserver); - } - return(rv); -} - -NS_IMETHODIMP -nsHTTPIndex::RemoveObserver(nsIRDFObserver *aObserver) -{ - nsresult rv = NS_ERROR_UNEXPECTED; - if (mInner) - { - rv = mInner->RemoveObserver(aObserver); - } - return(rv); -} - -NS_IMETHODIMP -nsHTTPIndex::HasArcIn(nsIRDFNode *aNode, nsIRDFResource *aArc, bool *result) -{ - if (!mInner) { - *result = false; - return NS_OK; - } - return mInner->HasArcIn(aNode, aArc, result); -} - -NS_IMETHODIMP -nsHTTPIndex::HasArcOut(nsIRDFResource *aSource, nsIRDFResource *aArc, bool *result) -{ - if (aArc == kNC_Child && isWellknownContainerURI(aSource)) { - *result = true; - return NS_OK; - } - - if (mInner) { - return mInner->HasArcOut(aSource, aArc, result); - } - - *result = false; - return NS_OK; -} - -NS_IMETHODIMP -nsHTTPIndex::ArcLabelsIn(nsIRDFNode *aNode, nsISimpleEnumerator **_retval) -{ - nsresult rv = NS_ERROR_UNEXPECTED; - if (mInner) - { - rv = mInner->ArcLabelsIn(aNode, _retval); - } - return(rv); -} - -NS_IMETHODIMP -nsHTTPIndex::ArcLabelsOut(nsIRDFResource *aSource, nsISimpleEnumerator **_retval) -{ - *_retval = nullptr; - - nsCOMPtr child, anonArcs; - if (isWellknownContainerURI(aSource)) - { - NS_NewSingletonEnumerator(getter_AddRefs(child), kNC_Child); - } - - if (mInner) - { - mInner->ArcLabelsOut(aSource, getter_AddRefs(anonArcs)); - } - - return NS_NewUnionEnumerator(_retval, child, anonArcs); -} - -NS_IMETHODIMP -nsHTTPIndex::GetAllResources(nsISimpleEnumerator **_retval) -{ - nsresult rv = NS_ERROR_UNEXPECTED; - if (mInner) - { - rv = mInner->GetAllResources(_retval); - } - return(rv); -} - -NS_IMETHODIMP -nsHTTPIndex::IsCommandEnabled(nsISupports *aSources, nsIRDFResource *aCommand, - nsISupports *aArguments, bool *_retval) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -nsHTTPIndex::DoCommand(nsISupports *aSources, nsIRDFResource *aCommand, - nsISupports *aArguments) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -nsHTTPIndex::BeginUpdateBatch() -{ - return mInner->BeginUpdateBatch(); -} - -NS_IMETHODIMP -nsHTTPIndex::EndUpdateBatch() -{ - return mInner->EndUpdateBatch(); -} - -NS_IMETHODIMP -nsHTTPIndex::GetAllCmds(nsIRDFResource *aSource, nsISimpleEnumerator **_retval) -{ - nsresult rv = NS_ERROR_UNEXPECTED; - if (mInner) - { - rv = mInner->GetAllCmds(aSource, _retval); - } - return(rv); -} - - -//---------------------------------------------------------------------- -// -// nsDirectoryViewerFactory -// -nsDirectoryViewerFactory::nsDirectoryViewerFactory() -{ -} - - - -nsDirectoryViewerFactory::~nsDirectoryViewerFactory() -{ -} - - -NS_IMPL_ISUPPORTS(nsDirectoryViewerFactory, nsIDocumentLoaderFactory) - - - -NS_IMETHODIMP -nsDirectoryViewerFactory::CreateInstance(const char *aCommand, - nsIChannel* aChannel, - nsILoadGroup* aLoadGroup, - const nsACString& aContentType, - nsIDocShell* aContainer, - nsISupports* aExtraInfo, - nsIStreamListener** aDocListenerResult, - nsIContentViewer** aDocViewerResult) -{ - nsresult rv; - - bool viewSource = FindInReadable(NS_LITERAL_CSTRING("view-source"), - aContentType); - - if (!viewSource && - Preferences::GetInt("network.dir.format", FORMAT_XUL) == FORMAT_XUL) { - // ... and setup the original channel's content type - (void)aChannel->SetContentType(NS_LITERAL_CSTRING("application/vnd.mozilla.xul+xml")); - - // This is where we shunt the HTTP/Index stream into our datasource, - // and open the directory viewer XUL file as the content stream to - // load in its place. - - // Create a dummy loader that will load a stub XUL document. - nsCOMPtr catMan(do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv)); - if (NS_FAILED(rv)) - return rv; - nsCString contractID; - rv = catMan->GetCategoryEntry("Gecko-Content-Viewers", "application/vnd.mozilla.xul+xml", - getter_Copies(contractID)); - if (NS_FAILED(rv)) - return rv; - - nsCOMPtr - factory(do_GetService(contractID.get(), &rv)); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr uri; - rv = NS_NewURI(getter_AddRefs(uri), "chrome://communicator/content/directory/directory.xul"); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr channel; - rv = NS_NewChannel(getter_AddRefs(channel), - uri, - nsContentUtils::GetSystemPrincipal(), - nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, - nsIContentPolicy::TYPE_OTHER, - nullptr, // PerformanceStorage - aLoadGroup); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr listener; - rv = factory->CreateInstance(aCommand, channel, aLoadGroup, - NS_LITERAL_CSTRING("application/vnd.mozilla.xul+xml"), - aContainer, aExtraInfo, getter_AddRefs(listener), - aDocViewerResult); - if (NS_FAILED(rv)) return rv; - - rv = channel->AsyncOpen2(listener); - if (NS_FAILED(rv)) return rv; - - // Create an HTTPIndex object so that we can stuff it into the script context - nsCOMPtr baseuri; - rv = aChannel->GetURI(getter_AddRefs(baseuri)); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr requestor = do_QueryInterface(aContainer,&rv); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr httpindex; - rv = nsHTTPIndex::Create(baseuri, requestor, getter_AddRefs(httpindex)); - if (NS_FAILED(rv)) return rv; - - // Now shanghai the stream into our http-index parsing datasource - // wrapper beastie. - listener = do_QueryInterface(httpindex,&rv); - *aDocListenerResult = listener.get(); - NS_ADDREF(*aDocListenerResult); - - return NS_OK; - } - - // setup the original channel's content type - (void)aChannel->SetContentType(NS_LITERAL_CSTRING("text/html")); - - // Otherwise, lets use the html listing - nsCOMPtr catMan(do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv)); - if (NS_FAILED(rv)) - return rv; - nsCString contractID; - rv = catMan->GetCategoryEntry("Gecko-Content-Viewers", "text/html", - getter_Copies(contractID)); - if (NS_FAILED(rv)) - return rv; - - nsCOMPtr - factory(do_GetService(contractID.get(), &rv)); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr listener; - - if (viewSource) { - rv = factory->CreateInstance("view-source", aChannel, aLoadGroup, - NS_LITERAL_CSTRING("text/html; x-view-type=view-source"), - aContainer, aExtraInfo, getter_AddRefs(listener), - aDocViewerResult); - } else { - rv = factory->CreateInstance("view", aChannel, aLoadGroup, - NS_LITERAL_CSTRING("text/html"), - aContainer, aExtraInfo, getter_AddRefs(listener), - aDocViewerResult); - } - - if (NS_FAILED(rv)) return rv; - - nsCOMPtr scs = do_GetService("@mozilla.org/streamConverters;1", &rv); - if (NS_FAILED(rv)) return rv; - - rv = scs->AsyncConvertData("application/http-index-format", - "text/html", - listener, - nullptr, - aDocListenerResult); - - if (NS_FAILED(rv)) return rv; - - return NS_OK; -} - - - -NS_IMETHODIMP -nsDirectoryViewerFactory::CreateInstanceForDocument(nsISupports* aContainer, - nsIDocument* aDocument, - const char *aCommand, - nsIContentViewer** aDocViewerResult) -{ - MOZ_ASSERT_UNREACHABLE("didn't expect to get here"); - return NS_ERROR_NOT_IMPLEMENTED; -} diff --git a/xpfe/components/directory/nsDirectoryViewer.h b/xpfe/components/directory/nsDirectoryViewer.h deleted file mode 100644 index ecb32b0a1404..000000000000 --- a/xpfe/components/directory/nsDirectoryViewer.h +++ /dev/null @@ -1,126 +0,0 @@ -/* -*- 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/. */ - -#ifndef nsdirectoryviewer__h____ -#define nsdirectoryviewer__h____ - -#include "nsCOMPtr.h" -#include "nsIStreamListener.h" -#include "nsIContentViewer.h" -#include "nsIHTTPIndex.h" -#include "nsIRDFService.h" -#include "nsIRDFDataSource.h" -#include "nsIRDFLiteral.h" -#include "nsIDocumentLoaderFactory.h" -#include "nsITimer.h" -#include "nsString.h" -#include "nsIDirIndexListener.h" -#include "nsIFTPChannel.h" -#include "nsCycleCollectionParticipant.h" -#include "nsIInterfaceRequestor.h" -#include "nsIURI.h" - -class nsIMutableArray; - -class nsDirectoryViewerFactory : public nsIDocumentLoaderFactory -{ -public: - nsDirectoryViewerFactory(); - - // nsISupports interface - NS_DECL_ISUPPORTS - NS_DECL_NSIDOCUMENTLOADERFACTORY - -protected: - virtual ~nsDirectoryViewerFactory(); -}; - -class nsHTTPIndex final : public nsIHTTPIndex, - public nsIRDFDataSource, - public nsIStreamListener, - public nsIDirIndexListener, - public nsIInterfaceRequestor, - public nsIFTPEventSink -{ -private: - - // note: these are NOT statics due to the native of nsHTTPIndex - // where it may or may not be treated as a singleton - - nsCOMPtr kNC_Child; - nsCOMPtr kNC_Comment; - nsCOMPtr kNC_Loading; - nsCOMPtr kNC_URL; - nsCOMPtr kNC_Description; - nsCOMPtr kNC_ContentLength; - nsCOMPtr kNC_LastModified; - nsCOMPtr kNC_ContentType; - nsCOMPtr kNC_FileType; - nsCOMPtr kNC_IsContainer; - nsCOMPtr kTrueLiteral; - nsCOMPtr kFalseLiteral; - - nsCOMPtr mDirRDF; - -protected: - // We grab a reference to the content viewer container (which - // indirectly owns us) so that we can insert ourselves as a global - // in the script context _after_ the XUL doc has been embedded into - // content viewer. We'll know that this has happened once we receive - // an OnStartRequest() notification - - nsCOMPtr mInner; - nsCOMPtr mConnectionList; - nsCOMPtr mNodeList; - nsCOMPtr mTimer; - nsCOMPtr mParser; - nsCString mBaseURL; - nsCString mEncoding; - bool mBindToGlobalObject; - nsIInterfaceRequestor* mRequestor; // WEAK - nsCOMPtr mDirectory; - - explicit nsHTTPIndex(nsIInterfaceRequestor* aRequestor); - nsresult CommonInit(void); - nsresult Init(nsIURI* aBaseURL); - void GetDestination(nsIRDFResource* r, nsACString& dest); - bool isWellknownContainerURI(nsIRDFResource *r); - nsresult AddElement(nsIRDFResource *parent, nsIRDFResource *prop, - nsIRDFNode *child); - - static void FireTimer(nsITimer* aTimer, void* aClosure); - - virtual ~nsHTTPIndex(); - -public: - nsHTTPIndex(); - nsresult Init(void); - - static nsresult Create(nsIURI* aBaseURI, nsIInterfaceRequestor* aContainer, - nsIHTTPIndex** aResult); - - // nsIHTTPIndex interface - NS_DECL_NSIHTTPINDEX - - // NSIRDFDataSource interface - NS_DECL_NSIRDFDATASOURCE - - NS_DECL_NSIREQUESTOBSERVER - NS_DECL_NSISTREAMLISTENER - - NS_DECL_NSIDIRINDEXLISTENER - NS_DECL_NSIINTERFACEREQUESTOR - NS_DECL_NSIFTPEVENTSINK - - // nsISupports interface - NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsHTTPIndex, nsIHTTPIndex) -}; - -// {82776710-5690-11d3-BE36-00104BDE6048} -#define NS_DIRECTORYVIEWERFACTORY_CID \ -{ 0x82776710, 0x5690, 0x11d3, { 0xbe, 0x36, 0x0, 0x10, 0x4b, 0xde, 0x60, 0x48 } } - -#endif // nsdirectoryviewer__h____ diff --git a/xpfe/components/directory/nsIHTTPIndex.idl b/xpfe/components/directory/nsIHTTPIndex.idl deleted file mode 100644 index 47697172bcc5..000000000000 --- a/xpfe/components/directory/nsIHTTPIndex.idl +++ /dev/null @@ -1,50 +0,0 @@ -/* -*- 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/. */ - -/* - - The interface to an HTTP index - -*/ - -#include "nsISupports.idl" - -interface nsIStreamListener; -interface nsIRDFDataSource; -interface nsIRDFNode; -interface nsIRDFResource; - -[scriptable, uuid(6F2BDBD0-58C3-11d3-BE36-00104BDE6048)] -interface nsIHTTPIndex : nsISupports -{ - /** - * The base URL of the HTTP index - */ - readonly attribute string BaseURL; - - /** - * The RDF datasource that contains the HTTP index information. - */ - readonly attribute nsIRDFDataSource DataSource; - - /** - * The charset to use for decoding FTP filenames - */ - attribute string encoding; -}; - -%{C++ - -// {{2587e382-1324-11d4-a652-eadbb2be3484} -#define NS_HTTPINDEX_SERVICE_CID \ -{ 0x2587e382, 0x1324, 0x11d4, { 0xa6, 0x52, 0xea, 0xdb, 0xb2, 0xbe, 0x34, 0x84 } } - -#define NS_HTTPINDEX_SERVICE_CONTRACTID \ - "@mozilla.org/browser/httpindex-service;1" - -#define NS_HTTPINDEX_DATASOURCE_CONTRACTID \ - "@mozilla.org/rdf/datasource;1?name=httpindex" - -%} diff --git a/xpfe/components/moz.build b/xpfe/components/moz.build deleted file mode 100644 index d85bd09e2750..000000000000 --- a/xpfe/components/moz.build +++ /dev/null @@ -1,14 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -with Files("**"): - BUG_COMPONENT = ("Core", "Window Management") - -DIRS += [ - 'directory', - 'build', -] - From 3d65fdbc34c929ec70091569806ceca98ed93e7f Mon Sep 17 00:00:00 2001 From: Kris Maglione Date: Sat, 28 Apr 2018 20:06:40 -0700 Subject: [PATCH 33/34] Bug 833098: Part 2 - Remove RDF service. r=hsivonen,Mossop,pike MozReview-Commit-ID: 32Nl5McAFGJ --HG-- extra : source : c00426f6bc7d1a10e5609ac9530eb315d64d9d85 extra : histedit_source : 4ab49fa208d0fc0ccd8e0b623644cc91d705d462 --- browser/components/build/nsModule.cpp | 1 - dom/bindings/Bindings.conf | 3 - dom/xul/XULDocument.h | 7 - dom/xul/nsXULCommandDispatcher.cpp | 1 - dom/xul/nsXULContentSink.cpp | 1 - dom/xul/nsXULContentUtils.cpp | 17 - dom/xul/nsXULContentUtils.h | 11 - layout/build/nsLayoutStatics.cpp | 10 - rdf/base/moz.build | 59 - rdf/base/nsCompositeDataSource.cpp | 1357 ------------ rdf/base/nsContainerEnumerator.cpp | 262 --- rdf/base/nsDefaultResourceFactory.cpp | 30 - rdf/base/nsIRDFCompositeDataSource.idl | 68 - rdf/base/nsIRDFContainer.idl | 94 - rdf/base/nsIRDFContainerUtils.idl | 82 - rdf/base/nsIRDFContentSink.h | 57 - rdf/base/nsIRDFDataSource.idl | 181 -- rdf/base/nsIRDFDelegateFactory.idl | 40 - rdf/base/nsIRDFInMemoryDataSource.idl | 14 - rdf/base/nsIRDFInferDataSource.idl | 28 - rdf/base/nsIRDFLiteral.idl | 68 - rdf/base/nsIRDFNode.idl | 15 - rdf/base/nsIRDFObserver.idl | 94 - rdf/base/nsIRDFPropagatableDataSource.idl | 27 - rdf/base/nsIRDFPurgeableDataSource.idl | 19 - rdf/base/nsIRDFRemoteDataSource.idl | 44 - rdf/base/nsIRDFResource.idl | 81 - rdf/base/nsIRDFService.idl | 146 -- rdf/base/nsIRDFXMLParser.idl | 33 - rdf/base/nsIRDFXMLSerializer.idl | 31 - rdf/base/nsIRDFXMLSink.idl | 133 -- rdf/base/nsIRDFXMLSource.idl | 20 - rdf/base/nsInMemoryDataSource.cpp | 1938 ----------------- rdf/base/nsNameSpaceMap.cpp | 64 - rdf/base/nsNameSpaceMap.h | 98 - rdf/base/nsRDFBaseDataSources.h | 32 - rdf/base/nsRDFContainer.cpp | 724 ------ rdf/base/nsRDFContainerUtils.cpp | 513 ----- rdf/base/nsRDFContentSink.cpp | 1444 ------------ rdf/base/nsRDFResource.cpp | 220 -- rdf/base/nsRDFResource.h | 59 - rdf/base/nsRDFService.cpp | 1540 ------------- rdf/base/nsRDFService.h | 66 - rdf/base/nsRDFXMLDataSource.cpp | 1173 ---------- rdf/base/nsRDFXMLParser.cpp | 137 -- rdf/base/nsRDFXMLParser.h | 31 - rdf/base/nsRDFXMLSerializer.cpp | 1123 ---------- rdf/base/nsRDFXMLSerializer.h | 117 - rdf/base/rdf.h | 57 - rdf/base/rdfIDataSource.idl | 38 - rdf/base/rdfITripleVisitor.idl | 31 - rdf/base/rdfutil.cpp | 110 - rdf/base/rdfutil.h | 38 - rdf/build/moz.build | 20 - rdf/build/nsRDFCID.h | 76 - rdf/build/nsRDFModule.cpp | 120 - rdf/datasource/moz.build | 21 - rdf/datasource/nsILocalStore.h | 34 - rdf/datasource/nsIRDFFTP.h | 33 - rdf/datasource/nsLocalStore.cpp | 474 ---- rdf/datasource/nsRDFBuiltInDataSources.h | 27 - rdf/moz.build | 12 - rdf/tests/moz.build | 7 - rdf/tests/unit/sample.rdf | 9 - rdf/tests/unit/test_rdfredirect.js | 92 - rdf/tests/unit/xpcshell.ini | 5 - .../components/build/nsToolkitCompsModule.cpp | 1 - toolkit/toolkit.mozbuild | 4 - 68 files changed, 13522 deletions(-) delete mode 100644 rdf/base/moz.build delete mode 100644 rdf/base/nsCompositeDataSource.cpp delete mode 100644 rdf/base/nsContainerEnumerator.cpp delete mode 100644 rdf/base/nsDefaultResourceFactory.cpp delete mode 100644 rdf/base/nsIRDFCompositeDataSource.idl delete mode 100644 rdf/base/nsIRDFContainer.idl delete mode 100644 rdf/base/nsIRDFContainerUtils.idl delete mode 100644 rdf/base/nsIRDFContentSink.h delete mode 100644 rdf/base/nsIRDFDataSource.idl delete mode 100644 rdf/base/nsIRDFDelegateFactory.idl delete mode 100644 rdf/base/nsIRDFInMemoryDataSource.idl delete mode 100644 rdf/base/nsIRDFInferDataSource.idl delete mode 100644 rdf/base/nsIRDFLiteral.idl delete mode 100644 rdf/base/nsIRDFNode.idl delete mode 100644 rdf/base/nsIRDFObserver.idl delete mode 100644 rdf/base/nsIRDFPropagatableDataSource.idl delete mode 100644 rdf/base/nsIRDFPurgeableDataSource.idl delete mode 100644 rdf/base/nsIRDFRemoteDataSource.idl delete mode 100644 rdf/base/nsIRDFResource.idl delete mode 100644 rdf/base/nsIRDFService.idl delete mode 100644 rdf/base/nsIRDFXMLParser.idl delete mode 100644 rdf/base/nsIRDFXMLSerializer.idl delete mode 100644 rdf/base/nsIRDFXMLSink.idl delete mode 100644 rdf/base/nsIRDFXMLSource.idl delete mode 100644 rdf/base/nsInMemoryDataSource.cpp delete mode 100644 rdf/base/nsNameSpaceMap.cpp delete mode 100644 rdf/base/nsNameSpaceMap.h delete mode 100644 rdf/base/nsRDFBaseDataSources.h delete mode 100644 rdf/base/nsRDFContainer.cpp delete mode 100644 rdf/base/nsRDFContainerUtils.cpp delete mode 100644 rdf/base/nsRDFContentSink.cpp delete mode 100644 rdf/base/nsRDFResource.cpp delete mode 100644 rdf/base/nsRDFResource.h delete mode 100644 rdf/base/nsRDFService.cpp delete mode 100644 rdf/base/nsRDFService.h delete mode 100644 rdf/base/nsRDFXMLDataSource.cpp delete mode 100644 rdf/base/nsRDFXMLParser.cpp delete mode 100644 rdf/base/nsRDFXMLParser.h delete mode 100644 rdf/base/nsRDFXMLSerializer.cpp delete mode 100644 rdf/base/nsRDFXMLSerializer.h delete mode 100644 rdf/base/rdf.h delete mode 100644 rdf/base/rdfIDataSource.idl delete mode 100644 rdf/base/rdfITripleVisitor.idl delete mode 100644 rdf/base/rdfutil.cpp delete mode 100644 rdf/base/rdfutil.h delete mode 100644 rdf/build/moz.build delete mode 100644 rdf/build/nsRDFCID.h delete mode 100644 rdf/build/nsRDFModule.cpp delete mode 100644 rdf/datasource/moz.build delete mode 100644 rdf/datasource/nsILocalStore.h delete mode 100644 rdf/datasource/nsIRDFFTP.h delete mode 100644 rdf/datasource/nsLocalStore.cpp delete mode 100644 rdf/datasource/nsRDFBuiltInDataSources.h delete mode 100644 rdf/moz.build delete mode 100644 rdf/tests/moz.build delete mode 100755 rdf/tests/unit/sample.rdf delete mode 100644 rdf/tests/unit/test_rdfredirect.js delete mode 100644 rdf/tests/unit/xpcshell.ini diff --git a/browser/components/build/nsModule.cpp b/browser/components/build/nsModule.cpp index 167efa4020c2..662321f3ff75 100644 --- a/browser/components/build/nsModule.cpp +++ b/browser/components/build/nsModule.cpp @@ -20,7 +20,6 @@ #include "nsIEHistoryEnumerator.h" #endif -#include "rdf.h" #include "nsFeedSniffer.h" #include "AboutRedirector.h" #include "nsIAboutModule.h" diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index 242c2d5ce0c7..33285168b49c 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -1707,9 +1707,6 @@ addExternalIface('LoadInfo', nativeType='nsILoadInfo', addExternalIface('MenuBuilder', nativeType='nsIMenuBuilder', notflattened=True) addExternalIface('XULControllers', nativeType='nsIControllers', notflattened=True) addExternalIface('MozObserver', nativeType='nsIObserver', notflattened=True) -addExternalIface('MozRDFCompositeDataSource', nativeType='nsIRDFCompositeDataSource', - notflattened=True) -addExternalIface('MozRDFResource', nativeType='nsIRDFResource', notflattened=True) addExternalIface('MozTreeView', nativeType='nsITreeView', headerFile='nsITreeView.h', notflattened=True) addExternalIface('MozWakeLockListener', headerFile='nsIDOMWakeLockListener.h') diff --git a/dom/xul/XULDocument.h b/dom/xul/XULDocument.h index 9f497fe72414..3b4b0ffd222e 100644 --- a/dom/xul/XULDocument.h +++ b/dom/xul/XULDocument.h @@ -29,8 +29,6 @@ #include "js/TracingAPI.h" #include "js/TypeDecls.h" -class nsIRDFResource; -class nsIRDFService; class nsPIWindowRoot; class nsXULPrototypeElement; #if 0 // XXXbe save me, scc (need NSCAP_FORWARD_DECL(nsXULPrototypeScript)) @@ -254,11 +252,6 @@ protected: // pseudo constants static int32_t gRefCnt; - static nsIRDFService* gRDFService; - static nsIRDFResource* kNC_persist; - static nsIRDFResource* kNC_attribute; - static nsIRDFResource* kNC_value; - static LazyLogModule gXULLog; nsresult diff --git a/dom/xul/nsXULCommandDispatcher.cpp b/dom/xul/nsXULCommandDispatcher.cpp index 09f1d099ab68..ccdf818c1ce1 100644 --- a/dom/xul/nsXULCommandDispatcher.cpp +++ b/dom/xul/nsXULCommandDispatcher.cpp @@ -21,7 +21,6 @@ #include "nsIScriptGlobalObject.h" #include "nsPIDOMWindow.h" #include "nsPIWindowRoot.h" -#include "nsRDFCID.h" #include "nsXULCommandDispatcher.h" #include "mozilla/Logging.h" #include "nsContentUtils.h" diff --git a/dom/xul/nsXULContentSink.cpp b/dom/xul/nsXULContentSink.cpp index c84168b43e57..155cc3c48a90 100644 --- a/dom/xul/nsXULContentSink.cpp +++ b/dom/xul/nsXULContentSink.cpp @@ -34,7 +34,6 @@ #include "nsIScriptSecurityManager.h" #include "nsLayoutCID.h" #include "nsNetUtil.h" -#include "nsRDFCID.h" #include "nsString.h" #include "nsReadableUtils.h" #include "nsXULElement.h" diff --git a/dom/xul/nsXULContentUtils.cpp b/dom/xul/nsXULContentUtils.cpp index 3f1ba523fdb8..bb97f37cca7e 100644 --- a/dom/xul/nsXULContentUtils.cpp +++ b/dom/xul/nsXULContentUtils.cpp @@ -19,11 +19,9 @@ #include "nsICollation.h" #include "nsIDocument.h" #include "nsIDOMXULCommandDispatcher.h" -#include "nsIRDFService.h" #include "nsIServiceManager.h" #include "nsXULContentUtils.h" #include "nsLayoutCID.h" -#include "nsRDFCID.h" #include "nsString.h" #include "nsGkAtoms.h" #include "XULDocument.h" @@ -33,30 +31,15 @@ using dom::XULDocument; //------------------------------------------------------------------------ -nsIRDFService* nsXULContentUtils::gRDF; nsICollation *nsXULContentUtils::gCollation; //------------------------------------------------------------------------ // Constructors n' stuff // -nsresult -nsXULContentUtils::Init() -{ - static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); - nsresult rv = CallGetService(kRDFServiceCID, &gRDF); - if (NS_FAILED(rv)) { - return rv; - } - - return NS_OK; -} - - nsresult nsXULContentUtils::Finish() { - NS_IF_RELEASE(gRDF); NS_IF_RELEASE(gCollation); return NS_OK; diff --git a/dom/xul/nsXULContentUtils.h b/dom/xul/nsXULContentUtils.h index 00b080cb4f30..2635d9df2cd9 100644 --- a/dom/xul/nsXULContentUtils.h +++ b/dom/xul/nsXULContentUtils.h @@ -18,7 +18,6 @@ class nsAtom; class nsICollation; class nsIContent; class nsIDocument; -class nsIRDFService; namespace mozilla { namespace dom { @@ -29,7 +28,6 @@ class Element; class nsXULContentUtils { protected: - static nsIRDFService* gRDF; static nsICollation *gCollation; static bool gDisableXULCache; @@ -38,9 +36,6 @@ protected: DisableXULCacheChangedCallback(const char* aPrefName, void* aClosure); public: - static nsresult - Init(); - static nsresult Finish(); @@ -53,12 +48,6 @@ public: static nsresult SetCommandUpdater(nsIDocument* aDocument, mozilla::dom::Element* aElement); - static nsIRDFService* - RDFService() - { - return gRDF; - } - static nsICollation* GetCollation(); }; diff --git a/layout/build/nsLayoutStatics.cpp b/layout/build/nsLayoutStatics.cpp index 1c52452e6d71..80a42627f203 100644 --- a/layout/build/nsLayoutStatics.cpp +++ b/layout/build/nsLayoutStatics.cpp @@ -49,7 +49,6 @@ #include "nsHTMLDNSPrefetch.h" #include "nsHtml5Module.h" #include "nsHTMLTags.h" -#include "nsIRDFContentSink.h" // for RDF atom initialization #include "mozilla/dom/FallbackEncoding.h" #include "nsFocusManager.h" #include "nsListControlFrame.h" @@ -181,15 +180,6 @@ nsLayoutStatics::Initialize() return rv; } -#ifdef MOZ_XUL - rv = nsXULContentUtils::Init(); - if (NS_FAILED(rv)) { - NS_ERROR("Could not initialize nsXULContentUtils"); - return rv; - } - -#endif - nsMathMLOperators::AddRefTable(); #ifdef DEBUG diff --git a/rdf/base/moz.build b/rdf/base/moz.build deleted file mode 100644 index 0411d6292463..000000000000 --- a/rdf/base/moz.build +++ /dev/null @@ -1,59 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -XPIDL_SOURCES += [ - 'nsIRDFCompositeDataSource.idl', - 'nsIRDFContainer.idl', - 'nsIRDFContainerUtils.idl', - 'nsIRDFDataSource.idl', - 'nsIRDFDelegateFactory.idl', - 'nsIRDFInferDataSource.idl', - 'nsIRDFInMemoryDataSource.idl', - 'nsIRDFLiteral.idl', - 'nsIRDFNode.idl', - 'nsIRDFObserver.idl', - 'nsIRDFPropagatableDataSource.idl', - 'nsIRDFPurgeableDataSource.idl', - 'nsIRDFRemoteDataSource.idl', - 'nsIRDFResource.idl', - 'nsIRDFService.idl', - 'nsIRDFXMLParser.idl', - 'nsIRDFXMLSerializer.idl', - 'nsIRDFXMLSink.idl', - 'nsIRDFXMLSource.idl', - 'rdfIDataSource.idl', - 'rdfITripleVisitor.idl', -] - -XPIDL_MODULE = 'rdf' - -EXPORTS += [ - 'nsIRDFContentSink.h', - 'nsRDFResource.h', - 'rdf.h', -] - -UNIFIED_SOURCES += [ - 'nsCompositeDataSource.cpp', - 'nsContainerEnumerator.cpp', - 'nsDefaultResourceFactory.cpp', - 'nsInMemoryDataSource.cpp', - 'nsNameSpaceMap.cpp', - 'nsRDFContainer.cpp', - 'nsRDFContainerUtils.cpp', - 'nsRDFContentSink.cpp', - 'nsRDFResource.cpp', - 'nsRDFService.cpp', - 'nsRDFXMLDataSource.cpp', - 'nsRDFXMLParser.cpp', - 'nsRDFXMLSerializer.cpp', - 'rdfutil.cpp', -] - -FINAL_LIBRARY = 'xul' - -if CONFIG['CC_TYPE'] in ('clang', 'gcc'): - CXXFLAGS += ['-Wno-error=shadow'] diff --git a/rdf/base/nsCompositeDataSource.cpp b/rdf/base/nsCompositeDataSource.cpp deleted file mode 100644 index f5c7492497b5..000000000000 --- a/rdf/base/nsCompositeDataSource.cpp +++ /dev/null @@ -1,1357 +0,0 @@ -/* -*- 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/. */ - -/* - - A simple composite data source implementation. A composit data - source is just a strategy for combining individual data sources into - a collective graph. - - - 1) A composite data source holds a sequence of data sources. The set - of data sources can be specified during creation of the - database. Data sources can also be added/deleted from a database - later. - - 2) The aggregation mechanism is based on simple super-positioning of - the graphs from the datasources. If there is a conflict (i.e., - data source A has a true arc from foo to bar while data source B - has a false arc from foo to bar), the data source that it earlier - in the sequence wins. - - The implementation below doesn't really do this and needs to be - fixed. - -*/ - -#include "xpcom-config.h" -#include "nsCOMPtr.h" -#include "nsIComponentManager.h" -#include "nsIRDFCompositeDataSource.h" -#include "nsIRDFNode.h" -#include "nsIRDFObserver.h" -#include "nsIRDFRemoteDataSource.h" -#include "nsTArray.h" -#include "nsCOMArray.h" -#include "nsArrayEnumerator.h" -#include "nsString.h" -#include "rdf.h" -#include "nsCycleCollectionParticipant.h" - -#include "nsEnumeratorUtils.h" - -#include "mozilla/Logging.h" -#include -mozilla::LazyLogModule nsRDFLog("RDF"); - -//---------------------------------------------------------------------- -// -// CompositeDataSourceImpl -// - -class CompositeEnumeratorImpl; -class CompositeArcsInOutEnumeratorImpl; -class CompositeAssertionEnumeratorImpl; - -class CompositeDataSourceImpl : public nsIRDFCompositeDataSource, - public nsIRDFObserver -{ -public: - CompositeDataSourceImpl(void); - explicit CompositeDataSourceImpl(char** dataSources); - - // nsISupports interface - NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(CompositeDataSourceImpl, - nsIRDFCompositeDataSource) - - // nsIRDFDataSource interface - NS_DECL_NSIRDFDATASOURCE - - // nsIRDFCompositeDataSource interface - NS_DECL_NSIRDFCOMPOSITEDATASOURCE - - // nsIRDFObserver interface - NS_DECL_NSIRDFOBSERVER - - bool HasAssertionN(int n, nsIRDFResource* source, - nsIRDFResource* property, - nsIRDFNode* target, - bool tv); - -protected: - nsCOMArray mObservers; - nsCOMArray mDataSources; - - bool mAllowNegativeAssertions; - bool mCoalesceDuplicateArcs; - int32_t mUpdateBatchNest; - - virtual ~CompositeDataSourceImpl() {} - - friend class CompositeEnumeratorImpl; - friend class CompositeArcsInOutEnumeratorImpl; - friend class CompositeAssertionEnumeratorImpl; -}; - -//---------------------------------------------------------------------- -// -// CompositeEnumeratorImpl -// - -class CompositeEnumeratorImpl : public nsISimpleEnumerator -{ - // nsISupports - NS_DECL_ISUPPORTS - - // nsISimpleEnumerator interface - NS_DECL_NSISIMPLEENUMERATOR - - // pure abstract methods to be overridden - virtual nsresult - GetEnumerator(nsIRDFDataSource* aDataSource, nsISimpleEnumerator** aResult) = 0; - - virtual nsresult - HasNegation(nsIRDFDataSource* aDataSource, nsIRDFNode* aNode, bool* aResult) = 0; - -protected: - CompositeEnumeratorImpl(CompositeDataSourceImpl* aCompositeDataSource, - bool aAllowNegativeAssertions, - bool aCoalesceDuplicateArcs); - - virtual ~CompositeEnumeratorImpl(); - - CompositeDataSourceImpl* mCompositeDataSource; - - nsISimpleEnumerator* mCurrent; - nsIRDFNode* mResult; - int32_t mNext; - AutoTArray, 8> mAlreadyReturned; - bool mAllowNegativeAssertions; - bool mCoalesceDuplicateArcs; -}; - - -CompositeEnumeratorImpl::CompositeEnumeratorImpl(CompositeDataSourceImpl* aCompositeDataSource, - bool aAllowNegativeAssertions, - bool aCoalesceDuplicateArcs) - : mCompositeDataSource(aCompositeDataSource), - mCurrent(nullptr), - mResult(nullptr), - mNext(0), - mAllowNegativeAssertions(aAllowNegativeAssertions), - mCoalesceDuplicateArcs(aCoalesceDuplicateArcs) -{ - NS_ADDREF(mCompositeDataSource); -} - - -CompositeEnumeratorImpl::~CompositeEnumeratorImpl(void) -{ - NS_IF_RELEASE(mCurrent); - NS_IF_RELEASE(mResult); - NS_RELEASE(mCompositeDataSource); -} - -NS_IMPL_ADDREF(CompositeEnumeratorImpl) -NS_IMPL_RELEASE(CompositeEnumeratorImpl) -NS_IMPL_QUERY_INTERFACE(CompositeEnumeratorImpl, nsISimpleEnumerator) - -NS_IMETHODIMP -CompositeEnumeratorImpl::HasMoreElements(bool* aResult) -{ - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - nsresult rv; - - // If we've already queued up a next target, then yep, there are - // more elements. - if (mResult) { - *aResult = true; - return NS_OK; - } - - // Otherwise, we'll need to find a next target, switching cursors - // if necessary. - for ( ; mNext < mCompositeDataSource->mDataSources.Count(); ++mNext) { - if (! mCurrent) { - // We don't have a current enumerator, so create a new one on - // the next data source. - nsIRDFDataSource* datasource = - mCompositeDataSource->mDataSources[mNext]; - - rv = GetEnumerator(datasource, &mCurrent); - if (NS_FAILED(rv)) return rv; - if (rv == NS_RDF_NO_VALUE) - continue; - - NS_ASSERTION(mCurrent != nullptr, "you're always supposed to return an enumerator from GetEnumerator, punk."); - if (! mCurrent) - continue; - } - - do { - int32_t i; - - bool hasMore; - rv = mCurrent->HasMoreElements(&hasMore); - if (NS_FAILED(rv)) return rv; - - // Is the current enumerator depleted? - if (! hasMore) { - NS_RELEASE(mCurrent); - break; - } - - // Even if the current enumerator has more elements, we still - // need to check that the current element isn't masked by - // a negation in an earlier data source. - - // "Peek" ahead and pull out the next target. - nsCOMPtr result; - rv = mCurrent->GetNext(getter_AddRefs(result)); - if (NS_FAILED(rv)) return rv; - - rv = result->QueryInterface(NS_GET_IID(nsIRDFNode), (void**) &mResult); - if (NS_FAILED(rv)) return rv; - - if (mAllowNegativeAssertions) - { - // See if any previous data source negates this - bool hasNegation = false; - for (i = mNext - 1; i >= 0; --i) - { - nsIRDFDataSource* datasource = - mCompositeDataSource->mDataSources[i]; - - rv = HasNegation(datasource, mResult, &hasNegation); - if (NS_FAILED(rv)) return rv; - - if (hasNegation) - break; - } - - // if so, we've gotta keep looking - if (hasNegation) - { - NS_RELEASE(mResult); - continue; - } - } - - if (mCoalesceDuplicateArcs) - { - // Now see if we've returned it once already. - // XXX N.B. performance here...may want to hash if things get large? - bool alreadyReturned = false; - for (i = mAlreadyReturned.Length() - 1; i >= 0; --i) - { - if (mAlreadyReturned[i] == mResult) - { - alreadyReturned = true; - break; - } - } - if (alreadyReturned) - { - NS_RELEASE(mResult); - continue; - } - } - - // If we get here, then we've really found one. It'll - // remain cached in mResult until GetNext() sucks it out. - *aResult = true; - - // Remember that we returned it, so we don't return duplicates. - - // XXX I wonder if we should make unique-checking be - // optional. This could get to be pretty expensive (this - // implementation turns iteration into O(n^2)). - - if (mCoalesceDuplicateArcs) - { - mAlreadyReturned.AppendElement(mResult); - } - - return NS_OK; - } while (1); - } - - // if we get here, there aren't any elements left. - *aResult = false; - return NS_OK; -} - - -NS_IMETHODIMP -CompositeEnumeratorImpl::GetNext(nsISupports** aResult) -{ - nsresult rv; - - bool hasMore; - rv = HasMoreElements(&hasMore); - if (NS_FAILED(rv)) return rv; - - if (! hasMore) - return NS_ERROR_UNEXPECTED; - - // Don't AddRef: we "transfer" ownership to the caller - *aResult = mResult; - mResult = nullptr; - - return NS_OK; -} - -//---------------------------------------------------------------------- -// -// CompositeArcsInOutEnumeratorImpl -// -// - -class CompositeArcsInOutEnumeratorImpl : public CompositeEnumeratorImpl -{ -public: - enum Type { eArcsIn, eArcsOut }; - - virtual ~CompositeArcsInOutEnumeratorImpl(); - - virtual nsresult - GetEnumerator(nsIRDFDataSource* aDataSource, nsISimpleEnumerator** aResult) override; - - virtual nsresult - HasNegation(nsIRDFDataSource* aDataSource, nsIRDFNode* aNode, bool* aResult) override; - - CompositeArcsInOutEnumeratorImpl(CompositeDataSourceImpl* aCompositeDataSource, - nsIRDFNode* aNode, - Type aType, - bool aAllowNegativeAssertions, - bool aCoalesceDuplicateArcs); - -private: - nsIRDFNode* mNode; - Type mType; -}; - - -CompositeArcsInOutEnumeratorImpl::CompositeArcsInOutEnumeratorImpl( - CompositeDataSourceImpl* aCompositeDataSource, - nsIRDFNode* aNode, - Type aType, - bool aAllowNegativeAssertions, - bool aCoalesceDuplicateArcs) - : CompositeEnumeratorImpl(aCompositeDataSource, aAllowNegativeAssertions, aCoalesceDuplicateArcs), - mNode(aNode), - mType(aType) -{ - NS_ADDREF(mNode); -} - -CompositeArcsInOutEnumeratorImpl::~CompositeArcsInOutEnumeratorImpl() -{ - NS_RELEASE(mNode); -} - - -nsresult -CompositeArcsInOutEnumeratorImpl::GetEnumerator( - nsIRDFDataSource* aDataSource, - nsISimpleEnumerator** aResult) -{ - if (mType == eArcsIn) { - return aDataSource->ArcLabelsIn(mNode, aResult); - } - else { - nsCOMPtr resource( do_QueryInterface(mNode) ); - return aDataSource->ArcLabelsOut(resource, aResult); - } -} - -nsresult -CompositeArcsInOutEnumeratorImpl::HasNegation( - nsIRDFDataSource* aDataSource, - nsIRDFNode* aNode, - bool* aResult) -{ - *aResult = false; - return NS_OK; -} - - -//---------------------------------------------------------------------- -// -// CompositeAssertionEnumeratorImpl -// - -class CompositeAssertionEnumeratorImpl : public CompositeEnumeratorImpl -{ -public: - virtual nsresult - GetEnumerator(nsIRDFDataSource* aDataSource, nsISimpleEnumerator** aResult) override; - - virtual nsresult - HasNegation(nsIRDFDataSource* aDataSource, nsIRDFNode* aNode, bool* aResult) override; - - CompositeAssertionEnumeratorImpl(CompositeDataSourceImpl* aCompositeDataSource, - nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue, - bool aAllowNegativeAssertions, - bool aCoalesceDuplicateArcs); - - virtual ~CompositeAssertionEnumeratorImpl(); - -private: - nsIRDFResource* mSource; - nsIRDFResource* mProperty; - nsIRDFNode* mTarget; - bool mTruthValue; -}; - - -CompositeAssertionEnumeratorImpl::CompositeAssertionEnumeratorImpl( - CompositeDataSourceImpl* aCompositeDataSource, - nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue, - bool aAllowNegativeAssertions, - bool aCoalesceDuplicateArcs) - : CompositeEnumeratorImpl(aCompositeDataSource, aAllowNegativeAssertions, aCoalesceDuplicateArcs), - mSource(aSource), - mProperty(aProperty), - mTarget(aTarget), - mTruthValue(aTruthValue) -{ - NS_IF_ADDREF(mSource); - NS_ADDREF(mProperty); // always must be specified - NS_IF_ADDREF(mTarget); -} - -CompositeAssertionEnumeratorImpl::~CompositeAssertionEnumeratorImpl() -{ - NS_IF_RELEASE(mSource); - NS_RELEASE(mProperty); - NS_IF_RELEASE(mTarget); -} - - -nsresult -CompositeAssertionEnumeratorImpl::GetEnumerator( - nsIRDFDataSource* aDataSource, - nsISimpleEnumerator** aResult) -{ - if (mSource) { - return aDataSource->GetTargets(mSource, mProperty, mTruthValue, aResult); - } - else { - return aDataSource->GetSources(mProperty, mTarget, mTruthValue, aResult); - } -} - -nsresult -CompositeAssertionEnumeratorImpl::HasNegation( - nsIRDFDataSource* aDataSource, - nsIRDFNode* aNode, - bool* aResult) -{ - if (mSource) { - return aDataSource->HasAssertion(mSource, mProperty, aNode, !mTruthValue, aResult); - } - else { - nsCOMPtr source( do_QueryInterface(aNode) ); - return aDataSource->HasAssertion(source, mProperty, mTarget, !mTruthValue, aResult); - } -} - -//////////////////////////////////////////////////////////////////////// - -nsresult -NS_NewRDFCompositeDataSource(nsIRDFCompositeDataSource** result) -{ - CompositeDataSourceImpl* db = new CompositeDataSourceImpl(); - if (! db) - return NS_ERROR_OUT_OF_MEMORY; - - *result = db; - NS_ADDREF(*result); - return NS_OK; -} - - -CompositeDataSourceImpl::CompositeDataSourceImpl(void) - : mAllowNegativeAssertions(true), - mCoalesceDuplicateArcs(true), - mUpdateBatchNest(0) -{ -} - -//---------------------------------------------------------------------- -// -// nsISupports interface -// - -NS_IMPL_CYCLE_COLLECTION_CLASS(CompositeDataSourceImpl) - -NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CompositeDataSourceImpl) - uint32_t i, count = tmp->mDataSources.Count(); - for (i = count; i > 0; --i) { - tmp->mDataSources[i - 1]->RemoveObserver(tmp); - tmp->mDataSources.RemoveObjectAt(i - 1); - } - NS_IMPL_CYCLE_COLLECTION_UNLINK(mObservers); -NS_IMPL_CYCLE_COLLECTION_UNLINK_END -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(CompositeDataSourceImpl) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mObservers) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDataSources) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END - - -NS_IMPL_CYCLE_COLLECTING_ADDREF(CompositeDataSourceImpl) -NS_IMPL_CYCLE_COLLECTING_RELEASE(CompositeDataSourceImpl) - -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CompositeDataSourceImpl) - NS_INTERFACE_MAP_ENTRY(nsIRDFCompositeDataSource) - NS_INTERFACE_MAP_ENTRY(nsIRDFDataSource) - NS_INTERFACE_MAP_ENTRY(nsIRDFObserver) - NS_INTERFACE_MAP_ENTRY(nsIRDFCompositeDataSource) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRDFCompositeDataSource) -NS_INTERFACE_MAP_END - - -//---------------------------------------------------------------------- -// -// nsIRDFDataSource interface -// - -NS_IMETHODIMP -CompositeDataSourceImpl::GetURI(nsACString& aURI) -{ - aURI.SetIsVoid(true); - return NS_OK; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::GetSource(nsIRDFResource* property, - nsIRDFNode* target, - bool tv, - nsIRDFResource** source) -{ - if (!mAllowNegativeAssertions && !tv) - return(NS_RDF_NO_VALUE); - - int32_t count = mDataSources.Count(); - for (int32_t i = 0; i < count; ++i) { - nsresult rv; - rv = mDataSources[i]->GetSource(property, target, tv, source); - if (NS_FAILED(rv)) return rv; - - if (rv == NS_RDF_NO_VALUE) - continue; - - if (!mAllowNegativeAssertions) return(NS_OK); - - // okay, found it. make sure we don't have the opposite - // asserted in a more local data source - if (!HasAssertionN(count-1, *source, property, target, !tv)) - return NS_OK; - - NS_RELEASE(*source); - return NS_RDF_NO_VALUE; - } - return NS_RDF_NO_VALUE; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::GetSources(nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue, - nsISimpleEnumerator** aResult) -{ - NS_PRECONDITION(aProperty != nullptr, "null ptr"); - if (! aProperty) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aTarget != nullptr, "null ptr"); - if (! aTarget) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - if (! mAllowNegativeAssertions && ! aTruthValue) - return(NS_RDF_NO_VALUE); - - *aResult = new CompositeAssertionEnumeratorImpl(this, nullptr, aProperty, - aTarget, aTruthValue, - mAllowNegativeAssertions, - mCoalesceDuplicateArcs); - - if (! *aResult) - return NS_ERROR_OUT_OF_MEMORY; - - NS_ADDREF(*aResult); - return NS_OK; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::GetTarget(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - bool aTruthValue, - nsIRDFNode** aResult) -{ - NS_PRECONDITION(aSource != nullptr, "null ptr"); - if (! aSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aProperty != nullptr, "null ptr"); - if (! aProperty) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - if (! mAllowNegativeAssertions && ! aTruthValue) - return(NS_RDF_NO_VALUE); - - int32_t count = mDataSources.Count(); - for (int32_t i = 0; i < count; ++i) { - nsresult rv; - rv = mDataSources[i]->GetTarget(aSource, aProperty, aTruthValue, - aResult); - if (NS_FAILED(rv)) - return rv; - - if (rv == NS_OK) { - // okay, found it. make sure we don't have the opposite - // asserted in an earlier data source - - if (mAllowNegativeAssertions) { - if (HasAssertionN(count-1, aSource, aProperty, *aResult, !aTruthValue)) { - // whoops, it's been negated. - NS_RELEASE(*aResult); - return NS_RDF_NO_VALUE; - } - } - return NS_OK; - } - } - - // Otherwise, we couldn't find it at all. - return NS_RDF_NO_VALUE; -} - -bool -CompositeDataSourceImpl::HasAssertionN(int n, - nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue) -{ - nsresult rv; - for (int32_t m = 0; m < n; ++m) { - bool result; - rv = mDataSources[m]->HasAssertion(aSource, aProperty, aTarget, - aTruthValue, &result); - if (NS_FAILED(rv)) - return false; - - // found it! - if (result) - return true; - } - return false; -} - - - -NS_IMETHODIMP -CompositeDataSourceImpl::GetTargets(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - bool aTruthValue, - nsISimpleEnumerator** aResult) -{ - NS_PRECONDITION(aSource != nullptr, "null ptr"); - if (! aSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aProperty != nullptr, "null ptr"); - if (! aProperty) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - if (! mAllowNegativeAssertions && ! aTruthValue) - return(NS_RDF_NO_VALUE); - - *aResult = - new CompositeAssertionEnumeratorImpl(this, - aSource, aProperty, nullptr, - aTruthValue, - mAllowNegativeAssertions, - mCoalesceDuplicateArcs); - - if (! *aResult) - return NS_ERROR_OUT_OF_MEMORY; - - NS_ADDREF(*aResult); - return NS_OK; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::Assert(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue) -{ - NS_PRECONDITION(aSource != nullptr, "null ptr"); - if (! aSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aProperty != nullptr, "null ptr"); - if (! aProperty) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aTarget != nullptr, "null ptr"); - if (! aTarget) - return NS_ERROR_NULL_POINTER; - - if (! mAllowNegativeAssertions && ! aTruthValue) - return(NS_RDF_ASSERTION_REJECTED); - - nsresult rv; - - // XXX Need to add back the stuff for unblocking ... - - // We iterate backwards from the last data source which was added - // ("the most remote") to the first ("the most local"), trying to - // apply the assertion in each. - for (int32_t i = mDataSources.Count() - 1; i >= 0; --i) { - rv = mDataSources[i]->Assert(aSource, aProperty, aTarget, aTruthValue); - if (NS_RDF_ASSERTION_ACCEPTED == rv) - return rv; - - if (NS_FAILED(rv)) - return rv; - } - - // nobody wanted to accept it - return NS_RDF_ASSERTION_REJECTED; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::Unassert(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget) -{ - NS_PRECONDITION(aSource != nullptr, "null ptr"); - if (! aSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aProperty != nullptr, "null ptr"); - if (! aProperty) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aTarget != nullptr, "null ptr"); - if (! aTarget) - return NS_ERROR_NULL_POINTER; - - nsresult rv; - - // Iterate through each of the datasources, starting with "the - // most local" and moving to "the most remote". If _any_ of the - // datasources have the assertion, attempt to unassert it. - bool unasserted = true; - int32_t i; - int32_t count = mDataSources.Count(); - for (i = 0; i < count; ++i) { - nsIRDFDataSource* ds = mDataSources[i]; - - bool hasAssertion; - rv = ds->HasAssertion(aSource, aProperty, aTarget, true, &hasAssertion); - if (NS_FAILED(rv)) return rv; - - if (hasAssertion) { - rv = ds->Unassert(aSource, aProperty, aTarget); - if (NS_FAILED(rv)) return rv; - - if (rv != NS_RDF_ASSERTION_ACCEPTED) { - unasserted = false; - break; - } - } - } - - // Either none of the datasources had it, or they were all willing - // to let it be unasserted. - if (unasserted) - return NS_RDF_ASSERTION_ACCEPTED; - - // If we get here, one of the datasources already had the - // assertion, and was adamant about not letting us remove - // it. Iterate from the "most local" to the "most remote" - // attempting to assert the negation... - for (i = 0; i < count; ++i) { - rv = mDataSources[i]->Assert(aSource, aProperty, aTarget, false); - if (NS_FAILED(rv)) return rv; - - // Did it take? - if (rv == NS_RDF_ASSERTION_ACCEPTED) - return rv; - } - - // Couln't get anyone to accept the negation, either. - return NS_RDF_ASSERTION_REJECTED; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::Change(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aOldTarget, - nsIRDFNode* aNewTarget) -{ - NS_PRECONDITION(aSource != nullptr, "null ptr"); - if (! aSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aProperty != nullptr, "null ptr"); - if (! aProperty) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aOldTarget != nullptr, "null ptr"); - if (! aOldTarget) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aNewTarget != nullptr, "null ptr"); - if (! aNewTarget) - return NS_ERROR_NULL_POINTER; - - nsresult rv; - - // XXX So we're assuming that a datasource _must_ accept the - // atomic change; i.e., we can't split it up across two - // datasources. That sucks. - - // We iterate backwards from the last data source which was added - // ("the most remote") to the first ("the most local"), trying to - // apply the change in each. - for (int32_t i = mDataSources.Count() - 1; i >= 0; --i) { - rv = mDataSources[i]->Change(aSource, aProperty, aOldTarget, aNewTarget); - if (NS_RDF_ASSERTION_ACCEPTED == rv) - return rv; - - if (NS_FAILED(rv)) - return rv; - } - - // nobody wanted to accept it - return NS_RDF_ASSERTION_REJECTED; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::Move(nsIRDFResource* aOldSource, - nsIRDFResource* aNewSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget) -{ - NS_PRECONDITION(aOldSource != nullptr, "null ptr"); - if (! aOldSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aNewSource != nullptr, "null ptr"); - if (! aNewSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aProperty != nullptr, "null ptr"); - if (! aProperty) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aTarget != nullptr, "null ptr"); - if (! aTarget) - return NS_ERROR_NULL_POINTER; - - nsresult rv; - - // XXX So we're assuming that a datasource _must_ accept the - // atomic move; i.e., we can't split it up across two - // datasources. That sucks. - - // We iterate backwards from the last data source which was added - // ("the most remote") to the first ("the most local"), trying to - // apply the assertion in each. - for (int32_t i = mDataSources.Count() - 1; i >= 0; --i) { - rv = mDataSources[i]->Move(aOldSource, aNewSource, aProperty, aTarget); - if (NS_RDF_ASSERTION_ACCEPTED == rv) - return rv; - - if (NS_FAILED(rv)) - return rv; - } - - // nobody wanted to accept it - return NS_RDF_ASSERTION_REJECTED; -} - - -NS_IMETHODIMP -CompositeDataSourceImpl::HasAssertion(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue, - bool* aResult) -{ - NS_PRECONDITION(aSource != nullptr, "null ptr"); - if (! aSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aProperty != nullptr, "null ptr"); - if (! aProperty) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - if (! mAllowNegativeAssertions && ! aTruthValue) - { - *aResult = false; - return(NS_OK); - } - - nsresult rv; - - // Otherwise, look through all the data sources to see if anyone - // has the positive... - int32_t count = mDataSources.Count(); - for (int32_t i = 0; i < count; ++i) { - nsIRDFDataSource* datasource = mDataSources[i]; - rv = datasource->HasAssertion(aSource, aProperty, aTarget, aTruthValue, aResult); - if (NS_FAILED(rv)) return rv; - - if (*aResult) - return NS_OK; - - if (mAllowNegativeAssertions) - { - bool hasNegation; - rv = datasource->HasAssertion(aSource, aProperty, aTarget, !aTruthValue, &hasNegation); - if (NS_FAILED(rv)) return rv; - - if (hasNegation) - { - *aResult = false; - return NS_OK; - } - } - } - - // If we get here, nobody had the assertion at all - *aResult = false; - return NS_OK; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::AddObserver(nsIRDFObserver* aObserver) -{ - NS_PRECONDITION(aObserver != nullptr, "null ptr"); - if (! aObserver) - return NS_ERROR_NULL_POINTER; - - // XXX ensure uniqueness? - mObservers.AppendObject(aObserver); - - return NS_OK; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::RemoveObserver(nsIRDFObserver* aObserver) -{ - NS_PRECONDITION(aObserver != nullptr, "null ptr"); - if (! aObserver) - return NS_ERROR_NULL_POINTER; - - mObservers.RemoveObject(aObserver); - - return NS_OK; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::HasArcIn(nsIRDFNode *aNode, nsIRDFResource *aArc, bool *result) -{ - nsresult rv; - *result = false; - int32_t count = mDataSources.Count(); - for (int32_t i = 0; i < count; ++i) { - rv = mDataSources[i]->HasArcIn(aNode, aArc, result); - if (NS_FAILED(rv)) return rv; - if (*result) - return NS_OK; - } - return NS_OK; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::HasArcOut(nsIRDFResource *aSource, nsIRDFResource *aArc, bool *result) -{ - nsresult rv; - *result = false; - int32_t count = mDataSources.Count(); - for (int32_t i = 0; i < count; ++i) { - rv = mDataSources[i]->HasArcOut(aSource, aArc, result); - if (NS_FAILED(rv)) return rv; - if (*result) - return NS_OK; - } - return NS_OK; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::ArcLabelsIn(nsIRDFNode* aTarget, nsISimpleEnumerator** aResult) -{ - NS_PRECONDITION(aTarget != nullptr, "null ptr"); - if (! aTarget) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - nsISimpleEnumerator* result = - new CompositeArcsInOutEnumeratorImpl(this, aTarget, - CompositeArcsInOutEnumeratorImpl::eArcsIn, - mAllowNegativeAssertions, - mCoalesceDuplicateArcs); - - if (! result) - return NS_ERROR_OUT_OF_MEMORY; - - NS_ADDREF(result); - *aResult = result; - return NS_OK; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::ArcLabelsOut(nsIRDFResource* aSource, - nsISimpleEnumerator** aResult) -{ - NS_PRECONDITION(aSource != nullptr, "null ptr"); - if (! aSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - nsISimpleEnumerator* result = - new CompositeArcsInOutEnumeratorImpl(this, aSource, - CompositeArcsInOutEnumeratorImpl::eArcsOut, - mAllowNegativeAssertions, - mCoalesceDuplicateArcs); - - if (! result) - return NS_ERROR_OUT_OF_MEMORY; - - NS_ADDREF(result); - *aResult = result; - return NS_OK; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::GetAllResources(nsISimpleEnumerator** aResult) -{ - MOZ_ASSERT_UNREACHABLE("CompositeDataSourceImpl::GetAllResources"); - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::GetAllCmds(nsIRDFResource* source, - nsISimpleEnumerator/**/** result) -{ - nsresult rv; - nsCOMPtr set; - - for (int32_t i = 0; i < mDataSources.Count(); i++) - { - nsCOMPtr dsCmds; - - rv = mDataSources[i]->GetAllCmds(source, getter_AddRefs(dsCmds)); - if (NS_SUCCEEDED(rv)) - { - nsCOMPtr tmp; - rv = NS_NewUnionEnumerator(getter_AddRefs(tmp), set, dsCmds); - set.swap(tmp); - if (NS_FAILED(rv)) return(rv); - } - } - - set.forget(result); - return NS_OK; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::IsCommandEnabled(nsISupports/* nsIRDFResource container */* aSources, - nsIRDFResource* aCommand, - nsISupports/* nsIRDFResource container */* aArguments, - bool* aResult) -{ - nsresult rv; - for (int32_t i = mDataSources.Count() - 1; i >= 0; --i) { - bool enabled = true; - rv = mDataSources[i]->IsCommandEnabled(aSources, aCommand, aArguments, &enabled); - if (NS_FAILED(rv) && (rv != NS_ERROR_NOT_IMPLEMENTED)) - { - return(rv); - } - - if (! enabled) { - *aResult = false; - return(NS_OK); - } - } - *aResult = true; - return(NS_OK); -} - -NS_IMETHODIMP -CompositeDataSourceImpl::DoCommand(nsISupports/* nsIRDFResource container */* aSources, - nsIRDFResource* aCommand, - nsISupports/* nsIRDFResource container */* aArguments) -{ - for (int32_t i = mDataSources.Count() - 1; i >= 0; --i) { - nsresult rv = mDataSources[i]->DoCommand(aSources, aCommand, aArguments); - if (NS_FAILED(rv) && (rv != NS_ERROR_NOT_IMPLEMENTED)) - { - return(rv); // all datasources must succeed - } - } - return(NS_OK); -} - -NS_IMETHODIMP -CompositeDataSourceImpl::BeginUpdateBatch() -{ - for (int32_t i = mDataSources.Count() - 1; i >= 0; --i) { - mDataSources[i]->BeginUpdateBatch(); - } - return NS_OK; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::EndUpdateBatch() -{ - for (int32_t i = mDataSources.Count() - 1; i >= 0; --i) { - mDataSources[i]->EndUpdateBatch(); - } - return NS_OK; -} - -//////////////////////////////////////////////////////////////////////// -// nsIRDFCompositeDataSource methods -// XXX rvg We should make this take an additional argument specifying where -// in the sequence of data sources (of the db), the new data source should -// fit in. Right now, the new datasource gets stuck at the end. -// need to add the observers of the CompositeDataSourceImpl to the new data source. - -NS_IMETHODIMP -CompositeDataSourceImpl::GetAllowNegativeAssertions(bool *aAllowNegativeAssertions) -{ - *aAllowNegativeAssertions = mAllowNegativeAssertions; - return(NS_OK); -} - -NS_IMETHODIMP -CompositeDataSourceImpl::SetAllowNegativeAssertions(bool aAllowNegativeAssertions) -{ - mAllowNegativeAssertions = aAllowNegativeAssertions; - return(NS_OK); -} - -NS_IMETHODIMP -CompositeDataSourceImpl::GetCoalesceDuplicateArcs(bool *aCoalesceDuplicateArcs) -{ - *aCoalesceDuplicateArcs = mCoalesceDuplicateArcs; - return(NS_OK); -} - -NS_IMETHODIMP -CompositeDataSourceImpl::SetCoalesceDuplicateArcs(bool aCoalesceDuplicateArcs) -{ - mCoalesceDuplicateArcs = aCoalesceDuplicateArcs; - return(NS_OK); -} - -NS_IMETHODIMP -CompositeDataSourceImpl::AddDataSource(nsIRDFDataSource* aDataSource) -{ - NS_ASSERTION(aDataSource != nullptr, "null ptr"); - if (! aDataSource) - return NS_ERROR_NULL_POINTER; - - mDataSources.AppendObject(aDataSource); - aDataSource->AddObserver(this); - return NS_OK; -} - - - -NS_IMETHODIMP -CompositeDataSourceImpl::RemoveDataSource(nsIRDFDataSource* aDataSource) -{ - NS_ASSERTION(aDataSource != nullptr, "null ptr"); - if (! aDataSource) - return NS_ERROR_NULL_POINTER; - - - if (mDataSources.IndexOf(aDataSource) >= 0) { - aDataSource->RemoveObserver(this); - mDataSources.RemoveObject(aDataSource); - } - return NS_OK; -} - - -NS_IMETHODIMP -CompositeDataSourceImpl::GetDataSources(nsISimpleEnumerator** _result) -{ - // NS_NewArrayEnumerator for an nsCOMArray takes a snapshot of the - // current state. - return NS_NewArrayEnumerator(_result, mDataSources); -} - -NS_IMETHODIMP -CompositeDataSourceImpl::OnAssert(nsIRDFDataSource* aDataSource, - nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget) -{ - // Make sure that the assertion isn't masked by another - // datasource. - // - // XXX We could make this more efficient if we knew _which_ - // datasource actually served up the OnAssert(): we could use - // HasAssertionN() to only search datasources _before_ the - // datasource that coughed up the assertion. - nsresult rv = NS_OK; - - if (mAllowNegativeAssertions) - { - bool hasAssertion; - rv = HasAssertion(aSource, aProperty, aTarget, true, &hasAssertion); - if (NS_FAILED(rv)) return rv; - - if (! hasAssertion) - return(NS_OK); - } - - for (int32_t i = mObservers.Count() - 1; i >= 0; --i) { - mObservers[i]->OnAssert(this, aSource, aProperty, aTarget); - } - return NS_OK; -} - -NS_IMETHODIMP -CompositeDataSourceImpl::OnUnassert(nsIRDFDataSource* aDataSource, - nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget) -{ - // Make sure that the un-assertion doesn't just unmask the - // same assertion in a different datasource. - // - // XXX We could make this more efficient if we knew _which_ - // datasource actually served up the OnAssert(): we could use - // HasAssertionN() to only search datasources _before_ the - // datasource that coughed up the assertion. - nsresult rv; - - if (mAllowNegativeAssertions) - { - bool hasAssertion; - rv = HasAssertion(aSource, aProperty, aTarget, true, &hasAssertion); - if (NS_FAILED(rv)) return rv; - - if (hasAssertion) - return NS_OK; - } - - for (int32_t i = mObservers.Count() - 1; i >= 0; --i) { - mObservers[i]->OnUnassert(this, aSource, aProperty, aTarget); - } - return NS_OK; -} - - -NS_IMETHODIMP -CompositeDataSourceImpl::OnChange(nsIRDFDataSource* aDataSource, - nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aOldTarget, - nsIRDFNode* aNewTarget) -{ - // Make sure that the change is actually visible, and not hidden - // by an assertion in a different datasource. - // - // XXX Because of aggregation, this could actually mutate into a - // variety of OnAssert or OnChange notifications, which we'll - // ignore for now :-/. - for (int32_t i = mObservers.Count() - 1; i >= 0; --i) { - mObservers[i]->OnChange(this, aSource, aProperty, - aOldTarget, aNewTarget); - } - return NS_OK; -} - - -NS_IMETHODIMP -CompositeDataSourceImpl::OnMove(nsIRDFDataSource* aDataSource, - nsIRDFResource* aOldSource, - nsIRDFResource* aNewSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget) -{ - // Make sure that the move is actually visible, and not hidden - // by an assertion in a different datasource. - // - // XXX Because of aggregation, this could actually mutate into a - // variety of OnAssert or OnMove notifications, which we'll - // ignore for now :-/. - for (int32_t i = mObservers.Count() - 1; i >= 0; --i) { - mObservers[i]->OnMove(this, aOldSource, aNewSource, - aProperty, aTarget); - } - return NS_OK; -} - - -NS_IMETHODIMP -CompositeDataSourceImpl::OnBeginUpdateBatch(nsIRDFDataSource* aDataSource) -{ - if (mUpdateBatchNest++ == 0) { - for (int32_t i = mObservers.Count() - 1; i >= 0; --i) { - mObservers[i]->OnBeginUpdateBatch(this); - } - } - return NS_OK; -} - - -NS_IMETHODIMP -CompositeDataSourceImpl::OnEndUpdateBatch(nsIRDFDataSource* aDataSource) -{ - NS_ASSERTION(mUpdateBatchNest > 0, "badly nested update batch"); - if (--mUpdateBatchNest == 0) { - for (int32_t i = mObservers.Count() - 1; i >= 0; --i) { - mObservers[i]->OnEndUpdateBatch(this); - } - } - return NS_OK; -} diff --git a/rdf/base/nsContainerEnumerator.cpp b/rdf/base/nsContainerEnumerator.cpp deleted file mode 100644 index 19700a9e1c0a..000000000000 --- a/rdf/base/nsContainerEnumerator.cpp +++ /dev/null @@ -1,262 +0,0 @@ -/* -*- 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/. */ - -/* - - A simple cursor that enumerates the elements of an RDF container - (RDF:Bag, RDF:Seq, or RDF:Alt). - - Caveats - ------- - - 1. This uses an implementation-specific detail to determine the - index of the last element in the container; specifically, the RDF - utilities maintain a counter attribute on the container that - holds the numeric value of the next value that is to be - assigned. So, this cursor will bust if you use it with a bag that - hasn't been created using the RDF utility routines. - - */ - -#include "nscore.h" -#include "nsCOMPtr.h" -#include "nsIRDFContainerUtils.h" -#include "nsIRDFDataSource.h" -#include "nsIRDFNode.h" -#include "nsIRDFService.h" -#include "nsIServiceManager.h" -#include "nsRDFCID.h" -#include "nsString.h" -#include "mozilla/Logging.h" -#include "rdf.h" -#include "rdfutil.h" - -//////////////////////////////////////////////////////////////////////// - -class ContainerEnumeratorImpl : public nsISimpleEnumerator { -private: - // pseudo-constants - static nsrefcnt gRefCnt; - static nsIRDFResource* kRDF_nextVal; - static nsIRDFContainerUtils* gRDFC; - - nsCOMPtr mDataSource; - nsCOMPtr mContainer; - nsCOMPtr mOrdinalProperty; - - nsCOMPtr mCurrent; - nsCOMPtr mResult; - int32_t mNextIndex; - - virtual ~ContainerEnumeratorImpl(); - -public: - ContainerEnumeratorImpl(nsIRDFDataSource* ds, nsIRDFResource* container); - - nsresult Init(); - - NS_DECL_ISUPPORTS - NS_DECL_NSISIMPLEENUMERATOR -}; - -nsrefcnt ContainerEnumeratorImpl::gRefCnt; -nsIRDFResource* ContainerEnumeratorImpl::kRDF_nextVal; -nsIRDFContainerUtils* ContainerEnumeratorImpl::gRDFC; - - -ContainerEnumeratorImpl::ContainerEnumeratorImpl(nsIRDFDataSource* aDataSource, - nsIRDFResource* aContainer) - : mDataSource(aDataSource), - mContainer(aContainer), - mNextIndex(1) -{ -} - -nsresult -ContainerEnumeratorImpl::Init() -{ - if (gRefCnt++ == 0) { - nsresult rv; - - NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); - nsCOMPtr rdf = do_GetService(kRDFServiceCID); - NS_ASSERTION(rdf != nullptr, "unable to acquire resource manager"); - if (! rdf) - return NS_ERROR_FAILURE; - - rv = rdf->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "nextVal"), &kRDF_nextVal); - NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get resource"); - if (NS_FAILED(rv)) return rv; - - NS_DEFINE_CID(kRDFContainerUtilsCID, NS_RDFCONTAINERUTILS_CID); - rv = CallGetService(kRDFContainerUtilsCID, &gRDFC); - if (NS_FAILED(rv)) return rv; - } - - return NS_OK; -} - - -ContainerEnumeratorImpl::~ContainerEnumeratorImpl() -{ - if (--gRefCnt == 0) { - NS_IF_RELEASE(kRDF_nextVal); - NS_IF_RELEASE(gRDFC); - } -} - -NS_IMPL_ISUPPORTS(ContainerEnumeratorImpl, nsISimpleEnumerator) - - -NS_IMETHODIMP -ContainerEnumeratorImpl::HasMoreElements(bool* aResult) -{ - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - nsresult rv; - - // If we've already queued up a next value, then we know there are more elements. - if (mResult) { - *aResult = true; - return NS_OK; - } - - // Otherwise, we need to grovel - - // Figure out the upper bound so we'll know when we're done. Since it's - // possible that we're targeting a composite datasource, we'll need to - // "GetTargets()" and take the maximum value of "nextVal" to know the - // upper bound. - // - // Remember that since nextVal is the next index that we'd assign - // to an element in a container, it's *one more* than count of - // elements in the container. - int32_t max = 0; - - nsCOMPtr targets; - rv = mDataSource->GetTargets(mContainer, kRDF_nextVal, true, getter_AddRefs(targets)); - if (NS_FAILED(rv)) return rv; - - while (1) { - bool hasmore; - targets->HasMoreElements(&hasmore); - if (! hasmore) - break; - - nsCOMPtr isupports; - targets->GetNext(getter_AddRefs(isupports)); - - nsCOMPtr nextValLiteral = do_QueryInterface(isupports); - if (! nextValLiteral) - continue; - - const char16_t *nextValStr; - nextValLiteral->GetValueConst(&nextValStr); - - nsresult err; - int32_t nextVal = nsAutoString(nextValStr).ToInteger(&err); - - if (nextVal > max) - max = nextVal; - } - - // Now pre-fetch our next value into mResult. - while (mCurrent || mNextIndex < max) { - - // If mCurrent has been depleted, then conjure up a new one - if (! mCurrent) { - rv = gRDFC->IndexToOrdinalResource(mNextIndex, getter_AddRefs(mOrdinalProperty)); - if (NS_FAILED(rv)) return rv; - - rv = mDataSource->GetTargets(mContainer, mOrdinalProperty, true, getter_AddRefs(mCurrent)); - if (NS_FAILED(rv)) return rv; - - ++mNextIndex; - } - - if (mCurrent) { - bool hasMore; - rv = mCurrent->HasMoreElements(&hasMore); - if (NS_FAILED(rv)) return rv; - - // Is the current enumerator depleted? If so, iterate to - // the next index. - if (! hasMore) { - mCurrent = nullptr; - continue; - } - - // "Peek" ahead and pull out the next target. - nsCOMPtr result; - rv = mCurrent->GetNext(getter_AddRefs(result)); - if (NS_FAILED(rv)) return rv; - - mResult = do_QueryInterface(result, &rv); - if (NS_FAILED(rv)) return rv; - - *aResult = true; - return NS_OK; - } - } - - // If we get here, we ran out of elements. The cursor is empty. - *aResult = false; - return NS_OK; -} - - -NS_IMETHODIMP -ContainerEnumeratorImpl::GetNext(nsISupports** aResult) -{ - nsresult rv; - - bool hasMore; - rv = HasMoreElements(&hasMore); - if (NS_FAILED(rv)) return rv; - - if (! hasMore) - return NS_ERROR_UNEXPECTED; - - NS_ADDREF(*aResult = mResult); - mResult = nullptr; - - return NS_OK; -} - - -//////////////////////////////////////////////////////////////////////// - -nsresult -NS_NewContainerEnumerator(nsIRDFDataSource* aDataSource, - nsIRDFResource* aContainer, - nsISimpleEnumerator** aResult) -{ - NS_PRECONDITION(aDataSource != nullptr, "null ptr"); - if (! aDataSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aContainer != nullptr, "null ptr"); - if (! aContainer) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - ContainerEnumeratorImpl* result = new ContainerEnumeratorImpl(aDataSource, aContainer); - if (! result) - return NS_ERROR_OUT_OF_MEMORY; - - NS_ADDREF(result); - - nsresult rv = result->Init(); - if (NS_FAILED(rv)) - NS_RELEASE(result); - - *aResult = result; - return rv; -} diff --git a/rdf/base/nsDefaultResourceFactory.cpp b/rdf/base/nsDefaultResourceFactory.cpp deleted file mode 100644 index 448822a9d96a..000000000000 --- a/rdf/base/nsDefaultResourceFactory.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- 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/. */ - -/* - - The default resource factory implementation. This resource factory - produces nsIRDFResource objects for any URI prefix that is not - covered by some other factory. - - */ - -#include "nsRDFResource.h" - -nsresult -NS_NewDefaultResource(nsIRDFResource** aResult) -{ - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - nsRDFResource* resource = new nsRDFResource(); - if (! resource) - return NS_ERROR_OUT_OF_MEMORY; - - NS_ADDREF(resource); - *aResult = resource; - return NS_OK; -} diff --git a/rdf/base/nsIRDFCompositeDataSource.idl b/rdf/base/nsIRDFCompositeDataSource.idl deleted file mode 100644 index 071b8f3ace44..000000000000 --- a/rdf/base/nsIRDFCompositeDataSource.idl +++ /dev/null @@ -1,68 +0,0 @@ -/* -*- 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/. */ - -#include "nsIRDFDataSource.idl" - -interface nsISimpleEnumerator; - -/** - * An nsIRDFCompositeDataSource composes individual data sources, providing - * the illusion of a single, coherent RDF graph. - */ -[scriptable, uuid(96343820-307C-11D2-BC15-00805F912FE7)] -interface nsIRDFCompositeDataSource : nsIRDFDataSource { - - /** - * - * Set this value to true if the composite datasource - * may contains at least one datasource that has negative - * assertions. (This is the default.) - * - * Set this value to false if none of the datasources - * being composed contains a negative assertion. This allows the - * composite datasource to perform some query optimizations. - * - * By default, this value is true. - */ - attribute boolean allowNegativeAssertions; - - /** - * Set to true if the composite datasource should - * take care to coalesce duplicate arcs when returning values from - * queries. (This is the default.) - * - * Set to false if the composite datasource shouldn't - * bother to check for duplicates. This allows the composite - * datasource to more efficiently answer queries. - * - * By default, this value is true. - */ - attribute boolean coalesceDuplicateArcs; - - /** - * Add a datasource the the composite data source. - * @param aDataSource the datasource to add to composite - */ - void AddDataSource(in nsIRDFDataSource aDataSource); - - /** - * Remove a datasource from the composite data source. - * @param aDataSource the datasource to remove from the composite - */ - void RemoveDataSource(in nsIRDFDataSource aDataSource); - - /** - * Retrieve the datasources in the composite data source. - * @return an nsISimpleEnumerator that will enumerate each - * of the datasources in the composite - */ - nsISimpleEnumerator GetDataSources(); -}; - -%{C++ -extern nsresult -NS_NewRDFCompositeDataSource(nsIRDFCompositeDataSource** result); -%} - diff --git a/rdf/base/nsIRDFContainer.idl b/rdf/base/nsIRDFContainer.idl deleted file mode 100644 index 78352b2b3c88..000000000000 --- a/rdf/base/nsIRDFContainer.idl +++ /dev/null @@ -1,94 +0,0 @@ -/* -*- 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/. */ - -#include "nsISupports.idl" -#include "nsIRDFDataSource.idl" -#include "nsIRDFResource.idl" -#include "nsIRDFNode.idl" -#include "nsISimpleEnumerator.idl" - -// A wrapper for manipulating RDF containers -[scriptable, uuid(D4214E90-FB94-11D2-BDD8-00104BDE6048)] -interface nsIRDFContainer : nsISupports { - readonly attribute nsIRDFDataSource DataSource; - readonly attribute nsIRDFResource Resource; - - /** - * Initialize the container wrapper to the specified resource - * using the specified datasource for context. - */ - void Init(in nsIRDFDataSource aDataSource, in nsIRDFResource aContainer); - - /** - * Return the number of elements in the container. Note that this - * may not always be accurate due to aggregation. - */ - long GetCount(); - - /** - * Return an enumerator that can be used to enumerate the contents - * of the container in ascending order. - */ - nsISimpleEnumerator GetElements(); - - /** - * Append an element to the container, assigning it the next - * available ordinal. - */ - void AppendElement(in nsIRDFNode aElement); - - /** - * Remove the first occurence of the specified element from the - * container. If aRenumber is 'true', then the underlying RDF graph - * will be 're-numbered' to account for the removal. - */ - void RemoveElement(in nsIRDFNode aElement, in boolean aRenumber); - - /** - * Insert aElement at the specified index. If aRenumber is 'true', then - * the underlying RDF graph will be 're-numbered' to accomodate the new - * element. - */ - void InsertElementAt(in nsIRDFNode aElement, in long aIndex, in boolean aRenumber); - - /** - * Remove the element at the specified index. If aRenumber is 'true', then - * the underlying RDF graph will be 're-numbered' to account for the - * removal. - * - * @return the element that was removed. - */ - nsIRDFNode RemoveElementAt(in long aIndex, in boolean aRenumber); - - /** - * Determine the index of an element in the container. - * - * @return The index of the specified element in the container. If - * the element is not contained in the container, this function - * returns '-1'. - */ - long IndexOf(in nsIRDFNode aElement); -}; - -%{C++ -nsresult -NS_NewRDFContainer(nsIRDFContainer** aResult); - -nsresult -NS_NewRDFContainer(nsIRDFDataSource* aDataSource, - nsIRDFResource* aResource, - nsIRDFContainer** aResult); - -/** - * Create a cursor on a container that enumerates its contents in - * order - */ -nsresult -NS_NewContainerEnumerator(nsIRDFDataSource* aDataSource, - nsIRDFResource* aContainer, - nsISimpleEnumerator** aResult); - - -%} diff --git a/rdf/base/nsIRDFContainerUtils.idl b/rdf/base/nsIRDFContainerUtils.idl deleted file mode 100644 index 21cb0b625f5f..000000000000 --- a/rdf/base/nsIRDFContainerUtils.idl +++ /dev/null @@ -1,82 +0,0 @@ -/* -*- 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/. */ - -#include "nsISupports.idl" -#include "nsIRDFContainer.idl" -#include "nsIRDFResource.idl" - - -// Container utilities -[scriptable, uuid(D4214E91-FB94-11D2-BDD8-00104BDE6048)] -interface nsIRDFContainerUtils : nsISupports { - /** - * Returns 'true' if the property is an RDF ordinal property. - */ - boolean IsOrdinalProperty(in nsIRDFResource aProperty); - - /** - * Convert the specified index to an ordinal property. - */ - nsIRDFResource IndexToOrdinalResource(in long aIndex); - - /** - * Convert the specified ordinal property into an index - */ - long OrdinalResourceToIndex(in nsIRDFResource aOrdinal); - - /** - * Return 'true' if the specified resource is a container - */ - boolean IsContainer(in nsIRDFDataSource aDataSource, in nsIRDFResource aResource); - - /** - * Return 'true' if the specified resource is a container and it is empty - */ - boolean IsEmpty(in nsIRDFDataSource aDataSource, in nsIRDFResource aResource); - - /** - * Return 'true' if the specified resource is a bag - */ - boolean IsBag(in nsIRDFDataSource aDataSource, in nsIRDFResource aResource); - - /** - * Return 'true' if the specified resource is a sequence - */ - boolean IsSeq(in nsIRDFDataSource aDataSource, in nsIRDFResource aResource); - - /** - * Return 'true' if the specified resource is an alternation - */ - boolean IsAlt(in nsIRDFDataSource aDataSource, in nsIRDFResource aResource); - - /** - * Decorates the specified resource appropriately to make it - * usable as an empty bag in the specified data source. - */ - nsIRDFContainer MakeBag(in nsIRDFDataSource aDataSource, in nsIRDFResource aResource); - - /** - * Decorates the specified resource appropriately to make it - * usable as an empty sequence in the specified data source. - */ - nsIRDFContainer MakeSeq(in nsIRDFDataSource aDataSource, in nsIRDFResource aResource); - - /** - * Decorates the specified resource appropriately to make it - * usable as an empty alternation in the specified data source. - */ - nsIRDFContainer MakeAlt(in nsIRDFDataSource aDataSource, in nsIRDFResource aResource); - - /** - * Retrieve the index of element in the container. Returns -1 if - * the element is not in the container. - */ - long indexOf(in nsIRDFDataSource aDataSource, in nsIRDFResource aContainer, in nsIRDFNode aElement); -}; - -%{C++ -extern nsresult -NS_NewRDFContainerUtils(nsIRDFContainerUtils** aResult); -%} diff --git a/rdf/base/nsIRDFContentSink.h b/rdf/base/nsIRDFContentSink.h deleted file mode 100644 index 293e8baadea4..000000000000 --- a/rdf/base/nsIRDFContentSink.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- 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/. */ - -/* - - An RDF-specific content sink. The content sink is targeted by the - parser for building the RDF content model. - - */ - -#ifndef nsIRDFContentSink_h___ -#define nsIRDFContentSink_h___ - -#include "nsIXMLContentSink.h" -class nsIRDFDataSource; -class nsIURI; - -// {3a7459d7-d723-483c-aef0-404fc48e09b8} -#define NS_IRDFCONTENTSINK_IID \ -{ 0x3a7459d7, 0xd723, 0x483c, { 0xae, 0xf0, 0x40, 0x4f, 0xc4, 0x8e, 0x09, 0xb8 } } - -/** - * This interface represents a content sink for RDF files. - */ - -class nsIRDFContentSink : public nsIXMLContentSink { -public: - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IRDFCONTENTSINK_IID) - - /** - * Initialize the content sink. - */ - NS_IMETHOD Init(nsIURI* aURL) = 0; - - /** - * Set the content sink's RDF Data source - */ - NS_IMETHOD SetDataSource(nsIRDFDataSource* aDataSource) = 0; - - /** - * Retrieve the content sink's RDF data source. - */ - NS_IMETHOD GetDataSource(nsIRDFDataSource*& rDataSource) = 0; -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIRDFContentSink, NS_IRDFCONTENTSINK_IID) - -/** - * This constructs a content sink that can be used without a - * document, say, to create a stand-alone in-memory graph. - */ -nsresult -NS_NewRDFContentSink(nsIRDFContentSink** aResult); - -#endif // nsIRDFContentSink_h___ diff --git a/rdf/base/nsIRDFDataSource.idl b/rdf/base/nsIRDFDataSource.idl deleted file mode 100644 index 6083b6117874..000000000000 --- a/rdf/base/nsIRDFDataSource.idl +++ /dev/null @@ -1,181 +0,0 @@ -/* -*- 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/. */ - -#include "nsISupports.idl" -#include "nsIRDFResource.idl" -#include "nsIRDFNode.idl" -#include "nsISimpleEnumerator.idl" -#include "nsIRDFObserver.idl" - -[scriptable, uuid(0F78DA58-8321-11d2-8EAC-00805F29F370)] -interface nsIRDFDataSource : nsISupports -{ - /** The "URI" of the data source. This used by the RDF service's - * |GetDataSource()| method to cache datasources. - */ - readonly attribute ACString URI; - - /** Find an RDF resource that points to a given node over the - * specified arc & truth value - * - * @throws NS_RDF_NO_VALUE if there is no source that leads - * to the target with the specified property. - */ - nsIRDFResource GetSource(in nsIRDFResource aProperty, - in nsIRDFNode aTarget, - in boolean aTruthValue); - - /** - * Find all RDF resources that point to a given node over the - * specified arc & truth value - */ - nsISimpleEnumerator GetSources(in nsIRDFResource aProperty, - in nsIRDFNode aTarget, - in boolean aTruthValue); - - /** - * Find a child of that is related to the source by the given arc - * arc and truth value - * - * @throws NS_RDF_NO_VALUE if there is no target accessible from the - * source via the specified property. - */ - nsIRDFNode GetTarget(in nsIRDFResource aSource, - in nsIRDFResource aProperty, - in boolean aTruthValue); - - /** - * Find all children of that are related to the source by the given arc - * arc and truth value. - */ - nsISimpleEnumerator GetTargets(in nsIRDFResource aSource, - in nsIRDFResource aProperty, - in boolean aTruthValue); - - /** - * Add an assertion to the graph. - */ - void Assert(in nsIRDFResource aSource, - in nsIRDFResource aProperty, - in nsIRDFNode aTarget, - in boolean aTruthValue); - - /** - * Remove an assertion from the graph. - */ - void Unassert(in nsIRDFResource aSource, - in nsIRDFResource aProperty, - in nsIRDFNode aTarget); - - /** - * Change an assertion from - * - * [aSource]--[aProperty]-->[aOldTarget] - * - * to - * - * [aSource]--[aProperty]-->[aNewTarget] - */ - void Change(in nsIRDFResource aSource, - in nsIRDFResource aProperty, - in nsIRDFNode aOldTarget, - in nsIRDFNode aNewTarget); - - /** - * 'Move' an assertion from - * - * [aOldSource]--[aProperty]-->[aTarget] - * - * to - * - * [aNewSource]--[aProperty]-->[aTarget] - */ - void Move(in nsIRDFResource aOldSource, - in nsIRDFResource aNewSource, - in nsIRDFResource aProperty, - in nsIRDFNode aTarget); - - /** - * Query whether an assertion exists in this graph. - */ - boolean HasAssertion(in nsIRDFResource aSource, - in nsIRDFResource aProperty, - in nsIRDFNode aTarget, - in boolean aTruthValue); - - /** - * Add an observer to this data source. If the datasource - * supports observers, the datasource source should hold a strong - * reference to the observer. - */ - void AddObserver(in nsIRDFObserver aObserver); - - /** - * Remove an observer from this data source. - */ - void RemoveObserver(in nsIRDFObserver aObserver); - - /** - * Get a cursor to iterate over all the arcs that point into a node. - */ - nsISimpleEnumerator ArcLabelsIn(in nsIRDFNode aNode); - - /** - * Get a cursor to iterate over all the arcs that originate in - * a resource. - */ - nsISimpleEnumerator ArcLabelsOut(in nsIRDFResource aSource); - - /** - * Retrieve all of the resources that the data source currently - * refers to. - */ - nsISimpleEnumerator GetAllResources(); - - /** - * Returns whether a given command is enabled for a set of sources. - */ - boolean IsCommandEnabled(in nsISupports aSources, - in nsIRDFResource aCommand, - in nsISupports aArguments); - - /** - * Perform the specified command on set of sources. - */ - void DoCommand(in nsISupports aSources, - in nsIRDFResource aCommand, - in nsISupports aArguments); - - /** - * Returns the set of all commands defined for a given source. - */ - nsISimpleEnumerator GetAllCmds(in nsIRDFResource aSource); - - /** - * Returns true if the specified node is pointed to by the specified arc. - * Equivalent to enumerating ArcLabelsIn and comparing for the specified arc. - */ - boolean hasArcIn(in nsIRDFNode aNode, in nsIRDFResource aArc); - - /** - * Returns true if the specified node has the specified outward arc. - * Equivalent to enumerating ArcLabelsOut and comparing for the specified arc. - */ - boolean hasArcOut(in nsIRDFResource aSource, in nsIRDFResource aArc); - - /** - * Notify observers that the datasource is about to send several - * notifications at once. - * This must be followed by calling endUpdateBatch(), otherwise - * viewers will get out of sync. - */ - void beginUpdateBatch(); - - /** - * Notify observers that the datasource has completed issuing - * a notification group. - */ - void endUpdateBatch(); -}; diff --git a/rdf/base/nsIRDFDelegateFactory.idl b/rdf/base/nsIRDFDelegateFactory.idl deleted file mode 100644 index 6fbc42fd54c6..000000000000 --- a/rdf/base/nsIRDFDelegateFactory.idl +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- 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/. */ - -/* - - An interface used for runtime pseudo-aggregation of RDF delegate - objects. - -*/ - -#include "nsrootidl.idl" -#include "nsISupports.idl" -interface nsIRDFResource; - -/** - * This interface should be implemented by an XPCOM factory that - * is registered to handle "@mozilla.org/rdf/delegate-factory/[key]/[scheme];1" - * ContractIDs. - * - * The factory will be invoked to create delegate objects from - * nsIRDFResource::GetDelegate(). - */ -[scriptable, uuid(A1B89470-A124-11d3-BE59-0020A6361667)] -interface nsIRDFDelegateFactory : nsISupports -{ - /** - * Create a delegate for the specified RDF resource. - * - * The created delegate should forward AddRef() and Release() - * calls to the aOuter object. - */ - void CreateDelegate(in nsIRDFResource aOuter, - in string aKey, - in nsIIDRef aIID, - [retval, iid_is(aIID)] out nsQIResult aResult); -}; - - diff --git a/rdf/base/nsIRDFInMemoryDataSource.idl b/rdf/base/nsIRDFInMemoryDataSource.idl deleted file mode 100644 index 35734efe63cd..000000000000 --- a/rdf/base/nsIRDFInMemoryDataSource.idl +++ /dev/null @@ -1,14 +0,0 @@ -/* -*- 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/. */ - -#include "nsISupports.idl" -#include "nsIRDFResource.idl" -#include "nsIRDFNode.idl" - -[scriptable, uuid(17C4E0AA-1DD2-11B2-8029-BF6F668DE500)] -interface nsIRDFInMemoryDataSource : nsISupports -{ - void EnsureFastContainment(in nsIRDFResource aSource); -}; diff --git a/rdf/base/nsIRDFInferDataSource.idl b/rdf/base/nsIRDFInferDataSource.idl deleted file mode 100644 index 07bafcfff9a6..000000000000 --- a/rdf/base/nsIRDFInferDataSource.idl +++ /dev/null @@ -1,28 +0,0 @@ -/* -*- 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/. */ - -#include "nsIRDFDataSource.idl" - -/** - * An nsIRDFInferDataSource is implemented by a infer engine. This - * engine mimics assertions in addition to those in the baseDataSource - * according to a particular vocabulary. - * Infer engines have contract IDs in the form of - * "@mozilla.org/rdf/infer-datasource;1?engine=" - */ - -[scriptable, uuid(2b04860f-4017-40f6-8a57-784a1e35077a)] -interface nsIRDFInferDataSource : nsIRDFDataSource { - /** - * - * The wrapped datasource. - * - * The InferDataSource contains all arcs from the wrapped - * datasource plus those infered by the vocabulary implemented - * by the InferDataSource. - */ - attribute nsIRDFDataSource baseDataSource; -}; - diff --git a/rdf/base/nsIRDFLiteral.idl b/rdf/base/nsIRDFLiteral.idl deleted file mode 100644 index 3d289c4fee69..000000000000 --- a/rdf/base/nsIRDFLiteral.idl +++ /dev/null @@ -1,68 +0,0 @@ -/* -*- 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/. */ - -#include "nsIRDFNode.idl" - -%{C++ -#include "nscore.h" // for char16_t -%} - -[ptr] native const_octet_ptr(const uint8_t); - -/** - * A literal node in the graph, whose value is a string. - */ -[scriptable, uuid(E0C493D2-9542-11d2-8EB8-00805F29F370)] -interface nsIRDFLiteral : nsIRDFNode { - /** - * The Unicode string value of the literal. - */ - readonly attribute wstring Value; - - /** - * An unscriptable version used to avoid a string copy. Meant - * for use as a performance optimization. - */ - [noscript] void GetValueConst([shared] out wstring aConstValue); -}; - -/** - * A literal node in the graph, whose value is a date - */ -[scriptable, uuid(E13A24E1-C77A-11d2-80BE-006097B76B8E)] -interface nsIRDFDate : nsIRDFNode { - /** - * The date value of the literal - */ - readonly attribute PRTime Value; -}; - -/** - * A literal node in the graph, whose value is an integer - */ -[scriptable, uuid(E13A24E3-C77A-11d2-80BE-006097B76B8E)] -interface nsIRDFInt : nsIRDFNode { - /** - * The integer value of the literal - */ - readonly attribute long Value; -}; - -/** - * A literal node in the graph, whose value is arbitrary - * binary data. - */ -[scriptable, uuid(237f85a2-1dd2-11b2-94af-8122582fc45e)] -interface nsIRDFBlob : nsIRDFNode { - /** - * The binary data. - */ - [noscript] readonly attribute const_octet_ptr value; - - /** - * The data's length. - */ - readonly attribute long length; -}; diff --git a/rdf/base/nsIRDFNode.idl b/rdf/base/nsIRDFNode.idl deleted file mode 100644 index 2bd7d4967ee3..000000000000 --- a/rdf/base/nsIRDFNode.idl +++ /dev/null @@ -1,15 +0,0 @@ -/* -*- 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/. */ - -#include "nsISupports.idl" - -// An nsIRDFNode object is an abstract placeholder for a node in the -// RDF data model. Its concreted implementations (e.g., nsIRDFResource -// or nsIRDFLiteral) are the actual objects that populate the graph. -[scriptable, uuid(0F78DA50-8321-11d2-8EAC-00805F29F370)] -interface nsIRDFNode : nsISupports { - // Determine if two nodes are identical - boolean EqualsNode(in nsIRDFNode aNode); -}; diff --git a/rdf/base/nsIRDFObserver.idl b/rdf/base/nsIRDFObserver.idl deleted file mode 100644 index 1923c5b38e4e..000000000000 --- a/rdf/base/nsIRDFObserver.idl +++ /dev/null @@ -1,94 +0,0 @@ -/* -*- 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/. */ - -#include "nsISupports.idl" -#include "nsIRDFResource.idl" -#include "nsIRDFNode.idl" - -interface nsIRDFDataSource; - -// An nsIRDFObserver object is an observer that will be notified -// when assertions are made or removed from a datasource -[scriptable, uuid(3CC75360-484A-11D2-BC16-00805F912FE7)] -interface nsIRDFObserver : nsISupports { - /** - * This method is called whenever a new assertion is made - * in the data source - * @param aDataSource the datasource that is issuing - * the notification. - * @param aSource the subject of the assertion - * @param aProperty the predicate of the assertion - * @param aTarget the object of the assertion - */ - void onAssert(in nsIRDFDataSource aDataSource, - in nsIRDFResource aSource, - in nsIRDFResource aProperty, - in nsIRDFNode aTarget); - - /** - * This method is called whenever an assertion is removed - * from the data source - * @param aDataSource the datasource that is issuing - * the notification. - * @param aSource the subject of the assertion - * @param aProperty the predicate of the assertion - * @param aTarget the object of the assertion - */ - void onUnassert(in nsIRDFDataSource aDataSource, - in nsIRDFResource aSource, - in nsIRDFResource aProperty, - in nsIRDFNode aTarget); - - /** - * This method is called when the object of an assertion - * changes from one value to another. - * @param aDataSource the datasource that is issuing - * the notification. - * @param aSource the subject of the assertion - * @param aProperty the predicate of the assertion - * @param aOldTarget the old object of the assertion - * @param aNewTarget the new object of the assertion - */ - void onChange(in nsIRDFDataSource aDataSource, - in nsIRDFResource aSource, - in nsIRDFResource aProperty, - in nsIRDFNode aOldTarget, - in nsIRDFNode aNewTarget); - - /** - * This method is called when the subject of an assertion - * changes from one value to another. - * @param aDataSource the datasource that is issuing - * the notification. - * @param aOldSource the old subject of the assertion - * @param aNewSource the new subject of the assertion - * @param aProperty the predicate of the assertion - * @param aTarget the object of the assertion - */ - void onMove(in nsIRDFDataSource aDataSource, - in nsIRDFResource aOldSource, - in nsIRDFResource aNewSource, - in nsIRDFResource aProperty, - in nsIRDFNode aTarget); - - /** - * This method is called when a datasource is about to - * send several notifications at once. The observer can - * use this as a cue to optimize its behavior. The observer - * can expect the datasource to call endUpdateBatch() when - * the group of notifications has completed. - * @param aDataSource the datasource that is going to - * be issuing the notifications. - */ - void onBeginUpdateBatch(in nsIRDFDataSource aDataSource); - - /** - * This method is called when a datasource has completed - * issuing a notification group. - * @param aDataSource the datasource that has finished - * issuing a group of notifications - */ - void onEndUpdateBatch(in nsIRDFDataSource aDataSource); -}; diff --git a/rdf/base/nsIRDFPropagatableDataSource.idl b/rdf/base/nsIRDFPropagatableDataSource.idl deleted file mode 100644 index dfe510e9c2ad..000000000000 --- a/rdf/base/nsIRDFPropagatableDataSource.idl +++ /dev/null @@ -1,27 +0,0 @@ -/* -*- Mode: idl; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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/. */ - - -#include "nsISupports.idl" - -/** - * An nsIRDFPropagatableDataSource provides an ability to suppress - * synchronization notifications. - */ -[scriptable, uuid(5a9b4770-9fcb-4307-a12e-4b6708e78b97)] -interface nsIRDFPropagatableDataSource: nsISupports { - - /** - * Set this value to true to enable synchronization - * notifications. - * - * Set this value to false to disable synchronization - * notifications. - * - * By default, this value is true. - */ - attribute boolean propagateChanges; - -}; diff --git a/rdf/base/nsIRDFPurgeableDataSource.idl b/rdf/base/nsIRDFPurgeableDataSource.idl deleted file mode 100644 index 05973df0e43a..000000000000 --- a/rdf/base/nsIRDFPurgeableDataSource.idl +++ /dev/null @@ -1,19 +0,0 @@ -/* -*- 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/. */ - -#include "nsISupports.idl" -#include "nsIRDFResource.idl" -#include "nsIRDFNode.idl" - -[scriptable, uuid(951700F0-FED0-11D2-BDD9-00104BDE6048)] -interface nsIRDFPurgeableDataSource : nsISupports -{ - boolean Mark(in nsIRDFResource aSource, - in nsIRDFResource aProperty, - in nsIRDFNode aTarget, - in boolean aTruthValue); - - void Sweep(); -}; diff --git a/rdf/base/nsIRDFRemoteDataSource.idl b/rdf/base/nsIRDFRemoteDataSource.idl deleted file mode 100644 index fd2cd1b0b069..000000000000 --- a/rdf/base/nsIRDFRemoteDataSource.idl +++ /dev/null @@ -1,44 +0,0 @@ -/* -*- 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/. */ - -#include "nsISupports.idl" - -/** - * A datasource that may load asynchronously - */ -[scriptable, uuid(1D297320-27F7-11d3-BE01-000064657374)] -interface nsIRDFRemoteDataSource : nsISupports -{ - /** - * This value is true when the datasource has - * fully loaded itself. - */ - readonly attribute boolean loaded; - - /** - * Specify the URI for the data source: this is the prefix - * that will be used to register the data source in the - * data source registry. - * @param aURI the URI to load - */ - void Init(in string aURI); - - /** - * Refresh the remote datasource, re-loading its contents - * from the URI. - * - * @param aBlocking If true, the call will block - * until the datasource has completely reloaded. - */ - void Refresh(in boolean aBlocking); - - /** - * Request that a data source write its contents out to - * permanent storage, if applicable. - */ - void Flush(); - void FlushTo(in string aURI); -}; - diff --git a/rdf/base/nsIRDFResource.idl b/rdf/base/nsIRDFResource.idl deleted file mode 100644 index df4d4b8ffd6d..000000000000 --- a/rdf/base/nsIRDFResource.idl +++ /dev/null @@ -1,81 +0,0 @@ -/* -*- 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/. */ - -#include "nsrootidl.idl" -#include "nsIRDFNode.idl" - - -/** - * An nsIRDFResource is an object that has unique identity in the - * RDF data model. The object's identity is determined by its URI. - */ -[scriptable, uuid(fb9686a7-719a-49dc-9107-10dea5739341)] -interface nsIRDFResource : nsIRDFNode { - /** - * The single-byte string value of the resource. - * @note THIS IS OBSOLETE. C++ should use GetValueConst and script - * should use .valueUTF8 - */ - readonly attribute string Value; - - /** - * The UTF-8 URI of the resource. - */ - readonly attribute AUTF8String ValueUTF8; - - /** - * An unscriptable version used to avoid a string copy. Meant - * for use as a performance optimization. The string is encoded - * in UTF-8. - */ - [noscript] void GetValueConst([shared] out string aConstValue); - - /** - * This method is called by the nsIRDFService after constructing - * a resource object to initialize its URI. You would not normally - * call this method directly - */ - void Init(in string uri); - - /** - * Determine if the resource has the given URI. - */ - boolean EqualsString(in string aURI); - - /** - * Retrieve the "delegate" object for this resource. A resource - * may have several delegate objects, each of whose lifetimes is - * bound to the life of the resource object. - * - * This method will return the delegate for the given key after - * QueryInterface()-ing it to the requested IID. - * - * If no delegate exists for the specified key, this method will - * attempt to create one using the component manager. Specifically, - * it will combine aKey with the resource's URI scheme to produce - * a ContractID as follows: - * - * component:/rdf/delegate-factory/[key]/[scheme] - * - * This ContractID will be used to locate a factory using the - * FindFactory() method of nsIComponentManager. If the nsIFactory - * exists, it will be used to create a "delegate factory"; that - * is, an object that supports nsIRDFDelegateFactory. The delegate - * factory will be used to construct the delegate object. - */ - void GetDelegate(in string aKey, in nsIIDRef aIID, - [iid_is(aIID),retval] out nsQIResult aResult); - - /** - * Force a delegate to be "unbound" from the resource. - * - * Normally, a delegate object's lifetime will be identical to - * that of the resource to which it is bound; this method allows a - * delegate to unlink itself from an RDF resource prematurely. - */ - void ReleaseDelegate(in string aKey); -}; - - diff --git a/rdf/base/nsIRDFService.idl b/rdf/base/nsIRDFService.idl deleted file mode 100644 index 08023feab7ea..000000000000 --- a/rdf/base/nsIRDFService.idl +++ /dev/null @@ -1,146 +0,0 @@ -/* -*- 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/. */ - -#include "nsISupports.idl" -#include "nsIRDFResource.idl" -#include "nsIRDFLiteral.idl" -#include "nsIRDFDataSource.idl" - - -/** - * The RDF service interface. This is a singleton object which should be - * obtained from the nsServiceManager. - */ -[scriptable, uuid(BFD05261-834C-11d2-8EAC-00805F29F370)] -interface nsIRDFService : nsISupports { - /** - * Construct an RDF resource from a single-byte URI. nsIRDFService - * caches resources that are in-use, so multiple calls to GetResource() - * for the same uri will return identical pointers. FindResource - * is used to find out whether there already exists a resource corresponding to that url. - */ - nsIRDFResource GetResource(in AUTF8String aURI); - - /** - * Construct an RDF resource from a Unicode URI. This is provided - * as a convenience method, allowing automatic, in-line C++ - * conversion from nsString objects. The uri will - * be converted to a single-byte representation internally. - */ - nsIRDFResource GetUnicodeResource(in AString aURI); - - nsIRDFResource GetAnonymousResource(); - - /** - * Construct an RDF literal from a Unicode string. - */ - nsIRDFLiteral GetLiteral(in wstring aValue); - - /** - * Construct an RDF literal from a PRTime. - */ - nsIRDFDate GetDateLiteral(in PRTime aValue); - - /** - * Construct an RDF literal from an int. - */ - nsIRDFInt GetIntLiteral(in long aValue); - - /** - * Construct an RDF literal from a data blob - */ - [noscript] nsIRDFBlob getBlobLiteral(in const_octet_ptr aValue, in long aLength); - - boolean IsAnonymousResource(in nsIRDFResource aResource); - - /** - * Registers a resource with the RDF system, making it unique w.r.t. - * GetResource. - * - * An implementation of nsIRDFResource should call this in its - * Init() method if it wishes the resource to be globally unique - * (which is usually the case). - * - * @note that the resource will not be ref-counted by the - * RDF service: the assumption is that the resource implementation - * will call nsIRDFService::UnregisterResource() when the last - * reference to the resource is released. - * - * @note that the nsIRDFService implementation may choose to - * maintain a reference to the resource's URI; therefore, the - * resource implementation should ensure that the resource's URI - * (accessible via nsIRDFResource::GetValue(const char* *aURI)) is - * valid before calling RegisterResource(). Furthermore, the - * resource implementation should ensure that this pointer - * remains valid for the lifetime of the resource. (The - * implementation of the resource cache in nsIRDFService uses the - * URI maintained "internally" in the resource as a key into the - * cache rather than copying the resource URI itself.) - */ - void RegisterResource(in nsIRDFResource aResource, in boolean aReplace); - - /** - * Called to notify the resource manager that a resource is no - * longer in use. This method should only be called from the - * destructor of a "custom" resource implementation to notify the - * RDF service that the last reference to the resource has been - * released, so the resource is no longer valid. - * - * @note As mentioned in nsIRDFResourceFactory::CreateResource(), - * the RDF service will use the result of - * nsIRDFResource::GetValue() as a key into its cache. For this - * reason, you must always un-cache the resource before - * releasing the storage for the const char* URI. - */ - void UnregisterResource(in nsIRDFResource aResource); - - /** - * Register a named data source. The RDF service will call - * nsIRDFDataSource::GetURI() to determine the URI under - * which to register the data source. - * - * @note that the data source will not be refcounted by the - * RDF service! The assumption is that an RDF data source - * registers with the service once it is initialized (via - * nsIRDFDataSource::Init()), and unregisters when the - * last reference to the data source is released. - */ - void RegisterDataSource(in nsIRDFDataSource aDataSource, - in boolean aReplace); - - /** - * Unregister a named data source. The RDF service will call - * nsIRDFDataSource::GetURI() to determine the URI under which the - * data source was registered. - */ - void UnregisterDataSource(in nsIRDFDataSource aDataSource); - - /** - * Get the named data source corresponding to the URI. If a data - * source has been registered via RegisterDataSource(), that - * data source will be returned. - * - * If no data source is currently - * registered for the specified URI, and a data source constructor - * function has been registered via RegisterDatasourceConstructor(), - * the RDF service will call the constructor to attempt to construct a - * new data source. If construction is successful, the data source will - * be initialized via nsIRDFDataSource::Init(). - */ - nsIRDFDataSource GetDataSource(in string aURI); - - /** - * Same as GetDataSource, but if a remote/XML data source needs to be - * constructed, then this method will issue a blocking Refresh - * call on that data source. - */ - nsIRDFDataSource GetDataSourceBlocking(in string aURI); -}; - -%{C++ -extern nsresult -NS_NewRDFService(nsIRDFService** result); -%} - diff --git a/rdf/base/nsIRDFXMLParser.idl b/rdf/base/nsIRDFXMLParser.idl deleted file mode 100644 index 1e7dde51f185..000000000000 --- a/rdf/base/nsIRDFXMLParser.idl +++ /dev/null @@ -1,33 +0,0 @@ -/* -*- 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/. */ - -#include "nsISupports.idl" -#include "nsIRDFDataSource.idl" -#include "nsIStreamListener.idl" -#include "nsIURI.idl" - -[scriptable, uuid(1831dd2e-1dd2-11b2-bdb3-86b7b50b70b5)] -interface nsIRDFXMLParser : nsISupports -{ - /** - * Create a stream listener that can be used to asynchronously - * parse RDF/XML. - * @param aSink the RDF datasource the will receive the data - * @param aBaseURI the base URI used to resolve relative - * references in the RDF/XML - * @return an nsIStreamListener object to handle the data - */ - nsIStreamListener parseAsync(in nsIRDFDataSource aSink, in nsIURI aBaseURI); - - /** - * Parse a string of RDF/XML - * @param aSink the RDF datasource that will receive the data - * @param aBaseURI the base URI used to resolve relative - * references in the RDF/XML - * @param aSource a UTF8 string containing RDF/XML data. - */ - void parseString(in nsIRDFDataSource aSink, in nsIURI aBaseURI, in AUTF8String aSource); -}; diff --git a/rdf/base/nsIRDFXMLSerializer.idl b/rdf/base/nsIRDFXMLSerializer.idl deleted file mode 100644 index edf113d4bead..000000000000 --- a/rdf/base/nsIRDFXMLSerializer.idl +++ /dev/null @@ -1,31 +0,0 @@ -/* -*- 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/. */ - -#include "nsISupports.idl" -#include "nsIRDFDataSource.idl" - -%{C++ -class nsAtom; -%} -[ptr] native nsAtomPtr(nsAtom); - -[scriptable, uuid(8ae1fbf8-1dd2-11b2-bd21-d728069cca92)] -interface nsIRDFXMLSerializer : nsISupports -{ - /** - * Initialize the serializer with the specified datasource. - * @param aDataSource the datasource from which data will be - * serialized - */ - void init(in nsIRDFDataSource aDataSource); - - /** - * Add the specified namespace to the serializer. - * @param aPrefix the attribute namespace prefix - * @param aURI the namespace URI - */ - [noscript] void addNameSpace(in nsAtomPtr aPrefix, in DOMString aURI); -}; diff --git a/rdf/base/nsIRDFXMLSink.idl b/rdf/base/nsIRDFXMLSink.idl deleted file mode 100644 index 1c950c867ab4..000000000000 --- a/rdf/base/nsIRDFXMLSink.idl +++ /dev/null @@ -1,133 +0,0 @@ -/* -*- 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/. */ - -/* - - Interfaces for the RDF/XML sink, which parses RDF/XML into - a graph representation. - -*/ - -#include "nsISupports.idl" - -%{C++ -class nsAtom; -%} -[ptr] native nsAtomPtr(nsAtom); - -// XXX Until these get scriptable. See nsIRDFXMLSink::AddNameSpace() -[ref] native nsStringRef(nsString); -%{C++ -#include "nsStringFwd.h" -%} - -interface nsIRDFXMLSink; - -/** - * An observer that is notified as progress is made on the load - * of an RDF/XML document in an nsIRDFXMLSink. - */ -[scriptable, uuid(EB1A5D30-AB33-11D2-8EC6-00805F29F370)] -interface nsIRDFXMLSinkObserver : nsISupports -{ - /** - * Called when the load begins. - * @param aSink the RDF/XML sink on which the load is beginning. - */ - void onBeginLoad(in nsIRDFXMLSink aSink); - - /** - * Called when the load is suspended (e.g., for network quantization). - * @param aSink the RDF/XML sink that is being interrupted. - */ - void onInterrupt(in nsIRDFXMLSink aSink); - - /** - * Called when a suspended load is resuming. - * @param aSink the RDF/XML sink that is resuming. - */ - void onResume(in nsIRDFXMLSink aSink); - - /** - * Called when an RDF/XML load completes successfully. - * @param aSink the RDF/XML sink that has finished loading. - */ - void onEndLoad(in nsIRDFXMLSink aSink); - - /** - * Called when an error occurs during the load - * @param aSink the RDF/XML sink in which the error occurred - * @param aStatus the networking result code - * @param aErrorMsg an error message, if applicable - */ - void onError(in nsIRDFXMLSink aSink, in nsresult aStatus, in wstring aErrorMsg); -}; - - - -/** - * A "sink" that receives and processes RDF/XML. This interface is used - * by the RDF/XML parser. - */ -[scriptable, uuid(EB1A5D31-AB33-11D2-8EC6-00805F29F370)] -interface nsIRDFXMLSink : nsISupports -{ - /** - * Set to true if the sink is read-only and cannot - * be modified - */ - attribute boolean readOnly; - - /** - * Initiate the RDF/XML load. - */ - void beginLoad(); - - /** - * Suspend the RDF/XML load. - */ - void interrupt(); - - /** - * Resume the RDF/XML load. - */ - void resume(); - - /** - * Complete the RDF/XML load. - */ - void endLoad(); - - /** - * Add namespace information to the RDF/XML sink. - * @param aPrefix the namespace prefix - * @param aURI the namespace URI - */ - [noscript] void addNameSpace(in nsAtomPtr aPrefix, - [const] in nsStringRef aURI); - - /** - * Add an observer that will be notified as the RDF/XML load - * progresses. - *

- * - * Note that the sink will acquire a strong reference to the - * observer, so care should be taken to avoid cyclical references - * that cannot be released (i.e., if the observer holds a - * reference to the sink, it should be sure that it eventually - * clears the reference). - * - * @param aObserver the observer to add to the sink's set of - * load observers. - */ - void addXMLSinkObserver(in nsIRDFXMLSinkObserver aObserver); - - /** - * Remove an observer from the sink's set of observers. - * @param aObserver the observer to remove. - */ - void removeXMLSinkObserver(in nsIRDFXMLSinkObserver aObserver); -}; - diff --git a/rdf/base/nsIRDFXMLSource.idl b/rdf/base/nsIRDFXMLSource.idl deleted file mode 100644 index 794d8b66269b..000000000000 --- a/rdf/base/nsIRDFXMLSource.idl +++ /dev/null @@ -1,20 +0,0 @@ -/* -*- 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/. */ - -#include "nsISupports.idl" -#include "nsIOutputStream.idl" - -[scriptable, uuid(4DA56F10-99FE-11d2-8EBB-00805F29F370)] -interface nsIRDFXMLSource : nsISupports -{ - /** - * Serialize the contents of the datasource to aStream. - * @param aStream the output stream the will receive the - * RDF/XML. Currently, the output stream need only - * implement the |write()| method. - */ - void Serialize(in nsIOutputStream aStream); -}; - diff --git a/rdf/base/nsInMemoryDataSource.cpp b/rdf/base/nsInMemoryDataSource.cpp deleted file mode 100644 index fe2d3199bf7e..000000000000 --- a/rdf/base/nsInMemoryDataSource.cpp +++ /dev/null @@ -1,1938 +0,0 @@ -/* -*- 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/. */ - -/* - - Implementation for an in-memory RDF data store. - - TO DO - - 1) Instrument this code to gather space and time performance - characteristics. - - 2) Optimize lookups for datasources which have a small number - of properties + fanning out to a large number of targets. - - 3) Complete implementation of thread-safety; specifically, make - assertions be reference counted objects (so that a cursor can - still refer to an assertion that gets removed from the graph). - - */ - -#include "nsAgg.h" -#include "nsCOMPtr.h" -#include "nscore.h" -#include "nsArrayEnumerator.h" -#include "nsIOutputStream.h" -#include "nsIRDFDataSource.h" -#include "nsIRDFLiteral.h" -#include "nsIRDFNode.h" -#include "nsIRDFObserver.h" -#include "nsIRDFInMemoryDataSource.h" -#include "nsIRDFPropagatableDataSource.h" -#include "nsIRDFPurgeableDataSource.h" -#include "nsIRDFService.h" -#include "nsIServiceManager.h" -#include "nsCOMArray.h" -#include "nsEnumeratorUtils.h" -#include "nsTArray.h" -#include "nsCRT.h" -#include "nsRDFCID.h" -#include "nsRDFBaseDataSources.h" -#include "nsString.h" -#include "nsReadableUtils.h" -#include "nsString.h" -#include "rdfutil.h" -#include "PLDHashTable.h" -#include "plstr.h" -#include "mozilla/Logging.h" -#include "rdf.h" - -#include "rdfIDataSource.h" -#include "rdfITripleVisitor.h" - -using mozilla::LogLevel; - -// This struct is used as the slot value in the forward and reverse -// arcs hash tables. -// -// Assertion objects are reference counted, because each Assertion's -// ownership is shared between the datasource and any enumerators that -// are currently iterating over the datasource. -// -class Assertion -{ -public: - Assertion(nsIRDFResource* aSource, // normal assertion - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue); - explicit Assertion(nsIRDFResource* aSource); // PLDHashTable assertion variant - -private: - ~Assertion(); - -public: - void AddRef() { - if (mRefCnt == UINT16_MAX) { - NS_WARNING("refcount overflow, leaking Assertion"); - return; - } - ++mRefCnt; - } - - void Release() { - if (mRefCnt == UINT16_MAX) { - NS_WARNING("refcount overflow, leaking Assertion"); - return; - } - if (--mRefCnt == 0) - delete this; - } - - // For nsIRDFPurgeableDataSource - inline void Mark() { u.as.mMarked = true; } - inline bool IsMarked() { return u.as.mMarked; } - inline void Unmark() { u.as.mMarked = false; } - - // public for now, because I'm too lazy to go thru and clean this up. - - // These are shared between hash/as (see the union below) - nsIRDFResource* mSource; - Assertion* mNext; - - union - { - struct hash - { - PLDHashTable* mPropertyHash; - } hash; - struct as - { - nsIRDFResource* mProperty; - nsIRDFNode* mTarget; - Assertion* mInvNext; - // make sure bool are final elements - bool mTruthValue; - bool mMarked; - } as; - } u; - - // also shared between hash/as (see the union above) - // but placed after union definition to ensure that - // all 32-bit entries are long aligned - uint16_t mRefCnt; - bool mHashEntry; -}; - - -struct Entry : PLDHashEntryHdr { - nsIRDFNode* mNode; - Assertion* mAssertions; -}; - - -Assertion::Assertion(nsIRDFResource* aSource) - : mSource(aSource), - mNext(nullptr), - mRefCnt(0), - mHashEntry(true) -{ - MOZ_COUNT_CTOR(Assertion); - - NS_ADDREF(mSource); - - u.hash.mPropertyHash = - new PLDHashTable(PLDHashTable::StubOps(), sizeof(Entry)); -} - -Assertion::Assertion(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue) - : mSource(aSource), - mNext(nullptr), - mRefCnt(0), - mHashEntry(false) -{ - MOZ_COUNT_CTOR(Assertion); - - u.as.mProperty = aProperty; - u.as.mTarget = aTarget; - - NS_ADDREF(mSource); - NS_ADDREF(u.as.mProperty); - NS_ADDREF(u.as.mTarget); - - u.as.mInvNext = nullptr; - u.as.mTruthValue = aTruthValue; - u.as.mMarked = false; -} - -Assertion::~Assertion() -{ - if (mHashEntry && u.hash.mPropertyHash) { - for (auto i = u.hash.mPropertyHash->Iter(); !i.Done(); i.Next()) { - auto entry = static_cast(i.Get()); - Assertion* as = entry->mAssertions; - while (as) { - Assertion* doomed = as; - as = as->mNext; - - // Unlink, and release the datasource's reference. - doomed->mNext = doomed->u.as.mInvNext = nullptr; - doomed->Release(); - } - } - delete u.hash.mPropertyHash; - u.hash.mPropertyHash = nullptr; - } - - MOZ_COUNT_DTOR(Assertion); -#ifdef DEBUG_REFS - --gInstanceCount; - fprintf(stdout, "%d - RDF: Assertion\n", gInstanceCount); -#endif - - NS_RELEASE(mSource); - if (!mHashEntry) - { - NS_RELEASE(u.as.mProperty); - NS_RELEASE(u.as.mTarget); - } -} - -//////////////////////////////////////////////////////////////////////// -// InMemoryDataSource -class InMemoryArcsEnumeratorImpl; -class InMemoryAssertionEnumeratorImpl; -class InMemoryResourceEnumeratorImpl; - -class InMemoryDataSource : public nsIRDFDataSource, - public nsIRDFInMemoryDataSource, - public nsIRDFPropagatableDataSource, - public nsIRDFPurgeableDataSource, - public rdfIDataSource -{ -protected: - // These hash tables are keyed on pointers to nsIRDFResource - // objects (the nsIRDFService ensures that there is only ever one - // nsIRDFResource object per unique URI). The value of an entry is - // an Assertion struct, which is a linked list of (subject - // predicate object) triples. - PLDHashTable mForwardArcs; - PLDHashTable mReverseArcs; - - nsCOMArray mObservers; - uint32_t mNumObservers; - - // VisitFoo needs to block writes, [Un]Assert only allowed - // during mReadCount == 0 - uint32_t mReadCount; - - friend class InMemoryArcsEnumeratorImpl; - friend class InMemoryAssertionEnumeratorImpl; - friend class InMemoryResourceEnumeratorImpl; // b/c it needs to enumerate mForwardArcs - - // Thread-safe writer implementation methods. - nsresult - LockedAssert(nsIRDFResource* source, - nsIRDFResource* property, - nsIRDFNode* target, - bool tv); - - nsresult - LockedUnassert(nsIRDFResource* source, - nsIRDFResource* property, - nsIRDFNode* target); - - explicit InMemoryDataSource(nsISupports* aOuter); - virtual ~InMemoryDataSource(); - - friend nsresult - NS_NewRDFInMemoryDataSource(nsISupports* aOuter, const nsIID& aIID, void** aResult); - -public: - NS_DECL_CYCLE_COLLECTING_AGGREGATED - NS_DECL_AGGREGATED_CYCLE_COLLECTION_CLASS(InMemoryDataSource) - - // nsIRDFDataSource methods - NS_DECL_NSIRDFDATASOURCE - - // nsIRDFInMemoryDataSource methods - NS_DECL_NSIRDFINMEMORYDATASOURCE - - // nsIRDFPropagatableDataSource methods - NS_DECL_NSIRDFPROPAGATABLEDATASOURCE - - // nsIRDFPurgeableDataSource methods - NS_DECL_NSIRDFPURGEABLEDATASOURCE - - // rdfIDataSource methods - NS_DECL_RDFIDATASOURCE - -protected: - struct SweepInfo { - Assertion* mUnassertList; - PLDHashTable* mReverseArcs; - }; - - static void - SweepForwardArcsEntries(PLDHashTable* aTable, SweepInfo* aArg); - -public: - // Implementation methods - Assertion* - GetForwardArcs(nsIRDFResource* u) { - PLDHashEntryHdr* hdr = mForwardArcs.Search(u); - return hdr ? static_cast(hdr)->mAssertions : nullptr; - } - - Assertion* - GetReverseArcs(nsIRDFNode* v) { - PLDHashEntryHdr* hdr = mReverseArcs.Search(v); - return hdr ? static_cast(hdr)->mAssertions : nullptr; - } - - void - SetForwardArcs(nsIRDFResource* u, Assertion* as) { - if (as) { - auto entry = - static_cast(mForwardArcs.Add(u, mozilla::fallible)); - if (entry) { - entry->mNode = u; - entry->mAssertions = as; - } - } - else { - mForwardArcs.Remove(u); - } - } - - void - SetReverseArcs(nsIRDFNode* v, Assertion* as) { - if (as) { - auto entry = - static_cast(mReverseArcs.Add(v, mozilla::fallible)); - if (entry) { - entry->mNode = v; - entry->mAssertions = as; - } - } - else { - mReverseArcs.Remove(v); - } - } - - void - LogOperation(const char* aOperation, - nsIRDFResource* asource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue = true); - - bool mPropagateChanges; - -private: - static mozilla::LazyLogModule gLog; -}; - -mozilla::LazyLogModule InMemoryDataSource::gLog("InMemoryDataSource"); - -//---------------------------------------------------------------------- -// -// InMemoryAssertionEnumeratorImpl -// - -/** - * InMemoryAssertionEnumeratorImpl - */ -class InMemoryAssertionEnumeratorImpl : public nsISimpleEnumerator -{ -private: - InMemoryDataSource* mDataSource; - nsIRDFResource* mSource; - nsIRDFResource* mProperty; - nsIRDFNode* mTarget; - nsIRDFNode* mValue; - bool mTruthValue; - Assertion* mNextAssertion; - - virtual ~InMemoryAssertionEnumeratorImpl(); - -public: - InMemoryAssertionEnumeratorImpl(InMemoryDataSource* aDataSource, - nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue); - - // nsISupports interface - NS_DECL_ISUPPORTS - - // nsISimpleEnumerator interface - NS_DECL_NSISIMPLEENUMERATOR -}; - -//////////////////////////////////////////////////////////////////////// - - -InMemoryAssertionEnumeratorImpl::InMemoryAssertionEnumeratorImpl( - InMemoryDataSource* aDataSource, - nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue) - : mDataSource(aDataSource), - mSource(aSource), - mProperty(aProperty), - mTarget(aTarget), - mValue(nullptr), - mTruthValue(aTruthValue), - mNextAssertion(nullptr) -{ - NS_ADDREF(mDataSource); - NS_IF_ADDREF(mSource); - NS_ADDREF(mProperty); - NS_IF_ADDREF(mTarget); - - if (mSource) { - mNextAssertion = mDataSource->GetForwardArcs(mSource); - - if (mNextAssertion && mNextAssertion->mHashEntry) { - // its our magical HASH_ENTRY forward hash for assertions - PLDHashEntryHdr* hdr = - mNextAssertion->u.hash.mPropertyHash->Search(aProperty); - mNextAssertion = - hdr ? static_cast(hdr)->mAssertions : nullptr; - } - } - else { - mNextAssertion = mDataSource->GetReverseArcs(mTarget); - } - - // Add an owning reference from the enumerator - if (mNextAssertion) - mNextAssertion->AddRef(); -} - -InMemoryAssertionEnumeratorImpl::~InMemoryAssertionEnumeratorImpl() -{ -#ifdef DEBUG_REFS - --gInstanceCount; - fprintf(stdout, "%d - RDF: InMemoryAssertionEnumeratorImpl\n", gInstanceCount); -#endif - - if (mNextAssertion) - mNextAssertion->Release(); - - NS_IF_RELEASE(mDataSource); - NS_IF_RELEASE(mSource); - NS_IF_RELEASE(mProperty); - NS_IF_RELEASE(mTarget); - NS_IF_RELEASE(mValue); -} - -NS_IMPL_ADDREF(InMemoryAssertionEnumeratorImpl) -NS_IMPL_RELEASE(InMemoryAssertionEnumeratorImpl) -NS_IMPL_QUERY_INTERFACE(InMemoryAssertionEnumeratorImpl, nsISimpleEnumerator) - -NS_IMETHODIMP -InMemoryAssertionEnumeratorImpl::HasMoreElements(bool* aResult) -{ - if (mValue) { - *aResult = true; - return NS_OK; - } - - while (mNextAssertion) { - bool foundIt = false; - if ((mProperty == mNextAssertion->u.as.mProperty) && - (mTruthValue == mNextAssertion->u.as.mTruthValue)) { - if (mSource) { - mValue = mNextAssertion->u.as.mTarget; - NS_ADDREF(mValue); - } - else { - mValue = mNextAssertion->mSource; - NS_ADDREF(mValue); - } - foundIt = true; - } - - // Remember the last assertion we were holding on to - Assertion* as = mNextAssertion; - - // iterate - mNextAssertion = (mSource) ? mNextAssertion->mNext : mNextAssertion->u.as.mInvNext; - - // grab an owning reference from the enumerator to the next assertion - if (mNextAssertion) - mNextAssertion->AddRef(); - - // ...and release the reference from the enumerator to the old one. - as->Release(); - - if (foundIt) { - *aResult = true; - return NS_OK; - } - } - - *aResult = false; - return NS_OK; -} - - -NS_IMETHODIMP -InMemoryAssertionEnumeratorImpl::GetNext(nsISupports** aResult) -{ - nsresult rv; - - bool hasMore; - rv = HasMoreElements(&hasMore); - if (NS_FAILED(rv)) return rv; - - if (! hasMore) - return NS_ERROR_UNEXPECTED; - - // Don't AddRef: we "transfer" ownership to the caller - *aResult = mValue; - mValue = nullptr; - - return NS_OK; -} - -//////////////////////////////////////////////////////////////////////// -// - -/** - * This class is a little bit bizarre in that it implements both the - * nsIRDFArcsOutCursor and nsIRDFArcsInCursor interfaces. - * Because the structure of the in-memory graph is pretty flexible, it's - * fairly easy to parameterize this class. The only funky thing to watch - * out for is the multiple inheritance clashes. - */ - -class InMemoryArcsEnumeratorImpl : public nsISimpleEnumerator -{ -private: - InMemoryDataSource* mDataSource; - nsIRDFResource* mSource; - nsIRDFNode* mTarget; - AutoTArray, 8> mAlreadyReturned; - nsIRDFResource* mCurrent; - Assertion* mAssertion; - nsCOMArray* mHashArcs; - - virtual ~InMemoryArcsEnumeratorImpl(); - -public: - InMemoryArcsEnumeratorImpl(InMemoryDataSource* aDataSource, - nsIRDFResource* aSource, - nsIRDFNode* aTarget); - - // nsISupports interface - NS_DECL_ISUPPORTS - - // nsISimpleEnumerator interface - NS_DECL_NSISIMPLEENUMERATOR -}; - - -InMemoryArcsEnumeratorImpl::InMemoryArcsEnumeratorImpl(InMemoryDataSource* aDataSource, - nsIRDFResource* aSource, - nsIRDFNode* aTarget) - : mDataSource(aDataSource), - mSource(aSource), - mTarget(aTarget), - mCurrent(nullptr), - mHashArcs(nullptr) -{ - NS_ADDREF(mDataSource); - NS_IF_ADDREF(mSource); - NS_IF_ADDREF(mTarget); - - if (mSource) { - // cast okay because it's a closed system - mAssertion = mDataSource->GetForwardArcs(mSource); - - if (mAssertion && mAssertion->mHashEntry) { - // its our magical HASH_ENTRY forward hash for assertions - mHashArcs = new nsCOMArray(); - for (auto i = mAssertion->u.hash.mPropertyHash->Iter(); - !i.Done(); - i.Next()) { - auto entry = static_cast(i.Get()); - mHashArcs->AppendElement(entry->mNode); - } - mAssertion = nullptr; - } - } - else { - mAssertion = mDataSource->GetReverseArcs(mTarget); - } -} - -InMemoryArcsEnumeratorImpl::~InMemoryArcsEnumeratorImpl() -{ -#ifdef DEBUG_REFS - --gInstanceCount; - fprintf(stdout, "%d - RDF: InMemoryArcsEnumeratorImpl\n", gInstanceCount); -#endif - - NS_RELEASE(mDataSource); - NS_IF_RELEASE(mSource); - NS_IF_RELEASE(mTarget); - NS_IF_RELEASE(mCurrent); - delete mHashArcs; -} - -NS_IMPL_ADDREF(InMemoryArcsEnumeratorImpl) -NS_IMPL_RELEASE(InMemoryArcsEnumeratorImpl) -NS_IMPL_QUERY_INTERFACE(InMemoryArcsEnumeratorImpl, nsISimpleEnumerator) - -NS_IMETHODIMP -InMemoryArcsEnumeratorImpl::HasMoreElements(bool* aResult) -{ - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - if (mCurrent) { - *aResult = true; - return NS_OK; - } - - if (mHashArcs) { - if (!mHashArcs->IsEmpty()) { - const uint32_t last = mHashArcs->Length() - 1; - nsCOMPtr tmp(do_QueryInterface(mHashArcs->ObjectAt(last))); - tmp.forget(&mCurrent); - mHashArcs->RemoveElementAt(last); - *aResult = true; - return NS_OK; - } - } - else - while (mAssertion) { - nsIRDFResource* next = mAssertion->u.as.mProperty; - - // "next" is the property arc we are tentatively going to return - // in a subsequent GetNext() call. It is important to do two - // things, however, before that can happen: - // 1) Make sure it's not an arc we've already returned. - // 2) Make sure that |mAssertion| is not left pointing to - // another assertion that has the same property as this one. - // The first is a practical concern; the second a defense against - // an obscure crash and other erratic behavior. To ensure the - // second condition, skip down the chain until we find the next - // assertion with a property that doesn't match the current one. - // (All these assertions would be skipped via mAlreadyReturned - // checks anyways; this is even a bit faster.) - - do { - mAssertion = (mSource ? mAssertion->mNext : - mAssertion->u.as.mInvNext); - } - while (mAssertion && (next == mAssertion->u.as.mProperty)); - - bool alreadyReturned = false; - for (int32_t i = mAlreadyReturned.Length() - 1; i >= 0; --i) { - if (mAlreadyReturned[i] == next) { - alreadyReturned = true; - break; - } - } - - if (! alreadyReturned) { - mCurrent = next; - NS_ADDREF(mCurrent); - *aResult = true; - return NS_OK; - } - } - - *aResult = false; - return NS_OK; -} - - -NS_IMETHODIMP -InMemoryArcsEnumeratorImpl::GetNext(nsISupports** aResult) -{ - nsresult rv; - - bool hasMore; - rv = HasMoreElements(&hasMore); - if (NS_FAILED(rv)) return rv; - - if (! hasMore) - return NS_ERROR_UNEXPECTED; - - // Add this to the set of things we've already returned so that we - // can ensure uniqueness - mAlreadyReturned.AppendElement(mCurrent); - - // Don't AddRef: we "transfer" ownership to the caller - *aResult = mCurrent; - mCurrent = nullptr; - - return NS_OK; -} - - -//////////////////////////////////////////////////////////////////////// -// InMemoryDataSource - -nsresult -NS_NewRDFInMemoryDataSource(nsISupports* aOuter, const nsIID& aIID, void** aResult) -{ - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - *aResult = nullptr; - - if (aOuter && !aIID.Equals(NS_GET_IID(nsISupports))) { - NS_ERROR("aggregation requires nsISupports"); - return NS_ERROR_ILLEGAL_VALUE; - } - - InMemoryDataSource* datasource = new InMemoryDataSource(aOuter); - NS_ADDREF(datasource); - - datasource->fAggregated.AddRef(); - nsresult rv = datasource->AggregatedQueryInterface(aIID, aResult); // This'll AddRef() - datasource->fAggregated.Release(); - - NS_RELEASE(datasource); - return rv; -} - - -InMemoryDataSource::InMemoryDataSource(nsISupports* aOuter) - : mForwardArcs(PLDHashTable::StubOps(), sizeof(Entry)) - , mReverseArcs(PLDHashTable::StubOps(), sizeof(Entry)) - , mNumObservers(0) - , mReadCount(0) -{ - NS_INIT_AGGREGATED(aOuter); - - mPropagateChanges = true; -} - - -InMemoryDataSource::~InMemoryDataSource() -{ -#ifdef DEBUG_REFS - --gInstanceCount; - fprintf(stdout, "%d - RDF: InMemoryDataSource\n", gInstanceCount); -#endif - - if (mForwardArcs.EntryCount() > 0) { - // This'll release all of the Assertion objects that are - // associated with this data source. We only need to do this - // for the forward arcs, because the reverse arcs table - // indexes the exact same set of resources. - for (auto iter = mForwardArcs.Iter(); !iter.Done(); iter.Next()) { - auto entry = static_cast(iter.Get()); - Assertion* as = entry->mAssertions; - while (as) { - Assertion* doomed = as; - as = as->mNext; - - // Unlink, and release the datasource's reference. - doomed->mNext = doomed->u.as.mInvNext = nullptr; - doomed->Release(); - } - } - } - - MOZ_LOG(gLog, LogLevel::Debug, - ("InMemoryDataSource(%p): destroyed.", this)); -} - - -//////////////////////////////////////////////////////////////////////// - -NS_IMPL_CYCLE_COLLECTION_CLASS(InMemoryDataSource) - -NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(InMemoryDataSource) - NS_IMPL_CYCLE_COLLECTION_UNLINK(mObservers) -NS_IMPL_CYCLE_COLLECTION_UNLINK_END -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_AGGREGATED(InMemoryDataSource) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mObservers) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END - -NS_IMPL_CYCLE_COLLECTING_AGGREGATED(InMemoryDataSource) -NS_INTERFACE_MAP_BEGIN_AGGREGATED(InMemoryDataSource) - NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION_AGGREGATED(InMemoryDataSource) - NS_INTERFACE_MAP_ENTRY(nsIRDFDataSource) - NS_INTERFACE_MAP_ENTRY(nsIRDFInMemoryDataSource) - NS_INTERFACE_MAP_ENTRY(nsIRDFPropagatableDataSource) - NS_INTERFACE_MAP_ENTRY(nsIRDFPurgeableDataSource) - NS_INTERFACE_MAP_ENTRY(rdfIDataSource) -NS_INTERFACE_MAP_END - -//////////////////////////////////////////////////////////////////////// - - -void -InMemoryDataSource::LogOperation(const char* aOperation, - nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue) -{ - if (! MOZ_LOG_TEST(gLog, LogLevel::Debug)) - return; - - nsCString uri; - aSource->GetValue(getter_Copies(uri)); - MOZ_LOG(gLog, LogLevel::Debug, - ("InMemoryDataSource(%p): %s", this, aOperation)); - - MOZ_LOG(gLog, LogLevel::Debug, - (" [(%p)%s]--", aSource, uri.get())); - - aProperty->GetValue(getter_Copies(uri)); - - char tv = (aTruthValue ? '-' : '!'); - MOZ_LOG(gLog, LogLevel::Debug, - (" --%c[(%p)%s]--", tv, aProperty, uri.get())); - - nsCOMPtr resource; - nsCOMPtr literal; - - if ((resource = do_QueryInterface(aTarget)) != nullptr) { - resource->GetValue(getter_Copies(uri)); - MOZ_LOG(gLog, LogLevel::Debug, - (" -->[(%p)%s]", aTarget, uri.get())); - } - else if ((literal = do_QueryInterface(aTarget)) != nullptr) { - nsString value; - literal->GetValue(getter_Copies(value)); - MOZ_LOG(gLog, LogLevel::Debug, - (" -->(\"%s\")\n", NS_ConvertUTF16toUTF8(value).get())); - } - else { - MOZ_LOG(gLog, LogLevel::Debug, - (" -->(unknown-type)\n")); - } -} - - -NS_IMETHODIMP -InMemoryDataSource::GetURI(nsACString& aURI) -{ - aURI.SetIsVoid(true); - return NS_OK; -} - -NS_IMETHODIMP -InMemoryDataSource::GetSource(nsIRDFResource* property, - nsIRDFNode* target, - bool tv, - nsIRDFResource** source) -{ - NS_PRECONDITION(source != nullptr, "null ptr"); - if (! source) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(property != nullptr, "null ptr"); - if (! property) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(target != nullptr, "null ptr"); - if (! target) - return NS_ERROR_NULL_POINTER; - - for (Assertion* as = GetReverseArcs(target); as; as = as->u.as.mInvNext) { - if ((property == as->u.as.mProperty) && (tv == as->u.as.mTruthValue)) { - *source = as->mSource; - NS_ADDREF(*source); - return NS_OK; - } - } - *source = nullptr; - return NS_RDF_NO_VALUE; -} - -NS_IMETHODIMP -InMemoryDataSource::GetTarget(nsIRDFResource* source, - nsIRDFResource* property, - bool tv, - nsIRDFNode** target) -{ - NS_PRECONDITION(source != nullptr, "null ptr"); - if (! source) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(property != nullptr, "null ptr"); - if (! property) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(target != nullptr, "null ptr"); - if (! target) - return NS_ERROR_NULL_POINTER; - - Assertion *as = GetForwardArcs(source); - if (as && as->mHashEntry) { - PLDHashEntryHdr* hdr = as->u.hash.mPropertyHash->Search(property); - Assertion* val = hdr ? static_cast(hdr)->mAssertions : nullptr; - while (val) { - if (tv == val->u.as.mTruthValue) { - *target = val->u.as.mTarget; - NS_IF_ADDREF(*target); - return NS_OK; - } - val = val->mNext; - } - } - else - for (; as != nullptr; as = as->mNext) { - if ((property == as->u.as.mProperty) && (tv == (as->u.as.mTruthValue))) { - *target = as->u.as.mTarget; - NS_ADDREF(*target); - return NS_OK; - } - } - - // If we get here, then there was no target with for the specified - // property & truth value. - *target = nullptr; - return NS_RDF_NO_VALUE; -} - -NS_IMETHODIMP -InMemoryDataSource::HasAssertion(nsIRDFResource* source, - nsIRDFResource* property, - nsIRDFNode* target, - bool tv, - bool* hasAssertion) -{ - if (! source) - return NS_ERROR_NULL_POINTER; - - if (! property) - return NS_ERROR_NULL_POINTER; - - if (! target) - return NS_ERROR_NULL_POINTER; - - Assertion *as = GetForwardArcs(source); - if (as && as->mHashEntry) { - PLDHashEntryHdr* hdr = as->u.hash.mPropertyHash->Search(property); - Assertion* val = hdr ? static_cast(hdr)->mAssertions : nullptr; - while (val) { - if ((val->u.as.mTarget == target) && (tv == (val->u.as.mTruthValue))) { - *hasAssertion = true; - return NS_OK; - } - val = val->mNext; - } - } - else - for (; as != nullptr; as = as->mNext) { - // check target first as its most unique - if (target != as->u.as.mTarget) - continue; - - if (property != as->u.as.mProperty) - continue; - - if (tv != (as->u.as.mTruthValue)) - continue; - - // found it! - *hasAssertion = true; - return NS_OK; - } - - // If we get here, we couldn't find the assertion - *hasAssertion = false; - return NS_OK; -} - -NS_IMETHODIMP -InMemoryDataSource::GetSources(nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue, - nsISimpleEnumerator** aResult) -{ - NS_PRECONDITION(aProperty != nullptr, "null ptr"); - if (! aProperty) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aTarget != nullptr, "null ptr"); - if (! aTarget) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - InMemoryAssertionEnumeratorImpl* result = - new InMemoryAssertionEnumeratorImpl(this, nullptr, aProperty, - aTarget, aTruthValue); - - if (! result) - return NS_ERROR_OUT_OF_MEMORY; - - NS_ADDREF(result); - *aResult = result; - - return NS_OK; -} - -NS_IMETHODIMP -InMemoryDataSource::GetTargets(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - bool aTruthValue, - nsISimpleEnumerator** aResult) -{ - NS_PRECONDITION(aSource != nullptr, "null ptr"); - if (! aSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aProperty != nullptr, "null ptr"); - if (! aProperty) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - InMemoryAssertionEnumeratorImpl* result = - new InMemoryAssertionEnumeratorImpl(this, aSource, aProperty, - nullptr, aTruthValue); - - if (! result) - return NS_ERROR_OUT_OF_MEMORY; - - NS_ADDREF(result); - *aResult = result; - - return NS_OK; -} - - -nsresult -InMemoryDataSource::LockedAssert(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue) -{ - LogOperation("ASSERT", aSource, aProperty, aTarget, aTruthValue); - - Assertion* next = GetForwardArcs(aSource); - Assertion* prev = next; - Assertion* as = nullptr; - - bool haveHash = (next) ? next->mHashEntry : false; - if (haveHash) { - PLDHashEntryHdr* hdr = next->u.hash.mPropertyHash->Search(aProperty); - Assertion* val = hdr ? static_cast(hdr)->mAssertions : nullptr; - while (val) { - if (val->u.as.mTarget == aTarget) { - // Wow, we already had the assertion. Make sure that the - // truth values are correct and bail. - val->u.as.mTruthValue = aTruthValue; - return NS_OK; - } - val = val->mNext; - } - } - else - { - while (next) { - // check target first as its most unique - if (aTarget == next->u.as.mTarget) { - if (aProperty == next->u.as.mProperty) { - // Wow, we already had the assertion. Make sure that the - // truth values are correct and bail. - next->u.as.mTruthValue = aTruthValue; - return NS_OK; - } - } - - prev = next; - next = next->mNext; - } - } - - as = new Assertion(aSource, aProperty, aTarget, aTruthValue); - if (! as) - return NS_ERROR_OUT_OF_MEMORY; - - // Add the datasource's owning reference. - as->AddRef(); - - if (haveHash) - { - PLDHashEntryHdr* hdr = next->u.hash.mPropertyHash->Search(aProperty); - Assertion *asRef = - hdr ? static_cast(hdr)->mAssertions : nullptr; - if (asRef) - { - as->mNext = asRef->mNext; - asRef->mNext = as; - } - else - { - hdr = next->u.hash.mPropertyHash->Add(aProperty, mozilla::fallible); - if (hdr) - { - Entry* entry = static_cast(hdr); - entry->mNode = aProperty; - entry->mAssertions = as; - } - } - } - else - { - // Link it in to the "forward arcs" table - if (!prev) { - SetForwardArcs(aSource, as); - } else { - prev->mNext = as; - } - } - - // Link it in to the "reverse arcs" table - - next = GetReverseArcs(aTarget); - as->u.as.mInvNext = next; - next = as; - SetReverseArcs(aTarget, next); - - return NS_OK; -} - -NS_IMETHODIMP -InMemoryDataSource::Assert(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue) -{ - NS_PRECONDITION(aSource != nullptr, "null ptr"); - if (! aSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aProperty != nullptr, "null ptr"); - if (! aProperty) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aTarget != nullptr, "null ptr"); - if (! aTarget) - return NS_ERROR_NULL_POINTER; - - if (mReadCount) { - NS_WARNING("Writing to InMemoryDataSource during read\n"); - return NS_RDF_ASSERTION_REJECTED; - } - - nsresult rv; - rv = LockedAssert(aSource, aProperty, aTarget, aTruthValue); - if (NS_FAILED(rv)) return rv; - - // notify observers - for (int32_t i = (int32_t)mNumObservers - 1; mPropagateChanges && i >= 0; --i) { - nsIRDFObserver* obs = mObservers[i]; - - // XXX this should never happen, but it does, and we can't figure out why. - NS_ASSERTION(obs, "observer array corrupted!"); - if (! obs) - continue; - - obs->OnAssert(this, aSource, aProperty, aTarget); - // XXX ignore return value? - } - - return NS_RDF_ASSERTION_ACCEPTED; -} - - -nsresult -InMemoryDataSource::LockedUnassert(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget) -{ - LogOperation("UNASSERT", aSource, aProperty, aTarget); - - Assertion* next = GetForwardArcs(aSource); - Assertion* prev = next; - Assertion* root = next; - Assertion* as = nullptr; - - bool haveHash = (next) ? next->mHashEntry : false; - if (haveHash) { - PLDHashEntryHdr* hdr = next->u.hash.mPropertyHash->Search(aProperty); - prev = next = hdr ? static_cast(hdr)->mAssertions : nullptr; - bool first = true; - while (next) { - if (aTarget == next->u.as.mTarget) { - break; - } - first = false; - prev = next; - next = next->mNext; - } - // We don't even have the assertion, so just bail. - if (!next) - return NS_OK; - - as = next; - - if (first) { - root->u.hash.mPropertyHash->RawRemove(hdr); - - if (next && next->mNext) { - PLDHashEntryHdr* hdr = - root->u.hash.mPropertyHash->Add(aProperty, - mozilla::fallible); - if (hdr) { - Entry* entry = static_cast(hdr); - entry->mNode = aProperty; - entry->mAssertions = next->mNext; - } - } - else { - // If this second-level hash empties out, clean it up. - if (!root->u.hash.mPropertyHash->EntryCount()) { - root->Release(); - SetForwardArcs(aSource, nullptr); - } - } - } - else { - prev->mNext = next->mNext; - } - } - else - { - while (next) { - // check target first as its most unique - if (aTarget == next->u.as.mTarget) { - if (aProperty == next->u.as.mProperty) { - if (prev == next) { - SetForwardArcs(aSource, next->mNext); - } else { - prev->mNext = next->mNext; - } - as = next; - break; - } - } - - prev = next; - next = next->mNext; - } - } - // We don't even have the assertion, so just bail. - if (!as) - return NS_OK; - -#ifdef DEBUG - bool foundReverseArc = false; -#endif - - next = prev = GetReverseArcs(aTarget); - while (next) { - if (next == as) { - if (prev == next) { - SetReverseArcs(aTarget, next->u.as.mInvNext); - } else { - prev->u.as.mInvNext = next->u.as.mInvNext; - } -#ifdef DEBUG - foundReverseArc = true; -#endif - break; - } - prev = next; - next = next->u.as.mInvNext; - } - -#ifdef DEBUG - NS_ASSERTION(foundReverseArc, "in-memory db corrupted: unable to find reverse arc"); -#endif - - // Unlink, and release the datasource's reference - as->mNext = as->u.as.mInvNext = nullptr; - as->Release(); - - return NS_OK; -} - -NS_IMETHODIMP -InMemoryDataSource::Unassert(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget) -{ - NS_PRECONDITION(aSource != nullptr, "null ptr"); - if (! aSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aProperty != nullptr, "null ptr"); - if (! aProperty) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aTarget != nullptr, "null ptr"); - if (! aTarget) - return NS_ERROR_NULL_POINTER; - - if (mReadCount) { - NS_WARNING("Writing to InMemoryDataSource during read\n"); - return NS_RDF_ASSERTION_REJECTED; - } - - nsresult rv; - - rv = LockedUnassert(aSource, aProperty, aTarget); - if (NS_FAILED(rv)) return rv; - - // Notify the world - for (int32_t i = int32_t(mNumObservers) - 1; mPropagateChanges && i >= 0; --i) { - nsIRDFObserver* obs = mObservers[i]; - - // XXX this should never happen, but it does, and we can't figure out why. - NS_ASSERTION(obs, "observer array corrupted!"); - if (! obs) - continue; - - obs->OnUnassert(this, aSource, aProperty, aTarget); - // XXX ignore return value? - } - - return NS_RDF_ASSERTION_ACCEPTED; -} - - -NS_IMETHODIMP -InMemoryDataSource::Change(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aOldTarget, - nsIRDFNode* aNewTarget) -{ - NS_PRECONDITION(aSource != nullptr, "null ptr"); - if (! aSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aProperty != nullptr, "null ptr"); - if (! aProperty) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aOldTarget != nullptr, "null ptr"); - if (! aOldTarget) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aNewTarget != nullptr, "null ptr"); - if (! aNewTarget) - return NS_ERROR_NULL_POINTER; - - if (mReadCount) { - NS_WARNING("Writing to InMemoryDataSource during read\n"); - return NS_RDF_ASSERTION_REJECTED; - } - - nsresult rv; - - // XXX We can implement LockedChange() if we decide that this - // is a performance bottleneck. - - rv = LockedUnassert(aSource, aProperty, aOldTarget); - if (NS_FAILED(rv)) return rv; - - rv = LockedAssert(aSource, aProperty, aNewTarget, true); - if (NS_FAILED(rv)) return rv; - - // Notify the world - for (int32_t i = int32_t(mNumObservers) - 1; mPropagateChanges && i >= 0; --i) { - nsIRDFObserver* obs = mObservers[i]; - - // XXX this should never happen, but it does, and we can't figure out why. - NS_ASSERTION(obs, "observer array corrupted!"); - if (! obs) - continue; - - obs->OnChange(this, aSource, aProperty, aOldTarget, aNewTarget); - // XXX ignore return value? - } - - return NS_RDF_ASSERTION_ACCEPTED; -} - - -NS_IMETHODIMP -InMemoryDataSource::Move(nsIRDFResource* aOldSource, - nsIRDFResource* aNewSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget) -{ - NS_PRECONDITION(aOldSource != nullptr, "null ptr"); - if (! aOldSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aNewSource != nullptr, "null ptr"); - if (! aNewSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aProperty != nullptr, "null ptr"); - if (! aProperty) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aTarget != nullptr, "null ptr"); - if (! aTarget) - return NS_ERROR_NULL_POINTER; - - if (mReadCount) { - NS_WARNING("Writing to InMemoryDataSource during read\n"); - return NS_RDF_ASSERTION_REJECTED; - } - - nsresult rv; - - // XXX We can implement LockedMove() if we decide that this - // is a performance bottleneck. - - rv = LockedUnassert(aOldSource, aProperty, aTarget); - if (NS_FAILED(rv)) return rv; - - rv = LockedAssert(aNewSource, aProperty, aTarget, true); - if (NS_FAILED(rv)) return rv; - - // Notify the world - for (int32_t i = int32_t(mNumObservers) - 1; mPropagateChanges && i >= 0; --i) { - nsIRDFObserver* obs = mObservers[i]; - - // XXX this should never happen, but it does, and we can't figure out why. - NS_ASSERTION(obs, "observer array corrupted!"); - if (! obs) - continue; - - obs->OnMove(this, aOldSource, aNewSource, aProperty, aTarget); - // XXX ignore return value? - } - - return NS_RDF_ASSERTION_ACCEPTED; -} - - -NS_IMETHODIMP -InMemoryDataSource::AddObserver(nsIRDFObserver* aObserver) -{ - NS_PRECONDITION(aObserver != nullptr, "null ptr"); - if (! aObserver) - return NS_ERROR_NULL_POINTER; - - mObservers.AppendObject(aObserver); - mNumObservers = mObservers.Count(); - - return NS_OK; -} - -NS_IMETHODIMP -InMemoryDataSource::RemoveObserver(nsIRDFObserver* aObserver) -{ - NS_PRECONDITION(aObserver != nullptr, "null ptr"); - if (! aObserver) - return NS_ERROR_NULL_POINTER; - - mObservers.RemoveObject(aObserver); - // note: use Count() instead of just decrementing - // in case aObserver wasn't in list, for example - mNumObservers = mObservers.Count(); - - return NS_OK; -} - -NS_IMETHODIMP -InMemoryDataSource::HasArcIn(nsIRDFNode *aNode, nsIRDFResource *aArc, bool *result) -{ - Assertion* ass = GetReverseArcs(aNode); - while (ass) { - nsIRDFResource* elbow = ass->u.as.mProperty; - if (elbow == aArc) { - *result = true; - return NS_OK; - } - ass = ass->u.as.mInvNext; - } - *result = false; - return NS_OK; -} - -NS_IMETHODIMP -InMemoryDataSource::HasArcOut(nsIRDFResource *aSource, nsIRDFResource *aArc, bool *result) -{ - Assertion* ass = GetForwardArcs(aSource); - if (ass && ass->mHashEntry) { - PLDHashEntryHdr* hdr = ass->u.hash.mPropertyHash->Search(aArc); - Assertion* val = hdr ? static_cast(hdr)->mAssertions : nullptr; - if (val) { - *result = true; - return NS_OK; - } - ass = ass->mNext; - } - while (ass) { - nsIRDFResource* elbow = ass->u.as.mProperty; - if (elbow == aArc) { - *result = true; - return NS_OK; - } - ass = ass->mNext; - } - *result = false; - return NS_OK; -} - -NS_IMETHODIMP -InMemoryDataSource::ArcLabelsIn(nsIRDFNode* aTarget, nsISimpleEnumerator** aResult) -{ - NS_PRECONDITION(aTarget != nullptr, "null ptr"); - if (! aTarget) - return NS_ERROR_NULL_POINTER; - - InMemoryArcsEnumeratorImpl* result = - new InMemoryArcsEnumeratorImpl(this, nullptr, aTarget); - - if (! result) - return NS_ERROR_OUT_OF_MEMORY; - - NS_ADDREF(result); - *aResult = result; - - return NS_OK; -} - -NS_IMETHODIMP -InMemoryDataSource::ArcLabelsOut(nsIRDFResource* aSource, nsISimpleEnumerator** aResult) -{ - NS_PRECONDITION(aSource != nullptr, "null ptr"); - if (! aSource) - return NS_ERROR_NULL_POINTER; - - InMemoryArcsEnumeratorImpl* result = - new InMemoryArcsEnumeratorImpl(this, aSource, nullptr); - - if (! result) - return NS_ERROR_OUT_OF_MEMORY; - - NS_ADDREF(result); - *aResult = result; - - return NS_OK; -} - - -NS_IMETHODIMP -InMemoryDataSource::GetAllResources(nsISimpleEnumerator** aResult) -{ - nsCOMArray nodes; - nodes.SetCapacity(mForwardArcs.EntryCount()); - - // Get all of our entries into an nsCOMArray - for (auto iter = mForwardArcs.Iter(); !iter.Done(); iter.Next()) { - auto entry = static_cast(iter.Get()); - nodes.AppendObject(entry->mNode); - } - return NS_NewArrayEnumerator(aResult, nodes); -} - -NS_IMETHODIMP -InMemoryDataSource::GetAllCmds(nsIRDFResource* source, - nsISimpleEnumerator/**/** commands) -{ - return(NS_NewEmptyEnumerator(commands)); -} - -NS_IMETHODIMP -InMemoryDataSource::IsCommandEnabled(nsISupports* aSources, - nsIRDFResource* aCommand, - nsISupports* aArguments, - bool* aResult) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -InMemoryDataSource::DoCommand(nsISupports* aSources, - nsIRDFResource* aCommand, - nsISupports* aArguments) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -InMemoryDataSource::BeginUpdateBatch() -{ - for (int32_t i = int32_t(mNumObservers) - 1; mPropagateChanges && i >= 0; --i) { - nsIRDFObserver* obs = mObservers[i]; - obs->OnBeginUpdateBatch(this); - } - return NS_OK; -} - -NS_IMETHODIMP -InMemoryDataSource::EndUpdateBatch() -{ - for (int32_t i = int32_t(mNumObservers) - 1; mPropagateChanges && i >= 0; --i) { - nsIRDFObserver* obs = mObservers[i]; - obs->OnEndUpdateBatch(this); - } - return NS_OK; -} - - - -//////////////////////////////////////////////////////////////////////// -// nsIRDFInMemoryDataSource methods - -NS_IMETHODIMP -InMemoryDataSource::EnsureFastContainment(nsIRDFResource* aSource) -{ - Assertion *as = GetForwardArcs(aSource); - bool haveHash = (as) ? as->mHashEntry : false; - - // if its already a hash, then nothing to do - if (haveHash) return(NS_OK); - - // convert aSource in forward hash into a hash - Assertion *hashAssertion = new Assertion(aSource); - NS_ASSERTION(hashAssertion, "unable to create Assertion"); - if (!hashAssertion) return(NS_ERROR_OUT_OF_MEMORY); - - // Add the datasource's owning reference. - hashAssertion->AddRef(); - - Assertion *first = GetForwardArcs(aSource); - SetForwardArcs(aSource, hashAssertion); - - // mutate references of existing forward assertions into this hash - PLDHashTable *table = hashAssertion->u.hash.mPropertyHash; - Assertion *nextRef; - while(first) { - nextRef = first->mNext; - nsIRDFResource *prop = first->u.as.mProperty; - - PLDHashEntryHdr* hdr = table->Search(prop); - Assertion* val = hdr ? static_cast(hdr)->mAssertions : nullptr; - if (val) { - first->mNext = val->mNext; - val->mNext = first; - } - else { - PLDHashEntryHdr* hdr = table->Add(prop, mozilla::fallible); - if (hdr) { - Entry* entry = static_cast(hdr); - entry->mNode = prop; - entry->mAssertions = first; - first->mNext = nullptr; - } - } - first = nextRef; - } - return(NS_OK); -} - - -//////////////////////////////////////////////////////////////////////// -// nsIRDFPropagatableDataSource methods -NS_IMETHODIMP -InMemoryDataSource::GetPropagateChanges(bool* aPropagateChanges) -{ - *aPropagateChanges = mPropagateChanges; - return NS_OK; -} - -NS_IMETHODIMP -InMemoryDataSource::SetPropagateChanges(bool aPropagateChanges) -{ - mPropagateChanges = aPropagateChanges; - return NS_OK; -} - - -//////////////////////////////////////////////////////////////////////// -// nsIRDFPurgeableDataSource methods - -NS_IMETHODIMP -InMemoryDataSource::Mark(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue, - bool* aDidMark) -{ - NS_PRECONDITION(aSource != nullptr, "null ptr"); - if (! aSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aProperty != nullptr, "null ptr"); - if (! aProperty) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aTarget != nullptr, "null ptr"); - if (! aTarget) - return NS_ERROR_NULL_POINTER; - - Assertion *as = GetForwardArcs(aSource); - if (as && as->mHashEntry) { - PLDHashEntryHdr* hdr = as->u.hash.mPropertyHash->Search(aProperty); - Assertion* val = hdr ? static_cast(hdr)->mAssertions : nullptr; - while (val) { - if ((val->u.as.mTarget == aTarget) && - (aTruthValue == (val->u.as.mTruthValue))) { - - // found it! so mark it. - as->Mark(); - *aDidMark = true; - - LogOperation("MARK", aSource, aProperty, aTarget, aTruthValue); - - return NS_OK; - } - val = val->mNext; - } - } - else for (; as != nullptr; as = as->mNext) { - // check target first as its most unique - if (aTarget != as->u.as.mTarget) - continue; - - if (aProperty != as->u.as.mProperty) - continue; - - if (aTruthValue != (as->u.as.mTruthValue)) - continue; - - // found it! so mark it. - as->Mark(); - *aDidMark = true; - - LogOperation("MARK", aSource, aProperty, aTarget, aTruthValue); - - return NS_OK; - } - - // If we get here, we couldn't find the assertion - *aDidMark = false; - return NS_OK; -} - -NS_IMETHODIMP -InMemoryDataSource::Sweep() -{ - SweepInfo info = { nullptr, &mReverseArcs }; - - // Remove all the assertions, but don't notify anyone. - SweepForwardArcsEntries(&mForwardArcs, &info); - - // Now do the notification. - Assertion* as = info.mUnassertList; - while (as) { - LogOperation("SWEEP", as->mSource, as->u.as.mProperty, as->u.as.mTarget, as->u.as.mTruthValue); - if (!(as->mHashEntry)) - { - for (int32_t i = int32_t(mNumObservers) - 1; mPropagateChanges && i >= 0; --i) { - nsIRDFObserver* obs = mObservers[i]; - // XXXbz other loops over mObservers null-check |obs| here! - obs->OnUnassert(this, as->mSource, as->u.as.mProperty, as->u.as.mTarget); - // XXX ignore return value? - } - } - - Assertion* doomed = as; - as = as->mNext; - - // Unlink, and release the datasource's reference - doomed->mNext = doomed->u.as.mInvNext = nullptr; - doomed->Release(); - } - - return NS_OK; -} - - -void -InMemoryDataSource::SweepForwardArcsEntries(PLDHashTable* aTable, - SweepInfo* aInfo) -{ - for (auto iter = aTable->Iter(); !iter.Done(); iter.Next()) { - auto entry = static_cast(iter.Get()); - - Assertion* as = entry->mAssertions; - if (as && (as->mHashEntry)) { - // Stuff in sub-hashes must be swept recursively (max depth: 1) - SweepForwardArcsEntries(as->u.hash.mPropertyHash, aInfo); - - // If the sub-hash is now empty, clean it up. - if (!as->u.hash.mPropertyHash->EntryCount()) { - as->Release(); - iter.Remove(); - } - continue; - } - - Assertion* prev = nullptr; - while (as) { - if (as->IsMarked()) { - prev = as; - as->Unmark(); - as = as->mNext; - } - else { - // remove from the list of assertions in the datasource - Assertion* next = as->mNext; - if (prev) { - prev->mNext = next; - } - else { - // it's the first one. update the hashtable entry. - entry->mAssertions = next; - } - - // remove from the reverse arcs - PLDHashEntryHdr* hdr = - aInfo->mReverseArcs->Search(as->u.as.mTarget); - NS_ASSERTION(hdr, "no assertion in reverse arcs"); - - Entry* rentry = static_cast(hdr); - Assertion* ras = rentry->mAssertions; - Assertion* rprev = nullptr; - while (ras) { - if (ras == as) { - if (rprev) { - rprev->u.as.mInvNext = ras->u.as.mInvNext; - } - else { - // it's the first one. update the hashtable entry. - rentry->mAssertions = ras->u.as.mInvNext; - } - as->u.as.mInvNext = nullptr; // for my sanity. - break; - } - rprev = ras; - ras = ras->u.as.mInvNext; - } - - // Wow, it was the _only_ one. Unhash it. - if (! rentry->mAssertions) { - aInfo->mReverseArcs->RawRemove(hdr); - } - - // add to the list of assertions to unassert - as->mNext = aInfo->mUnassertList; - aInfo->mUnassertList = as; - - // Advance to the next assertion - as = next; - } - } - - // if no more assertions exist for this resource, then unhash it. - if (! entry->mAssertions) { - iter.Remove(); - } - } -} - -//////////////////////////////////////////////////////////////////////// -// rdfIDataSource methods - -NS_IMETHODIMP -InMemoryDataSource::VisitAllSubjects(rdfITripleVisitor *aVisitor) -{ - // Lock datasource against writes - ++mReadCount; - - // Enumerate all of our entries. - nsresult rv = NS_OK; - for (auto iter = mForwardArcs.Iter(); !iter.Done(); iter.Next()) { - auto entry = static_cast(iter.Get()); - nsresult rv2; - nsCOMPtr subject = do_QueryInterface(entry->mNode, &rv2); - if (NS_FAILED(rv2)) { - NS_WARNING("QI to nsIRDFNode failed"); - continue; - } - rv = aVisitor->Visit(subject, nullptr, nullptr, true); - if (NS_FAILED(rv) || rv == NS_RDF_STOP_VISIT) { - break; - } - } - - // Unlock datasource - --mReadCount; - - return rv; -} - -NS_IMETHODIMP -InMemoryDataSource::VisitAllTriples(rdfITripleVisitor *aVisitor) -{ - // Lock datasource against writes - ++mReadCount; - - // Enumerate all of our entries. - nsresult rv = NS_OK; - for (auto iter = mForwardArcs.Iter(); !iter.Done(); iter.Next()) { - auto entry = static_cast(iter.Get()); - - nsresult rv2; - nsCOMPtr subject = do_QueryInterface(entry->mNode, &rv2); - if (NS_FAILED(rv2)) { - NS_WARNING("QI to nsIRDFNode failed"); - - } else if (entry->mAssertions->mHashEntry) { - for (auto iter = entry->mAssertions->u.hash.mPropertyHash->Iter(); - !iter.Done(); - iter.Next()) { - auto entry = static_cast(iter.Get()); - Assertion* assertion = entry->mAssertions; - while (assertion) { - NS_ASSERTION(!assertion->mHashEntry, "shouldn't have to hashes"); - rv = aVisitor->Visit(subject, assertion->u.as.mProperty, - assertion->u.as.mTarget, - assertion->u.as.mTruthValue); - if (NS_FAILED(rv)) { - goto end; - } - if (rv == NS_RDF_STOP_VISIT) { - goto inner_end; - } - assertion = assertion->mNext; - } - } - - } else { - Assertion* assertion = entry->mAssertions; - while (assertion) { - NS_ASSERTION(!assertion->mHashEntry, "shouldn't have to hashes"); - rv = aVisitor->Visit(subject, assertion->u.as.mProperty, - assertion->u.as.mTarget, - assertion->u.as.mTruthValue); - if (NS_FAILED(rv) || rv == NS_RDF_STOP_VISIT) { - goto end; - } - assertion = assertion->mNext; - } - } - - inner_end: - (void) 0; - } - - end: - // Unlock datasource - --mReadCount; - - return rv; -} - -//////////////////////////////////////////////////////////////////////// - diff --git a/rdf/base/nsNameSpaceMap.cpp b/rdf/base/nsNameSpaceMap.cpp deleted file mode 100644 index 4ddf945c6f54..000000000000 --- a/rdf/base/nsNameSpaceMap.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* -*- 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/. */ - -#include "nsNameSpaceMap.h" -#include "nsReadableUtils.h" - -nsNameSpaceMap::nsNameSpaceMap() - : mEntries(nullptr) -{ - MOZ_COUNT_CTOR(nsNameSpaceMap); -} - -nsNameSpaceMap::~nsNameSpaceMap() -{ - MOZ_COUNT_DTOR(nsNameSpaceMap); - - while (mEntries) { - Entry* doomed = mEntries; - mEntries = mEntries->mNext; - delete doomed; - } -} - -nsresult -nsNameSpaceMap::Put(const nsAString& aURI, nsAtom* aPrefix) -{ - nsCString uriUTF8; - AppendUTF16toUTF8(aURI, uriUTF8); - return Put(uriUTF8, aPrefix); -} - -nsresult -nsNameSpaceMap::Put(const nsACString& aURI, nsAtom* aPrefix) -{ - Entry* entry; - - // Make sure we're not adding a duplicate - for (entry = mEntries; entry != nullptr; entry = entry->mNext) { - if (entry->mURI == aURI || entry->mPrefix == aPrefix) - return NS_ERROR_FAILURE; - } - - entry = new Entry(aURI, aPrefix); - if (! entry) - return NS_ERROR_OUT_OF_MEMORY; - - entry->mNext = mEntries; - mEntries = entry; - return NS_OK; -} - -nsNameSpaceMap::const_iterator -nsNameSpaceMap::GetNameSpaceOf(const nsACString& aURI) const -{ - for (Entry* entry = mEntries; entry != nullptr; entry = entry->mNext) { - if (StringBeginsWith(aURI, entry->mURI)) - return const_iterator(entry); - } - - return last(); -} diff --git a/rdf/base/nsNameSpaceMap.h b/rdf/base/nsNameSpaceMap.h deleted file mode 100644 index 96a80fd13f13..000000000000 --- a/rdf/base/nsNameSpaceMap.h +++ /dev/null @@ -1,98 +0,0 @@ -/* -*- 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/. */ - -#ifndef nsNameSpaceMap_h__ -#define nsNameSpaceMap_h__ - -#include "nsCOMPtr.h" -#include "nsString.h" -#include "nsAtom.h" - -class nsNameSpaceMap -{ -public: - class Entry { - public: - Entry(const nsACString& aURI, nsAtom* aPrefix) - : mURI(aURI), mPrefix(aPrefix), mNext(nullptr) { - MOZ_COUNT_CTOR(nsNameSpaceMap::Entry); } - - ~Entry() { MOZ_COUNT_DTOR(nsNameSpaceMap::Entry); } - - nsCString mURI; - RefPtr mPrefix; - - Entry* mNext; - }; - - nsNameSpaceMap(); - ~nsNameSpaceMap(); - - nsresult - Put(const nsAString& aURI, nsAtom* aPrefix); - - nsresult - Put(const nsACString& aURI, nsAtom* aPrefix); - - class const_iterator { - protected: - friend class nsNameSpaceMap; - - explicit const_iterator(const Entry* aCurrent) - : mCurrent(aCurrent) {} - - const Entry* mCurrent; - - public: - const_iterator() - : mCurrent(nullptr) {} - - const_iterator(const const_iterator& iter) - : mCurrent(iter.mCurrent) {} - - const_iterator& - operator=(const const_iterator& iter) { - mCurrent = iter.mCurrent; - return *this; } - - const_iterator& - operator++() { - mCurrent = mCurrent->mNext; - return *this; } - - const_iterator - operator++(int) { - const_iterator tmp(*this); - mCurrent = mCurrent->mNext; - return tmp; } - - const Entry* operator->() const { return mCurrent; } - - const Entry& operator*() const { return *mCurrent; } - - bool - operator==(const const_iterator& iter) const { - return mCurrent == iter.mCurrent; } - - bool - operator!=(const const_iterator& iter) const { - return ! iter.operator==(*this); } - }; - - const_iterator first() const { - return const_iterator(mEntries); } - - const_iterator last() const { - return const_iterator(nullptr); } - - const_iterator GetNameSpaceOf(const nsACString& aURI) const; - -protected: - Entry* mEntries; -}; - - -#endif // nsNameSpaceMap_h__ diff --git a/rdf/base/nsRDFBaseDataSources.h b/rdf/base/nsRDFBaseDataSources.h deleted file mode 100644 index 0243e1359559..000000000000 --- a/rdf/base/nsRDFBaseDataSources.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -*- 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 header file just contains prototypes for the factory methods - for "builtin" data sources that are included in rdf.dll. - - Each of these data sources is exposed to the external world via its - CID in ../include/nsRDFCID.h. - -*/ - -#ifndef nsBaseDataSources_h__ -#define nsBaseDataSources_h__ - -#include "nsError.h" -class nsIRDFDataSource; - -// in nsInMemoryDataSource.cpp -nsresult -NS_NewRDFInMemoryDataSource(nsISupports* aOuter, const nsIID& aIID, void** aResult); - -// in nsRDFXMLDataSource.cpp -extern nsresult -NS_NewRDFXMLDataSource(nsIRDFDataSource** aResult); - -#endif // nsBaseDataSources_h__ - - diff --git a/rdf/base/nsRDFContainer.cpp b/rdf/base/nsRDFContainer.cpp deleted file mode 100644 index 1ef97ab0f0d3..000000000000 --- a/rdf/base/nsRDFContainer.cpp +++ /dev/null @@ -1,724 +0,0 @@ -/* -*- 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/. */ - -/* - - Implementation for the RDF container. - - Notes - ----- - - 1. RDF containers are one-indexed. This means that a lot of the loops - that you'd normally think you'd write like this: - - for (i = 0; i < count; ++i) {} - - You've gotta write like this: - - for (i = 1; i <= count; ++i) {} - - "Sure, right, yeah, of course.", you say. Well maybe I'm just - thick, but it's easy to slip up. - - 2. The RDF:nextVal property on the container is an - implementation-level hack that is used to quickly compute the - next value for appending to the container. It will no doubt - become royally screwed up in the case of aggregation. - - 3. The RDF:nextVal property is also used to retrieve the count of - elements in the container. - - */ - - -#include "nsCOMPtr.h" -#include "nsIRDFContainer.h" -#include "nsIRDFContainerUtils.h" -#include "nsIRDFInMemoryDataSource.h" -#include "nsIRDFPropagatableDataSource.h" -#include "nsIRDFService.h" -#include "nsIServiceManager.h" -#include "nsRDFCID.h" -#include "nsString.h" -#include "rdf.h" - -#define RDF_SEQ_LIST_LIMIT 8 - -class RDFContainerImpl : public nsIRDFContainer -{ -public: - - // nsISupports interface - NS_DECL_ISUPPORTS - - // nsIRDFContainer interface - NS_DECL_NSIRDFCONTAINER - -private: - friend nsresult NS_NewRDFContainer(nsIRDFContainer** aResult); - - RDFContainerImpl(); - virtual ~RDFContainerImpl(); - - nsresult Init(); - - nsresult Renumber(int32_t aStartIndex, int32_t aIncrement); - nsresult SetNextValue(int32_t aIndex); - nsresult GetNextValue(nsIRDFResource** aResult); - - nsIRDFDataSource* mDataSource; - nsIRDFResource* mContainer; - - // pseudo constants - static int32_t gRefCnt; - static nsIRDFService* gRDFService; - static nsIRDFContainerUtils* gRDFContainerUtils; - static nsIRDFResource* kRDF_nextVal; -}; - - -int32_t RDFContainerImpl::gRefCnt = 0; -nsIRDFService* RDFContainerImpl::gRDFService; -nsIRDFContainerUtils* RDFContainerImpl::gRDFContainerUtils; -nsIRDFResource* RDFContainerImpl::kRDF_nextVal; - -//////////////////////////////////////////////////////////////////////// -// nsISupports interface - -NS_IMPL_ISUPPORTS(RDFContainerImpl, nsIRDFContainer) - - - -//////////////////////////////////////////////////////////////////////// -// nsIRDFContainer interface - -NS_IMETHODIMP -RDFContainerImpl::GetDataSource(nsIRDFDataSource** _retval) -{ - *_retval = mDataSource; - NS_IF_ADDREF(*_retval); - return NS_OK; -} - - -NS_IMETHODIMP -RDFContainerImpl::GetResource(nsIRDFResource** _retval) -{ - *_retval = mContainer; - NS_IF_ADDREF(*_retval); - return NS_OK; -} - - -NS_IMETHODIMP -RDFContainerImpl::Init(nsIRDFDataSource *aDataSource, nsIRDFResource *aContainer) -{ - NS_PRECONDITION(aDataSource != nullptr, "null ptr"); - if (! aDataSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aContainer != nullptr, "null ptr"); - if (! aContainer) - return NS_ERROR_NULL_POINTER; - - nsresult rv; - bool isContainer; - rv = gRDFContainerUtils->IsContainer(aDataSource, aContainer, &isContainer); - if (NS_FAILED(rv)) return rv; - - // ``throw'' if we can't create a container on the specified - // datasource/resource combination. - if (! isContainer) - return NS_ERROR_FAILURE; - - NS_IF_RELEASE(mDataSource); - mDataSource = aDataSource; - NS_ADDREF(mDataSource); - - NS_IF_RELEASE(mContainer); - mContainer = aContainer; - NS_ADDREF(mContainer); - - return NS_OK; -} - - -NS_IMETHODIMP -RDFContainerImpl::GetCount(int32_t *aCount) -{ - if (!mDataSource || !mContainer) - return NS_ERROR_NOT_INITIALIZED; - - nsresult rv; - - // Get the next value, which hangs off of the bag via the - // RDF:nextVal property. This is the _next value_ that will get - // assigned in a one-indexed array. So, it's actually _one more_ - // than the actual count of elements in the container. - // - // XXX To handle aggregation, this should probably be a - // GetTargets() that enumerates all of the values and picks the - // largest one. - nsCOMPtr nextValNode; - rv = mDataSource->GetTarget(mContainer, kRDF_nextVal, true, getter_AddRefs(nextValNode)); - if (NS_FAILED(rv)) return rv; - - if (rv == NS_RDF_NO_VALUE) - return NS_ERROR_UNEXPECTED; - - nsCOMPtr nextValLiteral; - rv = nextValNode->QueryInterface(NS_GET_IID(nsIRDFLiteral), getter_AddRefs(nextValLiteral)); - if (NS_FAILED(rv)) return rv; - - const char16_t *s; - rv = nextValLiteral->GetValueConst( &s ); - if (NS_FAILED(rv)) return rv; - - nsAutoString nextValStr(s); - - int32_t nextVal; - nsresult err; - nextVal = nextValStr.ToInteger(&err); - if (NS_FAILED(err)) - return NS_ERROR_UNEXPECTED; - - *aCount = nextVal - 1; - return NS_OK; -} - - -NS_IMETHODIMP -RDFContainerImpl::GetElements(nsISimpleEnumerator **_retval) -{ - if (!mDataSource || !mContainer) - return NS_ERROR_NOT_INITIALIZED; - - return NS_NewContainerEnumerator(mDataSource, mContainer, _retval); -} - - -NS_IMETHODIMP -RDFContainerImpl::AppendElement(nsIRDFNode *aElement) -{ - if (!mDataSource || !mContainer) - return NS_ERROR_NOT_INITIALIZED; - - NS_PRECONDITION(aElement != nullptr, "null ptr"); - if (! aElement) - return NS_ERROR_NULL_POINTER; - - nsresult rv; - - nsCOMPtr nextVal; - rv = GetNextValue(getter_AddRefs(nextVal)); - if (NS_FAILED(rv)) return rv; - - rv = mDataSource->Assert(mContainer, nextVal, aElement, true); - if (NS_FAILED(rv)) return rv; - - return NS_OK; -} - - -NS_IMETHODIMP -RDFContainerImpl::RemoveElement(nsIRDFNode *aElement, bool aRenumber) -{ - if (!mDataSource || !mContainer) - return NS_ERROR_NOT_INITIALIZED; - - NS_PRECONDITION(aElement != nullptr, "null ptr"); - if (! aElement) - return NS_ERROR_NULL_POINTER; - - nsresult rv; - - int32_t idx; - rv = IndexOf(aElement, &idx); - if (NS_FAILED(rv)) return rv; - - if (idx < 0) - return NS_OK; - - // Remove the element. - nsCOMPtr ordinal; - rv = gRDFContainerUtils->IndexToOrdinalResource(idx, - getter_AddRefs(ordinal)); - if (NS_FAILED(rv)) return rv; - - rv = mDataSource->Unassert(mContainer, ordinal, aElement); - if (NS_FAILED(rv)) return rv; - - if (aRenumber) { - // Now slide the rest of the collection backwards to fill in - // the gap. This will have the side effect of completely - // renumber the container from index to the end. - rv = Renumber(idx + 1, -1); - if (NS_FAILED(rv)) return rv; - } - - return NS_OK; -} - - -NS_IMETHODIMP -RDFContainerImpl::InsertElementAt(nsIRDFNode *aElement, int32_t aIndex, bool aRenumber) -{ - if (!mDataSource || !mContainer) - return NS_ERROR_NOT_INITIALIZED; - - NS_PRECONDITION(aElement != nullptr, "null ptr"); - if (! aElement) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aIndex >= 1, "illegal value"); - if (aIndex < 1) - return NS_ERROR_ILLEGAL_VALUE; - - nsresult rv; - - int32_t count; - rv = GetCount(&count); - if (NS_FAILED(rv)) return rv; - - NS_ASSERTION(aIndex <= count + 1, "illegal value"); - if (aIndex > count + 1) - return NS_ERROR_ILLEGAL_VALUE; - - if (aRenumber) { - // Make a hole for the element. This will have the side effect of - // completely renumbering the container from 'aIndex' to 'count', - // and will spew assertions. - rv = Renumber(aIndex, +1); - if (NS_FAILED(rv)) return rv; - } - - nsCOMPtr ordinal; - rv = gRDFContainerUtils->IndexToOrdinalResource(aIndex, getter_AddRefs(ordinal)); - if (NS_FAILED(rv)) return rv; - - rv = mDataSource->Assert(mContainer, ordinal, aElement, true); - if (NS_FAILED(rv)) return rv; - - return NS_OK; -} - -NS_IMETHODIMP -RDFContainerImpl::RemoveElementAt(int32_t aIndex, bool aRenumber, nsIRDFNode** _retval) -{ - if (!mDataSource || !mContainer) - return NS_ERROR_NOT_INITIALIZED; - - *_retval = nullptr; - - if (aIndex< 1) - return NS_ERROR_ILLEGAL_VALUE; - - nsresult rv; - - int32_t count; - rv = GetCount(&count); - if (NS_FAILED(rv)) return rv; - - if (aIndex > count) - return NS_ERROR_ILLEGAL_VALUE; - - nsCOMPtr ordinal; - rv = gRDFContainerUtils->IndexToOrdinalResource(aIndex, getter_AddRefs(ordinal)); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr old; - rv = mDataSource->GetTarget(mContainer, ordinal, true, getter_AddRefs(old)); - if (NS_FAILED(rv)) return rv; - - if (rv == NS_OK) { - rv = mDataSource->Unassert(mContainer, ordinal, old); - if (NS_FAILED(rv)) return rv; - - if (aRenumber) { - // Now slide the rest of the collection backwards to fill in - // the gap. This will have the side effect of completely - // renumber the container from index to the end. - rv = Renumber(aIndex + 1, -1); - if (NS_FAILED(rv)) return rv; - } - } - - old.swap(*_retval); - - return NS_OK; -} - -NS_IMETHODIMP -RDFContainerImpl::IndexOf(nsIRDFNode *aElement, int32_t *aIndex) -{ - if (!mDataSource || !mContainer) - return NS_ERROR_NOT_INITIALIZED; - - return gRDFContainerUtils->IndexOf(mDataSource, mContainer, - aElement, aIndex); -} - - -//////////////////////////////////////////////////////////////////////// - - -RDFContainerImpl::RDFContainerImpl() - : mDataSource(nullptr), mContainer(nullptr) -{ -} - - -nsresult -RDFContainerImpl::Init() -{ - if (gRefCnt++ == 0) { - nsresult rv; - - NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); - rv = CallGetService(kRDFServiceCID, &gRDFService); - if (NS_FAILED(rv)) { - NS_ERROR("unable to get RDF service"); - return rv; - } - - rv = gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "nextVal"), - &kRDF_nextVal); - if (NS_FAILED(rv)) return rv; - - NS_DEFINE_CID(kRDFContainerUtilsCID, NS_RDFCONTAINERUTILS_CID); - rv = CallGetService(kRDFContainerUtilsCID, &gRDFContainerUtils); - if (NS_FAILED(rv)) { - NS_ERROR("unable to get RDF container utils service"); - return rv; - } - } - - return NS_OK; -} - - -RDFContainerImpl::~RDFContainerImpl() -{ -#ifdef DEBUG_REFS - --gInstanceCount; - fprintf(stdout, "%d - RDF: RDFContainerImpl\n", gInstanceCount); -#endif - - NS_IF_RELEASE(mContainer); - NS_IF_RELEASE(mDataSource); - - if (--gRefCnt == 0) { - NS_IF_RELEASE(gRDFContainerUtils); - NS_IF_RELEASE(gRDFService); - NS_IF_RELEASE(kRDF_nextVal); - } -} - - -nsresult -NS_NewRDFContainer(nsIRDFContainer** aResult) -{ - RDFContainerImpl* result = new RDFContainerImpl(); - if (! result) - return NS_ERROR_OUT_OF_MEMORY; - - nsresult rv; - rv = result->Init(); - if (NS_FAILED(rv)) { - delete result; - return rv; - } - - NS_ADDREF(result); - *aResult = result; - return NS_OK; -} - - -nsresult -NS_NewRDFContainer(nsIRDFDataSource* aDataSource, - nsIRDFResource* aResource, - nsIRDFContainer** aResult) -{ - nsresult rv; - rv = NS_NewRDFContainer(aResult); - if (NS_FAILED(rv)) return rv; - - rv = (*aResult)->Init(aDataSource, aResource); - if (NS_FAILED(rv)) { - NS_RELEASE(*aResult); - } - return rv; -} - - -nsresult -RDFContainerImpl::Renumber(int32_t aStartIndex, int32_t aIncrement) -{ - if (!mDataSource || !mContainer) - return NS_ERROR_NOT_INITIALIZED; - - // Renumber the elements in the container starting with - // aStartIndex, updating each element's index by aIncrement. For - // example, - // - // (1:a 2:b 3:c) - // Renumber(2, +1); - // (1:a 3:b 4:c) - // Renumber(3, -1); - // (1:a 2:b 3:c) - // - nsresult rv; - - if (! aIncrement) - return NS_OK; - - int32_t count; - rv = GetCount(&count); - if (NS_FAILED(rv)) return rv; - - if (aIncrement > 0) { - // Update the container's nextVal to reflect the - // renumbering. We do this now if aIncrement > 0 because we'll - // want to be able to acknowledge that new elements are in the - // container. - rv = SetNextValue(count + aIncrement + 1); - if (NS_FAILED(rv)) return rv; - } - - int32_t i; - if (aIncrement < 0) { - i = aStartIndex; - } - else { - i = count; // we're one-indexed. - } - - // Note: once we disable notifications, don't exit this method until - // enabling notifications - nsCOMPtr propagatable = - do_QueryInterface(mDataSource); - if (propagatable) { - propagatable->SetPropagateChanges(false); - } - - bool err = false; - while (!err && ((aIncrement < 0) ? (i <= count) : (i >= aStartIndex))) - { - nsCOMPtr oldOrdinal; - rv = gRDFContainerUtils->IndexToOrdinalResource(i, getter_AddRefs(oldOrdinal)); - if (NS_FAILED(rv)) - { - err = true; - continue; - } - - nsCOMPtr newOrdinal; - rv = gRDFContainerUtils->IndexToOrdinalResource(i + aIncrement, getter_AddRefs(newOrdinal)); - if (NS_FAILED(rv)) - { - err = true; - continue; - } - - // Because of aggregation, we need to be paranoid about the - // possibility that >1 element may be present per ordinal. If - // there _is_ in fact more than one element, they'll all get - // assigned to the same new ordinal; i.e., we don't make any - // attempt to "clean up" the duplicate numbering. (Doing so - // would require two passes.) - nsCOMPtr targets; - rv = mDataSource->GetTargets(mContainer, oldOrdinal, true, getter_AddRefs(targets)); - if (NS_FAILED(rv)) - { - err = true; - continue; - } - - while (1) { - bool hasMore; - rv = targets->HasMoreElements(&hasMore); - if (NS_FAILED(rv)) - { - err = true; - break; - } - - if (! hasMore) - break; - - nsCOMPtr isupports; - rv = targets->GetNext(getter_AddRefs(isupports)); - if (NS_FAILED(rv)) - { - err = true; - break; - } - - nsCOMPtr element( do_QueryInterface(isupports) ); - NS_ASSERTION(element != nullptr, "something funky in the enumerator"); - if (! element) - { - err = true; - rv = NS_ERROR_UNEXPECTED; - break; - } - - rv = mDataSource->Unassert(mContainer, oldOrdinal, element); - if (NS_FAILED(rv)) - { - err = true; - break; - } - - rv = mDataSource->Assert(mContainer, newOrdinal, element, true); - if (NS_FAILED(rv)) - { - err = true; - break; - } - } - - i -= aIncrement; - } - - if (!err && (aIncrement < 0)) - { - // Update the container's nextVal to reflect the - // renumbering. We do this now if aIncrement < 0 because, up - // until this point, we'll want people to be able to find - // things that are still "at the end". - rv = SetNextValue(count + aIncrement + 1); - if (NS_FAILED(rv)) - { - err = true; - } - } - - // Note: MUST enable notifications before exiting this method - if (propagatable) { - propagatable->SetPropagateChanges(true); - } - - if (err) return(rv); - - return NS_OK; -} - - - -nsresult -RDFContainerImpl::SetNextValue(int32_t aIndex) -{ - if (!mDataSource || !mContainer) - return NS_ERROR_NOT_INITIALIZED; - - nsresult rv; - - // Remove the current value of nextVal, if there is one. - nsCOMPtr nextValNode; - if (NS_SUCCEEDED(rv = mDataSource->GetTarget(mContainer, - kRDF_nextVal, - true, - getter_AddRefs(nextValNode)))) { - if (NS_FAILED(rv = mDataSource->Unassert(mContainer, kRDF_nextVal, nextValNode))) { - NS_ERROR("unable to update nextVal"); - return rv; - } - } - - nsAutoString s; - s.AppendInt(aIndex, 10); - - nsCOMPtr nextVal; - if (NS_FAILED(rv = gRDFService->GetLiteral(s.get(), getter_AddRefs(nextVal)))) { - NS_ERROR("unable to get nextVal literal"); - return rv; - } - - rv = mDataSource->Assert(mContainer, kRDF_nextVal, nextVal, true); - if (rv != NS_RDF_ASSERTION_ACCEPTED) { - NS_ERROR("unable to update nextVal"); - return NS_ERROR_FAILURE; - } - - return NS_OK; -} - - -nsresult -RDFContainerImpl::GetNextValue(nsIRDFResource** aResult) -{ - if (!mDataSource || !mContainer) - return NS_ERROR_NOT_INITIALIZED; - - nsresult rv; - - // Get the next value, which hangs off of the bag via the - // RDF:nextVal property. - nsCOMPtr nextValNode; - rv = mDataSource->GetTarget(mContainer, kRDF_nextVal, true, getter_AddRefs(nextValNode)); - if (NS_FAILED(rv)) return rv; - - if (rv == NS_RDF_NO_VALUE) - return NS_ERROR_UNEXPECTED; - - nsCOMPtr nextValLiteral; - rv = nextValNode->QueryInterface(NS_GET_IID(nsIRDFLiteral), getter_AddRefs(nextValLiteral)); - if (NS_FAILED(rv)) return rv; - - const char16_t* s; - rv = nextValLiteral->GetValueConst(&s); - if (NS_FAILED(rv)) return rv; - - int32_t nextVal = 0; - { - for (const char16_t* p = s; *p != 0; ++p) { - NS_ASSERTION(*p >= '0' && *p <= '9', "not a digit"); - if (*p < '0' || *p > '9') - break; - - nextVal *= 10; - nextVal += *p - '0'; - } - } - - static const char kRDFNameSpaceURI[] = RDF_NAMESPACE_URI; - nsAutoCStringN nextValStr; - nextValStr = kRDFNameSpaceURI; - nextValStr.Append('_'); - nextValStr.AppendInt(nextVal, 10); - - rv = gRDFService->GetResource(nextValStr, aResult); - if (NS_FAILED(rv)) return rv; - - // Now increment the RDF:nextVal property. - rv = mDataSource->Unassert(mContainer, kRDF_nextVal, nextValLiteral); - if (NS_FAILED(rv)) return rv; - - ++nextVal; - nextValStr.Truncate(); - nextValStr.AppendInt(nextVal, 10); - - rv = gRDFService->GetLiteral(NS_ConvertASCIItoUTF16(nextValStr).get(), getter_AddRefs(nextValLiteral)); - if (NS_FAILED(rv)) return rv; - - rv = mDataSource->Assert(mContainer, kRDF_nextVal, nextValLiteral, true); - if (NS_FAILED(rv)) return rv; - - if (RDF_SEQ_LIST_LIMIT == nextVal) - { - // focal point for RDF container mutation; - // basically, provide a hint to allow for fast access - nsCOMPtr inMem = do_QueryInterface(mDataSource); - if (inMem) - { - // ignore error; failure just means slower access - (void)inMem->EnsureFastContainment(mContainer); - } - } - - return NS_OK; -} diff --git a/rdf/base/nsRDFContainerUtils.cpp b/rdf/base/nsRDFContainerUtils.cpp deleted file mode 100644 index d92f00c3e8a9..000000000000 --- a/rdf/base/nsRDFContainerUtils.cpp +++ /dev/null @@ -1,513 +0,0 @@ -/* -*- 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/. */ - -/* - - Implementation for the RDF container utils. - - */ - - -#include "nsCOMPtr.h" -#include "nsIServiceManager.h" -#include "nsIRDFContainer.h" -#include "nsIRDFContainerUtils.h" -#include "nsIRDFService.h" -#include "nsRDFCID.h" -#include "nsString.h" -#include "plstr.h" -#include "rdf.h" -#include "rdfutil.h" - -class RDFContainerUtilsImpl : public nsIRDFContainerUtils -{ -public: - // nsISupports interface - NS_DECL_ISUPPORTS - - // nsIRDFContainerUtils interface - NS_DECL_NSIRDFCONTAINERUTILS - -private: - friend nsresult NS_NewRDFContainerUtils(nsIRDFContainerUtils** aResult); - - RDFContainerUtilsImpl(); - virtual ~RDFContainerUtilsImpl(); - - nsresult MakeContainer(nsIRDFDataSource* aDataSource, - nsIRDFResource* aResource, - nsIRDFResource* aType, - nsIRDFContainer** aResult); - - bool IsA(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource, nsIRDFResource* aType); - - // pseudo constants - static int32_t gRefCnt; - static nsIRDFService* gRDFService; - static nsIRDFResource* kRDF_instanceOf; - static nsIRDFResource* kRDF_nextVal; - static nsIRDFResource* kRDF_Bag; - static nsIRDFResource* kRDF_Seq; - static nsIRDFResource* kRDF_Alt; - static nsIRDFLiteral* kOne; - static const char kRDFNameSpaceURI[]; -}; - -int32_t RDFContainerUtilsImpl::gRefCnt = 0; -nsIRDFService* RDFContainerUtilsImpl::gRDFService; -nsIRDFResource* RDFContainerUtilsImpl::kRDF_instanceOf; -nsIRDFResource* RDFContainerUtilsImpl::kRDF_nextVal; -nsIRDFResource* RDFContainerUtilsImpl::kRDF_Bag; -nsIRDFResource* RDFContainerUtilsImpl::kRDF_Seq; -nsIRDFResource* RDFContainerUtilsImpl::kRDF_Alt; -nsIRDFLiteral* RDFContainerUtilsImpl::kOne; -const char RDFContainerUtilsImpl::kRDFNameSpaceURI[] = RDF_NAMESPACE_URI; - -//////////////////////////////////////////////////////////////////////// -// nsISupports interface - -NS_IMPL_ISUPPORTS(RDFContainerUtilsImpl, nsIRDFContainerUtils) - -//////////////////////////////////////////////////////////////////////// -// nsIRDFContainerUtils interface - -NS_IMETHODIMP -RDFContainerUtilsImpl::IsOrdinalProperty(nsIRDFResource *aProperty, bool *_retval) -{ - NS_PRECONDITION(aProperty != nullptr, "null ptr"); - if (! aProperty) - return NS_ERROR_NULL_POINTER; - - nsresult rv; - - const char *propertyStr; - rv = aProperty->GetValueConst( &propertyStr ); - if (NS_FAILED(rv)) return rv; - - if (PL_strncmp(propertyStr, kRDFNameSpaceURI, sizeof(kRDFNameSpaceURI) - 1) != 0) { - *_retval = false; - return NS_OK; - } - - const char* s = propertyStr; - s += sizeof(kRDFNameSpaceURI) - 1; - if (*s != '_') { - *_retval = false; - return NS_OK; - } - - ++s; - while (*s) { - if (*s < '0' || *s > '9') { - *_retval = false; - return NS_OK; - } - - ++s; - } - - *_retval = true; - return NS_OK; -} - - -NS_IMETHODIMP -RDFContainerUtilsImpl::IndexToOrdinalResource(int32_t aIndex, nsIRDFResource **aOrdinal) -{ - NS_PRECONDITION(aIndex > 0, "illegal value"); - if (aIndex <= 0) - return NS_ERROR_ILLEGAL_VALUE; - - nsAutoCString uri(kRDFNameSpaceURI); - uri.Append('_'); - uri.AppendInt(aIndex); - - nsresult rv = gRDFService->GetResource(uri, aOrdinal); - NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get ordinal resource"); - if (NS_FAILED(rv)) return rv; - - return NS_OK; -} - - -NS_IMETHODIMP -RDFContainerUtilsImpl::OrdinalResourceToIndex(nsIRDFResource *aOrdinal, int32_t *aIndex) -{ - NS_PRECONDITION(aOrdinal != nullptr, "null ptr"); - if (! aOrdinal) - return NS_ERROR_NULL_POINTER; - - const char *ordinalStr; - if (NS_FAILED(aOrdinal->GetValueConst( &ordinalStr ))) - return NS_ERROR_FAILURE; - - const char* s = ordinalStr; - if (PL_strncmp(s, kRDFNameSpaceURI, sizeof(kRDFNameSpaceURI) - 1) != 0) { - NS_ERROR("not an ordinal"); - return NS_ERROR_UNEXPECTED; - } - - s += sizeof(kRDFNameSpaceURI) - 1; - if (*s != '_') { - NS_ERROR("not an ordinal"); - return NS_ERROR_UNEXPECTED; - } - - int32_t idx = 0; - - ++s; - while (*s) { - if (*s < '0' || *s > '9') { - NS_ERROR("not an ordinal"); - return NS_ERROR_UNEXPECTED; - } - - idx *= 10; - idx += (*s - '0'); - - ++s; - } - - *aIndex = idx; - return NS_OK; -} - -NS_IMETHODIMP -RDFContainerUtilsImpl::IsContainer(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, bool *_retval) -{ - NS_PRECONDITION(aDataSource != nullptr, "null ptr"); - if (! aDataSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aResource != nullptr, "null ptr"); - if (! aResource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(_retval != nullptr, "null ptr"); - if (! _retval) - return NS_ERROR_NULL_POINTER; - - if (IsA(aDataSource, aResource, kRDF_Seq) || - IsA(aDataSource, aResource, kRDF_Bag) || - IsA(aDataSource, aResource, kRDF_Alt)) { - *_retval = true; - } - else { - *_retval = false; - } - return NS_OK; -} - - -NS_IMETHODIMP -RDFContainerUtilsImpl::IsEmpty(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource, bool* _retval) -{ - if (! aDataSource) - return NS_ERROR_NULL_POINTER; - - nsresult rv; - - // By default, say that we're an empty container. Even if we're not - // really even a container. - *_retval = true; - - nsCOMPtr nextValNode; - rv = aDataSource->GetTarget(aResource, kRDF_nextVal, true, getter_AddRefs(nextValNode)); - if (NS_FAILED(rv)) return rv; - - if (rv == NS_RDF_NO_VALUE) - return NS_OK; - - nsCOMPtr nextValLiteral; - rv = nextValNode->QueryInterface(NS_GET_IID(nsIRDFLiteral), getter_AddRefs(nextValLiteral)); - if (NS_FAILED(rv)) return rv; - - if (nextValLiteral.get() != kOne) - *_retval = false; - - return NS_OK; -} - - -NS_IMETHODIMP -RDFContainerUtilsImpl::IsBag(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, bool *_retval) -{ - NS_PRECONDITION(aDataSource != nullptr, "null ptr"); - if (! aDataSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aResource != nullptr, "null ptr"); - if (! aResource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(_retval != nullptr, "null ptr"); - if (! _retval) - return NS_ERROR_NULL_POINTER; - - *_retval = IsA(aDataSource, aResource, kRDF_Bag); - return NS_OK; -} - - -NS_IMETHODIMP -RDFContainerUtilsImpl::IsSeq(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, bool *_retval) -{ - NS_PRECONDITION(aDataSource != nullptr, "null ptr"); - if (! aDataSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aResource != nullptr, "null ptr"); - if (! aResource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(_retval != nullptr, "null ptr"); - if (! _retval) - return NS_ERROR_NULL_POINTER; - - *_retval = IsA(aDataSource, aResource, kRDF_Seq); - return NS_OK; -} - - -NS_IMETHODIMP -RDFContainerUtilsImpl::IsAlt(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, bool *_retval) -{ - NS_PRECONDITION(aDataSource != nullptr, "null ptr"); - if (! aDataSource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aResource != nullptr, "null ptr"); - if (! aResource) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(_retval != nullptr, "null ptr"); - if (! _retval) - return NS_ERROR_NULL_POINTER; - - *_retval = IsA(aDataSource, aResource, kRDF_Alt); - return NS_OK; -} - - -NS_IMETHODIMP -RDFContainerUtilsImpl::MakeBag(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, nsIRDFContainer **_retval) -{ - return MakeContainer(aDataSource, aResource, kRDF_Bag, _retval); -} - - -NS_IMETHODIMP -RDFContainerUtilsImpl::MakeSeq(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, nsIRDFContainer **_retval) -{ - return MakeContainer(aDataSource, aResource, kRDF_Seq, _retval); -} - - -NS_IMETHODIMP -RDFContainerUtilsImpl::MakeAlt(nsIRDFDataSource *aDataSource, nsIRDFResource *aResource, nsIRDFContainer **_retval) -{ - return MakeContainer(aDataSource, aResource, kRDF_Alt, _retval); -} - - - -//////////////////////////////////////////////////////////////////////// - - -RDFContainerUtilsImpl::RDFContainerUtilsImpl() -{ - if (gRefCnt++ == 0) { - nsresult rv; - - NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); - rv = CallGetService(kRDFServiceCID, &gRDFService); - - NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get RDF service"); - if (NS_SUCCEEDED(rv)) { - gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "instanceOf"), - &kRDF_instanceOf); - gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "nextVal"), - &kRDF_nextVal); - gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "Bag"), - &kRDF_Bag); - gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "Seq"), - &kRDF_Seq); - gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "Alt"), - &kRDF_Alt); - gRDFService->GetLiteral(u"1", &kOne); - } - } -} - - -RDFContainerUtilsImpl::~RDFContainerUtilsImpl() -{ -#ifdef DEBUG_REFS - --gInstanceCount; - fprintf(stdout, "%d - RDF: RDFContainerUtilsImpl\n", gInstanceCount); -#endif - - if (--gRefCnt == 0) { - NS_IF_RELEASE(gRDFService); - NS_IF_RELEASE(kRDF_instanceOf); - NS_IF_RELEASE(kRDF_nextVal); - NS_IF_RELEASE(kRDF_Bag); - NS_IF_RELEASE(kRDF_Seq); - NS_IF_RELEASE(kRDF_Alt); - NS_IF_RELEASE(kOne); - } -} - - - -nsresult -NS_NewRDFContainerUtils(nsIRDFContainerUtils** aResult) -{ - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - RDFContainerUtilsImpl* result = - new RDFContainerUtilsImpl(); - - if (! result) - return NS_ERROR_OUT_OF_MEMORY; - - NS_ADDREF(result); - *aResult = result; - return NS_OK; -} - - -nsresult -RDFContainerUtilsImpl::MakeContainer(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource, nsIRDFResource* aType, nsIRDFContainer** aResult) -{ - NS_PRECONDITION(aDataSource != nullptr, "null ptr"); - if (! aDataSource) return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aResource != nullptr, "null ptr"); - if (! aResource) return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aType != nullptr, "null ptr"); - if (! aType) return NS_ERROR_NULL_POINTER; - - if (aResult) *aResult = nullptr; - - nsresult rv; - - // Check to see if somebody has already turned it into a container; if so - // don't try to do it again. - bool isContainer; - rv = IsContainer(aDataSource, aResource, &isContainer); - if (NS_FAILED(rv)) return rv; - - if (!isContainer) - { - rv = aDataSource->Assert(aResource, kRDF_instanceOf, aType, true); - if (NS_FAILED(rv)) return rv; - - rv = aDataSource->Assert(aResource, kRDF_nextVal, kOne, true); - if (NS_FAILED(rv)) return rv; - } - - if (aResult) { - rv = NS_NewRDFContainer(aResult); - if (NS_FAILED(rv)) return rv; - - rv = (*aResult)->Init(aDataSource, aResource); - if (NS_FAILED(rv)) return rv; - } - - return NS_OK; -} - -bool -RDFContainerUtilsImpl::IsA(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource, nsIRDFResource* aType) -{ - if (!aDataSource || !aResource || !aType) { - NS_WARNING("Unexpected null argument"); - return false; - } - - nsresult rv; - - bool result; - rv = aDataSource->HasAssertion(aResource, kRDF_instanceOf, aType, true, &result); - if (NS_FAILED(rv)) - return false; - - return result; -} - -NS_IMETHODIMP -RDFContainerUtilsImpl::IndexOf(nsIRDFDataSource* aDataSource, nsIRDFResource* aContainer, nsIRDFNode* aElement, int32_t* aIndex) -{ - if (!aDataSource || !aContainer) - return NS_ERROR_NULL_POINTER; - - // Assume we can't find it. - *aIndex = -1; - - // If the resource is null, bail quietly - if (! aElement) - return NS_OK; - - // We'll assume that fan-out is much higher than fan-in, so grovel - // through the inbound arcs, look for an ordinal resource, and - // decode it. - nsCOMPtr arcsIn; - aDataSource->ArcLabelsIn(aElement, getter_AddRefs(arcsIn)); - if (! arcsIn) - return NS_OK; - - while (1) { - bool hasMoreArcs = false; - arcsIn->HasMoreElements(&hasMoreArcs); - if (! hasMoreArcs) - break; - - nsCOMPtr isupports; - arcsIn->GetNext(getter_AddRefs(isupports)); - if (! isupports) - break; - - nsCOMPtr property = - do_QueryInterface(isupports); - - if (! property) - continue; - - bool isOrdinal; - IsOrdinalProperty(property, &isOrdinal); - if (! isOrdinal) - continue; - - nsCOMPtr sources; - aDataSource->GetSources(property, aElement, true, getter_AddRefs(sources)); - if (! sources) - continue; - - while (1) { - bool hasMoreSources = false; - sources->HasMoreElements(&hasMoreSources); - if (! hasMoreSources) - break; - - nsCOMPtr isupports2; - sources->GetNext(getter_AddRefs(isupports2)); - if (! isupports2) - break; - - nsCOMPtr source = - do_QueryInterface(isupports2); - - if (source == aContainer) - // Found it. - return OrdinalResourceToIndex(property, aIndex); - } - } - - return NS_OK; -} diff --git a/rdf/base/nsRDFContentSink.cpp b/rdf/base/nsRDFContentSink.cpp deleted file mode 100644 index 3557e817baff..000000000000 --- a/rdf/base/nsRDFContentSink.cpp +++ /dev/null @@ -1,1444 +0,0 @@ -/* -*- 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/. */ - -/* - - An implementation for an NGLayout-style content sink that knows how - to build an RDF content model from XML-serialized RDF. - - For more information on the RDF/XML syntax, - see http://www.w3.org/TR/REC-rdf-syntax/ - - This code is based on the final W3C Recommendation, - http://www.w3.org/TR/1999/REC-rdf-syntax-19990222. - - Open Issues ------------------ - - 1) factoring code with nsXMLContentSink - There's some amount of - common code between this and the HTML content sink. This will - increase as we support more and more HTML elements. How can code - from XML/HTML be factored? - - 2) We don't support the `parseType' attribute on the Description - tag; therefore, it is impossible to "inline" raw XML in this - implemenation. - - 3) We don't build the reifications at parse time due to the - footprint overhead it would incur for large RDF documents. (It - may be possible to attach a "reification" wrapper datasource that - would present this information at query-time.) Because of this, - the `bagID' attribute is not processed correctly. - - 4) No attempt is made to `resolve URIs' to a canonical form (the - specification hints that an implementation should do this). This - is omitted for the obvious reason that we can ill afford to - resolve each URI reference. - -*/ - -#include "nsCOMPtr.h" -#include "nsInterfaceHashtable.h" -#include "nsIContentSink.h" -#include "nsIRDFContainer.h" -#include "nsIRDFContainerUtils.h" -#include "nsIRDFContentSink.h" -#include "nsIRDFNode.h" -#include "nsIRDFService.h" -#include "nsIRDFXMLSink.h" -#include "nsIServiceManager.h" -#include "nsIURL.h" -#include "nsIXMLContentSink.h" -#include "nsRDFCID.h" -#include "nsTArray.h" -#include "nsString.h" -#include "mozilla/Logging.h" -#include "rdf.h" -#include "rdfutil.h" -#include "nsReadableUtils.h" -#include "nsIExpatSink.h" -#include "nsCRT.h" -#include "nsAtom.h" -#include "nsGkAtoms.h" -#include "nsIScriptError.h" -#include "nsIDTD.h" - -using namespace mozilla; - -/////////////////////////////////////////////////////////////////////// - -enum RDFContentSinkState { - eRDFContentSinkState_InProlog, - eRDFContentSinkState_InDocumentElement, - eRDFContentSinkState_InDescriptionElement, - eRDFContentSinkState_InContainerElement, - eRDFContentSinkState_InPropertyElement, - eRDFContentSinkState_InMemberElement, - eRDFContentSinkState_InEpilog -}; - -enum RDFContentSinkParseMode { - eRDFContentSinkParseMode_Resource, - eRDFContentSinkParseMode_Literal, - eRDFContentSinkParseMode_Int, - eRDFContentSinkParseMode_Date -}; - -typedef decltype(&nsIRDFContainerUtils::IsAlt) nsContainerTestFn; -typedef decltype(&nsIRDFContainerUtils::MakeAlt) nsMakeContainerFn; - -class RDFContentSinkImpl : public nsIRDFContentSink, - public nsIExpatSink -{ -public: - RDFContentSinkImpl(); - - // nsISupports - NS_DECL_ISUPPORTS - NS_DECL_NSIEXPATSINK - - // nsIContentSink - NS_IMETHOD WillParse(void) override; - NS_IMETHOD WillBuildModel(nsDTDMode aDTDMode) override; - NS_IMETHOD DidBuildModel(bool aTerminated) override; - NS_IMETHOD WillInterrupt(void) override; - NS_IMETHOD WillResume(void) override; - NS_IMETHOD SetParser(nsParserBase* aParser) override; - virtual void FlushPendingNotifications(mozilla::FlushType aType) override { } - virtual void SetDocumentCharset(NotNull aEncoding) - override { } - virtual nsISupports *GetTarget() override { return nullptr; } - - // nsIRDFContentSink - NS_IMETHOD Init(nsIURI* aURL) override; - NS_IMETHOD SetDataSource(nsIRDFDataSource* aDataSource) override; - NS_IMETHOD GetDataSource(nsIRDFDataSource*& aDataSource) override; - - // pseudo constants - static int32_t gRefCnt; - static nsIRDFService* gRDFService; - static nsIRDFContainerUtils* gRDFContainerUtils; - static nsIRDFResource* kRDF_type; - static nsIRDFResource* kRDF_instanceOf; // XXX should be RDF:type - static nsIRDFResource* kRDF_Alt; - static nsIRDFResource* kRDF_Bag; - static nsIRDFResource* kRDF_Seq; - static nsIRDFResource* kRDF_nextVal; - - typedef struct ContainerInfo { - nsIRDFResource** mType; - nsContainerTestFn mTestFn; - nsMakeContainerFn mMakeFn; - } ContainerInfo; - -protected: - virtual ~RDFContentSinkImpl(); - - // Text management - void ParseText(nsIRDFNode **aResult); - - nsresult FlushText(); - nsresult AddText(const char16_t* aText, int32_t aLength); - - // RDF-specific parsing - nsresult OpenRDF(const char16_t* aName); - nsresult OpenObject(const char16_t* aName ,const char16_t** aAttributes); - nsresult OpenProperty(const char16_t* aName, const char16_t** aAttributes); - nsresult OpenMember(const char16_t* aName, const char16_t** aAttributes); - nsresult OpenValue(const char16_t* aName, const char16_t** aAttributes); - - nsresult GetIdAboutAttribute(const char16_t** aAttributes, nsIRDFResource** aResource, bool* aIsAnonymous = nullptr); - nsresult GetResourceAttribute(const char16_t** aAttributes, nsIRDFResource** aResource); - nsresult AddProperties(const char16_t** aAttributes, nsIRDFResource* aSubject, int32_t* aCount = nullptr); - void SetParseMode(const char16_t **aAttributes); - - char16_t* mText; - int32_t mTextLength; - int32_t mTextSize; - - /** - * 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. - */ - void RegisterNamespaces(const char16_t **aAttributes); - - /** - * 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. - */ - const nsDependentSubstring SplitExpatName(const char16_t *aExpatName, - nsAtom **aLocalName); - - enum eContainerType { eBag, eSeq, eAlt }; - nsresult InitContainer(nsIRDFResource* aContainerType, nsIRDFResource* aContainer); - nsresult ReinitContainer(nsIRDFResource* aContainerType, nsIRDFResource* aContainer); - - // The datasource in which we're assigning assertions - nsCOMPtr mDataSource; - - // A hash of all the node IDs referred to - nsInterfaceHashtable mNodeIDMap; - - // The current state of the content sink - RDFContentSinkState mState; - RDFContentSinkParseMode mParseMode; - - // content stack management - int32_t - PushContext(nsIRDFResource *aContext, - RDFContentSinkState aState, - RDFContentSinkParseMode aParseMode); - - nsresult - PopContext(nsIRDFResource *&aContext, - RDFContentSinkState &aState, - RDFContentSinkParseMode &aParseMode); - - nsIRDFResource* GetContextElement(int32_t ancestor = 0); - - - struct RDFContextStackElement { - nsCOMPtr mResource; - RDFContentSinkState mState; - RDFContentSinkParseMode mParseMode; - }; - - AutoTArray* mContextStack; - - nsCOMPtr mDocumentURL; - -private: - static mozilla::LazyLogModule gLog; -}; - -int32_t RDFContentSinkImpl::gRefCnt = 0; -nsIRDFService* RDFContentSinkImpl::gRDFService; -nsIRDFContainerUtils* RDFContentSinkImpl::gRDFContainerUtils; -nsIRDFResource* RDFContentSinkImpl::kRDF_type; -nsIRDFResource* RDFContentSinkImpl::kRDF_instanceOf; -nsIRDFResource* RDFContentSinkImpl::kRDF_Alt; -nsIRDFResource* RDFContentSinkImpl::kRDF_Bag; -nsIRDFResource* RDFContentSinkImpl::kRDF_Seq; -nsIRDFResource* RDFContentSinkImpl::kRDF_nextVal; - -mozilla::LazyLogModule RDFContentSinkImpl::gLog("nsRDFContentSink"); - -//////////////////////////////////////////////////////////////////////// - -RDFContentSinkImpl::RDFContentSinkImpl() - : mText(nullptr), - mTextLength(0), - mTextSize(0), - mState(eRDFContentSinkState_InProlog), - mParseMode(eRDFContentSinkParseMode_Literal), - mContextStack(nullptr) -{ - if (gRefCnt++ == 0) { - NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); - nsresult rv = CallGetService(kRDFServiceCID, &gRDFService); - - NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get RDF service"); - if (NS_SUCCEEDED(rv)) { - rv = gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "type"), - &kRDF_type); - rv = gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "instanceOf"), - &kRDF_instanceOf); - rv = gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "Alt"), - &kRDF_Alt); - rv = gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "Bag"), - &kRDF_Bag); - rv = gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "Seq"), - &kRDF_Seq); - rv = gRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "nextVal"), - &kRDF_nextVal); - } - - NS_DEFINE_CID(kRDFContainerUtilsCID, NS_RDFCONTAINERUTILS_CID); - rv = CallGetService(kRDFContainerUtilsCID, &gRDFContainerUtils); - } -} - - -RDFContentSinkImpl::~RDFContentSinkImpl() -{ -#ifdef DEBUG_REFS - --gInstanceCount; - fprintf(stdout, "%d - RDF: RDFContentSinkImpl\n", gInstanceCount); -#endif - - if (mContextStack) { - MOZ_LOG(gLog, LogLevel::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. - int32_t i = mContextStack->Length(); - while (0 < i--) { - nsIRDFResource* resource = nullptr; - RDFContentSinkState state; - RDFContentSinkParseMode parseMode; - PopContext(resource, state, parseMode); - - // 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 && MOZ_LOG_TEST(gLog, LogLevel::Debug)) { - nsCString uri; - resource->GetValue(getter_Copies(uri)); - MOZ_LOG(gLog, LogLevel::Debug, - ("rdfxml: uri=%s", uri.get())); - } - - NS_IF_RELEASE(resource); - } - - delete mContextStack; - } - free(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); - } -} - -//////////////////////////////////////////////////////////////////////// -// nsISupports interface - -NS_IMPL_ADDREF(RDFContentSinkImpl) -NS_IMPL_RELEASE(RDFContentSinkImpl) - -NS_IMETHODIMP -RDFContentSinkImpl::QueryInterface(REFNSIID iid, void** result) -{ - NS_PRECONDITION(result, "null ptr"); - if (! result) - return NS_ERROR_NULL_POINTER; - - NS_DEFINE_IID(kIContentSinkIID, NS_ICONTENT_SINK_IID); - NS_DEFINE_IID(kIExpatSinkIID, NS_IEXPATSINK_IID); - NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); - NS_DEFINE_IID(kIXMLContentSinkIID, NS_IXMLCONTENT_SINK_IID); - NS_DEFINE_IID(kIRDFContentSinkIID, NS_IRDFCONTENTSINK_IID); - - *result = nullptr; - if (iid.Equals(kIRDFContentSinkIID) || - iid.Equals(kIXMLContentSinkIID) || - iid.Equals(kIContentSinkIID) || - iid.Equals(kISupportsIID)) { - *result = static_cast(this); - AddRef(); - return NS_OK; - } - else if (iid.Equals(kIExpatSinkIID)) { - *result = static_cast(this); - AddRef(); - return NS_OK; - } - return NS_NOINTERFACE; -} - -NS_IMETHODIMP -RDFContentSinkImpl::HandleStartElement(const char16_t *aName, - const char16_t **aAtts, - uint32_t aAttsCount, - uint32_t aLineNumber) -{ - FlushText(); - - nsresult rv = NS_ERROR_UNEXPECTED; // XXX - - RegisterNamespaces(aAtts); - - switch (mState) { - case eRDFContentSinkState_InProlog: - rv = OpenRDF(aName); - break; - - case eRDFContentSinkState_InDocumentElement: - rv = OpenObject(aName,aAtts); - break; - - case eRDFContentSinkState_InDescriptionElement: - rv = OpenProperty(aName,aAtts); - break; - - case eRDFContentSinkState_InContainerElement: - rv = OpenMember(aName,aAtts); - break; - - case eRDFContentSinkState_InPropertyElement: - case eRDFContentSinkState_InMemberElement: - rv = OpenValue(aName,aAtts); - break; - - case eRDFContentSinkState_InEpilog: - MOZ_LOG(gLog, LogLevel::Warning, - ("rdfxml: unexpected content in epilog at line %d", - aLineNumber)); - break; - } - - return rv; -} - -NS_IMETHODIMP -RDFContentSinkImpl::HandleEndElement(const char16_t *aName) -{ - FlushText(); - - nsIRDFResource* resource; - if (NS_FAILED(PopContext(resource, mState, mParseMode))) { - // XXX parser didn't catch unmatched tags? - if (MOZ_LOG_TEST(gLog, LogLevel::Warning)) { - nsAutoString tagStr(aName); - char* tagCStr = ToNewCString(tagStr); - - MOZ_LOG(gLog, LogLevel::Warning, - ("rdfxml: extra close tag '%s' at line %d", - tagCStr, 0/*XXX fix me */)); - - free(tagCStr); - } - - return NS_ERROR_UNEXPECTED; // XXX - } - - // If we've just popped a member or property element, _now_ is the - // time to add that element to the graph. - switch (mState) { - case eRDFContentSinkState_InMemberElement: - { - nsCOMPtr container; - NS_NewRDFContainer(getter_AddRefs(container)); - container->Init(mDataSource, GetContextElement(1)); - container->AppendElement(resource); - } - break; - - case eRDFContentSinkState_InPropertyElement: - { - mDataSource->Assert(GetContextElement(1), GetContextElement(0), resource, true); - } break; - default: - break; - } - - if (mContextStack->IsEmpty()) - mState = eRDFContentSinkState_InEpilog; - - NS_IF_RELEASE(resource); - return NS_OK; -} - -NS_IMETHODIMP -RDFContentSinkImpl::HandleComment(const char16_t *aName) -{ - return NS_OK; -} - -NS_IMETHODIMP -RDFContentSinkImpl::HandleCDataSection(const char16_t *aData, - uint32_t aLength) -{ - return aData ? AddText(aData, aLength) : NS_OK; -} - -NS_IMETHODIMP -RDFContentSinkImpl::HandleDoctypeDecl(const nsAString & aSubset, - const nsAString & aName, - const nsAString & aSystemId, - const nsAString & aPublicId, - nsISupports* aCatalogData) -{ - return NS_OK; -} - -NS_IMETHODIMP -RDFContentSinkImpl::HandleCharacterData(const char16_t *aData, - uint32_t aLength) -{ - return aData ? AddText(aData, aLength) : NS_OK; -} - -NS_IMETHODIMP -RDFContentSinkImpl::HandleProcessingInstruction(const char16_t *aTarget, - const char16_t *aData) -{ - return NS_OK; -} - -NS_IMETHODIMP -RDFContentSinkImpl::HandleXMLDeclaration(const char16_t *aVersion, - const char16_t *aEncoding, - int32_t aStandalone) -{ - return NS_OK; -} - -NS_IMETHODIMP -RDFContentSinkImpl::ReportError(const char16_t* aErrorText, - const char16_t* aSourceText, - nsIScriptError *aError, - bool *_retval) -{ - NS_PRECONDITION(aError && aSourceText && aErrorText, "Check arguments!!!"); - - // The expat driver should report the error. - *_retval = true; - return NS_OK; -} - -//////////////////////////////////////////////////////////////////////// -// nsIContentSink interface - -NS_IMETHODIMP -RDFContentSinkImpl::WillParse(void) -{ - return NS_OK; -} - - -NS_IMETHODIMP -RDFContentSinkImpl::WillBuildModel(nsDTDMode) -{ - if (mDataSource) { - nsCOMPtr sink = do_QueryInterface(mDataSource); - if (sink) - return sink->BeginLoad(); - } - return NS_OK; -} - -NS_IMETHODIMP -RDFContentSinkImpl::DidBuildModel(bool aTerminated) -{ - if (mDataSource) { - nsCOMPtr sink = do_QueryInterface(mDataSource); - if (sink) - return sink->EndLoad(); - } - return NS_OK; -} - -NS_IMETHODIMP -RDFContentSinkImpl::WillInterrupt(void) -{ - if (mDataSource) { - nsCOMPtr sink = do_QueryInterface(mDataSource); - if (sink) - return sink->Interrupt(); - } - return NS_OK; -} - -NS_IMETHODIMP -RDFContentSinkImpl::WillResume(void) -{ - if (mDataSource) { - nsCOMPtr sink = do_QueryInterface(mDataSource); - if (sink) - return sink->Resume(); - } - return NS_OK; -} - -NS_IMETHODIMP -RDFContentSinkImpl::SetParser(nsParserBase* aParser) -{ - return NS_OK; -} - -//////////////////////////////////////////////////////////////////////// -// nsIRDFContentSink interface - -NS_IMETHODIMP -RDFContentSinkImpl::Init(nsIURI* aURL) -{ - NS_PRECONDITION(aURL != nullptr, "null ptr"); - if (! aURL) - return NS_ERROR_NULL_POINTER; - - mDocumentURL = aURL; - mState = eRDFContentSinkState_InProlog; - return NS_OK; -} - -NS_IMETHODIMP -RDFContentSinkImpl::SetDataSource(nsIRDFDataSource* aDataSource) -{ - NS_PRECONDITION(aDataSource != nullptr, "SetDataSource null ptr"); - mDataSource = aDataSource; - NS_ASSERTION(mDataSource != nullptr,"Couldn't QI RDF DataSource"); - return NS_OK; -} - - -NS_IMETHODIMP -RDFContentSinkImpl::GetDataSource(nsIRDFDataSource*& aDataSource) -{ - aDataSource = mDataSource; - NS_IF_ADDREF(aDataSource); - return NS_OK; -} - -//////////////////////////////////////////////////////////////////////// -// Text buffering - -static bool -rdf_IsDataInBuffer(char16_t* buffer, int32_t length) -{ - for (int32_t i = 0; i < length; ++i) { - if (buffer[i] == ' ' || - buffer[i] == '\t' || - buffer[i] == '\n' || - buffer[i] == '\r') - continue; - - return true; - } - return false; -} - -void -RDFContentSinkImpl::ParseText(nsIRDFNode **aResult) -{ - // 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: - { - nsresult err; - int32_t i = value.ToInteger(&err); - nsIRDFInt *result; - gRDFService->GetIntLiteral(i, &result); - *aResult = result; - } - break; - - case eRDFContentSinkParseMode_Date: - { - PRTime t = rdf_ParseDate(nsDependentCString(NS_LossyConvertUTF16toASCII(value).get(), value.Length())); - nsIRDFDate *result; - gRDFService->GetDateLiteral(t, &result); - *aResult = result; - } - break; - - default: - NS_NOTREACHED("unknown parse type"); - break; - } -} - -nsresult -RDFContentSinkImpl::FlushText() -{ - nsresult rv = NS_OK; - if (0 != mTextLength) { - if (rdf_IsDataInBuffer(mText, mTextLength)) { - // XXX if there's anything but whitespace, then we'll - // create a text node. - - switch (mState) { - case eRDFContentSinkState_InMemberElement: { - nsCOMPtr node; - ParseText(getter_AddRefs(node)); - - nsCOMPtr container; - NS_NewRDFContainer(getter_AddRefs(container)); - container->Init(mDataSource, GetContextElement(1)); - - container->AppendElement(node); - } break; - - case eRDFContentSinkState_InPropertyElement: { - nsCOMPtr node; - ParseText(getter_AddRefs(node)); - - mDataSource->Assert(GetContextElement(1), GetContextElement(0), node, true); - } break; - - default: - // just ignore it - break; - } - } - mTextLength = 0; - } - return rv; -} - - -nsresult -RDFContentSinkImpl::AddText(const char16_t* aText, int32_t aLength) -{ - // Create buffer when we first need it - if (0 == mTextSize) { - mText = (char16_t *) malloc(sizeof(char16_t) * 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. - int32_t amount = mTextSize - mTextLength; - if (amount < aLength) { - // Grow the buffer by at least a factor of two to prevent thrashing. - // Since realloc() will leave mText intact if the call fails, - // don't clobber mText or mTextSize until the new mem is allocated. - int32_t newSize = (2 * mTextSize > (mTextSize + aLength)) ? - (2 * mTextSize) : (mTextSize + aLength); - char16_t* newText = - (char16_t *) realloc(mText, sizeof(char16_t) * newSize); - if (!newText) - return NS_ERROR_OUT_OF_MEMORY; - mTextSize = newSize; - mText = newText; - } - memcpy(&mText[mTextLength], aText, sizeof(char16_t) * aLength); - mTextLength += aLength; - - return NS_OK; -} - -bool -rdf_RequiresAbsoluteURI(const nsString& uri) -{ - // cheap shot at figuring out if this requires an absolute url translation - return !(StringBeginsWith(uri, NS_LITERAL_STRING("urn:")) || - StringBeginsWith(uri, NS_LITERAL_STRING("chrome:"))); -} - -nsresult -RDFContentSinkImpl::GetIdAboutAttribute(const char16_t** aAttributes, - nsIRDFResource** aResource, - bool* aIsAnonymous) -{ - // This corresponds to the dirty work of production [6.5] - nsresult rv = NS_OK; - - nsAutoString nodeID; - - RefPtr 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 == nsGkAtoms::about) { - if (aIsAnonymous) - *aIsAnonymous = false; - - nsAutoString relURI(aAttributes[1]); - if (rdf_RequiresAbsoluteURI(relURI)) { - nsAutoCString uri; - rv = mDocumentURL->Resolve(NS_ConvertUTF16toUTF8(aAttributes[1]), uri); - if (NS_FAILED(rv)) return rv; - - return gRDFService->GetResource(uri, - aResource); - } - return gRDFService->GetResource(NS_ConvertUTF16toUTF8(aAttributes[1]), - aResource); - } - else if (localName == nsGkAtoms::ID) { - if (aIsAnonymous) - *aIsAnonymous = false; - // 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. - nsAutoCString name; - nsAutoCString ref('#'); - AppendUTF16toUTF8(aAttributes[1], ref); - - rv = mDocumentURL->Resolve(ref, name); - if (NS_FAILED(rv)) return rv; - - return gRDFService->GetResource(name, aResource); - } - else if (localName == nsGkAtoms::nodeID) { - nodeID.Assign(aAttributes[1]); - } - else if (localName == nsGkAtoms::about) { - // XXX we don't deal with aboutEach... - //MOZ_LOG(gLog, LogLevel::Warning, - // ("rdfxml: ignoring aboutEach at line %d", - // aNode.GetSourceLineNumber())); - } - } - - // Otherwise, we couldn't find anything, so just gensym one... - if (aIsAnonymous) - *aIsAnonymous = 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; -} - -nsresult -RDFContentSinkImpl::GetResourceAttribute(const char16_t** aAttributes, - nsIRDFResource** aResource) -{ - RefPtr 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 == nsGkAtoms::resource) { - // XXX Take the URI and make it fully qualified by - // sticking it into the document's URL. This may not be - // appropriate... - nsAutoString relURI(aAttributes[1]); - if (rdf_RequiresAbsoluteURI(relURI)) { - nsresult rv; - nsAutoCString uri; - - rv = mDocumentURL->Resolve(NS_ConvertUTF16toUTF8(aAttributes[1]), uri); - if (NS_FAILED(rv)) return rv; - - return gRDFService->GetResource(uri, aResource); - } - return gRDFService->GetResource(NS_ConvertUTF16toUTF8(aAttributes[1]), - aResource); - } - else if (localName == nsGkAtoms::nodeID) { - 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) { - nsresult rv; - rv = gRDFService->GetAnonymousResource(aResource); - if (NS_FAILED(rv)) { - return rv; - } - mNodeIDMap.Put(nodeID,*aResource); - } - return NS_OK; - } - - return NS_ERROR_FAILURE; -} - -nsresult -RDFContentSinkImpl::AddProperties(const char16_t** aAttributes, - nsIRDFResource* aSubject, - int32_t* aCount) -{ - if (aCount) - *aCount = 0; - - RefPtr 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 == nsGkAtoms::about || localName == nsGkAtoms::ID || - localName == nsGkAtoms::resource || localName == nsGkAtoms::nodeID) { - 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 == nsGkAtoms::parseType) { - if (nameSpaceURI.IsEmpty() || - nameSpaceURI.EqualsLiteral(RDF_NAMESPACE_URI) || - nameSpaceURI.EqualsLiteral(NC_NAMESPACE_URI)) { - continue; - } - } - - NS_ConvertUTF16toUTF8 propertyStr(nameSpaceURI); - propertyStr.Append(nsAtomCString(localName)); - - // Add the assertion to RDF - nsCOMPtr property; - gRDFService->GetResource(propertyStr, getter_AddRefs(property)); - - nsCOMPtr target; - gRDFService->GetLiteral(aAttributes[1], - getter_AddRefs(target)); - - mDataSource->Assert(aSubject, property, target, true); - } - return NS_OK; -} - -void -RDFContentSinkImpl::SetParseMode(const char16_t **aAttributes) -{ - RefPtr localName; - for (; *aAttributes; aAttributes += 2) { - const nsDependentSubstring& nameSpaceURI = - SplitExpatName(aAttributes[0], getter_AddRefs(localName)); - - if (localName == nsGkAtoms::parseType) { - nsDependentString v(aAttributes[1]); - - 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; - } - } - } -} - -//////////////////////////////////////////////////////////////////////// -// RDF-specific routines used to build the model - -nsresult -RDFContentSinkImpl::OpenRDF(const char16_t* aName) -{ - // ensure that we're actually reading RDF by making sure that the - // opening tag is , where "rdf:" corresponds to whatever - // they've declared the standard RDF namespace to be. - RefPtr localName; - const nsDependentSubstring& nameSpaceURI = - SplitExpatName(aName, getter_AddRefs(localName)); - - if (!nameSpaceURI.EqualsLiteral(RDF_NAMESPACE_URI) || - localName != nsGkAtoms::RDF) { - // MOZ_LOG(gLog, LogLevel::Info, - // ("rdfxml: expected RDF:RDF at line %d", - // aNode.GetSourceLineNumber())); - - return NS_ERROR_UNEXPECTED; - } - - PushContext(nullptr, mState, mParseMode); - mState = eRDFContentSinkState_InDocumentElement; - return NS_OK; -} - -nsresult -RDFContentSinkImpl::OpenObject(const char16_t* aName, - const char16_t** aAttributes) -{ - // an "object" non-terminal is either a "description", a "typed - // node", or a "container", so this change the content sink's - // state appropriately. - RefPtr localName; - const nsDependentSubstring& nameSpaceURI = - SplitExpatName(aName, getter_AddRefs(localName)); - - // Figure out the URI of this object, and create an RDF node for it. - nsCOMPtr 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. - bool isaTypedNode = true; - - if (nameSpaceURI.EqualsLiteral(RDF_NAMESPACE_URI)) { - isaTypedNode = false; - - if (localName == nsGkAtoms::Description) { - // it's a description - mState = eRDFContentSinkState_InDescriptionElement; - } - else if (localName == nsGkAtoms::Bag) { - // it's a bag container - InitContainer(kRDF_Bag, source); - mState = eRDFContentSinkState_InContainerElement; - } - else if (localName == nsGkAtoms::Seq) { - // it's a seq container - InitContainer(kRDF_Seq, source); - mState = eRDFContentSinkState_InContainerElement; - } - else if (localName == nsGkAtoms::Alt) { - // 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 = true; - } - } - - if (isaTypedNode) { - NS_ConvertUTF16toUTF8 typeStr(nameSpaceURI); - typeStr.Append(nsAtomCString(localName)); - - nsCOMPtr type; - nsresult rv = gRDFService->GetResource(typeStr, getter_AddRefs(type)); - if (NS_FAILED(rv)) return rv; - - rv = mDataSource->Assert(source, kRDF_type, type, true); - if (NS_FAILED(rv)) return rv; - - mState = eRDFContentSinkState_InDescriptionElement; - } - - AddProperties(aAttributes, source); - return NS_OK; -} - -nsresult -RDFContentSinkImpl::OpenProperty(const char16_t* aName, const char16_t** aAttributes) -{ - 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. - RefPtr localName; - const nsDependentSubstring& nameSpaceURI = - SplitExpatName(aName, getter_AddRefs(localName)); - - NS_ConvertUTF16toUTF8 propertyStr(nameSpaceURI); - propertyStr.Append(nsAtomCString(localName)); - - nsCOMPtr 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 target; - GetResourceAttribute(aAttributes, getter_AddRefs(target)); - - bool isAnonymous = 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. - int32_t 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, 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; -} - -nsresult -RDFContentSinkImpl::OpenMember(const char16_t* aName, - const char16_t** aAttributes) -{ - // ensure that we're actually reading a member element by making - // sure that the opening tag is , where "rdf:" corresponds - // to whatever they've declared the standard RDF namespace to be. - nsresult rv; - - RefPtr localName; - const nsDependentSubstring& nameSpaceURI = - SplitExpatName(aName, getter_AddRefs(localName)); - - if (!nameSpaceURI.EqualsLiteral(RDF_NAMESPACE_URI) || - localName != nsGkAtoms::li) { - MOZ_LOG(gLog, LogLevel::Error, - ("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 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(nullptr, mState, mParseMode); - mState = eRDFContentSinkState_InMemberElement; - SetParseMode(aAttributes); - - return NS_OK; -} - - -nsresult -RDFContentSinkImpl::OpenValue(const char16_t* aName, const char16_t** aAttributes) -{ - // 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); -} - -//////////////////////////////////////////////////////////////////////// -// namespace resolution -void -RDFContentSinkImpl::RegisterNamespaces(const char16_t **aAttributes) -{ - nsCOMPtr 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 char16_t* attr = aAttributes[0]; - const char16_t* 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 char16_t* endLocal = ++attr; - while (*endLocal && *endLocal != 0xFFFF) { - ++endLocal; - } - nsDependentSubstring lname(attr, endLocal); - RefPtr preferred = NS_Atomize(lname); - if (preferred == nsGkAtoms::xmlns) { - preferred = nullptr; - } - sink->AddNameSpace(preferred, nsDependentString(aAttributes[1])); - } -} - -//////////////////////////////////////////////////////////////////////// -// Qualified name resolution - -const nsDependentSubstring -RDFContentSinkImpl::SplitExpatName(const char16_t *aExpatName, - nsAtom **aLocalName) -{ - /** - * Expat can send the following: - * localName - * namespaceURIlocalName - * namespaceURIlocalNameprefix - * - * and we use 0xFFFF for the . - * - */ - - const char16_t *uriEnd = aExpatName; - const char16_t *nameStart = aExpatName; - const char16_t *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_Atomize(Substring(nameStart, pos)).take(); - return nameSpaceURI; -} - -nsresult -RDFContentSinkImpl::InitContainer(nsIRDFResource* aContainerType, nsIRDFResource* aContainer) -{ - // 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; - - bool isContainer; - rv = (gRDFContainerUtils->*(info->mTestFn))(mDataSource, aContainer, &isContainer); - if (isContainer) { - rv = ReinitContainer(aContainerType, aContainer); - } - else { - rv = (gRDFContainerUtils->*(info->mMakeFn))(mDataSource, aContainer, nullptr); - } - return rv; - } - - NS_NOTREACHED("not an RDF container type"); - return NS_ERROR_FAILURE; -} - - - -nsresult -RDFContentSinkImpl::ReinitContainer(nsIRDFResource* aContainerType, nsIRDFResource* aContainer) -{ - // 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 one; - rv = gRDFService->GetLiteral(u"1", getter_AddRefs(one)); - if (NS_FAILED(rv)) return rv; - - // Re-initialize the 'nextval' property - nsCOMPtr nextval; - rv = mDataSource->GetTarget(aContainer, kRDF_nextVal, 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, true); - NS_ASSERTION(NS_SUCCEEDED(rv), "unable to mark container as such"); - if (NS_FAILED(rv)) return rv; - - return NS_OK; -} - -//////////////////////////////////////////////////////////////////////// -// Content stack management - -nsIRDFResource* -RDFContentSinkImpl::GetContextElement(int32_t ancestor /* = 0 */) -{ - if ((nullptr == mContextStack) || - (uint32_t(ancestor) >= mContextStack->Length())) { - return nullptr; - } - - return mContextStack->ElementAt( - mContextStack->Length()-ancestor-1).mResource; -} - -int32_t -RDFContentSinkImpl::PushContext(nsIRDFResource *aResource, - RDFContentSinkState aState, - RDFContentSinkParseMode aParseMode) -{ - if (! mContextStack) { - mContextStack = new AutoTArray(); - if (! mContextStack) - return 0; - } - - RDFContextStackElement* e = mContextStack->AppendElement(); - if (! e) - return mContextStack->Length(); - - e->mResource = aResource; - e->mState = aState; - e->mParseMode = aParseMode; - - return mContextStack->Length(); -} - -nsresult -RDFContentSinkImpl::PopContext(nsIRDFResource *&aResource, - RDFContentSinkState &aState, - RDFContentSinkParseMode &aParseMode) -{ - if ((nullptr == mContextStack) || - (mContextStack->IsEmpty())) { - return NS_ERROR_NULL_POINTER; - } - - uint32_t i = mContextStack->Length() - 1; - RDFContextStackElement &e = mContextStack->ElementAt(i); - - aResource = e.mResource; - NS_IF_ADDREF(aResource); - aState = e.mState; - aParseMode = e.mParseMode; - - mContextStack->RemoveElementAt(i); - return NS_OK; -} - - -//////////////////////////////////////////////////////////////////////// - -nsresult -NS_NewRDFContentSink(nsIRDFContentSink** aResult) -{ - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - RDFContentSinkImpl* sink = new RDFContentSinkImpl(); - if (! sink) - return NS_ERROR_OUT_OF_MEMORY; - - NS_ADDREF(sink); - *aResult = sink; - return NS_OK; -} diff --git a/rdf/base/nsRDFResource.cpp b/rdf/base/nsRDFResource.cpp deleted file mode 100644 index 46e078a4cc13..000000000000 --- a/rdf/base/nsRDFResource.cpp +++ /dev/null @@ -1,220 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; 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/. */ - -#include "nsRDFResource.h" -#include "nsIServiceManager.h" -#include "nsIRDFDelegateFactory.h" -#include "nsIRDFService.h" -#include "nsRDFCID.h" -#include "mozilla/Logging.h" -#include "nsComponentManagerUtils.h" -#include "nsServiceManagerUtils.h" - -static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); - -nsIRDFService* nsRDFResource::gRDFService = nullptr; -nsrefcnt nsRDFResource::gRDFServiceRefCnt = 0; - -//////////////////////////////////////////////////////////////////////////////// - -nsRDFResource::nsRDFResource(void) - : mDelegates(nullptr) -{ -} - -nsRDFResource::~nsRDFResource(void) -{ - // Release all of the delegate objects - while (mDelegates) { - DelegateEntry* doomed = mDelegates; - mDelegates = mDelegates->mNext; - delete doomed; - } - - if (!gRDFService) - return; - - gRDFService->UnregisterResource(this); - - if (--gRDFServiceRefCnt == 0) - NS_RELEASE(gRDFService); -} - -NS_IMPL_ISUPPORTS(nsRDFResource, nsIRDFResource, nsIRDFNode) - -//////////////////////////////////////////////////////////////////////////////// -// nsIRDFNode methods: - -NS_IMETHODIMP -nsRDFResource::EqualsNode(nsIRDFNode* aNode, bool* aResult) -{ - NS_PRECONDITION(aNode != nullptr, "null ptr"); - if (! aNode) - return NS_ERROR_NULL_POINTER; - - nsresult rv; - nsIRDFResource* resource; - rv = aNode->QueryInterface(NS_GET_IID(nsIRDFResource), (void**)&resource); - if (NS_SUCCEEDED(rv)) { - *aResult = (static_cast(this) == resource); - NS_RELEASE(resource); - return NS_OK; - } - if (rv == NS_NOINTERFACE) { - *aResult = false; - return NS_OK; - } - - return rv; -} - -//////////////////////////////////////////////////////////////////////////////// -// nsIRDFResource methods: - -NS_IMETHODIMP -nsRDFResource::Init(const char* aURI) -{ - NS_PRECONDITION(aURI != nullptr, "null ptr"); - if (! aURI) - return NS_ERROR_NULL_POINTER; - - mURI = aURI; - - if (gRDFServiceRefCnt++ == 0) { - nsresult rv = CallGetService(kRDFServiceCID, &gRDFService); - if (NS_FAILED(rv)) return rv; - } - - // don't replace an existing resource with the same URI automatically - return gRDFService->RegisterResource(this, true); -} - -NS_IMETHODIMP -nsRDFResource::GetValue(char* *aURI) -{ - NS_ASSERTION(aURI, "Null out param."); - - *aURI = ToNewCString(mURI); - - if (!*aURI) - return NS_ERROR_OUT_OF_MEMORY; - - return NS_OK; -} - -NS_IMETHODIMP -nsRDFResource::GetValueUTF8(nsACString& aResult) -{ - aResult = mURI; - return NS_OK; -} - -NS_IMETHODIMP -nsRDFResource::GetValueConst(const char** aURI) -{ - *aURI = mURI.get(); - return NS_OK; -} - -NS_IMETHODIMP -nsRDFResource::EqualsString(const char* aURI, bool* aResult) -{ - NS_PRECONDITION(aURI != nullptr, "null ptr"); - if (! aURI) - return NS_ERROR_NULL_POINTER; - - NS_PRECONDITION(aResult, "null ptr"); - - *aResult = mURI.Equals(aURI); - return NS_OK; -} - -NS_IMETHODIMP -nsRDFResource::GetDelegate(const char* aKey, REFNSIID aIID, void** aResult) -{ - NS_PRECONDITION(aKey != nullptr, "null ptr"); - if (! aKey) - return NS_ERROR_NULL_POINTER; - - nsresult rv; - *aResult = nullptr; - - DelegateEntry* entry = mDelegates; - while (entry) { - if (entry->mKey.Equals(aKey)) { - rv = entry->mDelegate->QueryInterface(aIID, aResult); - return rv; - } - - entry = entry->mNext; - } - - // Construct a ContractID of the form "@mozilla.org/rdf/delegate/[key]/[scheme];1 - nsAutoCString contractID(NS_RDF_DELEGATEFACTORY_CONTRACTID_PREFIX); - contractID.Append(aKey); - contractID.AppendLiteral("&scheme="); - - int32_t i = mURI.FindChar(':'); - contractID += StringHead(mURI, i); - - nsCOMPtr delegateFactory = - do_CreateInstance(contractID.get(), &rv); - if (NS_FAILED(rv)) return rv; - - rv = delegateFactory->CreateDelegate(this, aKey, aIID, aResult); - if (NS_FAILED(rv)) return rv; - - // Okay, we've successfully created a delegate. Let's remember it. - entry = new DelegateEntry; - if (! entry) { - NS_RELEASE(*reinterpret_cast(aResult)); - return NS_ERROR_OUT_OF_MEMORY; - } - - entry->mKey = aKey; - entry->mDelegate = do_QueryInterface(*reinterpret_cast(aResult), &rv); - if (NS_FAILED(rv)) { - NS_ERROR("nsRDFResource::GetDelegate(): can't QI to nsISupports!"); - - delete entry; - NS_RELEASE(*reinterpret_cast(aResult)); - return NS_ERROR_FAILURE; - } - - entry->mNext = mDelegates; - - mDelegates = entry; - - return NS_OK; -} - -NS_IMETHODIMP -nsRDFResource::ReleaseDelegate(const char* aKey) -{ - NS_PRECONDITION(aKey != nullptr, "null ptr"); - if (! aKey) - return NS_ERROR_NULL_POINTER; - - DelegateEntry* entry = mDelegates; - DelegateEntry** link = &mDelegates; - - while (entry) { - if (entry->mKey.Equals(aKey)) { - *link = entry->mNext; - delete entry; - return NS_OK; - } - - link = &(entry->mNext); - entry = entry->mNext; - } - - NS_WARNING("nsRDFResource::ReleaseDelegate() no delegate found"); - return NS_OK; -} - - - -//////////////////////////////////////////////////////////////////////////////// diff --git a/rdf/base/nsRDFResource.h b/rdf/base/nsRDFResource.h deleted file mode 100644 index ace7060eb04e..000000000000 --- a/rdf/base/nsRDFResource.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; 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/. */ - -#ifndef nsRDFResource_h__ -#define nsRDFResource_h__ - -#include "nsCOMPtr.h" -#include "nsIRDFNode.h" -#include "nsIRDFResource.h" -#include "nscore.h" -#include "nsString.h" -#include "rdf.h" - -class nsIRDFService; - -/** - * This simple base class implements nsIRDFResource, and can be used as a - * superclass for more sophisticated resource implementations. - */ -class nsRDFResource : public nsIRDFResource { -public: - - NS_DECL_THREADSAFE_ISUPPORTS - - // nsIRDFNode methods: - NS_IMETHOD EqualsNode(nsIRDFNode* aNode, bool* aResult) override; - - // nsIRDFResource methods: - NS_IMETHOD Init(const char* aURI) override; - NS_IMETHOD GetValue(char* *aURI) override; - NS_IMETHOD GetValueUTF8(nsACString& aResult) override; - NS_IMETHOD GetValueConst(const char** aURI) override; - NS_IMETHOD EqualsString(const char* aURI, bool* aResult) override; - NS_IMETHOD GetDelegate(const char* aKey, REFNSIID aIID, void** aResult) override; - NS_IMETHOD ReleaseDelegate(const char* aKey) override; - - // nsRDFResource methods: - nsRDFResource(void); - -protected: - virtual ~nsRDFResource(void); - static nsIRDFService* gRDFService; - static nsrefcnt gRDFServiceRefCnt; - -protected: - nsCString mURI; - - struct DelegateEntry { - nsCString mKey; - nsCOMPtr mDelegate; - DelegateEntry* mNext; - }; - - DelegateEntry* mDelegates; -}; - -#endif // nsRDFResource_h__ diff --git a/rdf/base/nsRDFService.cpp b/rdf/base/nsRDFService.cpp deleted file mode 100644 index 842b5eb10de0..000000000000 --- a/rdf/base/nsRDFService.cpp +++ /dev/null @@ -1,1540 +0,0 @@ -/* -*- 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 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 "nsAtom.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 "nsNetUtil.h" -#include "nsIURI.h" -#include "PLDHashTable.h" -#include "plhash.h" -#include "plstr.h" -#include "mozilla/Logging.h" -#include "prprf.h" -#include "rdf.h" -#include "nsCRT.h" -#include "nsCRTGlue.h" -#include "mozilla/HashFunctions.h" -#include "mozilla/IntegerPrintfMacros.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 malloc(size); -} - -static void -DataSourceFreeTable(void *pool, void *item) -{ - free(item); -} - -static PLHashEntry * -DataSourceAllocEntry(void *pool, const void *key) -{ - return (PLHashEntry*) malloc(sizeof(PLHashEntry)); -} - -static void -DataSourceFreeEntry(void *pool, PLHashEntry *he, unsigned flag) -{ - if (flag == HT_FREE_ENTRY) { - PL_strfree((char*) he->key); - 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(key)); - } - - static bool - MatchEntry(const PLDHashEntryHdr *hdr, const void *key) - { - const ResourceHashEntry *entry = - static_cast(hdr); - - return 0 == nsCRT::strcmp(static_cast(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(key)); - } - - static bool - MatchEntry(const PLDHashEntryHdr *hdr, const void *key) - { - const LiteralHashEntry *entry = - static_cast(hdr); - - return 0 == nsCRT::strcmp(static_cast(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(key)); - } - - static bool - MatchEntry(const PLDHashEntryHdr *hdr, const void *key) - { - const IntHashEntry *entry = - static_cast(hdr); - - return *static_cast(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(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(hdr); - - return *static_cast(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 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(key); - return HashBytes(data->mBytes, data->mLength); - } - - static bool - MatchEntry(const PLDHashEntryHdr *hdr, const void *key) - { - const BlobHashEntry *entry = - static_cast(hdr); - - const BlobImpl::Data *left = &entry->mBlob->mData; - - const BlobImpl::Data *right = - static_cast(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(reinterpret_cast(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::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(static_cast(objectPtr) + objectSize); - nsCharTraits::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(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(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(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(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 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 nsCString& 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(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 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(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(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(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(aBytes) }; - - PLDHashEntryHdr *hdr = mBlobs.Search(&key); - if (hdr) { - BlobHashEntry *entry = static_cast(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(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(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; - - nsAutoCString uri; - rv = aDataSource->GetURI(uri); - if (NS_FAILED(rv)) return rv; - - PLHashEntry** hep = - PL_HashTableRawLookup(mNamedDataSources, - (*mNamedDataSources->keyHash)(uri.get()), - uri.get()); - - 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, uri.get())); - - (*hep)->value = aDataSource; - } - else { - const char* key = PL_strdup(uri.get()); - if (! key) - return NS_ERROR_OUT_OF_MEMORY; - - PL_HashTableAdd(mNamedDataSources, key, aDataSource); - - MOZ_LOG(gLog, LogLevel::Debug, - ("rdfserv register-datasource [%p] %s", - aDataSource, uri.get())); - - // 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; - - nsAutoCString uri; - rv = aDataSource->GetURI(uri); - if (NS_FAILED(rv)) return rv; - - //NS_ASSERTION(uri != nullptr, "datasource has no URI"); - if (uri.IsVoid()) - return NS_ERROR_UNEXPECTED; - - PLHashEntry** hep = - PL_HashTableRawLookup(mNamedDataSources, - (*mNamedDataSources->keyHash)(uri.get()), - uri.get()); - - // 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, uri.get())); - - 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 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(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 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 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 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(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, NS_ConvertUTF16toUTF8(value).get())); - - 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, NS_ConvertUTF16toUTF8(value).get())); - - 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(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(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] %" PRId64, - 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] %" PRId64, - 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(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; -} diff --git a/rdf/base/nsRDFService.h b/rdf/base/nsRDFService.h deleted file mode 100644 index 19ef355edb00..000000000000 --- a/rdf/base/nsRDFService.h +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- 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/. */ - -#ifndef nsRDFService_h__ -#define nsRDFService_h__ - -#include "nsIRDFService.h" -#include "nsWeakReference.h" -#include "nsIFactory.h" -#include "nsCOMPtr.h" -#include "PLDHashTable.h" -#include "nsString.h" - -struct PLHashTable; -class nsIRDFLiteral; -class nsIRDFInt; -class nsIRDFDate; -class BlobImpl; - -class RDFServiceImpl final : public nsIRDFService, - public nsSupportsWeakReference -{ -protected: - PLHashTable* mNamedDataSources; - PLDHashTable mResources; - PLDHashTable mLiterals; - PLDHashTable mInts; - PLDHashTable mDates; - PLDHashTable mBlobs; - - nsCString mLastURIPrefix; - nsCOMPtr mLastFactory; - nsCOMPtr mDefaultResourceFactory; - - RDFServiceImpl(); - nsresult Init(); - virtual ~RDFServiceImpl(); - -public: - static RDFServiceImpl *gRDFService NS_VISIBILITY_HIDDEN; - static nsresult CreateSingleton(nsISupports* aOuter, - const nsIID& aIID, void **aResult); - - // nsISupports - NS_DECL_ISUPPORTS - - // nsIRDFService - NS_DECL_NSIRDFSERVICE - - // Implementation methods - nsresult RegisterLiteral(nsIRDFLiteral* aLiteral); - nsresult UnregisterLiteral(nsIRDFLiteral* aLiteral); - nsresult RegisterInt(nsIRDFInt* aInt); - nsresult UnregisterInt(nsIRDFInt* aInt); - nsresult RegisterDate(nsIRDFDate* aDate); - nsresult UnregisterDate(nsIRDFDate* aDate); - nsresult RegisterBlob(BlobImpl* aBlob); - nsresult UnregisterBlob(BlobImpl* aBlob); - - nsresult GetDataSource(const char *aURI, bool aBlock, nsIRDFDataSource **aDataSource ); -}; - -#endif // nsRDFService_h__ diff --git a/rdf/base/nsRDFXMLDataSource.cpp b/rdf/base/nsRDFXMLDataSource.cpp deleted file mode 100644 index 5d4200a049ad..000000000000 --- a/rdf/base/nsRDFXMLDataSource.cpp +++ /dev/null @@ -1,1173 +0,0 @@ -/* -*- 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/. */ - -/* - - A data source that can read itself from and write itself to an - RDF/XML stream. - - For more information on the RDF/XML syntax, - see http://www.w3.org/TR/REC-rdf-syntax/. - - This code is based on the final W3C Recommendation, - http://www.w3.org/TR/1999/REC-rdf-syntax-19990222. - - - TO DO - ----- - - 1) Right now, the only kind of stream data sources that are _really_ - writable are "file:" URIs. (In fact, _all_ "file:" URIs are - writable, modulo file system permissions; this may lead to some - surprising behavior.) Eventually, it'd be great if we could open - an arbitrary nsIOutputStream on *any* URL, and Netlib could just - do the magic. - - 2) Implement a more terse output for "typed" nodes; that is, instead - of "RDF:Description type='ns:foo'", just output "ns:foo". - - 3) When re-serializing, we "cheat" for Descriptions that talk about - inline resources (i.e.., using the `ID' attribute specified in - [6.21]). Instead of writing an `ID="foo"' for the first instance, - and then `about="#foo"' for each subsequent instance, we just - _always_ write `about="#foo"'. - - We do this so that we can handle the case where an RDF container - has been assigned arbitrary properties: the spec says we can't - dangle the attributes directly off the container, so we need to - refer to it. Of course, with a little cleverness, we could fix - this. But who cares? - - 4) When re-serializing containers. We have to cheat on some - containers, and use an illegal "about=" construct. We do this to - handle containers that have been assigned URIs outside of the - local document. - - - Logging - ------- - - To turn on logging for this module, set - - MOZ_LOG=nsRDFXMLDataSource:5 - - */ - -#include "nsIFileStreams.h" -#include "nsIOutputStream.h" -#include "nsIFile.h" -#include "nsIFileChannel.h" -#include "nsIDTD.h" -#include "nsIRDFPurgeableDataSource.h" -#include "nsIInputStream.h" -#include "nsIOutputStream.h" -#include "nsIRDFContainerUtils.h" -#include "nsIRDFNode.h" -#include "nsIRDFRemoteDataSource.h" -#include "nsIRDFService.h" -#include "nsIRDFXMLParser.h" -#include "nsIRDFXMLSerializer.h" -#include "nsIRDFXMLSink.h" -#include "nsIRDFXMLSource.h" -#include "nsISafeOutputStream.h" -#include "nsIServiceManager.h" -#include "nsIStreamListener.h" -#include "nsIURL.h" -#include "nsIFileURL.h" -#include "nsISafeOutputStream.h" -#include "nsIChannel.h" -#include "nsRDFCID.h" -#include "nsRDFBaseDataSources.h" -#include "nsCOMArray.h" -#include "nsString.h" -#include "plstr.h" -#include "prio.h" -#include "prthread.h" -#include "rdf.h" -#include "rdfutil.h" -#include "mozilla/Logging.h" -#include "nsNameSpaceMap.h" -#include "nsCRT.h" -#include "nsCycleCollectionParticipant.h" -#include "nsIScriptSecurityManager.h" -#include "nsIChannelEventSink.h" -#include "nsIAsyncVerifyRedirectCallback.h" -#include "nsNetUtil.h" -#include "nsIContentPolicy.h" -#include "nsContentUtils.h" - -#include "rdfIDataSource.h" - -//---------------------------------------------------------------------- -// -// RDFXMLDataSourceImpl -// - -class RDFXMLDataSourceImpl : public nsIRDFDataSource, - public nsIRDFRemoteDataSource, - public nsIRDFXMLSink, - public nsIRDFXMLSource, - public nsIStreamListener, - public rdfIDataSource, - public nsIInterfaceRequestor, - public nsIChannelEventSink -{ -protected: - enum LoadState { - eLoadState_Unloaded, - eLoadState_Pending, - eLoadState_Loading, - eLoadState_Loaded - }; - - nsCOMPtr mInner; - bool mIsWritable; // true if the document can be written back - bool mIsDirty; // true if the document should be written back - LoadState mLoadState; // what we're doing now - nsCOMArray mObservers; - nsCOMPtr mURL; - nsCOMPtr mListener; - nsNameSpaceMap mNameSpaces; - - // pseudo-constants - static int32_t gRefCnt; - static nsIRDFService* gRDFService; - - static mozilla::LazyLogModule gLog; - - nsresult Init(); - RDFXMLDataSourceImpl(void); - virtual ~RDFXMLDataSourceImpl(void); - nsresult rdfXMLFlush(nsIURI *aURI); - - friend nsresult - NS_NewRDFXMLDataSource(nsIRDFDataSource** aResult); - - inline bool IsLoading() { - return (mLoadState == eLoadState_Pending) || - (mLoadState == eLoadState_Loading); - } - -public: - // nsISupports - NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(RDFXMLDataSourceImpl, - nsIRDFDataSource) - - // nsIRDFDataSource - NS_IMETHOD GetURI(nsACString& aURI) override; - - NS_IMETHOD GetSource(nsIRDFResource* property, - nsIRDFNode* target, - bool tv, - nsIRDFResource** source) override { - return mInner->GetSource(property, target, tv, source); - } - - NS_IMETHOD GetSources(nsIRDFResource* property, - nsIRDFNode* target, - bool tv, - nsISimpleEnumerator** sources) override { - return mInner->GetSources(property, target, tv, sources); - } - - NS_IMETHOD GetTarget(nsIRDFResource* source, - nsIRDFResource* property, - bool tv, - nsIRDFNode** target) override { - return mInner->GetTarget(source, property, tv, target); - } - - NS_IMETHOD GetTargets(nsIRDFResource* source, - nsIRDFResource* property, - bool tv, - nsISimpleEnumerator** targets) override { - return mInner->GetTargets(source, property, tv, targets); - } - - NS_IMETHOD Assert(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool tv) override; - - NS_IMETHOD Unassert(nsIRDFResource* source, - nsIRDFResource* property, - nsIRDFNode* target) override; - - NS_IMETHOD Change(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aOldTarget, - nsIRDFNode* aNewTarget) override; - - NS_IMETHOD Move(nsIRDFResource* aOldSource, - nsIRDFResource* aNewSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget) override; - - NS_IMETHOD HasAssertion(nsIRDFResource* source, - nsIRDFResource* property, - nsIRDFNode* target, - bool tv, - bool* hasAssertion) override { - return mInner->HasAssertion(source, property, target, tv, hasAssertion); - } - - NS_IMETHOD AddObserver(nsIRDFObserver* aObserver) override { - return mInner->AddObserver(aObserver); - } - - NS_IMETHOD RemoveObserver(nsIRDFObserver* aObserver) override { - return mInner->RemoveObserver(aObserver); - } - - NS_IMETHOD HasArcIn(nsIRDFNode *aNode, nsIRDFResource *aArc, bool *_retval) override { - return mInner->HasArcIn(aNode, aArc, _retval); - } - - NS_IMETHOD HasArcOut(nsIRDFResource *aSource, nsIRDFResource *aArc, bool *_retval) override { - return mInner->HasArcOut(aSource, aArc, _retval); - } - - NS_IMETHOD ArcLabelsIn(nsIRDFNode* node, - nsISimpleEnumerator** labels) override { - return mInner->ArcLabelsIn(node, labels); - } - - NS_IMETHOD ArcLabelsOut(nsIRDFResource* source, - nsISimpleEnumerator** labels) override { - return mInner->ArcLabelsOut(source, labels); - } - - NS_IMETHOD GetAllResources(nsISimpleEnumerator** aResult) override { - return mInner->GetAllResources(aResult); - } - - NS_IMETHOD GetAllCmds(nsIRDFResource* source, - nsISimpleEnumerator/**/** commands) override { - return mInner->GetAllCmds(source, commands); - } - - NS_IMETHOD IsCommandEnabled(nsISupports* aSources, - nsIRDFResource* aCommand, - nsISupports* aArguments, - bool* aResult) override { - return NS_ERROR_NOT_IMPLEMENTED; - } - - NS_IMETHOD DoCommand(nsISupports* aSources, - nsIRDFResource* aCommand, - nsISupports* aArguments) override { - return NS_ERROR_NOT_IMPLEMENTED; - } - - NS_IMETHOD BeginUpdateBatch() override { - return mInner->BeginUpdateBatch(); - } - - NS_IMETHOD EndUpdateBatch() override { - return mInner->EndUpdateBatch(); - } - - // nsIRDFRemoteDataSource interface - NS_DECL_NSIRDFREMOTEDATASOURCE - - // nsIRDFXMLSink interface - NS_DECL_NSIRDFXMLSINK - - // nsIRDFXMLSource interface - NS_DECL_NSIRDFXMLSOURCE - - // nsIRequestObserver - NS_DECL_NSIREQUESTOBSERVER - - // nsIStreamListener - NS_DECL_NSISTREAMLISTENER - - // nsIInterfaceRequestor - NS_DECL_NSIINTERFACEREQUESTOR - - // nsIChannelEventSink - NS_DECL_NSICHANNELEVENTSINK - - // rdfIDataSource - NS_IMETHOD VisitAllSubjects(rdfITripleVisitor *aVisitor) override { - nsresult rv; - nsCOMPtr rdfds = do_QueryInterface(mInner, &rv); - if (NS_FAILED(rv)) return rv; - return rdfds->VisitAllSubjects(aVisitor); - } - - NS_IMETHOD VisitAllTriples(rdfITripleVisitor *aVisitor) override { - nsresult rv; - nsCOMPtr rdfds = do_QueryInterface(mInner, &rv); - if (NS_FAILED(rv)) return rv; - return rdfds->VisitAllTriples(aVisitor); - } - - // Implementation methods - bool - MakeQName(nsIRDFResource* aResource, - nsString& property, - nsString& nameSpacePrefix, - nsString& nameSpaceURI); - - nsresult - SerializeAssertion(nsIOutputStream* aStream, - nsIRDFResource* aResource, - nsIRDFResource* aProperty, - nsIRDFNode* aValue); - - nsresult - SerializeProperty(nsIOutputStream* aStream, - nsIRDFResource* aResource, - nsIRDFResource* aProperty); - - bool - IsContainerProperty(nsIRDFResource* aProperty); - - nsresult - SerializeDescription(nsIOutputStream* aStream, - nsIRDFResource* aResource); - - nsresult - SerializeMember(nsIOutputStream* aStream, - nsIRDFResource* aContainer, - nsIRDFNode* aMember); - - nsresult - SerializeContainer(nsIOutputStream* aStream, - nsIRDFResource* aContainer); - - nsresult - SerializePrologue(nsIOutputStream* aStream); - - nsresult - SerializeEpilogue(nsIOutputStream* aStream); - - bool - IsA(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource, nsIRDFResource* aType); - -protected: - nsresult - BlockingParse(nsIURI* aURL, nsIStreamListener* aConsumer); -}; - -int32_t RDFXMLDataSourceImpl::gRefCnt = 0; -nsIRDFService* RDFXMLDataSourceImpl::gRDFService; - -mozilla::LazyLogModule RDFXMLDataSourceImpl::gLog("nsRDFXMLDataSource"); - -static const char kFileURIPrefix[] = "file:"; -static const char kResourceURIPrefix[] = "resource:"; - - -//---------------------------------------------------------------------- - -nsresult -NS_NewRDFXMLDataSource(nsIRDFDataSource** aResult) -{ - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - RDFXMLDataSourceImpl* datasource = new RDFXMLDataSourceImpl(); - if (! datasource) - return NS_ERROR_OUT_OF_MEMORY; - - nsresult rv; - rv = datasource->Init(); - - if (NS_FAILED(rv)) { - delete datasource; - return rv; - } - - NS_ADDREF(datasource); - *aResult = datasource; - return NS_OK; -} - - -RDFXMLDataSourceImpl::RDFXMLDataSourceImpl(void) - : mIsWritable(true), - mIsDirty(false), - mLoadState(eLoadState_Unloaded) -{ -} - - -nsresult -RDFXMLDataSourceImpl::Init() -{ - nsresult rv; - NS_DEFINE_CID(kRDFInMemoryDataSourceCID, NS_RDFINMEMORYDATASOURCE_CID); - mInner = do_CreateInstance(kRDFInMemoryDataSourceCID, &rv); - if (NS_FAILED(rv)) return rv; - - if (gRefCnt++ == 0) { - NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); - rv = CallGetService(kRDFServiceCID, &gRDFService); - - NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get RDF service"); - if (NS_FAILED(rv)) return rv; - } - - return NS_OK; -} - - -RDFXMLDataSourceImpl::~RDFXMLDataSourceImpl(void) -{ - // Unregister first so that nobody else tries to get us. - (void) gRDFService->UnregisterDataSource(this); - - // Now flush contents - (void) Flush(); - - // Release RDF/XML sink observers - mObservers.Clear(); - - if (--gRefCnt == 0) - NS_IF_RELEASE(gRDFService); -} - -NS_IMPL_CYCLE_COLLECTION_CLASS(RDFXMLDataSourceImpl) - -NS_IMPL_CYCLE_COLLECTION_UNLINK_0(RDFXMLDataSourceImpl) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(RDFXMLDataSourceImpl) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mInner) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END - -NS_IMPL_CYCLE_COLLECTING_ADDREF(RDFXMLDataSourceImpl) -NS_IMPL_CYCLE_COLLECTING_RELEASE(RDFXMLDataSourceImpl) - -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(RDFXMLDataSourceImpl) - NS_INTERFACE_MAP_ENTRY(nsIRDFDataSource) - NS_INTERFACE_MAP_ENTRY(nsIRDFRemoteDataSource) - NS_INTERFACE_MAP_ENTRY(nsIRDFXMLSink) - NS_INTERFACE_MAP_ENTRY(nsIRDFXMLSource) - NS_INTERFACE_MAP_ENTRY(nsIRequestObserver) - NS_INTERFACE_MAP_ENTRY(nsIStreamListener) - NS_INTERFACE_MAP_ENTRY(rdfIDataSource) - NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor) - NS_INTERFACE_MAP_ENTRY(nsIChannelEventSink) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRDFDataSource) -NS_INTERFACE_MAP_END - -// nsIInterfaceRequestor -NS_IMETHODIMP -RDFXMLDataSourceImpl::GetInterface(const nsIID& aIID, void** aSink) -{ - return QueryInterface(aIID, aSink); -} - -nsresult -RDFXMLDataSourceImpl::BlockingParse(nsIURI* aURL, nsIStreamListener* aConsumer) -{ - nsresult rv; - - // XXX I really hate the way that we're spoon-feeding this stuff - // to the parser: it seems like this is something that netlib - // should be able to do by itself. - - nsCOMPtr channel; - - // Null LoadGroup ? - rv = NS_NewChannel(getter_AddRefs(channel), - aURL, - nsContentUtils::GetSystemPrincipal(), - nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, - nsIContentPolicy::TYPE_OTHER); - - if (NS_FAILED(rv)) return rv; - nsCOMPtr in; - rv = channel->Open2(getter_AddRefs(in)); - - // Report success if the file doesn't exist, but propagate other errors. - if (rv == NS_ERROR_FILE_NOT_FOUND) return NS_OK; - if (NS_FAILED(rv)) return rv; - - if (! in) { - NS_ERROR("no input stream"); - return NS_ERROR_FAILURE; - } - - // Wrap the channel's input stream in a buffered stream to ensure that - // ReadSegments is implemented (which OnDataAvailable expects). - nsCOMPtr bufStream; - rv = NS_NewBufferedInputStream(getter_AddRefs(bufStream), in.forget(), - 4096 /* buffer size */); - if (NS_FAILED(rv)) return rv; - - // Notify load observers - int32_t i; - for (i = mObservers.Count() - 1; i >= 0; --i) { - // Make sure to hold a strong reference to the observer so - // that it doesn't go away in this call if it removes itself - // as an observer - nsCOMPtr obs = mObservers[i]; - - if (obs) { - obs->OnBeginLoad(this); - } - } - - rv = aConsumer->OnStartRequest(channel, nullptr); - - uint64_t offset = 0; - while (NS_SUCCEEDED(rv)) { - // Skip ODA if the channel is canceled - channel->GetStatus(&rv); - if (NS_FAILED(rv)) - break; - - uint64_t avail; - if (NS_FAILED(rv = bufStream->Available(&avail))) - break; // error - - if (avail == 0) - break; // eof - - if (avail > UINT32_MAX) - avail = UINT32_MAX; - - rv = aConsumer->OnDataAvailable(channel, nullptr, bufStream, offset, (uint32_t)avail); - if (NS_SUCCEEDED(rv)) - offset += avail; - } - - if (NS_FAILED(rv)) - channel->Cancel(rv); - - channel->GetStatus(&rv); - aConsumer->OnStopRequest(channel, nullptr, rv); - - // Notify load observers - for (i = mObservers.Count() - 1; i >= 0; --i) { - // Make sure to hold a strong reference to the observer so - // that it doesn't go away in this call if it removes itself - // as an observer - nsCOMPtr obs = mObservers[i]; - - if (obs) { - if (NS_FAILED(rv)) - obs->OnError(this, rv, nullptr); - - obs->OnEndLoad(this); - } - } - - return rv; -} - -NS_IMETHODIMP -RDFXMLDataSourceImpl::GetLoaded(bool* _result) -{ - *_result = (mLoadState == eLoadState_Loaded); - return NS_OK; -} - -NS_IMETHODIMP -RDFXMLDataSourceImpl::Init(const char* uri) -{ - NS_PRECONDITION(mInner != nullptr, "not initialized"); - if (! mInner) - return NS_ERROR_OUT_OF_MEMORY; - - nsresult rv; - - rv = NS_NewURI(getter_AddRefs(mURL), nsDependentCString(uri)); - if (NS_FAILED(rv)) return rv; - - // XXX this is a hack: any "file:" URI is considered writable. All - // others are considered read-only. - if ((PL_strncmp(uri, kFileURIPrefix, sizeof(kFileURIPrefix) - 1) != 0) && - (PL_strncmp(uri, kResourceURIPrefix, sizeof(kResourceURIPrefix) - 1) != 0)) { - mIsWritable = false; - } - - rv = gRDFService->RegisterDataSource(this, false); - if (NS_FAILED(rv)) return rv; - - return NS_OK; -} - - -NS_IMETHODIMP -RDFXMLDataSourceImpl::GetURI(nsACString& aURI) -{ - if (!mURL) { - aURI.SetIsVoid(true); - return NS_OK; - } - - return mURL->GetSpec(aURI); -} - -NS_IMETHODIMP -RDFXMLDataSourceImpl::Assert(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue) -{ - // We don't accept assertions unless we're writable (except in the - // case that we're actually _reading_ the datasource in). - nsresult rv; - - if (IsLoading()) { - bool hasAssertion = false; - - nsCOMPtr gcable = do_QueryInterface(mInner); - if (gcable) { - rv = gcable->Mark(aSource, aProperty, aTarget, aTruthValue, &hasAssertion); - if (NS_FAILED(rv)) return rv; - } - - rv = NS_RDF_ASSERTION_ACCEPTED; - - if (! hasAssertion) { - rv = mInner->Assert(aSource, aProperty, aTarget, aTruthValue); - - if (NS_SUCCEEDED(rv) && gcable) { - // Now mark the new assertion, so it doesn't get - // removed when we sweep. Ignore rv, because we want - // to return what mInner->Assert() gave us. - bool didMark; - (void) gcable->Mark(aSource, aProperty, aTarget, aTruthValue, &didMark); - } - - if (NS_FAILED(rv)) return rv; - } - - return rv; - } - else if (mIsWritable) { - rv = mInner->Assert(aSource, aProperty, aTarget, aTruthValue); - - if (rv == NS_RDF_ASSERTION_ACCEPTED) - mIsDirty = true; - - return rv; - } - else { - return NS_RDF_ASSERTION_REJECTED; - } -} - - -NS_IMETHODIMP -RDFXMLDataSourceImpl::Unassert(nsIRDFResource* source, - nsIRDFResource* property, - nsIRDFNode* target) -{ - // We don't accept assertions unless we're writable (except in the - // case that we're actually _reading_ the datasource in). - nsresult rv; - - if (IsLoading() || mIsWritable) { - rv = mInner->Unassert(source, property, target); - if (!IsLoading() && rv == NS_RDF_ASSERTION_ACCEPTED) - mIsDirty = true; - } - else { - rv = NS_RDF_ASSERTION_REJECTED; - } - - return rv; -} - -NS_IMETHODIMP -RDFXMLDataSourceImpl::Change(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aOldTarget, - nsIRDFNode* aNewTarget) -{ - nsresult rv; - - if (IsLoading() || mIsWritable) { - rv = mInner->Change(aSource, aProperty, aOldTarget, aNewTarget); - - if (!IsLoading() && rv == NS_RDF_ASSERTION_ACCEPTED) - mIsDirty = true; - } - else { - rv = NS_RDF_ASSERTION_REJECTED; - } - - return rv; -} - -NS_IMETHODIMP -RDFXMLDataSourceImpl::Move(nsIRDFResource* aOldSource, - nsIRDFResource* aNewSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget) -{ - nsresult rv; - - if (IsLoading() || mIsWritable) { - rv = mInner->Move(aOldSource, aNewSource, aProperty, aTarget); - if (!IsLoading() && rv == NS_RDF_ASSERTION_ACCEPTED) - mIsDirty = true; - } - else { - rv = NS_RDF_ASSERTION_REJECTED; - } - - return rv; -} - - -nsresult -RDFXMLDataSourceImpl::rdfXMLFlush(nsIURI *aURI) -{ - - nsresult rv; - - { - // Quick and dirty check to see if we're in XPCOM shutdown. If - // we are, we're screwed: it's too late to serialize because - // many of the services that we'll need to acquire to properly - // write the file will be unaquirable. - NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); - nsCOMPtr dummy = do_GetService(kRDFServiceCID, &rv); - if (NS_FAILED(rv)) { - NS_WARNING("unable to Flush() dirty datasource during XPCOM shutdown"); - return rv; - } - } - - // Is it a file? If so, we can write to it. Some day, it'd be nice - // if we didn't care what kind of stream this was... - nsCOMPtr fileURL = do_QueryInterface(aURI); - - if (fileURL) { - nsCOMPtr file; - fileURL->GetFile(getter_AddRefs(file)); - if (file) { - // get a safe output stream, so we don't clobber the datasource file unless - // all the writes succeeded. - nsCOMPtr out; - rv = NS_NewSafeLocalFileOutputStream(getter_AddRefs(out), - file, - PR_WRONLY | PR_CREATE_FILE, - /*octal*/ 0666, - 0); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr bufferedOut; - rv = NS_NewBufferedOutputStream(getter_AddRefs(bufferedOut), - out.forget(), 4096); - if (NS_FAILED(rv)) return rv; - - rv = Serialize(bufferedOut); - if (NS_FAILED(rv)) return rv; - - // All went ok. Maybe except for problems in Write(), but the stream detects - // that for us - nsCOMPtr safeStream = do_QueryInterface(bufferedOut, &rv); - if (NS_FAILED(rv)) return rv; - - rv = safeStream->Finish(); - if (NS_FAILED(rv)) { - NS_WARNING("failed to save datasource file! possible dataloss"); - return rv; - } - } - } - - return NS_OK; -} - - -NS_IMETHODIMP -RDFXMLDataSourceImpl::FlushTo(const char *aURI) -{ - NS_PRECONDITION(aURI != nullptr, "not initialized"); - if (!aURI) - return NS_ERROR_NULL_POINTER; - - // XXX this is a hack: any "file:" URI is considered writable. All - // others are considered read-only. - if ((PL_strncmp(aURI, kFileURIPrefix, sizeof(kFileURIPrefix) - 1) != 0) && - (PL_strncmp(aURI, kResourceURIPrefix, sizeof(kResourceURIPrefix) - 1) != 0)) - { - return NS_ERROR_ILLEGAL_VALUE; - } - - nsCOMPtr url; - nsresult rv = NS_NewURI(getter_AddRefs(url), aURI); - if (NS_FAILED(rv)) - return rv; - rv = rdfXMLFlush(url); - return rv; -} - - -NS_IMETHODIMP -RDFXMLDataSourceImpl::Flush(void) -{ - if (!mIsWritable || !mIsDirty) - return NS_OK; - - // while it is not fatal if mURL is not set, - // indicate failure since we can't flush back to an unknown origin - if (! mURL) - return NS_ERROR_NOT_INITIALIZED; - - if (MOZ_LOG_TEST(gLog, LogLevel::Debug)) { - MOZ_LOG(gLog, LogLevel::Debug, - ("rdfxml[%p] flush(%s)", this, mURL->GetSpecOrDefault().get())); - } - - nsresult rv; - if (NS_SUCCEEDED(rv = rdfXMLFlush(mURL))) - { - mIsDirty = false; - } - return rv; -} - - -//---------------------------------------------------------------------- -// -// nsIRDFXMLDataSource methods -// - -NS_IMETHODIMP -RDFXMLDataSourceImpl::GetReadOnly(bool* aIsReadOnly) -{ - *aIsReadOnly = !mIsWritable; - return NS_OK; -} - - -NS_IMETHODIMP -RDFXMLDataSourceImpl::SetReadOnly(bool aIsReadOnly) -{ - if (mIsWritable && aIsReadOnly) - mIsWritable = false; - - return NS_OK; -} - -// nsIChannelEventSink - -// This code is copied from nsSameOriginChecker::OnChannelRedirect. See -// bug 475940 on providing this code in a shared location. -NS_IMETHODIMP -RDFXMLDataSourceImpl::AsyncOnChannelRedirect(nsIChannel *aOldChannel, - nsIChannel *aNewChannel, - uint32_t aFlags, - nsIAsyncVerifyRedirectCallback *cb) -{ - NS_PRECONDITION(aNewChannel, "Redirecting to null channel?"); - - nsresult rv; - nsCOMPtr secMan = - do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr oldPrincipal; - secMan->GetChannelResultPrincipal(aOldChannel, getter_AddRefs(oldPrincipal)); - - nsCOMPtr newURI; - aNewChannel->GetURI(getter_AddRefs(newURI)); - nsCOMPtr newOriginalURI; - aNewChannel->GetOriginalURI(getter_AddRefs(newOriginalURI)); - - NS_ENSURE_STATE(oldPrincipal && newURI && newOriginalURI); - - rv = oldPrincipal->CheckMayLoad(newURI, false, false); - if (NS_SUCCEEDED(rv) && newOriginalURI != newURI) { - rv = oldPrincipal->CheckMayLoad(newOriginalURI, false, false); - } - - if (NS_FAILED(rv)) - return rv; - - cb->OnRedirectVerifyCallback(NS_OK); - return NS_OK; -} - -NS_IMETHODIMP -RDFXMLDataSourceImpl::Refresh(bool aBlocking) -{ - nsAutoCString spec; - if (mURL) { - spec = mURL->GetSpecOrDefault(); - } - MOZ_LOG(gLog, LogLevel::Debug, - ("rdfxml[%p] refresh(%s) %sblocking", this, spec.get(), (aBlocking ? "" : "non"))); - - // If an asynchronous load is already pending, then just let it do - // the honors. - if (IsLoading()) { - MOZ_LOG(gLog, LogLevel::Debug, - ("rdfxml[%p] refresh(%s) a load was pending", this, spec.get())); - - if (aBlocking) { - NS_WARNING("blocking load requested when async load pending"); - return NS_ERROR_FAILURE; - } - else { - return NS_OK; - } - } - - if (! mURL) - return NS_ERROR_FAILURE; - nsCOMPtr parser = do_CreateInstance("@mozilla.org/rdf/xml-parser;1"); - if (! parser) - return NS_ERROR_FAILURE; - - nsresult rv = parser->ParseAsync(this, mURL, getter_AddRefs(mListener)); - if (NS_FAILED(rv)) return rv; - - if (aBlocking) { - rv = BlockingParse(mURL, this); - - mListener = nullptr; // release the parser - - if (NS_FAILED(rv)) return rv; - } - else { - // Null LoadGroup ? - nsCOMPtr channel; - rv = NS_NewChannel(getter_AddRefs(channel), - mURL, - nsContentUtils::GetSystemPrincipal(), - nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, - nsIContentPolicy::TYPE_OTHER, - nullptr, // aPerformanceStorage - nullptr, // aLoadGroup - this); // aCallbacks - NS_ENSURE_SUCCESS(rv, rv); - rv = channel->AsyncOpen2(this); - NS_ENSURE_SUCCESS(rv, rv); - - // So we don't try to issue two asynchronous loads at once. - mLoadState = eLoadState_Pending; - } - - return NS_OK; -} - -NS_IMETHODIMP -RDFXMLDataSourceImpl::BeginLoad(void) -{ - if (MOZ_LOG_TEST(gLog, LogLevel::Debug)) { - MOZ_LOG(gLog, LogLevel::Debug, - ("rdfxml[%p] begin-load(%s)", this, - mURL ? mURL->GetSpecOrDefault().get() : "")); - } - - mLoadState = eLoadState_Loading; - for (int32_t i = mObservers.Count() - 1; i >= 0; --i) { - // Make sure to hold a strong reference to the observer so - // that it doesn't go away in this call if it removes itself - // as an observer - nsCOMPtr obs = mObservers[i]; - - if (obs) { - obs->OnBeginLoad(this); - } - } - return NS_OK; -} - -NS_IMETHODIMP -RDFXMLDataSourceImpl::Interrupt(void) -{ - if (MOZ_LOG_TEST(gLog, LogLevel::Debug)) { - MOZ_LOG(gLog, LogLevel::Debug, - ("rdfxml[%p] interrupt(%s)", this, - mURL ? mURL->GetSpecOrDefault().get() : "")); - } - - for (int32_t i = mObservers.Count() - 1; i >= 0; --i) { - // Make sure to hold a strong reference to the observer so - // that it doesn't go away in this call if it removes itself - // as an observer - nsCOMPtr obs = mObservers[i]; - - if (obs) { - obs->OnInterrupt(this); - } - } - return NS_OK; -} - -NS_IMETHODIMP -RDFXMLDataSourceImpl::Resume(void) -{ - if (MOZ_LOG_TEST(gLog, LogLevel::Debug)) { - MOZ_LOG(gLog, LogLevel::Debug, - ("rdfxml[%p] resume(%s)", this, - mURL ? mURL->GetSpecOrDefault().get() : "")); - } - - for (int32_t i = mObservers.Count() - 1; i >= 0; --i) { - // Make sure to hold a strong reference to the observer so - // that it doesn't go away in this call if it removes itself - // as an observer - nsCOMPtr obs = mObservers[i]; - - if (obs) { - obs->OnResume(this); - } - } - return NS_OK; -} - -NS_IMETHODIMP -RDFXMLDataSourceImpl::EndLoad(void) -{ - if (MOZ_LOG_TEST(gLog, LogLevel::Debug)) { - MOZ_LOG(gLog, LogLevel::Debug, - ("rdfxml[%p] end-load(%s)", this, - mURL ? mURL->GetSpecOrDefault().get() : "")); - } - - mLoadState = eLoadState_Loaded; - - // Clear out any unmarked assertions from the datasource. - nsCOMPtr gcable = do_QueryInterface(mInner); - if (gcable) { - gcable->Sweep(); - } - - // Notify load observers - for (int32_t i = mObservers.Count() - 1; i >= 0; --i) { - // Make sure to hold a strong reference to the observer so - // that it doesn't go away in this call if it removes itself - // as an observer - nsCOMPtr obs = mObservers[i]; - - if (obs) { - obs->OnEndLoad(this); - } - } - return NS_OK; -} - -NS_IMETHODIMP -RDFXMLDataSourceImpl::AddNameSpace(nsAtom* aPrefix, const nsString& aURI) -{ - mNameSpaces.Put(aURI, aPrefix); - return NS_OK; -} - - -NS_IMETHODIMP -RDFXMLDataSourceImpl::AddXMLSinkObserver(nsIRDFXMLSinkObserver* aObserver) -{ - if (! aObserver) - return NS_ERROR_NULL_POINTER; - - mObservers.AppendObject(aObserver); - return NS_OK; -} - -NS_IMETHODIMP -RDFXMLDataSourceImpl::RemoveXMLSinkObserver(nsIRDFXMLSinkObserver* aObserver) -{ - if (! aObserver) - return NS_ERROR_NULL_POINTER; - - mObservers.RemoveObject(aObserver); - - return NS_OK; -} - - -//---------------------------------------------------------------------- -// -// nsIRequestObserver -// - -NS_IMETHODIMP -RDFXMLDataSourceImpl::OnStartRequest(nsIRequest *request, nsISupports *ctxt) -{ - return mListener->OnStartRequest(request, ctxt); -} - -NS_IMETHODIMP -RDFXMLDataSourceImpl::OnStopRequest(nsIRequest *request, - nsISupports *ctxt, - nsresult status) -{ - if (NS_FAILED(status)) { - for (int32_t i = mObservers.Count() - 1; i >= 0; --i) { - // Make sure to hold a strong reference to the observer so - // that it doesn't go away in this call if it removes - // itself as an observer - nsCOMPtr obs = mObservers[i]; - - if (obs) { - obs->OnError(this, status, nullptr); - } - } - } - - nsresult rv; - rv = mListener->OnStopRequest(request, ctxt, status); - - mListener = nullptr; // release the parser - - return rv; -} - -//---------------------------------------------------------------------- -// -// nsIStreamListener -// - -NS_IMETHODIMP -RDFXMLDataSourceImpl::OnDataAvailable(nsIRequest *request, - nsISupports *ctxt, - nsIInputStream *inStr, - uint64_t sourceOffset, - uint32_t count) -{ - return mListener->OnDataAvailable(request, ctxt, inStr, sourceOffset, count); -} - -//---------------------------------------------------------------------- -// -// nsIRDFXMLSource -// - -NS_IMETHODIMP -RDFXMLDataSourceImpl::Serialize(nsIOutputStream* aStream) -{ - nsresult rv; - nsCOMPtr serializer - = do_CreateInstance("@mozilla.org/rdf/xml-serializer;1", &rv); - - if (! serializer) - return rv; - - rv = serializer->Init(this); - if (NS_FAILED(rv)) return rv; - - // Add any namespace information that we picked up when reading - // the RDF/XML - nsNameSpaceMap::const_iterator last = mNameSpaces.last(); - for (nsNameSpaceMap::const_iterator iter = mNameSpaces.first(); - iter != last; ++iter) { - // We might wanna change nsIRDFXMLSerializer to nsACString and - // use a heap allocated buffer here in the future. - NS_ConvertUTF8toUTF16 uri(iter->mURI); - serializer->AddNameSpace(iter->mPrefix, uri); - } - - // Serialize! - nsCOMPtr source = do_QueryInterface(serializer); - if (! source) - return NS_ERROR_FAILURE; - - return source->Serialize(aStream); -} diff --git a/rdf/base/nsRDFXMLParser.cpp b/rdf/base/nsRDFXMLParser.cpp deleted file mode 100644 index 819e53d702bb..000000000000 --- a/rdf/base/nsRDFXMLParser.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/* -*- 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/. */ - -#include "nsRDFXMLParser.h" - -#include "mozilla/Encoding.h" -#include "nsIComponentManager.h" -#include "nsIParser.h" -#include "nsCharsetSource.h" -#include "nsIRDFContentSink.h" -#include "nsParserCIID.h" -#include "nsStringStream.h" -#include "nsNetUtil.h" -#include "NullPrincipal.h" - -static NS_DEFINE_CID(kParserCID, NS_PARSER_CID); - -NS_IMPL_ISUPPORTS(nsRDFXMLParser, nsIRDFXMLParser) - -nsresult -nsRDFXMLParser::Create(nsISupports* aOuter, REFNSIID aIID, void** aResult) -{ - if (aOuter) - return NS_ERROR_NO_AGGREGATION; - - nsRDFXMLParser* result = new nsRDFXMLParser(); - if (! result) - return NS_ERROR_OUT_OF_MEMORY; - - nsresult rv; - NS_ADDREF(result); - rv = result->QueryInterface(aIID, aResult); - NS_RELEASE(result); - return rv; -} - -nsRDFXMLParser::nsRDFXMLParser() -{ -} - -nsRDFXMLParser::~nsRDFXMLParser() -{ -} - -NS_IMETHODIMP -nsRDFXMLParser::ParseAsync(nsIRDFDataSource* aSink, nsIURI* aBaseURI, nsIStreamListener** aResult) -{ - nsresult rv; - - nsCOMPtr sink = - do_CreateInstance("@mozilla.org/rdf/content-sink;1", &rv); - - if (NS_FAILED(rv)) return rv; - - rv = sink->Init(aBaseURI); - if (NS_FAILED(rv)) return rv; - - // We set the content sink's data source directly to our in-memory - // store. This allows the initial content to be generated "directly". - rv = sink->SetDataSource(aSink); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr parser = do_CreateInstance(kParserCID, &rv); - if (NS_FAILED(rv)) return rv; - - parser->SetDocumentCharset(UTF_8_ENCODING, - kCharsetFromDocTypeDefault); - parser->SetContentSink(sink); - - rv = parser->Parse(aBaseURI); - if (NS_FAILED(rv)) return rv; - - return CallQueryInterface(parser, aResult); -} - -NS_IMETHODIMP -nsRDFXMLParser::ParseString(nsIRDFDataSource* aSink, nsIURI* aBaseURI, const nsACString& aString) -{ - nsresult rv; - - nsCOMPtr sink = - do_CreateInstance("@mozilla.org/rdf/content-sink;1", &rv); - - if (NS_FAILED(rv)) return rv; - - rv = sink->Init(aBaseURI); - if (NS_FAILED(rv)) return rv; - - // We set the content sink's data source directly to our in-memory - // store. This allows the initial content to be generated "directly". - rv = sink->SetDataSource(aSink); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr parser = do_CreateInstance(kParserCID, &rv); - if (NS_FAILED(rv)) return rv; - - parser->SetDocumentCharset(UTF_8_ENCODING, - kCharsetFromOtherComponent); - parser->SetContentSink(sink); - - rv = parser->Parse(aBaseURI); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr listener = - do_QueryInterface(parser); - - if (! listener) - return NS_ERROR_FAILURE; - - nsCOMPtr stream; - rv = NS_NewCStringInputStream(getter_AddRefs(stream), aString); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr nullPrincipal = NullPrincipal::CreateWithoutOriginAttributes(); - - // The following channel is never openend, so it does not matter what - // securityFlags we pass; let's follow the principle of least privilege. - nsCOMPtr channel; - nsCOMPtr tmpStream = stream; - rv = NS_NewInputStreamChannel(getter_AddRefs(channel), - aBaseURI, - tmpStream.forget(), - nullPrincipal, - nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED, - nsIContentPolicy::TYPE_OTHER, - NS_LITERAL_CSTRING("text/xml")); - if (NS_FAILED(rv)) return rv; - - listener->OnStartRequest(channel, nullptr); - listener->OnDataAvailable(channel, nullptr, stream, 0, aString.Length()); - listener->OnStopRequest(channel, nullptr, NS_OK); - - return NS_OK; -} diff --git a/rdf/base/nsRDFXMLParser.h b/rdf/base/nsRDFXMLParser.h deleted file mode 100644 index d35c873fbecf..000000000000 --- a/rdf/base/nsRDFXMLParser.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -*- 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/. */ - -#ifndef nsRDFParser_h__ -#define nsRDFParser_h__ - -#include "nsCOMPtr.h" -#include "nsString.h" -#include "nsIRDFXMLParser.h" -#include "nsIRDFDataSource.h" - -/** - * A helper class that is used to parse RDF/XML. - */ -class nsRDFXMLParser : public nsIRDFXMLParser { -public: - static nsresult - Create(nsISupports* aOuter, REFNSIID aIID, void** aResult); - - NS_DECL_ISUPPORTS - NS_DECL_NSIRDFXMLPARSER - -protected: - nsRDFXMLParser(); - virtual ~nsRDFXMLParser(); -}; - -#endif // nsRDFParser_h__ diff --git a/rdf/base/nsRDFXMLSerializer.cpp b/rdf/base/nsRDFXMLSerializer.cpp deleted file mode 100644 index c93307c9da72..000000000000 --- a/rdf/base/nsRDFXMLSerializer.cpp +++ /dev/null @@ -1,1123 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=4 sw=4 et tw=80: - * - * 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/. */ - -#include "nsRDFXMLSerializer.h" - -#include "nsAtom.h" -#include "nsIOutputStream.h" -#include "nsIRDFService.h" -#include "nsIRDFContainerUtils.h" -#include "nsIServiceManager.h" -#include "nsString.h" -#include "nsTArray.h" -#include "rdf.h" -#include "rdfutil.h" -#include "mozilla/Attributes.h" - -#include "rdfIDataSource.h" - -int32_t nsRDFXMLSerializer::gRefCnt = 0; -nsIRDFContainerUtils* nsRDFXMLSerializer::gRDFC; -nsIRDFResource* nsRDFXMLSerializer::kRDF_instanceOf; -nsIRDFResource* nsRDFXMLSerializer::kRDF_type; -nsIRDFResource* nsRDFXMLSerializer::kRDF_nextVal; -nsIRDFResource* nsRDFXMLSerializer::kRDF_Bag; -nsIRDFResource* nsRDFXMLSerializer::kRDF_Seq; -nsIRDFResource* nsRDFXMLSerializer::kRDF_Alt; - -static const char kRDFDescriptionOpen[] = " \n"; -static const char kRDFParseTypeInteger[] = " NC:parseType=\"Integer\">"; -static const char kRDFParseTypeDate[] = " NC:parseType=\"Date\">"; -static const char kRDFUnknown[] = ">"; - -nsresult -nsRDFXMLSerializer::Create(nsISupports* aOuter, REFNSIID aIID, void** aResult) -{ - if (aOuter) - return NS_ERROR_NO_AGGREGATION; - - nsCOMPtr result = new nsRDFXMLSerializer(); - if (! result) - return NS_ERROR_OUT_OF_MEMORY; - // The serializer object is here, addref gRefCnt so that the - // destructor can safely release it. - gRefCnt++; - - nsresult rv; - rv = result->QueryInterface(aIID, aResult); - - if (NS_FAILED(rv)) return rv; - - if (gRefCnt == 1) do { - nsCOMPtr rdf = do_GetService("@mozilla.org/rdf/rdf-service;1", &rv); - if (NS_FAILED(rv)) break; - - rv = rdf->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "instanceOf"), - &kRDF_instanceOf); - if (NS_FAILED(rv)) break; - - rv = rdf->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "type"), - &kRDF_type); - if (NS_FAILED(rv)) break; - - rv = rdf->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "nextVal"), - &kRDF_nextVal); - if (NS_FAILED(rv)) break; - - rv = rdf->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "Bag"), - &kRDF_Bag); - if (NS_FAILED(rv)) break; - - rv = rdf->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "Seq"), - &kRDF_Seq); - if (NS_FAILED(rv)) break; - - rv = rdf->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "Alt"), - &kRDF_Alt); - if (NS_FAILED(rv)) break; - - rv = CallGetService("@mozilla.org/rdf/container-utils;1", &gRDFC); - if (NS_FAILED(rv)) break; - } while (0); - - return rv; -} - -nsRDFXMLSerializer::nsRDFXMLSerializer() -{ -} - -nsRDFXMLSerializer::~nsRDFXMLSerializer() -{ - if (--gRefCnt == 0) { - NS_IF_RELEASE(kRDF_Bag); - NS_IF_RELEASE(kRDF_Seq); - NS_IF_RELEASE(kRDF_Alt); - NS_IF_RELEASE(kRDF_instanceOf); - NS_IF_RELEASE(kRDF_type); - NS_IF_RELEASE(kRDF_nextVal); - NS_IF_RELEASE(gRDFC); - } -} - -NS_IMPL_ISUPPORTS(nsRDFXMLSerializer, nsIRDFXMLSerializer, nsIRDFXMLSource) - -NS_IMETHODIMP -nsRDFXMLSerializer::Init(nsIRDFDataSource* aDataSource) -{ - if (! aDataSource) - return NS_ERROR_NULL_POINTER; - - mDataSource = aDataSource; - mDataSource->GetURI(mBaseURLSpec); - - // Add the ``RDF'' prefix, by default. - RefPtr prefix; - - prefix = NS_Atomize("RDF"); - AddNameSpace(prefix, NS_LITERAL_STRING("http://www.w3.org/1999/02/22-rdf-syntax-ns#")); - - prefix = NS_Atomize("NC"); - AddNameSpace(prefix, NS_LITERAL_STRING("http://home.netscape.com/NC-rdf#")); - - mPrefixID = 0; - - return NS_OK; -} - -NS_IMETHODIMP -nsRDFXMLSerializer::AddNameSpace(nsAtom* aPrefix, const nsAString& aURI) -{ - RefPtr prefix = aPrefix; - if (!prefix) { - // Make up a prefix, we don't want default namespaces, so - // that we can use QNames for elements and attributes alike. - prefix = EnsureNewPrefix(); - } - mNameSpaces.Put(aURI, prefix); - return NS_OK; -} - -static nsresult -rdf_BlockingWrite(nsIOutputStream* stream, const char* buf, uint32_t size) -{ - uint32_t written = 0; - uint32_t remaining = size; - while (remaining > 0) { - nsresult rv; - uint32_t cb; - - if (NS_FAILED(rv = stream->Write(buf + written, remaining, &cb))) - return rv; - - written += cb; - remaining -= cb; - } - return NS_OK; -} - -static nsresult -rdf_BlockingWrite(nsIOutputStream* stream, const nsACString& s) -{ - return rdf_BlockingWrite(stream, s.BeginReading(), s.Length()); -} - -static nsresult -rdf_BlockingWrite(nsIOutputStream* stream, const nsAString& s) -{ - NS_ConvertUTF16toUTF8 utf8(s); - return rdf_BlockingWrite(stream, utf8.get(), utf8.Length()); -} - -already_AddRefed -nsRDFXMLSerializer::EnsureNewPrefix() -{ - nsAutoString qname; - RefPtr prefix; - bool isNewPrefix; - do { - isNewPrefix = true; - qname.AssignLiteral("NS"); - qname.AppendInt(++mPrefixID, 10); - prefix = NS_Atomize(qname); - nsNameSpaceMap::const_iterator iter = mNameSpaces.first(); - while (iter != mNameSpaces.last() && isNewPrefix) { - isNewPrefix = (iter->mPrefix != prefix); - ++iter; - } - } while (!isNewPrefix); - return prefix.forget(); -} - -// This converts a property resource (like -// "http://www.w3.org/TR/WD-rdf-syntax#Description") into a QName -// ("RDF:Description"), and registers the namespace, if it's made up. - -nsresult -nsRDFXMLSerializer::RegisterQName(nsIRDFResource* aResource) -{ - nsAutoCString uri, qname; - aResource->GetValueUTF8(uri); - - nsNameSpaceMap::const_iterator iter = mNameSpaces.GetNameSpaceOf(uri); - if (iter != mNameSpaces.last()) { - NS_ENSURE_TRUE(iter->mPrefix, NS_ERROR_UNEXPECTED); - iter->mPrefix->ToUTF8String(qname); - qname.Append(':'); - qname += StringTail(uri, uri.Length() - iter->mURI.Length()); - mQNames.Put(aResource, qname); - return NS_OK; - } - - // Okay, so we don't have it in our map. Try to make one up. This - // is very bogus. - int32_t i = uri.RFindChar('#'); // first try a '#' - if (i == -1) { - i = uri.RFindChar('/'); - if (i == -1) { - // Okay, just punt and assume there is _no_ namespace on - // this thing... - mQNames.Put(aResource, uri); - return NS_OK; - } - } - - // Take whatever is to the right of the '#' or '/' and call it the - // local name, make up a prefix. - RefPtr prefix = EnsureNewPrefix(); - mNameSpaces.Put(StringHead(uri, i+1), prefix); - prefix->ToUTF8String(qname); - qname.Append(':'); - qname += StringTail(uri, uri.Length() - (i + 1)); - - mQNames.Put(aResource, qname); - return NS_OK; -} - -nsresult -nsRDFXMLSerializer::GetQName(nsIRDFResource* aResource, nsCString& aQName) -{ - return mQNames.Get(aResource, &aQName) ? NS_OK : NS_ERROR_UNEXPECTED; -} - -bool -nsRDFXMLSerializer::IsContainerProperty(nsIRDFResource* aProperty) -{ - // Return `true' if the property is an internal property related - // to being a container. - if (aProperty == kRDF_instanceOf) - return true; - - if (aProperty == kRDF_nextVal) - return true; - - bool isOrdinal = false; - gRDFC->IsOrdinalProperty(aProperty, &isOrdinal); - if (isOrdinal) - return true; - - return false; -} - - -// convert '&', '<', and '>' into "&", "<", and ">", respectively. -static const char amp[] = "&"; -static const char lt[] = "<"; -static const char gt[] = ">"; -static const char quot[] = """; - -static void -rdf_EscapeAmpersandsAndAngleBrackets(nsCString& s) -{ - uint32_t newLength, origLength; - newLength = origLength = s.Length(); - - // Compute the length of the result string. - const char* start = s.BeginReading(); - const char* end = s.EndReading(); - const char* c = start; - while (c != end) { - switch (*c) { - case '&' : - newLength += sizeof(amp) - 2; - break; - case '<': - case '>': - newLength += sizeof(gt) - 2; - break; - default: - break; - } - ++c; - } - if (newLength == origLength) { - // nothing to escape - return; - } - - // escape the chars from the end back to the front. - s.SetLength(newLength); - - // Buffer might have changed, get the pointers again - start = s.BeginReading(); // begin of string - c = start + origLength - 1; // last char in original string - char* w = s.EndWriting() - 1; // last char in grown buffer - while (c >= start) { - switch (*c) { - case '&' : - w -= 4; - nsCharTraits::copy(w, amp, sizeof(amp) - 1); - break; - case '<': - w -= 3; - nsCharTraits::copy(w, lt, sizeof(lt) - 1); - break; - case '>': - w -= 3; - nsCharTraits::copy(w, gt, sizeof(gt) - 1); - break; - default: - *w = *c; - } - --w; - --c; - } -} - -// convert '"' to """ -static void -rdf_EscapeQuotes(nsCString& s) -{ - int32_t i = 0; - while ((i = s.FindChar('"', i)) != -1) { - s.Replace(i, 1, quot, sizeof(quot) - 1); - i += sizeof(quot) - 2; - } -} - -static void -rdf_EscapeAttributeValue(nsCString& s) -{ - rdf_EscapeAmpersandsAndAngleBrackets(s); - rdf_EscapeQuotes(s); -} - - -nsresult -nsRDFXMLSerializer::SerializeInlineAssertion(nsIOutputStream* aStream, - nsIRDFResource* aResource, - nsIRDFResource* aProperty, - nsIRDFLiteral* aValue) -{ - nsresult rv; - nsCString qname; - rv = GetQName(aProperty, qname); - NS_ENSURE_SUCCESS(rv, rv); - - rv = rdf_BlockingWrite(aStream, - NS_LITERAL_CSTRING("\n ")); - if (NS_FAILED(rv)) return rv; - - const char16_t* value; - aValue->GetValueConst(&value); - NS_ConvertUTF16toUTF8 s(value); - - rdf_EscapeAttributeValue(s); - - rv = rdf_BlockingWrite(aStream, qname); - if (NS_FAILED(rv)) return rv; - rv = rdf_BlockingWrite(aStream, "=\"", 2); - if (NS_FAILED(rv)) return rv; - s.Append('"'); - return rdf_BlockingWrite(aStream, s); -} - -nsresult -nsRDFXMLSerializer::SerializeChildAssertion(nsIOutputStream* aStream, - nsIRDFResource* aResource, - nsIRDFResource* aProperty, - nsIRDFNode* aValue) -{ - nsCString qname; - nsresult rv = GetQName(aProperty, qname); - NS_ENSURE_SUCCESS(rv, rv); - - rv = rdf_BlockingWrite(aStream, " <", 5); - if (NS_FAILED(rv)) return rv; - rv = rdf_BlockingWrite(aStream, qname); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr resource; - nsCOMPtr literal; - nsCOMPtr number; - nsCOMPtr date; - - if ((resource = do_QueryInterface(aValue)) != nullptr) { - nsAutoCString uri; - resource->GetValueUTF8(uri); - - rdf_MakeRelativeRef(mBaseURLSpec, uri); - rdf_EscapeAttributeValue(uri); - - rv = rdf_BlockingWrite(aStream, kRDFResource1, - sizeof(kRDFResource1) - 1); - if (NS_FAILED(rv)) return rv; - rv = rdf_BlockingWrite(aStream, uri); - if (NS_FAILED(rv)) return rv; - rv = rdf_BlockingWrite(aStream, kRDFResource2, - sizeof(kRDFResource2) - 1); - if (NS_FAILED(rv)) return rv; - - goto no_close_tag; - } - else if ((literal = do_QueryInterface(aValue)) != nullptr) { - const char16_t *value; - literal->GetValueConst(&value); - NS_ConvertUTF16toUTF8 s(value); - - rdf_EscapeAmpersandsAndAngleBrackets(s); - - rv = rdf_BlockingWrite(aStream, ">", 1); - if (NS_FAILED(rv)) return rv; - rv = rdf_BlockingWrite(aStream, s); - if (NS_FAILED(rv)) return rv; - } - else if ((number = do_QueryInterface(aValue)) != nullptr) { - int32_t value; - number->GetValue(&value); - - nsAutoCString n; - n.AppendInt(value); - - rv = rdf_BlockingWrite(aStream, kRDFParseTypeInteger, - sizeof(kRDFParseTypeInteger) - 1); - if (NS_FAILED(rv)) return rv; - rv = rdf_BlockingWrite(aStream, n); - if (NS_FAILED(rv)) return rv; - } - else if ((date = do_QueryInterface(aValue)) != nullptr) { - PRTime value; - date->GetValue(&value); - - nsAutoCString s; - rdf_FormatDate(value, s); - - rv = rdf_BlockingWrite(aStream, kRDFParseTypeDate, - sizeof(kRDFParseTypeDate) - 1); - if (NS_FAILED(rv)) return rv; - rv = rdf_BlockingWrite(aStream, s); - if (NS_FAILED(rv)) return rv; - } - else { - // XXX it doesn't support nsIRDFResource _or_ nsIRDFLiteral??? - // We should serialize nsIRDFInt, nsIRDFDate, etc... - NS_WARNING("unknown RDF node type"); - - rv = rdf_BlockingWrite(aStream, kRDFUnknown, sizeof(kRDFUnknown) - 1); - if (NS_FAILED(rv)) return rv; - } - - rv = rdf_BlockingWrite(aStream, "\n", 2); - - no_close_tag: - return NS_OK; -} - -nsresult -nsRDFXMLSerializer::SerializeProperty(nsIOutputStream* aStream, - nsIRDFResource* aResource, - nsIRDFResource* aProperty, - bool aInline, - int32_t* aSkipped) -{ - nsresult rv = NS_OK; - - int32_t skipped = 0; - - nsCOMPtr assertions; - mDataSource->GetTargets(aResource, aProperty, true, getter_AddRefs(assertions)); - if (! assertions) - return NS_ERROR_FAILURE; - - // Serializing the assertion inline is ok as long as the property has - // only one target value, and it is a literal that doesn't include line - // breaks. - bool needsChild = false; - - while (1) { - bool hasMore = false; - assertions->HasMoreElements(&hasMore); - if (! hasMore) - break; - - nsCOMPtr isupports; - assertions->GetNext(getter_AddRefs(isupports)); - nsCOMPtr literal = do_QueryInterface(isupports); - needsChild |= (!literal); - - if (!needsChild) { - assertions->HasMoreElements(&needsChild); - if (!needsChild) { - const char16_t* literalVal = nullptr; - literal->GetValueConst(&literalVal); - if (literalVal) { - for (; *literalVal; literalVal++) { - if (*literalVal == char16_t('\n') || - *literalVal == char16_t('\r')) { - needsChild = true; - break; - } - } - } - } - } - - if (aInline && !needsChild) { - rv = SerializeInlineAssertion(aStream, aResource, aProperty, literal); - } - else if (!aInline && needsChild) { - nsCOMPtr value = do_QueryInterface(isupports); - rv = SerializeChildAssertion(aStream, aResource, aProperty, value); - } - else { - ++skipped; - rv = NS_OK; - } - - if (NS_FAILED(rv)) - break; - } - - *aSkipped += skipped; - return rv; -} - - -nsresult -nsRDFXMLSerializer::SerializeDescription(nsIOutputStream* aStream, - nsIRDFResource* aResource) -{ - nsresult rv; - - bool isTypedNode = false; - nsCString typeQName; - - nsCOMPtr typeNode; - mDataSource->GetTarget(aResource, kRDF_type, true, getter_AddRefs(typeNode)); - if (typeNode) { - nsCOMPtr type = do_QueryInterface(typeNode, &rv); - if (type) { - // Try to get a namespace prefix. If none is available, - // just treat the description as if it weren't a typed node - // after all and emit rdf:type as a normal property. This - // seems preferable to using a bogus (invented) prefix. - isTypedNode = NS_SUCCEEDED(GetQName(type, typeQName)); - } - } - - nsAutoCString uri; - rv = aResource->GetValueUTF8(uri); - if (NS_FAILED(rv)) return rv; - - rdf_MakeRelativeRef(mBaseURLSpec, uri); - rdf_EscapeAttributeValue(uri); - - // Emit an open tag and the subject - if (isTypedNode) { - rv = rdf_BlockingWrite(aStream, NS_LITERAL_STRING(" <")); - if (NS_FAILED(rv)) return rv; - // Watch out for the default namespace! - rv = rdf_BlockingWrite(aStream, typeQName); - if (NS_FAILED(rv)) return rv; - } - else { - rv = rdf_BlockingWrite(aStream, kRDFDescriptionOpen, - sizeof(kRDFDescriptionOpen) - 1); - if (NS_FAILED(rv)) return rv; - } - if (uri[0] == char16_t('#')) { - uri.Cut(0, 1); - rv = rdf_BlockingWrite(aStream, kIDAttr, sizeof(kIDAttr) - 1); - } - else { - rv = rdf_BlockingWrite(aStream, kAboutAttr, sizeof(kAboutAttr) - 1); - } - if (NS_FAILED(rv)) return rv; - - uri.Append('"'); - rv = rdf_BlockingWrite(aStream, uri); - if (NS_FAILED(rv)) return rv; - - // Any value that's a literal we can write out as an inline - // attribute on the RDF:Description - AutoTArray visited; - int32_t skipped = 0; - - nsCOMPtr arcs; - mDataSource->ArcLabelsOut(aResource, getter_AddRefs(arcs)); - - if (arcs) { - // Don't re-serialize rdf:type later on - if (isTypedNode) - visited.AppendElement(kRDF_type); - - while (1) { - bool hasMore = false; - arcs->HasMoreElements(&hasMore); - if (! hasMore) - break; - - nsCOMPtr isupports; - arcs->GetNext(getter_AddRefs(isupports)); - - nsCOMPtr property = do_QueryInterface(isupports); - if (! property) - continue; - - // Ignore properties that pertain to containers; we may be - // called from SerializeContainer() if the container resource - // has been assigned non-container properties. - if (IsContainerProperty(property)) - continue; - - // Only serialize values for the property once. - if (visited.Contains(property.get())) - continue; - - visited.AppendElement(property.get()); - - SerializeProperty(aStream, aResource, property, true, &skipped); - } - } - - if (skipped) { - // Close the RDF:Description tag. - rv = rdf_BlockingWrite(aStream, NS_LITERAL_CSTRING(">\n")); - if (NS_FAILED(rv)) return rv; - - // Now write out resources (which might have their own - // substructure) as children. - mDataSource->ArcLabelsOut(aResource, getter_AddRefs(arcs)); - - if (arcs) { - // Forget that we've visited anything - visited.Clear(); - // ... except for rdf:type - if (isTypedNode) - visited.AppendElement(kRDF_type); - - while (1) { - bool hasMore = false; - arcs->HasMoreElements(&hasMore); - if (! hasMore) - break; - - nsCOMPtr isupports; - arcs->GetNext(getter_AddRefs(isupports)); - - nsCOMPtr property = do_QueryInterface(isupports); - if (! property) - continue; - - // Ignore properties that pertain to containers; we may be - // called from SerializeContainer() if the container - // resource has been assigned non-container properties. - if (IsContainerProperty(property)) - continue; - - // have we already seen this property? If so, don't write it - // out again; serialize property will write each instance. - if (visited.Contains(property.get())) - continue; - - visited.AppendElement(property.get()); - - SerializeProperty(aStream, aResource, property, false, &skipped); - } - } - - // Emit a proper close-tag. - if (isTypedNode) { - rv = rdf_BlockingWrite(aStream, NS_LITERAL_CSTRING(" \n", 2); - if (NS_FAILED(rv)) return rv; - } - else { - rv = rdf_BlockingWrite(aStream, kRDFDescriptionClose, - sizeof(kRDFDescriptionClose) - 1); - if (NS_FAILED(rv)) return rv; - } - } - else { - // If we saw _no_ child properties, then we can don't need a - // close-tag. - rv = rdf_BlockingWrite(aStream, NS_LITERAL_CSTRING(" />\n")); - if (NS_FAILED(rv)) return rv; - } - - return NS_OK; -} - -nsresult -nsRDFXMLSerializer::SerializeMember(nsIOutputStream* aStream, - nsIRDFResource* aContainer, - nsIRDFNode* aMember) -{ - // If it's a resource, then output a "" - // tag, because we'll be dumping the resource separately. (We - // iterate thru all the resources in the datasource, - // remember?) Otherwise, output the literal value. - - nsCOMPtr resource; - nsCOMPtr literal; - nsCOMPtr number; - nsCOMPtr date; - -static const char kRDFLIOpen[] = " GetValueUTF8(uri); - - rdf_MakeRelativeRef(mBaseURLSpec, uri); - rdf_EscapeAttributeValue(uri); - - rv = rdf_BlockingWrite(aStream, kRDFResource1, - sizeof(kRDFResource1) - 1); - if (NS_FAILED(rv)) return rv; - rv = rdf_BlockingWrite(aStream, uri); - if (NS_FAILED(rv)) return rv; - rv = rdf_BlockingWrite(aStream, kRDFResource2, - sizeof(kRDFResource2) - 1); - if (NS_FAILED(rv)) return rv; - - goto no_close_tag; - } - else if ((literal = do_QueryInterface(aMember)) != nullptr) { - const char16_t *value; - literal->GetValueConst(&value); -static const char kRDFLIOpenGT[] = ">"; - // close the 'GetValue(&value); - - nsAutoCString n; - n.AppendInt(value); - - rv = rdf_BlockingWrite(aStream, kRDFParseTypeInteger, - sizeof(kRDFParseTypeInteger) - 1); - if (NS_FAILED(rv)) return rv; - rv = rdf_BlockingWrite(aStream, n); - if (NS_FAILED(rv)) return rv; - } - else if ((date = do_QueryInterface(aMember)) != nullptr) { - PRTime value; - date->GetValue(&value); - - nsAutoCString s; - rdf_FormatDate(value, s); - - rv = rdf_BlockingWrite(aStream, kRDFParseTypeDate, - sizeof(kRDFParseTypeDate) - 1); - if (NS_FAILED(rv)) return rv; - rv = rdf_BlockingWrite(aStream, s); - if (NS_FAILED(rv)) return rv; - } - else { - // XXX it doesn't support nsIRDFResource _or_ nsIRDFLiteral??? - // We should serialize nsIRDFInt, nsIRDFDate, etc... - NS_WARNING("unknown RDF node type"); - - rv = rdf_BlockingWrite(aStream, kRDFUnknown, sizeof(kRDFUnknown) - 1); - if (NS_FAILED(rv)) return rv; - } - - { -static const char kRDFLIClose[] = "\n"; - rv = rdf_BlockingWrite(aStream, kRDFLIClose, sizeof(kRDFLIClose) - 1); - if (NS_FAILED(rv)) return rv; - } - - no_close_tag: - return NS_OK; -} - - -nsresult -nsRDFXMLSerializer::SerializeContainer(nsIOutputStream* aStream, - nsIRDFResource* aContainer) -{ - nsresult rv; - nsAutoCString tag; - - // Decide if it's a sequence, bag, or alternation, and print the - // appropriate tag-open sequence - - if (IsA(mDataSource, aContainer, kRDF_Bag)) { - tag.AssignLiteral("RDF:Bag"); - } - else if (IsA(mDataSource, aContainer, kRDF_Seq)) { - tag.AssignLiteral("RDF:Seq"); - } - else if (IsA(mDataSource, aContainer, kRDF_Alt)) { - tag.AssignLiteral("RDF:Alt"); - } - else { - NS_ASSERTION(false, "huh? this is _not_ a container."); - return NS_ERROR_UNEXPECTED; - } - - rv = rdf_BlockingWrite(aStream, " <", 3); - if (NS_FAILED(rv)) return rv; - rv = rdf_BlockingWrite(aStream, tag); - if (NS_FAILED(rv)) return rv; - - - // Unfortunately, we always need to print out the identity of the - // resource, even if was constructed "anonymously". We need to do - // this because we never really know who else might be referring - // to it... - - nsAutoCString uri; - if (NS_SUCCEEDED(aContainer->GetValueUTF8(uri))) { - rdf_MakeRelativeRef(mBaseURLSpec, uri); - - rdf_EscapeAttributeValue(uri); - - if (uri.First() == '#') { - // Okay, it's actually identified as an element in the - // current document, not trying to decorate some absolute - // URI. We can use the 'ID=' attribute... - - uri.Cut(0, 1); // chop the '#' - rv = rdf_BlockingWrite(aStream, kIDAttr, sizeof(kIDAttr) - 1); - if (NS_FAILED(rv)) return rv; - } - else { - // We need to cheat and spit out an illegal 'about=' on - // the sequence. - rv = rdf_BlockingWrite(aStream, kAboutAttr, - sizeof(kAboutAttr) - 1); - if (NS_FAILED(rv)) return rv; - } - - rv = rdf_BlockingWrite(aStream, uri); - if (NS_FAILED(rv)) return rv; - rv = rdf_BlockingWrite(aStream, "\"", 1); - if (NS_FAILED(rv)) return rv; - } - - rv = rdf_BlockingWrite(aStream, ">\n", 2); - if (NS_FAILED(rv)) return rv; - - // First iterate through each of the ordinal elements (the RDF/XML - // syntax doesn't allow us to place properties on RDF container - // elements). - nsCOMPtr elements; - rv = NS_NewContainerEnumerator(mDataSource, aContainer, getter_AddRefs(elements)); - - if (NS_SUCCEEDED(rv)) { - while (1) { - bool hasMore; - rv = elements->HasMoreElements(&hasMore); - if (NS_FAILED(rv)) break; - - if (! hasMore) - break; - - nsCOMPtr isupports; - elements->GetNext(getter_AddRefs(isupports)); - - nsCOMPtr element = do_QueryInterface(isupports); - NS_ASSERTION(element != nullptr, "not an nsIRDFNode"); - if (! element) - continue; - - SerializeMember(aStream, aContainer, element); - } - } - - // close the container tag - rv = rdf_BlockingWrite(aStream, " \n", 2); - rv = rdf_BlockingWrite(aStream, tag); - if (NS_FAILED(rv)) return rv; - - // Now, we iterate through _all_ of the arcs, in case someone has - // applied properties to the bag itself. These'll be placed in a - // separate RDF:Description element. - nsCOMPtr arcs; - mDataSource->ArcLabelsOut(aContainer, getter_AddRefs(arcs)); - - bool wroteDescription = false; - while (! wroteDescription) { - bool hasMore = false; - rv = arcs->HasMoreElements(&hasMore); - if (NS_FAILED(rv)) break; - - if (! hasMore) - break; - - nsIRDFResource* property; - rv = arcs->GetNext((nsISupports**) &property); - if (NS_FAILED(rv)) break; - - // If it's a membership property, then output a "LI" - // tag. Otherwise, output a property. - if (! IsContainerProperty(property)) { - rv = SerializeDescription(aStream, aContainer); - wroteDescription = true; - } - - NS_RELEASE(property); - if (NS_FAILED(rv)) - break; - } - - return NS_OK; -} - - -nsresult -nsRDFXMLSerializer::SerializePrologue(nsIOutputStream* aStream) -{ -static const char kXMLVersion[] = "\n"; - - nsresult rv; - rv = rdf_BlockingWrite(aStream, kXMLVersion, sizeof(kXMLVersion) - 1); - if (NS_FAILED(rv)) return rv; - - // global name space declarations - rv = rdf_BlockingWrite(aStream, NS_LITERAL_CSTRING("mPrefix) { - rv = rdf_BlockingWrite(aStream, NS_LITERAL_CSTRING(":")); - if (NS_FAILED(rv)) return rv; - nsAutoCString prefix; - entry->mPrefix->ToUTF8String(prefix); - rv = rdf_BlockingWrite(aStream, prefix); - if (NS_FAILED(rv)) return rv; - } - - rv = rdf_BlockingWrite(aStream, NS_LITERAL_CSTRING("=\"")); - if (NS_FAILED(rv)) return rv; - nsAutoCString uri(entry->mURI); - rdf_EscapeAttributeValue(uri); - rv = rdf_BlockingWrite(aStream, uri); - if (NS_FAILED(rv)) return rv; - rv = rdf_BlockingWrite(aStream, NS_LITERAL_CSTRING("\"")); - if (NS_FAILED(rv)) return rv; - } - - return rdf_BlockingWrite(aStream, NS_LITERAL_CSTRING(">\n")); -} - - -nsresult -nsRDFXMLSerializer::SerializeEpilogue(nsIOutputStream* aStream) -{ - return rdf_BlockingWrite(aStream, NS_LITERAL_CSTRING("\n")); -} - -class QNameCollector final : public rdfITripleVisitor { -public: - NS_DECL_ISUPPORTS - NS_DECL_RDFITRIPLEVISITOR - explicit QNameCollector(nsRDFXMLSerializer* aParent) - : mParent(aParent){} -private: - ~QNameCollector() {} - nsRDFXMLSerializer* mParent; -}; - -NS_IMPL_ISUPPORTS(QNameCollector, rdfITripleVisitor) -nsresult -QNameCollector::Visit(nsIRDFNode* aSubject, nsIRDFResource* aPredicate, - nsIRDFNode* aObject, bool aTruthValue) -{ - if (aPredicate == nsRDFXMLSerializer::kRDF_type) { - // try to get a type QName for aObject, should be a resource - nsCOMPtr resType = do_QueryInterface(aObject); - if (!resType) { - // ignore error - return NS_OK; - } - if (mParent->mQNames.Get(resType, nullptr)) { - return NS_OK; - } - mParent->RegisterQName(resType); - return NS_OK; - } - - if (mParent->mQNames.Get(aPredicate, nullptr)) { - return NS_OK; - } - if (aPredicate == nsRDFXMLSerializer::kRDF_instanceOf || - aPredicate == nsRDFXMLSerializer::kRDF_nextVal) - return NS_OK; - bool isOrdinal = false; - nsRDFXMLSerializer::gRDFC->IsOrdinalProperty(aPredicate, &isOrdinal); - if (isOrdinal) - return NS_OK; - - mParent->RegisterQName(aPredicate); - - return NS_OK; -} - -nsresult -nsRDFXMLSerializer::CollectNamespaces() -{ - // Iterate over all Triples to get namespaces for subject resource types - // and Predicates and cache all the QNames we want to use. - nsCOMPtr collector = - new QNameCollector(this); - nsCOMPtr ds = do_QueryInterface(mDataSource); // XXX API - NS_ENSURE_TRUE(collector && ds, NS_ERROR_FAILURE); - return ds->VisitAllTriples(collector); -} - -//---------------------------------------------------------------------- - -NS_IMETHODIMP -nsRDFXMLSerializer::Serialize(nsIOutputStream* aStream) -{ - nsresult rv; - - rv = CollectNamespaces(); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr resources; - rv = mDataSource->GetAllResources(getter_AddRefs(resources)); - if (NS_FAILED(rv)) return rv; - - rv = SerializePrologue(aStream); - if (NS_FAILED(rv)) - return rv; - - while (1) { - bool hasMore = false; - resources->HasMoreElements(&hasMore); - if (! hasMore) - break; - - nsCOMPtr isupports; - resources->GetNext(getter_AddRefs(isupports)); - - nsCOMPtr resource = do_QueryInterface(isupports); - if (! resource) - continue; - - if (IsA(mDataSource, resource, kRDF_Bag) || - IsA(mDataSource, resource, kRDF_Seq) || - IsA(mDataSource, resource, kRDF_Alt)) { - rv = SerializeContainer(aStream, resource); - } - else { - rv = SerializeDescription(aStream, resource); - } - - if (NS_FAILED(rv)) - break; - } - - rv = SerializeEpilogue(aStream); - - return rv; -} - - -bool -nsRDFXMLSerializer::IsA(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource, nsIRDFResource* aType) -{ - nsresult rv; - - bool result; - rv = aDataSource->HasAssertion(aResource, kRDF_instanceOf, aType, true, &result); - if (NS_FAILED(rv)) return false; - - return result; -} diff --git a/rdf/base/nsRDFXMLSerializer.h b/rdf/base/nsRDFXMLSerializer.h deleted file mode 100644 index 235753eb24d6..000000000000 --- a/rdf/base/nsRDFXMLSerializer.h +++ /dev/null @@ -1,117 +0,0 @@ -/* -*- 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/. */ - -#ifndef nsRDFXMLSerializer_h__ -#define nsRDFXMLSerializer_h__ - -#include "nsIRDFLiteral.h" -#include "nsIRDFXMLSerializer.h" -#include "nsIRDFXMLSource.h" -#include "nsNameSpaceMap.h" -#include "nsString.h" - -#include "nsDataHashtable.h" -#include "rdfITripleVisitor.h" - -class nsIOutputStream; -class nsIRDFContainerUtils; - -/** - * A helper class that can serialize RDF/XML from a - * datasource. Implements both nsIRDFXMLSerializer and - * nsIRDFXMLSource. - */ -class nsRDFXMLSerializer : public nsIRDFXMLSerializer, - public nsIRDFXMLSource -{ -public: - static nsresult - Create(nsISupports* aOuter, REFNSIID aIID, void** aResult); - - NS_DECL_ISUPPORTS - NS_DECL_NSIRDFXMLSERIALIZER - NS_DECL_NSIRDFXMLSOURCE - -protected: - nsRDFXMLSerializer(); - virtual ~nsRDFXMLSerializer(); - - // Implementation methods - nsresult - RegisterQName(nsIRDFResource* aResource); - nsresult - GetQName(nsIRDFResource* aResource, nsCString& aQName); - already_AddRefed - EnsureNewPrefix(); - - nsresult - SerializeInlineAssertion(nsIOutputStream* aStream, - nsIRDFResource* aResource, - nsIRDFResource* aProperty, - nsIRDFLiteral* aValue); - - nsresult - SerializeChildAssertion(nsIOutputStream* aStream, - nsIRDFResource* aResource, - nsIRDFResource* aProperty, - nsIRDFNode* aValue); - - nsresult - SerializeProperty(nsIOutputStream* aStream, - nsIRDFResource* aResource, - nsIRDFResource* aProperty, - bool aInline, - int32_t* aSkipped); - - bool - IsContainerProperty(nsIRDFResource* aProperty); - - nsresult - SerializeDescription(nsIOutputStream* aStream, - nsIRDFResource* aResource); - - nsresult - SerializeMember(nsIOutputStream* aStream, - nsIRDFResource* aContainer, - nsIRDFNode* aMember); - - nsresult - SerializeContainer(nsIOutputStream* aStream, - nsIRDFResource* aContainer); - - nsresult - SerializePrologue(nsIOutputStream* aStream); - - nsresult - SerializeEpilogue(nsIOutputStream* aStream); - - nsresult - CollectNamespaces(); - - bool - IsA(nsIRDFDataSource* aDataSource, nsIRDFResource* aResource, nsIRDFResource* aType); - - nsCOMPtr mDataSource; - nsNameSpaceMap mNameSpaces; - nsCString mBaseURLSpec; - - // hash mapping resources to utf8-encoded QNames - nsDataHashtable mQNames; - friend class QNameCollector; - - uint32_t mPrefixID; - - static int32_t gRefCnt; - static nsIRDFResource* kRDF_instanceOf; - static nsIRDFResource* kRDF_type; - static nsIRDFResource* kRDF_nextVal; - static nsIRDFResource* kRDF_Bag; - static nsIRDFResource* kRDF_Seq; - static nsIRDFResource* kRDF_Alt; - static nsIRDFContainerUtils* gRDFC; -}; - -#endif // nsRDFXMLSerializer_h__ diff --git a/rdf/base/rdf.h b/rdf/base/rdf.h deleted file mode 100644 index 65087cee5174..000000000000 --- a/rdf/base/rdf.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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/. */ - -/* - - A catch-all header file for miscellaneous RDF stuff. Currently - contains error codes and vocabulary macros. - - */ - -#ifndef rdf_h___ -#define rdf_h___ - -#include "nsError.h" - -/** - * The following macros are to aid in vocabulary definition. They - * creates const char*'s for "kURI[prefix]_[name]", appropriate - * complete namespace qualification on the URI, e.g., - * - * #define RDF_NAMESPACE_URI "http://www.w3.org/TR/WD-rdf-syntax#" - * DEFINE_RDF_ELEMENT(RDF_NAMESPACE_URI, RDF, ID); - * - * will define: - * - * kURIRDF_ID to be "http://www.w3.org/TR/WD-rdf-syntax#ID" - */ - -#define DEFINE_RDF_VOCAB(ns, prefix, name) \ -static const char kURI##prefix##_##name[] = ns #name - -/** - * Core RDF vocabularies that we use to define semantics - */ - -#define RDF_NAMESPACE_URI "http://www.w3.org/1999/02/22-rdf-syntax-ns#" -#define WEB_NAMESPACE_URI "http://home.netscape.com/WEB-rdf#" -#define NC_NAMESPACE_URI "http://home.netscape.com/NC-rdf#" - -/* ContractID prefixes for RDF DLL registration. */ -#define NS_RDF_CONTRACTID "@mozilla.org/rdf" -#define NS_RDF_DATASOURCE_CONTRACTID NS_RDF_CONTRACTID "/datasource;1" -#define NS_RDF_DATASOURCE_CONTRACTID_PREFIX NS_RDF_DATASOURCE_CONTRACTID "?name=" -#define NS_RDF_RESOURCE_FACTORY_CONTRACTID "@mozilla.org/rdf/resource-factory;1" -#define NS_RDF_RESOURCE_FACTORY_CONTRACTID_PREFIX NS_RDF_RESOURCE_FACTORY_CONTRACTID "?name=" -#define NS_RDF_INFER_DATASOURCE_CONTRACTID_PREFIX NS_RDF_CONTRACTID "/infer-datasource;1?engine=" - -// contract ID is in the form -// @mozilla.org/rdf/delegate-factory;1?key=&scheme= -#define NS_RDF_DELEGATEFACTORY_CONTRACTID "@mozilla.org/rdf/delegate-factory;1" -#define NS_RDF_DELEGATEFACTORY_CONTRACTID_PREFIX NS_RDF_DELEGATEFACTORY_CONTRACTID "?key=" - -/*@}*/ - -#endif /* rdf_h___ */ diff --git a/rdf/base/rdfIDataSource.idl b/rdf/base/rdfIDataSource.idl deleted file mode 100644 index 848cbca117d7..000000000000 --- a/rdf/base/rdfIDataSource.idl +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- Mode: IDL; 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/. */ - -#include "nsISupports.idl" - -interface rdfITripleVisitor; - -/** - * Interface used in RDF to describe data sources. - * - * @status PLASMA - */ - -[scriptable, uuid(ebce86bd-1568-4a34-a808-9ccf9cde8087)] -interface rdfIDataSource : nsISupports -{ - /** - * Visit all the subject resources in the datasource. The order is - * intederminate and may change from one invocation to the next. - * The subjects will be in the aSubject argument in calls into - * aVisitor, aPredicate and aObject will be null. - * @note Implementations may throw NS_ERROR_NOT_IMPLEMENTED for - * this method, but in this case RDF serializations of this - * datasource will not be possible. - */ - void visitAllSubjects(in rdfITripleVisitor aVisitor); - - /** - * Visit all the triples in the datasource. The order is - * intederminate and may change from one invocation to the next. - * @note Implementations may throw NS_ERROR_NOT_IMPLEMENTED for - * this method, but in this case RDF serializations of this - * datasource will not be possible. - */ - void visitAllTriples(in rdfITripleVisitor aVisitor); -}; diff --git a/rdf/base/rdfITripleVisitor.idl b/rdf/base/rdfITripleVisitor.idl deleted file mode 100644 index ecac14871567..000000000000 --- a/rdf/base/rdfITripleVisitor.idl +++ /dev/null @@ -1,31 +0,0 @@ -/* -*- Mode: IDL; 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/. */ - -#include "nsISupports.idl" - -interface nsIRDFResource; -interface nsIRDFNode; - -/** - * Interface used in RDF to enumerate triples. - * Also used by rdfIDataSource::getAllSubjects, then aPredicate, - * aObject and aTruthValue are ignored. - * - * @status PLASMA - */ - -[scriptable, function, uuid(aafea151-c271-4505-9978-a100d292800c)] -interface rdfITripleVisitor : nsISupports -{ - /** - * Callback function for returning query results. - * - * @param aSubject, aPredicate, aObject describe the (sub-)arc - * @returnCode NS_RDF_STOP_VISIT to stop iterating over the query result. - * Any error code will stop the iteration as well. - */ - void visit(in nsIRDFNode aSubject, in nsIRDFResource aPredicate, - in nsIRDFNode aObject, in boolean aTruthValue); -}; diff --git a/rdf/base/rdfutil.cpp b/rdf/base/rdfutil.cpp deleted file mode 100644 index 191ee68d1a26..000000000000 --- a/rdf/base/rdfutil.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* -*- 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/. */ - -/* - - Implementations for a bunch of useful RDF utility routines. Many of - these will eventually be exported outside of RDF.DLL via the - nsIRDFService interface. - - TO DO - - 1) Make this so that it doesn't permanently leak the RDF service - object. - - 2) Make container functions thread-safe. They currently don't ensure - that the RDF:nextVal property is maintained safely. - - */ - -#include "nsCOMPtr.h" -#include "nsIRDFDataSource.h" -#include "nsIRDFNode.h" -#include "nsIRDFService.h" -#include "nsIServiceManager.h" -#include "nsIURL.h" -#include "nsIIOService.h" -#include "nsIURL.h" -#include "nsRDFCID.h" -#include "nsString.h" -#include "nsUnicharUtils.h" -#include "rdfutil.h" -#include "prtime.h" - -//////////////////////////////////////////////////////////////////////// - -nsresult -rdf_MakeRelativeRef(const nsACString& aBaseURI, nsCString& aURI) -{ - // This implementation is extremely simple: e.g., it can't compute - // relative paths, or anything fancy like that. If the context URI - // is not a prefix of the URI in question, we'll just bail. - uint32_t prefixLen = aBaseURI.Length(); - if (prefixLen != 0 && StringBeginsWith(aURI, aBaseURI)) { - if (prefixLen < aURI.Length() && aURI.CharAt(prefixLen) == '/') - ++prefixLen; // chop the leading slash so it's not `absolute' - - aURI.Cut(0, prefixLen); - } - - return NS_OK; -} - -void -rdf_FormatDate(PRTime aTime, nsACString &aResult) -{ - // Outputs Unixish date in GMT plus usecs; e.g., - // Wed Jan 9 19:15:13 2002 +002441 - // - PRExplodedTime t; - PR_ExplodeTime(aTime, PR_GMTParameters, &t); - - char buf[256]; - PR_FormatTimeUSEnglish(buf, sizeof buf, "%a %b %d %H:%M:%S %Y", &t); - aResult.Append(buf); - - // usecs - aResult.AppendLiteral(" +"); - int32_t usec = t.tm_usec; - for (int32_t digit = 100000; digit > 1; digit /= 10) { - aResult.Append(char('0' + (usec / digit))); - usec %= digit; - } - aResult.Append(char('0' + usec)); -} - -PRTime -rdf_ParseDate(const nsACString &aTime) -{ - PRTime t; - PR_ParseTimeString(PromiseFlatCString(aTime).get(), true, &t); - - int32_t usec = 0; - - nsACString::const_iterator begin, digit, end; - aTime.BeginReading(begin); - aTime.EndReading(end); - - // Walk backwards until we find a `+', run out of string, or a - // non-numeric character. - digit = end; - while (--digit != begin && *digit != '+') { - if (*digit < '0' || *digit > '9') - break; - } - - if (digit != begin && *digit == '+') { - // There's a usec field specified (or, at least, something - // that looks close enough. Parse it, and add it to the time. - while (++digit != end) { - usec *= 10; - usec += *digit - '0'; - } - - t += usec; - } - - return t; -} diff --git a/rdf/base/rdfutil.h b/rdf/base/rdfutil.h deleted file mode 100644 index 70f9b656437f..000000000000 --- a/rdf/base/rdfutil.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- 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/. */ - - -/* - - A bunch of useful RDF utility routines. Many of these will - eventually be exported outside of RDF.DLL via the nsIRDFService - interface. - - TO DO - - 1) Move the anonymous resource stuff to nsIRDFService? - - 2) All that's left is rdf_PossiblyMakeRelative() and - -Absolute(). Maybe those go on nsIRDFService, too. - - */ - -#ifndef rdfutil_h__ -#define rdfutil_h__ - -#include "nsStringFwd.h" - -nsresult -rdf_MakeRelativeRef(const nsACString& aBaseURI, nsCString& aURI); - -void -rdf_FormatDate(PRTime aTime, nsACString &aResult); - -PRTime -rdf_ParseDate(const nsACString &aTime); - -#endif // rdfutil_h__ - - diff --git a/rdf/build/moz.build b/rdf/build/moz.build deleted file mode 100644 index d7be68954dcd..000000000000 --- a/rdf/build/moz.build +++ /dev/null @@ -1,20 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -EXPORTS += [ - 'nsRDFCID.h', -] - -SOURCES += [ - 'nsRDFModule.cpp', -] - -FINAL_LIBRARY = 'xul' - -LOCAL_INCLUDES += [ - '/rdf/base', - '/rdf/datasource', -] diff --git a/rdf/build/nsRDFCID.h b/rdf/build/nsRDFCID.h deleted file mode 100644 index 18d47aed5211..000000000000 --- a/rdf/build/nsRDFCID.h +++ /dev/null @@ -1,76 +0,0 @@ -/* -*- 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/. */ - -/* - - XPCOM Class IDs for RDF objects that can be constructed via the RDF - factory. - - */ - -#ifndef nsRDFCID_h__ -#define nsRDFCID_h__ - -// {0F78DA56-8321-11d2-8EAC-00805F29F370} -#define NS_RDFDEFAULTRESOURCE_CID \ -{ 0xf78da56, 0x8321, 0x11d2, { 0x8e, 0xac, 0x0, 0x80, 0x5f, 0x29, 0xf3, 0x70 } } - -// {BFD05264-834C-11d2-8EAC-00805F29F370} -#define NS_RDFSERVICE_CID \ -{ 0xbfd05264, 0x834c, 0x11d2, { 0x8e, 0xac, 0x0, 0x80, 0x5f, 0x29, 0xf3, 0x70 } } - -// {BFD0526D-834C-11d2-8EAC-00805F29F370} -#define NS_RDFINMEMORYDATASOURCE_CID \ -{ 0xbfd0526d, 0x834c, 0x11d2, { 0x8e, 0xac, 0x0, 0x80, 0x5f, 0x29, 0xf3, 0x70 } } - -// {E638D760-8687-11d2-B530-000000000001} -#define NS_RDFFILESYSTEMDATASOURCE_CID \ -{ 0xe638d760, 0x8687, 0x11d2, { 0xb5, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x01 } } - -// {6bd1d807-1c67-11d3-9820-ed1b357eb3c4} -#define NS_RDFSEARCHDATASOURCE_CID \ -{ 0x6bd1d807, 0x1c67, 0x11d3, { 0x98, 0x20, 0xed, 0x1b, 0x35, 0x7e, 0xb3, 0xc4 } } - -// {E638D760-8687-11d2-B530-000000000002} -#define NS_RDFFINDDATASOURCE_CID \ -{ 0xe638d760, 0x8687, 0x11d2, { 0xb5, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x02 } } - -// {E638D761-8687-11d2-B530-000000000000} -#define NS_RDFCOMPOSITEDATASOURCE_CID \ -{ 0xe638d761, 0x8687, 0x11d2, { 0xb5, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } } - -// {7BAF62E0-8E61-11d2-8EB1-00805F29F370} -#define NS_RDFXMLDATASOURCE_CID \ -{ 0x7baf62e0, 0x8e61, 0x11d2, { 0x8e, 0xb1, 0x0, 0x80, 0x5f, 0x29, 0xf3, 0x70 } } - -// {0958B101-9ADA-11d2-8EBC-00805F29F370} -#define NS_RDFCONTENTSINK_CID \ -{ 0x958b101, 0x9ada, 0x11d2, { 0x8e, 0xbc, 0x0, 0x80, 0x5f, 0x29, 0xf3, 0x70 } } - -// {1EAAFD60-D596-11d2-80BE-006097B76B8E} -#define NS_RDFHISTORYDATASOURCE_CID \ -{ 0x1eaafd60, 0xd596, 0x11d2, { 0x80, 0xbe, 0x0, 0x60, 0x97, 0xb7, 0x6b, 0x8e } } - -// {D4214E92-FB94-11d2-BDD8-00104BDE6048} -#define NS_RDFCONTAINERUTILS_CID \ -{ 0xd4214e92, 0xfb94, 0x11d2, { 0xbd, 0xd8, 0x0, 0x10, 0x4b, 0xde, 0x60, 0x48 } } - -// {D4214E93-FB94-11d2-BDD8-00104BDE6048} -#define NS_RDFCONTAINER_CID \ -{ 0xd4214e93, 0xfb94, 0x11d2, { 0xbd, 0xd8, 0x0, 0x10, 0x4b, 0xde, 0x60, 0x48 } } - -// {0032d852-1dd2-11b2-95f7-e0a1910ed2da} -#define NS_RDFXMLSERIALIZER_CID \ -{ 0x0032d852, 0x1dd2, 0x11b2, { 0x95, 0xf7, 0xe0, 0xa1, 0x91, 0x0e, 0xd2, 0xda } } - -// {a4048e94-1dd1-11b2-a676-8a06c086cc7d} -#define NS_RDFXMLPARSER_CID \ -{ 0xa4048e94, 0x1dd1, 0x11b2, { 0xa6, 0x76, 0x8a, 0x06, 0xc0, 0x86, 0xcc, 0x7d } } - -// {0a5cd734-eb65-4d14-88a0-9f0bb2aba206} -#define NS_RDFNTRIPLES_SERIALIZER_CID \ -{ 0x0a5cd734, 0xeb65, 0x4d14, { 0x88, 0xa0, 0x9f, 0x0b, 0xb2, 0xab, 0xa2, 0x06 } } - -#endif // nsRDFCID_h__ diff --git a/rdf/build/nsRDFModule.cpp b/rdf/build/nsRDFModule.cpp deleted file mode 100644 index 3828fdd50bc7..000000000000 --- a/rdf/build/nsRDFModule.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* -*- 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/. */ -#include "nsCOMPtr.h" -#include "mozilla/ModuleUtils.h" - -#include "nsIFactory.h" -#include "nsRDFService.h" -#include "nsIRDFContainer.h" -#include "nsIRDFContainerUtils.h" -#include "nsIRDFCompositeDataSource.h" -#include "nsIRDFContentSink.h" -#include "nsISupports.h" -#include "nsRDFBaseDataSources.h" -#include "nsRDFBuiltInDataSources.h" -#include "nsRDFCID.h" -#include "nsIComponentManager.h" -#include "rdf.h" -#include "nsIServiceManager.h" -#include "nsILocalStore.h" -#include "nsRDFXMLParser.h" -#include "nsRDFXMLSerializer.h" - -//---------------------------------------------------------------------- - -// Functions used to create new instances of a given object by the -// generic factory. - -#define MAKE_CTOR(_func,_new,_ifname) \ -static nsresult \ -CreateNew##_func(nsISupports* aOuter, REFNSIID aIID, void **aResult) \ -{ \ - if (!aResult) { \ - return NS_ERROR_INVALID_POINTER; \ - } \ - if (aOuter) { \ - *aResult = nullptr; \ - return NS_ERROR_NO_AGGREGATION; \ - } \ - nsI##_ifname* inst; \ - nsresult rv = NS_New##_new(&inst); \ - if (NS_FAILED(rv)) { \ - *aResult = nullptr; \ - return rv; \ - } \ - rv = inst->QueryInterface(aIID, aResult); \ - if (NS_FAILED(rv)) { \ - *aResult = nullptr; \ - } \ - NS_RELEASE(inst); /* get rid of extra refcnt */ \ - return rv; \ -} - -extern nsresult -NS_NewDefaultResource(nsIRDFResource** aResult); - -MAKE_CTOR(RDFXMLDataSource,RDFXMLDataSource,RDFDataSource) -MAKE_CTOR(RDFCompositeDataSource,RDFCompositeDataSource,RDFCompositeDataSource) -MAKE_CTOR(RDFContainer,RDFContainer,RDFContainer) - -MAKE_CTOR(RDFContainerUtils,RDFContainerUtils,RDFContainerUtils) - -MAKE_CTOR(RDFContentSink,RDFContentSink,RDFContentSink) -MAKE_CTOR(RDFDefaultResource,DefaultResource,RDFResource) - -NS_DEFINE_NAMED_CID(NS_RDFCOMPOSITEDATASOURCE_CID); -NS_DEFINE_NAMED_CID(NS_RDFINMEMORYDATASOURCE_CID); -NS_DEFINE_NAMED_CID(NS_RDFXMLDATASOURCE_CID); -NS_DEFINE_NAMED_CID(NS_RDFDEFAULTRESOURCE_CID); -NS_DEFINE_NAMED_CID(NS_RDFCONTENTSINK_CID); -NS_DEFINE_NAMED_CID(NS_RDFCONTAINER_CID); -NS_DEFINE_NAMED_CID(NS_RDFCONTAINERUTILS_CID); -NS_DEFINE_NAMED_CID(NS_RDFSERVICE_CID); -NS_DEFINE_NAMED_CID(NS_RDFXMLPARSER_CID); -NS_DEFINE_NAMED_CID(NS_RDFXMLSERIALIZER_CID); -NS_DEFINE_NAMED_CID(NS_LOCALSTORE_CID); - - -static const mozilla::Module::CIDEntry kRDFCIDs[] = { - { &kNS_RDFCOMPOSITEDATASOURCE_CID, false, nullptr, CreateNewRDFCompositeDataSource }, - { &kNS_RDFINMEMORYDATASOURCE_CID, false, nullptr, NS_NewRDFInMemoryDataSource }, - { &kNS_RDFXMLDATASOURCE_CID, false, nullptr, CreateNewRDFXMLDataSource }, - { &kNS_RDFDEFAULTRESOURCE_CID, false, nullptr, CreateNewRDFDefaultResource }, - { &kNS_RDFCONTENTSINK_CID, false, nullptr, CreateNewRDFContentSink }, - { &kNS_RDFCONTAINER_CID, false, nullptr, CreateNewRDFContainer }, - { &kNS_RDFCONTAINERUTILS_CID, false, nullptr, CreateNewRDFContainerUtils }, - { &kNS_RDFSERVICE_CID, false, nullptr, RDFServiceImpl::CreateSingleton }, - { &kNS_RDFXMLPARSER_CID, false, nullptr, nsRDFXMLParser::Create }, - { &kNS_RDFXMLSERIALIZER_CID, false, nullptr, nsRDFXMLSerializer::Create }, - { &kNS_LOCALSTORE_CID, false, nullptr, NS_NewLocalStore }, - { nullptr } -}; - -static const mozilla::Module::ContractIDEntry kRDFContracts[] = { - { NS_RDF_DATASOURCE_CONTRACTID_PREFIX "composite-datasource", &kNS_RDFCOMPOSITEDATASOURCE_CID }, - { NS_RDF_DATASOURCE_CONTRACTID_PREFIX "in-memory-datasource", &kNS_RDFINMEMORYDATASOURCE_CID }, - { NS_RDF_DATASOURCE_CONTRACTID_PREFIX "xml-datasource", &kNS_RDFXMLDATASOURCE_CID }, - { NS_RDF_RESOURCE_FACTORY_CONTRACTID, &kNS_RDFDEFAULTRESOURCE_CID }, - { NS_RDF_CONTRACTID "/content-sink;1", &kNS_RDFCONTENTSINK_CID }, - { NS_RDF_CONTRACTID "/container;1", &kNS_RDFCONTAINER_CID }, - { NS_RDF_CONTRACTID "/container-utils;1", &kNS_RDFCONTAINERUTILS_CID }, - { NS_RDF_CONTRACTID "/rdf-service;1", &kNS_RDFSERVICE_CID }, - { NS_RDF_CONTRACTID "/xml-parser;1", &kNS_RDFXMLPARSER_CID }, - { NS_RDF_CONTRACTID "/xml-serializer;1", &kNS_RDFXMLSERIALIZER_CID }, - { NS_LOCALSTORE_CONTRACTID, &kNS_LOCALSTORE_CID }, - { nullptr } -}; - -static const mozilla::Module kRDFModule = { - mozilla::Module::kVersion, - kRDFCIDs, - kRDFContracts, - nullptr, - nullptr, - nullptr, - nullptr -}; - -NSMODULE_DEFN(nsRDFModule) = &kRDFModule; diff --git a/rdf/datasource/moz.build b/rdf/datasource/moz.build deleted file mode 100644 index 8267d67e2289..000000000000 --- a/rdf/datasource/moz.build +++ /dev/null @@ -1,21 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -EXPORTS += [ - 'nsILocalStore.h', -] - -UNIFIED_SOURCES += [ - 'nsLocalStore.cpp', -] - -FINAL_LIBRARY = 'xul' - -# "This is a dependency on rdfutil.h: it'll go away once that becomes -# a first-class XPCOM interface." -LOCAL_INCLUDES += [ - '/rdf/base', -] diff --git a/rdf/datasource/nsILocalStore.h b/rdf/datasource/nsILocalStore.h deleted file mode 100644 index b4122659376c..000000000000 --- a/rdf/datasource/nsILocalStore.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -*- 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/. */ - -#ifndef nsILocalStore_h__ -#define nsILocalStore_h__ - -#include "rdf.h" -#include "nsISupports.h" - -// {DF71C6F1-EC53-11d2-BDCA-000064657374} -#define NS_ILOCALSTORE_IID \ -{ 0xdf71c6f1, 0xec53, 0x11d2, { 0xbd, 0xca, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } } - -// {DF71C6F0-EC53-11d2-BDCA-000064657374} -#define NS_LOCALSTORE_CID \ -{ 0xdf71c6f0, 0xec53, 0x11d2, { 0xbd, 0xca, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } } - -#define NS_LOCALSTORE_CONTRACTID NS_RDF_DATASOURCE_CONTRACTID_PREFIX "local-store" - -class nsILocalStore : public nsISupports -{ -public: - NS_DECLARE_STATIC_IID_ACCESSOR(NS_ILOCALSTORE_IID) -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsILocalStore, NS_ILOCALSTORE_IID) - -extern nsresult -NS_NewLocalStore(nsISupports* aOuter, REFNSIID aIID, void** aResult); - - -#endif // nsILocalStore_h__ diff --git a/rdf/datasource/nsIRDFFTP.h b/rdf/datasource/nsIRDFFTP.h deleted file mode 100644 index 8965b4a3825a..000000000000 --- a/rdf/datasource/nsIRDFFTP.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -*- 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/. */ - -#ifndef nsIRDFFTP_h__ -#define nsIRDFFTP_h__ - -#include "nscore.h" -#include "nsISupports.h" -#include "nsIRDFNode.h" - - - -#define NS_IRDFFTPDATAOURCE_IID \ -{ 0x1222e6f0, 0xa5e3, 0x11d2, { 0x8b, 0x7c, 0x00, 0x80, 0x5f, 0x8a, 0x7d, 0xb7 } } - -class nsIRDFFTPDataSource : public nsIRDFDataSource -{ -public: -}; - - -#define NS_IRDFFTPDATASOURCECALLBACK_IID \ -{ 0x204a1a00, 0xa5e4, 0x11d2, { 0x8b, 0x7c, 0x00, 0x80, 0x5f, 0x8a, 0x7d, 0xb8 } } - -class nsIRDFFTPDataSourceCallback : public nsIStreamListener -{ -public: -}; - - -#endif // nsIRDFFTP_h__ diff --git a/rdf/datasource/nsLocalStore.cpp b/rdf/datasource/nsLocalStore.cpp deleted file mode 100644 index 25ad3e0ccee0..000000000000 --- a/rdf/datasource/nsLocalStore.cpp +++ /dev/null @@ -1,474 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim: set cindent tabstop=4 expandtab shiftwidth=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/. */ - -/* - - Implementation for the local store - - */ - -#include "nsNetUtil.h" -#include "nsIFile.h" -#include "nsIURI.h" -#include "nsIIOService.h" -#include "nsIOutputStream.h" -#include "nsIComponentManager.h" -#include "nsILocalStore.h" -#include "nsIRDFDataSource.h" -#include "nsIRDFRemoteDataSource.h" -#include "nsIRDFService.h" -#include "nsIServiceManager.h" -#include "nsRDFCID.h" -#include "nsString.h" -#include "plstr.h" -#include "rdf.h" -#include "nsCOMPtr.h" -#include "nsWeakPtr.h" -#include "nsAppDirectoryServiceDefs.h" -#include "nsIObserver.h" -#include "nsIObserverService.h" -#include "nsWeakReference.h" -#include "nsCRTGlue.h" -#include "nsCRT.h" -#include "nsEnumeratorUtils.h" -#include "nsCycleCollectionParticipant.h" - -//////////////////////////////////////////////////////////////////////// - -class LocalStoreImpl : public nsILocalStore, - public nsIRDFDataSource, - public nsIRDFRemoteDataSource, - public nsIObserver, - public nsSupportsWeakReference -{ -protected: - nsCOMPtr mInner; - - LocalStoreImpl(); - virtual ~LocalStoreImpl(); - nsresult Init(); - nsresult CreateLocalStore(nsIFile* aFile); - nsresult LoadData(); - - friend nsresult - NS_NewLocalStore(nsISupports* aOuter, REFNSIID aIID, void** aResult); - - nsCOMPtr mRDFService; - -public: - // nsISupports interface - NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(LocalStoreImpl, nsILocalStore) - - // nsILocalStore interface - - // nsIRDFDataSource interface. Most of these are just delegated to - // the inner, in-memory datasource. - NS_IMETHOD GetURI(nsACString& aURI) override; - - NS_IMETHOD GetSource(nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue, - nsIRDFResource** aSource) override { - return mInner->GetSource(aProperty, aTarget, aTruthValue, aSource); - } - - NS_IMETHOD GetSources(nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue, - nsISimpleEnumerator** aSources) override { - return mInner->GetSources(aProperty, aTarget, aTruthValue, aSources); - } - - NS_IMETHOD GetTarget(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - bool aTruthValue, - nsIRDFNode** aTarget) override { - return mInner->GetTarget(aSource, aProperty, aTruthValue, aTarget); - } - - NS_IMETHOD GetTargets(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - bool aTruthValue, - nsISimpleEnumerator** aTargets) override { - return mInner->GetTargets(aSource, aProperty, aTruthValue, aTargets); - } - - NS_IMETHOD Assert(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue) override { - return mInner->Assert(aSource, aProperty, aTarget, aTruthValue); - } - - NS_IMETHOD Unassert(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget) override { - return mInner->Unassert(aSource, aProperty, aTarget); - } - - NS_IMETHOD Change(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aOldTarget, - nsIRDFNode* aNewTarget) override { - return mInner->Change(aSource, aProperty, aOldTarget, aNewTarget); - } - - NS_IMETHOD Move(nsIRDFResource* aOldSource, - nsIRDFResource* aNewSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget) override { - return mInner->Move(aOldSource, aNewSource, aProperty, aTarget); - } - - NS_IMETHOD HasAssertion(nsIRDFResource* aSource, - nsIRDFResource* aProperty, - nsIRDFNode* aTarget, - bool aTruthValue, - bool* hasAssertion) override { - return mInner->HasAssertion(aSource, aProperty, aTarget, aTruthValue, hasAssertion); - } - - NS_IMETHOD AddObserver(nsIRDFObserver* aObserver) override { - return NS_ERROR_NOT_IMPLEMENTED; - } - - NS_IMETHOD RemoveObserver(nsIRDFObserver* aObserver) override { - return NS_ERROR_NOT_IMPLEMENTED; - } - - NS_IMETHOD HasArcIn(nsIRDFNode *aNode, nsIRDFResource *aArc, bool *_retval) override { - return mInner->HasArcIn(aNode, aArc, _retval); - } - - NS_IMETHOD HasArcOut(nsIRDFResource *aSource, nsIRDFResource *aArc, bool *_retval) override { - return mInner->HasArcOut(aSource, aArc, _retval); - } - - NS_IMETHOD ArcLabelsIn(nsIRDFNode* aNode, - nsISimpleEnumerator** aLabels) override { - return mInner->ArcLabelsIn(aNode, aLabels); - } - - NS_IMETHOD ArcLabelsOut(nsIRDFResource* aSource, - nsISimpleEnumerator** aLabels) override { - return mInner->ArcLabelsOut(aSource, aLabels); - } - - NS_IMETHOD GetAllResources(nsISimpleEnumerator** aResult) override { - return mInner->GetAllResources(aResult); - } - - NS_IMETHOD GetAllCmds(nsIRDFResource* aSource, - nsISimpleEnumerator/**/** aCommands) override; - - NS_IMETHOD IsCommandEnabled(nsISupports* aSources, - nsIRDFResource* aCommand, - nsISupports* aArguments, - bool* aResult) override; - - NS_IMETHOD DoCommand(nsISupports* aSources, - nsIRDFResource* aCommand, - nsISupports* aArguments) override; - - NS_IMETHOD BeginUpdateBatch() override { - return mInner->BeginUpdateBatch(); - } - - NS_IMETHOD EndUpdateBatch() override { - return mInner->EndUpdateBatch(); - } - - NS_IMETHOD GetLoaded(bool* _result) override; - NS_IMETHOD Init(const char *uri) override; - NS_IMETHOD Flush() override; - NS_IMETHOD FlushTo(const char *aURI) override; - NS_IMETHOD Refresh(bool sync) override; - - // nsIObserver - NS_DECL_NSIOBSERVER -}; - -//////////////////////////////////////////////////////////////////////// - - -LocalStoreImpl::LocalStoreImpl(void) -{ -} - -LocalStoreImpl::~LocalStoreImpl(void) -{ - if (mRDFService) - mRDFService->UnregisterDataSource(this); -} - - -nsresult -NS_NewLocalStore(nsISupports* aOuter, REFNSIID aIID, void** aResult) -{ - NS_PRECONDITION(aOuter == nullptr, "no aggregation"); - if (aOuter) - return NS_ERROR_NO_AGGREGATION; - - NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) - return NS_ERROR_NULL_POINTER; - - LocalStoreImpl* impl = new LocalStoreImpl(); - if (! impl) - return NS_ERROR_OUT_OF_MEMORY; - - NS_ADDREF(impl); - - nsresult rv; - rv = impl->Init(); - if (NS_SUCCEEDED(rv)) { - // Set up the result pointer - rv = impl->QueryInterface(aIID, aResult); - } - - NS_RELEASE(impl); - return rv; -} - -NS_IMPL_CYCLE_COLLECTION(LocalStoreImpl, mInner) -NS_IMPL_CYCLE_COLLECTING_ADDREF(LocalStoreImpl) -NS_IMPL_CYCLE_COLLECTING_RELEASE(LocalStoreImpl) - -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(LocalStoreImpl) - NS_INTERFACE_MAP_ENTRY(nsILocalStore) - NS_INTERFACE_MAP_ENTRY(nsIRDFDataSource) - NS_INTERFACE_MAP_ENTRY(nsIRDFRemoteDataSource) - NS_INTERFACE_MAP_ENTRY(nsIObserver) - NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsILocalStore) -NS_INTERFACE_MAP_END - -// nsILocalStore interface - -// nsIRDFDataSource interface - -NS_IMETHODIMP -LocalStoreImpl::GetLoaded(bool* _result) -{ - nsCOMPtr remote = do_QueryInterface(mInner); - NS_ASSERTION(remote != nullptr, "not an nsIRDFRemoteDataSource"); - if (! remote) - return NS_ERROR_UNEXPECTED; - - return remote->GetLoaded(_result); -} - - -NS_IMETHODIMP -LocalStoreImpl::Init(const char *uri) -{ - return(NS_OK); -} - -NS_IMETHODIMP -LocalStoreImpl::Flush() -{ - nsCOMPtr remote = do_QueryInterface(mInner); - // FIXME Bug 340242: Temporarily make this a warning rather than an - // assertion until we sort out the ordering of how we write - // everything to the localstore, flush it, and disconnect it when - // we're getting profile-change notifications. - NS_WARNING_ASSERTION(remote != nullptr, "not an nsIRDFRemoteDataSource"); - if (! remote) - return NS_ERROR_UNEXPECTED; - - return remote->Flush(); -} - -NS_IMETHODIMP -LocalStoreImpl::FlushTo(const char *aURI) -{ - // Do not ever implement this (security) - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -LocalStoreImpl::Refresh(bool sync) -{ - nsCOMPtr remote = do_QueryInterface(mInner); - NS_ASSERTION(remote != nullptr, "not an nsIRDFRemoteDataSource"); - if (! remote) - return NS_ERROR_UNEXPECTED; - - return remote->Refresh(sync); -} - -nsresult -LocalStoreImpl::Init() -{ - nsresult rv; - - rv = LoadData(); - if (NS_FAILED(rv)) return rv; - - // register this as a named data source with the RDF service - mRDFService = do_GetService(NS_RDF_CONTRACTID "/rdf-service;1", &rv); - if (NS_FAILED(rv)) return rv; - - mRDFService->RegisterDataSource(this, false); - - // Register as an observer of profile changes - nsCOMPtr obs = - do_GetService("@mozilla.org/observer-service;1"); - - if (obs) { - obs->AddObserver(this, "profile-before-change", true); - obs->AddObserver(this, "profile-do-change", true); - } - - return NS_OK; -} - -nsresult -LocalStoreImpl::CreateLocalStore(nsIFile* aFile) -{ - nsresult rv; - - rv = aFile->Create(nsIFile::NORMAL_FILE_TYPE, 0666); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr outStream; - rv = NS_NewLocalFileOutputStream(getter_AddRefs(outStream), aFile); - if (NS_FAILED(rv)) return rv; - - const char defaultRDF[] = - "\n" \ - "\n" \ - " \n" \ - "\n"; - - uint32_t count; - rv = outStream->Write(defaultRDF, sizeof(defaultRDF)-1, &count); - if (NS_FAILED(rv)) return rv; - - if (count != sizeof(defaultRDF)-1) - return NS_ERROR_UNEXPECTED; - - // Okay, now see if the file exists _for real_. If it's still - // not there, it could be that the profile service gave us - // back a read-only directory. Whatever. - bool fileExistsFlag = false; - aFile->Exists(&fileExistsFlag); - if (!fileExistsFlag) - return NS_ERROR_UNEXPECTED; - - return NS_OK; -} - -nsresult -LocalStoreImpl::LoadData() -{ - nsresult rv; - - // Look for localstore.rdf in the current profile - // directory. Bomb if we can't find it. - - nsCOMPtr aFile; - rv = NS_GetSpecialDirectory(NS_APP_LOCALSTORE_50_FILE, getter_AddRefs(aFile)); - if (NS_FAILED(rv)) return rv; - - bool fileExistsFlag = false; - (void)aFile->Exists(&fileExistsFlag); - if (!fileExistsFlag) { - // if file doesn't exist, create it - rv = CreateLocalStore(aFile); - if (NS_FAILED(rv)) return rv; - } - - mInner = do_CreateInstance(NS_RDF_DATASOURCE_CONTRACTID_PREFIX "xml-datasource", &rv); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr remote = do_QueryInterface(mInner, &rv); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr aURI; - rv = NS_NewFileURI(getter_AddRefs(aURI), aFile); - if (NS_FAILED(rv)) return rv; - - nsAutoCString spec; - rv = aURI->GetSpec(spec); - if (NS_FAILED(rv)) return rv; - - rv = remote->Init(spec.get()); - if (NS_FAILED(rv)) return rv; - - // Read the datasource synchronously. - rv = remote->Refresh(true); - - if (NS_FAILED(rv)) { - // Load failed, delete and recreate a fresh localstore - aFile->Remove(true); - rv = CreateLocalStore(aFile); - if (NS_FAILED(rv)) return rv; - - rv = remote->Refresh(true); - } - - return rv; -} - - -NS_IMETHODIMP -LocalStoreImpl::GetURI(nsACString& aURI) -{ - aURI.AssignLiteral("rdf:local-store"); - return NS_OK; -} - - -NS_IMETHODIMP -LocalStoreImpl::GetAllCmds(nsIRDFResource* aSource, - nsISimpleEnumerator/**/** aCommands) -{ - return(NS_NewEmptyEnumerator(aCommands)); -} - -NS_IMETHODIMP -LocalStoreImpl::IsCommandEnabled(nsISupports* aSources, - nsIRDFResource* aCommand, - nsISupports* aArguments, - bool* aResult) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -LocalStoreImpl::DoCommand(nsISupports* aSources, - nsIRDFResource* aCommand, - nsISupports* aArguments) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -LocalStoreImpl::Observe(nsISupports *aSubject, const char *aTopic, const char16_t *someData) -{ - nsresult rv = NS_OK; - - if (!nsCRT::strcmp(aTopic, "profile-before-change")) { - // Write out the old datasource's contents. - if (mInner) { - nsCOMPtr remote = do_QueryInterface(mInner); - if (remote) - remote->Flush(); - } - - // Create an in-memory datasource for use while we're - // profile-less. - mInner = do_CreateInstance(NS_RDF_DATASOURCE_CONTRACTID_PREFIX "in-memory-datasource"); - } - else if (!nsCRT::strcmp(aTopic, "profile-do-change")) { - rv = LoadData(); - } - return rv; -} diff --git a/rdf/datasource/nsRDFBuiltInDataSources.h b/rdf/datasource/nsRDFBuiltInDataSources.h deleted file mode 100644 index 297fe71640dd..000000000000 --- a/rdf/datasource/nsRDFBuiltInDataSources.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -*- 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 header file just contains prototypes for the factory methods - for "builtin" data sources that are included in rdf.dll. - - Each of these data sources is exposed to the external world via its - CID in ../include/nsRDFCID.h. - - */ - -#ifndef nsBuiltinDataSources_h__ -#define nsBuiltinDataSources_h__ - -#include "nsError.h" - -class nsIRDFDataSource; - -// in nsFileSystemDataSource.cpp -nsresult NS_NewRDFFileSystemDataSource(nsIRDFDataSource** result); - -#endif // nsBuiltinDataSources_h__ - diff --git a/rdf/moz.build b/rdf/moz.build deleted file mode 100644 index 6f678fed085b..000000000000 --- a/rdf/moz.build +++ /dev/null @@ -1,12 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -with Files('**'): - BUG_COMPONENT = ('Core', 'RDF') - -DIRS += ['base', 'datasource', 'build'] -TEST_DIRS += ['tests'] - diff --git a/rdf/tests/moz.build b/rdf/tests/moz.build deleted file mode 100644 index d8fb7519d5da..000000000000 --- a/rdf/tests/moz.build +++ /dev/null @@ -1,7 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -XPCSHELL_TESTS_MANIFESTS += ['unit/xpcshell.ini'] diff --git a/rdf/tests/unit/sample.rdf b/rdf/tests/unit/sample.rdf deleted file mode 100755 index 42de8cd08b9f..000000000000 --- a/rdf/tests/unit/sample.rdf +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - diff --git a/rdf/tests/unit/test_rdfredirect.js b/rdf/tests/unit/test_rdfredirect.js deleted file mode 100644 index f3c076ba7a61..000000000000 --- a/rdf/tests/unit/test_rdfredirect.js +++ /dev/null @@ -1,92 +0,0 @@ -ChromeUtils.import("resource://testing-common/httpd.js"); - -function getRDFService() -{ - return Cc["@mozilla.org/rdf/rdf-service;1"]. - getService(Ci.nsIRDFService); -} - -var server1, server2; - -function run_test() -{ - var samplefile = do_get_file('sample.rdf'); - - server1 = new HttpServer(); - server1.registerPathHandler("/sample-xs.rdf", xsRedirect); - server1.registerPathHandler("/sample-local.rdf", localRedirect); - server1.registerFile('/sample.rdf', samplefile); - server1.start(4444); - - server2 = new HttpServer(); - server2.registerFile('/sample.rdf', samplefile); - server2.start(4445); - - do_test_pending(); - - new rdfLoadObserver('http://localhost:4444/sample.rdf', true); - new rdfLoadObserver('http://localhost:4445/sample.rdf', true); - new rdfLoadObserver('http://localhost:4444/sample-xs.rdf', false); - new rdfLoadObserver('http://localhost:4444/sample-local.rdf', true); -} - -var gPending = 0; - -function rdfLoadObserver(uri, shouldPass) -{ - this.shouldPass = shouldPass; - this.uri = uri; - - ++gPending; - - var rdfService = getRDFService(); - this.ds = rdfService.GetDataSource(uri). - QueryInterface(Ci.nsIRDFXMLSink); - this.ds.addXMLSinkObserver(this); -} - -rdfLoadObserver.prototype = -{ - onBeginLoad : function() { }, - onInterrupt : function() { }, - onResume : function() { }, - onEndLoad : function() { - print("Testing results of loading " + this.uri); - - var rdfs = getRDFService(); - var res = rdfs.GetResource("urn:mozilla:sample-data"); - var arc = rdfs.GetResource("http://purl.org/dc/elements/1.1/title"); - var answer = this.ds.GetTarget(res, arc, true); - if (answer !== null) { - Assert.ok(this.shouldPass); - Assert.ok(answer instanceof Ci.nsIRDFLiteral); - Assert.equal(answer.Value, "Sample"); - } - else { - Assert.ok(!this.shouldPass); - } - - gPending -= 1; - - this.ds.removeXMLSinkObserver(this); - - if (gPending == 0) { - do_test_pending(); - server1.stop(do_test_finished); - server2.stop(do_test_finished); - } - }, - onError : function() { } -} - -function xsRedirect(metadata, response) -{ - response.setStatusLine(metadata.httpVersion, 301, "Moved Permanently"); - response.setHeader("Location", "http://localhost:4445/sample.rdf", false); -} - -function localRedirect(metadata, response) -{ - response.setStatusLine(metadata.httpVersion, 301, "Moved Permanently"); - response.setHeader("Location", "http://localhost:4444/sample.rdf", false); -} diff --git a/rdf/tests/unit/xpcshell.ini b/rdf/tests/unit/xpcshell.ini deleted file mode 100644 index 4cea6cc1421e..000000000000 --- a/rdf/tests/unit/xpcshell.ini +++ /dev/null @@ -1,5 +0,0 @@ -[DEFAULT] -head = -support-files = sample.rdf - -[test_rdfredirect.js] diff --git a/toolkit/components/build/nsToolkitCompsModule.cpp b/toolkit/components/build/nsToolkitCompsModule.cpp index ed0bc38b663e..6d6fad377756 100644 --- a/toolkit/components/build/nsToolkitCompsModule.cpp +++ b/toolkit/components/build/nsToolkitCompsModule.cpp @@ -20,7 +20,6 @@ #include "nsAlertsService.h" #include "DownloadPlatform.h" -#include "rdf.h" #include "nsTypeAheadFind.h" diff --git a/toolkit/toolkit.mozbuild b/toolkit/toolkit.mozbuild index 4e033764a578..1ec2f8c1451d 100644 --- a/toolkit/toolkit.mozbuild +++ b/toolkit/toolkit.mozbuild @@ -88,10 +88,6 @@ DIRS += [ '/extensions/permissions', ] -DIRS += [ - '/rdf', -] - if CONFIG['MOZ_WEBRTC'] and CONFIG['COMPILE_ENVIRONMENT']: DIRS += [ '/media/webrtc', From 5b65a3ab01d4f56dd41b3fa2b320d83a4bbcc747 Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Tue, 8 May 2018 15:52:53 +0200 Subject: [PATCH 34/34] Bug 1374745 - nsScriptSecurityManager should not use a string bundle before profile selection, r=ckerschb --- caps/nsScriptSecurityManager.cpp | 141 +++++++++++++++++++++++-------- 1 file changed, 106 insertions(+), 35 deletions(-) diff --git a/caps/nsScriptSecurityManager.cpp b/caps/nsScriptSecurityManager.cpp index 32b885f07a32..1171e1827bfa 100644 --- a/caps/nsScriptSecurityManager.cpp +++ b/caps/nsScriptSecurityManager.cpp @@ -77,10 +77,76 @@ using namespace mozilla; using namespace mozilla::dom; nsIIOService *nsScriptSecurityManager::sIOService = nullptr; -nsIStringBundle *nsScriptSecurityManager::sStrBundle = nullptr; JSContext *nsScriptSecurityManager::sContext = nullptr; bool nsScriptSecurityManager::sStrictFileOriginPolicy = true; +namespace { + +class BundleHelper +{ +public: + NS_INLINE_DECL_REFCOUNTING(BundleHelper) + + static nsIStringBundle* + GetOrCreate() + { + MOZ_ASSERT(!sShutdown); + + // Already shutting down. Nothing should require the use of the string + // bundle when shutting down. + if (sShutdown) { + return nullptr; + } + + if (!sSelf) { + sSelf = new BundleHelper(); + } + + return sSelf->GetOrCreateInternal(); + } + + static void + Shutdown() + { + sSelf = nullptr; + sShutdown = true; + } + +private: + ~BundleHelper() = default; + + nsIStringBundle* + GetOrCreateInternal() + { + if (!mBundle) { + nsCOMPtr bundleService = + mozilla::services::GetStringBundleService(); + if (NS_WARN_IF(!bundleService)) { + return nullptr; + } + + nsresult rv = + bundleService->CreateBundle("chrome://global/locale/security/caps.properties", + getter_AddRefs(mBundle)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return nullptr; + } + } + + return mBundle; + } + + nsCOMPtr mBundle; + + static StaticRefPtr sSelf; + static bool sShutdown; +}; + +StaticRefPtr BundleHelper::sSelf; +bool BundleHelper::sShutdown = false; + +} // anonymous + /////////////////////////// // Convenience Functions // /////////////////////////// @@ -981,20 +1047,22 @@ nsScriptSecurityManager::CheckLoadURIFlags(nsIURI *aSourceURI, &hasSubsumersFlag); NS_ENSURE_SUCCESS(rv, rv); if (!hasFlags && !hasSubsumersFlag) { - nsAutoString message; - NS_ConvertASCIItoUTF16 ucsTargetScheme(targetScheme); - const char16_t* formatStrings[] = { ucsTargetScheme.get() }; - rv = sStrBundle-> - FormatStringFromName("ProtocolFlagError", - formatStrings, - ArrayLength(formatStrings), - message); - if (NS_SUCCEEDED(rv)) { - nsCOMPtr console( - do_GetService("@mozilla.org/consoleservice;1")); - NS_ENSURE_TRUE(console, NS_ERROR_FAILURE); + nsCOMPtr bundle = BundleHelper::GetOrCreate(); + if (bundle) { + nsAutoString message; + NS_ConvertASCIItoUTF16 ucsTargetScheme(targetScheme); + const char16_t* formatStrings[] = { ucsTargetScheme.get() }; + rv = bundle->FormatStringFromName("ProtocolFlagError", + formatStrings, + ArrayLength(formatStrings), + message); + if (NS_SUCCEEDED(rv)) { + nsCOMPtr console( + do_GetService("@mozilla.org/consoleservice;1")); + NS_ENSURE_TRUE(console, NS_ERROR_FAILURE); - console->LogStringMessage(message.get()); + console->LogStringMessage(message.get()); + } } } @@ -1018,15 +1086,20 @@ nsScriptSecurityManager::ReportError(JSContext* cx, const char* aMessageTag, rv = aTarget->GetAsciiSpec(targetSpec); NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr bundle = BundleHelper::GetOrCreate(); + if (NS_WARN_IF(!bundle)) { + return NS_OK; + } + // Localize the error message nsAutoString message; NS_ConvertASCIItoUTF16 ucsSourceSpec(sourceSpec); NS_ConvertASCIItoUTF16 ucsTargetSpec(targetSpec); const char16_t *formatStrings[] = { ucsSourceSpec.get(), ucsTargetSpec.get() }; - rv = sStrBundle->FormatStringFromName(aMessageTag, - formatStrings, - ArrayLength(formatStrings), - message); + rv = bundle->FormatStringFromName(aMessageTag, + formatStrings, + ArrayLength(formatStrings), + message); NS_ENSURE_SUCCESS(rv, rv); // If a JS context was passed in, set a JS exception. @@ -1237,22 +1310,28 @@ nsScriptSecurityManager::CanCreateWrapper(JSContext *cx, if (classInfoNameUTF8.IsEmpty()) { classInfoNameUTF8.AssignLiteral("UnnamedClass"); } + + nsCOMPtr bundle = BundleHelper::GetOrCreate(); + if (NS_WARN_IF(!bundle)) { + return NS_OK; + } + NS_ConvertUTF8toUTF16 classInfoUTF16(classInfoNameUTF8); nsresult rv; nsAutoString errorMsg; if (originUTF16.IsEmpty()) { const char16_t* formatStrings[] = { classInfoUTF16.get() }; - rv = sStrBundle->FormatStringFromName("CreateWrapperDenied", - formatStrings, - 1, - errorMsg); + rv = bundle->FormatStringFromName("CreateWrapperDenied", + formatStrings, + 1, + errorMsg); } else { const char16_t* formatStrings[] = { classInfoUTF16.get(), originUTF16.get() }; - rv = sStrBundle->FormatStringFromName("CreateWrapperDeniedForOrigin", - formatStrings, - 2, - errorMsg); + rv = bundle->FormatStringFromName("CreateWrapperDeniedForOrigin", + formatStrings, + 2, + errorMsg); } NS_ENSURE_SUCCESS(rv, rv); @@ -1336,14 +1415,6 @@ nsresult nsScriptSecurityManager::Init() InitPrefs(); - nsCOMPtr bundleService = - mozilla::services::GetStringBundleService(); - if (!bundleService) - return NS_ERROR_FAILURE; - - rv = bundleService->CreateBundle("chrome://global/locale/security/caps.properties", &sStrBundle); - NS_ENSURE_SUCCESS(rv, rv); - // Create our system principal singleton RefPtr system = SystemPrincipal::Create(); @@ -1392,7 +1463,7 @@ nsScriptSecurityManager::Shutdown() } NS_IF_RELEASE(sIOService); - NS_IF_RELEASE(sStrBundle); + BundleHelper::Shutdown(); } nsScriptSecurityManager *