soma-io  5.0.5
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 #ifndef SOMAIO_IO_WRITER_D_H
35 #define SOMAIO_IO_WRITER_D_H
36 //--- soma-io ----------------------------------------------------------------
38 #include <soma-io/io/writer.h>
43 //--- cartobase --------------------------------------------------------------
47 //--- system -----------------------------------------------------------------
48 #include <set>
49 //--- debug ------------------------------------------------------------------
51 #define localMsg( message ) cartoCondMsg( 4, message, "WRITER" )
52 // localMsg must be undef at end of file
53 //----------------------------------------------------------------------------
54 
55 namespace soma
56 {
57 
58  template <typename T>
59  bool GenericWriter::write( const T & obj, carto::Object options )
60  {
61  Writer<T> *writer = dynamic_cast< Writer<T> * >( this );
62  if ( ! writer ) {
63  std::string filename;
64  filename = _datasourceinfo->list().dataSource()->url();
65 
66  throw carto::format_mismatch_error( filename );
67  }
68  return writer->write( obj, options );
69  }
70 
71 
72  template <typename T>
74  {
75  }
76 
77 
78  template <typename T>
80  {
81  }
82 
83 
84  template <typename T>
85  Writer<T>::Writer( const std::string& filename ) : GenericWriter( filename )
86  {
87  }
88 
89 
90  template <typename T>
91  Writer<T>::Writer( std::ostream & stream ) : GenericWriter( stream )
92  {
93  }
94 
95 
96  template<typename T>
98  {
99  }
100 
101 
102  template<class T>
103  std::string Writer<T>::writtenObjectType() const
104  {
106  }
107 
108  //==========================================================================
109  // W R I T E M E T H O D S
110  //==========================================================================
111 
112  //--- useful typedef -------------------------------------------------------
113  typedef std::multimap<std::string,std::string> multi_S;
114  typedef std::set<std::string> set_S;
115  typedef std::pair<std::multimap<std::string, std::string>::const_iterator,
116  std::multimap<std::string, std::string>::const_iterator> pair_cit_S;
117  //--------------------------------------------------------------------------
118 
119  template<class T>
120  bool Writer<T>::write( const T & obj, carto::Object options,
121  int passbegin, int passend )
122  {
123  localMsg( "<" + carto::DataTypeCode<T>::name() + ">" );
124 
125  set_S tried;
126  FormatWriter<T> *writer;
127  set_S::iterator notyet = tried.end();
128  int excp = 0;
129  int exct = -1;
130  std::string excm;
131 
132  if( !options.get() )
134 
136  std::string filename
137  = FileUtil::uriFilename( _datasourceinfo->list().dataSource()->url() );
138  carto::Object urioptions
139  = FileUtil::uriOptions( _datasourceinfo->list().dataSource()->url() );
140  if( urioptions.get() ) {
141  _datasourceinfo->list().dataSource()
142  .reset( new FileDataSource( filename ) );
143  options->copyProperties( urioptions );
144  }
145 
146  std::string format;
147  options->getProperty( "format", format );
148  localMsg( "format: " + format );
149  bool exactformat = false;
150  try
151  {
152  carto::Object exact = options->getProperty( "exact_format" );
153  exactformat = exact->getScalar();
154  }
155  catch( ... )
156  {
157  }
158 
160  if( passbegin <= 1 && passend >= 1 && !format.empty() )
161  {
162  localMsg( "Pass 1..." );
163  writer = FormatDictionary<T>::writeFormat( format );
164  if( writer )
165  {
166  try
167  {
168  localMsg( "1. try writer " + format );
169  if( writer->write( obj, _datasourceinfo, options ) )
170  {
171  localMsg( "1. " + format + " OK" );
172  return true;
173  }
174  else if( exactformat )
175  throw carto::wrong_format_error( std::string( "Cannot write "
176  "object in format " ) + format, _datasourceinfo->url() );
177  }
178  catch( std::exception & e )
179  {
180  localMsg( "1. " + format + " failed" );
181  if( exactformat )
182  throw;
183  carto::io_error::keepExceptionPriority( e, excp, exct, excm, 5 );
184  }
185  tried.insert( format );
186  }
187  else if( exactformat )
188  throw carto::wrong_format_error( std::string( "Cannot write "
189  "object in format " ) + format, _datasourceinfo->url() );
190  }
191 
192  std::string ext = carto::FileUtil::extension( filename );
193  const multi_S & extensions = FormatDictionary<T>::writeExtensions();
194  pair_cit_S iext;
195  multi_S::const_iterator ie, ee;
196  localMsg( "extension: " + carto::toString( ext ) );
197 
199  if( passbegin <= 2 && passend >= 2 )
200  {
201  localMsg( "Pass 2..." );
202  iext = extensions.equal_range( ext );
203  for( ie=iext.first, ee=iext.second; ie!=ee; ++ie )
204  if( tried.find( ie->second ) == notyet ) {
205  writer = FormatDictionary<T>::writeFormat( ie->second );
206  if( writer )
207  {
208  try
209  {
210  localMsg( "2. try writer " + ie->second );
211  if( writer->write( obj, _datasourceinfo, options ) )
212  {
213  localMsg( "2. " + ie->second + " OK" );
214  return true;
215  }
216  else if( exactformat )
217  throw carto::wrong_format_error( std::string( "Cannot write "
218  "object in format " ) + format, _datasourceinfo->url() );
219  }
220  catch( std::exception & e )
221  {
222  localMsg( " 2. " + ie->second + " failed" );
223  if( exactformat )
224  throw;
225  carto::io_error::keepExceptionPriority( e, excp, exct, excm );
226  }
227  tried.insert( ie->second );
228  }
229  }
230  }
231 
233  if( passbegin <= 3 && passend >= 3 && !ext.empty() )
234  {
235  localMsg( "Pass 3..." );
236  iext = extensions.equal_range( "" );
237  for( ie=iext.first, ee=iext.second; ie!=ee; ++ie )
238  if( tried.find( ie->second ) == notyet ) {
239  writer = FormatDictionary<T>::writeFormat( ie->second );
240  if( writer )
241  {
242  try
243  {
244  localMsg( "3. try writer " + ie->second );
245  if( writer->write( obj, _datasourceinfo, options ) )
246  {
247  localMsg( "3. " + ie->second + " OK" );
248  return true;
249  }
250  else if( exactformat )
251  throw carto::wrong_format_error( std::string( "Cannot write "
252  "object in format " ) + format, _datasourceinfo->url() );
253  }
254  catch( std::exception & e )
255  {
256  localMsg( "3. " + ie->second + " failed" );
257  if( exactformat )
258  throw;
259  carto::io_error::keepExceptionPriority( e, excp, exct, excm );
260  }
261  tried.insert( ie->second );
262  }
263  }
264  }
265 
267  if( passbegin <= 4 && passend >= 4 )
268  {
269  localMsg( "Pass 4..." );
270  iext.first = extensions.begin();
271  iext.second = extensions.end();
272  for( ie=iext.first, ee=iext.second; ie!=ee; ++ie )
273  if( tried.find( ie->second ) == notyet ) {
274  writer = FormatDictionary<T>::writeFormat( ie->second );
275  if( writer )
276  {
277  try
278  {
279  localMsg( "4. try writer " + ie->second );
280  if( writer->write( obj, _datasourceinfo, options ) )
281  {
282  localMsg( "4. " + ie->second + " OK" );
283  return true;
284  }
285  else if( exactformat )
286  throw carto::wrong_format_error( std::string( "Cannot write "
287  "object in format " ) + format, _datasourceinfo->url() );
288  }
289  catch( std::exception & e )
290  {
291  localMsg( "4. " + ie->second + " failed" );
292  if( exactformat )
293  throw;
294  carto::io_error::keepExceptionPriority( e, excp, exct, excm );
295  }
296  tried.insert( ie->second );
297  }
298  }
299  }
300 
302  carto::io_error::launchExcept( exct, excm,
303  filename + " : no matching format" );
304  return false;
305  }
306 
307 }
308 
309 #undef localMsg
310 #endif
static const std::multimap< std::string, std::string > & writeExtensions()
static std::string extension(const std::string &)
static FormatWriter< T > * writeFormat(const std::string &format)
static void keepExceptionPriority(std::exception &e, int &prio, int &type, std::string &message, int raiseprio=0)
std::multimap< std::string, std::string > multi_S
Definition: reader_d.h:214
virtual ~Writer()
Definition: writer_d.h:97
Generic writer for every format of Aims object.
Definition: writer.h:102
virtual std::string writtenObjectType() const
Definition: writer_d.h:103
std::string name()
Definition: allocator.h:48
virtual bool write(const T &obj, carto::Object options=carto::none(), int passbegin=1, int passend=4)
Finds the correct format and writes the object.
Definition: writer_d.h:120
Low-level object IO writer specialized for a specific format.
carto::rc_ptr< DataSourceInfo > _datasourceinfo
Definition: writer.h:81
static Object value()
std::pair< std::multimap< std::string, std::string >::const_iterator, std::multimap< std::string, std::string >::const_iterator > pair_cit_S
Definition: reader_d.h:217
GenericObject * get() const
static void launchExcept(int code, const std::string &msg, const std::string &defmsg="")
virtual bool write(const T &obj, carto::rc_ptr< DataSourceInfo > dsi, carto::Object options)=0
std::set< std::string > set_S
Definition: reader_d.h:215
std::string toString(const T &object)
#define localMsg(message)
Definition: writer_d.h:51
bool write(const T &obj, carto::Object options=carto::none())
Finds the correct format and writes the object.
Definition: writer_d.h:59