soma-io  5.0.5
asciidatasourcetraits.h
Go to the documentation of this file.
1 /* This software and supporting documentation are distributed by
2  * Institut Federatif de Recherche 49
3  * CEA/NeuroSpin, Batiment 145,
4  * 91191 Gif-sur-Yvette cedex
5  * France
6  *
7  * This software is governed by the CeCILL-B license under
8  * French law and abiding by the rules of distribution of free software.
9  * You can use, modify and/or redistribute the software under the
10  * terms of the CeCILL-B license as circulated by CEA, CNRS
11  * and INRIA at the following URL "http://www.cecill.info".
12  *
13  * As a counterpart to the access to the source code and rights to copy,
14  * modify and redistribute granted by the license, users are provided only
15  * with a limited warranty and the software's author, the holder of the
16  * economic rights, and the successive licensors have only limited
17  * liability.
18  *
19  * In this respect, the user's attention is drawn to the risks associated
20  * with loading, using, modifying and/or developing or reproducing the
21  * software by the user in light of its specific status of free software,
22  * that may mean that it is complicated to manipulate, and that also
23  * therefore means that it is reserved for developers and experienced
24  * professionals having in-depth computer knowledge. Users are therefore
25  * encouraged to load and test the software's suitability as regards their
26  * requirements in conditions enabling the security of their systems and/or
27  * data to be ensured and, more generally, to use and operate it in the
28  * same conditions as regards security.
29  *
30  * The fact that you are presently reading this means that you have had
31  * knowledge of the CeCILL-B license and that you accept its terms.
32  */
33 
34 #ifndef SOMAIO_UTILITIES_ASCIIDATASOURCETRAITS_H
35 #define SOMAIO_UTILITIES_ASCIIDATASOURCETRAITS_H
36 //--- soma-io ----------------------------------------------------------------
39 //--- cartobase --------------------------------------------------------------
40 #include <cartobase/type/types.h>
44 #include <cartobase/type/limits.h>
49 //--- system -----------------------------------------------------------------
50 #include <cstring>
51 #include <iostream>
52 #include <limits>
53 //----------------------------------------------------------------------------
54 
55 namespace soma
56 {
57 
58  template<typename T>
60  {
61  public:
62  static bool read( DataSource & ds, T & item );
63  static bool write( DataSource & ds, const T & item );
64  };
65 
66 
67  class StreamUtil
68  {
69  public:
70  static std::string readWhile( DataSource &,
71  const std::string & chars = " \t\n\r",
72  bool ascii = true );
73  static std::string readUntil( DataSource &,
74  const std::string & chars = " \t\n\r",
75  bool ascii = true );
76  static bool skip( DataSource &, const std::string & chars = " \t\n\r",
77  bool ascii = true );
78  static bool skipUntil( DataSource &,
79  const std::string & chars = " \t\n\r",
80  bool ascii = true );
81  static bool getline( DataSource & ds, std::string & );
82 
83  static bool skip( std::istream &, const std::string & chars = " \t\n\r",
84  bool ascii = true );
85  };
86 
87  // -----------
88 
89 #ifndef DOXYGEN_HIDE_INTERNAL_CLASSES
90 
91  template<typename T>
92  inline
94  {
95  make_compil_error( x, "Instanciation on an unexpected type. "
96  "This function must be specialized." );
97 
98  /*
99  throw carto::datatype_format_error
100  ( std::string( "cannot read an ASCII element of type " )
101  + DataTypeCode<T>::name() );
102  */
103  return false;
104  }
105 
106 
107  template<typename T>
108  inline
110  {
111  make_compil_error( x, "Instanciation on an unexpected type. "
112  "This function must be specialized." );
113 
114  /*
115  throw carto::datatype_format_error
116  ( std::string( "cannot write an ASCII element of type " )
117  + DataTypeCode<T>::name() );
118  */
119  return false;
120  }
121 
122 
123  namespace internal
124  {
125 
126  template <typename T>
128  {
129  public:
130  static bool read( DataSource &, T & );
131  static bool write( DataSource &, const T & );
132  };
133 
134  template <typename T>
136  {
137  public:
138  static bool read( DataSource &, T & );
139  static bool write( DataSource &, const T & );
140  };
141 
142  } // namespace internal
143 
144 
145  template<>
146  inline
148  {
149  return internal::AsciiIntReadTraits<bool>::read( ds, item );
150  }
151 
152  template<>
153  inline
155  const bool & item )
156  {
158  }
159 
160  template<>
161  inline
163  {
165  }
166 
167  template<>
168  inline
170  const uint8_t & item )
171  {
173  }
174 
175  template<>
176  inline
178  {
180  }
181 
182  template<>
183  inline
185  const int8_t & item )
186  {
188  }
189 
190 #if !defined(__sun__) || !defined(_CHAR_IS_SIGNED)
191  template<>
192  inline
194  {
195  return internal::AsciiIntReadTraits<char>::read( ds, item );
196  }
197 
198  template<>
199  inline
201  const char & item )
202  {
204  }
205 #endif
206 
207  template<>
208  inline
210  uint16_t & item )
211  {
213  }
214 
215  template<>
216  inline
218  const uint16_t & item )
219  {
221  }
222 
223  template<>
224  inline
226  {
228  }
229 
230  template<>
231  inline
233  const int16_t & item )
234  {
236  }
237 
238  template<>
239  inline
241  uint32_t & item )
242  {
244  }
245 
246  template<>
247  inline
249  const uint32_t & item )
250  {
252  }
253 
254  template<>
255  inline
257  {
259  }
260 
261  template<>
262  inline
264  const int32_t & item )
265  {
267  }
268 
269  template<>
270  inline
272  {
274  }
275 
276  template<>
277  inline
279  const int64_t & item )
280  {
282  }
283 
284  template<>
285  inline
287  uint64_t & item )
288  {
290  }
291 
292  template<>
293  inline
294  bool
296  const uint64_t & item )
297  {
299  }
300 
301 #ifdef CARTO_LONG_IS_DISTINCT
302  // these types are int64_t/uint64_t on 64 bit systems
303  template<>
304  inline
306  {
307  return internal::AsciiIntReadTraits<long>::read( ds, item );
308  }
309 
310  template<>
311  inline
313  const long & item )
314  {
316  }
317 
318  template<>
319  inline
321  unsigned long & item )
322  {
324  }
325 
326  template<>
327  inline
328  bool
330  const unsigned long & item )
331  {
333  }
334 
335 #endif
336 
337  template<>
338  inline
340  {
342  }
343 
344  template<>
345  inline
347  const float & item )
348  {
350  }
351 
352  template<>
353  inline
355  {
357  }
358 
359  template<>
360  inline
362  const double & item )
363  {
365  }
366 
367  template<>
368  inline
370  std::string & item )
371  {
372  int c, i = 0;
373  item.clear();
374 
375  while( true )
376  {
377  c = ds.getch();
378  if( c == '\0' || !ds.isOpen() || c == '\n' || c == '\r' || c == ' '
379  || c == '\t' )
380  break;
381  item += static_cast<char>( c );
382  ++i;
383  }
384  ds.ungetch( c );
385  if( i == 0 )
386  return false;
387  return true;
388  }
389 
390  template<>
391  inline
393  const std::string & item )
394  {
395  ds.writeBlock( item.c_str(), item.size() );
396  return ds.isOpen();
397  }
398 
399 
400  template<>
401  inline
403  char * const & item )
404  {
405  ds.writeBlock( item, strlen( item ) );
406  return ds.isOpen();
407  }
408 
409 
410  template<>
411  inline
413  const char * const & item )
414  {
415  ds.writeBlock( item, strlen( item ) );
416  return ds.isOpen();
417  }
418 
419  namespace internal
420  {
421 
422  template<typename T>
423  inline
425  {
426  int c, i = 0;
427  std::string num;
428  bool hex = false;
429  int sign = 0;
430  int expo = 0;
431 
432  StreamUtil::skip( ds, " \t" );
433  while( true )
434  {
435  c = ds.getch();
436  if( c == '\0' || !ds.isOpen() )
437  break;
438  if( c < '0' || c > '9' )
439  {
440  if( !sign && i == expo && ( c == '-' || c == '+' ) )
441  sign = i+1;
442  else if( c == 'x' && !hex && i == sign+1 && num[sign] == '0' )
443  hex = true;
444  else if( !hex && !expo && ( c == 'e' || c == 'E' ) && i > sign )
445  {
446  expo = i+1;
447  sign = 0;
448  }
449  else if( !hex || c < 'A' || ( c > 'F' && c < 'a' ) || c > 'f' )
450  break;
451  }
452  num += static_cast<char>( c );
453  ++i;
454  }
455  ds.ungetch( c );
456  if( i == 0 )
457  return false;
458  carto::stringTo( num, item );
459  return true;
460  }
461 
462 
463  template<typename T>
464  inline
465  bool AsciiIntReadTraits<T>::write( DataSource & ds, const T & item )
466  {
467  std::ostringstream ss;
468  ss << item;
469  return AsciiDataSourceTraits<std::string>::write( ds, ss.str() );
470  }
471 
472 
473  template<typename T>
474  inline
476  {
477  int c, i = 0;
478  std::string num;
479  bool hex = false;
480  bool dot = false;
481  int nan = 0;
482  int inf = 0;
483  int sign = 0;
484  int expo = 0;
485 
486  StreamUtil::skip( ds, " \t" );
487  while( true )
488  {
489  c = ds.getch();
490  if( c == '\0' || !ds.isOpen() )
491  break;
492  if( inf )
493  {
494  if( c != "nf"[inf-1] && c != "NF"[inf-1] )
495  return false;
496  ++ inf;
497  if( inf >= 3 )
498  {
499  if( sign )
501  else
503  return true;
504  }
505  }
506  else if( nan )
507  {
508  if( c != "an"[nan-1] && c != "AN"[nan-1] )
509  return false;
510  ++nan;
511  if( nan >= 3 )
512  {
513  if( sign )
515  else
517  return true;
518  }
519  }
520  else if( c < '0' || c > '9' )
521  {
522  if( !sign && i == expo && ( c == '-' || c == '+' ) )
523  sign = i+1;
524  else if( !dot && c == 'x' && !hex && i == sign+1
525  && num[sign] == '0' )
526  hex = true;
527  else if( !dot && !hex && c == '.' )
528  dot = true;
529  else if( !hex && !expo && ( c == 'e' || c == 'E' ) && i > sign )
530  {
531  expo = i+1;
532  sign = 0;
533  }
534  else if( !hex && !dot && ( c == 'n' || c == 'N' ) )
535  nan = 1;
536  else if( !hex && !dot && ( c == 'i' || c == 'I' ) )
537  inf = 1;
538  else if( !hex || c < 'A' || ( c > 'F' && c < 'a' ) || c > 'f' )
539  break;
540  }
541  num += static_cast<char>( c );
542  ++i;
543  }
544  ds.ungetch( c );
545  if( i == 0 )
546  return false;
547  carto::stringTo( num, item );
548  return true;
549  }
550 
551 
552  template<typename T>
553  inline
554  bool AsciiFloatReadTraits<T>::write( DataSource & ds, const T & item )
555  {
556  std::ostringstream ss;
558  ss << item;
559  return AsciiDataSourceTraits<std::string>::write( ds, ss.str() );
560  }
561 
562 
563  } // namespace internal
564 
565 #endif // DOXYGEN_HIDE_INTERNAL_CLASSES
566 
567  // stream operators
568  /*
569  template<typename T> inline
570  DataSource &
571  operator << ( DataSource & ds, const T & x )
572  {
573  AsciiDataSourceTraits<T>::write( ds, x );
574  return ds;
575  }
576  */
577 
578  template<typename T> inline
579  DataSource &
580  operator >> ( DataSource & ds, T & x )
581  {
583  return ds;
584  }
585 
586 #if !defined(__sun__) || !defined(_CHAR_IS_SIGNED)
587  inline DataSource &
588  operator << ( DataSource & ds, const char & x )
589  {
591  return ds;
592  }
593 #endif
594 
595  inline DataSource &
596  operator << ( DataSource & ds, const int8_t & x )
597  {
599  return ds;
600  }
601 
602  inline DataSource &
603  operator << ( DataSource & ds, const uint8_t & x )
604  {
606  return ds;
607  }
608 
609  inline DataSource &
610  operator << ( DataSource & ds, const int16_t & x )
611  {
613  return ds;
614  }
615 
616  inline DataSource &
617  operator << ( DataSource & ds, const uint16_t & x )
618  {
620  return ds;
621  }
622 
623  inline DataSource &
624  operator << ( DataSource & ds, const int32_t & x )
625  {
627  return ds;
628  }
629 
630  inline DataSource &
631  operator << ( DataSource & ds, const uint32_t & x )
632  {
634  return ds;
635  }
636 
637  inline DataSource &
638  operator << ( DataSource & ds, const int64_t & x )
639  {
641  return ds;
642  }
643 
644  inline DataSource &
645  operator << ( DataSource & ds, const uint64_t & x )
646  {
648  return ds;
649  }
650 
651 #ifdef CARTO_LONG_IS_DISTINCT
652  // these types are int64_t/uint64_t on 64 bit systems
653  inline DataSource &
654  operator << ( DataSource & ds, const long & x )
655  {
657  return ds;
658  }
659 
660  inline DataSource &
661  operator << ( DataSource & ds, const unsigned long & x )
662  {
664  return ds;
665  }
666 #endif
667 
668  inline DataSource &
669  operator << ( DataSource & ds, const float & x )
670  {
672  return ds;
673  }
674 
675  inline DataSource &
676  operator << ( DataSource & ds, const double & x )
677  {
679  return ds;
680  }
681 
682  inline DataSource &
683  operator << ( DataSource & ds, const std::string & x )
684  {
686  return ds;
687  }
688 
689  inline DataSource &
690  operator << ( DataSource & ds, const char * const & x )
691  {
693  return ds;
694  }
695 
696  //=== VOXEL VALUE ==========================================================
697 
698  template <typename T, unsigned int C>
699  class AsciiDataSourceTraits< carto::VoxelValue<T,C> >
700  {
701  public:
702  static bool read( DataSource &ds, carto::VoxelValue<T,C> &item );
703  static bool write( DataSource &ds, const carto::VoxelValue<T,C> &item );
704  };
705 
706  template <typename T, unsigned int C> inline
708  carto::VoxelValue<T,C> & item )
709  {
710  int c;
711  carto::VoxelValue<T,C> result;
712 
713  while( true )
714  {
715  c = ds.getch();
716  if( c != ' ' && c != '\t' && c != '\n' && c != '(' )
717  break;
718  if( c == '(' ) {
719  AsciiDataSourceTraits<T>::read( ds, result[0] );
720  if( !ds.isOpen() )
721  return false;
722  c = ds.getch();
723  for( unsigned int i=1; i<C; ++i )
724  {
725  while( ( c == ' ' || c == '\t' ) && ds.isOpen() )
726  c = ds.getch();
727  if( !ds.isOpen() )
728  return false;
729  if( !ds.isOpen() )
730  return false;
731  if( c == ',' )
732  {
733  AsciiDataSourceTraits<T>::read( ds, result[i] );
734  if( !ds.isOpen() )
735  return false;
736  c = ds.getch();
737  }
738  else
739  return false; // unexpected char
740  }
741  while( ( c == ' ' || c == '\t' ) && ds.isOpen() )
742  c = ds.getch();
743  if( c == 0 || c == ')' ) {
744  item = result;
745  return true;
746  }
747  return false;
748  }
749  }
750  return false;
751  }
752 
753  template <typename T, unsigned int C> inline
756  & item )
757  {
758  ds << '(';
759  for( unsigned int i=0; i<C-1; ++i )
760  ds << static_cast<int>( item[i] ) << ',';
761  ds << static_cast<int>( item[C-1] ) << ')';
762  return true;
763  }
764 
765  template<typename T, unsigned int C> inline DataSource &
766  operator << ( DataSource & ds, const carto::VoxelValue<T,C> & x )
767  {
769  return ds;
770  }
771 
772  //=== VOXEL RGB ============================================================
773 
774  template <> inline
776  carto::VoxelRGB & item )
777  {
779  }
780 
781  template <> inline
783  const carto::VoxelRGB & item )
784  {
786  }
787 
788  inline DataSource &
790  {
792  return ds;
793  }
794 
795  //=== VOXEL RGBA ===========================================================
796 
797  template <> inline
799  carto::VoxelRGBA & item )
800  {
802  }
803 
804  template <> inline
806  const carto::VoxelRGBA & item )
807  {
809  }
810 
811  inline DataSource &
813  {
815  return ds;
816  }
817 
818  //=== VOXEL HSV ============================================================
819 
820  template <> inline
822  carto::VoxelHSV & item )
823  {
825  }
826 
827  template <> inline
829  const carto::VoxelHSV & item )
830  {
832  }
833 
834  inline DataSource &
836  {
838  return ds;
839  }
840 
841  //=== COMPLEX<FLOAT> =======================================================
842 
843  template <> inline
845  DataSource & ds, std::complex<float> & item )
846  {
849  return false;
850  item = std::complex<float>( x[0], x[1] );
851  return true;
852  }
853 
854  template <> inline
856  DataSource & ds, const std::complex<float> & item )
857  {
859  x[0] = item.real();
860  x[1] = item.imag();
862  ds, x );
863  }
864 
865  inline DataSource &
866  operator << ( DataSource & ds, const std::complex<float> & x )
867  {
869  return ds;
870  }
871 
872  //=== COMPLEX<DOUBLE> =======================================================
873 
874  template <> inline
876  DataSource & ds, std::complex<double> & item )
877  {
880  return false;
881  item = std::complex<double>( x[0], x[1] );
882  return true;
883  }
884 
885  template <> inline
887  DataSource & ds, const std::complex<double> & item )
888  {
890  x[0] = item.real();
891  x[1] = item.imag();
893  ds, x );
894  }
895 
896  inline DataSource &
897  operator << ( DataSource & ds, const std::complex<double> & x )
898  {
900  return ds;
901  }
902 
903 } // namespace soma
904 
905 #endif
static bool read(DataSource &ds, T &item)
virtual long writeBlock(const char *data, unsigned long len)=0
static bool skip(DataSource &, const std::string &chars=" \\, bool ascii=true)
static bool write(DataSource &, const T &)
DataSource & operator>>(DataSource &ds, T &x)
Abstraction layer for various data sources (file, buffer, socket...).
Definition: datasource.h:64
Definition: allocator.h:48
void stringTo(const std::string &value, T &result)
static bool write(DataSource &ds, const T &item)
static _Tp quiet_NaN()
std::ostream & operator<<(std::ostream &os, const MemoryAllocator &thing)
virtual bool ungetch(int ch)=0
static _Tp infinity()
static bool read(DataSource &, T &)
static bool write(DataSource &, const T &)
virtual bool isOpen() const =0
static bool read(DataSource &, T &)
virtual int getch()=0