soma-io 6.0.6
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>
41#include <cartobase/exception/ioexcept.h>
42#include <cartobase/stream/sstream.h>
43#include <cartobase/type/string_conversion.h>
44#include <cartobase/type/limits.h>
45#include <cartobase/type/voxelvalue.h>
46#include <cartobase/type/voxelrgb.h>
47#include <cartobase/type/voxelrgba.h>
48#include <cartobase/type/voxelhsv.h>
49//--- system -----------------------------------------------------------------
50#include <cstring>
51#include <iostream>
52#include <limits>
53//----------------------------------------------------------------------------
54
55namespace 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
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, "Instantiation 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, "Instantiation 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 {
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 {
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 {
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
709 {
710 int c;
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
780
781 template <> inline
787
788 inline DataSource &
789 operator << ( DataSource & ds, const carto::VoxelRGB & x )
790 {
792 return ds;
793 }
794
795 //=== VOXEL RGBA ===========================================================
796
797 template <> inline
803
804 template <> inline
810
811 inline DataSource &
812 operator << ( DataSource & ds, const carto::VoxelRGBA & x )
813 {
815 return ds;
816 }
817
818 //=== VOXEL HSV ============================================================
819
820 template <> inline
826
827 template <> inline
833
834 inline DataSource &
835 operator << ( DataSource & ds, const carto::VoxelHSV & x )
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, AimsVector< T, D > &item)
Definition vector.h:1186
static bool write(DataSource &ds, const AimsVector< T, D > &item)
Definition vector.h:1225
static bool write(DataSource &ds, const carto::VoxelValue< T, C > &item)
static bool read(DataSource &ds, carto::VoxelValue< T, C > &item)
static bool read(DataSource &ds, T &item)
static bool write(DataSource &ds, const T &item)
Abstraction layer for various data sources (file, buffer, socket...).
Definition datasource.h:65
virtual int getch()=0
virtual long writeBlock(const char *data, unsigned long len)=0
virtual bool ungetch(int ch)=0
virtual bool isOpen() const =0
static std::string readUntil(DataSource &, const std::string &chars=" \t\n\r", bool ascii=true)
static std::string readWhile(DataSource &, const std::string &chars=" \t\n\r", bool ascii=true)
static bool skip(DataSource &, const std::string &chars=" \t\n\r", bool ascii=true)
static bool skip(std::istream &, const std::string &chars=" \t\n\r", bool ascii=true)
static bool getline(DataSource &ds, std::string &)
static bool skipUntil(DataSource &, const std::string &chars=" \t\n\r", bool ascii=true)
static bool read(DataSource &, T &)
static bool write(DataSource &, const T &)
static bool read(DataSource &, T &)
static bool write(DataSource &, const T &)
void stringTo(const std::string &value, T &result)
static _Tp infinity()
static _Tp quiet_NaN()