Statistics
| Branch: | Revision:

root / src / nedxml / saxparser_expat.cc @ 68da4f12

History | View | Annotate | Download (4.33 KB)

1 01873262 Georg Kunz
//==========================================================================
2
//  SAXPARSER.CC - part of
3
//
4
//                     OMNeT++/OMNEST
5
//            Discrete System Simulation in C++
6
//
7
//==========================================================================
8
9
/*--------------------------------------------------------------*
10
  Copyright (C) 2002-2008 Andras Varga
11
  Copyright (C) 2006-2008 OpenSim Ltd.
12

13
  This file is distributed WITHOUT ANY WARRANTY. See the file
14
  `license' for details on this and other legal matters.
15
*--------------------------------------------------------------*/
16
17
18
#include <string.h>
19
#include <stdio.h>
20
#include <assert.h>
21
#include <stdio.h>
22
#include "expat.h"
23
#include "saxparser.h"
24
25
USING_NAMESPACE
26
27
28
static bool hasDTD;
29
30
31
static void expatStartElementHandler(void *userData, const XML_Char *name, const XML_Char **atts)
32
{
33
    SAXHandler *sh = (SAXHandler *)userData;
34
    sh->startElement(name,atts);
35
}
36
37
static void expatEndElementHandler(void *userData, const XML_Char *name)
38
{
39
    SAXHandler *sh = (SAXHandler *)userData;
40
    sh->endElement(name);
41
}
42
43
static void expatCharacterDataHandler(void *userData, const XML_Char *s, int len)
44
{
45
    SAXHandler *sh = (SAXHandler *)userData;
46
    sh->characterData(s,len);
47
}
48
49
static void expatProcessingInstructionHandler(void *userData, const XML_Char *target, const XML_Char *data)
50
{
51
    SAXHandler *sh = (SAXHandler *)userData;
52
    sh->processingInstruction(target,data);
53
}
54
55
static void expatCommentHandler(void *userData, const XML_Char *data)
56
{
57
    SAXHandler *sh = (SAXHandler *)userData;
58
    sh->comment(data);
59
}
60
61
62
static void expatStartCdataSectionHandler(void *userData)
63
{
64
    SAXHandler *sh = (SAXHandler *)userData;
65
    sh->startCdataSection();
66
}
67
68
static void expatEndCdataSectionHandler(void *userData)
69
{
70
    SAXHandler *sh = (SAXHandler *)userData;
71
    sh->endCdataSection();
72
}
73
74
static void expatStartDoctypeDeclHandler(void *userData,
75
                                         const XML_Char *, // doctypeName
76
                                         const XML_Char *, // sysid
77
                                         const XML_Char *, // pubid
78
                                         int)              // has_internal_subset
79
{
80
    hasDTD = true;
81
}
82
83
SAXParser::SAXParser()
84
{
85
    saxhandler = NULL;
86
}
87
88
void SAXParser::setHandler(SAXHandler *sh)
89
{
90
    saxhandler = sh;
91
    sh->setParser(this);
92
}
93
94
bool SAXParser::parse(const char *filename)
95
{
96
    // open file
97
    FILE *f = fopen(filename,"r");
98
    if (!f)
99
    {
100
        sprintf(errortext, "Cannot open file");
101
        return false;
102
    }
103
104
    // prepare parser
105
    XML_Parser parser = XML_ParserCreate(NULL);
106
    XML_SetUserData(parser, saxhandler);
107
    XML_SetStartElementHandler(parser, expatStartElementHandler);
108
    XML_SetEndElementHandler(parser, expatEndElementHandler);
109
    XML_SetCharacterDataHandler(parser, expatCharacterDataHandler);
110
    XML_SetProcessingInstructionHandler(parser, expatProcessingInstructionHandler);
111
    XML_SetCommentHandler(parser, expatCommentHandler);
112
    XML_SetStartCdataSectionHandler(parser, expatStartCdataSectionHandler);
113
    XML_SetEndCdataSectionHandler(parser, expatEndCdataSectionHandler);
114
    XML_SetStartDoctypeDeclHandler(parser, expatStartDoctypeDeclHandler);
115
    currentparser = &parser;
116
117
    // read file chunk-by-chunk and parse it
118
    char buf[BUFSIZ];
119
    bool done;
120
    bool err = false;
121
    hasDTD = false;
122
    do {
123
        size_t len = fread(buf, 1, sizeof(buf), f);
124
        done = len < sizeof(buf);
125
        if (!XML_Parse(parser, buf, len, done))
126
        {
127
            sprintf(errortext, "Parse error: %s at line %d",
128
                    XML_ErrorString(XML_GetErrorCode(parser)),
129
                    XML_GetCurrentLineNumber(parser));
130
            err=true;
131
            done=true;
132
        }
133
        if (hasDTD)
134
        {
135
            sprintf(errortext, "Cannot validate document and complete default attributes "
136
                    "from DTD, because underlying parser (Expat) does not support it. "
137
                    "Recompile OMNeT++ with another parser (LibXML), or remove DOCTYPE from "
138
                    " %s",
139
                    filename);
140
            err=true;
141
            done = true;
142
        }
143
    } while (!done);
144
145
    // cleanup and return
146
    XML_ParserFree(parser);
147
    fclose(f);
148
    return !err;
149
}
150
151
int SAXParser::getCurrentLineNumber()
152
{
153
    return XML_GetCurrentLineNumber(*(XML_Parser *)currentparser);
154
}
155