Subversion Repositories tpanel

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
74 andreas 1
/*
137 andreas 2
 * Copyright (C) 2022 by Andreas Theofilu <andreas@theosys.at>
74 andreas 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
#include <fstream>
407 andreas 20
#include <iomanip>
74 andreas 21
 
75 andreas 22
#include <string.h>
23
 
74 andreas 24
#include "texpat++.h"
25
#include "terror.h"
26
 
27
using namespace Expat;
28
using std::string;
29
using std::vector;
30
using std::ifstream;
31
 
32
int TExpat::mDepth = 0;
33
string TExpat::mContent;
34
string TExpat::mLastName;
35
vector<_ATTRIBUTE_t> TExpat::mAttributes;
36
 
37
TExpat::TExpat()
38
{
39
    DECL_TRACER("TExpat::TExpat()");
40
}
41
 
42
TExpat::TExpat(const std::string &file)
43
    : mFile(file)
44
{
45
    DECL_TRACER("TExpat::TExpat(const std::string &file)");
78 andreas 46
 
47
    mLastIter = mElements.end();
74 andreas 48
}
49
 
50
TExpat::~TExpat()
51
{
52
    DECL_TRACER("TExpat::~TExpat()");
53
}
54
 
75 andreas 55
void TExpat::setEncoding(TENCODING_t enc)
56
{
57
    DECL_TRACER("TExpat::setEncoding(TENCODING_t enc)");
58
 
59
    mSetEncoding = enc;
60
 
61
    switch(enc)
62
    {
63
        case ENC_ISO_8859_1:    mEncoding = "ISO-8859-1"; break;
64
        case ENC_US_ASCII:      mEncoding = "US-ASCII"; break;
65
        case ENC_UTF16:         mEncoding = "UTF-16"; break;
66
        case ENC_CP1250:        mEncoding = "CP1250"; break;
67
 
68
        default:
69
            mEncoding = "UTF-8";
70
            mSetEncoding = ENC_UTF8;
71
    }
72
}
73
 
137 andreas 74
bool TExpat::parse(bool debug)
74 andreas 75
{
76
    DECL_TRACER("TExpat::parse()");
77
 
78
    if (!isValidFile(mFile))
79
    {
80
        MSG_ERROR("Invalid file: " << mFile);
81
        TError::setError();
82
        return false;
83
    }
84
 
85
    string buf;
86
    size_t size = 0;
87
 
88
    // First we read the whole XML file into a buffer
89
    try
90
    {
91
        ifstream stream(mFile, std::ios::in);
92
 
93
        if (!stream || !stream.is_open())
94
            return false;
95
 
96
        stream.seekg(0, stream.end);    // Find the end of the file
97
        size = stream.tellg();          // Get the position and save it
98
        stream.seekg(0, stream.beg);    // rewind to the beginning of the file
99
 
100
        buf.resize(size, '\0');         // Initialize the buffer with zeros
101
        char *begin = &*buf.begin();    // Assign the plain data buffer
102
        stream.read(begin, size);       // Read the whole file
103
        stream.close();                 // Close the file
104
    }
105
    catch (std::exception& e)
106
    {
107
        MSG_ERROR("File error: " << e.what());
108
        TError::setError();
109
        return false;
110
    }
111
 
112
    // Now we parse the file and write the relevant contents into our internal
113
    // variables.
114
    // First we initialialize the parser.
115
    int done = 1;   // 1 = Buffer is complete
116
    XML_Parser parser = XML_ParserCreate(NULL);
117
    XML_SetElementHandler(parser, &TExpat::startElement, &TExpat::endElement);
118
    XML_SetCharacterDataHandler(parser, &TExpat::CharacterDataHandler);
75 andreas 119
    XML_SetEncoding(parser, mEncoding.c_str());
74 andreas 120
    XML_SetUserData(parser, &mElements);
121
 
75 andreas 122
    if (mSetEncoding == ENC_CP1250)
123
        XML_SetUnknownEncodingHandler(parser, &TExpat::cp1250_encoding_handler, NULL);
124
 
125
    MSG_TRACE("Parsing XML file " << mFile);
126
 
74 andreas 127
    if (XML_Parse(parser, buf.data(), size, done) == XML_STATUS_ERROR)
128
    {
129
        MSG_ERROR(XML_ErrorString(XML_GetErrorCode(parser)) << " at line " << XML_GetCurrentLineNumber(parser));
130
        XML_ParserFree(parser);
131
        TError::setError();
132
        return false;
133
    }
134
 
135
    XML_ParserFree(parser);
137 andreas 136
 
137
    if (TStreamError::checkFilter(HLOG_DEBUG) && debug && mElements.size() > 0)
75 andreas 138
    {
139
        // Print out the whole XML file formatted
140
        vector<_ELEMENT_t>::iterator iter;
137 andreas 141
        size_t cnt = 0;
75 andreas 142
 
143
        for (iter = mElements.begin(); iter != mElements.end(); ++iter)
144
        {
145
            string sIndent;
146
 
147
            for (int i = 0; i < iter->depth; i++)
148
                sIndent += "   ";
149
 
137 andreas 150
            string attrs;
151
 
152
            if ((iter->eType == _ET_START || iter->eType == _ET_ATOMIC) && iter->attrs.size() > 0)
75 andreas 153
            {
137 andreas 154
                vector<ATTRIBUTE_t>::iterator atiter;
75 andreas 155
 
137 andreas 156
                for (atiter = iter->attrs.begin(); atiter != iter->attrs.end(); ++atiter)
75 andreas 157
                {
137 andreas 158
                    if (!attrs.empty())
159
                        attrs += " ";
75 andreas 160
 
137 andreas 161
                    attrs += atiter->name + " = \"" + atiter->content + "\"";
162
                }
163
            }
75 andreas 164
 
137 andreas 165
            if (iter->eType == _ET_START)
166
            {
167
                if (iter->attrs.size() > 0)
168
                {
169
                    MSG_DEBUG(std::setw(3) << std::setfill(' ') << "[" << cnt << "] (" << std::setw(0) << iter->depth << ") " << sIndent << "<" << iter->name << " " << attrs << ">");
75 andreas 170
                }
171
                else
172
                {
137 andreas 173
                    MSG_DEBUG(std::setw(3) << std::setfill(' ') << "[" << cnt << "] (" << std::setw(0) << iter->depth << ") " << sIndent << "<" << iter->name << ">");
75 andreas 174
                }
175
            }
176
            else if (iter->eType == _ET_ATOMIC)
177
            {
137 andreas 178
                if (iter->attrs.size() > 0)
179
                {
180
                    MSG_DEBUG(std::setw(3) << std::setfill(' ') << "[" << cnt << "] (" << std::setw(0) << iter->depth << ") " << sIndent << "<" << iter->name << " " << attrs << ">" << iter->content << "</" << iter->name << ">");
181
                }
182
                else
183
                {
184
                    MSG_DEBUG(std::setw(3) << std::setfill(' ') << "[" << cnt << "] (" << std::setw(0) << iter->depth << ") " << sIndent << "<" << iter->name << ">" << iter->content << "</" << iter->name << ">");
185
                }
75 andreas 186
            }
187
            else
188
            {
137 andreas 189
                MSG_DEBUG(std::setw(3) << std::setfill(' ') << "[" << cnt << "] (" << std::setw(0) << iter->depth << ") " << sIndent << "</" << iter->name << ">");
75 andreas 190
            }
137 andreas 191
 
192
            cnt++;
75 andreas 193
        }
194
    }
137 andreas 195
 
74 andreas 196
    return true;
197
}
198
 
77 andreas 199
string TExpat::getElement(const string &name, int depth, bool *valid)
74 andreas 200
{
201
    DECL_TRACER("TExpat::getElement(const string &name, int depth)");
202
 
78 andreas 203
    vector<_ELEMENT_t>::iterator iter, startElement;
204
    bool start = false;
74 andreas 205
 
323 andreas 206
    if (!mElements.empty() && mLastIter != mElements.end())
78 andreas 207
        startElement = mLastIter;
323 andreas 208
    else if (!mElements.empty())
88 andreas 209
        startElement = mElements.begin();
78 andreas 210
    else
88 andreas 211
    {
212
        MSG_DEBUG("Have no elements in queue!");
323 andreas 213
 
214
        if (valid)
215
            *valid = false;
216
 
88 andreas 217
        return string();
218
    }
78 andreas 219
 
220
    for (iter = startElement; iter != mElements.end(); ++iter)
74 andreas 221
    {
78 andreas 222
        if (!start && iter->depth == depth && iter->eType != _ET_END)
223
            start = true;
224
 
225
        if (start && iter->eType != _ET_END && iter->name.compare(name)  == 0 && iter->depth == depth)
77 andreas 226
        {
227
            if (valid)
228
                *valid = true;
229
 
74 andreas 230
            return iter->content;
77 andreas 231
        }
78 andreas 232
        else if (start && (iter->eType == _ET_END || iter->depth != depth))
233
            break;
74 andreas 234
    }
235
 
77 andreas 236
    if (valid)
237
        *valid = false;
238
 
74 andreas 239
    return string();
240
}
241
 
77 andreas 242
int TExpat::getElementInt(const string &name, int depth, bool *valid)
243
{
244
    DECL_TRACER("TExpat::getElementInt(const string &name, int depth, bool *valid)");
245
 
246
    bool val;
247
    string erg = getElement(name, depth, &val);
248
 
249
    if (valid)
250
        *valid = val;
251
 
252
    if (!val)
253
        return 0;
254
 
255
    return atoi(erg.c_str());
256
}
257
 
258
long TExpat::getElementLong(const string &name, int depth, bool *valid)
259
{
260
    DECL_TRACER("TExpat::getElementLong(const string &name, int depth, bool *valid)");
261
 
262
    bool val;
263
    string erg = getElement(name, depth, &val);
264
 
265
    if (valid)
266
        *valid = val;
267
 
268
    if (!val)
269
        return 0;
270
 
271
    return atol(erg.c_str());
272
}
273
 
274
float TExpat::getElementFloat(const string &name, int depth, bool *valid)
275
{
276
    DECL_TRACER("TExpat::getElementFloat(const string &name, int depth, bool *valid)");
277
 
278
    bool val;
279
    string erg = getElement(name, depth, &val);
280
 
281
    if (valid)
282
        *valid = val;
283
 
284
    if (!val)
285
        return 0;
286
 
287
    return (float)atof(erg.c_str());
288
}
289
 
290
double TExpat::getElementDouble(const string &name, int depth, bool *valid)
291
{
292
    DECL_TRACER("TExpat::getElementDouble(const string &name, int depth, bool *valid)");
293
 
323 andreas 294
    bool val = false;
77 andreas 295
    string erg = getElement(name, depth, &val);
296
 
297
    if (valid)
298
        *valid = val;
299
 
300
    if (!val)
301
        return 0;
302
 
303
    return atof(erg.c_str());
304
}
305
 
75 andreas 306
size_t TExpat::getElementIndex(const string& name, int depth)
307
{
308
    DECL_TRACER("TExpat::getElementIndex(const string& name, int depth)");
309
 
310
    vector<_ELEMENT_t>::iterator iter;
311
    size_t idx = 0;
312
 
88 andreas 313
    if (mElements.size() == 0)
314
    {
315
        mLastIter = mElements.end();
316
        return npos;
317
    }
318
 
75 andreas 319
    for (iter = mElements.begin(); iter != mElements.end(); ++iter)
320
    {
321
        if (iter->eType != _ET_END && iter->name.compare(name) == 0 && iter->depth == depth)
322
        {
323
            mLastIter = iter;
324
            return idx;
325
        }
326
 
327
        idx++;
328
    }
329
 
330
    mLastIter = mElements.end();
331
    return npos;
332
}
333
 
334
size_t TExpat::getElementIndex(const string& name, int* depth)
335
{
336
    DECL_TRACER("TExpat::getElementIndex(const string& name, int* depth)");
337
 
84 andreas 338
    if (mElements.size() == 0)
339
    {
340
        mLastIter = mElements.end();
341
        return npos;
342
    }
343
 
75 andreas 344
    vector<_ELEMENT_t>::iterator iter;
345
    size_t idx = 0;
346
 
347
    for (iter = mElements.begin(); iter != mElements.end(); ++iter)
348
    {
349
        if (iter->eType != _ET_END && iter->name.compare(name) == 0)
350
        {
351
            if (depth)
352
                *depth = iter->depth;
353
 
354
            mLastIter = iter;
355
            return idx;
356
        }
357
 
358
        idx++;
359
    }
360
 
361
    if (depth)
362
        *depth = -1;
363
 
364
    mLastIter = mElements.end();
365
    return npos;
366
}
367
 
368
size_t TExpat::getElementFromIndex(size_t index, string* name, string* content, vector<ATTRIBUTE_t> *attrs)
369
{
370
    DECL_TRACER("TExpat::getElementFromIndex(size_t index, string* name, string* content, vector<ATTRIBUTE_t> *attrs)");
371
 
372
    if (index == npos || index >= mElements.size() || mElements.at(index).eType == _ET_END)
373
        return npos;
374
 
375
    if (name)
376
        name->assign(mElements.at(index).name);
377
 
378
    if (content)
379
        content->assign(mElements.at(index).content);
380
 
381
    if (attrs)
382
        *attrs = mElements.at(index).attrs;
383
 
384
    return index;
385
}
386
 
387
size_t TExpat::getNextElementFromIndex(size_t index, string* name, string* content, vector<ATTRIBUTE_t>* attrs)
388
{
389
    DECL_TRACER("TExpat::getNextElementFromIndex(size_t index, int depth, string* name, string* content, vector<ATTRIBUTE_t>* attrs)");
390
 
391
    if (index == npos)
392
        return npos;
393
 
394
    size_t idx = index + 1;
395
 
396
    if (idx >= mElements.size() || mElements.at(idx).eType == _ET_END)
397
        return npos;
398
 
399
    if (name)
400
        name->assign(mElements.at(idx).name);
401
 
402
    if (content)
403
        content->assign(mElements.at(idx).content);
404
 
405
    if (attrs)
406
        *attrs = mElements.at(idx).attrs;
407
 
408
    return idx;
409
}
410
 
74 andreas 411
string TExpat::getFirstElement(const string &name, int *depth)
412
{
413
    DECL_TRACER("TExpat::getFirstElement(const string &name, int *depth)");
414
 
415
    vector<_ELEMENT_t>::iterator iter;
416
 
417
    for (iter = mElements.begin(); iter != mElements.end(); ++iter)
418
    {
75 andreas 419
        if (iter->eType != _ET_END && iter->name.compare(name) == 0)
74 andreas 420
        {
421
            if (depth)
422
                *depth = iter->depth;
423
 
424
            mLastIter = iter;
425
            return iter->content;
426
        }
427
    }
428
 
429
    if (depth)
430
        *depth = -1;
431
 
432
    mLastIter = mElements.end();
433
    return string();
434
}
435
 
77 andreas 436
string TExpat::getNextElement(const string &name, int depth, bool *valid)
74 andreas 437
{
438
    DECL_TRACER("TExpat::getNextElement(const string &name, int depth)");
439
 
77 andreas 440
    if (valid)
441
        *valid = false;
442
 
74 andreas 443
    if (mLastIter == mElements.end())
444
        return string();
445
 
446
    mLastIter++;
447
 
75 andreas 448
    while (mLastIter != mElements.end())
449
    {
450
        if (mLastIter == mElements.end() || mLastIter->eType == _ET_END)
451
            return string();
452
 
77 andreas 453
        if (mLastIter->name.compare(name) == 0 && mLastIter->depth == depth)
454
        {
455
            if (valid)
456
                *valid = true;
457
 
75 andreas 458
            return mLastIter->content;
77 andreas 459
        }
75 andreas 460
 
461
        mLastIter++;
462
    }
463
 
464
    return string();
465
}
466
 
467
size_t TExpat::getNextElementIndex(const string& name, int depth)
468
{
469
    DECL_TRACER("TExpat::getNextElementIndex(const string& name, int depth)");
470
 
74 andreas 471
    if (mLastIter == mElements.end())
75 andreas 472
        return npos;
74 andreas 473
 
75 andreas 474
    mLastIter++;
74 andreas 475
 
75 andreas 476
    while (mLastIter != mElements.end())
477
    {
78 andreas 478
        if (mLastIter->eType == _ET_END && mLastIter->depth < depth)
479
            break;
75 andreas 480
 
78 andreas 481
        if (mLastIter->name.compare(name)  == 0 && mLastIter->depth == depth && mLastIter->eType != _ET_END)
75 andreas 482
        {
483
            size_t idx = 0;
484
            vector<_ELEMENT_t>::iterator iter;
485
 
486
            for (iter = mElements.begin(); iter != mElements.end(); ++iter)
487
            {
488
                if (iter == mLastIter)
489
                    return idx;
490
 
491
                idx++;
492
            }
493
        }
494
 
495
        mLastIter++;
496
    }
497
 
498
    return npos;
499
}
500
 
501
string TExpat::getAttribute(const string& name, vector<ATTRIBUTE_t>& attrs)
502
{
503
    DECL_TRACER("TExpat::getAttribute(const string& name, vector<ATTRIBUTE_t>& attrs)");
504
 
505
    vector<ATTRIBUTE_t>::iterator iter;
506
 
88 andreas 507
    if (attrs.size() == 0)
508
        return string();
509
 
75 andreas 510
    for (iter = attrs.begin(); iter != attrs.end(); ++iter)
511
    {
512
        if (iter->name.compare(name) == 0)
513
            return iter->content;
514
    }
515
 
74 andreas 516
    return string();
517
}
518
 
75 andreas 519
int TExpat::getAttributeInt(const string& name, vector<ATTRIBUTE_t>& attrs)
520
{
521
    DECL_TRACER("TExpat::getAttributeInt(const string& name, vector<ATTRIBUTE_t>& attrs)");
74 andreas 522
 
75 andreas 523
    return atoi(getAttribute(name, attrs).c_str());
524
}
525
 
526
long Expat::TExpat::getAttributeLong(const std::string& name, std::vector<ATTRIBUTE_t>& attrs)
74 andreas 527
{
75 andreas 528
    DECL_TRACER("TExpat::getAttributeLong(const string& name, vector<ATTRIBUTE_t>& attrs)");
529
 
530
    return atol(getAttribute(name, attrs).c_str());
531
}
532
 
533
float Expat::TExpat::getAttributeFloat(const std::string& name, std::vector<ATTRIBUTE_t>& attrs)
534
{
535
    DECL_TRACER("TExpat::getAttributeFloat(const string& name, vector<ATTRIBUTE_t>& attrs)");
536
 
537
    return (float)atof(getAttribute(name, attrs).c_str());
538
}
539
 
540
double Expat::TExpat::getAttributeDouble(const std::string& name, std::vector<ATTRIBUTE_t>& attrs)
541
{
542
    DECL_TRACER("TExpat::getAttributeDouble(const string& name, vector<ATTRIBUTE_t>& attrs)");
543
 
544
    return atof(getAttribute(name, attrs).c_str());
545
}
546
 
547
int TExpat::convertElementToInt(const string& content)
548
{
549
    DECL_TRACER("TExpat::convertElementToInt(const string& content)");
550
 
551
    if (content.empty())
552
    {
553
        TError::setErrorMsg("Empty content!");
554
        return 0;
555
    }
556
 
557
    return atoi(content.c_str());
558
}
559
 
560
long TExpat::convertElementToLong(const string& content)
561
{
562
    DECL_TRACER("TExpat::convertElementToLong(const string& content)");
563
 
564
    if (content.empty())
565
    {
566
        TError::setErrorMsg("Empty content!");
567
        return 0;
568
    }
569
 
570
    return atol(content.c_str());
571
}
572
 
573
float TExpat::convertElementToFloat(const string& content)
574
{
575
    DECL_TRACER("TExpat::convertElementToFloat(const string& content)");
576
 
577
    if (content.empty())
578
    {
579
        TError::setErrorMsg("Empty content!");
580
        return 0;
581
    }
582
 
583
    return (float)atof(content.c_str());
584
}
585
 
586
double TExpat::convertElementToDouble(const string& content)
587
{
588
    DECL_TRACER("TExpat::convertElementToDouble(const string& content)");
589
 
590
    if (content.empty())
591
    {
592
        TError::setErrorMsg("Empty content!");
593
        return 0;
594
    }
595
 
596
    return atof(content.c_str());
597
}
598
 
599
bool TExpat::setIndex(size_t index)
600
{
601
    DECL_TRACER("TExpat::setIndex(size_t index)");
602
 
603
    if (index >= mElements.size())
604
    {
605
        TError::setErrorMsg("Invalid index " + std::to_string(index) + "!");
606
        mLastIter = mElements.end();
607
        return false;
608
    }
609
 
610
    vector<_ELEMENT_t>::iterator iter;
611
    size_t idx = 0;
612
 
613
    for (iter = mElements.begin(); iter != mElements.end(); ++iter)
614
    {
615
        if (idx == index)
616
        {
617
            mLastIter = iter;
618
            return true;
619
        }
620
 
621
        idx++;
622
    }
623
 
624
    mLastIter = mElements.end();
625
    return false;   // Should not happen and is just for satisfy the compiler.
626
}
627
 
628
vector<ATTRIBUTE_t> TExpat::getAttributes()
629
{
630
    DECL_TRACER("TExpat::getAttributes()");
631
 
632
    if (mLastIter == mElements.end())
633
        return vector<ATTRIBUTE_t>();
634
 
635
    return mLastIter->attrs;
636
}
637
 
638
vector<ATTRIBUTE_t> TExpat::getAttributes(size_t index)
639
{
640
    DECL_TRACER("TExpat::getAttributes(size_t index)");
641
 
642
    if (index >= mElements.size())
643
        return vector<ATTRIBUTE_t>();
644
 
645
    return mElements.at(index).attrs;
646
}
647
 
78 andreas 648
string TExpat::getElementName(bool *valid)
649
{
650
    DECL_TRACER("TExpat::getElementName()");
651
 
652
    if (mLastIter != mElements.end())
653
    {
654
        if (valid)
655
            *valid = true;
656
 
657
        return mLastIter->name;
658
    }
659
 
660
    if (valid)
661
        *valid = false;
662
 
663
    return string();
664
}
665
 
666
string TExpat::getElementContent(bool *valid)
667
{
668
    DECL_TRACER("TExpat::getElementContent()");
669
 
670
    if (mLastIter != mElements.end())
671
    {
672
        if (valid)
673
            *valid = true;
674
 
675
        return mLastIter->content;
676
    }
677
 
678
    if (valid)
679
        *valid = false;
680
 
681
    return string();
682
}
683
 
684
int TExpat::getElementContentInt(bool *valid)
685
{
686
    DECL_TRACER("TExpat::getElementContentInt(bool *valid)");
687
 
688
    if (mLastIter != mElements.end())
689
    {
690
        if (valid)
691
            *valid = true;
692
 
693
        return atoi(mLastIter->content.c_str());
694
    }
695
 
696
    if (valid)
697
        *valid = false;
698
 
699
    return 0;
700
}
701
 
702
long TExpat::getElementContentLong(bool *valid)
703
{
704
    DECL_TRACER("TExpat::getElementContentLong(bool *valid)");
705
 
706
    if (mLastIter != mElements.end())
707
    {
708
        if (valid)
709
            *valid = true;
710
 
711
        return atol(mLastIter->content.c_str());
712
    }
713
 
714
    if (valid)
715
        *valid = false;
716
 
717
    return 0;
718
}
719
 
720
float TExpat::getElementContentFloat(bool *valid)
721
{
722
    DECL_TRACER("TExpat::getElementContentFloat(bool *valid)");
723
 
724
    if (mLastIter != mElements.end())
725
    {
726
        if (valid)
727
            *valid = true;
728
 
729
        return (float)atof(mLastIter->content.c_str());
730
    }
731
 
732
    if (valid)
733
        *valid = false;
734
 
735
    return 0.0;
736
}
737
 
738
double TExpat::getElementContentDouble(bool *valid)
739
{
740
    DECL_TRACER("TExpat::getElementContentDouble(bool *valid)");
741
 
742
    if (mLastIter != mElements.end())
743
    {
744
        if (valid)
745
            *valid = true;
746
 
747
        return atof(mLastIter->content.c_str());
748
    }
749
 
750
    if (valid)
751
        *valid = false;
752
 
753
    return 0.0;
754
}
755
 
75 andreas 756
/******************************************************************************
757
 *                        Static methods starting here
758
 ******************************************************************************/
