Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members  

SerialTree-libxml.cpp

00001 //  SerialTree-libxml - GNOME libxml support for SerialTree
00002 //  Copyright (C) 2000 rusty@sgi.com
00003 //
00004 //  This program is free software; you can redistribute it and/or
00005 //  modify it under the terms of the GNU General Public License
00006 //  as published by the Free Software Foundation; either version 2
00007 //  of the License, or (at your option) any later version.
00008 //
00009 //  This program is distributed in the hope that it will be useful,
00010 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 //  GNU General Public License for more details.
00013 //
00014 //  You should have received a copy of the GNU General Public License
00015 //  along with this program; if not, write to the Free Software
00016 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00017 
00018 #include <fun/SerialTree.h>
00019 
00020 //  This should only be built if HAVE_LIBXML is defined!
00021 #ifdef HAVE_LIBXML
00022 
00023 #include <fun/XMLUtil.h>  //  this will go away
00024 #include <iostream>
00025 #include <gnome-xml/tree.h>
00026 #include <gnome-xml/parser.h>
00027 
00028 namespace fun {
00029 
00030 //  copied from XMLUtil.c++, which will go away
00031 static ostream &
00032 operator<<(ostream &os, xmlElementType t)
00033 {
00034     switch(t)
00035     {
00036         case XML_ELEMENT_NODE:       os << "ELEMENT";       break;
00037         case XML_ATTRIBUTE_NODE:     os << "ATTRIBUTE";     break;
00038         case XML_TEXT_NODE:          os << "TEXT";          break;
00039         case XML_CDATA_SECTION_NODE: os << "CDATA_SECTION"; break;
00040         case XML_ENTITY_REF_NODE:    os << "ENTITY_REF";    break;
00041         case XML_ENTITY_NODE:        os << "ENTITY";        break;
00042         case XML_PI_NODE:            os << "PI";            break;
00043         case XML_COMMENT_NODE:       os << "COMMENT";       break;
00044         case XML_DOCUMENT_NODE:      os << "DOCUMENT";      break;
00045         case XML_DOCUMENT_TYPE_NODE: os << "DOCUMENT_TYPE"; break;
00046         case XML_DOCUMENT_FRAG_NODE: os << "DOCUMENT_FRAG"; break;
00047         case XML_NOTATION_NODE:      os << "NOTATION";      break;
00048         default:                     os << "(wha??)";
00049     }
00050     return os;
00051 }
00052 
00053 static QString
00054 getSerializableClass(xmlNode *np)
00055 {
00056     return XMLUtil::getTextAttr(np, "class");
00057 }
00058 
00059 static void
00060 setSerializableClass(xmlNode *np, const QString &cls)
00061 {
00062     XMLUtil::addTextAttr(np, "class", cls);
00063 }
00064 
00065 SerialTree *
00066 SerialTree::loadFromXMLFile(const QString &filename)
00067 {
00068     xmlDoc *xdoc = xmlParseFile(filename);
00069     if(xdoc == NULL) return NULL;
00070 //XMLUtil::dumpDoc(xdoc);
00071 
00072     SerialTree *root = NULL;
00073     Child *cp = NULL;
00074     xmlNode *lastcmnt = NULL;
00075     for(xmlNode *xnp = xdoc->root; (xnp != NULL) && root == NULL; xnp = xnp->next)
00076     {
00077 //cout << "xnp->type == " << xnp->type << endl;
00078         switch(xnp->type)
00079         {
00080             case XML_COMMENT_NODE:
00081                 break;
00082             case XML_ELEMENT_NODE:
00083 //cout << "found root..." << endl;
00084                 root = new SerialTree;
00085                 cp = new Child((const char *)(xnp->name));
00086                 childFromXMLNode(*cp, xnp);
00087                 root->children.append(cp);
00088 //cout << "  cp->tval->getSerializableClass() == " << cp->tval->getSerializableClass() << endl;
00089                 if(cp->tval) cp->tval->setSerializableClass(::getSerializableClass(xnp));
00090 //cout << "  root class is " << root->getSerializableClass() << endl;
00091                 break;
00092             default:
00093                 NOT_DONE("parseXML() doesn't handle node type " << xnp->type);
00094         }
00095     }
00096     return root;
00097 }
00098 
00099 bool
00100 SerialTree::saveToXMLFile(const QString &filename, int mode)
00101 {
00102     xmlDoc *doc = XMLUtil::newDocument();
00103 NOT_DONE("saveToXMLFile() doesn't handle parent node right");
00104 //  //  Actually, we'd better have only one child.
00105 //  xmlNode *np = XMLUtil::addChild((xmlNode *)doc, XML_ELEMENT_NODE, "rustyIsABozo");
00106     toXMLNode((xmlNode *)doc);
00107 
00108 //XMLUtil::dumpDoc(doc);
00109 
00110     XMLUtil::saveFile(doc, filename);
00111 
00112     XMLUtil::deleteDocument(doc);
00113 NOT_DONE("saveToXMLFile() does no error checking");
00114     return true;
00115 }
00116 
00117 void
00118 SerialTree::toXMLNode(void *xmlnode) const
00119 {
00120     xmlNode *np = (xmlNode *)xmlnode;
00121     if(!getSerializableClass().isNull()) ::setSerializableClass(np, getSerializableClass());
00122     for(QPtrListIterator<Child> it(children); it.current(); ++it)
00123     {
00124         xmlNode *cnp = XMLUtil::addChild(np, XML_ELEMENT_NODE, it.current()->key);
00125         if(it.current()->sval)
00126         {
00127             XMLUtil::addChild(cnp, XML_TEXT_NODE, *(it.current()->sval));
00128         }
00129         else if(it.current()->tval)
00130         {
00131             it.current()->tval->toXMLNode(cnp);
00132         }
00133         else
00134         {
00135             NOT_DONE("toXMLNode() doesn't handle stubby children");
00136         }
00137     }
00138 }
00139 
00140 void
00141 SerialTree::childFromXMLNode(Child &child, void *xmlnode)
00142 {
00143     xmlNode *xnp = (xmlNode *)xmlnode;
00144     if(xnp->type != XML_ELEMENT_NODE)
00145     {
00146         NOT_DONE("brain damage in childFromXMLNode");
00147         return;
00148     }
00149 //  QString name = (const char *)(xnp->name);
00150 //  QString tc = "";
00151     QString valbuf;
00152     QString lastcmnt;
00153     Child *newkid = NULL;
00154 //  NOT_DONE("not getting TreeableClass from node");
00155 
00156     //  Run through and concatenate all TEXT elements into a buffer.  If
00157     //  this has any ELEMENT children, though, toss the buffer and treat
00158     //  this as a non-leaf node, as SerialTree nodes can have either a
00159     //  value or children, not both.
00160     for(xmlNode *xcp = xnp->childs; xcp; xcp = xcp->next)
00161     {
00162 //cout << "xcp->type == " << xcp->type << endl;
00163         switch(xcp->type)
00164         {
00165             case XML_COMMENT_NODE:
00166                 lastcmnt = (const char *)xmlNodeGetContent(xcp);
00167 //cout << "  now lastcmnt == \"" << lastcmnt << "\"" << endl;
00168                 break;
00169             case XML_TEXT_NODE:
00170                 valbuf += (const char *)xmlNodeGetContent(xcp);
00171 //cout << "  now valbuf == \"" << valbuf << "\"" << endl;
00172                 lastcmnt = QString();
00173                 break;
00174             case XML_ELEMENT_NODE:
00175 //cout << "  got element == \"" << xcp->name << "\"" << endl;
00176                 valbuf = QString();
00177 //cout << "  adding child == \"" << xcp->name << "\"" << endl;
00178                 if(!child.tval) child.tval = new SerialTree();
00179 //cout << "    with class " << child.tval->getSerializableClass() << endl;
00180                 newkid = new Child((const char *)(xcp->name));
00181                 //newkid->setComment(
00182                 child.tval->setComment((const char *)(xcp->name), lastcmnt);
00183                 lastcmnt = QString();
00184                 childFromXMLNode(*newkid, xcp);
00185                 if(newkid->tval) newkid->tval->setSerializableClass(::getSerializableClass(xcp));
00186 //cout << "  done adding child == \"" << xcp->name << "\"" << endl;
00187                 child.tval->children.append(newkid);
00188                 break;
00189             default:
00190                 NOT_DONE("parseXML() doesn't handle node type " << xnp->type);
00191         }
00192     }
00193     if(!child.tval)
00194     {
00195         //  no sub-child elements, so this must have just been text.
00196         child.sval = new QString(valbuf);
00197     }
00198 }
00199 
00200 }  //  namespace fun
00201 
00202 #endif  //  HAVE_LIBXML

Generated on Mon Aug 11 14:06:56 2003 for libfunutil by doxygen1.2.18