diff --git a/modules/io/src/CMakeLists.txt b/modules/io/src/CMakeLists.txt
index 3dafdc92e9fd34452d32d5aab64fb751ce8f2eab..e77cfda20a98d8b856113f12c0b50deb470a2e92 100644
--- a/modules/io/src/CMakeLists.txt
+++ b/modules/io/src/CMakeLists.txt
@@ -9,6 +9,7 @@ binary_data_source.hh
module_config.hh
container_serialization.hh
swap_util.hh
+io_utils.hh
io_exception.hh
convert.hh
converting_streams.hh
@@ -17,6 +18,7 @@ converting_streams.hh
set(OST_IO_SOURCES
io_manager.cc
convert.cc
+io_utils.cc
)
@@ -47,7 +49,6 @@ foreach(fname ${OST_IO_SEQ_HEADERS})
endforeach(fname ${OST_IO_SEQ_HEADERS})
-
set(OST_IO_DEPENDENCIES base;conop;seq)
if (ENABLE_IMG)
set(OST_IO_DEPENDENCIES ${OST_IO_DEPENDENCIES};img;img_alg)
@@ -55,8 +56,8 @@ endif()
module(NAME io SOURCES "${OST_IO_SOURCES}"
HEADERS ${OST_IO_MOL_HEADERS} IN_DIR mol
${OST_IO_IMG_HEADERS} IN_DIR img
- ${OST_IO_SEQ_HEADERS} IN_DIR seq
- ${OST_IO_HEADERS}
+ ${OST_IO_SEQ_HEADERS} IN_DIR seq
+ ${OST_IO_HEADERS}
DEPENDS_ON ${OST_IO_DEPENDENCIES})
if (NOT WIN32)
# see note in modules/gui/src/CMakeLists.txt
diff --git a/modules/io/src/img/map_io_dat_handler.cc b/modules/io/src/img/map_io_dat_handler.cc
index dc375df8e78db14eac7e3297589200898a5e996c..e9642373c020854ba18f8a0a3e4e9d508a14d527 100644
--- a/modules/io/src/img/map_io_dat_handler.cc
+++ b/modules/io/src/img/map_io_dat_handler.cc
@@ -74,9 +74,9 @@ bool MapIODatHandler::MatchType(const ImageFormatBase& type)
return false;
}
-bool MapIODatHandler::MatchSuffix(const String& suffix)
+bool MapIODatHandler::MatchSuffix(const boost::filesystem::path& loc)
{
- if(suffix==".dat" || suffix==".img") {
+ if(detail::FilenameEndsWith(loc.string(),".dat") || detail::FilenameEndsWith(loc.string(),".img") ) {
return true;
}
return false;
diff --git a/modules/io/src/img/map_io_dat_handler.hh b/modules/io/src/img/map_io_dat_handler.hh
index f501d0b2ee8e5b1112a6504fe22f7b857b3bdc6a..e6964f819fa4096b42b7f9851eb65d1b27e1790b 100644
--- a/modules/io/src/img/map_io_dat_handler.hh
+++ b/modules/io/src/img/map_io_dat_handler.hh
@@ -60,7 +60,7 @@ class DLLEXPORT_OST_IO MapIODatHandler: public MapIOHandler
virtual void Export(const img::MapHandle& sh, std::ostream& loc,const ImageFormatBase& formatstruct) const;
static bool MatchContent(unsigned char* header);
static bool MatchType(const ImageFormatBase& type);
- static bool MatchSuffix(const String& suffix);
+ static bool MatchSuffix(const boost::filesystem::path& loc);
static String GetFormatName() { return String("Dat"); }
static String GetFormatDescription() {return String("Simple binary format for square images");}
};
diff --git a/modules/io/src/img/map_io_dm3_handler.cc b/modules/io/src/img/map_io_dm3_handler.cc
index 4c0816a3831f13b3b596dc325943e47228274d97..2ff70625db3c6f6a5f4a480635850b9ea79d2409 100644
--- a/modules/io/src/img/map_io_dm3_handler.cc
+++ b/modules/io/src/img/map_io_dm3_handler.cc
@@ -636,9 +636,9 @@ bool MapIODm3Handler::MatchType(const ImageFormatBase& type)
}
return false;
}
-bool MapIODm3Handler::MatchSuffix(const String& suffix)
+bool MapIODm3Handler::MatchSuffix(const boost::filesystem::path& loc)
{
- if(suffix==".dm3") {
+ if(detail::FilenameEndsWith(loc.string(),".dm3") ) {
return true;
}
return false;
diff --git a/modules/io/src/img/map_io_dm3_handler.hh b/modules/io/src/img/map_io_dm3_handler.hh
index b1c5e09fc295ec4578857621d11750fe5292e9a5..c09832a5a7110bd2d17e8e0343d07e8bc8513eb0 100644
--- a/modules/io/src/img/map_io_dm3_handler.hh
+++ b/modules/io/src/img/map_io_dm3_handler.hh
@@ -48,7 +48,7 @@ class DLLEXPORT_OST_IO MapIODm3Handler: public MapIOHandler
virtual void Export(const img::MapHandle& sh, std::ostream& loc,const ImageFormatBase& formatstruct) const;
static bool MatchContent(unsigned char* header);
static bool MatchType(const ImageFormatBase& type);
- static bool MatchSuffix(const String& suffix);
+ static bool MatchSuffix(const boost::filesystem::path& loc);
static String GetFormatName() { return String("Dm3"); }
static String GetFormatDescription() {return String("Format used by Gatan Inc.'s Digital Micrograph software");}
diff --git a/modules/io/src/img/map_io_dx_handler.cc b/modules/io/src/img/map_io_dx_handler.cc
index 4d5b50c4832e66bdb96b69b957a96dd81a7a0a4b..7c564eaaba5ab132fcefcfb9432949e146d25538 100644
--- a/modules/io/src/img/map_io_dx_handler.cc
+++ b/modules/io/src/img/map_io_dx_handler.cc
@@ -264,9 +264,9 @@ bool MapIODxHandler::MatchType(const ImageFormatBase& formatstruct)
}
return false;
}
-bool MapIODxHandler::MatchSuffix(const String& suffix)
+bool MapIODxHandler::MatchSuffix(const boost::filesystem::path& loc)
{
- if(suffix==".dx") {
+ if(detail::FilenameEndsWith(loc.string(),".dx") ) {
return true;
}
return false;
diff --git a/modules/io/src/img/map_io_dx_handler.hh b/modules/io/src/img/map_io_dx_handler.hh
index f0933aa1cfb1a183121d6b710216600a1db04777..f54c6ca86abb9511d20398a3156add794c9f16e5 100644
--- a/modules/io/src/img/map_io_dx_handler.hh
+++ b/modules/io/src/img/map_io_dx_handler.hh
@@ -62,7 +62,7 @@ class DLLEXPORT_OST_IO MapIODxHandler: public MapIOHandler
std::ostream& loc, const ImageFormatBase& formatstruct) const;
static bool MatchContent(unsigned char* header);
static bool MatchType(const ImageFormatBase& type);
- static bool MatchSuffix(const String& suffix);
+ static bool MatchSuffix(const boost::filesystem::path& locx);
static String GetFormatName() { return String("Dx"); };
static String GetFormatDescription() { return String("Format used by the OpenDX software package"); };
diff --git a/modules/io/src/img/map_io_handler.hh b/modules/io/src/img/map_io_handler.hh
index 295492b4d696790d0a5563a87a1a2e2f881bae6f..3be88313a5f2df7b3ebe1e5b984c45352fb46fa0 100644
--- a/modules/io/src/img/map_io_handler.hh
+++ b/modules/io/src/img/map_io_handler.hh
@@ -26,6 +26,7 @@
#include <ost/img/map.hh>
#include <ost/img/alg/normalizer.hh>
#include <ost/io/img/image_format.hh>
+#include <ost/io/io_utils.hh>
namespace ost { namespace io {
@@ -45,7 +46,7 @@ public:
virtual ~MapIOHandlerFactoryBase() {}
virtual bool MatchContent(unsigned char* header) const = 0;
virtual bool MatchType(const ImageFormatBase& type) const = 0;
- virtual bool MatchSuffix(const String& suffix) const =0 ;
+ virtual bool MatchSuffix(const boost::filesystem::path& loc) const =0 ;
virtual MapIOHandlerPtr Create() const = 0 ;
virtual String GetFormatName() const =0;
virtual String GetFormatDescription() const =0;
@@ -66,8 +67,8 @@ class MapIOHandlerFactory: public MapIOHandlerFactoryBase
return HANDLER::MatchType(type);
}
- virtual bool MatchSuffix(const String& suffix) const {
- return HANDLER::MatchSuffix(suffix);
+ virtual bool MatchSuffix(const boost::filesystem::path& loc) const {
+ return HANDLER::MatchSuffix(loc);
}
virtual String GetFormatName() const {
diff --git a/modules/io/src/img/map_io_jpk_handler.cc b/modules/io/src/img/map_io_jpk_handler.cc
index 5122ab3c346bcc315236f6be4c4e119490f9fb1b..f941c37dfeb9f0f2ad2c53a3689b7e96904c3a33 100644
--- a/modules/io/src/img/map_io_jpk_handler.cc
+++ b/modules/io/src/img/map_io_jpk_handler.cc
@@ -300,9 +300,9 @@ bool MapIOJpkHandler::MatchType(const ImageFormatBase& formatstruct)
return false;
}
-bool MapIOJpkHandler::MatchSuffix(const String& suffix)
+bool MapIOJpkHandler::MatchSuffix(const boost::filesystem::path& loc)
{
- if(suffix==".jpk") {
+ if(detail::FilenameEndsWith(loc.string(),".jpk") ) {
return true;
}
return false;
diff --git a/modules/io/src/img/map_io_jpk_handler.hh b/modules/io/src/img/map_io_jpk_handler.hh
index 1191924a4a05c7b68456c85c7ad66d38d4f757be..074c632deadc7ba2dea32ff7eb3b0e00d9d17e92 100644
--- a/modules/io/src/img/map_io_jpk_handler.hh
+++ b/modules/io/src/img/map_io_jpk_handler.hh
@@ -48,7 +48,7 @@ class DLLEXPORT_OST_IO MapIOJpkHandler: public MapIOTiffHandler
void Export(const img::MapHandle& image, std::ostream& loc,const ImageFormatBase& formatstruct) const;
static bool MatchContent(unsigned char* header);
static bool MatchType(const ImageFormatBase& type);
- static bool MatchSuffix(const String& suffix);
+ static bool MatchSuffix(const boost::filesystem::path& loc);
static String GetFormatName() { return String("Jpk");}
static String GetFormatDescription() { return String("Format used by JPK Instruments AG's software (Customized Tiff format)"); }
diff --git a/modules/io/src/img/map_io_mrc_handler.cc b/modules/io/src/img/map_io_mrc_handler.cc
index 7590eefb74954be5a8c4fdef2f0488394f1f75af..80ee6025057a01b494dfd086fd18cfc9273539c5 100644
--- a/modules/io/src/img/map_io_mrc_handler.cc
+++ b/modules/io/src/img/map_io_mrc_handler.cc
@@ -57,10 +57,16 @@ u v w x . . . d*c*b*a b c d 3
#include <cstdio>
#include <iostream>
#include <sstream>
+#include <streambuf>
#include <boost/scoped_array.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/filesystem/fstream.hpp>
+#include <boost/iostreams/filtering_stream.hpp>
+#include <boost/iostreams/device/array.hpp>
+#include <boost/iostreams/device/file.hpp>
+#include <boost/iostreams/filtering_streambuf.hpp>
+#include <boost/iostreams/filter/gzip.hpp>
#include <boost/format.hpp>
#include <ost/base.hh>
@@ -76,6 +82,7 @@ u v w x . . . d*c*b*a b c d 3
#include <ost/io/img/image_format.hh>
#include <ost/io/swap_util.hh>
#include <ost/io/converting_streams.hh>
+#include <ost/io/io_utils.hh>
#include "map_io_mrc_handler.hh"
@@ -132,6 +139,67 @@ CCP4::CCP4(bool normalize_on_save, Endianess endianess_on_save):
namespace detail{
+class ptristream : public std::istream
+{
+ class ptrinbuf : public std::streambuf
+ {
+ protected:
+ char * ptr;
+ std::size_t len;
+
+ public:
+ ptrinbuf(char * _ptr, std::size_t _len) : ptr(_ptr), len(_len) {
+ assert(ptr);
+ if (*ptr && len == 0)
+ len = std::strlen(ptr);
+
+ setg(ptr, // beginning of putback area
+ ptr, // read position
+ ptr+len); // end position
+ }
+
+ protected:
+ virtual int_type underflow() {
+ // is read position before end of buffer?
+ if (gptr() < egptr())
+ return traits_type::to_int_type(*gptr());
+ else
+ return EOF;
+ }
+
+ virtual pos_type seekoff(off_type off, ios_base::seekdir way,
+ ios_base::openmode mode =
+ ios_base::in | ios_base::out)
+ {
+ switch (way) {
+ case std::ios::cur:
+ setg(ptr, gptr()+off, ptr+len);
+ break;
+ case std::ios::beg:
+ setg(ptr, ptr+off, ptr+len);
+ break;
+ case std::ios::end:
+ setg(ptr, egptr()+off, ptr+len);
+ break;
+
+ default:
+ assert(false);
+ break;
+ }
+ return pos_type(gptr() - ptr);
+ }
+ };
+
+protected:
+ ptrinbuf buf;
+public:
+ ptristream(char * ptr, std::size_t len = 0)
+ : std::istream(0), buf(ptr, len) {
+ rdbuf(&buf);
+ }
+};
+
+
class header_base {
public:
header_base():
@@ -331,8 +399,9 @@ BinaryOStream<CONVERSIONTYPE>& operator<< (BinaryOStream<CONVERSIONTYPE>& out, c
template<int CONVERSIONTYPE>
BinaryIStream<CONVERSIONTYPE>& operator>> (BinaryIStream<CONVERSIONTYPE>& in, mrc_header& h)
{
+ char dummy[116];
h.ReadCommonData(in);
- in.seekg(116,std::ios::cur);
+ in.read(dummy,116);
in >> h.xorigin >> h.yorigin;
h.ReadLabel(in);
@@ -342,7 +411,9 @@ BinaryIStream<CONVERSIONTYPE>& operator>> (BinaryIStream<CONVERSIONTYPE>& in, mr
// skip symm info, seek to start of actual data
if(h.nsymbt>0){
- in.seekg(h.nsymbt,std::ios::cur);
+ for (int counter=0;counter<h.nsymbt;++counter){
+ in.read(dummy,1);
+ }
}
return in;
}
@@ -382,39 +453,39 @@ public:
arms = 0.1;
}
-static int DetermineDataFormat( std::istream& f)
-{
- char machst[4];
- // from the ccp4 documentation
- // The machine stamp is a 32-bit quantity containing a set of four `nibbles'
- // (half-bytes)---only half the space is used. Each nibble is a number
- // specifying the representation of (in C terms) double (d) , float (f),
- // int (i) and unsigned char (c) types. Thus each stamp is of the form
- // 0xdfic0000. The values for the floating point nibbles may be taken from the
- // list (following HDF):
- // 1 Big-endian ieee
- // 2 VAX
- // 3 Cray
- // 4 Little-endian ieee
- // 5 Convex native
- // 6 Fijitsu VP
- f.seekg(53*4,std::ios::beg); // seek to machine stamp
- f.read(machst,4);
- f.seekg(0,std::ios::beg); // seek to beginning
- char float_machst= machst[0] & 0x0f;
- if(float_machst == 1){
- LOGN_DEBUG("CCP4Import: reading big endian data");
- return OST_BIG_ENDIAN;
- }else if(float_machst == 2){
- LOGN_DEBUG("CCP4Import: reading vax data");
- return OST_VAX_DATA;
- }else if(float_machst == 4){
- LOGN_DEBUG("CCP4Import: reading little endian data");
- return OST_LITTLE_ENDIAN;
- } else{
- throw(IOException("CCP4Import: Cray, Convex native and Fijitsu VP formats are not supported."));
+ static int DetermineDataFormat(std::istream& f)
+ {
+ char machst[4];
+ // from the ccp4 documentation
+ // The machine stamp is a 32-bit quantity containing a set of four `nibbles'
+ // (half-bytes)---only half the space is used. Each nibble is a number
+ // specifying the representation of (in C terms) double (d) , float (f),
+ // int (i) and unsigned char (c) types. Thus each stamp is of the form
+ // 0xdfic0000. The values for the floating point nibbles may be taken from the
+ // list (following HDF):
+ // 1 Big-endian ieee
+ // 2 VAX
+ // 3 Cray
+ // 4 Little-endian ieee
+ // 5 Convex native
+ // 6 Fijitsu VP
+ f.seekg(53*4,std::ios::beg); // seek to machine stamp
+ f.read(machst,4);
+ f.seekg(0,std::ios::beg); // seek to beginning
+ char float_machst= machst[0] & 0x0f;
+ if(float_machst == 1){
+ LOGN_DEBUG("CCP4Import: reading big endian data");
+ return OST_BIG_ENDIAN;
+ }else if(float_machst == 2){
+ LOGN_DEBUG("CCP4Import: reading vax data");
+ return OST_VAX_DATA;
+ }else if(float_machst == 4){
+ LOGN_DEBUG("CCP4Import: reading little endian data");
+ return OST_LITTLE_ENDIAN;
+ } else{
+ throw(IOException("CCP4Import: Cray, Convex native and Fijitsu VP formats are not supported."));
+ }
}
-}
void Print()
@@ -440,15 +511,16 @@ static int DetermineDataFormat( std::istream& f)
template <int CONVERSIONTYPE>
BinaryIStream<CONVERSIONTYPE>& operator>> (BinaryIStream<CONVERSIONTYPE>& in, ccp4_header& header)
{
+ char dummy[48];
header.ReadCommonData(in);
in >> header.lskflag;
in >> header.skwmat[0] >> header.skwmat[1] >> header.skwmat[2];
in >> header.skwmat[3] >> header.skwmat[4] >> header.skwmat[5];
in >> header.skwmat[6] >> header.skwmat[7] >> header.skwmat[8];
in >> header.skwtrn[0] >> header.skwtrn[1] >> header.skwtrn[2];
- in.seekg(48,std::ios::cur);
+ in.read(dummy,48);
in >> header.ox >> header.oy >> header.oz;
- in.seekg(8,std::ios::cur); // skip map and machst
+ in.read(dummy,8);
in >> header.arms;
header.ReadLabel(in);
@@ -457,8 +529,11 @@ BinaryIStream<CONVERSIONTYPE>& operator>> (BinaryIStream<CONVERSIONTYPE>& in, cc
if(header.nz<1) header.nz=1;
// skip symm info, seek to start of actual data
- if(header.nsymbt>0)
- in.seekg(header.nsymbt,std::ios::cur);
+ if(header.nsymbt>0) {
+ for (int counter=0;counter<header.nsymbt;++counter){
+ in.read(dummy,1);
+ }
+ }
return in;
}
template <int CONVERSIONTYPE>
@@ -693,7 +768,7 @@ void complex_dumper(BinaryOStream<CONVERSIONTYPE>& f,
}
template<class HEADER,int CONVERSIONTYPE>
-void import_helper(img::MapHandle& image, std::istream& in, const MRC& formatmrc)
+void import_helper(img::MapHandle& image, std::istream& in,const MRC& formatmrc)
{
BinaryIStream<CONVERSIONTYPE> f(in);
HEADER header;
@@ -756,9 +831,10 @@ void import_helper(img::MapHandle& image, std::istream& in, const MRC& formatmrc
template<class HEADER>
void import_endianess_switcher(img::MapHandle& image,
std::istream& f,
+ std::istream& header_str,
const MRC& formatmrc)
{
- switch(HEADER::DetermineDataFormat(f)){
+ switch(HEADER::DetermineDataFormat(header_str)){
case OST_BIG_ENDIAN:
import_helper<HEADER,OST_BIG_ENDIAN>(image,f,formatmrc);
break;
@@ -799,8 +875,7 @@ void export_endianess_switcher(const img::MapHandle& image,
std::ostream& f,
const MRC& formatmrc)
{
-
-switch(formatmrc.GetEndianessOnSave()){
+ switch(formatmrc.GetEndianessOnSave()){
case OST_BIG_ENDIAN:
export_helper<HEADER,OST_BIG_ENDIAN>(image,f,formatmrc);
break;
@@ -819,15 +894,22 @@ namespace bf = boost::filesystem;
void MapIOMrcHandler::Import(img::MapHandle& sh, const boost::filesystem::path& loc,const ImageFormatBase& formatstruct )
{
- boost::filesystem::
- ifstream infile(loc, std::ios::binary);
+ boost::filesystem::ifstream infile(loc, std::ios::binary);
if(!infile)
{
throw IOException("could not open "+loc.string());
}
+ boost::iostreams::filtering_stream<boost::iostreams::input> in;
+ if (detail::FilenameEndsWith(loc.string(),".map.gz")) {
+ in.push(boost::iostreams::gzip_decompressor());
+ }
+ in.push(boost::iostreams::file_source(loc.string()));
+ in.read(reinterpret_cast<char*>(&header_),256);
+ in.pop();
+ in.push(boost::iostreams::file_source(loc.string()));
is_file_=true;
- extension_=extension(loc);
- this->Import(sh,infile,formatstruct);
+ filename_=loc.string();
+ this->Import(sh,in,formatstruct);
infile.close();
}
@@ -840,26 +922,32 @@ void MapIOMrcHandler::Import(img::MapHandle& sh, std::istream& loc, const ImageF
} else {
assert (formatstruct.GetFormatString()==UndefinedImageFormat::FORMAT_STRING);
}
-
+ if (is_file_ == false){
+ loc.read(reinterpret_cast<char*>(&header_),256);
+ loc.seekg(0,std::ios::beg);
+ }
+ char* headerptr=(char*)&header_;
+ boost::iostreams::filtering_streambuf<boost::iostreams::input> head_strbuf;
+ std::istream head_str(&head_strbuf);
+ head_strbuf.push(boost::iostreams::basic_array_source<char>(headerptr,sizeof(header_)));
if (formatmrc.GetSubformat()==MRC_OLD_FORMAT) {
LOGN_DEBUG("mrc io: importing old style format");
- detail::import_endianess_switcher<detail::mrc_header>(sh,loc,formatmrc);
+ detail::import_endianess_switcher<detail::mrc_header>(sh,loc,head_str,formatmrc);
} else if (formatmrc.GetSubformat()==MRC_NEW_FORMAT) {
LOGN_DEBUG("mrc io: importing new style format");
- detail::import_endianess_switcher<detail::ccp4_header>(sh,loc,formatmrc);
- } else if (is_file_ && ( extension_==".ccp4" || extension_==".map")) {
+ detail::import_endianess_switcher<detail::ccp4_header>(sh,loc,head_str,formatmrc);
+ } else if (is_file_ && (detail::FilenameEndsWith(filename_,".ccp4") || detail::FilenameEndsWith(filename_,".map") || detail::FilenameEndsWith(filename_,".map.gz"))) {
LOGN_DEBUG("mrc io: importing new style format");
- detail::import_endianess_switcher<detail::ccp4_header>(sh,loc,formatmrc);
+ detail::import_endianess_switcher<detail::ccp4_header>(sh,loc,head_str,formatmrc);
} else {
- unsigned char header[256];
- loc.read(reinterpret_cast<char*>(&header),256);
- loc.seekg(0, std::ios::beg);
- if (MatchContent(header) == true) {
+ unsigned char header_content[256];
+ memcpy(&header_content,&header_,256*sizeof(char));
+ if (MatchContent(header_content) == true) {
LOGN_DEBUG("mrc io: importing new style format");
- detail::import_endianess_switcher<detail::ccp4_header>(sh,loc,formatmrc);
+ detail::import_endianess_switcher<detail::ccp4_header>(sh,loc,head_str,formatmrc);
} else {
LOGN_DEBUG("mrc io: importing old style format");
- detail::import_endianess_switcher<detail::mrc_header>(sh,loc,formatmrc);
+ detail::import_endianess_switcher<detail::mrc_header>(sh,loc,head_str,formatmrc);
}
}
}
@@ -873,7 +961,7 @@ void MapIOMrcHandler::Export(const img::MapHandle& image,
throw IOException("could not open "+loc.string());
}
is_file_=true;
- extension_=extension(loc);
+ filename_=loc.string();
Export(image,outfile,formatstruct);
outfile.close();
}
@@ -915,10 +1003,11 @@ bool MapIOMrcHandler::MatchType(const ImageFormatBase& type)
return false;
}
-bool MapIOMrcHandler::MatchSuffix(const String& suffix)
+bool MapIOMrcHandler::MatchSuffix(const boost::filesystem::path& loc)
{
- if(suffix==".mrc" || suffix==".map" || suffix==".ccp4") {
- return true;
+ if(detail::FilenameEndsWith(loc.string(),".mrc") || detail::FilenameEndsWith(loc.string(),".map") ||
+ detail::FilenameEndsWith(loc.string(),".ccp4") || detail::FilenameEndsWith(loc.string(),".map.gz")) {
+ return true;
}
return false;
}
diff --git a/modules/io/src/img/map_io_mrc_handler.hh b/modules/io/src/img/map_io_mrc_handler.hh
index d5f96b6f9e0a692a17d5d80cac30167f1ad85f2f..76a6b9d369af0321a63e3da2c72cbcfd33166e9b 100644
--- a/modules/io/src/img/map_io_mrc_handler.hh
+++ b/modules/io/src/img/map_io_mrc_handler.hh
@@ -62,7 +62,7 @@ public:
MapIOMrcHandler():
is_file_(false),
- extension_("") {}
+ filename_("") {}
/// \brief Map IO handler to read/write mrc and ccp4 map files
///
@@ -74,14 +74,15 @@ public:
virtual void Export(const img::MapHandle& sh, std::ostream& loc,const ImageFormatBase& formatstruct) const;
static bool MatchContent(unsigned char* header);
static bool MatchType(const ImageFormatBase& type);
- static bool MatchSuffix(const String& suffix);
+ static bool MatchSuffix(const boost::filesystem::path& loc);
static String GetFormatName() { return String("Mrc"); };
static String GetFormatDescription() { return String("Format used by the MRC software package"); };
private:
mutable bool is_file_;
- mutable String extension_;
+ mutable String filename_;
+ char header_[256];
};
diff --git a/modules/io/src/img/map_io_nanoscope_handler.cc b/modules/io/src/img/map_io_nanoscope_handler.cc
index 7288f703b5f5df1be7839204ce2f0b2e7ab6b6b5..32ce6ccd162fa940800ae9e13b6f99e806355c11 100644
--- a/modules/io/src/img/map_io_nanoscope_handler.cc
+++ b/modules/io/src/img/map_io_nanoscope_handler.cc
@@ -234,9 +234,9 @@ bool MapIONanoscopeHandler::MatchType(const ImageFormatBase& type)
return false;
}
-bool MapIONanoscopeHandler::MatchSuffix(const String& suffix)
+bool MapIONanoscopeHandler::MatchSuffix(const boost::filesystem::path& loc)
{
- if(suffix==".mod") {
+ if(detail::FilenameEndsWith(loc.string(),".mod") ) {
return true;
}
return false;
diff --git a/modules/io/src/img/map_io_nanoscope_handler.hh b/modules/io/src/img/map_io_nanoscope_handler.hh
index e9dda75c7de18827e318071c3d3a04a623c88ae1..6758897691f0206046a9feb7f6490806aaca6f58 100644
--- a/modules/io/src/img/map_io_nanoscope_handler.hh
+++ b/modules/io/src/img/map_io_nanoscope_handler.hh
@@ -57,7 +57,7 @@ public:
virtual void Export(const img::MapHandle& sh, std::ostream& loc,const ImageFormatBase& formatstruct) const;
static bool MatchContent(unsigned char* header);
static bool MatchType(const ImageFormatBase& type);
- static bool MatchSuffix(const String& suffix);
+ static bool MatchSuffix(const boost::filesystem::path& loc);
static String GetFormatName() { return String("Nanoscope"); }
static String GetFormatDescription() { return String("Format used by software from Veeco"); }
};
diff --git a/modules/io/src/img/map_io_png_handler.cc b/modules/io/src/img/map_io_png_handler.cc
index f11e472b3b73aa0751170492869b593dcddbb663..38d88be665497120b7cec05c148d59d0b5f0b1f9 100644
--- a/modules/io/src/img/map_io_png_handler.cc
+++ b/modules/io/src/img/map_io_png_handler.cc
@@ -311,9 +311,9 @@ bool MapIOPngHandler::MatchType(const ImageFormatBase& type)
}
return false;
}
-bool MapIOPngHandler::MatchSuffix(const String& suffix)
+bool MapIOPngHandler::MatchSuffix(const boost::filesystem::path& loc)
{
- if(suffix==".png") {
+ if(detail::FilenameEndsWith(loc.string(),".png") ) {
return true;
}
return false;
diff --git a/modules/io/src/img/map_io_png_handler.hh b/modules/io/src/img/map_io_png_handler.hh
index 0f3b5454370eb14c168f4a6348409d069cdf53f7..d5267a6da98f939827679fe49c76d07dc117b180 100644
--- a/modules/io/src/img/map_io_png_handler.hh
+++ b/modules/io/src/img/map_io_png_handler.hh
@@ -52,7 +52,7 @@ public:
virtual void Export(const img::MapHandle& sh, std::ostream& loc,const ImageFormatBase& formatstruct) const;
static bool MatchContent(unsigned char* header);
static bool MatchType(const ImageFormatBase& type);
- static bool MatchSuffix(const String& suffix);
+ static bool MatchSuffix(const boost::filesystem::path& loc);
static String GetFormatName() { return String("Png");}
static String GetFormatDescription() { return String("Portable Network Graphic image format");}
};
diff --git a/modules/io/src/img/map_io_situs_handler.cc b/modules/io/src/img/map_io_situs_handler.cc
index 33a0391fa68f9ec82e393a80fc4948dd062ac576..f31444b3004afde7a02ac6964a1919775d19fe61 100644
--- a/modules/io/src/img/map_io_situs_handler.cc
+++ b/modules/io/src/img/map_io_situs_handler.cc
@@ -272,9 +272,9 @@ bool MapIOSitusHandler::MatchType(const ImageFormatBase& type)
return false;
}
-bool MapIOSitusHandler::MatchSuffix(const String& suffix)
+bool MapIOSitusHandler::MatchSuffix(const boost::filesystem::path& loc)
{
- if(suffix==".situs" || suffix==".sit") {
+ if(detail::FilenameEndsWith(loc.string(),".situs") || detail::FilenameEndsWith(loc.string(),".sit") ) {
return true;
}
return false;
diff --git a/modules/io/src/img/map_io_situs_handler.hh b/modules/io/src/img/map_io_situs_handler.hh
index 05933c5528cf9ada58b7fdd06177091d3b9078ad..a5d64a72796f77c5d3a5df55d0acbd56fb550e2f 100644
--- a/modules/io/src/img/map_io_situs_handler.hh
+++ b/modules/io/src/img/map_io_situs_handler.hh
@@ -54,7 +54,7 @@ class DLLEXPORT_OST_IO MapIOSitusHandler: public MapIOHandler
virtual void Export(const img::MapHandle& sh, std::ostream& loc,const ImageFormatBase& formatstruct) const;
static bool MatchContent(unsigned char* header);
static bool MatchType(const ImageFormatBase& type);
- static bool MatchSuffix(const String& suffix);
+ static bool MatchSuffix(const boost::filesystem::path& loc);
static String GetFormatName() { return "Situs"; };
static String GetFormatDescription() { return "Format used by the Situs software package"; };
};
diff --git a/modules/io/src/img/map_io_spi_handler.cc b/modules/io/src/img/map_io_spi_handler.cc
index 4a2f0a18f263fa71fe81c45aa8d9ff268f0f005a..6e10c30ccd01968ebfee27f4edee2be5e7ae46f7 100644
--- a/modules/io/src/img/map_io_spi_handler.cc
+++ b/modules/io/src/img/map_io_spi_handler.cc
@@ -512,9 +512,9 @@ bool MapIOSpiHandler::MatchType(const ImageFormatBase& type)
}
return false;
}
-bool MapIOSpiHandler::MatchSuffix(const String& suffix)
+bool MapIOSpiHandler::MatchSuffix(const boost::filesystem::path& loc)
{
- if(suffix==".spi") {
+ if (detail::FilenameEndsWith(loc.string(),".spi") ) {
return true;
}
return false;
diff --git a/modules/io/src/img/map_io_spi_handler.hh b/modules/io/src/img/map_io_spi_handler.hh
index 91eccb9799aa8dac4bd267c6556202d8735e16d1..df2d6152647c66482fb33a750c1223bb72fb2e85 100644
--- a/modules/io/src/img/map_io_spi_handler.hh
+++ b/modules/io/src/img/map_io_spi_handler.hh
@@ -64,7 +64,7 @@ class DLLEXPORT_OST_IO MapIOSpiHandler: public MapIOHandler
virtual void Export(const img::MapHandle& sh, std::ostream& loc,const ImageFormatBase& formatstruct) const;
static bool MatchContent(unsigned char* header);
static bool MatchType(const ImageFormatBase& type);
- static bool MatchSuffix(const String& suffix);
+ static bool MatchSuffix(const boost::filesystem::path& loc);
static String GetFormatName() { return String("Spider"); };
static String GetFormatDescription() { return String("Format sued by the Spider software package"); };
diff --git a/modules/io/src/img/map_io_tiff_handler.cc b/modules/io/src/img/map_io_tiff_handler.cc
index 7203d99b0102e50a471c958642c2b1195ae9b678..863013dd00055a8cee87c913a9dd307df443e839 100644
--- a/modules/io/src/img/map_io_tiff_handler.cc
+++ b/modules/io/src/img/map_io_tiff_handler.cc
@@ -427,9 +427,9 @@ bool MapIOTiffHandler::MatchType(const ImageFormatBase& type)
return (type.GetFormatString()=="defined_tiff");
}
-bool MapIOTiffHandler::MatchSuffix(const String& suffix)
+bool MapIOTiffHandler::MatchSuffix(const boost::filesystem::path& loc)
{
- return (suffix==".tif" || suffix==".tiff");
+ return (detail::FilenameEndsWith(loc.string(),".tif") || detail::FilenameEndsWith(loc.string(),".tiff") );
}
diff --git a/modules/io/src/img/map_io_tiff_handler.hh b/modules/io/src/img/map_io_tiff_handler.hh
index 2ae42d7f2bf578805149a32a6c2df09b06821320..8d9a9e3a6426677d6ee4160b5635f5557c2b5d69 100644
--- a/modules/io/src/img/map_io_tiff_handler.hh
+++ b/modules/io/src/img/map_io_tiff_handler.hh
@@ -90,7 +90,7 @@ class DLLEXPORT_OST_IO MapIOTiffHandler: public MapIOHandler
virtual void Export(const img::MapHandle& sh, std::ostream& loc,const ImageFormatBase& formatstruct) const;
static bool MatchContent(unsigned char* header);
static bool MatchType(const ImageFormatBase& type);
- static bool MatchSuffix(const String& suffix);
+ static bool MatchSuffix(const boost::filesystem::path& loc);
static String GetFormatName() { return String( "Tiff"); }
static String GetFormatDescription() { return String("Tagged Image File Format"); }
diff --git a/modules/io/src/io_manager.cc b/modules/io/src/io_manager.cc
index b48b679537b4a23ce3862e873e0058cb287dce76..d64358ffa2de7f22119d3ac86727bcdce533187f 100644
--- a/modules/io/src/io_manager.cc
+++ b/modules/io/src/io_manager.cc
@@ -140,16 +140,9 @@ MapIOHandlerPtr IOManager::FindMapImportHandlerFile(const boost::filesystem::pat
}
throw IOException("Unsupported type in FindMapImportHandle.");
}else{
- String filename = loc.string();
- String::size_type pos = filename.rfind(".");
- String::size_type spos = filename.rfind("/");
- if (pos != String::npos && (spos==String::npos || spos<pos)){
- String ext=filename.substr(pos);
- std::transform(ext.begin(),ext.end(),ext.begin(),tolower);
- for(MapIOFList::const_iterator it=map_io_list_.begin(); it!=map_io_list_.end();++it) {
- if((*it)->MatchSuffix(ext)) {
- return (*it)->Create();
- }
+ for(MapIOFList::const_iterator it=map_io_list_.begin(); it!=map_io_list_.end();++it) {
+ if((*it)->MatchSuffix(loc)) {
+ return (*it)->Create();
}
}
unsigned char header[256];
@@ -167,7 +160,7 @@ MapIOHandlerPtr IOManager::FindMapImportHandlerFile(const boost::filesystem::pat
return (*it)->Create();
}
}
- throw IOException("No file suffix given for " + filename+", and could not detect automatically, please indicate file type.");
+ throw IOException("No file suffix given for " + loc.string()+", and could not detect automatically, please indicate file type.");
}
return MapIOHandlerPtr(); // removes warning
}
@@ -213,10 +206,8 @@ MapIOHandlerPtr IOManager::FindMapExportHandlerFile(const boost::filesystem::pat
if (pos == String::npos){
throw IOException("No file suffix given for " + filename+", please indicate file type.");
}
- String ext=filename.substr(pos);
- std::transform(ext.begin(),ext.end(),ext.begin(),tolower);
for(MapIOFList::const_iterator it=map_io_list_.begin(); it!=map_io_list_.end();++it) {
- if((*it)->MatchSuffix(ext)) {
+ if((*it)->MatchSuffix(loc)) {
return(*it)->Create();
}
}
diff --git a/modules/io/src/io_manager.hh b/modules/io/src/io_manager.hh
index a320f01ce5eef4d042b69cf40c1e9d07dbd2558d..cccc375750843de94ea13615d508a5bccbf496e2 100644
--- a/modules/io/src/io_manager.hh
+++ b/modules/io/src/io_manager.hh
@@ -145,6 +145,8 @@ private:
#endif
};
+
+
}}
#endif
diff --git a/modules/io/src/io_utils.cc b/modules/io/src/io_utils.cc
new file mode 100644
index 0000000000000000000000000000000000000000..905c5545cf72d3ec7d22bb3411f5337b383986ba
--- /dev/null
+++ b/modules/io/src/io_utils.cc
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2003-2010 by the IPLT authors
+// Copyright (C) 2008-2010 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+//------------------------------------------------------------------------------
+
+#include <algorithm>
+#include "io_utils.hh"
+
+namespace ost { namespace io { namespace detail {
+
+bool FilenameEndsWith(const String& target,const String& probe) {
+ return std::mismatch( probe.rbegin(), probe.rend(), target.rbegin() ).first == probe.rend();
+}
+
+}}}
diff --git a/modules/io/src/io_utils.hh b/modules/io/src/io_utils.hh
new file mode 100644
index 0000000000000000000000000000000000000000..677b3024a84625dce480ded7bb125d47f8823edd
--- /dev/null
+++ b/modules/io/src/io_utils.hh
@@ -0,0 +1,31 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2003-2010 by the IPLT authors
+// Copyright (C) 2008-2010 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+//------------------------------------------------------------------------------
+#ifndef OST_IO_UTIL_HH
+#define OST_IO_UTIL_HH
+
+#include <ost/base.hh>
+
+namespace ost { namespace io { namespace detail {
+
+bool FilenameEndsWith(const String& target,const String& probe);
+
+}}} // ns
+
+#endif // OST_IO_UTIL_HH
diff --git a/modules/io/src/mol/entity_io_crd_handler.cc b/modules/io/src/mol/entity_io_crd_handler.cc
index 7ff0dc0f282677e0aede5d7ebaac41cb175dc7e1..5d730787a8fdf42ec722f0601c229126adc3471c 100644
--- a/modules/io/src/mol/entity_io_crd_handler.cc
+++ b/modules/io/src/mol/entity_io_crd_handler.cc
@@ -181,8 +181,7 @@ namespace {
bool crd_handler_is_responsible_for(const boost::filesystem::path& loc,
const String& type) {
if(type=="auto") {
- String ext=extension(loc);
- if(boost::iequals(ext,".crd") || boost::iequals(ext, ".crd.gz")) {
+ if( detail::FilenameEndsWith(loc.string(),".crd") || detail::FilenameEndsWith(loc.string(),".crd.gz") ) {
return true;
}
} else if(type=="crd") {
diff --git a/modules/io/src/mol/entity_io_handler.hh b/modules/io/src/mol/entity_io_handler.hh
index 8885a1d91ee752cd57a888701d94d97a73ff2136..c1a64703d47d9637c2d675f9bf666606c2627a6e 100644
--- a/modules/io/src/mol/entity_io_handler.hh
+++ b/modules/io/src/mol/entity_io_handler.hh
@@ -24,6 +24,7 @@
#include <ost/io/module_config.hh>
+#include <ost/io/io_utils.hh>
#include <ost/mol/mol.hh>
namespace ost { namespace io {
diff --git a/modules/io/src/mol/entity_io_pdb_handler.cc b/modules/io/src/mol/entity_io_pdb_handler.cc
index d3dceb0ff601296f9115110cfea3e93020eeb62c..8ec58b26c76d892aa2fc73231f1b460035269b67 100644
--- a/modules/io/src/mol/entity_io_pdb_handler.cc
+++ b/modules/io/src/mol/entity_io_pdb_handler.cc
@@ -76,9 +76,8 @@ namespace {
bool pdb_handler_is_responsible_for(const boost::filesystem::path& loc,
const String& type) {
if(type=="auto") {
- String ext=extension(loc);
- if(boost::iequals(ext,".pdb") || boost::iequals(ext, ".ent")||
- boost::iequals(ext, ".gz") || boost::iequals(ext, ".pqr")) {
+ if(detail::FilenameEndsWith(loc.string(),".pdb") || detail::FilenameEndsWith(loc.string(),".ent") ||
+ detail::FilenameEndsWith(loc.string(),".pdb.gz") || detail::FilenameEndsWith(loc.string(),".par") ){
return true;
}
diff --git a/modules/io/src/mol/entity_io_sdf_handler.cc b/modules/io/src/mol/entity_io_sdf_handler.cc
index d3d0bda1d2db993ae0e44721d4c66b132998cd71..49b699024f066320d57381c87e551c0c0043ecc0 100644
--- a/modules/io/src/mol/entity_io_sdf_handler.cc
+++ b/modules/io/src/mol/entity_io_sdf_handler.cc
@@ -409,8 +409,7 @@ namespace {
bool sdf_handler_is_responsible_for(const boost::filesystem::path& loc,
const String& type) {
if(type=="auto") {
- String ext=extension(loc);
- if(boost::iequals(ext,".sdf")) {
+ if(detail::FilenameEndsWith(loc.string(),".sdf")) {
return true;
}
diff --git a/modules/io/src/seq/clustal_io_handler.cc b/modules/io/src/seq/clustal_io_handler.cc
index 9c56a05fa9644ea0ea393f2ad64b65bbc2209d3f..3456befad32648b5551ed4ec41a31bbefeea4554 100644
--- a/modules/io/src/seq/clustal_io_handler.cc
+++ b/modules/io/src/seq/clustal_io_handler.cc
@@ -51,8 +51,7 @@ void ClustalIOHandler::Export(const seq::ConstSequenceList& msa,
bool ClustalIOHandler::ProvidesImport(const boost::filesystem::path& loc,
const String& format) {
if (format=="auto") {
- String ext=extension(loc);
- if (boost::iequals(ext,".aln")) {
+ if (detail::FilenameEndsWith(loc.string(),".aln")) {
return true;
}
} else if(format=="clustal") {
diff --git a/modules/io/src/seq/fasta_io_handler.cc b/modules/io/src/seq/fasta_io_handler.cc
index 5bb0e9797d22336a782d1e1db473444e68c95142..af2b2db50e9d39da1f1b02b175c8f49e025dfaf4 100644
--- a/modules/io/src/seq/fasta_io_handler.cc
+++ b/modules/io/src/seq/fasta_io_handler.cc
@@ -56,11 +56,12 @@ void FastaIOHandler::Export(const seq::ConstSequenceList& msa,
bool FastaIOHandler::ProvidesImport(const boost::filesystem::path& loc,
const String& format) {
if (format=="auto") {
- String ext=extension(loc);
- if (boost::iequals(ext,".fasta") || boost::iequals(ext, ".fa") ||
- boost::iequals(ext, ".fna") || boost::iequals(ext, ".fsa") ||
- boost::iequals(ext, ".fas")) {
- return true;
+
+
+ if (detail::FilenameEndsWith(loc.string(),".fasta") || detail::FilenameEndsWith(loc.string(),".fa") ||
+ detail::FilenameEndsWith(loc.string(),".fnaa") || detail::FilenameEndsWith(loc.string(),".fsa") ||
+ detail::FilenameEndsWith(loc.string(),".fas") ) {
+ return true;
}
} else if(format=="fasta") {
return true;
diff --git a/modules/io/src/seq/promod_io_handler.cc b/modules/io/src/seq/promod_io_handler.cc
index 8851d885efcfee90e471332aa46507e3d243f4db..518c6b34eb8e4eed2e75a89bb5cfb36022dc4e52 100644
--- a/modules/io/src/seq/promod_io_handler.cc
+++ b/modules/io/src/seq/promod_io_handler.cc
@@ -52,8 +52,7 @@ void PromodIOHandler::Export(const seq::ConstSequenceList& msa,
bool PromodIOHandler::ProvidesImport(const boost::filesystem::path& loc,
const String& format) {
if (format=="auto") {
- String ext=extension(loc);
- if (boost::iequals(ext,".ali")) {
+ if (detail::FilenameEndsWith(loc.string(),".ali")) {
return true;
}
} else if(format=="promod") {
diff --git a/modules/io/src/seq/sequence_io_handler.hh b/modules/io/src/seq/sequence_io_handler.hh
index 84249c4fc3a8cd3b3362afb522db9ae7002bd444..cc918478ae4d034c30ac46be7e4d1f9b51c9304d 100644
--- a/modules/io/src/seq/sequence_io_handler.hh
+++ b/modules/io/src/seq/sequence_io_handler.hh
@@ -25,6 +25,7 @@
#include <ost/io/module_config.hh>
#include <ost/seq/sequence_list.hh>
+#include <ost/io/io_utils.hh>
namespace ost { namespace io {