Subversion Repositories gelsvn

Rev

Rev 381 | Rev 540 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 381 Rev 539
1
#include <fstream>
1
#include <fstream>
2
#include <string>
2
#include <string>
3
#include <sstream>
3
#include <sstream>
4
#include <cstring>
4
#include <cstring>
5
#include <algorithm>
5
#include <algorithm>
6
#include <list>
6
#include <list>
7
#include "XmlParser.h"
7
#include "XmlParser.h"
8
#include "string_utils.h"
8
#include "string_utils.h"
9
 
9
 
10
using namespace std;
10
using namespace std;
11
 
11
 
12
namespace Util
12
namespace Util
13
{
13
{
14
  /////////////////////////////////////////////////////////////////
14
  /////////////////////////////////////////////////////////////////
15
  // String handling
15
  // String handling
16
  /////////////////////////////////////////////////////////////////
16
  /////////////////////////////////////////////////////////////////
17
 
17
 
18
  void parse_attribs(const string& s, map<string, string>& result)
18
  void parse_attribs(const string& s, map<string, string>& result)
19
  {
19
  {
20
    string name1, name2;
20
    string name1, name2;
21
    list<string> atts;
21
    list<string> atts;
22
    trim_split(s, atts, "=");
22
    trim_split(s, atts, "=");
23
    if(atts.empty())
23
    if(atts.empty())
24
      return;
24
      return;
25
 
25
 
26
    get_last(atts.front(), name1);
26
    get_last(atts.front(), name1);
27
    list<string>::iterator i = atts.begin();
27
    list<string>::iterator i = atts.begin();
28
    list<string>::iterator end = atts.end();
28
    list<string>::iterator end = atts.end();
29
    if(i == --end)
29
    if(i == --end)
30
      return;
30
      return;
31
    
31
    
32
    for(++i; i != end; ++i)
32
    for(++i; i != end; ++i)
33
    { 
33
    { 
34
      get_last(*i, name2);
34
      get_last(*i, name2);
35
      result[trim(name1)] = trim(*i, " \"");
35
      result[trim(name1)] = trim(*i, " \"");
36
      name1 = name2;
36
      name1 = name2;
37
    }
37
    }
38
    result[trim(name1)] = trim(*end, " \"");
38
    result[trim(name1)] = trim(*end, " \"");
39
  }
39
  }
40
 
40
 
41
  /////////////////////////////////////////////////////////////////
41
  /////////////////////////////////////////////////////////////////
42
  // File handling
42
  // File handling
43
  /////////////////////////////////////////////////////////////////
43
  /////////////////////////////////////////////////////////////////
44
 
44
 
45
  ifstream& seek_string(ifstream& in, const string& s, const size_t bufsize = 100)
45
  ifstream& seek_string(ifstream& in, const string& s, const size_t bufsize = 100)
46
  {
46
  {
47
    const int bsize = static_cast<int>(max(s.size(), bufsize));
47
    const int bsize = static_cast<int>(max(s.size(), bufsize));
48
    const int n = static_cast<int>(s.size());
48
    const int n = static_cast<int>(s.size());
49
    char* buf = new char[bsize + 1];
49
    char* buf = new char[bsize + 1];
50
    char s0 = s[0];
50
    char s0 = s[0];
51
 
51
 
52
    in.get(buf, bsize, s0);
52
    in.get(buf, bsize, s0);
53
    in.clear();
53
    in.clear();
54
    in.read(buf, n);
54
    in.read(buf, n);
55
    buf[n] = '\0'; 
55
    buf[n] = '\0'; 
56
    while(in && strcmp(s.c_str(), buf) != 0)
56
    while(in && strcmp(s.c_str(), buf) != 0)
57
    {
57
    {
58
      in.get(buf, bsize, s0);
58
      in.get(buf, bsize, s0);
59
      in.clear();
59
      in.clear();
60
      in.read(buf, n);
60
      in.read(buf, n);
61
      buf[n] = '\0'; 
61
      buf[n] = '\0'; 
62
    }
62
    }
63
    
63
    
64
    delete [] buf;
64
    delete [] buf;
65
    return in;
65
    return in;
66
  }
66
  }
67
 
67
 
68
  ifstream& read_until(ifstream& in, string& s_in, const string s, const size_t bufsize = 500)
68
  ifstream& read_until(ifstream& in, string& s_in, const string s, const size_t bufsize = 500)
69
  {
69
  {
70
    const int bsize = static_cast<int>(max(s.size(), bufsize));
70
    const int bsize = static_cast<int>(max(s.size(), bufsize));
71
    const int n = static_cast<int>(s.size());
71
    const int n = static_cast<int>(s.size());
72
    char* buf = new char[bsize + 1];
72
    char* buf = new char[bsize + 1];
73
    char s0 = s[0];
73
    char s0 = s[0];
74
    ostringstream ostr;
74
    ostringstream ostr;
75
 
75
 
76
    in.get(buf, bsize, s0);
76
    in.get(buf, bsize, s0);
77
    ostr << buf;
77
    ostr << buf;
78
    in.clear();
78
    in.clear();
79
    in.read(buf, n);
79
    in.read(buf, n);
80
    buf[n] = '\0'; 
80
    buf[n] = '\0'; 
81
    while(in && strcmp(s.c_str(), buf) != 0)
81
    while(in && strcmp(s.c_str(), buf) != 0)
82
    {
82
    {
83
      ostr << buf;
83
      ostr << buf;
84
      in.get(buf, bsize, s0);
84
      in.get(buf, bsize, s0);
85
      ostr << buf;
85
      ostr << buf;
86
      in.clear();
86
      in.clear();
87
      in.read(buf, n);
87
      in.read(buf, n);
88
      buf[n] = '\0'; 
88
      buf[n] = '\0'; 
89
    }
89
    }
90
    s_in = ostr.str();
90
    s_in = ostr.str();
91
 
91
 
92
    delete [] buf;
92
    delete [] buf;
93
    return in;
93
    return in;
94
  }
94
  }
95
 
95
 
96
  ifstream& operator>>(ifstream& in, XmlHead& fhead)
96
  ifstream& operator>>(ifstream& in, XmlHead& fhead)
97
  {
97
  {
98
    seek_string(in, "<?xml");
98
    seek_string(in, "<?xml");
99
 
99
 
100
    string head;
100
    string head;
101
    read_until(in, head, "?>");
101
    read_until(in, head, "?>");
102
 
102
 
103
    fhead.is_xml = in.good();
103
    fhead.is_xml = in.good();
104
    parse_attribs(head, fhead.atts);
104
    parse_attribs(head, fhead.atts);
105
 
105
 
106
    return in;
106
    return in;
107
  }
107
  }
108
 
108
 
109
  ifstream& operator>>(ifstream& in, XmlElement& elem)
109
  ifstream& operator>>(ifstream& in, XmlElement& elem)
110
  {
110
  {
111
    seek_string(in, "<");
111
    seek_string(in, "<");
112
 
112
 
113
    string head;
113
    string head;
114
    read_until(in, head, ">");
114
    read_until(in, head, ">");
115
 
115
 
116
    if(head[0] == '!') return in;
116
    if(head.empty() || head[0] == '!') return in;
117
    if(head[0] == '/')
117
    if(head[0] == '/')
118
    {
118
    {
119
      if(elem.parent && elem.parent->name == head.substr(1))
119
      if(elem.parent && elem.parent->name == head.substr(1))
120
        in.setstate(ios_base::eofbit);
120
        in.setstate(ios_base::eofbit);
121
      else
121
      else
122
        elem.name = "";
122
        elem.name = "";
123
      return in;
123
      return in;
124
    }
124
    }
125
 
125
 
126
    bool has_body = true;
126
    bool has_body = true;
127
    if(head[head.size() - 1] == '/')
127
    if(head[head.size() - 1] == '/')
128
    {
128
    {
129
      has_body = false;
129
      has_body = false;
130
      head.erase(head.size() - 1);
130
      head.erase(head.size() - 1);
131
    }
131
    }
132
 
132
 
133
    get_first(head, elem.name);
133
    get_first(head, elem.name);
134
    elem.name = trim(elem.name);
134
    elem.name = trim(elem.name);
135
    parse_attribs(head, elem.atts);
135
    parse_attribs(head, elem.atts);
136
 
136
 
137
    if(has_body)
137
    if(has_body)
138
    {
138
    {
139
      delete elem.body;
139
      delete elem.body;
140
      elem.body = new XmlBody(elem.doc);
140
      elem.body = new XmlBody(elem.doc);
141
      elem.body->element.parent = &elem;
141
      elem.body->element.parent = &elem;
142
      read_until(in, elem.body->text, "<");
142
      read_until(in, elem.body->text, "<");
143
      in.putback('<');
143
      in.putback('<');
144
    }
144
    }
145
    return in;
145
    return in;
146
  }
146
  }
147
 
147
 
148
  ifstream& operator>>(ifstream& in, XmlBody& body)
148
  ifstream& operator>>(ifstream& in, XmlBody& body)
149
  {
149
  {
150
    read_until(in, body.text, "<");
150
    read_until(in, body.text, "<");
151
    in.putback('<');
151
    in.putback('<');
152
    return in;
152
    return in;
153
  }
153
  }
154
 
154
 
155
  /////////////////////////////////////////////////////////////////
155
  /////////////////////////////////////////////////////////////////
156
  // Methods
156
  // Methods
157
  /////////////////////////////////////////////////////////////////
157
  /////////////////////////////////////////////////////////////////
158
 
158
 
159
  XmlElement::~XmlElement()
159
  XmlElement::~XmlElement()
160
  {
160
  {
161
    delete body;
161
    delete body;
162
  }
162
  }
163
 
163
 
164
  void XmlBody::process_element()
164
  void XmlBody::process_element()
165
  {
165
  {
166
    if(!doc) return;
166
    if(!doc) return;
167
    if((doc->infile >> element) && !doc->infile.eof())
167
    if((doc->infile >> element) && !doc->infile.eof())
168
    {
168
    {
169
      XmlElementHandler h = doc->handlers[element.name];
169
      XmlElementHandler h = doc->handlers[element.name];
170
      if(h) 
170
      if(h) 
171
        h(element);
171
        h(element);
172
      else 
172
      else 
173
        element.process_elements();
173
        element.process_elements();
174
    }
174
    }
175
  }
175
  }
176
 
176
 
177
  void XmlElement::process_elements()
177
  void XmlElement::process_elements()
178
  {
178
  {
179
    if(!doc) return;
179
    if(!doc) return;
180
    if(!body) return; 
180
    if(!body) return; 
181
 
181
 
182
    while((doc->infile >> body->element) && !doc->infile.eof())
182
    while(!doc->infile.eof() && (doc->infile >> body->element))
183
    {
183
    {
184
      XmlElementHandler h = doc->handlers[body->element.name];
184
      XmlElementHandler h = doc->handlers[body->element.name];
185
      if(h) 
185
      if(h) 
186
        h(body->element);
186
        h(body->element);
187
      else 
187
      else 
188
        body->element.process_elements();
188
        body->element.process_elements();
189
    }
189
    }
190
    doc->infile.clear();
190
    doc->infile.clear();
191
  }
191
  }
192
 
192
 
193
  XmlDoc::XmlDoc(const char *filename)
193
  XmlDoc::XmlDoc(const char *filename)
194
    : body(0), infile(filename)
194
    : body(0), infile(filename)
195
  {
195
  {
196
    if(!infile)
196
    if(!infile)
197
    {
197
    {
198
       cerr << "cannot open input file" << filename << endl;
198
       cerr << "cannot open input file" << filename << endl;
199
       return;
199
       return;
200
    }
200
    }
201
    
201
    
202
    if(infile >> head)
202
    if(infile >> head)
203
      infile >> body;
203
      infile >> body;
204
    else
204
    else
205
      cerr << filename << " is not a valid xml-file" << endl;
205
      cerr << filename << " is not a valid xml-file" << endl;
206
 
206
 
207
    body.doc = this;
207
    body.doc = this;
208
    body.element.doc = this;
208
    body.element.doc = this;
209
  }
209
  }
210
 
210
 
211
  void XmlDoc::process_elements()
211
  void XmlDoc::process_elements()
212
  {
212
  {
213
    while((infile >> body.element) && !infile.eof())
213
    while((infile >> body.element) && !infile.eof())
214
    {
214
    {
215
      XmlElementHandler h = handlers[body.element.name];
215
      XmlElementHandler h = handlers[body.element.name];
216
      if(h) 
216
      if(h) 
217
        h(body.element);
217
        h(body.element);
218
      else 
218
      else 
219
        body.element.process_elements();
219
        body.element.process_elements();
220
    }
220
    }
221
    infile.clear();
221
    infile.clear();
222
  }
222
  }
223
 
223
 
224
  /////////////////////////////////////////////////////////////////
224
  /////////////////////////////////////////////////////////////////
225
  // Output handling
225
  // Output handling
226
  /////////////////////////////////////////////////////////////////
226
  /////////////////////////////////////////////////////////////////
227
 
227
 
228
  ostream& operator<<(ostream& out, const pair<string, string>& attrib)
228
  ostream& operator<<(ostream& out, const pair<string, string>& attrib)
229
  {
229
  {
230
    return out << attrib.first << "=\"" << attrib.second << "\"";
230
    return out << attrib.first << "=\"" << attrib.second << "\"";
231
  }
231
  }
232
 
232
 
233
  ostream& operator<<(ostream& out, const XmlHead& head)
233
  ostream& operator<<(ostream& out, const XmlHead& head)
234
  {
234
  {
235
    out << "<?xml";
235
    out << "<?xml";
236
    for(map<string, string>::const_iterator i = head.atts.begin(); i != head.atts.end(); ++i)
236
    for(map<string, string>::const_iterator i = head.atts.begin(); i != head.atts.end(); ++i)
237
      out << " " << *i;
237
      out << " " << *i;
238
    out << "?>";
238
    out << "?>";
239
    return out;
239
    return out;
240
  }
240
  }
241
}
241
}
242
 
242
 
243

Generated by GNU Enscript 1.6.6.
243

Generated by GNU Enscript 1.6.6.
244
 
244
 
245
 
245
 
246
 
246