Coverage Report

Created: 2025-06-13 06:18

/src/gdal/port/cpl_minixml.h
Line
Count
Source (jump to first uncovered line)
1
/**********************************************************************
2
 *
3
 * Project:  CPL - Common Portability Library
4
 * Purpose:  Declarations for MiniXML Handler.
5
 * Author:   Frank Warmerdam, warmerdam@pobox.com
6
 *
7
 **********************************************************************
8
 * Copyright (c) 2001, Frank Warmerdam
9
 *
10
 * SPDX-License-Identifier: MIT
11
 ****************************************************************************/
12
13
#ifndef CPL_MINIXML_H_INCLUDED
14
#define CPL_MINIXML_H_INCLUDED
15
16
#include "cpl_port.h"
17
18
/**
19
 * \file cpl_minixml.h
20
 *
21
 * Definitions for CPL mini XML Parser/Serializer.
22
 */
23
24
CPL_C_START
25
26
/** XML node type */
27
typedef enum
28
{
29
    /*! Node is an element */ CXT_Element = 0,
30
    /*! Node is a raw text value */ CXT_Text = 1,
31
    /*! Node is attribute */ CXT_Attribute = 2,
32
    /*! Node is an XML comment. */ CXT_Comment = 3,
33
    /*! Node is a special literal */ CXT_Literal = 4
34
} CPLXMLNodeType;
35
36
/*! @cond Doxygen_Suppress */
37
typedef struct CPLXMLNode CPLXMLNode;
38
39
/*! @endcond */
40
41
/**
42
 * Document node structure.
43
 *
44
 * This C structure is used to hold a single text fragment representing a
45
 * component of the document when parsed.   It should be allocated with the
46
 * appropriate CPL function, and freed with CPLDestroyXMLNode().  The structure
47
 * contents should not normally be altered by application code, but may be
48
 * freely examined by application code.
49
 *
50
 * Using the psChild and psNext pointers, a hierarchical tree structure
51
 * for a document can be represented as a tree of CPLXMLNode structures.
52
 */
53
struct CPLXMLNode
54
{
55
    /**
56
     * \brief Node type
57
     *
58
     * One of CXT_Element, CXT_Text, CXT_Attribute, CXT_Comment,
59
     * or CXT_Literal.
60
     */
61
    CPLXMLNodeType eType;
62
63
    /**
64
     * \brief Node value
65
     *
66
     * For CXT_Element this is the name of the element, without the angle
67
     * brackets.  Note there is a single CXT_Element even when the document
68
     * contains a start and end element tag.  The node represents the pair.
69
     * All text or other elements between the start and end tag will appear
70
     * as children nodes of this CXT_Element node.
71
     *
72
     * For CXT_Attribute the pszValue is the attribute name.  The value of
73
     * the attribute will be a CXT_Text child.
74
     *
75
     * For CXT_Text this is the text itself (value of an attribute, or a
76
     * text fragment between an element start and end tags.
77
     *
78
     * For CXT_Literal it is all the literal text.  Currently this is just
79
     * used for !DOCTYPE lines, and the value would be the entire line.
80
     *
81
     * For CXT_Comment the value is all the literal text within the comment,
82
     * but not including the comment start/end indicators ("<--" and "-->").
83
     */
84
    char *pszValue;
85
86
    /**
87
     * \brief Next sibling.
88
     *
89
     * Pointer to next sibling, that is the next node appearing after this
90
     * one that has the same parent as this node.  NULL if this node is the
91
     * last child of the parent element.
92
     */
93
    struct CPLXMLNode *psNext;
94
95
    /**
96
     * \brief Child node.
97
     *
98
     * Pointer to first child node, if any.  Only CXT_Element and CXT_Attribute
99
     * nodes should have children.  For CXT_Attribute it should be a single
100
     * CXT_Text value node, while CXT_Element can have any kind of child.
101
     * The full list of children for a node are identified by walking the
102
     * psNext's starting with the psChild node.
103
     */
104
105
    struct CPLXMLNode *psChild;
106
};
107
108
CPLXMLNode CPL_DLL *CPLParseXMLString(const char *);
109
void CPL_DLL CPLDestroyXMLNode(CPLXMLNode *);
110
CPLXMLNode CPL_DLL *CPLGetXMLNode(CPLXMLNode *poRoot, const char *pszPath);
111
#if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
112
/*! @cond Doxygen_Suppress */
113
extern "C++"
114
{
115
    inline const CPLXMLNode *CPLGetXMLNode(const CPLXMLNode *poRoot,
116
                                           const char *pszPath)
117
0
    {
118
0
        return const_cast<const CPLXMLNode *>(
119
0
            CPLGetXMLNode(const_cast<CPLXMLNode *>(poRoot), pszPath));
120
0
    }
121
}
122
/*! @endcond */
123
#endif
124
CPLXMLNode CPL_DLL *CPLSearchXMLNode(CPLXMLNode *poRoot, const char *pszTarget);
125
#if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
126
/*! @cond Doxygen_Suppress */
127
extern "C++"
128
{
129
    inline const CPLXMLNode *CPLSearchXMLNode(const CPLXMLNode *poRoot,
130
                                              const char *pszTarget)
131
0
    {
132
0
        return const_cast<const CPLXMLNode *>(
133
0
            CPLSearchXMLNode(const_cast<CPLXMLNode *>(poRoot), pszTarget));
134
0
    }
135
}
136
/*! @endcond */
137
#endif
138
const char CPL_DLL *CPLGetXMLValue(const CPLXMLNode *poRoot,
139
                                   const char *pszPath, const char *pszDefault);
