00001 /** @file 00002 00003 A brief file description 00004 00005 @section license License 00006 00007 Licensed to the Apache Software Foundation (ASF) under one 00008 or more contributor license agreements. See the NOTICE file 00009 distributed with this work for additional information 00010 regarding copyright ownership. The ASF licenses this file 00011 to you under the Apache License, Version 2.0 (the 00012 "License"); you may not use this file except in compliance 00013 with the License. You may obtain a copy of the License at 00014 00015 http://www.apache.org/licenses/LICENSE-2.0 00016 00017 Unless required by applicable law or agreed to in writing, software 00018 distributed under the License is distributed on an "AS IS" BASIS, 00019 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00020 See the License for the specific language governing permissions and 00021 limitations under the License. 00022 */ 00023 00024 00025 00026 #ifndef INK_XML_H 00027 #define INK_XML_H 00028 00029 #include "List.h" 00030 00031 /*------------------------------------------------------------------------- 00032 InkXml.h 00033 00034 This file defines the interface for parsing XML-style config files. Such 00035 a file contains various XML objects, each with tags (or attibutes). The 00036 parser's job is to build a database of these objects that can then be 00037 queried later to extract the desired information. 00038 -------------------------------------------------------------------------*/ 00039 00040 /*------------------------------------------------------------------------- 00041 InkXmlAttr 00042 -------------------------------------------------------------------------*/ 00043 00044 class InkXmlAttr 00045 { 00046 public: 00047 InkXmlAttr(const char *tag, const char *value); 00048 ~InkXmlAttr(); 00049 00050 char *tag() const 00051 { 00052 return m_tag; 00053 } 00054 char *value() const 00055 { 00056 return m_value; 00057 } 00058 void display(FILE * fd = stdout); 00059 00060 private: 00061 char *m_tag; 00062 char *m_value; 00063 00064 public: 00065 LINK(InkXmlAttr, link); 00066 00067 private: 00068 // -- member functions that are not allowed -- 00069 InkXmlAttr(); 00070 InkXmlAttr(const InkXmlAttr &); 00071 InkXmlAttr & operator=(InkXmlAttr &); 00072 }; 00073 00074 /*------------------------------------------------------------------------- 00075 InkXmlObject 00076 00077 An XmlObject has a name and a set of <tag,value> attributes. 00078 -------------------------------------------------------------------------*/ 00079 00080 class InkXmlObject 00081 { 00082 public: 00083 InkXmlObject(const char *object_name, bool dup_attrs_allowed = true); 00084 ~InkXmlObject(); 00085 00086 void clear_tags(); 00087 int add_tag(const char *tag, const char *value); 00088 int add_attr(InkXmlAttr * attr); 00089 char *tag_value(const char *tag_name); 00090 void display(FILE * fd = stdout); 00091 00092 char *object_name() const 00093 { 00094 return m_object_name; 00095 } 00096 InkXmlAttr *first() const 00097 { 00098 return m_tags.head; 00099 } 00100 InkXmlAttr *next(InkXmlAttr * here) const 00101 { 00102 return (here->link).next; 00103 } 00104 00105 private: 00106 char *m_object_name; 00107 bool m_dup_attrs_allowed; 00108 Queue<InkXmlAttr> m_tags; 00109 00110 public: 00111 LINK(InkXmlObject, link); 00112 00113 private: 00114 InkXmlObject * get_next_xml_object(int fd); 00115 00116 private: 00117 // -- member functions that are not allowed -- 00118 InkXmlObject(); 00119 InkXmlObject(const InkXmlObject &); 00120 InkXmlObject & operator=(InkXmlObject &); 00121 }; 00122 00123 /*------------------------------------------------------------------------- 00124 InkXmlConfigFile 00125 00126 This object is used to parse an XML-style config file and create a 00127 database of resulting XML objects. 00128 -------------------------------------------------------------------------*/ 00129 00130 class InkXmlConfigFile 00131 { 00132 00133 public: 00134 InkXmlConfigFile(const char *config_file); 00135 ~InkXmlConfigFile(); 00136 00137 void clear_objects(); 00138 /* */ 00139 int parse(int fd); 00140 /* */ 00141 int parse(); 00142 void add_object(InkXmlObject * object); 00143 InkXmlObject *find_object(const char *object_name); 00144 void display(FILE * fd = stdout); 00145 00146 InkXmlObject *first() 00147 { 00148 return m_objects.head; 00149 } 00150 InkXmlObject *next(InkXmlObject * here) 00151 { 00152 return (here->link).next; 00153 } 00154 00155 private: 00156 InkXmlObject * get_next_xml_object(int fd); 00157 InkXmlObject *parse_error(); 00158 InkXmlObject *scan_object(int fd, char token); 00159 InkXmlAttr *scan_attr(int fd, const char *ident); 00160 char next_token(int fd, bool eat_whitespace = true); 00161 char scan_comment(int fd); 00162 00163 private: 00164 char *m_config_file; 00165 unsigned m_line; 00166 unsigned m_col; 00167 Queue<InkXmlObject> m_objects; 00168 00169 private: 00170 // -- member functions that are not allowed -- 00171 InkXmlConfigFile(); 00172 InkXmlConfigFile(const InkXmlConfigFile &); 00173 InkXmlConfigFile & operator=(InkXmlConfigFile &); 00174 }; 00175 00176 class NameList 00177 { 00178 private: 00179 struct ListElem 00180 { 00181 char *m_name; 00182 LINK(ListElem, link); 00183 00184 ListElem(char *name):m_name(name) 00185 { } 00186 }; 00187 00188 public: 00189 NameList():m_count(0) { 00190 } 00191 ~NameList() { 00192 clear(); 00193 } 00194 00195 void enqueue(char *name) 00196 { 00197 ListElem *e = new ListElem(name); 00198 00199 m_list.enqueue(e); 00200 m_count++; 00201 } 00202 00203 char *dequeue() 00204 { 00205 char *ret = NULL; 00206 ListElem *e = m_list.dequeue(); 00207 00208 if (e) { 00209 ret = e->m_name; 00210 delete e; 00211 m_count--; 00212 } 00213 return ret; 00214 } 00215 00216 void clear() 00217 { 00218 ListElem *e; 00219 00220 while ((e = m_list.dequeue()) != NULL) { 00221 delete e; 00222 } 00223 m_count = 0; 00224 } 00225 00226 unsigned count() 00227 { 00228 return m_count; 00229 } 00230 00231 private: 00232 Queue<ListElem> m_list; 00233 unsigned m_count; 00234 }; 00235 00236 #endif /* INK_XML_H */