~ubuntu-branches/ubuntu/wily/afnix/wily

« back to all changes in this revision

Viewing changes to src/mod/xml/shl/XsmReader.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anibal Monsalve Salazar
  • Date: 2011-03-16 21:31:18 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20110316213118-gk4k3ez3e5d2huna
Tags: 2.0.0-1
* QA upload.
* New upstream release
* Debian source format is 3.0 (quilt)
* Fix debhelper-but-no-misc-depends
* Fix ancient-standards-version
* Fix package-contains-linda-override
* debhelper compatibility is 7
* Fix dh-clean-k-is-deprecated

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
// - the copyright holder be liable for any  direct, indirect, incidental or -
12
12
// - special damages arising in any way out of the use of this software.     -
13
13
// ---------------------------------------------------------------------------
14
 
// - copyright (c) 1999-2007 amaury darsch                                   -
 
14
// - copyright (c) 1999-2011 amaury darsch                                   -
15
15
// ---------------------------------------------------------------------------
16
16
 
17
17
#include "Vector.hpp"
 
18
#include "Boolean.hpp"
18
19
#include "Unicode.hpp"
19
20
#include "Runnable.hpp"
20
21
#include "XsmBuffer.hpp"
21
22
#include "XsmReader.hpp"
 
23
#include "XsoStream.hpp"
22
24
#include "QuarkZone.hpp"
23
25
#include "Exception.hpp"
24
26
#include "InputString.hpp"
54
56
 
55
57
  // this function parse a xsm tag node
56
58
  static XsmNode* parse_xsm_tag (XsmBuffer& xbuf) {
57
 
   // create a tag node by string
 
59
    // create a tag node by string
58
60
    XsmNode* node = new XsmNode (XsmNode::TAG_NODE, xbuf.tostring ());
59
61
    // set the node line number
60
62
    node->setlnum (xbuf.getlnum ());
88
90
    return node;
89
91
  }
90
92
 
 
93
  // this function clear a node buffer
 
94
  static void clear_xsm_node (XsoStream& xis) {
 
95
    // loop until we have an exit condition
 
96
    while (xis.valid () == true) {
 
97
      try {
 
98
        t_quad c = xis.getu ();
 
99
        switch (c) {
 
100
        case XSM_CHAR_LT:
 
101
          xis.pushback (c);
 
102
          return;
 
103
        case nilq:
 
104
        case eosq:
 
105
        case XSM_CHAR_GT:
 
106
          return;
 
107
        default:
 
108
          break;
 
109
        }
 
110
      } catch (...) {
 
111
        continue;
 
112
      }
 
113
    }
 
114
  }
 
115
 
91
116
  // this function parse a xsm node
