VPR-6.0
|
00001 /** 00002 * @file ezxml.h 00003 * 00004 * Copyright 2004-2006 Aaron Voisine <aaron@voisine.org> 00005 * 00006 * Permission is hereby granted, free of charge, to any person obtaining 00007 * a copy of this software and associated documentation files (the 00008 * "Software"), to deal in the Software without restriction, including 00009 * without limitation the rights to use, copy, modify, merge, publish, 00010 * distribute, sublicense, and/or sell copies of the Software, and to 00011 * permit persons to whom the Software is furnished to do so, subject to 00012 * the following conditions: 00013 * 00014 * The above copyright notice and this permission notice shall be included 00015 * in all copies or substantial portions of the Software. 00016 * 00017 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 00018 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00019 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 00020 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 00021 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 00022 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 00023 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00024 */ 00025 00026 #ifndef _EZXML_H 00027 #define _EZXML_H 00028 00029 #include <stdlib.h> 00030 #include <stdio.h> 00031 #include <stdarg.h> 00032 #include <fcntl.h> 00033 00034 #ifdef __cplusplus 00035 extern "C" 00036 { 00037 #endif 00038 00039 #define EZXML_BUFSIZE 1024 /**< size of internal memory buffers */ 00040 #define EZXML_NAMEM 0x80 /**< name is malloced */ 00041 #define EZXML_TXTM 0x40 /**< txt is malloced */ 00042 #define EZXML_DUP 0x20 /**< attribute name and value are strduped */ 00043 #define EZXML_ERRL 128 /**< maximum error string length */ 00044 00045 typedef struct ezxml *ezxml_t; 00046 struct ezxml 00047 { 00048 char *name; /**< tag name */ 00049 char **attr; /**< tag attributes { name, value, name, value, ... NULL } */ 00050 char *txt; /**< tag character content, empty string if none */ 00051 size_t off; /**< tag offset from start of parent tag character content */ 00052 ezxml_t next; /**< next tag with same name in this section at this depth */ 00053 ezxml_t sibling; /**< next tag with different name in same section and depth */ 00054 ezxml_t ordered; /**< next tag, same section and depth, in original order */ 00055 ezxml_t child; /**< head of sub tag list, NULL if none */ 00056 ezxml_t parent; /**< parent tag, NULL if current tag is root tag */ 00057 short flags; /**< additional information */ 00058 /* Jason Luu June 22, 2010, Added line number support */ 00059 int line; 00060 }; 00061 00062 /* Jason Luu June 22, 2010, Moved root definition to header */ 00063 /** additional data for the root tag */ 00064 typedef struct ezxml_root *ezxml_root_t; 00065 struct ezxml_root 00066 { 00067 struct ezxml xml; /**< is a super-struct built on top of ezxml struct */ 00068 ezxml_t cur; /**< current xml tree insertion point */ 00069 char *m; /**< original xml string */ 00070 size_t len; /**< length of allocated memory for mmap, -1 for malloc */ 00071 char *u; /**< UTF-8 conversion of string if original was UTF-16 */ 00072 char *s; /**< start of work area */ 00073 char *e; /**< end of work area */ 00074 char **ent; /**< general entities (ampersand sequences) */ 00075 char ***attr; /**< default attributes */ 00076 char ***pi; /**< processing instructions */ 00077 short standalone; /**< non-zero if <?xml standalone="yes"?> */ 00078 char err[EZXML_ERRL]; /**< error string */ 00079 }; 00080 00081 00082 /** Given a string of xml data and its length, parses it and creates an ezxml 00083 * structure. For efficiency, modifies the data by adding null terminators 00084 * and decoding ampersand sequences. If you don't want this, copy the data and 00085 * pass in the copy. Returns NULL on failure. 00086 */ 00087 ezxml_t ezxml_parse_str(char *s, 00088 size_t len); 00089 00090 /** A wrapper for ezxml_parse_str() that accepts a file descriptor. First 00091 * attempts to mem map the file. Failing that, reads the file into memory. 00092 * Returns NULL on failure. 00093 */ 00094 ezxml_t ezxml_parse_fd(int fd); 00095 00096 /** a wrapper for ezxml_parse_fd() that accepts a file name */ 00097 ezxml_t ezxml_parse_file(const char *file); 00098 00099 /** Wrapper for ezxml_parse_str() that accepts a file stream. Reads the entire 00100 * stream into memory and then parses it. For xml files, use ezxml_parse_file() 00101 * or ezxml_parse_fd() 00102 */ 00103 ezxml_t ezxml_parse_fp(FILE * fp); 00104 00105 /** returns the first child tag (one level deeper) with the given name or NULL 00106 * if not found 00107 */ 00108 ezxml_t ezxml_child(ezxml_t xml, 00109 const char *name); 00110 00111 /** returns the next tag of the same name in the same section and depth or NULL 00112 * if not found 00113 */ 00114 #define ezxml_next(xml) ((xml) ? xml->next : NULL) 00115 00116 /** Returns the Nth tag with the same name in the same section at the same depth 00117 * or NULL if not found. An index of 0 returns the tag given. 00118 */ 00119 ezxml_t ezxml_idx(ezxml_t xml, 00120 int idx); 00121 00122 /** returns the name of the given tag */ 00123 #define ezxml_name(xml) ((xml) ? xml->name : NULL) 00124 00125 /** returns the given tag's character content or empty string if none */ 00126 #define ezxml_txt(xml) ((xml) ? xml->txt : "") 00127 00128 /** returns the value of the requested tag attribute, or NULL if not found */ 00129 const char *ezxml_attr(ezxml_t xml, 00130 const char *attr); 00131 00132 /** Traverses the ezxml sturcture to retrieve a specific subtag. Takes a 00133 * variable length list of tag names and indexes. The argument list must be 00134 * terminated by either an index of -1 or an empty string tag name. Example: 00135 * title = ezxml_get(library, "shelf", 0, "book", 2, "title", -1); 00136 * This retrieves the title of the 3rd book on the 1st shelf of library. 00137 * Returns NULL if not found. 00138 */ 00139 ezxml_t ezxml_get(ezxml_t xml, 00140 ...); 00141 00142 /** Converts an ezxml structure back to xml. Returns a string of xml data that 00143 * must be freed. 00144 */ 00145 char *ezxml_toxml(ezxml_t xml); 00146 00147 /** returns a NULL terminated array of processing instructions for the given 00148 * target 00149 */ 00150 const char **ezxml_pi(ezxml_t xml, 00151 const char *target); 00152 00153 /** frees the memory allocated for an ezxml structure */ 00154 void ezxml_free(ezxml_t xml); 00155 00156 /** returns parser error message or empty string if none */ 00157 const char *ezxml_error(ezxml_t xml); 00158 00159 /** returns a new empty ezxml structure with the given root tag name */ 00160 ezxml_t ezxml_new(const char *name); 00161 00162 /** wrapper for ezxml_new() that strdup()s name */ 00163 #define ezxml_new_d(name) ezxml_set_flag(ezxml_new(strdup(name)), EZXML_NAMEM) 00164 00165 /** Adds a child tag. off is the offset of the child tag relative to the start 00166 * of the parent tag's character content. Returns the child tag. 00167 */ 00168 ezxml_t ezxml_add_child( 00169 ezxml_t xml, 00170 const char *name, 00171 size_t off); 00172 00173 /** wrapper for ezxml_add_child() that strdup()s name */ 00174 #define ezxml_add_child_d(xml, name, off) \ 00175 ezxml_set_flag(ezxml_add_child(xml, strdup(name), off), EZXML_NAMEM) 00176 00177 /** sets the character content for the given tag and returns the tag */ 00178 ezxml_t ezxml_set_txt(ezxml_t xml, 00179 const char *txt); 00180 00181 /** wrapper for ezxml_set_txt() that strdup()s txt */ 00182 #define ezxml_set_txt_d(xml, txt) \ 00183 ezxml_set_flag(ezxml_set_txt(xml, strdup(txt)), EZXML_TXTM) 00184 00185 /** Sets the given tag attribute or adds a new attribute if not found. A value 00186 * of NULL will remove the specified attribute. Returns the tag given. 00187 */ 00188 ezxml_t ezxml_set_attr(ezxml_t xml, 00189 const char *name, 00190 const char *value); 00191 00192 /** Wrapper for ezxml_set_attr() that strdup()s name/value. Value cannot be NULL */ 00193 #define ezxml_set_attr_d(xml, name, value) \ 00194 ezxml_set_attr(ezxml_set_flag(xml, EZXML_DUP), strdup(name), strdup(value)) 00195 00196 /** sets a flag for the given tag and returns the tag */ 00197 ezxml_t ezxml_set_flag(ezxml_t xml, 00198 short flag); 00199 00200 /** removes a tag along with its subtags without freeing its memory */ 00201 ezxml_t ezxml_cut(ezxml_t xml); 00202 00203 /** inserts an existing tag into an ezxml structure */ 00204 ezxml_t ezxml_insert(ezxml_t xml, 00205 ezxml_t dest, 00206 size_t off); 00207 00208 /** Moves an existing tag to become a subtag of dest at the given offset from 00209 * the start of dest's character content. Returns the moved tag. 00210 */ 00211 #define ezxml_move(xml, dest, off) ezxml_insert(ezxml_cut(xml), dest, off) 00212 00213 /** removes a tag along with all its subtags */ 00214 #define ezxml_remove(xml) ezxml_free(ezxml_cut(xml)) 00215 00216 #ifdef __cplusplus 00217 } 00218 #endif 00219 #endif /* _EZXML_H */