ome-files  0.5.0
FormatHandler.h
1 /*
2  * #%L
3  * OME-FILES C++ library for image IO.
4  * Copyright © 2006 - 2015 Open Microscopy Environment:
5  * - Massachusetts Institute of Technology
6  * - National Institutes of Health
7  * - University of Dundee
8  * - Board of Regents of the University of Wisconsin-Madison
9  * - Glencoe Software, Inc.
10  * %%
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions are met:
13  *
14  * 1. Redistributions of source code must retain the above copyright notice,
15  * this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright notice,
17  * this list of conditions and the following disclaimer in the documentation
18  * and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  *
32  * The views and conclusions contained in the software and documentation are
33  * those of the authors and should not be interpreted as representing official
34  * policies, either expressed or implied, of any organization.
35  * #L%
36  */
37 
38 #ifndef OME_FILES_FORMATHANDLER_H
39 #define OME_FILES_FORMATHANDLER_H
40 
41 #include <algorithm>
42 #include <iterator>
43 #include <stdexcept>
44 #include <string>
45 #include <vector>
46 
47 #include <boost/filesystem/path.hpp>
48 #include <boost/format.hpp>
49 #include <boost/optional.hpp>
50 #include <boost/version.hpp>
51 
52 namespace ome
53 {
54  namespace files
55  {
56 
64  {
65  protected:
68  {}
69 
71  FormatHandler (const FormatHandler&) = delete;
72 
74  operator= (const FormatHandler&) = delete;
76 
77  public:
79  virtual
81  {}
82 
97  virtual
98  bool
99  isThisType(const boost::filesystem::path& name,
100  bool open = true) const = 0;
101 
107  virtual
108  const std::string&
109  getFormat() const = 0;
110 
116  virtual
117  const std::string&
118  getFormatDescription() const = 0;
119 
125  virtual
126  const std::vector<boost::filesystem::path>&
127  getSuffixes() const = 0;
128 
134  virtual
135  const std::vector<boost::filesystem::path>&
136  getCompressionSuffixes() const = 0;
137 
146  virtual void
147  setId(const boost::filesystem::path& id) = 0;
148 
168  virtual
169  void
170  close(bool fileOnly = false) = 0;
171 
172  // -- Utility methods --
173 
182  static bool
183  checkSuffix(const boost::filesystem::path& name,
184  const boost::filesystem::path& suffix)
185  {
186  bool match = true;
187 
188  boost::filesystem::path filename(name);
189 #if !defined(BOOST_VERSION) || BOOST_VERSION >= 105000 // Boost >= 1.50
190  boost::filesystem::path ext;
191  ext.replace_extension(suffix); // Adds leading dot if missing
192 #else // Boost < 1.50
193  // replace_extension doesn't work nicely with older Boost versions.
194  boost::filesystem::path ext(suffix);
195  std::string suffixString(ext.string());
196  if (!suffixString.empty() && suffixString[0] != '.')
197  ext = boost::filesystem::path(std::string(".") + suffixString);
198 #endif // Boost version
199 
200  while(true)
201  {
202  boost::filesystem::path filename_ext = filename.extension();
203  boost::filesystem::path current_ext = ext.extension();
204  filename.replace_extension();
205  ext.replace_extension();
206 
207  if (filename_ext.empty() && current_ext.empty())
208  break; // End of matches
209  else if (!filename_ext.empty() && !current_ext.empty() &&
210  filename_ext == current_ext) // Match OK
211  continue;
212 
213  // Unbalanced or unequal extensions.
214  match = false;
215  break;
216  }
217 
218  return match;
219  }
220 
229  static bool
230  checkSuffix(const boost::filesystem::path& name,
231  const std::vector<boost::filesystem::path>& suffixes)
232  {
233  for (const auto& suffix : suffixes)
234  {
235  if (checkSuffix(name, suffix))
236  return true;
237  }
238 
239  return false;
240  }
241 
251  static bool
252  checkSuffix(const boost::filesystem::path& name,
253  const std::vector<boost::filesystem::path>& suffixes,
254  const std::vector<boost::filesystem::path>& compression_suffixes)
255  {
256  if (checkSuffix(name, suffixes))
257  return true;
258 
259  for (const auto& suffix : suffixes)
260  {
261  for (const auto& compsuffix : compression_suffixes)
262  {
263  boost::filesystem::path fullsuffix(suffix);
264  fullsuffix += boost::filesystem::path(".");
265  fullsuffix += compsuffix;
266 
267  if (checkSuffix(name, fullsuffix))
268  return true;
269  }
270  }
271  return false;
272  }
273 
285  static void
286  assertId(const boost::optional<boost::filesystem::path>& id,
287  bool notNull = true)
288  {
289  if (!id && notNull)
290  {
291  throw std::logic_error("Current file should not be null; call setId() first");
292  }
293  else if (id && !notNull)
294  {
295  boost::format fmt("Current file should be null, but is '%1%'; call close() first");
296  fmt % id.get();
297  throw std::logic_error(fmt.str());
298  }
299  }
300  };
301 
302 
303  }
304 }
305 
306 #endif // OME_FILES_FORMATHANDLER_H
307 
308 /*
309  * Local Variables:
310  * mode:C++
311  * End:
312  */
313 
virtual bool isThisType(const boost::filesystem::path &name, bool open=true) const =0
Check if the given file is a valid instance of this file format.
static bool checkSuffix(const boost::filesystem::path &name, const std::vector< boost::filesystem::path > &suffixes, const std::vector< boost::filesystem::path > &compression_suffixes)
Perform suffix matching for the given filename.
Definition: FormatHandler.h:252
virtual void setId(const boost::filesystem::path &id)=0
Set the current file name.
Open Microscopy Environment C++.
virtual void close(bool fileOnly=false)=0
Close the currently open file.
FormatHandler()
Constructor.
Definition: FormatHandler.h:67
virtual const std::vector< boost::filesystem::path > & getCompressionSuffixes() const =0
Get the default compression suffixes for this file format.
static bool checkSuffix(const boost::filesystem::path &name, const std::vector< boost::filesystem::path > &suffixes)
Perform suffix matching for the given filename.
Definition: FormatHandler.h:230
virtual ~FormatHandler()
Destructor.
Definition: FormatHandler.h:80
virtual const std::string & getFormatDescription() const =0
Get the description of this file format.
static void assertId(const boost::optional< boost::filesystem::path > &id, bool notNull=true)
Assert that the current file is valid.
Definition: FormatHandler.h:286
static bool checkSuffix(const boost::filesystem::path &name, const boost::filesystem::path &suffix)
Perform suffix matching for the given filename.
Definition: FormatHandler.h:183
virtual const std::vector< boost::filesystem::path > & getSuffixes() const =0
Get the default file suffixes for this file format.
Interface for all biological file format readers and writers.
Definition: FormatHandler.h:63
virtual const std::string & getFormat() const =0
Get the name of this file format.