CLAM-Development
1.1
|
00001 /* 00002 * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG) 00003 * UNIVERSITAT POMPEU FABRA 00004 * 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 * 00020 */ 00021 #ifndef _LibXmlDomDocumentHandler_hxx_ 00022 #define _LibXmlDomDocumentHandler_hxx_ 00023 00024 #include "LibXmlDomReadingContext.hxx" 00025 #include "LibXmlDomWritingContext.hxx" 00026 #include "LibXmlDomReader.hxx" 00027 #include "LibXmlDomWriter.hxx" 00028 00029 00030 #include <libxml++/libxml++.h> 00031 00032 namespace CLAM 00033 { 00034 class LibXmlDomReadingContext; 00035 class LibXmlDomWritingContext; 00040 class LibXmlDomDocumentHandler 00041 { 00042 public: 00043 typedef LibXmlDomWritingContext WritingContext; 00044 typedef LibXmlDomReadingContext ReadingContext; 00045 ReadingContext * GetReadingContext() 00046 { 00047 return _currentReadContext; 00048 } 00049 void SetReadingContext(ReadingContext * context) 00050 { 00051 _currentReadContext = context; 00052 } 00053 WritingContext * GetWritingContext() 00054 { 00055 return _currentWriteContext; 00056 } 00057 void SetWritingContext(WritingContext * context) 00058 { 00059 _currentWriteContext = context; 00060 } 00061 private: 00062 ReadingContext * _currentReadContext; 00063 WritingContext * _currentWriteContext; 00064 xmlpp::Document * _document; 00065 xmlpp::Element * _selection; 00066 xmlpp::DomParser * _parser; 00067 public: 00068 LibXmlDomDocumentHandler() 00069 { 00070 _document = 0; 00071 _selection = 0; 00072 _parser = 0; 00073 } 00074 ~LibXmlDomDocumentHandler() 00075 { 00076 releaseIfAnyDocument(); 00077 } 00078 void setDocument(xmlpp::Document * document) 00079 { 00080 _document = document; 00081 _selection = _document->get_root_node(); 00082 } 00083 void selectPath(const char * path) 00084 { 00085 if (path[0]!='/') 00086 _selection = recursiveSelection(_selection, path, 0); 00087 else 00088 _selection = absoluteSelection(path); 00089 return; 00090 } 00091 xmlpp::Element * getSelection() 00092 { 00093 return _selection; 00094 } 00095 void create(const char * rootName) 00096 { 00097 releaseIfAnyDocument(); 00098 00099 xmlpp::Document * domDoc = new xmlpp::Document; 00100 domDoc->create_root_node(rootName); 00101 setDocument(domDoc); 00102 } 00103 void read(std::istream & stream) 00104 { 00105 LibXmlDomReader reader; 00106 xmlpp::Document * domDoc; 00107 domDoc = reader.read(stream); 00108 setDocument(domDoc); 00109 _parser = reader.adoptParser(); 00110 } 00111 void writeDocument(std::ostream & os, bool useIndentation=false) 00112 { 00113 LibXmlDomWriter writer; 00114 writer.DoIndentedFormat(useIndentation); 00115 writer.write(os,_document); 00116 } 00117 void writeSelection(std::ostream & os, bool useIndentation=false) 00118 { 00119 LibXmlDomWriter writer; 00120 writer.DoIndentedFormat(useIndentation); 00121 writer.write(os,_selection); 00122 } 00123 private: 00124 void releaseIfAnyDocument() 00125 { 00126 if (!_document) return; 00127 00128 if (_parser) 00129 delete _parser; 00130 else 00131 delete _document; 00132 _parser=0; 00133 _document=0; 00134 } 00135 xmlpp::Element * absoluteSelection(const std::string & path) 00136 { 00137 xmlpp::Element * root = _document->get_root_node(); 00138 unsigned int nextSlash = std::string(path).find('/',1); 00139 std::string rootStep = std::string(path).substr(1,nextSlash-1); 00140 std::string rootName = root->get_name(); 00141 if (rootStep=="") return root; 00142 00143 if (rootName== rootStep) 00144 return recursiveSelection(root, path, nextSlash+1); 00145 00146 throw XmlStorageErr("Wrong root name, expected '"+rootStep+"' but found '"+rootName+"'"); 00147 } 00148 xmlpp::Element * recursiveSelection(xmlpp::Element * current, const std::string & path, unsigned int pos) 00149 { 00150 if (pos >= path.length()) return current; 00151 unsigned int slashPosition = path.find('/', pos); 00152 unsigned int stepSize = 00153 slashPosition == std::string::npos ? 00154 std::string::npos : slashPosition-pos; 00155 std::string step = path.substr(pos, stepSize); 00156 xmlpp::Element::NodeList children = current->get_children(); 00157 for ( 00158 xmlpp::Element::NodeList::iterator child = children.begin(); 00159 child!=children.end(); 00160 child++) 00161 { 00162 xmlpp::Element * element = dynamic_cast<xmlpp::Element*>(*child); 00163 if (!element) continue; 00164 std::string nodeName= element->get_name(); 00165 if (nodeName != step) continue; 00166 if (slashPosition==std::string::npos) return element; 00167 return recursiveSelection(element, path, slashPosition+1); 00168 } 00169 std::string msg = "Wrong path step '" + step + "'"; 00170 throw XmlStorageErr(msg); 00171 } 00172 }; 00173 00174 00175 } 00176 00181 #endif//_LibXmlDomDocumentHandler_hxx_ 00182