aimsdata 6.0.0
Neuroimaging data handling
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>
44#include <cartobase/exception/ioexcept.h>
45#include <cartobase/stream/fileutil.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
70namespace 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 {
90 }
91
92
93 template<class T>
95 {
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
111 carto::PluginLoader::load();
112
113 bool exactformat = false;
115
116 errno = 0; // start with a clean situation
117
118 // Copy aims settings to options
119 options->copyProperties(
121 Settings::settings().getValue() ) );
122
123 if( !_options.isNull() )
124 {
125 try
126 {
127 carto::Object exact = _options->getProperty( "exact_format" );
128 exactformat = (bool) exact->getScalar();
129 }
130 catch( ... )
131 {
132 }
133 options->copyProperties( _options );
134 }
135
136 if( !options->hasProperty( "ascii" ) )
137 options->setProperty( "ascii", ascii );
138
139 std::string _format;
140 if( !format )
141 {
142 try
143 {
144 carto::Object oformat = options->getProperty( "format" );
145 _format = oformat->getString();
146 format = &_format;
147 }
148 catch( ... )
149 {
150 }
151 }
152 else
153 options->setProperty( "format", *format );
154
155 // try first soma-io writer (since 2013)
156 // try first 3 passes
157 try
158 {
159 // building uri
160 std::string uri = _filename;
161 if( ascii || format )
162 uri += "?";
163 if( ascii )
164 uri += "ascii";
165 if( ascii && format )
166 uri += "&";
167 if ( format )
168 uri += ( "format=" + *format );
169
170 soma::Writer<T> writer( uri );
171 // copy options so that they are not modified
173 // Copy aims settings to options
174 options->copyProperties(
176 Settings::settings().getValue() ) );
177
178 if( !_options.isNull() )
179 options->copyProperties( _options );
180 return writer.write( obj, options, 1, 3 );
181 }
182 catch( ... )
183 {
185 }
186
187 // if it failed, continue with aims writer.
188
189 std::set<std::string> tried;
190 FileFormat<T> *writer;
191 std::set<std::string>::iterator notyet = tried.end();
192 int excp = 0;
193 int exct = -1;
194 std::string excm;
195
196 if( format ) // priority to format hint
197 {
198
199 writer = FileFormatDictionary<T>::fileFormat( *format );
200 if( writer )
201 {
202#ifdef AIMS_DEBUG_IO
203 std::cout << "1. try writer " << *format << std::endl;
204#endif
205 try
206 {
207 if( writer->write( _filename, obj, options ) )
208 return true;
209 else
210 {
212 if( exactformat )
213 throw carto::wrong_format_error( std::string( "1. Cannot write "
214 "object in format " ) + *format, _filename );
215 }
216 }
217 catch( std::exception & e )
218 {
219 if( exactformat )
220 throw;
222 carto::io_error::keepExceptionPriority( e, excp, exct, excm,
223 5 );
224 }
225 tried.insert( *format );
226 }
227 }
228
229 std::string bname = carto::FileUtil::basename( _filename );
230 std::string::size_type pos = bname.find( '.' );
231 std::string::size_type dlen = _filename.length() - bname.length();
232 std::string ext;
233
234 if( pos != std::string::npos )
235 ext = _filename.substr( dlen+pos+1, _filename.length() - pos - 1 );
236
237 const std::map<std::string, std::list<std::string> > & extensions
239
240 std::map<std::string, std::list<std::string> >::const_iterator iext
241 = extensions.find( ext ),
242 eext = extensions.end();
243 std::list<std::string>::const_iterator ie, ee;
244
245 if( ext.empty() )
246 {
247 // no extension: use settings for default_writer if one is specified
248 const Settings &sett = Settings::settings();
249 try
250 {
251 carto::Object defwriters = sett.getProperty( "default_writers" );
252 carto::Object defformato;
253 try
254 {
255 defformato
256 = defwriters->getProperty( carto::DataTypeCode<T>::name() );
257 }
258 catch( std::exception & )
259 {
260 // exact type not found, try just the object type
261 defformato
262 = defwriters->getProperty( carto::DataTypeCode<T>::objectType() );
263 }
264 if( defformato )
265 {
266 std::string defformat = defformato->getString();
267
268 if( tried.find( defformat ) == notyet )
269 {
270 writer = FileFormatDictionary<T>::fileFormat( defformat );
271 if( writer )
272 {
273#ifdef AIMS_DEBUG_IO
274 std::cout << "2. try writer " << defformat << std::endl;
275#endif
276 try
277 {
278 if( writer->write( _filename, obj, options ) )
279 return true;
280 else
281 {
283 if( exactformat )
285 std::string( "2. Cannot write object in format " )
286 + defformat, _filename );
287 }
288 }
289 catch( std::exception & e )
290 {
291 if( exactformat )
292 throw;
294 carto::io_error::keepExceptionPriority( e, excp, exct, excm,
295 5 );
296 }
297 tried.insert( defformat );
298 }
299 }
300 }
301 }
302 catch( std::exception & )
303 {
304 }
305 }
306
307 while( iext == eext && (pos=bname.find( '.', pos+1 ))!=std::string::npos )
308 {
309 ext = _filename.substr( dlen+pos+1, _filename.length() - pos - 1 );
310 iext = extensions.find( ext );
311 }
312
313 // try every matching format until one works
314 if( iext != eext )
315 for( ie=iext->second.begin(), ee=iext->second.end(); ie!=ee; ++ie )
316 {
317 if( tried.find( *ie ) == notyet )
318 {
320 if( writer )
321 {
322#ifdef AIMS_DEBUG_IO
323 std::cout << "3. try writer " << *ie << std::endl;
324#endif
325 try
326 {
327 if( writer->write( _filename, obj, options ) )
328 return true;
329 else
330 {
332 if( exactformat )
334 std::string( "3. Cannot write object in format " )
335 + *ie, _filename );
336 }
337 }
338 catch( std::exception & e )
339 {
340#ifdef AIMS_DEBUG_IO
341 std::cout << "3. failed for " << *ie << ": " << e.what()
342 << std::endl;
343#endif
344 if( exactformat )
345 throw;
348 excm );
349 }
350 tried.insert( *ie );
351 }
352 }
353 }
354
355 if( !ext.empty() )
356 {
357 // not found or none works: try writers with no extension
358 iext = extensions.find( "" );
359
360 if( iext != eext )
361 for( ie=iext->second.begin(), ee=iext->second.end(); ie!=ee; ++ie )
362 if( tried.find( *ie ) == notyet )
363 {
365 if( writer )
366 {
367#ifdef AIMS_DEBUG_IO
368 std::cout << "4. try writer " << *ie << std::endl;
369#endif
370 try
371 {
372 if( writer->write( _filename, obj, options ) )
373 return true;
374 else
375 {
377 if( exactformat )
379 std::string( "4. Cannot write object in format " )
380 + *ie, _filename );
381 }
382 }
383 catch( std::exception & e )
384 {
385 if( exactformat )
386 throw;
389 excm );
390 }
391 tried.insert( *ie );
392 }
393 }
394 }
395
396 // still not found ? well, try EVERY format this time...
397 for( iext=extensions.begin(); iext!=eext; ++iext )
398 for( ie=iext->second.begin(), ee=iext->second.end(); ie!=ee; ++ie )
399 if( tried.find( *ie ) == notyet )
400 {
402 if( writer )
403 {
404#ifdef AIMS_DEBUG_IO
405 std::cout << "5. try writer " << *ie << std::endl;
406#endif
407 try
408 {
409 if( writer->write( _filename, obj, options ) )
410 return true;
411 else
412 {
414 if( exactformat )
416 std::string( "5. Cannot write object in format " )
417 + *ie, _filename );
418 }
419 }
420 catch( std::exception & e )
421 {
422 if( exactformat )
423 throw;
426 excm );
427 }
428 tried.insert( *ie );
429 }
430 }
431
432 // try first soma-io writer (since 2013)
433 // try pass 4
434 try{
435 // building uri
436 std::string uri = _filename;
437 if( ascii || format )
438 uri += "?";
439 if( ascii )
440 uri += "ascii";
441 if( ascii && format )
442 uri += "&";
443 if ( format )
444 uri += ( "format=" + *format );
445
446 soma::Writer<T> writer( uri );
447 return writer.write( obj, _options, 4, 4 );
448 }
449 catch( ... )
450 {
452 }
453 // if it failed, it's hopeless
454
455 // still not succeeded, it's hopeless...
457 _filename + " : no matching format" );
458 return( false );
459 }
460
461}
462
463
464#endif
465
466
static FileFormat< T > * fileFormat(const std::string &format)
static const std::map< std::string, std::list< std::string > > & extensions()
Low-level object IO format: each specific format has such a reader / writer.
Definition fileFormat.h:62
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...
const carto::Object options() const
Definition writer.h:72
carto::Object _options
Definition writer.h:81
const std::string & fileName() const
get output file name
Definition writer.h:71
std::string _filename
Definition writer.h:80
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
static Settings & settings()
Generic writer for every format of Aims object.
Definition writer.h:94
virtual std::string writtenObjectType() const
Definition writer_d.h:87
virtual std::string writtenObjectDataType() const
Definition writer_d.h:94
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
virtual std::string writtenObjectFullType() const
Definition writer_d.h:101
std::string name()
std::string objectType()
std::string dataType()
static std::string basename(const std::string &)
Object reference(Object &value)
static Object value()
static void keepExceptionPriority(std::exception &e, int &prio, int &type, std::string &message, int raiseprio=0)
static void checkFatalIOErrno(const std::string &filename="")
static void launchExcept(int code, const std::string &msg, const std::string &defmsg="")
virtual bool write(const T &obj, carto::Object options=carto::none(), int passbegin=1, int passend=4)
The class for EcatSino data write operation.
std::map< std::string, Object > Dictionary