soma-io 6.0.6
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() + ">" );
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 const multi_S & extensions = FormatDictionary<T>::writeExtensions();
202 pair_cit_S iext;
203 multi_S::const_iterator ie, ee;
204 localMsg( "extension: " + carto::toString( ext ) );
205
207 if( passbegin <= 2 && passend >= 2 )
208 {
209 localMsg( "Pass 2..." );
210 iext = extensions.equal_range( ext );
211 for( ie=iext.first, ee=iext.second; ie!=ee; ++ie )
212 if( tried.find( ie->second ) == notyet ) {
213 writer = FormatDictionary<T>::writeFormat( ie->second );
214 if( writer )
215 {
216 try
217 {
218 localMsg( "2. try writer " + ie->second );
219 if( writer->write( obj, _datasourceinfo, options ) )
220 {
221 localMsg( "2. " + ie->second + " OK" );
222 return true;
223 }
224 else
225 {
226 io_error::checkFatalIOErrno( _datasourceinfo->url() );
227 if( exactformat )
228 throw carto::wrong_format_error( std::string( "Cannot write "
229 "object in format " ) + format, _datasourceinfo->url() );
230 }
231 }
232 catch( std::exception & e )
233 {
234 localMsg( " 2. " + ie->second + " failed" );
235 if( exactformat )
236 throw;
237 io_error::checkFatalIOErrno( _datasourceinfo->url() );
238 carto::io_error::keepExceptionPriority( e, excp, exct, excm );
239 }
240 tried.insert( ie->second );
241 }
242 }
243 }
244
246 if( passbegin <= 3 && passend >= 3 && !ext.empty() )
247 {
248 localMsg( "Pass 3..." );
249 iext = extensions.equal_range( "" );
250 for( ie=iext.first, ee=iext.second; ie!=ee; ++ie )
251 if( tried.find( ie->second ) == notyet ) {
252 writer = FormatDictionary<T>::writeFormat( ie->second );
253 if( writer )
254 {
255 try
256 {
257 localMsg( "3. try writer " + ie->second );
258 if( writer->write( obj, _datasourceinfo, options ) )
259 {
260 localMsg( "3. " + ie->second + " OK" );
261 return true;
262 }
263 else
264 {
265 io_error::checkFatalIOErrno( _datasourceinfo->url() );
266 if( exactformat )
267 throw carto::wrong_format_error( std::string( "Cannot write "
268 "object in format " ) + format, _datasourceinfo->url() );
269 }
270 }
271 catch( std::exception & e )
272 {
273 localMsg( "3. " + ie->second + " failed" );
274 if( exactformat )
275 throw;
276 io_error::checkFatalIOErrno( _datasourceinfo->url() );
277 carto::io_error::keepExceptionPriority( e, excp, exct, excm );
278 }
279 tried.insert( ie->second );
280 }
281 }
282 }
283
285 if( passbegin <= 4 && passend >= 4 )
286 {
287 localMsg( "Pass 4..." );
288 iext.first = extensions.begin();
289 iext.second = extensions.end();
290 for( ie=iext.first, ee=iext.second; ie!=ee; ++ie )
291 if( tried.find( ie->second ) == notyet ) {
292 writer = FormatDictionary<T>::writeFormat( ie->second );
293 if( writer )
294 {
295 try
296 {
297 localMsg( "4. try writer " + ie->second );
298 if( writer->write( obj, _datasourceinfo, options ) )
299 {
300 localMsg( "4. " + ie->second + " OK" );
301 return true;
302 }
303 else
304 {
305 io_error::checkFatalIOErrno( _datasourceinfo->url() );
306 if( exactformat )
307 throw carto::wrong_format_error( std::string( "Cannot write "
308 "object in format " ) + format, _datasourceinfo->url() );
309 }
310 }
311 catch( std::exception & e )
312 {
313 localMsg( "4. " + ie->second + " failed" );
314 if( exactformat )
315 throw;
316 io_error::checkFatalIOErrno( _datasourceinfo->url() );
317 carto::io_error::keepExceptionPriority( e, excp, exct, excm );
318 }
319 tried.insert( ie->second );
320 }
321 }
322 }
323
326 filename + " : no matching format" );
327 return false;
328 }
329
330}
331
332#undef localMsg
333#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