DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
dunedaq::oks::OksXmlInputStream Class Reference

#include <xml.hpp>

Collaboration diagram for dunedaq::oks::OksXmlInputStream:
[legend]

Public Member Functions

 OksXmlInputStream (std::shared_ptr< std::istream > p)
 
 ~OksXmlInputStream ()
 
void get_num_token (char last)
 
size_t get_quoted ()
 
const char * get_tag ()
 
const char * get_tag_start ()
 
bool good () const
 
bool eof () const
 
void store_position ()
 
void restore_position ()
 
long get_position () const
 
void seek_position (std::streamoff off)
 
std::ostream & error_msg (const char *)
 
unsigned long get_line_no () const
 
unsigned long get_line_pos () const
 
OksXmlTokenget_xml_token ()
 
OksXmlValue get_value (unsigned int len)
 
void throw_unexpected_tag (const char *what, const char *expected=0)
 
void throw_unexpected_attribute (const char *what)
 

Static Public Member Functions

static void __throw_strto (const char *f, const char *where, const char *what, unsigned long line_no, unsigned long line_pos)
 

Private Member Functions

void init ()
 
size_t get_token (const char s1, OksXmlToken &token)
 
size_t get_token2 (char, const char s1, const char s2, OksXmlToken &token)
 
void get_token5 (const char s1, const char s2, const char s3, const char s4, const char s5, OksXmlToken &token)
 
char cvt_char ()
 
char get_first_non_empty ()
 
char get ()
 
unsigned long get_value_pre ()
 
void get_value_post (unsigned long)
 
void __throw_eof () const
 
 OksXmlInputStream (const OksXmlInputStream &)
 
OksXmlInputStreamoperator= (const OksXmlInputStream &)
 

Private Attributes

std::shared_ptr< std::istream > f
 
std::streambuf * m_pbuf
 
unsigned long line_no
 
unsigned long line_pos
 
char last_read_c
 
std::istream::pos_type pos
 
unsigned long m_line_no_sav
 
unsigned long m_line_pos_sav
 
OksXmlTokenm_cvt_char
 
OksXmlTokenm_v1
 
OksXmlTokenm_v2
 
OksXmlTokenm_v3
 

Static Private Attributes

static OksXmlTokenPool s_tokens_pool
 

Friends

struct OksXmlAttribute
 
struct OksData
 
class OksObject
 

Detailed Description

Definition at line 359 of file xml.hpp.

Constructor & Destructor Documentation

◆ OksXmlInputStream() [1/2]

dunedaq::oks::OksXmlInputStream::OksXmlInputStream ( std::shared_ptr< std::istream > p)
inline

Definition at line 367 of file xml.hpp.

367 :
368 f(p), m_pbuf(p->rdbuf()), line_no(1), line_pos(0)
369 {
370 init();
371 };
std::streambuf * m_pbuf
Definition xml.hpp:430
std::shared_ptr< std::istream > f
Definition xml.hpp:429

◆ ~OksXmlInputStream()

dunedaq::oks::OksXmlInputStream::~OksXmlInputStream ( )
inline

Definition at line 373 of file xml.hpp.

373 {
374 std::lock_guard lock(s_tokens_pool.m_mutex);
379 }
static OksXmlTokenPool s_tokens_pool
Definition xml.hpp:441
void release(OksXmlToken *token)
Definition xml.hpp:346

◆ OksXmlInputStream() [2/2]

dunedaq::oks::OksXmlInputStream::OksXmlInputStream ( const OksXmlInputStream & )
private

Member Function Documentation

◆ __throw_eof()

void dunedaq::oks::OksXmlInputStream::__throw_eof ( ) const
private

Definition at line 614 of file xml.cpp.

615{
616 throw std::runtime_error("unexpected end of file");
617}

◆ __throw_strto()

void dunedaq::oks::OksXmlInputStream::__throw_strto ( const char * f,
const char * where,
const char * what,
unsigned long line_no,
unsigned long line_pos )
static

Definition at line 620 of file xml.cpp.

621{
622 std::ostringstream text;
623 text << "function " << f << "(\'" << what << "\') has failed";
624 if(*where) text << " on unrecognized characters \'" << where << "\'";
625 if(errno) text << " with code " << errno << ", reason = \'" << oks::strerror(errno) << '\'';
626 throw oks::BadFileData(text.str(), line_no, line_pos);
627}
const std::string strerror(int error)
Convert C error number to string.
Definition kernel.cpp:114

◆ cvt_char()

char dunedaq::oks::OksXmlInputStream::cvt_char ( )
private

Read encoded symbol (&xxx;)

Definition at line 585 of file xml.cpp.

586{
587 get_token(';', *m_cvt_char);
588
591 else if(oks::cmp_str3n(m_cvt_char->m_buf, oks::xml::ampersand + 1)) return '&';
592 else if(oks::cmp_str3n(m_cvt_char->m_buf, oks::xml::carriage_return + 1)) return '\r';
593 else if(oks::cmp_str3n(m_cvt_char->m_buf, oks::xml::new_line + 1)) return '\n';
594 else if(oks::cmp_str3n(m_cvt_char->m_buf, oks::xml::tabulation + 1)) return '\t';
595 else if(oks::cmp_str4n(m_cvt_char->m_buf, oks::xml::single_quote + 1)) return '\'';
596 else if(oks::cmp_str4n(m_cvt_char->m_buf, oks::xml::double_quote + 1)) return '\"';
597 else {
598 std::string text("bad symbol \'&");
599 text += m_cvt_char->m_buf;
600 text += '\'';
601 throw std::runtime_error(text.c_str());
602 }
603}
size_t get_token(const char s1, OksXmlToken &token)
Definition xml.cpp:423
const char left_angle_bracket[]
Definition xml.cpp:26
const char new_line[]
Definition xml.cpp:30
const char tabulation[]
Definition xml.cpp:31
const char single_quote[]
Definition xml.cpp:32
const char ampersand[]
Definition xml.cpp:28
const char right_angle_bracket[]
Definition xml.cpp:27
const char carriage_return[]
Definition xml.cpp:29
const char double_quote[]
Definition xml.cpp:33
bool cmp_str2n(const char *s1, const char s2[2])
Definition cstring.hpp:17
bool cmp_str3n(const char *s1, const char s2[3])
Definition cstring.hpp:25
bool cmp_str4n(const char *s1, const char s2[4])
Definition cstring.hpp:33

◆ eof()

bool dunedaq::oks::OksXmlInputStream::eof ( ) const
inline

Definition at line 398 of file xml.hpp.

398{ return f->eof(); }

◆ error_msg()

std::ostream & dunedaq::oks::OksXmlInputStream::error_msg ( const char * msg)

Definition at line 607 of file xml.cpp.

608{
609 return Oks::error_msg(msg)
610 << "(line " << line_no << ", char " << line_pos << ")\n";
611}
static std::ostream & error_msg(const char *)
Definition kernel.cpp:556

◆ get()

char dunedaq::oks::OksXmlInputStream::get ( )
inlineprivate

Definition at line 488 of file xml.hpp.

489{
490 char c(m_pbuf->sbumpc());
491
492 line_pos++;
493 if( __builtin_expect((c == EOF), 0) ) __throw_eof();
494 else if( __builtin_expect((c == '\n'), 0) ) { line_no++; line_pos = 0; }
495
496 return c;
497}

◆ get_first_non_empty()

char dunedaq::oks::OksXmlInputStream::get_first_non_empty ( )
inlineprivate

Definition at line 506 of file xml.hpp.

507{
508 while(true) {
509 char c(get());
510 if(c == ' ' || c == '\n' || c == '\r' || c == '\t') continue;
511 else return c;
512 }
513}

◆ get_line_no()

unsigned long dunedaq::oks::OksXmlInputStream::get_line_no ( ) const
inline

Definition at line 410 of file xml.hpp.

410{ return line_no; }

◆ get_line_pos()

unsigned long dunedaq::oks::OksXmlInputStream::get_line_pos ( ) const
inline

Definition at line 411 of file xml.hpp.

411{ return line_pos; }

◆ get_num_token()

void dunedaq::oks::OksXmlInputStream::get_num_token ( char last)

◆ get_position()

long dunedaq::oks::OksXmlInputStream::get_position ( ) const
inline

Definition at line 402 of file xml.hpp.

402 {
403 return f->tellg();
404 }

◆ get_quoted()

size_t dunedaq::oks::OksXmlInputStream::get_quoted ( )

Definition at line 290 of file xml.cpp.

291{
292 size_t pos(0);
293
294 try {
295 char c = get_first_non_empty();
296
297 if( __builtin_expect((c != '\"'), 0) ) {
299 }
300
301 while(true) {
302 c = get();
303
304 if( __builtin_expect((c == '\"'), 0) ) {
305 m_v1->m_buf[pos] = 0;
306 return pos;
307 }
308 else if( __builtin_expect((c == '&'), 0) ) {
309 c = cvt_char();
310 }
311
312 m_v1->realloc(pos);
313 m_v1->m_buf[pos++] = c;
314 }
315
316 throw std::runtime_error("cannot find closing quote character");
317 }
318 catch (std::exception & ex) {
319 m_v1->m_buf[pos] = 0;
320 throw oks::BadFileData(std::string("Failed to read quoted string: ") + ex.what(), line_no, line_pos);
321 }
322}
std::istream::pos_type pos
Definition xml.hpp:436
static void __throw_runtime_error_unexpected_symbol(const char expected, const char read)
Definition xml.cpp:100
void realloc(unsigned long pos)
Definition xml.hpp:208

◆ get_tag()

const char * dunedaq::oks::OksXmlInputStream::get_tag ( )

Definition at line 338 of file xml.cpp.

339{
340 m_v1->m_buf[0] = 0;
341
342 unsigned long start_line_no = line_no;
343 unsigned long start_line_pos = line_pos;
344
345 size_t pos(0);
346
347 try {
348 while(true) {
349 char c(get_first_non_empty());
350
351 if( __builtin_expect((c != '<'), 0) ) {
353 }
354
355 start_line_no = line_no;
356 start_line_pos = line_pos;
357
358 m_v1->m_buf[0] = c;
359 pos = 1;
360
361 int count(1);
362
363 while(true) {
364 char c2 = get();
365
366 if(c2 == '<') count++;
367 else if(c2 == '>') count--;
368
369 m_v1->realloc(pos);
370 m_v1->m_buf[pos++] = c2;
371
372 if(pos > 3) {
373 if(__is_comment(m_v1->m_buf + pos - 4)) {
374 char buf[3] = {0, 0, 0};
375 unsigned long start_comment_line_no = line_no;
376 try {
377 while(true) {
378 buf[0] = buf[1];
379 buf[1] = buf[2];
380 buf[2] = get();
381
382 if(oks::cmp_str3n(buf, "-->")) {
383 break; // end of comment = '-->'
384 }
385 }
386 }
387 catch(std::exception& failure) {
388 std::ostringstream what;
389 what << "Cannot find end of comment started on line " << start_comment_line_no << ": " << failure.what();
390 throw oks::BadFileData(what.str(), line_no, line_pos);
391 }
392
393 pos -= 4;
394 count--;
395 }
396 }
397
398 if(count == 0) {
399 m_v1->m_buf[pos] = '\0';
400 break;
401 }
402 }
403
404 if(pos > 0) {
405 if(count != 0) { throw std::runtime_error("unbalanced tags"); }
406 else { return m_v1->m_buf; }
407 }
408 }
409 }
410 catch(std::exception& ex) {
411 m_v1->m_buf[pos] = '\0';
412 throw oks::BadFileData(std::string(ex.what()) + " when read xml tag started at", start_line_no, start_line_pos);
413 }
414}
static void __throw_bad_file_data_unexpected_symbol(const char *what, const char expected, const char read, unsigned long l, unsigned long p)
Definition xml.cpp:106
bool __is_comment(const char *s)
Definition xml.cpp:327

◆ get_tag_start()

const char * dunedaq::oks::OksXmlInputStream::get_tag_start ( )

Definition at line 485 of file xml.cpp.

486{
487 try {
488 while(true) {
489 char c = get_first_non_empty();
490
491 if( __builtin_expect((c != '<'), 0) ) {
493 }
494
495 get_token5(' ', '>', '\t', '\n', '\r', *m_v1);
496 TLOG_DEBUG(8) << "read tag \'" << m_v1->m_buf << '\'';
497
498 if( __builtin_expect((oks::cmp_str3n(m_v1->m_buf, "!--")), 0) ) {
499 char buf[3] = {0, 0, 0};
500 unsigned long start_comment_line_no = line_no;
501 auto tag_len = strlen(m_v1->m_buf);
502 if(tag_len < 5 || !oks::cmp_str2n(m_v1->m_buf + tag_len- 2, "--")) // special case for comments without empty symbols like <!--foo-->
503 try {
504 while(true) {
505 buf[0] = buf[1];
506 buf[1] = buf[2];
507 c = buf[2] = get();
508 if(oks::cmp_str3n(buf, "-->")) {
509 break; // end of comment = '-->'
510 }
511 }
512 }
513 catch(std::exception& failure) {
514 std::ostringstream what;
515 what << "Cannot find end of comment started on line " << start_comment_line_no << ": " << failure.what();
516 throw oks::BadFileData(what.str(), line_no, line_pos);
517 }
518 }
519
520 if( __builtin_expect((c != '>'), 1) ) return m_v1->m_buf;
521 }
522 }
523 catch(std::exception& ex) {
524 throw oks::BadFileData(std::string("Failed to read start-of-tag: ") + ex.what(), line_no, line_pos);
525 }
526
527 return 0; // never reach this line
528}
void get_token5(const char s1, const char s2, const char s3, const char s4, const char s5, OksXmlToken &token)
Definition xml.cpp:465
#define TLOG_DEBUG(lvl,...)
Definition Logging.hpp:112