140
CPLXMLNode CPL_DLL *CPLCreateXMLNode(CPLXMLNode *poParent, CPLXMLNodeType eType,
141
                                     const char *pszText);
142
char CPL_DLL *CPLSerializeXMLTree(const CPLXMLNode *psNode);
143
void CPL_DLL CPLAddXMLChild(CPLXMLNode *psParent, CPLXMLNode *psChild);
144
int CPL_DLL CPLRemoveXMLChild(CPLXMLNode *psParent, CPLXMLNode *psChild);
145
void CPL_DLL CPLAddXMLSibling(CPLXMLNode *psOlderSibling,
146
                              CPLXMLNode *psNewSibling);
147
CPLXMLNode CPL_DLL *CPLCreateXMLElementAndValue(CPLXMLNode *psParent,
148
                                                const char *pszName,
149
                                                const char *pszValue);
150
void CPL_DLL CPLAddXMLAttributeAndValue(CPLXMLNode *psParent,
151
                                        const char *pszName,
152
                                        const char *pszValue);
153
CPLXMLNode CPL_DLL *CPLCloneXMLTree(const CPLXMLNode *psTree);
154
int CPL_DLL CPLSetXMLValue(CPLXMLNode *psRoot, const char *pszPath,
155
                           const char *pszValue);
156
void CPL_DLL CPLStripXMLNamespace(CPLXMLNode *psRoot, const char *pszNameSpace,
157
                                  int bRecurse);
158
void CPL_DLL CPLCleanXMLElementName(char *);
159
160
CPLXMLNode CPL_DLL *CPLParseXMLFile(const char *pszFilename);
161
int CPL_DLL CPLSerializeXMLTreeToFile(const CPLXMLNode *psTree,
162
                                      const char *pszFilename);
163
164
size_t CPL_DLL CPLXMLNodeGetRAMUsageEstimate(const CPLXMLNode *psNode);
165
166
CPL_C_END
167
168
#if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
169
170
extern "C++"
171
{
172
#ifndef DOXYGEN_SKIP
173
#include <memory>
174
#endif
175
176
    /*! @cond Doxygen_Suppress */
177
    struct CPL_DLL CPLXMLTreeCloserDeleter
178
    {
179
        void operator()(CPLXMLNode *psNode) const
180
0
        {
181
0
            CPLDestroyXMLNode(psNode);
182
0
        }
183
    };
184
185
    /*! @endcond */
186
187
    /** Manage a tree of XML nodes so that all nodes are freed when the instance
188
     * goes out of scope.  Only the top level node should be in a
189
     * CPLXMLTreeCloser.
190
     */
191
    class CPL_DLL CPLXMLTreeCloser
192
        : public std::unique_ptr<CPLXMLNode, CPLXMLTreeCloserDeleter>
193
    {
194
      public:
195
        /** Constructor */
196
        explicit CPLXMLTreeCloser(CPLXMLNode *data)
197
0
            : std::unique_ptr<CPLXMLNode, CPLXMLTreeCloserDeleter>(data)
198
0
        {
199
0
        }
200
201
        /** Returns a pointer to the document (root) element
202
         * @return the node pointer */
203
        CPLXMLNode *getDocumentElement();
204
    };
205
206
}  // extern "C++"
207
208
#endif /* __cplusplus */
209
210
#endif /* CPL_MINIXML_H_INCLUDED */