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