92
117
  static XsmNode* parse_xsm_node (XsoStream& xis) {
93
118
    // create a xml buffer
96
121
    // state: s_helo
97
122
    // get the first character for dispatch
98
123
  s_helo:
99
 
    t_quad c = xis.rduc ();
 
124
    t_quad c = xis.getu ();
100
125
    switch (c) {
101
126
    case XSM_CHAR_LT:
102
127
      xbuf.begin (xis.getlnum ());
105
130
      xbuf.begin (xis.getlnum ());
106
131
      goto s_sref;
107
132
    case nilq:
108
 
    case eofq:
 
133
    case eosq:
109
134
      return nilp;
110
135
    default:
111
136
      if (xbuf.isspc (c) == true) {
120
145
    // state: s_text
121
146
    // read some text and accumulate
122
147
  s_text:
123
 
    c = xis.rduc ();
 
148
    c = xis.getu ();
124
149
    switch (c) {
125
150
    case XSM_CHAR_LT:
126
151
    case XSM_CHAR_AM:
127
 
    case eofq:
 
152
    case eosq:
128
153
      xis.pushback (c);
129
154
      return parse_xsm_txt (xbuf);
130
155
    default:
135
160
    // state: s_stag
136
161
    // start a tag with anything inside
137
162
  s_stag:
138
 
    c = xis.rduc ();
 
163
    c = xis.getu ();
139
164
    switch (c) {
140
165
    case XSM_CHAR_GT:
141
166
      return parse_xsm_tag (xbuf);
144
169
    case XSM_CHAR_EP:
145
170
      xbuf.add (c);
146
171
      goto s_ptag;
147
 
    case eofq:
 
172
    case eosq:
148
173
      goto s_error;
149
174
    default:
150
175
      xbuf.add (c);
154
179
    // state: s_ntag
155
180
    // read a tag with anything inside
156
181
  s_ntag:
157
 
    c = xis.rduc ();
 
182
    c = xis.getu ();
158
183
    switch (c) {
159
184
    case XSM_CHAR_GT:
160
185
      return parse_xsm_tag (xbuf);
161
 
    case eofq:
 
186
    case eosq:
162
187
      goto s_error;
163
188
    default:
164
189
      xbuf.add (c);
168
193
    // state: s_etag
169
194
    // read an end tag
170
195
  s_etag:
171
 
    c = xis.rduc ();
 
196
    c = xis.getu ();
172
197
    switch (c) {
173
198
    case XSM_CHAR_GT:
174
199
      return parse_xsm_end (xbuf);
175
 
    case eofq:
 
200
    case eosq:
176
201
      goto s_error;
177
202
    default:
178
203
      xbuf.add (c);
182
207
    // state: s_ptag
183
208
    // read a special tag with !
184
209
  s_ptag:
185
 
    c = xis.rduc ();
 
210
    c = xis.getu ();
186
211
    switch (c) {
187
212
    case XSM_CHAR_LB:
188
213
      xbuf.add (c);
190
215
    case XSM_CHAR_MN:
191
216
      xbuf.add (c);
192
217
      goto s_bgcm;
193
 
    case eofq:
 
218
    case eosq:
194
219
      goto s_error;
195
220
    default:
196
221
      xbuf.add (c);
200
225
    // state: s_btag
201
226
    // read a bracket tag 
202
227
  s_btag:
203
 
    c = xis.rduc ();
 
228
    c = xis.getu ();
204
229
    switch (c) {
205
230
    case XSM_CHAR_RB:
206
231
      xbuf.add (c);
207
232
      goto s_rtag;
208
 
    case eofq:
 
233
    case eosq:
209
234
      goto s_error;
210
235
    default:
211
236
      xbuf.add (c);
215
240
    // state: s_rtag
216
241
    // read a bracket tag end
217
242
  s_rtag:
218
 
    c = xis.rduc ();
 
243
    c = xis.getu ();
219
244
    switch (c) {
220
245
    case XSM_CHAR_GT:
221
246
      return parse_xsm_tag (xbuf);
222
247
    case XSM_CHAR_RB:
223
248
      xbuf.add (c);
224
249
      goto s_rtag;
225
 
    case eofq:
 
250
    case eosq:
226
251
      goto s_error;
227
252
    default:
228
253
      xbuf.add (c);
232
257
    // state: s_sref
233
258
    // start a reference node
234
259
  s_sref:
235
 
    c = xis.rduc ();
 
260
    c = xis.getu ();
236
261
    switch (c) {
237
262
    case XSM_CHAR_SC:
238
263
      return parse_xsm_ref (xbuf);
239
264
    case XSM_CHAR_LT:
240
 
    case eofq:
 
265
    case eosq:
241
266
      xbuf.pushback (XSM_CHAR_AM);
242
267
      xis.pushback  (c);
243
268
      return parse_xsm_txt (xbuf);
249
274
    // state: s_bgcm
250
275
    // begin a comment node
251
276
  s_bgcm:
252
 
    c = xis.rduc ();
 
277
    c = xis.getu ();
253
278
    switch (c) {
254
279
    case XSM_CHAR_MN:
255
280
      xbuf.add (c);
256
281
      goto s_ctag;
257
 
    case eofq:
 
282
    case eosq:
258
283
      goto s_error;
259
284
    default:
260
285
      xbuf.add (c);
264
289
    // state: s_ctag
265
290
    // read a comment node
266
291
  s_ctag:
267
 
    c = xis.rduc ();
 
292
    c = xis.getu ();
268
293
    switch (c) {
269
294
    case XSM_CHAR_MN:
270
295
      xbuf.add (c);
271
296
      goto s_encm;
272
 
    case eofq:
 
297
    case eosq:
273
298
      goto s_error;
274
299
    default:
275
300
      xbuf.add (c);
279
304
    // state: s_encm
280
305
    // start the end comment node
281
306
  s_encm:
282
 
    c = xis.rduc ();
 
307
    c = xis.getu ();
283
308
    switch (c) {
284
309
    case XSM_CHAR_MN:
285
310
      xbuf.add (c);
286
311
      goto s_fncm;
287
 
    case eofq:
 
312
    case eosq:
288
313
      goto s_error;
289
314
    default:
290
315
      xbuf.add (c);
294
319
    // state: s_fncm
295
320
    // finish the end comment node
296
321
  s_fncm:
297
 
    c = xis.rduc ();
 
322
    c = xis.getu ();
298
323
    switch (c) {
299
324
    case XSM_CHAR_GT:
300
325
      return parse_xsm_tag (xbuf);
301
 
    case eofq:
 
326
    case eosq:
302
327
      throw Exception ("xsm-error", "unterminated comment node");
303
328
    default:
304
 
      throw Exception ("xsm-error", "invalid -- sequence in comment node");
 
329
      xbuf.add (c);
 
330
      goto s_ctag;
305
331
    }
306
332
 
307
333
    // state: s_error
318
344
  // create an empty reader
319
345
 
320
346
  XsmReader::XsmReader (void) {
321
 
    p_xis = nilp;
 
347
    d_erf = false;
 
348
    p_is  = nilp;
322
349
  }
323
350
 
324
351
  // create a xsm reader by input stream
325
352
 
326
 
  XsmReader::XsmReader (Input* is) {
327
 
    p_xis = nilp;
 
353
  XsmReader::XsmReader (InputStream* is) {
 
354
    d_erf = false;
 
355
    p_is  = nilp;
328
356
    setis (is);
329
357
  }
330
358
 
331
359
  // create a xsm reader by string
332
360
 
333
361
  XsmReader::XsmReader (const String& xval) {
334
 
    p_xis = nilp;
 
362
    d_erf = false;
 
363
    p_is  = nilp;
335
364
    setis (xval);
336
365
  }
337
366
  
 
367
  // create a xsm reader by input stream and error flag
 
368
 
 
369
  XsmReader::XsmReader (InputStream* is, const bool erf) {
 
370
    d_erf = erf;
 
371
    p_is  = nilp;
 
372
    setis (is);
 
373
  }
 
374
 
338
375
  // destroy this reader
339
376
 
340
377
  XsmReader::~XsmReader (void) {
341
 
    delete p_xis;
 
378
    Object::dref (p_is);
342
379
  }
343
380
 
344
381
  // return the document class name
347
384
    return "XsmReader";
348
385
  }
349
386
 
 
387
  // set the erf flag
 
388
 
 
389
  void XsmReader::seterf (const bool erf) {
 
390
    wrlock ();
 
391
    try {
 
392
      d_erf = erf;
 
393
      unlock ();
 
394
    } catch (...) {
 
395
      unlock ();
 
396
      throw;
 
397
    }
 
398
  }
 
399
 
 
400
  // get the erf flag
 
401
 
 
402
  bool XsmReader::geterf (void) const {
 
403
    rdlock ();
 
404
    try {
 
405
      bool result = d_erf;
 
406
      unlock ();
 
407
      return result;
 
408
    } catch (...) {
 
409
      unlock ();
 
410
      throw;
 
411
    }
 
412
  }
 
413
 
350
414
  // set the reader input stream
351
415
 
352
 
  void XsmReader::setis (Input* is) {
 
416
  void XsmReader::setis (InputStream* is) {
353
417
    wrlock ();
354
 
    delete p_xis;
355
 
    p_xis = new XsoStream (is);
356
 
    unlock ();
 
418
    try {
 
419
      Object::iref (is);
 
420
      Object::dref (p_is);
 
421
      p_is = is;
 
422
      unlock ();
 
423
    } catch (...) {
 
424
      Object::dref (p_is);
 
425
      p_is = nilp;
 
426
      unlock ();
 
427
      throw;
 
428
    }
357
429
  }
358
430
 
359
431
  // set the reader input stream by string
360
432
 
361
433
  void XsmReader::setis (const String& xval) {
362
434
    wrlock ();
363
 
    delete p_xis;
364
 
    p_xis = new XsoStream (new InputString (xval));
365
 
    unlock ();
 
435
    try {
 
436
      Object::dref (p_is); p_is = nilp;
 
437
      Object::iref (p_is = new InputString (xval));
 
438
      unlock ();
 
439
    } catch (...) {
 
440
      Object::dref (p_is);
 
441
      p_is = nilp;
 
442
      unlock ();
 
443
      throw;
 
444
    }
366
445
  }
367
446
 
368
447
  // get the next available node
370
449
  XsmNode* XsmReader::getnode (void) {
371
450
    wrlock ();
372
451
    // check the input stream
373
 
    if (p_xis == nilp) {
 
452
    if (p_is == nilp) {
374
453
      unlock ();
375
454
      return nilp;
376
455
    }
 
456
    // create a xso stream
 
457
    XsoStream xis (p_is);
377
458
    try {
378
459
      // parse the xml stream
379
 
      XsmNode* result = parse_xsm_node (*p_xis);
 
460
      XsmNode* result = parse_xsm_node (xis);
380
461
      unlock ();
381
462
      return result;
382
463
    } catch (Exception& e) {
383
 
      e.updlnum (p_xis->getlnum ());
384
 
      unlock ();
385
 
      throw e;
 
464
      if (d_erf == true) {
 
465
        // clear the stream
 
466
        clear_xsm_node (xis);
 
467
        // try to get the next node
 
468
        XsmNode* result = getnode ();
 
469
        unlock ();
 
470
        return result;
 
471
      } else {
 
472
        e.updlnum (xis.getlnum ());
 
473
        unlock ();
 
474
        throw e;
 
475
      }
386
476
    } catch (...) {
387
477
      unlock ();
388
478
      throw;
389
479
    }
390
480
  }
391
 
 
 
481
  
392
482
  // -------------------------------------------------------------------------
393
483
  // - object section                                                        -
394
484
  // -------------------------------------------------------------------------
395
485
 
396
486
  // the quark zone
397
 
  static const long QUARK_ZONE_LENGTH = 2;
 
487
  static const long QUARK_ZONE_LENGTH = 4;
398
488
  static QuarkZone  zone (QUARK_ZONE_LENGTH);
399
489
 
400
490
  // the object supported quarks
401
491
  static const long QUARK_SETIS   = zone.intern ("set-input-stream");
 
492
  static const long QUARK_SETERF  = zone.intern ("set-error-resume");
 
493
  static const long QUARK_GETERF  = zone.intern ("get-error-resume");
402
494
  static const long QUARK_GETNODE = zone.intern ("get-node");
403
495
 
404
496
  // create a new object in a generic way
411
503
    if (argc == 1) {
412
504
      Object* obj = argv->get (0);
413
505
      // check for an input stream
414
 
      Input* is = dynamic_cast <Input*> (obj);
 
506
      InputStream* is = dynamic_cast <InputStream*> (obj);
415
507
      if (is != nilp) return new XsmReader (is);
416
508
      // check for a string
417
509
      String* sobj = dynamic_cast <String*> (obj);
448
540
 
449
541
    // check for 0 argument
450
542
    if (argc == 0) {
 
543
      if (quark == QUARK_GETERF)  return new Boolean (geterf ());
451
544
      if (quark == QUARK_GETNODE) return getnode ();
452
545
    }
453
546
    // check for 1 argument
454
547
    if (argc == 1) {
 
548
      if (quark == QUARK_SETERF) {
 
549
        bool erf = argv->getbool (0);
 
550
        seterf (erf);
 
551
        return nilp;
 
552
      }
455
553
      if (quark == QUARK_SETIS) {
456
554
        Object* obj = argv->get (0);
457
555
        if (obj == nilp) return nilp;
458
556
        // check for an input stream
459
 
        Input* is = dynamic_cast <Input*> (obj);
 
557
        InputStream* is = dynamic_cast <InputStream*> (obj);
460
558
        if (is != nilp) {
461
559
          setis (is);
462
560
          return nilp;