Subversion Repositories tpanel

Rev

Rev 446 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
446 andreas 1
/*
2
 * Copyright (C) 2022 by Andreas Theofilu <andreas@theosys.at>
3
 *
4
 * This program is free software; you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program; if not, write to the Free Software Foundation,
16
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
17
 */
18
 
19
#ifndef __TEXPATPP_H__
20
#define __TEXPATPP_H__
21
 
22
#include <string>
23
#include <vector>
24
 
25
#include <expat.h>
26
#include "tvalidatefile.h"
27
 
28
namespace Expat
29
{
30
    /**
31
     * @enum _ETYPE_t
32
     * @brief Internal used type identifier for elements.
33
     */
34
    typedef enum _ETYPE_t
35
    {
36
        _ET_START,      //!< Element is a start element. Other elements with a bigger depth follow.
37
        _ET_END,        //!< Element is an end element. Other elements with a bigger depth are before.
38
        _ET_ATOMIC      //!< Element is a single one which starts and stop in one line.
39
    }_ETYPE_t;
40
 
41
    typedef struct _ATTRIBUTE_t
42
    {
43
        std::string name;
44
        std::string content;
45
    }_ATTRIBUTE_t;
46
 
47
    typedef _ATTRIBUTE_t ATTRIBUTE_t;
48
 
49
    typedef struct _ELEMENT_t
50
    {
51
        std::string name;
52
        int depth;
53
        std::string content;
54
        std::vector<_ATTRIBUTE_t> attrs;
55
        _ETYPE_t eType;
56
    }_ELEMENT_t;
57
 
58
    /**
59
     * @enum TENCODING_t
60
     * @brief Defines the possible integrated encodings.
61
     * If the encoding is not ENC_UTF8 it must be set before the parser is
62
     * started. The encoding defines the character set used for the XML file.
63
     * If the XML file is encoded in a different character set than defined,
64
     * it may lead into parsing errors.
65
     */
66
    typedef enum TENCODING_t
67
    {
68
        ENC_UNKNOWN,        //!< Unknown encoding. This is equal with ENC_UTF8
69
        ENC_UTF8,           //!< Default encoding if not defined elsewhere
70
        ENC_UTF16,          //!< UTF16 encoding.
71
        ENC_ISO_8859_1,     //!< ISO-8859-1 encoding.
72
        ENC_CP1250,         //!< CP1250 (Windows) character set.
73
        ENC_US_ASCII        //!< US-ASCII encoding.
74
    }TENCODING_t;
75
 
76
    /**
77
    * @class TExpat
78
    * @brief C++ wrapper class for the XML parser expat.
79
    *
80
    * This class is a small C++ wrapper for the XML parser expat. Expat is part of
81
    * *NIX system and also in the NDK of Android. Therefor it is used in this
82
    * project.
83
    */
84
    class TExpat : public TValidateFile
85
    {
86
        public:
87
            /**
88
            * Constructor.
89
            */
90
            TExpat();
91
            /**
92
            * Constructor.
93
            *
94
            * @param file  The file name of a file containing the XML code to parse.
95
            */
96
            TExpat(const std::string& file);
97
            /**
98
            * Destructor.
99
            */
100
            ~TExpat();
101
 
102
            /**
103
             * @brief Sets the file to parse.
104
             * This method does not check the file. If it is invalid, the parser
105
             * will fail.
106
             *
107
             * @param file  The file to parse.
108
             */
109
            void setFile(const std::string& file) { mFile = file; }
110
            /**
111
             * @brief Set the encoding of the XML file.
112
             * By default UTF8 encoding is assumed if not explicitely defined
113
             * in the XML file. If there is an encoding defination in the XML
114
             * file like:
115
             *
116
             *  <?xml version="1.0" encoding="ISO-8859-2"?>
117
             *
118
             * for example, than this encoding is used by default.
119
             *
120
             * This method sets the encoding to one of the supported encodings.
121
             * If the XML file is encoded in another character set as defined,
122
             * than it may come to errors during parsing!
123
             *
124
             * @param enc   Encoding to be used for parsing the XML file.
125
             */
126
            void setEncoding(TENCODING_t enc);
127
            /**
128
             * @brief Starts the XML parser.
129
             * This method invoke the XML parser. If any error occure and error
130
             * message is logged and the error handler is set.
131
             *
132
             * @return On success it returns TRUE and FALSE otherwise.
133
             */
134
            bool parse(bool debug=false);
135
 
136
            /**
137
             * Retrieves the first element with the name \p name at the depth
138
             * \p depth.
139
             *
140
             * @param name  The name of the wanted element. This is case
141
             * sensitive!
142
             * @param depth The depth where the element is.
143
             *
144
             * @return On success the content of the element is returned.
145
             * Otherwise an empty string is returned.
146
             */
147
            std::string getElement(const std::string& name, int depth, bool *valid=nullptr);
148
            /**
149
             * Retrieves the first element with the name \p name at the depth
150
             * \p depth.
151
             *
152
             * @param name  The name of the wanted element. This is case
153
             * sensitive!
154
             * @param depth The depth where the element is.
155
             * @param valid An optional pointer retrieving the state of the
156
             * search. On success it returns TRUE, otherwise FALSE.
157
             * @return On success the content of the element is returned as an
158
             * integer. Otherwise 0 is returned and \p valid is set to FALSE.
159
             */
160
            int getElementInt(const std::string& name, int depth, bool *valid=nullptr);
161
            /**
162
             * Retrieves the first element with the name \p name at the depth
163
             * \p depth.
164
             *
165
             * @param name  The name of the wanted element. This is case
166
             * sensitive!
167
             * @param depth The depth where the element is.
168
             * @param valid An optional pointer retrieving the state of the
169
             * search. On success it returns TRUE, otherwise FALSE.
170
             * @return On success the content of the element is returned as a
171
             * long integer. Otherwise 0 is returned and \p valid is set to FALSE.
172
             */
173
            long getElementLong(const std::string& name, int depth, bool *valid=nullptr);
174
            /**
175
             * Retrieves the first element with the name \p name at the depth
176
             * \p depth.
177
             *
178
             * @param name  The name of the wanted element. This is case
179
             * sensitive!
180
             * @param depth The depth where the element is.
181
             * @param valid An optional pointer retrieving the state of the
182
             * search. On success it returns TRUE, otherwise FALSE.
183
             * @return On success the content of the element is returned as a
184
             * floating value. Otherwise 0 is returned and \p valid is set to FALSE.
185
             */
186
            float getElementFloat(const std::string& name, int depth, bool *valid=nullptr);
187
            /**
188
             * Retrieves the first element with the name \p name at the depth
189
             * \p depth.
190
             *
191
             * @param name  The name of the wanted element. This is case
192
             * sensitive!
193
             * @param depth The depth where the element is.
194
             * @param valid An optional pointer retrieving the state of the
195
             * search. On success it returns TRUE, otherwise FALSE.
196
             * @return On success the content of the element is returned as a
197
             * double value. Otherwise 0 is returned and \p valid is set to FALSE.
198
             */
199
            double getElementDouble(const std::string& name, int depth, bool *valid=nullptr);
200
            /**
201
             * Retrieves the first element with the name \p name at the depth
202
             * \p depth.
203
             *
204
             * @param name  The name of the wanted element. This is case
205
             * sensitive!
206
             * @param depth The depth where the element is.
207
             *
208
             * @return On success returns the index of the element found.
209
             * Otherwise TExpat::npos is returned.
210
             */
211
            size_t getElementIndex(const std::string& name, int depth);
212
            /**
213
             * @brief Retrieves the first element with the name \p name.
214
             * This method saves the found position internally. If no matching
215
             * entity was found, the internal position is set to an invalid
216
             * position.
217
             *
218
             * @param name  The name of the wanted element. This is case
219
             * sensitive!
220
             * @param depth This parameter is optional and can be NULL. If it is
221
             * present, the method returns the depth of the found element with
222
             * this parameter. If the element was not found, this parameter
223
             * will contain -1.
224
             *
225
             * @return On success returns the index of the element found.
226
             * Otherwise TExpat::npos is returned.
227
             */
228
            size_t getElementIndex(const std::string& name, int *depth);
229
            /**
230
             * Retrieves the \p name, the \p content and the attributes of the
231
             * element. If the element has no attributes, an empty attribute
232
             * list is returned.
233
             *
234
             * This method does not set the internal position. This means that
235
             * a method depending on the internal position like getNextElement()
236
             * will not succeed or return the content of another entity!
237
             *
238
             * @param index The index of the element. This value may be
239
             * retrieved by calling previously the method getElementIndex().
240
             * @param name  This parameter can be NULL. If it is present, the
241
             * name of the element is returned.
242
             * @param content   This parameter can be NULL. If it is present,
243
             * the content of the element is returned. If there was no content,
244
             * an empty string is returned.
245
             * @param attrs This parameter can be NULL. If it is present and if
246
             * the element contains at least 1 attribute, the attributes are
247
             * returned in the vector.
248
             *
249
             * @return If a valid element was found, the index is returned.
250
             * Otherwise TExpat::npos will be returned.
251
             */
252
            size_t getElementFromIndex(size_t index, std::string *name, std::string *content, std::vector<ATTRIBUTE_t> *attrs);
253
            /**
254
             * @brief Retrieves the next element from the given index \p index.
255
             * The method succeeds if the next element is not an end tag or if
256
             * \p index is less than the number of total elements. The method
257
             * increases the index by 1 and returns this entity.
258
             *
259
             * This method does not set the internal position. This means that
260
             * a method depending on the internal position like getNextElement()
261
             * will not succeed or return the content of another entity!
262
             *
263
             * @param index The index of the element. This value may be
264
             * retrieved by calling previously the method getElementIndex().
265
             * @param name  This parameter can be NULL. If it is present, the
266
             * name of the element is returned.
267
             * @param content   This parameter can be NULL. If it is present,
268
             * the content of the element is returned. If there was no content,
269
             * an empty string is returned.
270
             * @param attrs This parameter can be NULL. If it is present and if
271
             * the element contains at least 1 attribute, the attributes are
272
             * returned in the vector.
273
             *
274
             * @return If a valid element was found, the index is returned.
275
             * Otherwise TExpat::npos will be returned.
276
             */
277
            size_t getNextElementFromIndex(size_t index, std::string *name, std::string *content, std::vector<ATTRIBUTE_t> *attrs);
278
            /**
279
             * @brief Retrieves the first element with the name \p name.
280
             *
281
             * This method saves the found position internally. If no matching
282
             * entity was found, the internal position is set to an invalid
283
             * position.
284
             *
285
             * @param name  The name of the wanted element.
286
             * @param depth A pointer to an integer. The method returns the
287
             * depth of the found element in this parameter.
288
             *
289
             * @return On success the content of the element is returned, if
290
             * any. Otherwise an error is logged and an empty string is returned.
291
             * The parameter \p depth is set to -1 on error.
292
             */
293
            std::string getFirstElement(const std::string& name, int *depth);
294
            /**
295
             * Retrieves the next element in the list. This method depends on
296
             * the method getFirstElement(), which must be called previous.
297
             *
298
             * This method saves the found position internally. If no matching
299
             * entity was found, the internal position is set to an invalid
300
             * position.
301
             *
302
             * @param name  The name of the element to search for. This
303
             * parameter is optional and may be NULL.
304
             * @param depth The depth of the element to return. If there are
305
             * no more elements with the name \p name and the depth \p depth
306
             * than an empty string is returned.
307
             *
308
             * @return On success the content of the element is returned. If
309
             * an error occurs an error message is logged and the error is set.
310
             */
311
            std::string getNextElement(const std::string& name, int depth, bool *valid=nullptr);
312
            /**
313
             * Retrieves the next element in the list. This method depends on
314
             * the method getFirstElement(), which must be called previous.
315
             *
316
             * This method saves the found position internally. If no matching
317
             * entity was found, the internal position is set to an invalid
318
             * position.
319
             *
320
             * @param name  The name of the element to search for. This
321
             * parameter is optional and may be NULL.
322
             * @param depth The depth of the element to return. If there are
323
             * no more elements with the name \p name and the depth \p depth
324
             * than an empty string is returned.
325
             *
326
             * @return On success the index of the element is returned. If
327
             * an error occurs an error message is logged and the error is set.
328
             */
329
            size_t getNextElementIndex(const std::string& name, int depth);
330
            /**
331
             * Searches in the attribute list of an attribute called \p name
332
             * and returns the content.
333
             *
334
             * @param name  The name of the wanted attribute.
335
             * @param attrs A vector list of attributes.
336
             *
337
             * @return On success returns the content of the attribute \p name.
338
             * Otherwise an empty string is returned.
339
             */
340
            std::string getAttribute(const std::string& name, std::vector<ATTRIBUTE_t>& attrs);
341
            /**
342
             * Searches in the attribute list of an attribute called \p name
343
             * and returns the content.
344
             *
345
             * @param name  The name of the wanted attribute.
346
             * @param attrs A vector list of attributes.
347
             *
480 andreas 348
             * @return On success returns TRUE or FALSE depending on the
349
             * content.
350
             */
351
            bool getAttributeBool(const std::string& name, std::vector<ATTRIBUTE_t>& attrs);
352
            /**
353
             * Searches in the attribute list of an attribute called \p name
354
             * and returns the content.
355
             *
356
             * @param name  The name of the wanted attribute.
357
             * @param attrs A vector list of attributes.
358
             *
446 andreas 359
             * @return On success returns the content of the attribute \p name
360
             * as an integer value.
361
             * Otherwise an error text is set (TError) and 0 is returned.
362
             */
363
            int getAttributeInt(const std::string& name, std::vector<ATTRIBUTE_t>& attrs);
364
            /**
365
             * Searches in the attribute list of an attribute called \p name
366
             * and returns the content.
367
             *
368
             * @param name  The name of the wanted attribute.
369
             * @param attrs A vector list of attributes.
370
             *
371
             * @return On success returns the content of the attribute \p name
372
             * as a long value.
373
             * Otherwise an error text is set (TError) and 0 is returned.
374
             */
375
            long getAttributeLong(const std::string& name, std::vector<ATTRIBUTE_t>& attrs);
376
            /**
377
             * Searches in the attribute list of an attribute called \p name
378
             * and returns the content.
379
             *
380
             * @param name  The name of the wanted attribute.
381
             * @param attrs A vector list of attributes.
382
             *
383
             * @return On success returns the content of the attribute \p name
384
             * as a floating value.
385
             * Otherwise an error text is set (TError) and 0 is returned.
386
             */
387
            float getAttributeFloat(const std::string& name, std::vector<ATTRIBUTE_t>& attrs);
388
            /**
389
             * Searches in the attribute list of an attribute called \p name
390
             * and returns the content.
391
             *
392
             * @param name  The name of the wanted attribute.
393
             * @param attrs A vector list of attributes.
394
             *
395
             * @return On success returns the content of the attribute \p name
396
             * as a double precission floating value.
397
             * Otherwise an error text is set (TError) and 0 is returned.
398
             */
399
            double getAttributeDouble(const std::string& name, std::vector<ATTRIBUTE_t>& attrs);
400
            /**
480 andreas 401
             * Converts a string into a boolean.
402
             *
403
             * @param content   A string containing numbers.
404
             * @return Returns the boolean value.
405
             */
406
            bool convertElementToBool(const std::string& content);
407
            /**
446 andreas 408
             * Converts a string into an integer value.
409
             *
410
             * @param content   A string containing numbers.
411
             * @return On success returns the value representation of the
412
             * \p content. If not convertable, TError is set and 0 is returned.
413
             */
414
            int convertElementToInt(const std::string& content);
415
            /**
416
             * Converts a string into a long integer value.
417
             *
418
             * @param content   A string containing numbers.
419
             * @return On success returns the value representation of the
420
             * \p content. If not convertable, TError is set and 0 is returned.
421
             */
422
            long convertElementToLong(const std::string& content);
423
            /**
424
             * Converts a string into a floating value.
425
             *
426
             * @param content   A string containing numbers.
427
             * @return On success returns the value representation of the
428
             * \p content. If not convertable, TError is set and 0 is returned.
429
             */
430
            float convertElementToFloat(const std::string& content);
431
            /**
432
             * Converts a string into a double floating value.
433
             *
434
             * @param content   A string containing numbers.
435
             * @return On success returns the value representation of the
436
             * \p content. If not convertable, TError is set and 0 is returned.
437
             */
438
            double convertElementToDouble(const std::string& content);
439
            /**
440
             * Sets the internal pointer to the \p index. If this points to an
441
             * invalid index, the method sets an error and returns FALSE.
442
             *
443
             * @param index The index into the internal XML list.
444
             * @return On success it returns TRUE.
445
             */
446
            bool setIndex(size_t index);
447
            /**
448
             * Retrieves the attribute list from the current position.
449
             *
450
             * @return On success the attributes of the current position are
451
             * returned. If the current position is at the end or doesn't
452
             * has attributes, an empty list is returned.
453
             */
454
            std::vector<ATTRIBUTE_t> getAttributes();
455
            /**
456
             * Retrieves the attribute list from the \p index.
457
             *
458
             * @return On success the attributes of the position \p index are
459
             * returned. If the position \p index is at the end or doesn't
460
             * has attributes, an empty list is returned.
461
             */
462
            std::vector<ATTRIBUTE_t> getAttributes(size_t index);
463
 
464
            /**
465
             * Checks whether the internal pointer points to a valid entry or
466
             * not. If the internal pointer is valid it returns the name of the
467
             * entity the pointer points to.
468
             *
469
             * @param valid This is an optional parameter. If this is set, then
470
             * it is set to TRUE when the method succeeds and to FALSE
471
             * otherwise.
472
             *
473
             * @return On success it returns the name of the entity and set the
474
             * parameter \p valid to TRUE. On error it returns an empty string
475
             * and sets the parameter \p valid to FALSE.
476
             */
477
            std::string getElementName(bool *valid=nullptr);
478
            /**
479
             * Checks whether the internal pointer points to a valid entry or
480
             * not. If the internal pointer is valid it returns the content of
481
             * the entity the pointer points to.
482
             *
483
             * @param valid This is an optional parameter. If this is set, then
484
             * it is set to TRUE when the method succeeds and to FALSE
485
             * otherwise.
486
             *
487
             * @return On success it returns the content of the entity and set
488
             * the parameter \p valid to TRUE. On error it returns an empty
489
             * string and sets the parameter \p valid to FALSE.
490
             */
491
            std::string getElementContent(bool *valid=nullptr);
492
            /**
493
             * Checks whether the internal pointer points to a valid entry or
494
             * not. If the internal pointer is valid it returns the content of
495
             * the entity converted to an integer.
496
             *
497
             * @param valid This is an optional parameter. If this is set, then
498
             * it is set to TRUE when the method succeeds and to FALSE
499
             * otherwise.
500
             *
501
             * @return On success it returns the content of the entity converted
502
             * to an integer and set  the parameter \p valid to TRUE. On error
503
             * it returns an empty string and sets the parameter \p valid to
504
             * FALSE.
505
             */
506
            int getElementContentInt(bool *valid=nullptr);
507
            /**
508
             * Checks whether the internal pointer points to a valid entry or
509
             * not. If the internal pointer is valid it returns the content of
510
             * the entity converted to a long.
511
             *
512
             * @param valid This is an optional parameter. If this is set, then
513
             * it is set to TRUE when the method succeeds and to FALSE
514
             * otherwise.
515
             *
516
             * @return On success it returns the content of the entity converted
517
             * to a long and set  the parameter \p valid to TRUE. On error
518
             * it returns an empty string and sets the parameter \p valid to
519
             * FALSE.
520
             */
521
            long getElementContentLong(bool *valid=nullptr);
522
            /**
523
             * Checks whether the internal pointer points to a valid entry or
524
             * not. If the internal pointer is valid it returns the content of
525
             * the entity converted to a floating value.
526
             *
527
             * @param valid This is an optional parameter. If this is set, then
528
             * it is set to TRUE when the method succeeds and to FALSE
529
             * otherwise.
530
             *
531
             * @return On success it returns the content of the entity converted
532
             * to a float and set  the parameter \p valid to TRUE. On error
533
             * it returns an empty string and sets the parameter \p valid to
534
             * FALSE.
535
             */
536
            float getElementContentFloat(bool *valid=nullptr);
537
            /**
538
             * Checks whether the internal pointer points to a valid entry or
539
             * not. If the internal pointer is valid it returns the content of
540
             * the entity converted to a double.
541
             *
542
             * @param valid This is an optional parameter. If this is set, then
543
             * it is set to TRUE when the method succeeds and to FALSE
544
             * otherwise.
545
             *
546
             * @return On success it returns the content of the entity converted
547
             * to a double and set  the parameter \p valid to TRUE. On error
548
             * it returns an empty string and sets the parameter \p valid to
549
             * FALSE.
550
             */
551
            double getElementContentDouble(bool *valid=nullptr);
552
 
553
            static const size_t npos = static_cast<size_t>(-1); //!< Marks an invalid index
554
 
555
        protected:
556
            static void startElement(void* userData, const XML_Char* name, const XML_Char** attrs);
557
            static void XMLCALL endElement(void *userData, const XML_Char *name);
558
            static void XMLCALL CharacterDataHandler(void *, const XML_Char *s, int len);
559
            static int cp1250_encoding_handler(void*, const XML_Char* encoding, XML_Encoding* info);
560
 
561
        private:
562
            static void createCP1250Encoding(XML_Encoding *enc);    //!< Internal handler to handle CP1250 encoded files.
563
 
564
            std::string mFile;                                      //!< The name of a file containing the XML code to parse
565
            std::vector<_ELEMENT_t> mElements;                      //!< The list of elemets in the order they appeared
566
            std::vector<_ELEMENT_t>::iterator mLastIter{mElements.end()};   //!< The pointer to the last iterator
567
            std::string mEncoding{"UTF-8"};                         //!< Encoding of the XML file. UTF-8 is default encoding.
568
            TENCODING_t mSetEncoding{ENC_UTF8};                     //!< Encoding of the XML file. UTF-8 is default encoding.
569
//            int mLastDepth{0};                                      //!< The depth of the last found element.
570
            // Variables used for the static methods
571
            static int mDepth;
572
            static std::string mContent;
573
            static std::string mLastName;
574
            static std::vector<_ATTRIBUTE_t> mAttributes;
575
    };
576
}
577
 
578
#endif