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