759
 
760
void TExpat::createCP1250Encoding(XML_Encoding* enc)
761
{
762
    if (!enc)
763
        return;
764
 
765
    for (int i = 0; i < 0x0100; i++)
766
    {
767
        if (i < 0x007f)
768
            enc->map[i] = i;
769
        else
770
        {
771
            switch(i)
772
            {
773
                case 0x080: enc->map[i] = 0x20AC; break;
774
                case 0x082: enc->map[i] = 0x201A; break;
775
                case 0x083: enc->map[i] = 0x0192; break;
776
                case 0x084: enc->map[i] = 0x201E; break;
777
                case 0x085: enc->map[i] = 0x2026; break;
778
                case 0x086: enc->map[i] = 0x2020; break;
779
                case 0x087: enc->map[i] = 0x2021; break;
780
                case 0x088: enc->map[i] = 0x02C6; break;
781
                case 0x089: enc->map[i] = 0x2030; break;
782
                case 0x08A: enc->map[i] = 0x0160; break;
783
                case 0x08B: enc->map[i] = 0x2039; break;
784
                case 0x08C: enc->map[i] = 0x0152; break;
785
                case 0x08D: enc->map[i] = 0x00A4; break;
786
                case 0x08E: enc->map[i] = 0x017D; break;
787
                case 0x08F: enc->map[i] = 0x00B9; break;
788
                case 0x091: enc->map[i] = 0x2018; break;
789
                case 0x092: enc->map[i] = 0x2019; break;
790
                case 0x093: enc->map[i] = 0x201C; break;
791
                case 0x094: enc->map[i] = 0x201D; break;
792
                case 0x095: enc->map[i] = 0x2022; break;
793
                case 0x096: enc->map[i] = 0x2013; break;
794
                case 0x097: enc->map[i] = 0x2014; break;
795
                case 0x098: enc->map[i] = 0x02DC; break;
796
                case 0x099: enc->map[i] = 0x2122; break;
797
                case 0x09A: enc->map[i] = 0x0161; break;
798
                case 0x09B: enc->map[i] = 0x203A; break;
799
                case 0x09C: enc->map[i] = 0x0153; break;
800
                case 0x09D: enc->map[i] = 0x00A5; break;
801
                case 0x09E: enc->map[i] = 0x017E; break;
802
                case 0x09F: enc->map[i] = 0x0178; break;
803
                case 0x0A0: enc->map[i] = 0x02A0; break;
804
                case 0x0A1: enc->map[i] = 0x02C7; break;
805
                case 0x0A2: enc->map[i] = 0x02D8; break;
806
                case 0x0A3: enc->map[i] = 0x0141; break;
807
                case 0x0A4: enc->map[i] = 0x00A4; break;
808
                case 0x0A5: enc->map[i] = 0x0104; break;
809
                case 0x0A6: enc->map[i] = 0x00A6; break;
810
                case 0x0A7: enc->map[i] = 0x00A7; break;
811
                case 0x0A8: enc->map[i] = 0x00A8; break;
812
                case 0x0A9: enc->map[i] = 0x00A9; break;
813
                case 0x0AA: enc->map[i] = 0x015E; break;
814
                case 0x0AB: enc->map[i] = 0x00AB; break;
815
                case 0x0AC: enc->map[i] = 0x00AC; break;
816
                case 0x0AD: enc->map[i] = 0x00AD; break;
817
                case 0x0AE: enc->map[i] = 0x00AE; break;
818
                case 0x0AF: enc->map[i] = 0x017B; break;
819
                case 0x0B0: enc->map[i] = 0x00B0; break;
820
                case 0x0B1: enc->map[i] = 0x00B1; break;
821
                case 0x0B2: enc->map[i] = 0x02DB; break;
822
                case 0x0B3: enc->map[i] = 0x0142; break;
823
                case 0x0B4: enc->map[i] = 0x00B4; break;
824
                case 0x0B5: enc->map[i] = 0x00B5; break;
825
                case 0x0B6: enc->map[i] = 0x00B6; break;
826
                case 0x0B7: enc->map[i] = 0x00B7; break;
827
                case 0x0B8: enc->map[i] = 0x00B8; break;
828
                case 0x0B9: enc->map[i] = 0x0105; break;
829
                case 0x0BA: enc->map[i] = 0x015F; break;
830
                case 0x0BB: enc->map[i] = 0x00BB; break;
831
                case 0x0BC: enc->map[i] = 0x013D; break;
832
                case 0x0BD: enc->map[i] = 0x02DD; break;
833
                case 0x0BE: enc->map[i] = 0x013E; break;
834
                case 0x0BF: enc->map[i] = 0x017C; break;
835
                case 0x0C0: enc->map[i] = 0x0154; break;
836
                case 0x0C1: enc->map[i] = 0x00C1; break;
837
                case 0x0C2: enc->map[i] = 0x00C2; break;
838
                case 0x0C3: enc->map[i] = 0x0102; break;
839
                case 0x0C4: enc->map[i] = 0x00C4; break;
840
                case 0x0C5: enc->map[i] = 0x0139; break;
841
                case 0x0C6: enc->map[i] = 0x0106; break;
842
                case 0x0C7: enc->map[i] = 0x00C7; break;
843
                case 0x0C8: enc->map[i] = 0x010C; break;
844
                case 0x0C9: enc->map[i] = 0x00C9; break;
845
                case 0x0CA: enc->map[i] = 0x0118; break;
846
                case 0x0CB: enc->map[i] = 0x00CB; break;
76 andreas 847
                case 0x0CC: enc->map[i] = 0x00CC; break;    //0x011A
75 andreas 848
                case 0x0CD: enc->map[i] = 0x00CD; break;
849
                case 0x0CE: enc->map[i] = 0x00CE; break;
76 andreas 850
                case 0x0CF: enc->map[i] = 0x00CF; break;
75 andreas 851
                case 0x0D0: enc->map[i] = 0x0110; break;
852
                case 0x0D1: enc->map[i] = 0x0143; break;
853
                case 0x0D2: enc->map[i] = 0x0147; break;
854
                case 0x0D3: enc->map[i] = 0x00D3; break;
855
                case 0x0D4: enc->map[i] = 0x00D4; break;
856
                case 0x0D5: enc->map[i] = 0x0150; break;
857
                case 0x0D6: enc->map[i] = 0x00D6; break;
858
                case 0x0D7: enc->map[i] = 0x00D7; break;
859
                case 0x0D8: enc->map[i] = 0x0158; break;
860
                case 0x0D9: enc->map[i] = 0x016E; break;
861
                case 0x0DA: enc->map[i] = 0x00DA; break;
862
                case 0x0DB: enc->map[i] = 0x0170; break;
863
                case 0x0DC: enc->map[i] = 0x00DC; break;
864
                case 0x0DD: enc->map[i] = 0x00DD; break;
865
                case 0x0DE: enc->map[i] = 0x0162; break;
866
                case 0x0DF: enc->map[i] = 0x00DF; break;
867
                case 0x0E0: enc->map[i] = 0x0155; break;
868
                case 0x0E1: enc->map[i] = 0x00E1; break;
869
                case 0x0E2: enc->map[i] = 0x00E2; break;
870
                case 0x0E3: enc->map[i] = 0x0103; break;
871
                case 0x0E4: enc->map[i] = 0x00E4; break;
872
                case 0x0E5: enc->map[i] = 0x013A; break;
873
                case 0x0E6: enc->map[i] = 0x0107; break;
874
                case 0x0E7: enc->map[i] = 0x00E7; break;
875
                case 0x0E8: enc->map[i] = 0x010D; break;
876
                case 0x0E9: enc->map[i] = 0x00E9; break;
877
                case 0x0EA: enc->map[i] = 0x0119; break;
878
                case 0x0EB: enc->map[i] = 0x00EB; break;
879
                case 0x0EC: enc->map[i] = 0x011B; break;
880
                case 0x0ED: enc->map[i] = 0x00ED; break;
881
                case 0x0EE: enc->map[i] = 0x00EE; break;
882
                case 0x0EF: enc->map[i] = 0x010F; break;
883
                case 0x0F0: enc->map[i] = 0x0111; break;
884
                case 0x0F1: enc->map[i] = 0x0144; break;
885
                case 0x0F2: enc->map[i] = 0x0148; break;
886
                case 0x0F3: enc->map[i] = 0x00F3; break;
887
                case 0x0F4: enc->map[i] = 0x00F4; break;
888
                case 0x0F5: enc->map[i] = 0x0151; break;
889
                case 0x0F6: enc->map[i] = 0x00F6; break;
890
                case 0x0F7: enc->map[i] = 0x00F7; break;
891
                case 0x0F8: enc->map[i] = 0x0159; break;
892
                case 0x0F9: enc->map[i] = 0x016F; break;
893
                case 0x0FA: enc->map[i] = 0x00FA; break;
894
                case 0x0FB: enc->map[i] = 0x0171; break;
895
                case 0x0FC: enc->map[i] = 0x00FC; break;
896
                case 0x0FD: enc->map[i] = 0x00FD; break;
897
                case 0x0FE: enc->map[i] = 0x0163; break;
898
                case 0x0FF: enc->map[i] = 0x02D9; break;
899
 
900
                default:
901
                    enc->map[i] = -1;
902
            }
903
        }
904
    }
905
}
906
 
