Jpp 21.0.0-rc.1-88-g0130508c4
the software that should make you happy
Loading...
Searching...
No Matches
JSingleFileScanner.hh
Go to the documentation of this file.
1#ifndef __JSUPPORT__JSINGLEFILESCANNER__
2#define __JSUPPORT__JSINGLEFILESCANNER__
3
4#include <string>
5#include <limits>
6#include <filesystem>
7
9#include "JLang/JTypeList.hh"
10#include "JLang/JNullType.hh"
11#include "JLang/JMultiEquals.hh"
12#include "JLang/JException.hh"
13
14#include "JSupport/JLimit.hh"
16
17
18/**
19 * \file
20 * Scanning of objects from a single file according a format that follows from the extension of each file name.
21 * \author mdejong
22 */
23namespace JSUPPORT {}
24namespace JPP { using namespace JSUPPORT; }
25
26namespace JSUPPORT {
27
29 using JLANG::JTypeList;
30 using JLANG::JTYPELIST;
31 using JLANG::JNullType;
33 using JLANG::skip_type;
35
36
37 /**
38 * Auxiliary base class for file name.
39 */
41 public std::string
42 {
43 /**
44 * Default constructor.
45 */
48
49
50 /**
51 * Constructor.
52 *
53 * \param file_name file name
54 */
55 JSingleFileScanner_t(const std::string& file_name) :
56 std::string(file_name)
57 {}
58
59
60 /**
61 * Get file name.
62 * This method constitutes a light weight wrapper to resolve symbolic links on the fly.
63 *
64 * \return file name
65 */
66 const std::string getFilename() const
67 {
68 using namespace std::filesystem;
69
70 path ps(static_cast<const std::string&>(*this));
71
72 if (is_symlink(ps)) {
73 ps = read_symlink(ps);
74 }
75
76 return ps.string();
77 }
78 };
79
80
81 /**
82 * Object reading from a list of files.
83 */
84 template<class T = JNullType>
86
87
88 /**
89 * Template specialisation of JSingleFileScanner for undefined type.\n
90 * This specialisation is used as a virtual base class for all implementations of JSingleFileScanner for defined type(s).
91 *
92 * This class is a simple container for a single file name and has an additional counter limit by extending from JSUPPORT::JLimit.\n
93 * This counter limit will be used to limit the number of calls to the method <tt>next</tt> of the derived class.\n
94 * Note that the counter limit can only be set via the member or friend methods of JSUPPORT::JLimit.
95 */
96 template<>
99 public JLimit,
100 public JMultiEquals<JSingleFileScanner<JNullType>,
101 JTYPELIST<JSingleFileScanner_t, JLimit>::typelist>
102 {
103 public:
104
106
107 /**
108 * Default constructor.
109 */
112
113
114 /**
115 * Virtual destructor.
116 */
118 {}
119
120
121 /**
122 * Configure.
123 *
124 * \param input file name
125 * \param limit limit
126 */
127 void configure(const input_type& input, const JLimit& limit)
128 {
129 static_cast<JSingleFileScanner_t&>(*this) = input;
130
131 this->setLimit(limit);
132 }
133
134
135 /**
136 * Configure.
137 *
138 * \param input file name
139 */
140 void configure(const input_type& input)
141 {
142 this->configure(input, JLimit());
143 }
144
145
146 /**
147 * Read single file scanner from input.
148 *
149 * \param in input stream
150 * \param file_name single file scanner
151 * \return input stream
152 */
153 friend inline std::istream& operator>>(std::istream& in, JSingleFileScanner& file_name)
154 {
155 return in >> static_cast<std::string&>(file_name);
156 }
157
158
159 /**
160 * Write single file scanner to output.
161 *
162 * \param out output stream
163 * \param file_name single file scanner
164 * \return output stream
165 */
166 friend inline std::ostream& operator<<(std::ostream& out, const JSingleFileScanner& file_name)
167 {
168 return out << static_cast<const std::string&>(file_name);
169 }
170 };
171
172
173 /**
174 * Object reading from a single file name.
175 *
176 * This class implements the JLANG::JRewindableObjectIterator interface.
177 */
178 template<class T>
180 public virtual JSingleFileScanner<>,
182 {
183 public:
184
187
188 /**
189 * Default constructor.
190 */
192 counter(0)
193 {}
194
195
196 /**
197 * Copy constructor.
198 *
199 * Note that the counter limit is not copied and the counter is set to zero.
200 *
201 * \param input input
202 */
203 template<class JTypelist_t>
205 counter(0)
206 {
207 this->configure(input.getFilename(), JLimit());
208 }
209
210
211 /**
212 * Constructor.
213 *
214 * \param file_name file name
215 */
216 JSingleFileScanner(const input_type& file_name) :
217 counter(0)
218 {
219 this->configure(file_name, JLimit());
220 }
221
222
223 /**
224 * Constructor.
225 *
226 * \param file_name file name
227 * \param limit limit
228 */
229 JSingleFileScanner(const input_type& file_name, const JLimit& limit) :
230 counter(0)
231 {
232 this->configure(file_name, limit);
233 }
234
235
236 /**
237 * Get counter.
238 *
239 * \return counter
240 */
242 {
243 return counter;
244 }
245
246
247 /**
248 * Rewind.
249 */
250 virtual void rewind() override
251 {
252 if (scanner.is_open()) {
253 scanner.close();
254 }
255
256 counter = 0;
257
258 scanner.reset();
259 }
260
261
262 /**
263 * Check availability of next element.
264 *
265 * \return true if the iteration has more elements; else false
266 */
267 virtual bool hasNext() override
268 {
269 if (is_valid()) {
270
271 if (counter < getUpperLimit()) {
272
273 // first time around
274
275 if (!scanner.is_open()) {
276 scanner.open(this->getFilename().c_str());
277 }
278
279 if (counter < getLowerLimit()) {
280 counter += scanner.skip(getLowerLimit() - counter);
281 }
282
283 if (!scanner.hasNext()) {
284
285 scanner.close();
286
287 return false;
288 }
289
290 return true;
291
292 } else {
293
294 // last time around
295
296 if (scanner.is_open()) {
297 scanner.close();
298 }
299
300 scanner.reset();
301 }
302 }
303
304 return false;
305 }
306
307
308 /**
309 * Get next element.
310 *
311 * \return pointer to element
312 */
313 virtual const pointer_type& next() override
314 {
315 ++counter;
316
317 return scanner.next();
318 }
319
320
321 /**
322 * Skip items.
323 *
324 * \param ns number of items to skip
325 * \return number of items skipped
326 */
327 virtual skip_type skip(const skip_type ns) override
328 {
329 const skip_type previous = counter;
330
331 counter += scanner.skip(ns);
332
333 return counter - previous;
334 }
335
336
337 protected:
340 };
341
342
343 /**
344 * Template specialisation of JSingleFileScanner for single data types.
345 *
346 * This class implements the JLANG::JRewindableObjectIterator interface for
347 * each data type.
348 * The method rewind(), rewinds each object iterator.
349 */
350 template<class JHead_t, class JTail_t>
351 class JSingleFileScanner< JTypeList<JHead_t, JTail_t> > :
352 public virtual JSingleFileScanner<>,
353 public JSingleFileScanner<JHead_t>,
354 public JSingleFileScanner<JTail_t>,
355 public JRewindableObjectIterator< JTypeList<JHead_t, JTail_t> >
356 {
357 public:
358
360
361 using JSingleFileScanner<JHead_t>::hasNext;
362 using JSingleFileScanner<JHead_t>::next;
363
364
365 /**
366 * Default constructor.
367 */
371
372
373 /**
374 * Copy constructor.
375 *
376 * Note that the counter limit is not copied and the counter is set to zero.
377 *
378 * \param input input
379 */
380 template<class JTypelist_t>
382 {
383 this->configure(input.getFilename(), JLimit());
384 }
385
386
387 /**
388 * Constructor.
389 *
390 * \param file_name file name
391 */
393 {
394 this->configure(file_name, JLimit());
395 }
396
397
398 /**
399 * Constructor.
400 *
401 * \param file_name file name
402 * \param limit limit
403 */
404 JSingleFileScanner(const input_type& file_name, const JLimit& limit)
405 {
406 this->configure(file_name, limit);
407 }
408
409
410 /**
411 * Rewind.\n
412 * This method rewinds the JSingleFileScanner for each data type.
413 */
414 virtual void rewind() override
415 {
418 }
419
420
421 /**
422 * Skip items.
423 *
424 * \param ns number of items to skip
425 * \return number of items skipped
426 */
427 virtual skip_type skip(const skip_type ns) override
428 {
429 if (JSingleFileScanner<JHead_t>::skip(ns) == ns &&
431 return ns;
432 else
433 THROW(JException, "JSingleFileScanner::skip(): inconsistent number of items skipped.");
434 }
435 };
436
437
438 /**
439 * Terminator class of recursive JSingleFileScanner class.
440 */
441 template<class JHead_t>
443 public JSingleFileScanner<JHead_t>
444 {
445 public:
446
448
449 /**
450 * Default constructor.
451 */
453 JSingleFileScanner<JHead_t>()
454 {}
455
456
457 /**
458 * Copy constructor.
459 *
460 * Note that the counter limit is not copied and the counter is set to zero.
461 *
462 * \param input input
463 */
464 template<class JTypelist_t>
466 {
467 this->configure(input.getFilename(), JLimit());
468 }
469
470
471 /**
472 * Constructor.
473 *
474 * \param file_name file name
475 */
476 JSingleFileScanner(const input_type& file_name) :
477 JSingleFileScanner<JHead_t>()
478 {
479 this->configure(file_name, JLimit());
480 }
481
482
483 /**
484 * Constructor.
485 *
486 * \param file_name file name
487 * \param limit limit
488 */
489 JSingleFileScanner(const input_type& file_name, const JLimit& limit) :
490 JSingleFileScanner<JHead_t>()
491 {
492 this->configure(file_name, limit);
493 }
494 };
495}
496
497#endif
Exceptions.
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Auxiliaries for defining the range of iterations of objects.
General exception.
Definition JException.hh:25
Interface for object iteration with rewinding.
Object reading from file.
friend std::ostream & operator<<(std::ostream &out, const JSingleFileScanner &file_name)
Write single file scanner to output.
void configure(const input_type &input, const JLimit &limit)
Configure.
friend std::istream & operator>>(std::istream &in, JSingleFileScanner &file_name)
Read single file scanner from input.
void configure(const input_type &input)
Configure.
virtual ~JSingleFileScanner()
Virtual destructor.
JSingleFileScanner(const input_type &file_name, const JLimit &limit)
Constructor.
JSingleFileScanner(const JSingleFileScanner< JTypelist_t > &input)
Copy constructor.
JSingleFileScanner(const input_type &file_name, const JLimit &limit)
Constructor.
virtual skip_type skip(const skip_type ns) override
Skip items.
JSingleFileScanner(const JSingleFileScanner< JTypelist_t > &input)
Copy constructor.
Object reading from a list of files.
JSingleFileScanner()
Default constructor.
virtual void rewind() override
Rewind.
JRewindableObjectIterator< T >::pointer_type pointer_type
virtual bool hasNext() override
Check availability of next element.
counter_type getCounter() const
Get counter.
virtual const pointer_type & next() override
Get next element.
JSingleFileScanner(const input_type &file_name)
Constructor.
virtual skip_type skip(const skip_type ns) override
Skip items.
JSingleFileScanner(const JSingleFileScanner< JTypelist_t > &input)
Copy constructor.
JSingleFileScanner(const input_type &file_name, const JLimit &limit)
Constructor.
JSingleFileScanner ::input_type input_type
std::string getFilename(const std::string &file_name)
Get file name part, i.e. part after last JEEP::PATHNAME_SEPARATOR if any.
unsigned int skip_type
Type definition for number of objects to skip.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Long64_t counter_type
Type definition for counter.
bool is_valid(const json &js)
Check validity of JSon data.
Support classes and methods for experiment specific I/O.
void configure(const T &value, const JAbstractCollection< JAbscissa_t > &bounds, std::false_type option)
Configuration of value.
Template definition of auxiliary base class for data structures composed of multiple base classes wit...
Auxiliary class for no type definition.
Definition JNullType.hh:19
Auxiliary class for recursive type list generation.
Definition JTypeList.hh:351
Type list.
Definition JTypeList.hh:23
Auxiliary class for defining the range of iterations of objects.
Definition JLimit.hh:45
Auxiliary base class for file name.
const std::string getFilename() const
Get file name.
JSingleFileScanner_t()
Default constructor.
JSingleFileScanner_t(const std::string &file_name)
Constructor.