A.I.M.S


writer_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 /*
35  * writer class
36  */
37 #ifndef AIMS_IO_WRITER_D_H
38 #define AIMS_IO_WRITER_D_H
39 
40 
41 #include <aims/io/writer.h>
42 #include <aims/io/fileFormat.h>
43 #include <aims/def/settings.h>
47 #include <set>
48 #include <soma-io/io/writer.h>
50 
51 #define AIMS_INSTANTIATE_WRITER( T ) \
52  namespace aims { \
53  template class aims::Writer< T >; \
54  template bool \
55  GenericWriter::write< T >( const T &, bool, const std::string * ); \
56  }
57 
58  #define AIMS_INSTANTIATE_ONLY_WRITER( T ) \
59  namespace aims { \
60  template class aims::Writer< T >; \
61  }
62 
63 #include <iostream>
64 
65 
66 /* WARNING: be careful to include <aims/io/datatypecode.h> before
67  including this writer_d.h header
68 */
69 
70 namespace aims
71 {
72 
73  template <typename T>
74  bool GenericWriter::write( const T & obj, bool ascii,
75  const std::string* format )
76  {
77  Writer<T> *writer = dynamic_cast< Writer<T> * >( this );
78  if ( ! writer ) {
80  }
81  return writer->write( obj, ascii, format );
82  }
83 
84 
85 
86  template<class T>
87  std::string Writer<T>::writtenObjectType() const
88  {
89  return carto::DataTypeCode<T>().objectType();
90  }
91 
92 
93  template<class T>
95  {
96  return carto::DataTypeCode<T>().dataType();
97  }
98 
99 
100  template<class T>
102  {
104  }
105 
106 
107  template<class T>
108  bool Writer<T>::write( const T & obj, bool ascii, const std::string* format )
109  {
110  // force loading plugins if it has not been done already
112 
113  bool exactformat = false;
115  if( !_options.isNull() )
116  {
117  try
118  {
119  carto::Object exact = _options->getProperty( "exact_format" );
120  exactformat = (bool) exact->getScalar();
121  }
122  catch( ... )
123  {
124  }
125  options->copyProperties( _options );
126  }
127 
128  if( !options->hasProperty( "ascii" ) )
129  options->setProperty( "ascii", ascii );
130 
131  std::string _format;
132  if( !format )
133  {
134  try
135  {
136  carto::Object oformat = options->getProperty( "format" );
137  _format = oformat->getString();
138  format = &_format;
139  }
140  catch( ... )
141  {
142  }
143  }
144  else
145  options->setProperty( "format", *format );
146 
147  // try first soma-io writer (since 2013)
148  // try first 3 passes
149  try
150  {
151  // building uri
152  std::string uri = _filename;
153  if( ascii || format )
154  uri += "?";
155  if( ascii )
156  uri += "ascii";
157  if( ascii && format )
158  uri += "&";
159  if ( format )
160  uri += ( "format=" + *format );
161 
162  soma::Writer<T> writer( uri );
163  // copy options so that they are not modified
165  if( !_options.isNull() )
166  options->copyProperties( _options );
167  return writer.write( obj, options, 1, 3 );
168  }
169  catch( ... )
170  {
171  }
172 
173  // if it failed, continue with aims writer.
174 
175  std::set<std::string> tried;
176  FileFormat<T> *writer;
177  std::set<std::string>::iterator notyet = tried.end();
178  int excp = 0;
179  int exct = -1;
180  std::string excm;
181 
182  if( format ) // priority to format hint
183  {
184 
185  writer = FileFormatDictionary<T>::fileFormat( *format );
186  if( writer )
187  {
188 #ifdef AIMS_DEBUG_IO
189  std::cout << "1. try writer " << *format << std::endl;
190 #endif
191  try
192  {
193  if( writer->write( _filename, obj, options ) )
194  return true;
195  else if( exactformat )
196  throw carto::wrong_format_error( std::string( "1. Cannot write "
197  "object in format " ) + *format, _filename );
198  }
199  catch( std::exception & e )
200  {
201  if( exactformat )
202  throw;
203  carto::io_error::keepExceptionPriority( e, excp, exct, excm,
204  5 );
205  }
206  tried.insert( *format );
207  }
208  }
209 
210  std::string bname = carto::FileUtil::basename( _filename );
211  std::string::size_type pos = bname.find( '.' );
212  std::string::size_type dlen = _filename.length() - bname.length();
213  std::string ext;
214 
215  if( pos != std::string::npos )
216  ext = _filename.substr( dlen+pos+1, _filename.length() - pos - 1 );
217 
218  const std::map<std::string, std::list<std::string> > & extensions
220 
221  std::map<std::string, std::list<std::string> >::const_iterator iext
222  = extensions.find( ext ),
223  eext = extensions.end();
224  std::list<std::string>::const_iterator ie, ee;
225 
226  if( ext.empty() )
227  {
228  // no extension: use settings for default_writer if one is specified
229  const Settings &sett = Settings::settings();
230  try
231  {
232  carto::Object defwriters = sett.getProperty( "default_writers" );
233  carto::Object defformato;
234  try
235  {
236  defformato
237  = defwriters->getProperty( carto::DataTypeCode<T>::name() );
238  }
239  catch( std::exception & )
240  {
241  // exact type not found, try just the object type
242  defformato
244  }
245  if( defformato )
246  {
247  std::string defformat = defformato->getString();
248 
249  if( tried.find( defformat ) == notyet )
250  {
251  writer = FileFormatDictionary<T>::fileFormat( defformat );
252  if( writer )
253  {
254 #ifdef AIMS_DEBUG_IO
255  std::cout << "2. try writer " << defformat << std::endl;
256 #endif
257  try
258  {
259  if( writer->write( _filename, obj, options ) )
260  return true;
261  else if( exactformat )
262  throw carto::wrong_format_error( std::string( "2. Cannot write "
263  "object in format " ) + defformat, _filename );
264  }
265  catch( std::exception & e )
266  {
267  if( exactformat )
268  throw;
269  carto::io_error::keepExceptionPriority( e, excp, exct, excm,
270  5 );
271  }
272  tried.insert( defformat );
273  }
274  }
275  }
276  }
277  catch( std::exception & )
278  {
279  }
280  }
281 
282  while( iext == eext && (pos=bname.find( '.', pos+1 ))!=std::string::npos )
283  {
284  ext = _filename.substr( dlen+pos+1, _filename.length() - pos - 1 );
285  iext = extensions.find( ext );
286  }
287 
288  // try every matching format until one works
289  if( iext != eext )
290  for( ie=iext->second.begin(), ee=iext->second.end(); ie!=ee; ++ie )
291  {
292  if( tried.find( *ie ) == notyet )
293  {
294  writer = FileFormatDictionary<T>::fileFormat( *ie );
295  if( writer )
296  {
297 #ifdef AIMS_DEBUG_IO
298  std::cout << "3. try writer " << *ie << std::endl;
299 #endif
300  try
301  {
302  if( writer->write( _filename, obj, options ) )
303  return true;
304  else if( exactformat )
305  throw carto::wrong_format_error( std::string( "3. Cannot write "
306  "object in format " ) + *ie, _filename );
307  }
308  catch( std::exception & e )
309  {
310 #ifdef AIMS_DEBUG_IO
311  std::cout << "3. failed for " << *ie << ": " << e.what()
312  << std::endl;
313 #endif
314  if( exactformat )
315  throw;
316  carto::io_error::keepExceptionPriority( e, excp, exct,
317  excm );
318  }
319  tried.insert( *ie );
320  }
321  }
322  }
323 
324  if( !ext.empty() )
325  {
326  // not found or none works: try writers with no extension
327  iext = extensions.find( "" );
328 
329  if( iext != eext )
330  for( ie=iext->second.begin(), ee=iext->second.end(); ie!=ee; ++ie )
331  if( tried.find( *ie ) == notyet )
332  {
333  writer = FileFormatDictionary<T>::fileFormat( *ie );
334  if( writer )
335  {
336 #ifdef AIMS_DEBUG_IO
337  std::cout << "4. try writer " << *ie << std::endl;
338 #endif
339  try
340  {
341  if( writer->write( _filename, obj, options ) )
342  return true;
343  else if( exactformat )
344  throw carto::wrong_format_error( std::string( "4. Cannot write "
345  "object in format " ) + *ie, _filename );
346  }
347  catch( std::exception & e )
348  {
349  if( exactformat )
350  throw;
351  carto::io_error::keepExceptionPriority( e, excp, exct,
352  excm );
353  }
354  tried.insert( *ie );
355  }
356  }
357  }
358 
359  // still not found ? well, try EVERY format this time...
360  for( iext=extensions.begin(); iext!=eext; ++iext )
361  for( ie=iext->second.begin(), ee=iext->second.end(); ie!=ee; ++ie )
362  if( tried.find( *ie ) == notyet )
363  {
364  writer = FileFormatDictionary<T>::fileFormat( *ie );
365  if( writer )
366  {
367 #ifdef AIMS_DEBUG_IO
368  std::cout << "5. try writer " << *ie << std::endl;
369 #endif
370  try
371  {
372  if( writer->write( _filename, obj, options ) )
373  return true;
374  else if( exactformat )
375  throw carto::wrong_format_error( std::string( "5. Cannot write "
376  "object in format " ) + *ie, _filename );
377  }
378  catch( std::exception & e )
379  {
380  if( exactformat )
381  throw;
382  carto::io_error::keepExceptionPriority( e, excp, exct,
383  excm );
384  }
385  tried.insert( *ie );
386  }
387  }
388 
389  // try first soma-io writer (since 2013)
390  // try pass 4
391  try{
392  // building uri
393  std::string uri = _filename;
394  if( ascii || format )
395  uri += "?";
396  if( ascii )
397  uri += "ascii";
398  if( ascii && format )
399  uri += "&";
400  if ( format )
401  uri += ( "format=" + *format );
402 
403  soma::Writer<T> writer( uri );
404  return writer.write( obj, _options, 4, 4 );
405  } catch( ... ) {}
406  // if it failed, it's hopeless
407 
408  // still not succeeded, it's hopeless...
409  carto::io_error::launchExcept( exct, excm,
410  _filename + " : no matching format" );
411  return( false );
412  }
413 
414 }
415 
416 
417 #endif
418 
419 
bool write(const T &obj, bool ascii=false, const std::string *format=0)
Finds the correct format and writes the object.
Definition: writer_d.h:74
virtual std::string writtenObjectDataType() const
Definition: writer_d.h:94
virtual bool getProperty(const std::string &key, Object &value) const =0
static std::string basename(const std::string &)
virtual bool hasProperty(const std::string &key) const =0
std::string name()
virtual std::string writtenObjectType() const
Definition: writer_d.h:87
virtual double getScalar() const =0
virtual bool write(const T &obj, carto::Object options=carto::none(), int passbegin=1, int passend=4)
virtual bool write(const T &obj, bool ascii=false, const std::string *format=0)
Finds the correct format and writes the object.
Definition: writer_d.h:108
static const std::map< std::string, std::list< std::string > > & extensions()
Definition: fileFormat_d.h:104
static FileFormat< T > * fileFormat(const std::string &format)
Definition: fileFormat_d.h:171
virtual void setProperty(const std::string &key, Object value)=0
virtual bool write(const std::string &, const T &, carto::Object options=carto::none())
the base class has a default implementation which only returns false so if your new format only suppo...
Definition: fileFormat_d.h:72
virtual std::string writtenObjectFullType() const
Definition: writer_d.h:101
static Object value()
static Settings & settings()
Generic writer for every format of Aims object.
Definition: writer.h:92
std::map< std::string, Object > Dictionary
static void load(int verboseLevel=-1, bool forcereload=false)
virtual std::string getString() const =0
virtual void copyProperties(Object source)
Low-level object IO format: each specific format has such a reader / writer.
Definition: fileFormat.h:61
const std::string & fileName() const
get output file name
Definition: writer.h:71