Navit SVN

/work/compile/navit/src/navit/support/ezxml/ezxml.h

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