Commit f36c59de authored by Mathias Goldau's avatar Mathias Goldau
Browse files

[ADD] Now the WLoader checks for file existence

parent f9a7c705
......@@ -22,6 +22,7 @@
//
//---------------------------------------------------------------------------
#include <iostream>
#include <string>
#include <vector>
......@@ -63,6 +64,13 @@ void WDataHandler::loadDataSets( std::vector< std::string > fileNames )
WLoaderManager lm;
for ( size_t i = 0 ; i < fileNames.size() ; ++i)
{
lm.load( fileNames[i], shared_from_this() );
try
{
lm.load( fileNames[i], shared_from_this() );
}
catch( WDHException e )
{
std::cerr << "Error :: DataHandler :: " << e.what() << std::endl;
}
}
}
......@@ -24,10 +24,18 @@
#include <string>
#include <boost/filesystem.hpp>
#include "WLoader.h"
#include "exceptions/WDHIOFailure.h"
WLoader::WLoader( std::string fileName )
WLoader::WLoader( std::string fileName ) throw( WDHIOFailure )
: m_fileName( fileName )
{
boost::filesystem::path p( m_fileName );
if( !boost::filesystem::exists( p ) )
{
throw WDHIOFailure( "file '" + m_fileName + "' doesn't exists." );
}
}
......@@ -27,6 +27,8 @@
#include <string>
#include "exceptions/WDHIOFailure.h"
/**
* Base class to all WLoaders which imports data from a given file and generate
* a WDataSet out of it. The WLoader subclasses will also have to determine
......@@ -36,7 +38,7 @@
class WLoader
{
public:
explicit WLoader( std::string fileName );
explicit WLoader( std::string fileName ) throw( WDHIOFailure );
virtual ~WLoader()
{
......
......@@ -24,10 +24,12 @@
#include <iostream>
#include <string>
#include <boost/thread.hpp>
#include <boost/filesystem.hpp>
#include "WLoaderManager.h"
#include "exceptions/WDHException.h"
#include "io/WLoaderNIfTI.h"
#include "io/WLoaderBiosig.h"
#include "io/WLoaderEEGASCII.h"
......@@ -39,7 +41,7 @@ std::string getSuffix( std::string name )
return p.extension();
}
void WLoaderManager::load( std::string fileName, boost::shared_ptr< WDataHandler > dataHandler )
void WLoaderManager::load( std::string fileName, boost::shared_ptr< WDataHandler > dataHandler ) throw( WDHException )
{
std::string suffix = getSuffix( fileName );
......@@ -79,8 +81,7 @@ void WLoaderManager::load( std::string fileName, boost::shared_ptr< WDataHandler
}
else
{
std::cout << "Unknown file type: \"" << suffix << "\"" << std::endl;
assert( 0 );
throw WDHException( "Unknown file type: '" + suffix + "'" );
}
}
......
......@@ -26,8 +26,11 @@
#define WLOADERMANAGER_H
#include <string>
#include <boost/shared_ptr.hpp>
#include "exceptions/WDHException.h"
class WDataHandler;
/**
......@@ -40,7 +43,7 @@ public:
/**
* Selects correct loader for fileName and creates loader thread.
*/
void load( std::string fileName, boost::shared_ptr< WDataHandler > dataHandler );
void load( std::string fileName, boost::shared_ptr< WDataHandler > dataHandler ) throw( WDHException );
protected:
private:
};
......
......@@ -38,43 +38,55 @@ WLoaderVTK::WLoaderVTK( std::string fname, boost::shared_ptr< WDataHandler > dat
{
}
void WLoaderVTK::operator()()
WLoaderVTK::~WLoaderVTK() throw()
{
readHeader();
if( !datasetTypeIs( "POLYDATA" ) )
{
throw WDHException( "Loading VTK files with DATASET != POLYDATA not implemented" );
}
if( !isBinary() )
{
throw WDHException( "Loading VTK files in ASCII format is not yet supported" );
}
}
void WLoaderVTK::readHeader() throw( WDHIOFailure )
void WLoaderVTK::operator()() throw()
{
std::ifstream in( m_fileName.c_str(), std::ifstream::in | std::ifstream::binary );
if( !in || in.bad() )
try
{
if( !in || in.bad() )
{
throw WDHIOFailure( "Load broken file '" + m_fileName + "'" );
}
readHeader( &in );
if( !datasetTypeIs( "POLYDATA" ) )
{
throw WDHException( "Invalid VTK DATASET type: DATASET != POLYDATA not implemented" );
}
if( !isBinary() )
{
throw WDHException( "VTK files in ASCII format is not yet supported" );
}
readPoints( &in );
}
catch( WDHException e )
{
throw WDHIOFailure( "Invalid file or filename: " + m_fileName );
in.close();
std::cerr << "Error :: DataHandler :: Abort loading VTK file due to: " << e.what() << std::endl;
}
in.close();
}
void WLoaderVTK::readHeader( std::ifstream* ifs ) throw( WDHIOFailure )
{
std::string line;
try
{
for( int i = 0; i < 4; ++i ) // strip first four lines
{
std::getline( in, line );
std::getline( *ifs, line );
m_header.push_back( line );
}
}
catch( std::ios_base::failure e )
{
throw WDHIOFailure( "Error while reading first four lines of " + m_fileName + ": " + e.what() );
throw WDHIOFailure( "Reading first 4 lines of '" + m_fileName + "': " + e.what() );
}
assert( m_header.size() == 4 );
in.close();
}
bool WLoaderVTK::datasetTypeIs( const std::string& type ) const
......@@ -90,5 +102,13 @@ bool WLoaderVTK::isBinary() const
{
assert( m_header.size() == 4 );
std::string thirdLine = string_utils::toUpper( string_utils::trim( m_header[2] ) );
if( thirdLine != "BINARY" )
{
assert( thirdLine == "ASCII" );
}
return "BINARY" == thirdLine;
}
void WLoaderVTK::readPoints( std::ifstream* ifs )
{
}
......@@ -25,6 +25,7 @@
#ifndef WLOADERVTK_H
#define WLOADERVTK_H
#include <fstream>
#include <string>
#include <vector>
#include <boost/shared_ptr.hpp>
......@@ -35,7 +36,11 @@
class WDataHandler;
/**
* Loader for the VTK file formats. For VTK just see http://www.vtk.org
* Loader for the VTK file formats. For VTK just see http://www.vtk.org.
* Currently only a subset of the legacy format is supported: MedInria's
* Fib-VTK format. The byte order of the files is assumed to be big endian by
* default.
*
* \ingroup dataHandler
*/
class WLoaderVTK : public WLoader
......@@ -45,19 +50,27 @@ public:
/**
* Constructs and makes a new VTK loader for separate thread start.
*/
WLoaderVTK( std::string fname, boost::shared_ptr< WDataHandler > dataHandler );
WLoaderVTK( std::string fname, boost::shared_ptr< WDataHandler >
dataHandler );
/**
* Destroys this instance and closes the file.
*/
virtual ~WLoaderVTK() throw();
/**
* This function is automatically called when creating a new thread for the
* loader with boost::thread. It calls the methods of the NIfTI I/O library.
*/
virtual void operator()();
virtual void operator()() throw();
protected:
/**
* Read header from file.
*
* \return The offset where header ends, so we may skip this next operation.
*/
void readHeader() throw( WDHIOFailure );
void readHeader( std::ifstream* ifs ) throw( WDHIOFailure );
/**
* Checks if the header defines the specified VTK DATASET type.
......@@ -67,10 +80,15 @@ protected:
bool datasetTypeIs( const std::string& type ) const;
/**
* Returns true if the VTK file is in BINARY format, otherwise false.
* Returns true if the VTK file is marked as BINARY format, otherwise false.
*/
bool isBinary() const;
/**
* Read points from file while starting at the given position.
*/
void readPoints( std::ifstream* ifs );
/**
* First four lines of ASCII text describing this file
*/
......
......@@ -25,15 +25,41 @@
#ifndef WLOADERVTK_TEST_H
#define WLOADERVTK_TEST_H
#include <sstream>
#include <string>
#include <vector>
#include <boost/filesystem.hpp>
#include <cxxtest/TestSuite.h>
#include <cxxtest/ValueTraits.h>
#include "../WLoaderVTK.h"
#include "../../WDataHandler.h"
// New value trait for std::streampos
#ifdef CXXTEST_RUNNING
namespace CxxTest
{
CXXTEST_TEMPLATE_INSTANTIATION
class ValueTraits< std::streampos >
{
char _s[256];
public: // NOLINT
explicit ValueTraits( const std::streampos &pos )
{
std::stringstream ss;
ss << pos;
snprintf( _s, ss.str().size(), "%s", ss.str().c_str() );
}
const char *asString() const
{
return _s;
}
};
}
#endif // CXXTEST_RUNNING
/**
* Unit tests the WLoaderVTK class.
*/
......@@ -68,7 +94,9 @@ public:
void testReadHeader( void )
{
WLoaderVTK loader( m_vtkFile.string(), m_dataHandler );
loader.readHeader();
std::ifstream ifs( m_vtkFile.string().c_str(), std::ifstream::in | std::ifstream::binary );
loader.readHeader( &ifs );
ifs.close();
std::vector< std::string > expected;
expected.push_back( "# vtk DataFile Version 3.0" );
expected.push_back( "vtk output" );
......@@ -78,15 +106,16 @@ public:
}
/**
* If the path is not valid there should be thrown an exception
* After reading the header the position in the stream should have
* changed
*/
void testReadHeaderOnInvalidFile( void )
void testReadHeaderReturnsCorrectStreamPosistion( void )
{
WLoaderVTK loader( "no/such/file", m_dataHandler );
TS_ASSERT_THROWS_EQUALS( loader.readHeader(),
const WDHIOFailure &e,
e.what(),
std::string( "Invalid file or filename: no/such/file" ) );
WLoaderVTK loader( m_vtkFile.string(), m_dataHandler );
std::ifstream ifs( m_vtkFile.string().c_str(), std::ifstream::in | std::ifstream::binary );
loader.readHeader( &ifs );
TS_ASSERT_EQUALS( ifs.tellg(), 70 );
ifs.close();
}
/**
......@@ -96,7 +125,9 @@ public:
void testCheckDatasetType( void )
{
WLoaderVTK loader( m_vtkFile.string(), m_dataHandler );
loader.readHeader();
std::ifstream ifs( m_vtkFile.string().c_str(), std::ifstream::in | std::ifstream::binary );
loader.readHeader( &ifs );
ifs.close();
TS_ASSERT_EQUALS( loader.datasetTypeIs( "STRUCTURED_POINTS" ), true );
}
......@@ -106,7 +137,9 @@ public:
void testBinaryOrAscii( void )
{
WLoaderVTK loader( m_vtkFile.string(), m_dataHandler );
loader.readHeader();
std::ifstream ifs( m_vtkFile.string().c_str(), std::ifstream::in | std::ifstream::binary );
loader.readHeader( &ifs );
ifs.close();
TS_ASSERT_EQUALS( loader.isBinary(), false );
}
......
......@@ -25,21 +25,44 @@
#ifndef WLOADER_TEST_H
#define WLOADER_TEST_H
#include <string>
#include <cxxtest/TestSuite.h>
#include "../WLoader.h"
/**
* TODO(math): Document this!
* Just a dummy for testing the base class
*/
class DummyLoader : public WLoader
{
public:
explicit DummyLoader( std::string fileName )
: WLoader( fileName )
{
}
virtual void operator()()
{
}
};
/**
* Unit tests the Loader base class.
*/
class WLoaderTest : public CxxTest::TestSuite
{
public:
/**
* TODO(math): Document this!
* If the given file name is invalid an exception should be thrown.
*/
void testSomething( void )
void testExceptionOnInvalidFilename( void )
{
TS_ASSERT_THROWS_EQUALS( DummyLoader( "no such file" ),
const WDHIOFailure &e,
e.what(),
std::string( "file 'no such file' doesn't exists." ) );
TS_ASSERT_THROWS_NOTHING( DummyLoader( "fixtures/scalar_float.nii.gz" ) );
}
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment