DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
xml.hpp
Go to the documentation of this file.
1// DUNE DAQ modification notice:
2// This file has been modified from the original ATLAS oks source for the DUNE DAQ project.
3// Fork baseline commit: oks-08-03-04 (2022-04-14).
4// Renamed since fork: yes (from oks/xml.h to include/oks/xml.hpp).
5
6#ifndef OKS_XML_H
7#define OKS_XML_H
8
9#include <string.h>
10
11#include <fstream>
12#include <memory>
13#include <stack>
14#include <stdexcept>
15
16#include "oks/cstring.hpp"
17#include "oks/defs.hpp"
18#include "oks/exceptions.hpp"
19
20namespace dunedaq {
21namespace oks {
22
23struct OksData;
24
25namespace xml {
26
28inline const char*
29bool2str(bool b) noexcept
30{
31 return (b ? "yes" : "no");
32}
33
35inline bool
36str2bool(const char* s) noexcept
37{
38 return oks::cmp_str3(s, "yes");
39}
40
41}
42
44
45class BadFileData : public exception
46{
47
48public:
49 BadFileData(const std::string& what, unsigned long line_no, unsigned long line_pos, int level_arg = 0) noexcept
50 : exception(fill(what, line_no, line_pos), level_arg)
51 {
52 }
53
54 virtual ~BadFileData() noexcept {}
55
56private:
57 static std::string fill(const std::string& what, unsigned long line_no, unsigned long line_pos) noexcept;
58};
59
61
62class FailedRead : public exception
63{
64
65public:
67 FailedRead(const std::string& what, const exception& reason) noexcept
68 : exception(fill(what, reason.what()), reason.level() + 1)
69 {
70 }
71
73 FailedRead(const std::string& what, const std::string& reason) noexcept
74 : exception(fill(what, reason), 0)
75 {
76 }
77
78 virtual ~FailedRead() noexcept {}
79
80private:
81 static std::string fill(const std::string& what, const std::string& reason) noexcept;
82};
83
85
86class FailedSave : public exception
87{
88
89public:
91 FailedSave(const std::string& what, const std::string& name, const exception& reason) noexcept
92 : exception(fill(what, name, reason.what()), reason.level() + 1)
93 {
94 }
95
97 FailedSave(const std::string& what, const std::string& name, const std::string& reason) noexcept
98 : exception(fill(what, name, reason), 0)
99 {
100 }
101
102 virtual ~FailedSave() noexcept {}
103
104private:
105 static std::string fill(const std::string& what, const std::string& name, const std::string& reason) noexcept;
106};
107
109{
110
111public:
112 EndOfXmlStream(const std::string& tag) noexcept
113 : exception(fill(tag), 0)
114 {
115 }
116
117 virtual ~EndOfXmlStream() noexcept {}
118
119private:
120 static std::string fill(const std::string& tag);
121};
122
123struct ReadFileParams;
124
126{
127
128public:
129 OksXmlOutputStream(std::ostream& p)
130 : f(p)
131 {
132 ;
133 }
134
135 std::ostream& get_stream() const { return f; }
136
141 void put(char c);
142
147 void put(const char* s);
148
153 void put_raw(char c)
154 {
155 if (__builtin_expect((f.rdbuf()->sputc(c) != c), 0))
157 }
158
159 void put_raw(const char* s, long len)
160 {
161 if (__builtin_expect((f.rdbuf()->sputn(s, len) != len), 0))
163 }
164
165 template<class T>
166 void put_value(T value)
167 {
168 f << value;
169 }
170
171 void put_quoted(const char*);
172
173 void put_start_tag(const char*, size_t len); // '<tag-name'
174
175 void put_end_tag(); // '/>\n'
176
177 void put_last_tag(const char*, size_t len); // '</tag-name>\n'
178
179 void put_attribute(const char*, size_t len, const char*);
180
181 void put_attribute(const char*, size_t len, uint32_t);
182
183 void put_attribute(const char*, size_t len, const OksData&);
184
185 void put_eol(); // '>\n'
186
187private:
188 std::ostream& f;
189
190 static void __throw_write_failed();
191};
192
194{
195
196 size_t m_len;
197 size_t m_len2; // (m_len - 2)
198 char* m_buf;
199
200 OksXmlToken(size_t len = 2048)
201 : m_len(len)
202 , m_len2(len - 2)
203 , m_buf(new char[len])
204 {
205 ;
206 }
207 ~OksXmlToken() { delete[] m_buf; }
208
209 void realloc(unsigned long pos)
210 {
211 if (__builtin_expect((pos >= m_len2), 0)) {
212 m_len += 2048;
213 m_len2 = m_len - 2;
214 char* ptr = new char[m_len];
215 memcpy(ptr, m_buf, pos);
216 delete[] m_buf;
217 m_buf = ptr;
218 }
219 }
220};
221
222class OksXmlInputStream;
223class OksClass;
224class OksString;
225
227{
229 unsigned int m_len;
230 unsigned int m_line_no;
231 unsigned int m_line_pos;
232
233 OksXmlValue(OksXmlToken* token = nullptr, unsigned int len = 0, unsigned int line_no = 0, unsigned int line_pos = 0)
234 : m_token(token)
235 , m_len(len)
238 {
239 ;
240 }
241
242 bool is_empty() { return (m_token == nullptr); }
243
244 OksXmlToken* get_token() const { return m_token; }
245
246 char* buf() const { return m_token->m_buf; }
247
248 unsigned int len() const { return m_len; }
249
250 unsigned int line_no() const { return m_line_no; }
251
252 unsigned int line_pos() const { return m_line_pos; }
253};
254
256{
258 : m_file_params(file_params)
259 , m_class(nullptr)
260 , m_class_id(nullptr)
261 {
262 ;
263 }
264
265 bool is_empty() { return m_value.is_empty() || (m_class == nullptr && m_class_id == nullptr); }
266
271};
272
276
278{
279
283
285
286 char* name() const { return p_name.m_buf; }
287 char* value() const { return p_value.m_buf; }
288 size_t value_len() const { return p_value_len; }
289};
290
292{
293
294 friend class OksXmlInputStream;
295
296public:
298 {
299 while (!m_tokens.empty()) {
300 OksXmlToken* t = m_tokens.top();
301 m_tokens.pop();
302 delete t;
303 }
304 }
305
306private:
311
313 {
314 if (!m_tokens.empty()) {
315 OksXmlToken* t = m_tokens.top();
316 m_tokens.pop();
317 return t;
318 } else {
319 return new OksXmlToken();
320 }
321 }
322
327
328 void release(OksXmlToken* token) { m_tokens.push(token); }
329
330private:
331 std::mutex m_mutex;
332 std::stack<OksXmlToken*> m_tokens;
333};
334
336{
337
338 friend struct OksXmlAttribute;
339 friend struct OksData;
340 friend class OksObject;
341
342public:
343 OksXmlInputStream(std::shared_ptr<std::istream> p)
344 : f(p)
345 , m_pbuf(p->rdbuf())
346 , line_no(1)
347 , line_pos(0)
348 {
349 init();
350 };
351
360
361 // get token separated by whitespace or "last" symbol
362 // put result on m_cvt_char token
363
364 void get_num_token(char last);
365
366 // throw exception
367
368 static void __throw_strto(const char* f,
369 const char* where,
370 const char* what,
371 unsigned long line_no,
372 unsigned long line_pos);
373
374 size_t get_quoted();
375
376 const char* get_tag();
377 const char* get_tag_start();
378
379 bool good() const { return f->good(); }
380 bool eof() const { return f->eof(); }
381
383 {
384 pos = f->tellg();
387 }
389 {
390 f->seekg(pos);
393 }
394 long get_position() const { return f->tellg(); }
395
396 void inline seek_position(std::streamoff off) { f->seekg(off, std::ios_base::cur); }
397
398 std::ostream& error_msg(const char*);
399
400 unsigned long get_line_no() const { return line_no; }
401 unsigned long get_line_pos() const { return line_pos; }
402
404
405 OksXmlValue get_value(unsigned int len)
406 {
407 OksXmlValue value(m_v2, len, line_no, line_pos);
408 m_v2 = m_v3;
409 m_v3 = value.get_token();
410 return value;
411 }
412
413 void throw_unexpected_tag(const char* what, const char* expected = 0);
414 void throw_unexpected_attribute(const char* what);
415
416private:
417 std::shared_ptr<std::istream> f;
418 std::streambuf* m_pbuf;
419 unsigned long line_no;
420 unsigned long line_pos;
421
423
424 std::istream::pos_type pos;
425
426 unsigned long m_line_no_sav;
427 unsigned long m_line_pos_sav;
428
430
431 OksXmlToken* m_cvt_char; // the token to be used by cvt_char()
434 OksXmlToken* m_v3; // used for swap with m_v2 to keep value of "val" attribute
435
436 void init()
437 {
438 f->setf(std::ios::showbase, std::ios::basefield);
439 f->exceptions(std::istream::eofbit | std::istream::failbit | std::istream::badbit);
440
441 std::lock_guard lock(s_tokens_pool.m_mutex);
446 }
447
448 inline size_t get_token(const char s1, OksXmlToken& token);
449 inline size_t get_token2(char, const char s1, const char s2, OksXmlToken& token);
450 inline void get_token5(const char s1,
451 const char s2,
452 const char s3,
453 const char s4,
454 const char s5,
455 OksXmlToken& token);
456 char cvt_char();
457
458 inline char get_first_non_empty();
459 inline char get();
460
461 inline unsigned long get_value_pre();
462 inline void get_value_post(unsigned long);
463
464 void __throw_eof() const;
465
466 // protect usage of copy constructor and assignment operator
467
470};
471
472//
473// Read new symbol from stream and change LINE and POS numbers.
474// Throw exception in case of I/O error or EOF
475//
476
477inline char
479{
480 char c(m_pbuf->sbumpc());
481
482 line_pos++;
483 if (__builtin_expect((c == EOF), 0))
484 __throw_eof();
485 else if (__builtin_expect((c == '\n'), 0)) {
486 line_no++;
487 line_pos = 0;
488 }
489
490 return c;
491}
492
493//
494// Read first non-null xml symbol
495// Return 0 if error
496//
497
498inline char
500{
501 while (true) {
502 char c(get());
503 if (c == ' ' || c == '\n' || c == '\r' || c == '\t')
504 continue;
505 else
506 return c;
507 }
508}
509} // namespace oks
510} // namespace dunedaq
511#endif
BadFileData(const std::string &what, unsigned long line_no, unsigned long line_pos, int level_arg=0) noexcept
Definition xml.hpp:49
virtual ~BadFileData() noexcept
Definition xml.hpp:54
static std::string fill(const std::string &what, unsigned long line_no, unsigned long line_pos) noexcept
Definition xml.cpp:58
virtual ~EndOfXmlStream() noexcept
Definition xml.hpp:117
EndOfXmlStream(const std::string &tag) noexcept
Definition xml.hpp:112
static std::string fill(const std::string &tag)
Definition xml.cpp:78
FailedRead(const std::string &what, const std::string &reason) noexcept
Definition xml.hpp:73
FailedRead(const std::string &what, const exception &reason) noexcept
Definition xml.hpp:67
virtual ~FailedRead() noexcept
Definition xml.hpp:78
static std::string fill(const std::string &what, const std::string &reason) noexcept
Definition xml.cpp:66
FailedSave(const std::string &what, const std::string &name, const std::string &reason) noexcept
Definition xml.hpp:97
FailedSave(const std::string &what, const std::string &name, const exception &reason) noexcept
Definition xml.hpp:91
static std::string fill(const std::string &what, const std::string &name, const std::string &reason) noexcept
Definition xml.cpp:72
virtual ~FailedSave() noexcept
Definition xml.hpp:102
The OKS class.
Definition class.hpp:223
Class OKS string.
Definition object.hpp:417
void throw_unexpected_attribute(const char *what)
Definition xml.cpp:291
unsigned long get_line_no() const
Definition xml.hpp:400
std::ostream & error_msg(const char *)
Definition xml.cpp:639
unsigned long m_line_pos_sav
Definition xml.hpp:427
std::streambuf * m_pbuf
Definition xml.hpp:418
OksXmlInputStream(const OksXmlInputStream &)
size_t get_token(const char s1, OksXmlToken &token)
Definition xml.cpp:430
size_t get_token2(char, const char s1, const char s2, OksXmlToken &token)
Definition xml.cpp:453
void throw_unexpected_tag(const char *what, const char *expected=0)
Definition xml.cpp:270
unsigned long get_line_pos() const
Definition xml.hpp:401
OksXmlValue get_value(unsigned int len)
Definition xml.hpp:405
void get_token5(const char s1, const char s2, const char s3, const char s4, const char s5, OksXmlToken &token)
Definition xml.cpp:481
OksXmlInputStream(std::shared_ptr< std::istream > p)
Definition xml.hpp:343
friend struct OksXmlAttribute
Definition xml.hpp:338
OksXmlInputStream & operator=(const OksXmlInputStream &)
OksXmlToken & get_xml_token()
Definition xml.hpp:403
unsigned long m_line_no_sav
Definition xml.hpp:426
void seek_position(std::streamoff off)
Definition xml.hpp:396
static void __throw_strto(const char *f, const char *where, const char *what, unsigned long line_no, unsigned long line_pos)
Definition xml.cpp:651
std::shared_ptr< std::istream > f
Definition xml.hpp:417
const char * get_tag_start()
Definition xml.cpp:510
std::istream::pos_type pos
Definition xml.hpp:424
void get_value_post(unsigned long)
static OksXmlTokenPool s_tokens_pool
Definition xml.hpp:429
void put_last_tag(const char *, size_t len)
Definition xml.cpp:215
void put_attribute(const char *, size_t len, const char *)
Definition xml.cpp:230
void put_start_tag(const char *, size_t len)
Definition xml.cpp:184
void put_raw(const char *s, long len)
Definition xml.hpp:159
static void __throw_write_failed()
Definition xml.cpp:120
OksXmlOutputStream(std::ostream &p)
Definition xml.hpp:129
void put_quoted(const char *)
Definition xml.cpp:171
std::ostream & get_stream() const
Definition xml.hpp:135
virtual const char * what() const noexcept
exception(const std::string &what_arg, int level_arg) noexcept
Definition xml.cpp:41
const char * bool2str(bool b) noexcept
Definition xml.hpp:29
bool str2bool(const char *s) noexcept
Definition xml.hpp:36
bool cmp_str3(const char *s1, const char s2[4])
Definition cstring.hpp:33
The DUNE-DAQ namespace.
Struct OKS data.
Definition object.hpp:510
size_t value_len() const
Definition xml.hpp:288
OksXmlAttribute(OksXmlInputStream &s)
Definition xml.cpp:555
OksXmlRelValue(const oks::ReadFileParams &file_params)
Definition xml.hpp:257
const oks::ReadFileParams & m_file_params
Definition xml.hpp:267
OksXmlToken * get()
Definition xml.hpp:312
std::stack< OksXmlToken * > m_tokens
Definition xml.hpp:332
friend class OksXmlInputStream
Definition xml.hpp:294
void release(OksXmlToken *token)
Definition xml.hpp:328
OksXmlToken(size_t len=2048)
Definition xml.hpp:200
void realloc(unsigned long pos)
Definition xml.hpp:209
unsigned int line_pos() const
Definition xml.hpp:252
unsigned int len() const
Definition xml.hpp:248
unsigned int line_no() const
Definition xml.hpp:250
unsigned int m_line_no
Definition xml.hpp:230
OksXmlToken * m_token
Definition xml.hpp:228
char * buf() const
Definition xml.hpp:246
OksXmlToken * get_token() const
Definition xml.hpp:244
unsigned int m_len
Definition xml.hpp:229
OksXmlValue(OksXmlToken *token=nullptr, unsigned int len=0, unsigned int line_no=0, unsigned int line_pos=0)
Definition xml.hpp:233
unsigned int m_line_pos
Definition xml.hpp:231