Hi All,

The following is a C++ non-member function I call from a method of a
C++ XPCOM component. I call it from Python using pyxpcom. The method
simply adds some nodes to a DOM document. I was doing this all in
Python (I have Moz embedded in my Python app) but I wrote this to get
some speedup.

Unfortunately, Moz has been hanging up intermitently. Switching back
to the pure Python implementation has solved the problem.

I'm wondering if I'm messing up reference counts - e.g. not using the
nsCOMPtr correctly?? Is my use of nsAutoString correct??

I've snipped out some of the calls to the Python/C api as they
probably don't mean much to this crowd.

Please note the nodes are always added correctly - it's just that
Mozilla then hangs at some point in the future.

I'd be very grateful if anyone could see if there are any mistakes in
this.

Thanks very much.

Tom.

---------------------
nsIDOMNode*  _AppendPythonNode(nsIDOMElement* domNode,
                               PyObject* pyNode,
                               PyObject* pyNodeType)
{
  nsCOMPtr<nsIDOMDocument> doc;
  domNode->GetOwnerDocument(getter_AddRefs(doc));

  if ([SNIP: should we add an element or a text-node?]) {
    nsAutoString nodeName = nsAutoString([SNIP: get the node name
                                          from python]);
  
    nsCOMPtr<nsIDOMElement> newElement;
    if ([SNIP: Is there a namespace?]) {
      nsAutoString nodeNamespace = [SNIP: the namespace];
      doc->CreateElementNS(nodeNamespace, nodeName,
                           getter_AddRefs(newElement));
    } else {
      doc->CreateElement(nodeName, getter_AddRefs(newElement));
    }
  
    nsCOMPtr<nsIDOMNode> node = newElement;
    nsCOMPtr<nsIDOMNode> dummy;
    nsresult res = domNode->AppendChild(node, getter_AddRefs(dummy));

    PyObject* attrs = [SNIP: Get the attributes (as a python dict)]
    PyObject *key, *value;
    int pos = 0;
    // This just iterates through the attribute name and values
    while (PyDict_Next(attrs, &pos, &key, &value)) {
      PyObject* keystr = PyObject_Unicode(key);
      PyObject* valstr = PyObject_Unicode(value);

      newElement->SetAttribute(
              nsAutoString(PyUnicode_AS_UNICODE(keystr)),
              nsAutoString(PyUnicode_AS_UNICODE(valstr)));

      Py_DECREF(keystr);
      Py_DECREF(valstr);
    }
  
    // recurse to add child nodes
    PyObject* childNodes = [SNIP: get a list of child nodes]
    int childCount = [SNIP: and get its size]
    for(int i = 0; i < childCount; i++) {
      _AppendPythonNode(newElement, PyList_GET_ITEM(childNodes, i),
                        pyNodeType);
    }
    Py_DECREF(childNodes);

    return node;

  } else {
    nsCOMPtr<nsIDOMText> textNode;
    doc->CreateTextNode(
            nsAutoString([SNIP: pyNode as unicode string]),
            getter_AddRefs(textNode));

    nsCOMPtr<nsIDOMNode> node = textNode;
    nsCOMPtr<nsIDOMNode> dummy;
    nsresult res = domNode->AppendChild(node, getter_AddRefs(dummy));
    
    return node;
  }
}
_______________________________________________
Mozilla-xpcom mailing list
[EMAIL PROTECTED]
http://mail.mozilla.org/listinfo/mozilla-xpcom

Reply via email to