1 /**
2  * @file xml_internal.h
3  * @author Radek Krejci <rkrejci@cesnet.cz>
4  * @brief Internal part of libyang XML parser
5  *
6  * Copyright (c) 2015 CESNET, z.s.p.o.
7  *
8  * This source code is licensed under BSD 3-Clause License (the "License").
9  * You may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     https://opensource.org/licenses/BSD-3-Clause
13  */
14 
15 #ifndef LY_XML_INTERNAL_H_
16 #define LY_XML_INTERNAL_H_
17 
18 #include <stdio.h>
19 #include "xml.h"
20 #include "printer.h"
21 
22 /*
23  * Macro to test if character is #x20 | #x9 | #xA | #xD (whitespace)
24  */
25 #define is_xmlws(c) (c == 0x20 || c == 0x9 || c == 0xa || c == 0xd)
26 
27 #define is_xmlnamestartchar(c) ((c >= 'a' && c <= 'z') || c == '_' || \
28         (c >= 'A' && c <= 'Z') || c == ':' || \
29         (c >= 0x370 && c <= 0x1fff && c != 0x37e ) || \
30         (c >= 0xc0 && c <= 0x2ff && c != 0xd7 && c != 0xf7) || c == 0x200c || \
31         c == 0x200d || (c >= 0x2070 && c <= 0x218f) || \
32         (c >= 0x2c00 && c <= 0x2fef) || (c >= 0x3001 && c <= 0xd7ff) || \
33         (c >= 0xf900 && c <= 0xfdcf) || (c >= 0xfdf0 && c <= 0xfffd) || \
34         (c >= 0x10000 && c <= 0xeffff))
35 
36 #define is_xmlnamechar(c) ((c >= 'a' && c <= 'z') || c == '_' || c == '-' || \
37         (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == ':' || \
38         c == '.' || c == 0xb7 || (c >= 0x370 && c <= 0x1fff && c != 0x37e ) ||\
39         (c >= 0xc0 && c <= 0x2ff && c != 0xd7 && c != 0xf7) || c == 0x200c || \
40         c == 0x200d || (c >= 0x300 && c <= 0x36f) || \
41         (c >= 0x2070 && c <= 0x218f) || (c >= 0x203f && c <= 0x2040) || \
42         (c >= 0x2c00 && c <= 0x2fef) || (c >= 0x3001 && c <= 0xd7ff) || \
43         (c >= 0xf900 && c <= 0xfdcf) || (c >= 0xfdf0 && c <= 0xfffd) || \
44         (c >= 0x10000 && c <= 0xeffff))
45 
46 /*
47  * Functions
48  * Tree Manipulation
49  */
50 
51 /**
52  * @brief Add a child element into a parent element.
53  *
54  * The child is added as a last child.
55  *
56  * @param[in] ctx libyang context to use.
57  * @param[in] parent Element where to add the child.
58  * @param[in] child Element to be added as a last child of the parent.
59  * @return EXIT_SUCCESS or EXIT_FAILURE
60  */
61 int lyxml_add_child(struct ly_ctx *ctx, struct lyxml_elem *parent, struct lyxml_elem *child);
62 
63 /* copy_ns: 0 - set invalid namespaces to NULL, 1 - copy them into this subtree */
64 void lyxml_correct_elem_ns(struct ly_ctx *ctx, struct lyxml_elem *elem, struct lyxml_elem *orig, int copy_ns,
65                            int correct_attrs);
66 
67 struct lyxml_elem *lyxml_dup_elem(struct ly_ctx *ctx, struct lyxml_elem *elem,
68                                   struct lyxml_elem *parent, int recursive, int with_siblings);
69 
70 /**
71  * @brief Free attribute. Includes unlinking from an element if the attribute
72  * is placed anywhere.
73  *
74  * @param[in] ctx libyang context to use
75  * @param[in] parent Parent element where the attribute is placed
76  * @param[in] attr Attribute to free.
77  */
78 void lyxml_free_attr(struct ly_ctx *ctx, struct lyxml_elem *parent, struct lyxml_attr *attr);
79 
80 /**
81  * @brief Free (and unlink from their element) all attributes (including
82  * namespace definitions) of the specified element.
83  *
84  * @param[in] elem Element to modify.
85  */
86 void lyxml_free_attrs(struct ly_ctx *ctx, struct lyxml_elem *elem);
87 
88 /**
89  * @brief Unlink the attribute from its parent element. In contrast to
90  * lyxml_free_attr(), after return the caller can still manipulate with the
91  * attr.
92  *
93  * @param[in] attr Attribute to unlink from its parent (if any).
94  */
95 void lyxml_unlink_attr(struct lyxml_attr *attr);
96 
97 /**
98  * @brief Unlink the element from its parent. In contrast to lyxml_free_elem(),
99  * after return the caller can still manipulate with the elem.
100  *
101  * @param[in] ctx libyang context to use.
102  * @param[in] elem Element to unlink from its parent (if any).
103  * @param[in] copy_ns 0 sets NS of \p elem and children that are defined
104  * outside \p elem subtree to NULL,
105  * 1 corrects NS of \p elem and children that are defined outside \p elem
106  * subtree (copy NS and update pointer),
107  * 2 skips any NS checking.
108  *
109  */
110 void lyxml_unlink_elem(struct ly_ctx *ctx, struct lyxml_elem *elem, int copy_ns);
111 
112 /**
113  * @brief Get the first UTF-8 character value (4bytes) from buffer
114  * @param[in] ctx Context to store errors in.
115  * @param[in] buf Pointer to the current position in input buffer.
116  * @param[out] read Number of processed bytes in buf (length of UTF-8
117  * character).
118  * @return UTF-8 value as 4 byte number. 0 means error, only UTF-8 characters
119  * valid for XML are returned, so:
120  * #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
121  * = any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
122  *
123  * UTF-8 mapping:
124  * 00000000 -- 0000007F:    0xxxxxxx
125  * 00000080 -- 000007FF:    110xxxxx 10xxxxxx
126  * 00000800 -- 0000FFFF:    1110xxxx 10xxxxxx 10xxxxxx
127  * 00010000 -- 001FFFFF:    11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
128  */
129 int lyxml_getutf8(struct ly_ctx *ctx, const char *buf, unsigned int *read);
130 
131 /**
132  * @brief Types of the XML data
133  */
134 typedef enum lyxml_data_type {
135     LYXML_DATA_ATTR = 1,   /**< XML attribute data */
136     LYXML_DATA_ELEM = 2    /**< XML element data */
137 } LYXML_DATA_TYPE;
138 
139 /**
140  * @brief Dump XML text. Converts special characters to their equivalent
141  * starting with '&'.
142  * @param[in] out Output structure.
143  * @param[in] text Text to dump.
144  * @return Number of dumped characters.
145  */
146 int lyxml_dump_text(struct lyout *out, const char *text, LYXML_DATA_TYPE type);
147 
148 #endif /* LY_XML_INTERNAL_H_ */
149