A.I.M.S


reader_d.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 AIMS_IO_READER_D_H
35 #define AIMS_IO_READER_D_H
36 
37 #include <aims/io/reader.h>
38 #include <aims/io/fileFormat.h>
39 #include <aims/io/finder.h>
43 #include <set>
44 #include <soma-io/io/reader.h>
46 #define AIMS_INSTANTIATE_READER( T ) \
47  namespace aims { \
48  template class aims::Reader< T >; \
49  } \
50  namespace soma { \
51  template class soma::FormatDictionary< T >; \
52  template class soma::Reader< T >; \
53  }
54 #define AIMS_INSTANTIATE_AIMS_READER( T ) \
55  namespace aims { \
56  template class aims::Reader< T >; \
57  }
58 
59 namespace aims
60 {
61 
62  template<class T> Reader<T>::Reader()
63  : _mode( carto::AllocatorStrategy::Memory )
64  {
65  }
66 
67  template<class T> Reader<T>::Reader( const std::string& filename )
68  : _filename( filename ), _mode( carto::AllocatorStrategy::Memory )
69  {
70  }
71 
72 
73  template<class T>
74  void Reader<T>::setMode( carto::AllocatorStrategy::MappingMode mode )
75  {
76  _mode = mode;
77  // compatibility with new AllocatorContext
78  switch( mode )
79  {
80  case carto::AllocatorStrategy::Memory:
82  case carto::AllocatorStrategy::CopyMap:
83  _alloccontext.setAccessMode( carto::AllocatorStrategy::InternalModif );
84  break;
85  case carto::AllocatorStrategy::ReadOnlyMap:
86  _alloccontext.setAccessMode( carto::AllocatorStrategy::ReadOnly );
87  break;
88  case carto::AllocatorStrategy::ReadWriteMap:
89  _alloccontext.setAccessMode( carto::AllocatorStrategy::ReadWrite );
90  break;
91  case carto::AllocatorStrategy::Unallocated:
92  _alloccontext.setAccessMode( carto::AllocatorStrategy::NotOwner );
93  break;
94  default:
95  _alloccontext.setAccessMode( carto::AllocatorStrategy::InternalModif );
96  break;
97  }
98  }
99 
100  template <typename T>
101  void Reader<T>::setAllocatorContext( const carto::AllocatorContext & ac )
102  {
103  _alloccontext = ac;
104  }
105 
106  template <typename T>
107  const carto::AllocatorContext & Reader<T>::allocatorContext() const
108  {
109  return _alloccontext;
110  }
111 
112  template<class T>
113  void Reader<T>::setFileName( const std::string &fileName )
114  {
115  _filename = fileName;
116  }
117 
118  template<class T>
120  {
121  _options = options;
122  }
123 
124  template<class T>
126  {
127  return _options;
128  }
129 
130  template<class T>
132  {
133  return _options;
134  }
135 
136  template<class T>
137  bool Reader<T>::read( T & obj, int border, const std::string* format,
138  int frame )
139  {
140 
141  // take care of old-style options
142  if( !_options.get() )
144  if( frame >= 0 )
145  {
146  _options->setProperty( "frame", frame );
147  // (for graphs)
148  _options->setProperty( "subobjectsfilter", frame );
149  }
150  if( border > 0 )
151  _options->setProperty( "border", border );
152 
153  std::string _format;
154  if( !format )
155  {
156  try
157  {
158  carto::Object oformat = _options->getProperty( "format" );
159  _format = oformat->getString();
160  format = &_format;
161  }
162  catch( ... )
163  {
164  }
165  }
166  else
167  _options->setProperty( "format", *format );
168 
169  // try first soma-io reader (since 2013)
170  // try first 3 passes
171  try
172  {
173  // building uri
174  std::string uri = _filename;
175  if( border != 0 || frame != -1 )
176  uri += "?";
177  if( border != 0 )
178  uri += ( "border=" + carto::toString( border ) );
179  if( border != 0 && frame != -1 )
180  uri += "&";
181  if ( frame != -1 )
182  uri += ( "ot=" + carto::toString( frame ) + "&st=1" );
183 
184  soma::Reader<T> reader( uri );
185  // set conversion option to invoque Carto2AimsHeaderTranslator
186  carto::Object options = _options;
187  if( options.isNull() )
189  options->setProperty( "convert_to_aims", true );
190  reader.setOptions( options );
191  reader.setAllocatorContext( allocatorContext() );
192  const carto::Object & n = carto::none();
193 #ifdef AIMS_DEBUG_IO
194  std::cout << "0. Try soma::Reader ..." << std::endl ;
195 #endif
196  return reader.read( obj, n, 1, 3 );
197  }
198 #ifdef AIMS_DEBUG_IO
199  catch( std::exception & e )
200  {
201  std::cout << "0. soma::Reader failed: " << e.what() << std::endl;
202  }
203 #else
204  catch( ... ) {}
205 #endif
206 
207  // if it failed, continue with aims reader.
208 
209 #ifdef AIMS_DEBUG_IO
210  std::cout << "Reader<" << carto::DataTypeCode<T>::name() << ">\n";
211 #endif
212 
213  std::set<std::string> tried;
214  std::set<FileFormat<T> *> triedf;
215  FileFormat<T> *reader;
216  std::set<std::string>::iterator notyet = tried.end();
217  typename std::set<FileFormat<T> *>::iterator notyetf = triedf.end();
218  int excp = 0;
219  int exct = -1;
220  std::string excm;
221 
222  if( format ) // priority to format hint
223  {
224  reader = FileFormatDictionary<T>::fileFormat( *format );
225  if( reader )
226  {
227  try
228  {
229 #ifdef AIMS_DEBUG_IO
230  std::cout << "1. try reader " << *format << std::endl;
231 #endif
232  if( reader->read( _filename, obj, _alloccontext, _options ) )
233  {
234 #ifdef AIMS_DEBUG_IO
235  std::cout << "1. " << *format << " OK\n";
236 #endif
238  if( h )
240  return true;
241  }
242  }
243  catch( std::exception & e )
244  {
245 #ifdef AIMS_DEBUG_IO
246  std::cout << "1. failed: " << e.what() << "\n";
247 #endif
248  carto::io_error::keepExceptionPriority( e, excp, exct, excm,
249  5 );
250  }
251  tried.insert( *format );
252  triedf.insert( reader );
253  }
254  }
255 
256  std::string bname = carto::FileUtil::basename( _filename );
257  std::string::size_type pos = bname.find( '.' );
258  std::string::size_type dlen = _filename.length() - bname.length();
259  std::string ext;
260 
261  if( pos != std::string::npos )
262  ext = _filename.substr( dlen+pos+1, _filename.length() - pos - 1 );
263 
264  const std::map<std::string, std::list<std::string> > & extensions
266 
267  std::map<std::string, std::list<std::string> >::const_iterator iext
268  = extensions.find( ext ),
269  eext = extensions.end();
270  std::list<std::string>::const_iterator ie, ee;
271 
272  while( iext == eext && (pos=bname.find( '.', pos+1 ))!=std::string::npos )
273  {
274  ext = _filename.substr( dlen+pos+1, _filename.length() - pos - 1 );
275  iext = extensions.find( ext );
276  }
277 
278  // try every matching format until one works
279  if( iext != eext )
280  for( ie=iext->second.begin(), ee=iext->second.end(); ie!=ee; ++ie )
281  if( tried.find( *ie ) == notyet )
282  {
283  reader = FileFormatDictionary<T>::fileFormat( *ie );
284  if( reader && triedf.find( reader ) == notyetf )
285  {
286  try
287  {
288 #ifdef AIMS_DEBUG_IO
289  std::cout << "2. try reader " << *ie << std::endl;
290 #endif
291  if( reader->read( _filename, obj, _alloccontext, _options ) )
292  {
293 #ifdef AIMS_DEBUG_IO
294  std::cout << "2. " << *ie << " OK\n";
295 #endif
297  if( h )
299  return true;
300  }
301  }
302  catch( std::exception & e )
303  {
304 #ifdef AIMS_DEBUG_IO
305  std::cout << "2. failed: " << e.what() << "\n";
306 #endif
307  carto::io_error::keepExceptionPriority( e, excp, exct,
308  excm );
309  }
310 #ifdef AIMS_DEBUG_IO
311  std::cout << "2. unsuccessfully tried " << *ie << std::endl;
312 #endif
313  tried.insert( *ie );
314  triedf.insert( reader );
315  }
316  }
317 
318  if( !ext.empty() )
319  {
320  // not found or none works: try readers with no extension
321  iext = extensions.find( "" );
322 
323  if( iext != eext )
324  for( ie=iext->second.begin(), ee=iext->second.end(); ie!=ee; ++ie )
325  if( tried.find( *ie ) == notyet )
326  {
327  reader = FileFormatDictionary<T>::fileFormat( *ie );
328  if( reader && triedf.find( reader ) == notyetf )
329  {
330  try
331  {
332 #ifdef AIMS_DEBUG_IO
333  std::cout << "3. try reader " << *ie << std::endl;
334 #endif
335  if( reader->read( _filename, obj, _alloccontext, _options ) )
336  {
337 #ifdef AIMS_DEBUG_IO
338  std::cout << "3. " << *ie << " OK\n";
339 #endif
341  if( h )
343  return true;
344  }
345  }
346  catch( std::exception & e )
347  {
348 #ifdef AIMS_DEBUG_IO
349  std::cout << "3. failed: " << e.what() << "\n";
350 #endif
351  carto::io_error::keepExceptionPriority( e, excp, exct,
352  excm );
353  }
354  tried.insert( *ie );
355  triedf.insert( reader );
356  }
357  }
358  }
359 
360  // still not found ? well, try EVERY format this time...
361  for( iext=extensions.begin(); iext!=eext; ++iext )
362  for( ie=iext->second.begin(), ee=iext->second.end(); ie!=ee; ++ie )
363  if( tried.find( *ie ) == notyet )
364  {
365  reader = FileFormatDictionary<T>::fileFormat( *ie );
366  if( reader && triedf.find( reader ) == notyetf )
367  {
368  try
369  {
370 #ifdef AIMS_DEBUG_IO
371  std::cout << "4. try reader " << *ie << std::endl;
372 #endif
373  if( reader->read( _filename, obj, _alloccontext, _options ) )
374  {
375 #ifdef AIMS_DEBUG_IO
376  std::cout << "4. " << *ie << " OK\n";
377 #endif
379  if( h )
381  return true;
382  }
383  }
384  catch( std::exception & e )
385  {
386 #ifdef AIMS_DEBUG_IO
387  std::cout << "4. failed: " << e.what() << "\n";
388 #endif
389  carto::io_error::keepExceptionPriority( e, excp, exct,
390  excm );
391  }
392  tried.insert( *ie );
393  triedf.insert( reader );
394  }
395  }
396 
397  // try first soma-io reader (since 2013)
398  // try pass 4
399  try
400  {
401  // building uri
402  std::string uri = _filename;
403  if( border != 0 || frame != -1 )
404  uri += "?";
405  if( border != 0 )
406  uri += ( "border=" + carto::toString( border ) );
407  if( border != 0 && frame != -1 )
408  uri += "&";
409  if ( frame != -1 )
410  uri += ( "ot=" + carto::toString( frame ) + "&st=1" );
411 
412  soma::Reader<T> reader( uri );
413  reader.setOptions( _options );
414  const carto::Object & n = carto::none();
415  return reader.read( obj, n, 4, 4 );
416  } catch( ... ) {}
417  // if it failed, it's hopeless.
418 
419  // still not succeeded, it's hopeless...
420  carto::io_error::launchExcept( exct, excm,
421  _filename + " : no matching format" );
422  return( false );
423  }
424 
425 
426  template<class T>
427  T* Reader<T>::read( int border, const std::string* format, int frame )
428  {
429  // take care of old-style options
430  if( !_options.get() )
432  if( frame >= 0 )
433  {
434  _options->setProperty( "frame", frame );
435  // (for graphs)
436  _options->setProperty( "subobjectsfilter", frame );
437  }
438  if( border > 0 )
439  _options->setProperty( "border", border );
440 
441  std::string _format;
442  if( !format )
443  {
444  try
445  {
446  carto::Object oformat = _options->getProperty( "format" );
447  _format = oformat->getString();
448  format = &_format;
449  }
450  catch( ... )
451  {
452  }
453  }
454  else
455  _options->setProperty( "format", *format );
456 
457  // try first soma-io reader (since 2013)
458  // try first 3 passes
459  try
460  {
461  // building uri
462  std::string uri = _filename;
463  if( border != 0 || frame != -1 )
464  uri += "?";
465  if( border != 0 )
466  uri += ( "border=" + carto::toString( border ) );
467  if( border != 0 && frame != -1 )
468  uri += "&";
469  if ( frame != -1 )
470  uri += ( "ot=" + carto::toString( frame ) + "&st=1" );
471 
472  soma::Reader<T> reader( uri );
473  // set conversion option to invoque Carto2AimsHeaderTranslator
474  carto::Object options = _options;
475  if( options.isNull() )
477  options->setProperty( "convert_to_aims", true );
478  reader.setOptions( options );
479  reader.setAllocatorContext( allocatorContext() );
480  return reader.read( carto::none(), 1, 3 );
481  } catch( ... ) {}
482  // if it failed, continue with aims reader.
483 
484  std::set<std::string> tried;
485  std::set<FileFormat<T> *> triedf;
486  FileFormat<T> *reader;
487  std::set<std::string>::iterator notyet = tried.end();
488  typename std::set<FileFormat<T> *>::iterator notyetf = triedf.end();
489  T *obj;
490  int excp = 0;
491  int exct = -1;
492  std::string excm;
493 
494  if( format ) // priority to format hint
495  {
496  reader = FileFormatDictionary<T>::fileFormat( *format );
497  if( reader )
498  {
499  try
500  {
501  obj = reader->read( _filename, _alloccontext, _options );
502  if( obj )
503  {
505  if( h )
507  return( obj );
508  }
509  }
510  catch( std::exception & e )
511  {
512  carto::io_error::keepExceptionPriority( e, excp, exct, excm,
513  5 );
514  }
515  tried.insert( *format );
516  triedf.insert( reader );
517  }
518  }
519 
520  std::string ext = FileFormatDictionary<T>::fileExtension( _filename );
521 
522  const std::map<std::string, std::list<std::string> > & extensions
524 
525  std::map<std::string, std::list<std::string> >::const_iterator iext
526  = extensions.find( ext ),
527  eext = extensions.end();
528  std::list<std::string>::const_iterator ie, ee;
529 
530  // try every matching format until one works
531  if( iext != eext )
532  for( ie=iext->second.begin(), ee=iext->second.end(); ie!=ee; ++ie )
533  if( tried.find( *ie ) == notyet )
534  {
535  reader = FileFormatDictionary<T>::fileFormat( *ie );
536  if( reader && triedf.find( reader ) == notyetf )
537  {
538  try
539  {
540  obj = reader->read( _filename, _alloccontext, _options );
541  if( obj )
542  {
544  if( h )
546  return( obj );
547  }
548  }
549  catch( std::exception & e )
550  {
551  carto::io_error::keepExceptionPriority( e, excp, exct,
552  excm );
553  }
554  tried.insert( *ie );
555  triedf.insert( reader );
556  }
557  }
558 
559  if( !ext.empty() )
560  {
561  // not found or none works: try readers with no extension
562  iext = extensions.find( "" );
563 
564  if( iext != eext )
565  for( ie=iext->second.begin(), ee=iext->second.end(); ie!=ee; ++ie )
566  if( tried.find( *ie ) == notyet )
567  {
568  reader = FileFormatDictionary<T>::fileFormat( *ie );
569  if( reader && triedf.find( reader ) == notyetf )
570  {
571  try
572  {
573  obj = reader->read( _filename, _alloccontext, _options );
574  if( obj )
575  {
577  if( h )
579  return( obj );
580  }
581  }
582  catch( std::exception & e )
583  {
584  carto::io_error::keepExceptionPriority( e, excp, exct,
585  excm );
586  }
587  tried.insert( *ie );
588  triedf.insert( reader );
589  }
590  }
591  }
592 
593  // still not found ? well, try EVERY format this time...
594  for( iext=extensions.begin(); iext!=eext; ++iext )
595  for( ie=iext->second.begin(), ee=iext->second.end(); ie!=ee; ++ie )
596  if( tried.find( *ie ) == notyet )
597  {
598  reader = FileFormatDictionary<T>::fileFormat( *ie );
599  if( reader && triedf.find( reader ) == notyetf )
600  {
601  try
602  {
603  obj = reader->read( _filename, _alloccontext, _options );
604  if( obj )
605  {
607  if( h )
609  return( obj );
610  }
611  }
612  catch( std::exception & e )
613  {
614  carto::io_error::keepExceptionPriority( e, excp, exct,
615  excm );
616  }
617  tried.insert( *ie );
618  triedf.insert( reader );
619  }
620  }
621 
622  // try first soma-io reader (since 2013)
623  // try pass 4
624  try
625  {
626  // building uri
627  std::string uri = _filename;
628  if( border != 0 || frame != -1 )
629  uri += "?";
630  if( border != 0 )
631  uri += ( "border=" + carto::toString( border ) );
632  if( border != 0 && frame != -1 )
633  uri += "&";
634  if ( frame != -1 )
635  uri += ( "ot=" + carto::toString( frame ) + "&st=1" );
636 
637  soma::Reader<T> reader( uri );
638  reader.setOptions( _options );
639  return reader.read( carto::none(), 4, 4 );
640  } catch( ... ) {}
641  // if it failed, it's hopeless
642 
643  // still not succeeded, it's hopeless...
644  carto::io_error::launchExcept( exct, excm,
645  _filename + " : no matching format" );
646  return( 0 );
647  }
648 
649 }
650 
651 
652 #endif
virtual bool getProperty(const std::string &key, Object &value) const =0
static std::string fileExtension(const std::string &filename)
Definition: fileFormat_d.h:126
static std::string basename(const std::string &)
void setMode(carto::AllocatorStrategy::MappingMode mode)
set input file mode - soon obsolete
Definition: reader_d.h:74
bool isNull() const
std::string name()
void setFileName(const std::string &fileName)
set input file name
Definition: reader_d.h:113
const carto::AllocatorStrategy::MappingMode MAP
carto::Object getObjectHeader(Headered &h)
void setAllocatorContext(const AllocatorContext &ac)
static const std::map< std::string, std::list< std::string > > & extensions()
Definition: fileFormat_d.h:104
virtual bool read(const std::string &filename, T &obj, const carto::AllocatorContext &context, carto::Object options)=0
static FileFormat< T > * fileFormat(const std::string &format)
Definition: fileFormat_d.h:171
void setAllocatorContext(const carto::AllocatorContext &ac)
allocator control (not used by every format yet)
Definition: reader_d.h:101
void setOptions(carto::Object options)
virtual void setProperty(const std::string &key, Object value)=0
static void postProcessHeader(carto::Object hdr)
carto::Object options() const
Definition: reader_d.h:125
static Object value()
const carto::AllocatorContext & allocatorContext() const
Definition: reader_d.h:107
virtual bool read(T &obj, carto::Object header=carto::none(), int passbegin=1, int passend=4)
std::map< std::string, Object > Dictionary
virtual std::string getString() const =0
std::string toString(const T &object)
Object none()
Pointer to an empty aims::StructuringElement.
virtual bool read(T &obj, int border=0, const std::string *format=0, int frame=-1)
Finds the correct format and reads the object. if format is specified, this format is tried first...
Definition: reader_d.h:137
void setOptions(carto::Object options)
Definition: reader_d.h:119
Low-level object IO format: each specific format has such a reader / writer.
Definition: fileFormat.h:61