907
void TExpat::startElement(void *userData, const XML_Char *name, const XML_Char **attrs)
908
{
74 andreas 909
    if (!name)
910
        return;
911
 
75 andreas 912
    std::vector<_ELEMENT_t> *ud = (std::vector<_ELEMENT_t> *)userData;
913
    _ELEMENT_t el;
914
 
74 andreas 915
    mLastName.assign(name);
916
    mDepth++;
917
    mAttributes.clear();
75 andreas 918
    mContent.clear();
74 andreas 919
 
75 andreas 920
    el.depth = mDepth;
921
    el.name = mLastName;
922
    el.eType = _ET_START;
923
 
74 andreas 924
    if (attrs && *attrs)
925
    {
926
        for (int i = 0; attrs[i]; i += 2)
927
        {
928
            _ATTRIBUTE_t at;
929
            at.name.assign(attrs[i]);
930
            at.content.assign(attrs[i + 1]);
931
            mAttributes.push_back(at);
932
        }
75 andreas 933
 
934
        el.attrs = mAttributes;
74 andreas 935
    }
75 andreas 936
 
937
    ud->push_back(el);
74 andreas 938
}
939
 
940
void TExpat::endElement(void *userData, const XML_Char *name)
941
{
942
    if (!userData || !name)
943
        return;
944
 
75 andreas 945
    std::vector<_ELEMENT_t> *ud = (std::vector<_ELEMENT_t> *)userData;
946
 
947
    if (mLastName.compare(name) == 0)
74 andreas 948
    {
75 andreas 949
        if (ud->back().depth == mDepth)
950
        {
951
            ud->back().eType = _ET_ATOMIC;
952
            ud->back().content = mContent;
953
 
954
            mDepth--;
955
            mLastName.clear();
956
            mContent.clear();
957
            return;
958
        }
74 andreas 959
    }
960
 
961
    _ELEMENT_t el;
962
    el.depth = mDepth;
75 andreas 963
    el.name.assign(name);
964
    el.eType = _ET_END;
74 andreas 965
    ud->push_back(el);
75 andreas 966
    mDepth--;
967
 
74 andreas 968
    mLastName.clear();
969
    mContent.clear();
970
}
971
 
972
void TExpat::CharacterDataHandler(void *, const XML_Char *s, int len)
973
{
974
    if (!s || len <= 0 || mLastName.empty())
975
        return;
976
 
76 andreas 977
    mContent.append(s, len);
74 andreas 978
}
75 andreas 979
 
980
int XMLCALL TExpat::cp1250_encoding_handler(void *, const XML_Char *encoding, XML_Encoding *info)
981
{
982
    if (!info)
983
        return XML_STATUS_ERROR;
984
 
985
    if (encoding && strcmp(encoding, "CP1250") != 0)
986
    {
987
        MSG_ERROR("Invalid encoding handler (" << encoding << ")");
988
        TError::setError();
989
        return XML_STATUS_ERROR;
990
    }
991
 
992
    memset(info, 0, sizeof(XML_Encoding));
993
    createCP1250Encoding(info);
994
    return XML_STATUS_OK;
995
}