◆ get_token()

size_t dunedaq::oks::OksXmlInputStream::get_token ( const char s1,
OksXmlToken & token )
inlineprivate

Read token (one separator)

Definition at line 423 of file xml.cpp.

424{
425 size_t pos(0);
426
427 while(true) {
428 last_read_c = get();
429
430 if(last_read_c == __s1) { token.m_buf[pos] = '\0'; return pos; }
431 else if( __builtin_expect((last_read_c == '&'), 0) ) last_read_c = cvt_char();
432
433 token.realloc(pos);
434 token.m_buf[pos++] = last_read_c;
435 }
436
437 token.m_buf[pos] = 0;
438
439 throw std::runtime_error("cannot find closing separator while read token");
440}

◆ get_token2()

size_t dunedaq::oks::OksXmlInputStream::get_token2 ( char __fs,
const char s1,
const char s2,
OksXmlToken & token )
inlineprivate

Read token (two separators)

Definition at line 443 of file xml.cpp.

444{
445 size_t pos(1);
446 token.m_buf[0] = __fs;
447 if(__fs == __s1 || __fs == __s2) { token.m_buf[1] = '\0'; return 1; }
448
449 while(true) {
450 last_read_c = get();
451
452 if(last_read_c == __s1 || last_read_c == __s2) { token.m_buf[pos] = '\0'; return pos; }
453 else if( __builtin_expect((last_read_c == '&'), 0) ) last_read_c = cvt_char();
454
455 token.realloc(pos);
456 token.m_buf[pos++] = last_read_c;
457 }
458
459 token.m_buf[pos] = 0;
460
461 throw std::runtime_error("cannot find closing separator while read token");
462}

◆ get_token5()

void dunedaq::oks::OksXmlInputStream::get_token5 ( const char s1,
const char s2,
const char s3,
const char s4,
const char s5,
OksXmlToken & token )
inlineprivate

Read token (five separators)

Definition at line 465 of file xml.cpp.

466{
467 size_t pos(0);
468
469 while(true) {
470 last_read_c = get();
471
472 if(last_read_c == __s1 || last_read_c == __s2 || last_read_c == __s3 || last_read_c == __s4 || last_read_c == __s5) { token.m_buf[pos] = '\0'; return; }
473 else if( __builtin_expect((last_read_c == '&'), 0) ) last_read_c = cvt_char();
474
475 token.realloc(pos);
476 token.m_buf[pos++] = last_read_c;
477 }
478
479 token.m_buf[pos] = 0;
480
481 throw std::runtime_error("cannot find closing separator while read token");
482}

◆ get_value()

OksXmlValue dunedaq::oks::OksXmlInputStream::get_value ( unsigned int len)
inline

Definition at line 416 of file xml.hpp.

417 {
418 OksXmlValue value(m_v2, len, line_no, line_pos);
419 m_v2 = m_v3;
420 m_v3 = value.get_token();
421 return value;
422 }

◆ get_value_post()

void dunedaq::oks::OksXmlInputStream::get_value_post ( unsigned long )
inlineprivate

◆ get_value_pre()

unsigned long dunedaq::oks::OksXmlInputStream::get_value_pre ( )
inlineprivate

◆ get_xml_token()

OksXmlToken & dunedaq::oks::OksXmlInputStream::get_xml_token ( )
inline

Definition at line 413 of file xml.hpp.

413{return *m_v1;}

◆ good()

bool dunedaq::oks::OksXmlInputStream::good ( ) const
inline

Definition at line 397 of file xml.hpp.

397{ return f->good(); }

◆ init()

void dunedaq::oks::OksXmlInputStream::init ( )
inlineprivate

Definition at line 449 of file xml.hpp.

