nova proba

Committer:
Bosko Lekovic
Date:
Sun Jan 17 23:03:43 2021 +0100
Revision:
27:0772451fb880
initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Bosko Lekovic 27:0772451fb880 1 /* dxml.h
Bosko Lekovic 27:0772451fb880 2 *
Bosko Lekovic 27:0772451fb880 3 * softverski modul korigovan 11.04.2020
Bosko Lekovic 27:0772451fb880 4 *
Bosko Lekovic 27:0772451fb880 5 */
Bosko Lekovic 27:0772451fb880 6
Bosko Lekovic 27:0772451fb880 7 #ifndef _dxml_H
Bosko Lekovic 27:0772451fb880 8 #define _dxml_H
Bosko Lekovic 27:0772451fb880 9
Bosko Lekovic 27:0772451fb880 10 #include <stdlib.h>
Bosko Lekovic 27:0772451fb880 11 #include <stdio.h>
Bosko Lekovic 27:0772451fb880 12 #include <stdarg.h>
Bosko Lekovic 27:0772451fb880 13 //#include <fcntl.h>
Bosko Lekovic 27:0772451fb880 14
Bosko Lekovic 27:0772451fb880 15 #ifdef __cplusplus
Bosko Lekovic 27:0772451fb880 16 extern "C" {
Bosko Lekovic 27:0772451fb880 17 #endif
Bosko Lekovic 27:0772451fb880 18
Bosko Lekovic 27:0772451fb880 19 #define dxml_BUFSIZE 1024 // size of internal memory buffers
Bosko Lekovic 27:0772451fb880 20 #define dxml_NAMEM 0x80 // name is malloced
Bosko Lekovic 27:0772451fb880 21 #define dxml_TXTM 0x40 // txt is malloced
Bosko Lekovic 27:0772451fb880 22 #define dxml_DUP 0x20 // attribute name and value are strduped
Bosko Lekovic 27:0772451fb880 23
Bosko Lekovic 27:0772451fb880 24 typedef struct dxml *dxml_t;
Bosko Lekovic 27:0772451fb880 25 struct dxml {
Bosko Lekovic 27:0772451fb880 26 char *name; // tag name
Bosko Lekovic 27:0772451fb880 27 char **attr; // tag attributes { name, value, name, value, ... NULL }
Bosko Lekovic 27:0772451fb880 28 char *txt; // tag character content, empty string if none
Bosko Lekovic 27:0772451fb880 29 size_t off; // tag offset from start of parent tag character content
Bosko Lekovic 27:0772451fb880 30 dxml_t next; // next tag with same name in this section at this depth
Bosko Lekovic 27:0772451fb880 31 dxml_t sibling; // next tag with different name in same section and depth
Bosko Lekovic 27:0772451fb880 32 dxml_t ordered; // next tag, same section and depth, in original order
Bosko Lekovic 27:0772451fb880 33 dxml_t child; // head of sub tag list, NULL if none
Bosko Lekovic 27:0772451fb880 34 dxml_t parent; // parent tag, NULL if current tag is root tag
Bosko Lekovic 27:0772451fb880 35 short flags; // additional information
Bosko Lekovic 27:0772451fb880 36 };
Bosko Lekovic 27:0772451fb880 37
Bosko Lekovic 27:0772451fb880 38 // Given a string of xml data and its length, parses it and creates an dxml
Bosko Lekovic 27:0772451fb880 39 // structure. For efficiency, modifies the data by adding null terminators
Bosko Lekovic 27:0772451fb880 40 // and decoding ampersand sequences. If you don't want this, copy the data and
Bosko Lekovic 27:0772451fb880 41 // pass in the copy. Returns NULL on failure.
Bosko Lekovic 27:0772451fb880 42 dxml_t dxml_parse_str(char *s, size_t len);
Bosko Lekovic 27:0772451fb880 43
Bosko Lekovic 27:0772451fb880 44 // A wrapper for dxml_parse_str() that accepts a file descriptor. First
Bosko Lekovic 27:0772451fb880 45 // attempts to mem map the file. Failing that, reads the file into memory.
Bosko Lekovic 27:0772451fb880 46 // Returns NULL on failure.
Bosko Lekovic 27:0772451fb880 47 //dxml_t dxml_parse_fd(int fd);
Bosko Lekovic 27:0772451fb880 48
Bosko Lekovic 27:0772451fb880 49 // a wrapper for dxml_parse_fd() that accepts a file name
Bosko Lekovic 27:0772451fb880 50 dxml_t dxml_parse_file(const char *file);
Bosko Lekovic 27:0772451fb880 51
Bosko Lekovic 27:0772451fb880 52 // Wrapper for dxml_parse_str() that accepts a file stream. Reads the entire
Bosko Lekovic 27:0772451fb880 53 // stream into memory and then parses it. For xml files, use dxml_parse_file()
Bosko Lekovic 27:0772451fb880 54 // or dxml_parse_fd()
Bosko Lekovic 27:0772451fb880 55 dxml_t dxml_parse_fp(FILE *fp);
Bosko Lekovic 27:0772451fb880 56
Bosko Lekovic 27:0772451fb880 57 // returns the first child tag (one level deeper) with the given name or NULL
Bosko Lekovic 27:0772451fb880 58 // if not found
Bosko Lekovic 27:0772451fb880 59 dxml_t dxml_child(dxml_t xml, const char *name);
Bosko Lekovic 27:0772451fb880 60
Bosko Lekovic 27:0772451fb880 61 // returns the next tag of the same name in the same section and depth or NULL
Bosko Lekovic 27:0772451fb880 62 // if not found
Bosko Lekovic 27:0772451fb880 63 #define dxml_next(xml) ((xml) ? xml->next : NULL)
Bosko Lekovic 27:0772451fb880 64
Bosko Lekovic 27:0772451fb880 65 // Returns the Nth tag with the same name in the same section at the same depth
Bosko Lekovic 27:0772451fb880 66 // or NULL if not found. An index of 0 returns the tag given.
Bosko Lekovic 27:0772451fb880 67 dxml_t dxml_idx(dxml_t xml, int idx);
Bosko Lekovic 27:0772451fb880 68
Bosko Lekovic 27:0772451fb880 69 // returns the name of the given tag
Bosko Lekovic 27:0772451fb880 70 #define dxml_name(xml) ((xml) ? xml->name : NULL)
Bosko Lekovic 27:0772451fb880 71
Bosko Lekovic 27:0772451fb880 72 // returns the given tag's character content or empty string if none
Bosko Lekovic 27:0772451fb880 73 #define dxml_txt(xml) ((xml) ? xml->txt : "")
Bosko Lekovic 27:0772451fb880 74
Bosko Lekovic 27:0772451fb880 75 // returns the value of the requested tag attribute, or NULL if not found
Bosko Lekovic 27:0772451fb880 76 const char *dxml_attr(dxml_t xml, const char *attr);
Bosko Lekovic 27:0772451fb880 77
Bosko Lekovic 27:0772451fb880 78 // Traverses the dxml sturcture to retrieve a specific subtag. Takes a
Bosko Lekovic 27:0772451fb880 79 // variable length list of tag names and indexes. The argument list must be
Bosko Lekovic 27:0772451fb880 80 // terminated by either an index of -1 or an empty string tag name. Example:
Bosko Lekovic 27:0772451fb880 81 // title = dxml_get(library, "shelf", 0, "book", 2, "title", -1);
Bosko Lekovic 27:0772451fb880 82 // This retrieves the title of the 3rd book on the 1st shelf of library.
Bosko Lekovic 27:0772451fb880 83 // Returns NULL if not found.
Bosko Lekovic 27:0772451fb880 84 dxml_t dxml_get(dxml_t xml, ...);
Bosko Lekovic 27:0772451fb880 85
Bosko Lekovic 27:0772451fb880 86 // Converts an dxml structure back to xml. Returns a string of xml data that
Bosko Lekovic 27:0772451fb880 87 // must be freed.
Bosko Lekovic 27:0772451fb880 88 char *dxml_toxml(dxml_t xml);
Bosko Lekovic 27:0772451fb880 89
Bosko Lekovic 27:0772451fb880 90 // returns a NULL terminated array of processing instructions for the given
Bosko Lekovic 27:0772451fb880 91 // target
Bosko Lekovic 27:0772451fb880 92 const char **dxml_pi(dxml_t xml, const char *target);
Bosko Lekovic 27:0772451fb880 93
Bosko Lekovic 27:0772451fb880 94 // frees the memory allocated for an dxml structure
Bosko Lekovic 27:0772451fb880 95 void dxml_free(dxml_t xml);
Bosko Lekovic 27:0772451fb880 96
Bosko Lekovic 27:0772451fb880 97 // returns parser error message or empty string if none
Bosko Lekovic 27:0772451fb880 98 const char *dxml_error(dxml_t xml);
Bosko Lekovic 27:0772451fb880 99
Bosko Lekovic 27:0772451fb880 100 // returns a new empty dxml structure with the given root tag name
Bosko Lekovic 27:0772451fb880 101 dxml_t dxml_new(const char *name);
Bosko Lekovic 27:0772451fb880 102
Bosko Lekovic 27:0772451fb880 103 // wrapper for dxml_new() that strdup()s name
Bosko Lekovic 27:0772451fb880 104 #define dxml_new_d(name) dxml_set_flag(dxml_new(strdup(name)), dxml_NAMEM)
Bosko Lekovic 27:0772451fb880 105
Bosko Lekovic 27:0772451fb880 106 // Adds a child tag. off is the offset of the child tag relative to the start
Bosko Lekovic 27:0772451fb880 107 // of the parent tag's character content. Returns the child tag.
Bosko Lekovic 27:0772451fb880 108 dxml_t dxml_add_child(dxml_t xml, const char *name, size_t off);
Bosko Lekovic 27:0772451fb880 109
Bosko Lekovic 27:0772451fb880 110 // wrapper for dxml_add_child() that strdup()s name
Bosko Lekovic 27:0772451fb880 111 #define dxml_add_child_d(xml, name, off) \
Bosko Lekovic 27:0772451fb880 112 dxml_set_flag(dxml_add_child(xml, strdup(name), off), dxml_NAMEM)
Bosko Lekovic 27:0772451fb880 113
Bosko Lekovic 27:0772451fb880 114 // sets the character content for the given tag and returns the tag
Bosko Lekovic 27:0772451fb880 115 dxml_t dxml_set_txt(dxml_t xml, const char *txt);
Bosko Lekovic 27:0772451fb880 116
Bosko Lekovic 27:0772451fb880 117 // wrapper for dxml_set_txt() that strdup()s txt
Bosko Lekovic 27:0772451fb880 118 #define dxml_set_txt_d(xml, txt) \
Bosko Lekovic 27:0772451fb880 119 dxml_set_flag(dxml_set_txt(xml, strdup(txt)), dxml_TXTM)
Bosko Lekovic 27:0772451fb880 120
Bosko Lekovic 27:0772451fb880 121 // Sets the given tag attribute or adds a new attribute if not found. A value
Bosko Lekovic 27:0772451fb880 122 // of NULL will remove the specified attribute. Returns the tag given.
Bosko Lekovic 27:0772451fb880 123 dxml_t dxml_set_attr(dxml_t xml, const char *name, const char *value);
Bosko Lekovic 27:0772451fb880 124
Bosko Lekovic 27:0772451fb880 125 // Wrapper for dxml_set_attr() that strdup()s name/value. Value cannot be NULL
Bosko Lekovic 27:0772451fb880 126 #define dxml_set_attr_d(xml, name, value) \
Bosko Lekovic 27:0772451fb880 127 dxml_set_attr(dxml_set_flag(xml, dxml_DUP), strdup(name), strdup(value))
Bosko Lekovic 27:0772451fb880 128
Bosko Lekovic 27:0772451fb880 129 // sets a flag for the given tag and returns the tag
Bosko Lekovic 27:0772451fb880 130 dxml_t dxml_set_flag(dxml_t xml, short flag);
Bosko Lekovic 27:0772451fb880 131
Bosko Lekovic 27:0772451fb880 132 // removes a tag along with its subtags without freeing its memory
Bosko Lekovic 27:0772451fb880 133 dxml_t dxml_cut(dxml_t xml);
Bosko Lekovic 27:0772451fb880 134
Bosko Lekovic 27:0772451fb880 135 // inserts an existing tag into an dxml structure
Bosko Lekovic 27:0772451fb880 136 dxml_t dxml_insert(dxml_t xml, dxml_t dest, size_t off);
Bosko Lekovic 27:0772451fb880 137
Bosko Lekovic 27:0772451fb880 138 // Moves an existing tag to become a subtag of dest at the given offset from
Bosko Lekovic 27:0772451fb880 139 // the start of dest's character content. Returns the moved tag.
Bosko Lekovic 27:0772451fb880 140 #define dxml_move(xml, dest, off) dxml_insert(dxml_cut(xml), dest, off)
Bosko Lekovic 27:0772451fb880 141
Bosko Lekovic 27:0772451fb880 142 // removes a tag along with all its subtags
Bosko Lekovic 27:0772451fb880 143 #define dxml_remove(xml) dxml_free(dxml_cut(xml))
Bosko Lekovic 27:0772451fb880 144
Bosko Lekovic 27:0772451fb880 145 #ifdef __cplusplus
Bosko Lekovic 27:0772451fb880 146 }
Bosko Lekovic 27:0772451fb880 147 #endif
Bosko Lekovic 27:0772451fb880 148
Bosko Lekovic 27:0772451fb880 149 #endif // _dxml_H
Bosko Lekovic 27:0772451fb880 150
Bosko Lekovic 27:0772451fb880 151