Subversion Repositories tpanel

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
74 andreas 1
/*
2
 * Copyright (C) 2021 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
{
75 andreas 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
 
74 andreas 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;
75 andreas 55
        _ETYPE_t eType;
74 andreas 56
    }_ELEMENT_t;
57
 
58
    /**
75 andreas 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
    /**
74 andreas 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
            /**
75 andreas 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
            /**
74 andreas 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();
75 andreas 135
 
74 andreas 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
             */
77 andreas 147
            std::string getElement(const std::string& name, int depth, bool *valid=nullptr);
74 andreas 148
            /**
75 andreas 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.
77 andreas 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.
75 andreas 164
             *
77 andreas 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
             *
75 andreas 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
            /**
76 andreas 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.
75 andreas 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
             *
76 andreas 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
             *
75 andreas 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
            /**
76 andreas 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.
75 andreas 258
             *
76 andreas 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
             *
75 andreas 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
            /**
76 andreas 279
             * @brief Retrieves the first element with the name \p name.
74 andreas 280
             *
76 andreas 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
             *
74 andreas 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
             *
76 andreas 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
             *
74 andreas 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
             */
77 andreas 311
            std::string getNextElement(const std::string& name, int depth, bool *valid=nullptr);
75 andreas 312
            /**
313
             * Retrieves the next element in the list. This method depends on
314
             * the method getFirstElement(), which must be called previous.
315
             *
76 andreas 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
             *
75 andreas 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
             *
348
             * @return On success returns the content of the attribute \p name
349
             * as an integer value.
350
             * Otherwise an error text is set (TError) and 0 is returned.
351
             */
352
            int getAttributeInt(const std::string& name, std::vector<ATTRIBUTE_t>& attrs);
353
            /**
354
             * Searches in the attribute list of an attribute called \p name
355
             * and returns the content.
356
             *
357
             * @param name  The name of the wanted attribute.
358
             * @param attrs A vector list of attributes.
359
             *
360
             * @return On success returns the content of the attribute \p name
361
             * as a long value.
362
             * Otherwise an error text is set (TError) and 0 is returned.
363
             */
364
            long getAttributeLong(const std::string& name, std::vector<ATTRIBUTE_t>& attrs);
365
            /**
366
             * Searches in the attribute list of an attribute called \p name
367
             * and returns the content.
368
             *
369
             * @param name  The name of the wanted attribute.
370
             * @param attrs A vector list of attributes.
371
             *
372
             * @return On success returns the content of the attribute \p name
373
             * as a floating value.
374
             * Otherwise an error text is set (TError) and 0 is returned.
375
             */
376
            float getAttributeFloat(const std::string& name, std::vector<ATTRIBUTE_t>& attrs);
377
            /**
378
             * Searches in the attribute list of an attribute called \p name
379
             * and returns the content.
380
             *
381
             * @param name  The name of the wanted attribute.
382
             * @param attrs A vector list of attributes.
383
             *
384
             * @return On success returns the content of the attribute \p name
385
             * as a double precission floating value.
386
             * Otherwise an error text is set (TError) and 0 is returned.
387
             */
388
            double getAttributeDouble(const std::string& name, std::vector<ATTRIBUTE_t>& attrs);
389
            /**
390
             * Converts a string into an integer value.
391
             *
392
             * @param content   A string containing numbers.
393
             * @return On success returns the value representation of the
394
             * \p content. If not convertable, TError is set and 0 is returned.
395
             */
396
            int convertElementToInt(const std::string& content);
397
            /**
398
             * Converts a string into a long integer value.
399
             *
400
             * @param content   A string containing numbers.
401
             * @return On success returns the value representation of the
402
             * \p content. If not convertable, TError is set and 0 is returned.
403
             */
404
            long convertElementToLong(const std::string& content);
405
            /**
406
             * Converts a string into a floating value.
407
             *
408
             * @param content   A string containing numbers.
409
             * @return On success returns the value representation of the
410
             * \p content. If not convertable, TError is set and 0 is returned.
411
             */
412
            float convertElementToFloat(const std::string& content);
413
            /**
414
             * Converts a string into a double floating value.
415
             *
416
             * @param content   A string containing numbers.
417
             * @return On success returns the value representation of the
418
             * \p content. If not convertable, TError is set and 0 is returned.
419
             */
420
            double convertElementToDouble(const std::string& content);
421
            /**
422
             * Sets the internal pointer to the \p index. If this points to an
423
             * invalid index, the method sets an error and returns FALSE.
424
             *
425
             * @param index The index into the internal XML list.
426
             * @return On success it returns TRUE.
427
             */
428
            bool setIndex(size_t index);
429
            /**
430
             * Retrieves the attribute list from the current position.
431
             *
432
             * @return On success the attributes of the current position are
433
             * returned. If the current position is at the end or doesn't
434
             * has attributes, an empty list is returned.
435
             */
436
            std::vector<ATTRIBUTE_t> getAttributes();
437
            /**
438
             * Retrieves the attribute list from the \p index.
439
             *
440
             * @return On success the attributes of the position \p index are
441
             * returned. If the position \p index is at the end or doesn't
442
             * has attributes, an empty list is returned.
443
             */
444
            std::vector<ATTRIBUTE_t> getAttributes(size_t index);
74 andreas 445
 