449 {
450 f->setf(std::ios::showbase, std::ios::basefield);
451 f->exceptions ( std::istream::eofbit | std::istream::failbit | std::istream::badbit );
452
453 std::lock_guard lock(s_tokens_pool.m_mutex);
458 }
OksXmlToken * get()
Definition xml.hpp:329

◆ operator=()

OksXmlInputStream & dunedaq::oks::OksXmlInputStream::operator= ( const OksXmlInputStream & )
private

◆ restore_position()

void dunedaq::oks::OksXmlInputStream::restore_position ( )
inline

Definition at line 401 of file xml.hpp.

unsigned long m_line_pos_sav
Definition xml.hpp:439
unsigned long m_line_no_sav
Definition xml.hpp:438

◆ seek_position()

void dunedaq::oks::OksXmlInputStream::seek_position ( std::streamoff off)
inline

Definition at line 406 of file xml.hpp.

406{ f->seekg(off, std::ios_base::cur); }

◆ store_position()

void dunedaq::oks::OksXmlInputStream::store_position ( )
inline

Definition at line 400 of file xml.hpp.

400{ pos = f->tellg(); m_line_no_sav = line_no; m_line_pos_sav = line_pos; }

◆ throw_unexpected_attribute()

void dunedaq::oks::OksXmlInputStream::throw_unexpected_attribute ( const char * what)

Definition at line 284 of file xml.cpp.

285{
286 throw oks::BadFileData(std::string("Value \'") + what + "\' is not a valid attribute name", line_no, line_pos);
287}

◆ throw_unexpected_tag()

void dunedaq::oks::OksXmlInputStream::throw_unexpected_tag ( const char * what,
const char * expected = 0 )

Definition at line 261 of file xml.cpp.

262{
263 std::ostringstream s;
264
265 if(!*what) {
266 if(expected) {
267 s << "expected tag \'" << expected << '\'';
268 }
269 else {
270 s << "empty tag";
271 }
272 }
273 else {
274 s << "unexpected tag \'" << what << '\'' ;
275 if(expected) {
276 s << " instead of \'" << expected << '\'' ;
277 }
278 }
279
280 throw oks::BadFileData(s.str(), line_no, line_pos);
281}

Friends And Related Symbol Documentation

◆ OksData

friend struct OksData
friend

Definition at line 362 of file xml.hpp.

◆ OksObject

friend class OksObject
friend

Definition at line 363 of file xml.hpp.

◆ OksXmlAttribute

friend struct OksXmlAttribute
friend

Definition at line 361 of file xml.hpp.

Member Data Documentation

◆ f

std::shared_ptr<std::istream> dunedaq::oks::OksXmlInputStream::f
private

Definition at line 429 of file xml.hpp.

◆ last_read_c

char dunedaq::oks::OksXmlInputStream::last_read_c
private

Definition at line 434 of file xml.hpp.

◆ line_no

unsigned long dunedaq::oks::OksXmlInputStream::line_no
private

Definition at line 431 of file xml.hpp.

◆ line_pos

unsigned long dunedaq::oks::OksXmlInputStream::line_pos
private

Definition at line 432 of file xml.hpp.

◆ m_cvt_char

OksXmlToken* dunedaq::oks::OksXmlInputStream::m_cvt_char
private

Definition at line 443 of file xml.hpp.

◆ m_line_no_sav

unsigned long dunedaq::oks::OksXmlInputStream::m_line_no_sav
private

Definition at line 438 of file xml.hpp.

◆ m_line_pos_sav

unsigned long dunedaq::oks::OksXmlInputStream::m_line_pos_sav
private

Definition at line 439 of file xml.hpp.

◆ m_pbuf

std::streambuf* dunedaq::oks::OksXmlInputStream::m_pbuf
private

Definition at line 430 of file xml.hpp.

◆ m_v1

OksXmlToken* dunedaq::oks::OksXmlInputStream::m_v1
private

Definition at line 444 of file xml.hpp.

◆ m_v2

OksXmlToken* dunedaq::oks::OksXmlInputStream::m_v2
private

Definition at line 445 of file xml.hpp.

◆ m_v3

OksXmlToken* dunedaq::oks::OksXmlInputStream::m_v3
private

Definition at line 446 of file xml.hpp.

◆ pos

std::istream::pos_type dunedaq::oks::OksXmlInputStream::pos
private

Definition at line 436 of file xml.hpp.

◆ s_tokens_pool

OksXmlTokenPool dunedaq::oks::OksXmlInputStream::s_tokens_pool
staticprivate

Definition at line 441 of file xml.hpp.


The documentation for this class was generated from the following files: