NCBI C++ ToolKit
row_reader.hpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 #ifndef UTIL___ROW_READER__HPP
2 #define UTIL___ROW_READER__HPP
3 
4 /* $Id: row_reader.hpp 82351 2018-05-23 12:13:23Z ivanov $
5 * ===========================================================================
6 *
7 * PUBLIC DOMAIN NOTICE
8 * National Center for Biotechnology Information
9 *
10 * This software/database is a "United States Government Work" under the
11 * terms of the United States Copyright Act. It was written as part of
12 * the author's official duties as a United States Government employee and
13 * thus cannot be copyrighted. This software/database is freely available
14 * to the public for use. The National Library of Medicine and the U.S.
15 * Government have not placed any restriction on its use or reproduction.
16 *
17 * Although all reasonable efforts have been taken to ensure the accuracy
18 * and reliability of the software and data, the NLM and the U.S.
19 * Government do not and cannot warrant the performance or results that
20 * may be obtained by using this software or data. The NLM and the U.S.
21 * Government disclaim all warranties, express or implied, including
22 * warranties of performance, merchantability or fitness for any particular
23 * purpose.
24 *
25 * Please cite the author in any work or product based on this material.
26 *
27 * ===========================================================================
28 *
29 * Authors: Design and advice - Denis Vakatov
30 * Implementation and critique - Sergey Satskiy
31 *
32 * Special credits: Wratko Hlavina, Alex Astashin, Mike Dicuccio
33 *
34 * File Description:
35 * CRowReader - generic API to work with row streams
36 ** ===========================================================================
37 */
38 
39 #include <corelib/ncbistd.hpp>
40 #include <corelib/ncbifile.hpp>
41 
42 
44 
45 
46 /// Position in the data stream (zero based)
47 typedef Uint8 TStreamPos;
48 
49 /// Line number (in the data stream, zero based)
50 typedef Uint8 TLineNo;
51 
52 /// Field number (zero based)
53 typedef Uint4 TFieldNo;
54 
55 
56 /// Basic field data types
57 /// @note
58 /// The row reader does not perform any data conversion by itself.
59 /// It is up to the user to set a certain field type and how to use it
60 /// further. The row reader merely provides a storage for the user
61 /// provided field data types.
63  eRR_String, ///< string
64  eRR_Boolean, ///< bool
65  eRR_Integer, ///< int
66  eRR_Double, ///< double
67  eRR_DateTime ///< CTime
68 };
69 
70 
71 
72 /// Basic or an extended field type with an added arbitrary string property.
73 /// The string property serves the purpose of special treatment of a field.
74 /// At the moment there is only one case supported:
75 /// if instantiated for ERR_FieldType and the field type is provided as
76 /// eRR_DateTime then the string stores a format string.
77 template <class TFieldType>
79 {
80 public:
81  CRR_FieldType(TFieldType field_type, const string& field_props = string())
82  : m_Type(field_type),
83  m_Props(field_props)
84  {}
85 
87  {}
88 
89 public:
90  TFieldType GetType(void) const
91  {
92  return m_Type;
93  }
94 
95  string GetProps(void) const
96  {
97  return m_Props;
98  }
99 
100 private:
101  TFieldType m_Type;
102  string m_Props;
103 };
104 
105 
106 
107 /// Row type
109  eRR_Data, ///< row contains data
110  eRR_Comment, ///< row contains a comment
111  eRR_Metadata, ///< row contains metadata
112  eRR_Invalid ///< row is invalid
113 };
114 
115 
116 /// Whether to check validity of the fields (names and/or values)
118  eRR_NoFieldValidation, ///< don't validate fields' value and name
119  eRR_FieldValidation ///< check that the field's value (or name) is valid
120 };
121 
122 
123 // Forward declarations
124 template <typename TTraits> class CRowReader;
125 template <typename TTraits> class CRR_Row;
126 
127 
128 #define UTIL___ROW_READER_INCLUDE__INL
129 #include "row_reader.inl"
130 #undef UTIL___ROW_READER_INCLUDE__INL
131 
132 
133 /// A single field in a row abstraction.
134 template <typename TTraits>
136 {
137 public:
138  /// Get the converted field value
139  /// @return
140  /// Converted field value
141  /// @note
142  /// Available specializations: string, bool, ints, floats, CTime
143  /// @exception
144  /// Throws an exception if there is conversion problem or the field
145  /// value is NULL
146  template <typename TValue>
147  TValue Get(void) const;
148 
149  /// Get the converted field value
150  /// @param default_value
151  /// Default value if the field was translated to NULL
152  /// @return
153  /// Converted field value or a default value
154  /// @note
155  /// Available specializations: string, bool, ints, floats, CTime
156  /// @exception
157  /// Throws an exception if there is conversion problem
158  template <typename TValue> TValue
159  GetWithDefault(const TValue& default_value) const;
160 
161  /// Get the field value converted to CTime
162  /// @param fmt
163  /// CTime format
164  /// @return
165  /// Converted to CTime field value
166  /// @exception
167  /// Throws an exception if there is conversion problem or the field
168  /// value was translated to NULL
169  CTime Get(const CTimeFormat& fmt) const;
170 
171  /// Check if the field value is NULL
172  /// @return
173  /// true if the field value is NULL
174  bool IsNull(void) const;
175 
176  /// Get the field original data
177  /// @return
178  /// The field original data
179  const CTempString GetOriginalData(void) const;
180 
181  // Construct an empty field
182  CRR_Field();
183 
184  // Copy constructor of a field
185  CRR_Field(const CRR_Field& field);
186 
187  // Moving coonstructor of a field
188  CRR_Field(const CRR_Field&& other_field);
189 
190  // Assignment
191  CRR_Field& operator=(const CRR_Field& other_field);
192 
193  // Moving assignment
194  CRR_Field& operator=(const CRR_Field&& other_field);
195 
196 private:
198 
199 private:
200  friend class CRowReader<TTraits>;
201  friend class CRR_Row<TTraits>;
202 
203  // Used only when copying is done
205 
206  bool m_IsNull;
210 
211  // Needs to provide a stream context in the exceptions if a row has not
212  // been copied yet.
214 };
215 
216 
217 
218 /// Represents one row from an input stream
219 template <typename TTraits>
220 class CRR_Row
221 {
222 public:
223  /// Construct an empty row
224  CRR_Row();
225 
226  // Construct a copy
227  CRR_Row(const CRR_Row& other_row);
228 
229  // Moving constructor of a row
230  CRR_Row(const CRR_Row&& other_row);
231 
232  // Assignment
233  CRR_Row& operator=(const CRR_Row& other_row);
234 
235  // Moving assignment
236  CRR_Row& operator=(const CRR_Row&& other_row);
237 
238  /// Get a row field
239  /// @param field
240  /// 0-based field number
241  /// @return
242  /// A reference to the field
243  /// @exception
244  /// Throws an exception in case if the field does not exist
245  const CRR_Field<TTraits>& operator[](TFieldNo field) const;
246 
247  /// Get a row field
248  /// @param field
249  /// Field name
250  /// @return
251  /// A reference to the field
252  /// @exception
253  /// Throws an exception in case if the field name is unknown or
254  /// if the field does not exist
255  const CRR_Field<TTraits>& operator[](CTempString field) const;
256 
257  /// Get the row type
258  /// @return
259  /// Row type
260  ERR_RowType GetType(void) const;
261 
262  /// Get the number of fields in the row
263  /// @return
264  /// The number of fields in the row
265  TFieldNo GetNumberOfFields(void) const;
266 
267  /// Get the row original data
268  /// @return
269  /// The row original data
270  CTempString GetOriginalData(void) const;
271 
272  /// Get the number of a fields for which any kind of meta info is provided.
273  /// @return
274  /// Number of fields for which any kind of meta info is provided
275  TFieldNo GetDescribedFieldCount(void) const;
276 
277  struct SFieldMetaInfo {
278  public:
282  {}
283 
285 
287  string name;
288 
291 
294  };
295 
296  /// Get the collected fields meta info.
297  /// @param from
298  /// Field number to start from
299  /// @param to
300  /// Field number to end with
301  /// @return
302  /// A vector of structures with a meta information about fields.
303  /// If a field has no meta information then the vector will not have a
304  /// corresponding structure.
305  /// The fields interval is inclusive.
306  vector<SFieldMetaInfo> GetFieldsMetaInfo
307  (TFieldNo from = 0,
309 
310 private:
311  friend class CRowReader<TTraits>;
312 
313  void x_OnFreshRead(void);
314  void x_AdjustFieldsSize(size_t new_size);
315  void x_CopyFields(const CRR_Row& other_row);
316  void x_SetFieldName(TFieldNo field, const string& name, bool user_init);
317  void x_SetFieldType(
318  TFieldNo field,
320  bool user_init);
321  void x_SetFieldTypeEx(
322  TFieldNo field,
325  bool user_init);
326  void x_ClearFieldsInfo(void);
328  void x_DetachMetaInfo(void);
329  TFieldNo x_GetFieldIndex(CTempString field) const;
330 
331 private:
332  string m_RawData;
335  mutable bool m_Copied;
336 
337  // The content of the vector is reused so there is a manual control
338  // over what the current size/capacity is
339  vector<CRR_Field<TTraits>> m_Fields;
340  size_t m_FieldsSize;
342 
343  // Needs to provide a stream context in the exceptions if a row has not
344  // been copied yet.
346 };
347 
348 
349 
350 /// Callback style template to iterate over a row stream.
351 /// The template provides a framework while the data source specifics are
352 /// implemented via stream traits. The stream traits are supplied in the
353 /// template parameter and must meet certain interface requirements.
354 /// The requirements are described in the CRowReaderStream_Base
355 /// class vanilla implementation of the traits (see row_reader_base.hpp)
356 template <typename TTraits>
358 {
359 public:
362 
363  /// Construct a row reader.
364  /// @note
365  /// If a row reader is constructed this way then the SetDataSource(...)
366  /// must be called before the first read from a source. Otherwise an
367  /// exception will be generated.
368  CRowReader();
369 
370  /// Construct a row reader
371  /// @param is
372  /// Input stream to read rows from
373  /// @param sourcename
374  /// Data source name
375  /// @param ownership
376  /// If set to eTakeOwnership then the stream will be owned by
377  /// CRowReader -- and automatically deleted when necessary
379  const string& sourcename,
380  EOwnership ownership = eNoOwnership);
381 
382  /// Construct a row reader out of a file
383  /// @param filename
384  /// File to read rows from
385  /// @note
386  /// The file will be opened immediately (and, using TTraits-specific mode)
387  /// @exception
388  /// Throws exceptions (in particular) if the file does not exist or there
389  /// are no read permissions
390  CRowReader(const string& filename);
391 
392  virtual ~CRowReader();
393 
394  /// Switch to processing data from another stream
395  /// @note
396  /// The stream's row iterator will still point to the current row in the
397  /// previous data source. Next call to CRowReader::begin() or
398  /// to iterator's operator++ will retrieve the data from the new stream.
399  /// @param is
400  /// Input stream to read rows from
401  /// @param sourcename
402  /// Data source name
403  /// @param ownership
404  /// If set to eTakeOwnership then the stream will be owned by
405  /// CRowReader -- and automatically deleted when necessary
406  void SetDataSource(CNcbiIstream* is,
407  const string& sourcename,
408  EOwnership ownership = eNoOwnership);
409 
410  /// Switch to processing data from another file
411  /// @note
412  /// The stream's row iterator will still point to the current row in the
413  /// previous data source. Next call to CRowReader::begin() or
414  /// to iterator's operator++ will retrieve the data from the new file.
415  /// @param filename
416  /// File to read rows from
417  /// @note
418  /// The file will be opened immediately (and, using TTraits-specific mode)
419  /// @exception
420  /// Throws exceptions (in particular) if the file does not exist or there
421  /// are no read permissions
422  void SetDataSource(const string& filename);
423 
424  /// Read and validate-only the stream, calling
425  /// TTraits::Validate(row, validation_mode) on each row
426  void Validate(typename TTraits::ERR_ValidationMode validation_mode
427  = TTraits::eRR_ValidationMode_Default,
428  ERR_FieldValidationMode field_validation_mode
430 
431  /// Get the number of the line that is currently being processed
432  /// @return
433  /// 0-based number of the currently processed line (in the current
434  /// data source)
435  /// @note
436  /// This method can also be safely used inside the TTraits methods
437  /// @exception
438  /// Throws an exception if called before any line was read
439  TLineNo GetCurrentLineNo(void) const;
440 
441  /// Get the absolute position (in the current data source) of the
442  /// beginning of the row that is currently being processed
443  /// @return
444  /// 0-based absolute position of the beginning of the currently processed
445  /// row
446  /// @note
447  /// This method can also be safely used in the TTraits methods
448  /// @exception
449  /// Throws an exception if called before any line was read
450  TStreamPos GetCurrentRowPos(void) const;
451 
452  /// Set the field name
453  /// @note
454  /// If the names are set then the fields can be referred to by their names
455  /// @param field
456  /// 0-based field number. The new name overrides the previously set if so.
457  /// @param name
458  /// The field name
459  void SetFieldName(TFieldNo field, const string& name);
460 
461  /// Set the (basic) data type of the field
462  /// @param field
463  /// 0-based field number. The new type overrides the previously set if so.
464  /// @param type
465  /// The field type
466  void SetFieldType
467  (TFieldNo field,
469 
470  /// Set the (trait specific) data type of the field
471  /// @param field
472  /// 0-based field number. The new types override the previously set if so.
473  /// @param type
474  /// The field type
475  /// @param extended_type
476  /// The field extended type
477  void SetFieldTypeEx
478  (TFieldNo field,
481 
482  /// Get the collected fields meta info.
483  /// @param from
484  /// Field number to start from
485  /// @param to
486  /// Field number to end with
487  /// @return
488  /// A vector of structures with a meta information about fields.
489  /// If a field has no meta information then the vector will not have a
490  /// corresponding structure.
491  /// The fields interval is inclusive.
492  vector<typename CRR_Row<TTraits>::SFieldMetaInfo> GetFieldsMetaInfo
493  (TFieldNo from = 0,
495 
496  /// Get the number of a fields for which any kind of meta info is provided.
497  /// @return
498  /// Number of fields for which any kind of meta info is provided
499  TFieldNo GetDescribedFieldCount(void) const;
500 
501  /// Clear the information about all field names, types and extended types
502  /// @note
503  /// SetDataSource() calls by themselves don't clear the info
504  /// (although it indeed may be changed, as usual, while reading new
505  /// metainfo from the data source)
506  void ClearFieldsInfo(void);
507 
508  /// Get the traits object
509  /// @return
510  /// A reference to the traits instance currently used
511  TTraits& GetTraits(void);
512 
513 public:
514 
515  /// A (forward-only) iterator to iterate over the rows from a stream
516  ///
517  /// All iterators related to the same instance of CRowReader
518  /// are in fact pointing to the one and the same row -- the (current) one
519  /// that the CRowReader has advanced to so far.
520  ///
521  /// @attention
522  /// The iterator's data is destroyed after the iterator is advanced.
524  {
525  public:
526  /// Get a row field
527  /// @param field
528  /// 0-based field number
529  /// @return
530  /// A reference to the field
531  /// @exception
532  /// Throws an exception in case if:
533  /// - the iterator has reached the end
534  /// - the field does not exist
535  const CRR_Field<TTraits>& operator[](TFieldNo field) const;
536 
537  /// Get a row field
538  /// @param field
539  /// Field name
540  /// @return
541  /// A reference to the field
542  /// @exception
543  /// Throws an exception in case if:
544  /// - the iterator has reached the end
545  /// - the field name is unknown
546  /// - the field does not exist
547  const CRR_Field<TTraits>& operator[](CTempString field) const;
548 
549  /// Get a reference to the current row
550  /// @return
551  /// A reference to the current row
552  /// @exception
553  /// Throws an exception if the iterator has reached the end
554  CRR_Row<TTraits>& operator* (void) const;
555 
556  /// Get a pointer to the current row
557  /// @return
558  /// A pointer to the current row
559  /// @exception
560  /// Throws an exception if the iterator has reached the end
561  CRR_Row<TTraits>* operator->(void) const;
562 
563  /// Compare this iterator with another
564  /// @attention
565  /// This and/or "iter" iterator must be "end()"
566  /// @param iter
567  /// RHS iterator to compare
568  /// @return
569  /// true if either of the following is true:
570  /// - this iterator points to the end of the same
571  /// underlying data source (SetDataSource() wise) as the
572  /// contemporary "end()"
573  /// - both iterators are "end()"
574  /// - both iterators are not at end
575  /// @exception
576  /// Throw if the compared iterators belong to different streams
577  bool operator==(const CRowIterator& iter) const;
578 
579  /// This is an exact negation of operator==
580  /// @sa operator==
581  bool operator!=(const CRowIterator& iter) const;
582 
583  // Iterator copy constructor
584  CRowIterator(const CRowIterator& iter);
585 
586  ~CRowIterator();
587 
588  CRowIterator& operator=(const CRowIterator& iter);
589 
590  /// Advance the iterator to the next row
591  /// @note
592  /// The next row can be in the next data source (if set using
593  /// SetDataSource()). In this case the ++ operator can
594  /// be legally applied to an iterator that points to the "end()" of
595  /// the previous data source.
596  /// @return
597  /// A reference to self
598  /// @exception
599  /// Throws an exception if any of the following happens:
600  /// - the iterator has already reached the end of its current(!)
601  /// data source
602  /// - the iterator belongs to another instance of CRowReader
603  /// @attention
604  /// The data that was previously obtained through the iterator is
605  /// invalidated.
606  /// Because all iterators related to the same instance of
607  /// CRowReader are in fact pointing to the one and the same
608  /// row so advancing any iterator will advance all iterators that
609  /// belong to the same stream.
610  CRowIterator& operator++(void);
611 
612  private:
615 
616  friend class CRowReader<TTraits>;
617 
618  CRowIterator(CRowReader<TTraits>* s, bool is_end);
619  CRowIterator(const CRowReader<TTraits>* s, bool is_end);
620  void x_CheckDereferencing(void) const;
621  void x_CheckAdvancing(void) const;
622  void x_CheckFieldAccess(void) const;
623  };
624 
625  /// It works exactly(!) like CRowIterator::operator++, except it creates
626  /// new iterator and therefore can also be used to create the very
627  /// first iterator.
628  CRowIterator begin(void);
629 
630  /// Get iterator pointing to the end of the current underlying data source
631  CRowIterator end(void) const;
632 
635 
636  /// Get basic context. It includes (if available) a data source name,
637  /// a position in the stream, the current line and the current row data.
638  /// @return
639  /// Basic context structure
640  CRR_Context GetBasicContext(void) const;
641 
642  /// Get traits context
643  /// @return
644  /// Traits current context
645  /// @note
646  /// Traits may extend the basic context (by deriving from it) or use
647  /// CRR_Context as is
648  typename TTraits::TRR_Context GetContext(void) const;
649 
650 private:
651  friend TTraits;
652 
653  bool x_GetRowData(size_t* phys_lines_read);
654  void x_ReadNextRow(void);
655  void x_OpenFile(SRR_SourceInfo& stream_info);
656  void x_Reset(void);
657  void x_ResetToEnd(void);
658  void x_UpdateCurrentLineNo(size_t phys_lines_read);
659 
660  // Three SetField...() methods are for the traits in opposite to the
661  // 'user' available methods SetField...(...)
662  void x_SetFieldName(TFieldNo field, const string& name);
663  void x_SetFieldType(
664  TFieldNo field,
666  void x_SetFieldTypeEx(
667  TFieldNo field,
670 
672 
675 
676 private:
677  // Note: it was decided that when an underlying data stream is switched the
678  // original one must stay intact till the first iteration over the next
679  // stream. So two structures are introduced below.
680  // Each of the structures holds an information about a stream, an ownership
681  // on it and a file name if so.
684 
685  // End of the current stream flag
686  bool m_AtEnd;
687 
695 
696  // if true => within the validate() loop
698 
699  // Note: this member is needed in a very limited scope within one method to
700  // support the tokenization stage. So from the maintainability point of
701  // view the variable had to be right there. However it was decided to do an
702  // optimization (without having any profiling to see if this is a
703  // performance bottleneck) and to reuse the tokens vector. Thus the
704  // variable scope was extended to the class scope introducing a pollution.
705  vector<CTempString> m_Tokens;
706 
707  // Note: instead of having two booleans here it is is possible to use just
708  // one because they are always in oppisite states. However the code looks
709  // easier to read if there are separate variables. Bearing in mind that the
710  // state switching happens only at the moment a stream is switched it seems
711  // acceptable (from the performance POV) to have two variables.
714 
715 private:
716  // prohibit assignment and copy-ctor
717  CRowReader(const CRowReader&) = delete;
718  CRowReader(CRowReader&&) = delete;
719  CRowReader& operator=(const CRowReader&) = delete;
721 };
722 
723 
724 
725 // Begin of the CRR_Field implementation
726 
727 template <typename TTraits>
729 {
730  if (m_RowReader == nullptr)
731  return CTime(x_GetStringValue(), fmt);
732  try {
733  return CTime(x_GetStringValue(), fmt);
734  } catch (CRowReaderException& exc) {
735  exc.SetContext(m_RowReader->GetBasicContext().Clone());
736  throw exc;
737  } catch (const CException& exc) {
738  NCBI_RETHROW2(exc, CRowReaderException, eFieldConvert,
739  "Cannot convert field value to CTime using "
740  "format " + fmt.GetString(),
741  m_RowReader->GetBasicContext().Clone());
742  } catch (const exception& exc) {
743  NCBI_THROW2(CRowReaderException, eFieldConvert,
744  exc.what(), m_RowReader->GetBasicContext().Clone());
745  } catch (...) {
746  NCBI_THROW2(CRowReaderException, eFieldConvert,
747  "Unknown error while converting field value to "
748  "CTime using format " + fmt.GetString(),
749  m_RowReader->GetBasicContext().Clone());
750  }
751 }
752 
753 
754 template <typename TTraits>
755 template <typename TValue>
756 TValue CRR_Field<TTraits>::Get(void) const
757 {
758  TValue val;
759  if (m_RowReader == nullptr) {
760  CRR_Util::GetFieldValueConverted(x_GetStringValue(), val);
761  } else {
762  try {
763  CRR_Util::GetFieldValueConverted(x_GetStringValue(), val);
764  } catch (CRowReaderException& exc) {
765  exc.SetContext(m_RowReader->GetBasicContext().Clone());
766  throw exc;
767  } catch (const CException& exc) {
768  NCBI_RETHROW2(exc, CRowReaderException, eFieldConvert,
769  "Cannot convert field value to " +
770  string(typeid(TValue).name()),
771  m_RowReader->GetBasicContext().Clone());
772  } catch (const exception& exc) {
773  NCBI_THROW2(CRowReaderException, eFieldConvert,
774  exc.what(), m_RowReader->GetBasicContext().Clone());
775  } catch (...) {
776  NCBI_THROW2(CRowReaderException, eFieldConvert,
777  "Unknown error while converting field value to " +
778  string(typeid(TValue).name()),
779  m_RowReader->GetBasicContext().Clone());
780  }
781  }
782  return val;
783 }
784 
785 
786 template <typename TTraits>
787 template <typename TValue> TValue
788 CRR_Field<TTraits>::GetWithDefault(const TValue& default_value) const
789 {
790  if (m_IsNull)
791  return default_value;
792  return Get<TValue>();
793 }
794 
795 
796 template <typename TTraits>
798 {
799  return m_IsNull;
800 }
801 
802 
803 template <typename TTraits>
805 {
806  return m_OriginalData;
807 }
808 
809 
810 template <typename TTraits>
812  m_IsNull(false), m_Translated(false),
813  m_OriginalData(nullptr, 0), m_RowReader(nullptr)
814 {}
815 
816 
817 template <typename TTraits>
819  m_OriginalDataCopy(other_field.m_OriginalData.data(),
820  other_field.m_OriginalData.size()),
821  m_IsNull(other_field.m_IsNull),
822  m_Translated(other_field.m_Translated),
823  m_OriginalData(m_OriginalDataCopy.data(), m_OriginalDataCopy.size()),
824  m_TranslatedValue(other_field.m_TranslatedValue),
825  m_RowReader(nullptr)
826 {}
827 
828 
829 template <typename TTraits>
831  m_OriginalDataCopy(std::move(other_field.m_OriginalDataCopy)),
832  m_IsNull(other_field.m_IsNull),
833  m_Translated(other_field.m_Translated),
834  m_OriginalData(m_OriginalDataCopy.data(), m_OriginalDataCopy.size()),
835  m_TranslatedValue(std::move(other_field.m_TranslatedValue)),
836  m_RowReader(other_field.m_RowReader)
837 {}
838 
839 
840 template <typename TTraits>
842 {
843  if (this != &other_field) {
844  m_OriginalDataCopy.assign(other_field.m_OriginalData.data(),
845  other_field.m_OriginalData.size());
846  m_IsNull = other_field.m_IsNull;
847  m_Translated = other_field.m_Translated;
848  m_OriginalData.assign(m_OriginalDataCopy.data(),
849  m_OriginalDataCopy.size());
850  m_TranslatedValue = other_field.m_TranslatedValue;
851  m_RowReader = nullptr;
852  }
853  return *this;
854 }
855 
856 
857 template <typename TTraits>
859 {
860  if (this != &other_field) {
861  m_OriginalDataCopy = std::move(other_field.m_OriginalDataCopy);
862  m_IsNull = other_field.m_IsNull;
863  m_Translated = other_field.m_Translated;
864  m_OriginalData.assign(m_OriginalDataCopy.data(),
865  m_OriginalDataCopy.size());
866  m_TranslatedValue = std::move(other_field.m_TranslatedValue);
867  m_RowReader = other_field.m_RowReader;
868  }
869  return *this;
870 }
871 
872 
873 template <typename TTraits>
875 {
876  if (m_IsNull)
877  NCBI_THROW2(CRowReaderException, eNullField,
878  "The field value is translated to NULL", nullptr);
879  if (m_Translated)
880  return m_TranslatedValue;
881  return m_OriginalData;
882 }
883 
884 // End of the CRR_Field implementation
885 
886 
887 
888 // Begin of the CRR_Row implementation
889 
890 template <typename TTraits>
892  m_RowType(eRR_Invalid),
893  m_MetaInfo(new CRR_MetaInfo<TTraits>()),
894  m_Copied(false),
895  m_FieldsSize(0),
896  m_FieldsCapacity(0),
897  m_RowReader(nullptr)
898 {}
899 
900 
901 template <typename TTraits>
903  m_RawData(other_row.m_RawData),
904  m_RowType(other_row.m_RowType),
905  m_MetaInfo(other_row.m_MetaInfo),
906  m_Copied(false),
907  m_FieldsSize(0),
908  m_FieldsCapacity(0),
909  m_RowReader(nullptr)
910 {
911  x_CopyFields(other_row);
912  other_row.m_Copied = true;
913 }
914 
915 
916 template <typename TTraits>
918 {
919  if (this != &other_row) {
920  m_RawData = other_row.m_RawData;
921  m_RowType = other_row.m_RowType;
922  m_MetaInfo = other_row.m_MetaInfo;
923  m_Copied = false;
924  m_RowReader = nullptr;
925 
926  x_CopyFields(other_row);
927  other_row.m_Copied = true;
928  }
929  return *this;
930 }
931 
932 
933 template <typename TTraits>
934 CRR_Row<TTraits>::CRR_Row(const CRR_Row&& other_row) :
935  m_RawData(std::move(other_row.m_RawData)),
936  m_RowType(other_row.m_RowType),
937  m_MetaInfo(std::move(other_row.m_MetaInfo)),
938  m_Copied(other_row.m_Copied),
939  m_Fields(std::move(other_row.m_Fields)),
940  m_FieldsSize(other_row.m_FieldsSize),
941  m_FieldsCapacity(other_row.m_FieldsCapacity),
942  m_RowReader(other_row.m_RowReader)
943 {}
944 
945 
946 template <typename TTraits>
948 {
949  m_RawData = std::move(other_row.m_RawData);
950  m_RowType = other_row.m_RowType;
951  m_MetaInfo = std::move(other_row.m_MetaInfo);
952  m_Copied = other_row.m_Copied;
953  m_Fields = std::move(other_row.m_Fields);
954  m_FieldsSize = other_row.m_FieldsSize;
955  m_FieldsCapacity = other_row.m_FieldsCapacity;
956  m_RowReader = other_row.m_RowReader;
957 }
958 
959 
960 template <typename TTraits>
962 {
963  if (field >= GetNumberOfFields()) {
964  CRR_Context* ctxt = nullptr;
965  if (m_RowReader != nullptr)
966  ctxt = m_RowReader->GetBasicContext().Clone();
967 
968  NCBI_THROW2(CRowReaderException, eFieldNoOutOfRange,
969  "Field index " + NStr::NumericToString(field) +
970  " is out of range for the current row", ctxt);
971  }
972  return m_Fields[field];
973 }
974 
975 
976 template <typename TTraits>
977 const CRR_Field<TTraits>&
979 {
980  TFieldNo index = x_GetFieldIndex(field);
981  if (index >= GetNumberOfFields()) {
982  CRR_Context* ctxt = nullptr;
983  if (m_RowReader != nullptr)
984  ctxt = m_RowReader->GetBasicContext().Clone();
985 
986  NCBI_THROW2(CRowReaderException, eFieldNoOutOfRange,
987  "Field index " + NStr::NumericToString(index) +
988  " provided for the field name '" + field +
989  "' is out of range for the current row", ctxt);
990  }
991  return m_Fields[index];
992 }
993 
994 
995 template <typename TTraits>
997 {
998  return m_RowType;
999 }
1000 
1001 
1002 template <typename TTraits>
1004 {
1005  return static_cast<TFieldNo>(m_FieldsSize);
1006 }
1007 
1008 
1009 template <typename TTraits>
1011 {
1012  return m_RawData;
1013 }
1014 
1015 
1016 template <typename TTraits>
1018 {
1019  m_RawData.clear();
1020  m_RowType = eRR_Invalid;
1021  m_FieldsSize = 0;
1022 }
1023 
1024 
1025 template <typename TTraits>
1027 {
1028  m_FieldsSize = new_size;
1029  while (m_FieldsCapacity < new_size) {
1030  m_Fields.push_back(CRR_Field<TTraits>());
1031  ++m_FieldsCapacity;
1032  }
1033 }
1034 
1035 
1036 template <typename TTraits>
1038 {
1039  // This is an optimization.
1040  // Technically it would be possible to copy a vector of the fields
1041  // however it will lead to creating copies of all strings for each field.
1042  // On the other hand it seems that copying of the rows would be a likely
1043  // case so the row raw data could be copied once and then the field are
1044  // used by a reference. Thus the only temp string pointers need to be
1045  // adjusted for each field.
1046  ptrdiff_t raw_data_delta = m_RawData.data() - other_row.m_RawData.data();
1047  x_AdjustFieldsSize(other_row.m_FieldsSize);
1048  for (size_t index = 0; index < m_FieldsSize; ++index) {
1049  CRR_Field<TTraits>& to_field = m_Fields[index];
1050  const CRR_Field<TTraits>& from_field = other_row.m_Fields[index];
1051 
1052  to_field.m_IsNull = from_field.m_IsNull;
1053  to_field.m_Translated = from_field.m_Translated;
1054  if (to_field.m_Translated)
1055  to_field.m_TranslatedValue = from_field.m_TranslatedValue;
1056  else
1057  to_field.m_TranslatedValue.clear();
1058 
1059  to_field.m_OriginalData = CTempString(
1060  from_field.m_OriginalData.data() + raw_data_delta,
1061  from_field.m_OriginalData.size());
1062 
1063  m_Fields[index].m_RowReader = nullptr;
1064  }
1065 }
1066 
1067 
1068 template <typename TTraits>
1069 void CRR_Row<TTraits>::x_SetFieldName(TFieldNo field, const string& name,
1070  bool user_init)
1071 {
1072  x_DetachMetaInfo();
1073  m_MetaInfo->SetFieldName(field, name, user_init);
1074 }
1075 
1076 
1077 template <typename TTraits>
1079  TFieldNo field,
1081  bool user_init)
1082 {
1083  x_DetachMetaInfo();
1084  m_MetaInfo->SetFieldType(field, type, user_init);
1085 }
1086 
1087 
1088 template <typename TTraits>
1090  TFieldNo field,
1093  bool user_init)
1094 {
1095  x_DetachMetaInfo();
1096  m_MetaInfo->SetFieldTypeEx(field, type, extended_type, user_init);
1097 }
1098 
1099 
1100 template <typename TTraits>
1102 {
1103  return m_MetaInfo->GetDescribedFieldCount();
1104 }
1105 
1106 
1107 template <typename TTraits>
1108 vector<typename CRR_Row<TTraits>::SFieldMetaInfo>
1110 {
1111  vector<SFieldMetaInfo> result;
1112 
1113  if (m_MetaInfo->m_FieldsInfo.empty())
1114  return result;
1115 
1116  size_t last_index = min(static_cast<size_t>(to),
1117  m_MetaInfo->m_FieldsInfo.size() - 1);
1118  for (size_t index = from; index <= to && index <= last_index; ++index) {
1119  const auto & field_info = m_MetaInfo->m_FieldsInfo[index];
1120  if (field_info.IsInitialized()) {
1122 
1123  info.field_no = (TFieldNo)index;
1124  info.is_name_initialized =
1125  field_info.m_NameInit != CRR_MetaInfo<TTraits>::eNotInitialized;
1126  if (info.is_name_initialized)
1127  info.name = *field_info.m_FieldName;
1128  info.is_type_initialized =
1129  field_info.m_TypeInit != CRR_MetaInfo<TTraits>::eNotInitialized;
1130  info.type = field_info.m_FieldType;
1131  info.is_ext_type_initialized =
1132  field_info.m_ExtTypeInit != CRR_MetaInfo<TTraits>::eNotInitialized;
1133  info.ext_type = field_info.m_FieldExtType;
1134 
1135  result.push_back(info);
1136  }
1137  }
1138  return result;
1139 }
1140 
1141 
1142 template <typename TTraits>
1144 {
1145  x_DetachMetaInfo();
1146  m_MetaInfo->Clear(true); // true -> clears both user and
1147  // traits provided meta info
1148 }
1149 
1150 
1151 template <typename TTraits>
1153 {
1154  x_DetachMetaInfo();
1155  m_MetaInfo->Clear(false); // false -> clears only trits provided
1156  // meta info
1157 }
1158 
1159 
1160 template <typename TTraits>
1162 {
1163  if (m_Copied) {
1164  CRR_MetaInfo<TTraits>* old_meta = m_MetaInfo.GetPointer();
1165  CRR_MetaInfo<TTraits>* new_meta = new CRR_MetaInfo<TTraits>(*old_meta);
1166 
1167  m_MetaInfo.Reset(new_meta);
1168  m_Copied = false;
1169  }
1170 }
1171 
1172 
1173 template <typename TTraits>
1175 {
1176  if (m_RowReader == nullptr)
1177  return m_MetaInfo->GetFieldIndexByName(field);
1178  try {
1179  return m_MetaInfo->GetFieldIndexByName(field);
1180  } catch (CRowReaderException& exc) {
1181  exc.SetContext(m_RowReader->GetBasicContext().Clone());
1182  throw exc;
1183  } catch (const CException& exc) {
1184  NCBI_RETHROW2(exc, CRowReaderException, eFieldMetaInfoAccess,
1185  "Cannot get field number by name ('"
1186  + string(field) + "')",
1187  m_RowReader->GetBasicContext().Clone());
1188  } catch (const exception& exc) {
1189  NCBI_THROW2(CRowReaderException, eFieldMetaInfoAccess,
1190  exc.what(), m_RowReader->GetBasicContext().Clone());
1191  } catch (...) {
1192  NCBI_THROW2(CRowReaderException, eFieldMetaInfoAccess,
1193  "Unknown error while getting field number by name ('"
1194  + string(field) + "')",
1195  m_RowReader->GetBasicContext().Clone());
1196  }
1197 }
1198 
1199 
1200 // End of the CRR_Row implementation
1201 
1202 
1203 
1204 // Begin of the CRowReader implementation
1205 template <typename TTraits>
1211 {
1212  m_Traits.x_SetMyStream(this);
1213  m_CurrentRow.m_RowReader = this;
1214 }
1215 
1216 
1217 template <typename TTraits>
1219  CNcbiIstream* is,
1220  const string& sourcename,
1221  EOwnership ownership) :
1222  m_DataSource(is, sourcename, ownership == eTakeOwnership),
1226 {
1227  if (is == nullptr)
1228  NCBI_THROW2(CRowReaderException, eInvalidStream,
1229  "Invalid data source stream", nullptr);
1230 
1232  m_Traits.x_SetMyStream(this);
1233  m_CurrentRow.m_RowReader = this;
1234 }
1235 
1236 
1237 template <typename TTraits>
1238 CRowReader<TTraits>::CRowReader(const string& filename) :
1239  m_DataSource(nullptr, filename, false),
1244 {
1248  m_Traits.x_SetMyStream(this);
1249  m_CurrentRow.m_RowReader = this;
1250 }
1251 
1252 
1253 template <typename TTraits>
1255 {}
1256 
1257 
1258 template <typename TTraits>
1260  CNcbiIstream* is,
1261  const string& sourcename,
1262  EOwnership ownership)
1263 {
1264  if (is == nullptr)
1265  NCBI_THROW2(CRowReaderException, eInvalidStream,
1266  "Invalid data source stream", nullptr);
1267 
1270  m_NextDataSource.m_Sourcename = sourcename;
1272 }
1273 
1274 
1275 template <typename TTraits>
1276 void CRowReader<TTraits>::SetDataSource(const string& filename)
1277 {
1280  m_NextDataSource.m_Sourcename = filename;
1281 
1283 }
1284 
1285 
1286 template <typename TTraits>
1288  typename TTraits::ERR_ValidationMode validation_mode,
1289  ERR_FieldValidationMode field_validation_mode)
1290 {
1291  if (m_DataSource.m_Stream == nullptr &&
1292  m_NextDataSource.m_Stream == nullptr)
1293  NCBI_THROW2(CRowReaderException, eValidating,
1294  "Data source stream has not been provided", nullptr);
1295 
1296  ERR_Action action = eRR_Interrupt;
1297  size_t phys_lines_read;
1298 
1299  x_ResetToEnd();
1300  if (m_DataSource.m_Stream != nullptr)
1302  else
1303  // The stream is going to be switched anyway so this is just for
1304  // consistency
1305  m_CurrentRowPos = 0;
1306 
1307  try {
1308  m_Traits.SetValidationMode(validation_mode);
1309  } catch (const CException& exc) {
1310  CRR_Context* ctxt = x_GetContextClone();
1311  x_ResetToEnd();
1312  NCBI_RETHROW2(exc, CRowReaderException, eValidating,
1313  "Set validation mode error", ctxt);
1314  } catch (const exception& exc) {
1315  CRR_Context* ctxt = x_GetContextClone();
1316  x_ResetToEnd();
1317  NCBI_THROW2(CRowReaderException, eValidating, exc.what(), ctxt);
1318  } catch (...) {
1319  CRR_Context* ctxt = x_GetContextClone();
1320  x_ResetToEnd();
1321  NCBI_THROW2(CRowReaderException, eValidating,
1322  "Unknown set validation mode error", ctxt);
1323  }
1324 
1325  for (;;) {
1326  m_AtEnd = false;
1327  m_Validation = true;
1328 
1329  // The beginning of the source
1330  try {
1331  if (m_NeedOnSourceBegin && m_NextDataSource.m_Stream == nullptr) {
1333  x_ResetToEnd();
1334  goto onEnd;
1335  }
1336  }
1337  } catch (...) {
1338  // The x_OnEvent() has already attached the proper context to the
1339  // generated exception so the only thing to to is to reset the
1340  // stream state.
1341  x_ResetToEnd();
1342  throw;
1343  }
1344 
1345  for (;;) {
1346  try {
1347  if (!x_GetRowData(&phys_lines_read))
1348  break;
1349  } catch (...) {
1350  // The x_GetRowData() can also generate an exception...
1351  x_ResetToEnd();
1352  throw;
1353  }
1354  x_UpdateCurrentLineNo(phys_lines_read);
1355 
1356  try {
1357  action = m_Traits.Validate(CTempString(m_CurrentRow.m_RawData),
1358  field_validation_mode);
1359  if (action == eRR_Interrupt)
1360  break;
1361  } catch (const CException& exc) {
1362  CRR_Context* ctxt = x_GetContextClone();
1363  x_ResetToEnd();
1364  NCBI_RETHROW2(exc, CRowReaderException, eValidating,
1365  "Validation error", ctxt);
1366  } catch (const exception& exc) {
1367  CRR_Context* ctxt = x_GetContextClone();
1368  x_ResetToEnd();
1369  NCBI_THROW2(CRowReaderException, eValidating, exc.what(), ctxt);
1370  } catch (...) {
1371  CRR_Context* ctxt = x_GetContextClone();
1372  x_ResetToEnd();
1373  NCBI_THROW2(CRowReaderException, eValidating,
1374  "Unknown validating error", ctxt);
1375  }
1376  }
1377 
1378  onEnd:
1379  m_AtEnd = true;
1380 
1381  try {
1382  if (m_NeedOnSourceEnd) {
1384  x_ResetToEnd();
1385  return;
1386  }
1387  }
1388  } catch (...) {
1389  // The x_OnEvent() has already attached the proper context to the
1390  // generated exception so the only thing to to is to reset the
1391  // stream state.
1392  x_ResetToEnd();
1393  throw;
1394  }
1395 
1396  x_ResetToEnd();
1397 
1398  // Test if there was a source switch in the Traits::onEvent(...) call.
1399  // If there was then we continue reading.
1400  if (m_NextDataSource.m_Stream == nullptr)
1401  break;
1402  }
1403 }
1404 
1405 
1406 template <typename TTraits>
1408 {
1409  if (!m_LinesAlreadyRead) {
1410  // Note: it was decided to make it a special case and return 0.
1411  // i.e. it is impossible to distinguish two cases:
1412  // - there ware no reads yet
1413  // - it was the very first read
1414  return 0;
1415  }
1416  return m_CurrentLineNo;
1417 }
1418 
1419 
1420 template <typename TTraits>
1422 {
1423  if (!m_LinesAlreadyRead) {
1424  // Note: it was decided to make it a special case and return 0.
1425  // i.e. it is impossible to distinguish two cases:
1426  // - there ware no reads yet
1427  // - it was the very first read
1428  return 0;
1429  }
1430  return m_CurrentRowPos;
1431 }
1432 
1433 
1434 template <typename TTraits>
1436  const string& name)
1437 {
1438  // true - user (not traits) setting
1439  m_CurrentRow.x_SetFieldName(field, name, true);
1440 }
1441 
1442 
1443 template <typename TTraits>
1444 void
1446  TFieldNo field,
1448 {
1449  // true = user (not traits) setting
1450  m_CurrentRow.x_SetFieldType(field, type, true);
1451 }
1452 
1453 
1454 template <typename TTraits>
1455 void
1457  TFieldNo field,
1460 {
1461  // true - user (not traits) setting
1462  m_CurrentRow.x_SetFieldTypeEx(field, type, extended_type, true);
1463 }
1464 
1465 
1466 template <typename TTraits>
1468  const string& name)
1469 {
1470  // false - traits (not user) setting
1471  m_CurrentRow.x_SetFieldName(field, name, false);
1472 }
1473 
1474 
1475 template <typename TTraits>
1477  TFieldNo field,
1479 {
1480  // false - traits (not user) setting
1481  m_CurrentRow.x_SetFieldType(field, type, false);
1482 }
1483 
1484 
1485 template <typename TTraits>
1487  TFieldNo field,
1490 {
1491  // false - traits (not user) setting
1492  m_CurrentRow.x_SetFieldTypeEx(field, type, extended_type, false);
1493 }
1494 
1495 
1496 template <typename TTraits>
1497 vector<typename CRR_Row<TTraits>::SFieldMetaInfo>
1499 {
1500  return m_CurrentRow.GetFieldsMetaInfo(from, to);
1501 }
1502 
1503 
1504 template <typename TTraits>
1506 {
1507  return m_CurrentRow.GetDescribedFieldCount();
1508 }
1509 
1510 
1511 template <typename TTraits>
1513 {
1514  m_CurrentRow.x_ClearFieldsInfo();
1515 }
1516 
1517 
1518 template <typename TTraits>
1520 {
1521  m_CurrentRow.x_ClearTraitsProvidedFieldsInfo();
1522 }
1523 
1524 
1525 template <typename TTraits>
1527 {
1528  return m_Traits;
1529 }
1530 
1531 
1532 template <typename TTraits>
1535 {
1536  CRowIterator it(this, false);
1537  ++it;
1538  return it;
1539 }
1540 
1541 
1542 template <typename TTraits>
1545 {
1546  if (m_Validation)
1547  NCBI_THROW2(CRowReaderException, eIteratorWhileValidating,
1548  "It is prohibited to use iterators "
1549  "during the stream validation", nullptr);
1550  return CRowIterator(this, true);
1551 }
1552 
1553 
1554 template <typename TTraits>
1556 {
1560 }
1561 
1562 
1563 template <typename TTraits>
1564 typename TTraits::TRR_Context
1566 {
1567  return m_Traits.GetContext(GetBasicContext());
1568 }
1569 
1570 
1571 // This member throws only exceptions which already have the attached context.
1572 // I.e. the higher level needs to bother only about the stream state after an
1573 // exception is generated.
1574 
1575 // true: the line is ready; a non-end iterator needs to be provided
1576 // false: the stream is over; an end iterator needs to be provided
1577 
1578 // In case of the soft end iterator it is an upper level responsibility to
1579 // update the stream state.
1580 template <typename TTraits>
1581 bool CRowReader<TTraits>::x_GetRowData(size_t* phys_lines_read)
1582 {
1583  for (;;) {
1584  // Switch the source stream if needed
1585  if (m_NextDataSource.m_Stream != nullptr) {
1586 
1587  if (m_NeedOnSourceEnd) {
1589  return false; // soft end iterator
1590  }
1591  }
1592 
1593  m_DataSource.Clear();
1595 
1596  m_NextDataSource.m_Stream = nullptr;
1599 
1600  x_Reset();
1602  m_DataSource.m_Stream->tellg());
1603 
1604  if (m_NeedOnSourceBegin) {
1606  // Note: there is no need to call eRR_Event_SourceEnd. When an
1607  // upper level function gets an end iterator, it calls
1608  // the eRR_Event_SourceEnd.
1609  return false; // soft end iterator
1610  }
1611  }
1612  }
1613 
1614  m_RawDataAvailable = false;
1615  m_CurrentRow.x_OnFreshRead();
1616 
1617  // Note: there is no need to check that there is a stream set. The
1618  // check that at least one of the streams (current or next) is
1619  // set is done in an upper level code.
1620 
1621  if (m_DataSource.m_Stream->bad() ||
1622  (m_DataSource.m_Stream->fail() && !m_DataSource.m_Stream->eof())) {
1623  switch ( x_OnEvent(eRR_Event_SourceError) ) {
1624  case eRR_EventAction_Stop:
1625  return false;
1627  // Note: if traits return eRR_EventAction_Continue without
1628  // switching the underlying data source or repairing the
1629  // current stream then an infinite loop is possible
1630  continue;
1632  default:
1633  NCBI_THROW2(CRowReaderException, eStreamFailure,
1634  "Input stream failed before reaching the end",
1635  x_GetContextClone());
1636  }
1637  }
1638 
1640 
1641  try {
1642  *phys_lines_read = m_Traits.ReadRowData(*m_DataSource.m_Stream,
1643  &m_CurrentRow.m_RawData);
1644  } catch (const CException& exc) {
1645  NCBI_RETHROW2(exc, CRowReaderException, eRowDataReading,
1646  "Reading row data error", x_GetContextClone());
1647  } catch (const exception& exc) {
1648  NCBI_THROW2(CRowReaderException, eRowDataReading, exc.what(),
1649  x_GetContextClone());
1650  } catch (...) {
1651  NCBI_THROW2(CRowReaderException, eRowDataReading,
1652  "Unknown reading row data error", x_GetContextClone());
1653  }
1654 
1655  m_RawDataAvailable = true;
1656  return bool(*m_DataSource.m_Stream);
1657  }
1658 }
1659 
1660 
1661 template <typename TTraits>
1663 {
1664  if (m_DataSource.m_Stream == nullptr &&
1665  m_NextDataSource.m_Stream == nullptr)
1666  NCBI_THROW2(CRowReaderException, eInvalidStream,
1667  "Data source stream has not been provided prior "
1668  "to the first read", nullptr);
1669 
1670  if (m_NeedOnSourceBegin && m_NextDataSource.m_Stream == nullptr) {
1671  if (m_DataSource.m_Stream != nullptr)
1673  m_DataSource.m_Stream->tellg());
1674  else
1675  m_CurrentRowPos = 0;
1676 
1677  try {
1679  x_ResetToEnd();
1681  x_ResetToEnd();
1682  return;
1683  }
1684  }
1685  } catch (...) {
1686  x_ResetToEnd();
1687  throw;
1688  }
1689  }
1690 
1691  ERR_Action action = eRR_Interrupt;
1692  size_t phys_lines_read;
1693 
1694  for (;;) {
1695  m_AtEnd = false;
1696  for (;;) {
1697  try {
1698  if (!x_GetRowData(&phys_lines_read))
1699  break;
1700  } catch (...) {
1701  // The x_GetRowData() can also generate an exception...
1702  x_ResetToEnd();
1703  throw;
1704  }
1705  x_UpdateCurrentLineNo(phys_lines_read);
1706 
1707  // Call the user OnNextLine(). The line may need to be skipped
1708  // or the stream processing needs to be interrupted.
1709  try {
1710  action = m_Traits.OnNextLine(m_CurrentRow.m_RawData);
1711 
1712  if (action == eRR_Skip)
1713  continue;
1714  if (action == eRR_Interrupt) {
1715  break; // Leads to a 'soft end' return
1716  }
1717 
1718  m_CurrentRow.m_RowType = CRR_Util::ActionToRowType(action);
1719 
1720  if (action == eRR_Continue_Data) {
1721  // Need to do tokenize
1722  m_Tokens.clear();
1723  action = m_Traits.Tokenize(m_CurrentRow.m_RawData,
1724  m_Tokens);
1725  if (action == eRR_Skip)
1726  continue;
1727  if (action == eRR_Interrupt) {
1728  break; // Leads to a 'soft end' return
1729  }
1730  if (action != eRR_Continue_Data) {
1732  eInvalidAction, "Invalid action " +
1734  " in response to the Tokenize() call.",
1735  nullptr);
1736  }
1737 
1738  // The current row fields vector content is reused so
1739  // adjust it to a new size
1740  m_CurrentRow.x_AdjustFieldsSize(m_Tokens.size());
1741 
1742  // Need to translate
1743  for (TFieldNo field_index = 0;
1744  field_index < m_Tokens.size(); ++field_index) {
1745  CRR_Field<TTraits>& current_field =
1746  m_CurrentRow.m_Fields[field_index];
1747 
1748  switch (m_Traits.Translate(
1749  field_index, m_Tokens[field_index],
1750  current_field.m_TranslatedValue)) {
1751  case eRR_UseOriginal:
1752  current_field.m_IsNull = false;
1753  current_field.m_Translated = false;
1754  break;
1755  case eRR_Translated:
1756  current_field.m_IsNull = false;
1757  current_field.m_Translated = true;
1758  break;
1759  case eRR_Null:
1760  current_field.m_IsNull = true;
1761  current_field.m_Translated = false;
1762  }
1763  current_field.m_OriginalData = m_Tokens[field_index];
1764  current_field.m_RowReader = this;
1765  }
1766  }
1767  } catch (CRowReaderException& exc) {
1769  x_ResetToEnd();
1770  throw exc;
1771  } catch (const CException& exc) {
1772  CRR_Context* ctxt = x_GetContextClone();
1773  x_ResetToEnd();
1775  eLineProcessing, "Error processing line", ctxt);
1776  } catch (const exception& exc) {
1777  CRR_Context* ctxt = x_GetContextClone();
1778  x_ResetToEnd();
1779  NCBI_THROW2(CRowReaderException, eLineProcessing, exc.what(),
1780  ctxt);
1781  } catch (...) {
1782  CRR_Context* ctxt = x_GetContextClone();
1783  x_ResetToEnd();
1784  NCBI_THROW2(CRowReaderException, eLineProcessing,
1785  "Unknown line processing error", ctxt);
1786  }
1787 
1788  // Data for an iterator has been prepared
1789  return;
1790  }
1791 
1792  m_AtEnd = true;
1793 
1794  try {
1795  if (m_NeedOnSourceEnd) {
1797  x_ResetToEnd();
1798  return;
1799  }
1800  }
1801  } catch (...) {
1802  // The x_OnEvent() has already attached the proper context to the
1803  // generated exception so the only thing to to is to reset the
1804  // stream state.
1805  x_ResetToEnd();
1806  throw;
1807  }
1808 
1809  x_ResetToEnd();
1810 
1811  // Test if there was a source switch in the Traits::onEvent(...) call.
1812  // If there was then we continue reading.
1813  if (m_NextDataSource.m_Stream == nullptr)
1814  return;
1815  }
1816 }
1817 
1818 
1819 template <typename TTraits>
1821 {
1822  ios_base::openmode open_mode = ios_base::in;
1823  if (m_Traits.GetFlags() | fRR_OpenFile_AsBinary)
1824  open_mode |= ios_base::binary;
1825  stream_info.m_Stream = new CNcbiIfstream(stream_info.m_Sourcename.c_str(),
1826  open_mode);
1827  stream_info.m_StreamOwner = true;
1828 }
1829 
1830 
1831 template <typename TTraits>
1833 {
1834  m_LinesAlreadyRead = false;
1835  m_RawDataAvailable = false;
1836  m_CurrentLineNo = 0;
1838  m_CurrentRowPos = 0;
1839 }
1840 
1841 
1842 template <typename TTraits>
1844 {
1845  // Resetting to end happens in a few cases:
1846  // - there was a normal end of the iterating over the rows
1847  // - there was an exception in the traits calls
1848  // - the traits instructed to stop the process
1849  // In all these cases the row reader is reset to the original state and no
1850  // data are available via iterators even if they were stored previously.
1851  m_AtEnd = true;
1852  m_Validation = false;
1853  m_NeedOnSourceEnd = false;
1854  m_NeedOnSourceBegin = true;
1855  x_Reset();
1856  m_CurrentRow.x_OnFreshRead();
1857 }
1858 
1859 
1860 template <typename TTraits>
1862 {
1863  // When a traits callback generates an exception, a context is required
1864  // to attach it to a CRowReaderException. The context generation may
1865  // generate an exception in turn...
1866  try {
1867  return m_Traits.GetContext(GetBasicContext()).Clone();
1868  } catch (const CException& exc) {
1869  ERR_POST("Exception while getting traits context: " << exc.what());
1870  return GetBasicContext().Clone();
1871  } catch (const exception& exc) {
1872  ERR_POST("Exception while getting traits context: " << exc.what());
1873  return GetBasicContext().Clone();
1874  } catch (...) {
1875  ERR_POST("Unknown exception while getting traits context");
1876  return GetBasicContext().Clone();
1877  }
1878 }
1879 
1880 
1881 template <typename TTraits>
1883 {
1884  if (m_LinesAlreadyRead)
1886  else
1887  m_LinesAlreadyRead = true;
1888  m_PreviousPhysLinesRead = phys_lines_read;
1889 }
1890 
1891 
1892 template <typename TTraits>
1894 {
1895  switch (event) {
1896  case eRR_Event_SourceBegin:
1897  m_NeedOnSourceEnd = true;
1898  m_NeedOnSourceBegin = false;
1899  break;
1900  case eRR_Event_SourceEnd:
1901  m_NeedOnSourceEnd = false;
1902  m_NeedOnSourceBegin = true;
1903  break;
1904  default: ;
1905  }
1906 
1907  if (m_DataSource.m_Stream == nullptr) {
1908  // There is no need in event notifications (like begin/end) for a not
1909  // initialized stream.
1910  return eRR_EventAction_Default;
1911  }
1912 
1913  try {
1915  if (m_Validation)
1916  event_mode = eRR_EventMode_Validating;
1917  return m_Traits.OnEvent(event, event_mode);
1918  } catch (const CException& exc) {
1919  NCBI_RETHROW2(exc, CRowReaderException, eTraitsOnEvent,
1920  "Traits error in handling the " +
1921  CRR_Util::ERR_EventToString(event) + " event",
1922  x_GetContextClone());
1923  } catch (const exception& exc) {
1924  NCBI_THROW2(CRowReaderException, eTraitsOnEvent, exc.what(),
1925  x_GetContextClone());
1926  } catch (...) {
1927  NCBI_THROW2(CRowReaderException, eTraitsOnEvent,
1928  "Unknown traits error in handling the " +
1929  CRR_Util::ERR_EventToString(event) + " event",
1930  x_GetContextClone());
1931  }
1932 }
1933 
1934 
1935 // End of the CRowReader implementation
1936 
1937 // Begin of the CRowReader::CRowIterator implementation
1938 
1939 template <typename TTraits>
1940 const CRR_Field<TTraits>&
1942 {
1944  return m_RowReader->m_CurrentRow[field];
1945 }
1946 
1947 
1948 template <typename TTraits>
1949 const CRR_Field<TTraits>&
1951 {
1952  x_CheckFieldAccess();
1953  return m_RowReader->m_CurrentRow[field];
1954 }
1955 
1956 
1957 template <typename TTraits>
1960 {
1961  x_CheckDereferencing();
1962  return m_RowReader->m_CurrentRow;
1963 }
1964 
1965 
1966 template <typename TTraits>
1969 {
1970  x_CheckDereferencing();
1971  return &m_RowReader->m_CurrentRow;
1972 }
1973 
1974 
1975 template <typename TTraits>
1976 bool
1978 (const CRowIterator& i) const
1979 {
1980  _ASSERT(m_RowReader == i.m_RowReader);
1981  _ASSERT(m_IsEndIter || i.m_IsEndIter);
1982 
1983  if (m_RowReader != i.m_RowReader)
1984  return false;
1985 
1986  if (!m_IsEndIter && !i.m_IsEndIter)
1987  NCBI_THROW2(CRowReaderException, eNonEndIteratorCompare,
1988  "Comparing two non end iterators is prohibited", nullptr);
1989 
1990  if (m_IsEndIter && i.m_IsEndIter)
1991  return true;
1992 
1993  if ( m_IsEndIter )
1994  return i.m_RowReader->m_AtEnd
1995  && (i.m_RowReader->m_NextDataSource.m_Stream == nullptr);
1996 
1997  return m_RowReader->m_AtEnd
1998  && (m_RowReader->m_NextDataSource.m_Stream == nullptr);
1999 }
2000 
2001 
2002 template <typename TTraits>
2003 bool
2005 (const CRowIterator& end_iterator) const
2006 {
2007  return !operator==(end_iterator);
2008 }
2009 
2010 
2011 template <typename TTraits>
2013  : m_RowReader(i.m_RowReader), m_IsEndIter(i.m_IsEndIter)
2014 {}
2015 
2016 
2017 template <typename TTraits>
2019 {}
2020 
2021 
2022 template <typename TTraits>
2025 {
2026  m_RowReader = i.m_RowReader;
2027  m_IsEndIter = i.m_IsEndIter;
2028  return *this;
2029 }
2030 
2031 
2032 template <typename TTraits>
2035 {
2036  x_CheckAdvancing();
2037  m_RowReader->x_ReadNextRow();
2038  return *this;
2039 }
2040 
2041 
2042 template <typename TTraits>
2045  bool is_end) :
2046  m_RowReader(s), m_IsEndIter(is_end)
2047 {}
2048 
2049 
2050 // Needed for the constness of the CRowReader::end() call
2051 template <typename TTraits>
2053  const CRowReader<TTraits>* s,
2054  bool is_end) :
2055  m_RowReader(const_cast<CRowReader<TTraits>*>(s)),
2056  m_IsEndIter(is_end)
2057 {}
2058 
2059 
2060 template <typename TTraits>
2062 {
2063  if (m_RowReader->m_Validation)
2064  NCBI_THROW2(CRowReaderException, eIteratorWhileValidating,
2065  "It is prohibited to use iterators "
2066  "during the stream validation", nullptr);
2067  if (m_IsEndIter || m_RowReader->m_AtEnd)
2068  NCBI_THROW2(CRowReaderException, eDereferencingEndIterator,
2069  "Dereferencing end iterator is prohibited", nullptr);
2070  if (!m_RowReader->m_RawDataAvailable)
2071  NCBI_THROW2(CRowReaderException, eDereferencingNoDataIterator,
2072  "Dereferencing iterator when no data is available",
2073  nullptr);
2074 }
2075 
2076 
2077 template <typename TTraits>
2079 {
2080  if (m_RowReader->m_Validation)
2081  NCBI_THROW2(CRowReaderException, eIteratorWhileValidating,
2082  "It is prohibited to use iterators "
2083  "during the stream validation", nullptr);
2084  if (m_IsEndIter ||
2085  (m_RowReader->m_AtEnd && m_RowReader->m_NextDataSource.m_Stream == nullptr))
2086  NCBI_THROW2(CRowReaderException, eAdvancingEndIterator,
2087  "Advancing end iterator is prohibited", nullptr);
2088 }
2089 
2090 
2091 template <typename TTraits>
2093 {
2094  if (m_RowReader->m_Validation)
2095  NCBI_THROW2(CRowReaderException, eIteratorWhileValidating,
2096  "It is prohibited to use iterators "
2097  "during the stream validation", nullptr);
2098  if (m_IsEndIter || m_RowReader->m_AtEnd)
2099  NCBI_THROW2(CRowReaderException, eEndIteratorRowAccess,
2100  "Accessing row field via end iterator", nullptr);
2101 }
2102 
2103 // End of the CRowReader::CRowIterator implementation
2104 
2105 
2107 
2108 #endif /* UTIL___ROW_READER__HPP */
The class represents the current delimited row stream context.
Definition: row_reader.inl:119
virtual CRR_Context * Clone(void) const
Definition: row_reader.inl:176
Basic or an extended field type with an added arbitrary string property.
Definition: row_reader.hpp:79
TFieldType m_Type
Definition: row_reader.hpp:101
CRR_FieldType(TFieldType field_type, const string &field_props=string())
Definition: row_reader.hpp:81
TFieldType GetType(void) const
Definition: row_reader.hpp:90
string GetProps(void) const
Definition: row_reader.hpp:95
A single field in a row abstraction.
Definition: row_reader.hpp:136
CTempString m_OriginalData
Definition: row_reader.hpp:208
const CTempString GetOriginalData(void) const
Get the field original data.
Definition: row_reader.hpp:804
bool IsNull(void) const
Check if the field value is NULL.
Definition: row_reader.hpp:797
CTempString x_GetStringValue(void) const
Definition: row_reader.hpp:874
string m_TranslatedValue
Definition: row_reader.hpp:209
TValue GetWithDefault(const TValue &default_value) const
Get the converted field value.
Definition: row_reader.hpp:788
CRowReader< TTraits > * m_RowReader
Definition: row_reader.hpp:213
bool m_IsNull
Definition: row_reader.hpp:206
string m_OriginalDataCopy
Definition: row_reader.hpp:204
TValue Get(void) const
Get the converted field value.
Definition: row_reader.hpp:756
CRR_Field & operator=(const CRR_Field &other_field)
Definition: row_reader.hpp:841
bool m_Translated
Definition: row_reader.hpp:207
Represents one row from an input stream.
Definition: row_reader.hpp:221
string m_RawData
Definition: row_reader.hpp:332
CRowReader< TTraits > * m_RowReader
Definition: row_reader.hpp:345
vector< CRR_Field< TTraits > > m_Fields
Definition: row_reader.hpp:339
CRR_Row()
Construct an empty row.
Definition: row_reader.hpp:891
size_t m_FieldsCapacity
Definition: row_reader.hpp:341
TFieldNo x_GetFieldIndex(CTempString field) const
void x_ClearFieldsInfo(void)
void x_SetFieldType(TFieldNo field, const CRR_FieldType< ERR_FieldType > &type, bool user_init)
void x_AdjustFieldsSize(size_t new_size)
CRef< CRR_MetaInfo< TTraits > > m_MetaInfo
Definition: row_reader.hpp:334
size_t m_FieldsSize
Definition: row_reader.hpp:340
vector< SFieldMetaInfo > GetFieldsMetaInfo(TFieldNo from=0, TFieldNo to=numeric_limits< TFieldNo >::max())
Get the collected fields meta info.
ERR_RowType GetType(void) const
Get the row type.
Definition: row_reader.hpp:996
void x_SetFieldName(TFieldNo field, const string &name, bool user_init)
ERR_RowType m_RowType
Definition: row_reader.hpp:333
TFieldNo GetNumberOfFields(void) const
Get the number of fields in the row.
void x_ClearTraitsProvidedFieldsInfo(void)
bool m_Copied
Definition: row_reader.hpp:335
void x_SetFieldTypeEx(TFieldNo field, const CRR_FieldType< ERR_FieldType > &type, const CRR_FieldType< typename TTraits::TExtendedFieldType > &extended_type, bool user_init)
CRR_Row & operator=(const CRR_Row &other_row)
Definition: row_reader.hpp:917
void x_CopyFields(const CRR_Row &other_row)
void x_OnFreshRead(void)
void x_DetachMetaInfo(void)
TFieldNo GetDescribedFieldCount(void) const
Get the number of a fields for which any kind of meta info is provided.
CTempString GetOriginalData(void) const
Get the row original data.
const CRR_Field< TTraits > & operator[](TFieldNo field) const
Get a row field.
Definition: row_reader.hpp:961
static void GetFieldValueConverted(const CTempString &str_value, CTime &converted)
Definition: row_reader.inl:412
static string ERR_EventToString(ERR_Event event)
Definition: row_reader.inl:359
static void CheckExistanceAndPermissions(const string &sourcename)
Definition: row_reader.inl:398
static ERR_RowType ActionToRowType(ERR_Action action)
Definition: row_reader.inl:383
static string ERR_ActionToString(ERR_Action action)
Definition: row_reader.inl:345
CRef –.
Definition: ncbiobj.hpp:618
Exception to be used throughout API.
Definition: row_reader.inl:206
void SetContext(CRR_Context *ctxt)
Definition: row_reader.inl:314
A (forward-only) iterator to iterate over the rows from a stream.
Definition: row_reader.hpp:524
CRR_Row< TTraits > & operator*(void) const
Get a reference to the current row.
CRowIterator & operator=(const CRowIterator &iter)
bool operator==(const CRowIterator &iter) const
Compare this iterator with another.
bool operator!=(const CRowIterator &iter) const
This is an exact negation of operator==.
CRowIterator & operator++(void)
Advance the iterator to the next row.
void x_CheckDereferencing(void) const
const CRR_Field< TTraits > & operator[](TFieldNo field) const
Get a row field.
void x_CheckFieldAccess(void) const
void x_CheckAdvancing(void) const
CRowReader< TTraits > * m_RowReader
Definition: row_reader.hpp:613
CRowIterator(const CRowIterator &iter)
CRR_Row< TTraits > * operator->(void) const
Get a pointer to the current row.
Callback style template to iterate over a row stream.
Definition: row_reader.hpp:358
TStreamPos GetCurrentRowPos(void) const
Get the absolute position (in the current data source) of the beginning of the row that is currently ...
void x_ReadNextRow(void)
CRowIterator iterator
Definition: row_reader.hpp:633
bool m_NeedOnSourceBegin
Definition: row_reader.hpp:712
void SetDataSource(CNcbiIstream *is, const string &sourcename, EOwnership ownership=eNoOwnership)
Switch to processing data from another stream.
void Validate(typename TTraits::ERR_ValidationMode validation_mode=TTraits::eRR_ValidationMode_Default, ERR_FieldValidationMode field_validation_mode=eRR_FieldValidation)
Read and validate-only the stream, calling TTraits::Validate(row, validation_mode) on each row.
void ClearFieldsInfo(void)
Clear the information about all field names, types and extended types.
CRowIterator begin(void)
It works exactly(!) like CRowIterator::operator++, except it creates new iterator and therefore can a...
virtual ~CRowReader()
TTraits & GetTraits(void)
Get the traits object.
SRR_SourceInfo m_NextDataSource
Definition: row_reader.hpp:683
TLineNo GetCurrentLineNo(void) const
Get the number of the line that is currently being processed.
void x_OpenFile(SRR_SourceInfo &stream_info)
CRR_Row< TTraits > m_CurrentRow
Definition: row_reader.hpp:694
CRowReader & operator=(const CRowReader &)=delete
CRowReader & operator=(CRowReader &&)=delete
size_t m_PreviousPhysLinesRead
Definition: row_reader.hpp:691
CRR_Context GetBasicContext(void) const
Get basic context.
vector< CTempString > m_Tokens
Definition: row_reader.hpp:705
void SetFieldTypeEx(TFieldNo field, const CRR_FieldType< ERR_FieldType > &type, const CRR_FieldType< typename TTraits::TExtendedFieldType > &extended_type)
Set the (trait specific) data type of the field.
void x_ClearTraitsProvidedFieldsInfo(void)
CRR_Context * x_GetContextClone(void)
CRowReader(const CRowReader &)=delete
CRR_Field< TTraits > CField
Definition: row_reader.hpp:360
bool x_GetRowData(size_t *phys_lines_read)
bool m_RawDataAvailable
Definition: row_reader.hpp:689
bool m_Validation
Definition: row_reader.hpp:697
friend TTraits
Definition: row_reader.hpp:651
TStreamPos m_CurrentRowPos
Definition: row_reader.hpp:692
TLineNo m_CurrentLineNo
Definition: row_reader.hpp:690
TTraits m_Traits
Definition: row_reader.hpp:693
ERR_EventAction x_OnEvent(ERR_Event event)
vector< typename CRR_Row< TTraits >::SFieldMetaInfo > GetFieldsMetaInfo(TFieldNo from=0, TFieldNo to=numeric_limits< TFieldNo >::max())
Get the collected fields meta info.
void x_SetFieldName(TFieldNo field, const string &name)
CRowReader(CRowReader &&)=delete
bool m_LinesAlreadyRead
Definition: row_reader.hpp:688
CRowIterator const_iterator
Definition: row_reader.hpp:634
TFieldNo GetDescribedFieldCount(void) const
Get the number of a fields for which any kind of meta info is provided.
void x_ResetToEnd(void)
SRR_SourceInfo m_DataSource
Definition: row_reader.hpp:682
void x_Reset(void)
void x_SetFieldType(TFieldNo field, const CRR_FieldType< ERR_FieldType > &type)
bool m_NeedOnSourceEnd
Definition: row_reader.hpp:713
void SetFieldType(TFieldNo field, const CRR_FieldType< ERR_FieldType > &type)
Set the (basic) data type of the field.
CRowIterator end(void) const
Get iterator pointing to the end of the current underlying data source.
TTraits::TRR_Context GetContext(void) const
Get traits context.
CRowReader()
Construct a row reader.
CRR_Row< TTraits > CRow
Definition: row_reader.hpp:361
void SetFieldName(TFieldNo field, const string &name)
Set the field name.
void x_UpdateCurrentLineNo(size_t phys_lines_read)
void x_SetFieldTypeEx(TFieldNo field, const CRR_FieldType< ERR_FieldType > &type, const CRR_FieldType< typename TTraits::TExtendedFieldType > &extended_type)
CTempString implements a light-weight string on top of a storage buffer whose lifetime management is ...
Definition: tempstr.hpp:65
CTimeFormat –.
Definition: ncbitime.hpp:131
CTime –.
Definition: ncbitime.hpp:296
Include a standard set of the NCBI C++ Toolkit most basic headers.
bool operator==(const CEquivRange &A, const CEquivRange &B)
#define true
Definition: bool.h:35
#define false
Definition: bool.h:36
#define bool
Definition: bool.h:34
char data[12]
Definition: iconv.c:80
@ eTakeOwnership
An object can take ownership of another.
Definition: ncbi_types.h:136
@ eNoOwnership
No ownership is assumed.
Definition: ncbi_types.h:135
#define ERR_POST(message)
Error posting with file, line number information but without error codes.
Definition: ncbidiag.hpp:186
#define NCBI_THROW2(exception_class, err_code, message, extra)
Throw exception with extra parameter.
Definition: ncbiexpt.hpp:1754
#define NCBI_RETHROW2(prev_exception, exception_class, err_code, message, extra)
Re-throw exception with extra parameter.
Definition: ncbiexpt.hpp:1761
virtual const char * what(void) const noexcept
Standard report (includes full backlog).
Definition: ncbiexpt.cpp:342
uint32_t Uint4
4-byte (32-bit) unsigned integer
Definition: ncbitype.h:103
uint64_t Uint8
8-byte (64-bit) unsigned integer
Definition: ncbitype.h:105
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
Int8 NcbiStreamposToInt8(NCBI_NS_STD::char_traits< char >::pos_type stream_pos)
Convert stream position to 64-bit int.
Definition: ncbistre.hpp:771
IO_PREFIX::istream CNcbiIstream
Portable alias for istream.
Definition: ncbistre.hpp:146
IO_PREFIX::ifstream CNcbiIfstream
Portable alias for ifstream.
Definition: ncbistre.hpp:439
const char * data(void) const
Return a pointer to the array represented.
Definition: tempstr.hpp:313
static enable_if< is_arithmetic< TNumeric >::value||is_convertible< TNumeric, Int8 >::value, string >::type NumericToString(TNumeric value, TNumToStringFlags flags=0, int base=10)
Convert numeric value to string.
Definition: ncbistr.hpp:673
size_type size(void) const
Return the length of the represented array.
Definition: tempstr.hpp:327
const string & GetString(void) const
Get format string.
Definition: ncbitime.hpp:2237
enum ENcbiOwnership EOwnership
Ownership relations between objects.
int i
static MDB_envinfo info
Definition: mdb_load.c:37
const struct ncbi::grid::netcache::search::fields::SIZE size
Defines classes: CDirEntry, CFile, CDir, CSymLink, CMemoryFile, CFileUtil, CFileLock,...
#define nullptr
Definition: ncbimisc.hpp:45
T max(T x_, T y_)
T min(T x_, T y_)
std::istream & in(std::istream &in_, double &x_)
Uint4 TFieldNo
Field number (zero based)
Definition: row_reader.hpp:53
ERR_FieldValidationMode
Whether to check validity of the fields (names and/or values)
Definition: row_reader.hpp:117
@ eRR_FieldValidation
check that the field's value (or name) is valid
Definition: row_reader.hpp:119
@ eRR_NoFieldValidation
don't validate fields' value and name
Definition: row_reader.hpp:118
ERR_RowType
Row type.
Definition: row_reader.hpp:108
@ eRR_Metadata
row contains metadata
Definition: row_reader.hpp:111
@ eRR_Invalid
row is invalid
Definition: row_reader.hpp:112
@ eRR_Data
row contains data
Definition: row_reader.hpp:109
@ eRR_Comment
row contains a comment
Definition: row_reader.hpp:110
Uint8 TLineNo
Line number (in the data stream, zero based)
Definition: row_reader.hpp:50
Uint8 TStreamPos
Position in the data stream (zero based)
Definition: row_reader.hpp:47
ERR_FieldType
Basic field data types.
Definition: row_reader.hpp:62
@ eRR_Double
double
Definition: row_reader.hpp:66
@ eRR_DateTime
CTime.
Definition: row_reader.hpp:67
@ eRR_Integer
int
Definition: row_reader.hpp:65
@ eRR_String
string
Definition: row_reader.hpp:63
@ eRR_Boolean
bool
Definition: row_reader.hpp:64
@ eRR_UseOriginal
No translation done.
Definition: row_reader.inl:72
@ eRR_Translated
The value has been translated to another string.
Definition: row_reader.inl:73
@ eRR_Null
The value has been translated to NULL.
Definition: row_reader.inl:74
ERR_Action
Delimited stream traits use the ERR_Action members to instruct what should be done next.
Definition: row_reader.inl:48
@ eRR_Continue_Data
Continue processing this line, in full.
Definition: row_reader.inl:52
@ eRR_Interrupt
Stop processing the stream.
Definition: row_reader.inl:66
@ eRR_Skip
Skip this line.
Definition: row_reader.inl:50
@ fRR_OpenFile_AsBinary
open file in a binary mode
Definition: row_reader.inl:85
ERR_EventAction
How to react to the potentially disruptive events.
Definition: row_reader.inl:110
@ eRR_EventAction_Continue
Resume processing.
Definition: row_reader.inl:113
@ eRR_EventAction_Stop
Stop further processing.
Definition: row_reader.inl:112
@ eRR_EventAction_Default
Do some default action.
Definition: row_reader.inl:111
ERR_EventMode
Indicate whether the "ERR_Event" event (passed to the OnEvent() callback) occured during regular read...
Definition: row_reader.inl:102
@ eRR_EventMode_Validating
We are performing data validation.
Definition: row_reader.inl:104
@ eRR_EventMode_Iterating
We are iterating through the rows.
Definition: row_reader.inl:103
ERR_Event
CRowReader passes such events to the Traits via OnEvent() callback.
Definition: row_reader.inl:92
@ eRR_Event_SourceEnd
Data source has hit EOF.
Definition: row_reader.inl:95
@ eRR_Event_SourceBegin
Data source has started or been switched (no reads yet though).
Definition: row_reader.inl:93
@ eRR_Event_SourceError
Data source has hit an error on read.
Definition: row_reader.inl:96
CRR_FieldType< typename TTraits::TExtendedFieldType > ext_type
Definition: row_reader.hpp:293
CRR_FieldType< ERR_FieldType > type
Definition: row_reader.hpp:290
string m_Sourcename
Definition: row_reader.inl:765
void Clear(void)
Definition: row_reader.inl:754
CNcbiIstream * m_Stream
Definition: row_reader.inl:764
Definition: type.c:6
#define _ASSERT
else result
Definition: token2.c:20
Modified on Tue Apr 23 07:39:54 2024 by modify_doxy.py rev. 669887