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