78 andreas 446
            /**
447
             * Checks whether the internal pointer points to a valid entry or
448
             * not. If the internal pointer is valid it returns the name of the
449
             * entity the pointer points to.
450
             *
451
             * @param valid This is an optional parameter. If this is set, then
452
             * it is set to TRUE when the method succeeds and to FALSE
453
             * otherwise.
454
             *
455
             * @return On success it returns the name of the entity and set the
456
             * parameter \p valid to TRUE. On error it returns an empty string
457
             * and sets the parameter \p valid to FALSE.
458
             */
459
            std::string getElementName(bool *valid=nullptr);
460
            /**
461
             * Checks whether the internal pointer points to a valid entry or
462
             * not. If the internal pointer is valid it returns the content of
463
             * the entity the pointer points to.
464
             *
465
             * @param valid This is an optional parameter. If this is set, then
466
             * it is set to TRUE when the method succeeds and to FALSE
467
             * otherwise.
468
             *
469
             * @return On success it returns the content of the entity and set
470
             * the parameter \p valid to TRUE. On error it returns an empty
471
             * string and sets the parameter \p valid to FALSE.
472
             */
473
            std::string getElementContent(bool *valid=nullptr);
474
            /**
475
             * Checks whether the internal pointer points to a valid entry or
476
             * not. If the internal pointer is valid it returns the content of
477
             * the entity converted to an integer.
478
             *
479
             * @param valid This is an optional parameter. If this is set, then
480
             * it is set to TRUE when the method succeeds and to FALSE
481
             * otherwise.
482
             *
483
             * @return On success it returns the content of the entity converted
484
             * to an integer and set  the parameter \p valid to TRUE. On error
485
             * it returns an empty string and sets the parameter \p valid to
486
             * FALSE.
487
             */
488
            int getElementContentInt(bool *valid=nullptr);
489
            /**
490
             * Checks whether the internal pointer points to a valid entry or
491
             * not. If the internal pointer is valid it returns the content of
492
             * the entity converted to a long.
493
             *
494
             * @param valid This is an optional parameter. If this is set, then
495
             * it is set to TRUE when the method succeeds and to FALSE
496
             * otherwise.
497
             *
498
             * @return On success it returns the content of the entity converted
499
             * to a long and set  the parameter \p valid to TRUE. On error
500
             * it returns an empty string and sets the parameter \p valid to
501
             * FALSE.
502
             */
503
            long getElementContentLong(bool *valid=nullptr);
504
            /**
505
             * Checks whether the internal pointer points to a valid entry or
506
             * not. If the internal pointer is valid it returns the content of
507
             * the entity converted to a floating value.
508
             *
509
             * @param valid This is an optional parameter. If this is set, then
510
             * it is set to TRUE when the method succeeds and to FALSE
511
             * otherwise.
512
             *
513
             * @return On success it returns the content of the entity converted
514
             * to a float and set  the parameter \p valid to TRUE. On error
515
             * it returns an empty string and sets the parameter \p valid to
516
             * FALSE.
517
             */
518
            float getElementContentFloat(bool *valid=nullptr);
519
            /**
520
             * Checks whether the internal pointer points to a valid entry or
521
             * not. If the internal pointer is valid it returns the content of
522
             * the entity converted to a double.
523
             *
524
             * @param valid This is an optional parameter. If this is set, then
525
             * it is set to TRUE when the method succeeds and to FALSE
526
             * otherwise.
527
             *
528
             * @return On success it returns the content of the entity converted
529
             * to a double and set  the parameter \p valid to TRUE. On error
530
             * it returns an empty string and sets the parameter \p valid to
531
             * FALSE.
532
             */
533
            double getElementContentDouble(bool *valid=nullptr);
534
 
75 andreas 535
            static const size_t npos = static_cast<size_t>(-1); //!< Marks an invalid index
536
 
74 andreas 537
        protected:
75 andreas 538
            static void startElement(void* userData, const XML_Char* name, const XML_Char** attrs);
74 andreas 539
            static void XMLCALL endElement(void *userData, const XML_Char *name);
75 andreas 540
            static void XMLCALL CharacterDataHandler(void *, const XML_Char *s, int len);
541
            static int cp1250_encoding_handler(void*, const XML_Char* encoding, XML_Encoding* info);
74 andreas 542
 
543
        private:
75 andreas 544
            static void createCP1250Encoding(XML_Encoding *enc);    //!< Internal handler to handle CP1250 encoded files.
545
 
74 andreas 546
            std::string mFile;                                      //!< The name of a file containing the XML code to parse
547
            std::vector<_ELEMENT_t> mElements;                      //!< The list of elemets in the order they appeared
548
            std::vector<_ELEMENT_t>::iterator mLastIter{mElements.end()};   //!< The pointer to the last iterator
75 andreas 549
            std::string mEncoding{"UTF-8"};                         //!< Encoding of the XML file. UTF-8 is default encoding.
550
            TENCODING_t mSetEncoding{ENC_UTF8};                     //!< Encoding of the XML file. UTF-8 is default encoding.
82 andreas 551
//            int mLastDepth{0};                                      //!< The depth of the last found element.
74 andreas 552
            // Variables used for the static methods
553
            static int mDepth;
554
            static std::string mContent;
555
            static std::string mLastName;
556
            static std::vector<_ATTRIBUTE_t> mAttributes;
557
    };
558
}
559
 
560
#endif