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

[CHANGE] Get rid of wiotools namespace, added a writeStringIntoFile function,...

[CHANGE] Get rid of wiotools namespace, added a writeStringIntoFile function, as well some unittests
parent 949862c6
......@@ -44,11 +44,20 @@ ENDIF()
# Unit tests
IF( OW_COMPILE_TESTS )
CXXTEST_ADD_TESTS_FROM_LIST( "${COMMON_SRC}"
"${LIB_NAME}"
"WSegmentationFault.cpp" # can't test seg-faults ;-)
"WTransferable.cpp" # its an empty class
"WPropertyBase.cpp" # its an abstract class. Its small functionality is tested in WPropertyVariable_test.h
"WLimits.cpp" # there are only some definitions
)
CXXTEST_ADD_TESTS_FROM_LIST( "${COMMON_SRC}"
"${LIB_NAME}"
"WSegmentationFault.cpp" # can't test seg-faults ;-)
"WTransferable.cpp" # its an empty class
"WPropertyBase.cpp" # its an abstract class. Its small functionality is tested in WPropertyVariable_test.h
"WLimits.cpp" # there are only some definitions
)
# Copy fixtures if existend
IF( EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/test/fixtures )
ADD_CUSTOM_TARGET( ${LIB_NAME}_CopyFixtures
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/test/fixtures ${CMAKE_BINARY_DIR}/common/fixtures/
COMMENT "Copy fixtures of ${LIB_NAME}"
)
ADD_DEPENDENCIES( ${LIB_NAME} ${LIB_NAME}_CopyFixtures )
ENDIF( EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/test/fixtures )
ENDIF( OW_COMPILE_TESTS )
......@@ -23,23 +23,65 @@
//---------------------------------------------------------------------------
#include <fstream>
#include <streambuf>
#include <string>
#include <boost/filesystem.hpp>
#include "WIOTools.h"
#include "exceptions/WFileNotFound.h"
#include "exceptions/WFileOpenFailed.h"
#include "WIOTools.h"
std::string readFileIntoString( const std::string& name )
{
return readFileIntoString( boost::filesystem::path( name ) );
}
std::string wiotools::getStringFromFile( const std::string& filename )
std::string readFileIntoString( const boost::filesystem::path& path )
{
std::string filename = path.file_string();
std::ifstream input( filename.c_str() );
if ( !input.is_open() )
if( !input.is_open() )
{
throw WFileNotFound( std::string( "The file \"" ) + filename +
std::string( "\" does not exist." ) );
throw WFileNotFound( std::string( "The file \"" ) + boost::filesystem::complete( path ).file_string() + std::string( "\" does not exist." ) );
}
std::string buf;
std::string line;
while( std::getline( input, line ) )
// preallocate space for the string.
std::string str;
input.seekg( 0, std::ios::end );
str.reserve( input.tellg() );
input.seekg( 0, std::ios::beg );
str.assign( ( std::istreambuf_iterator< char >( input ) ), std::istreambuf_iterator< char >() );
input.close();
return str;
}
void writeStringIntoFile( const std::string& name, const std::string& content )
{
writeStringIntoFile( boost::filesystem::path( name ), content );
}
void writeStringIntoFile( const boost::filesystem::path& path, const std::string& content )
{
std::ofstream outfile( path.file_string().c_str() );
if( !outfile.is_open() )
{
buf += line;
throw WFileOpenFailed( "The file \"" + boost::filesystem::complete( path ).file_string() + "\" could not be opened." );
}
return buf;
outfile << content << std::flush;
outfile.close();
}
boost::filesystem::path tempFileName()
{
// REGARDING THE COMPILER WARNING
// 1. mkstemp is only available for POSIX systems
// 2. reason: the warning generated here is due to a race condition
// while tmpnam invents the fileName it may be created by another process
// 3. file names like "/tmp/pansen" or "C:\pansen" are platform dependent
return boost::filesystem::path( std::string( std::tmpnam( NULL ) ) );
}
......@@ -25,114 +25,139 @@
#ifndef WIOTOOLS_H
#define WIOTOOLS_H
#include <stdint.h>
// #include <stdint.h>
#include <cstdio>
#include <algorithm>
#include <cassert>
// #include <cstdio>
#include <string>
#include <boost/filesystem.hpp>
#include "WExportCommon.h"
#include "WAssert.h"
/**
* Namespaces for several tools we may need while doing IO
* Checks if you are on a big endian machine or not.
*/
namespace wiotools
inline bool isBigEndian()
{
/**
* Checks if you are on a big endian machine or not.
*/
inline bool isBigEndian()
union
{
union
{
uint32_t i;
char c[4];
} some = {0x01020305}; // NOLINT assigning an 32 bit unsigned integer
uint32_t i;
char c[4];
} some = {0x01020305}; // NOLINT assigning an 32 bit unsigned integer
return some.c[0] == 1;
}
return some.c[0] == 1;
}
/**
* Transforms a value of type T into the opposite byte order.
*
* \param value The value where byte swapping should be applied to
*/
template< class T > T switchByteOrder( const T value )
/**
* Transforms a value of type T into the opposite byte order.
*
* \param value The value where byte swapping should be applied to
*/
template< class T > T switchByteOrder( const T value )
{
size_t numBytes = sizeof( T );
T result = value;
if( numBytes == 1 )
{
size_t numBytes = sizeof( T );
T result = value;
if( numBytes == 1 )
{
return result;
}
assert( numBytes % 2 == 0 && numBytes > 0 );
char *s = reinterpret_cast< char* >( &result );
for( size_t i = 0; i < numBytes / 2; ++i )
{
std::swap( s[i], s[ ( numBytes - 1 ) - i ] );
}
return result;
}
/**
* Transform a whole array of elements (of type T and size of sizeof(T))
* into opposite byte order.
*
* \param array Array containing the data
* \param arraySize The number of elements which is not the number of
* bytes but e.g. the number of floats
*/
template< class T > void switchByteOrderOfArray( T *array, const size_t arraySize )
WAssert( numBytes % 2 == 0 && numBytes > 0, "odd number of bytes whilte switching byte order" );
char *s = reinterpret_cast< char* >( &result );
for( size_t i = 0; i < numBytes / 2; ++i )
{
for( size_t i = 0; i < arraySize; ++i )
{
array[i] = switchByteOrder< T >( array[i] );
}
std::swap( s[i], s[ ( numBytes - 1 ) - i ] );
}
return result;
}
/**
* \param name File name to get the extension or suffix from.
* \return filename suffix
*/
inline std::string getSuffix( std::string name )
/**
* Transform a whole array of elements (of type T and size of sizeof(T))
* into opposite byte order.
*
* \param array Array containing the data
* \param arraySize The number of elements which is not the number of
* bytes but e.g. the number of floats
*/
template< class T > void switchByteOrderOfArray( T *array, const size_t arraySize )
{
for( size_t i = 0; i < arraySize; ++i )
{
return boost::filesystem::path( name ).extension();
array[i] = switchByteOrder< T >( array[i] );
}
}
/**
* Checks if a given path already exists or not
*
* \param path Path to be checked on existence
*/
inline bool fileExists( std::string path )
{
return boost::filesystem::exists( boost::filesystem::path( path ) );
}
/**
* \param name File name to get the extension or suffix from.
* \return filename suffix
*/
inline std::string getSuffix( std::string name )
{
return boost::filesystem::path( name ).extension();
}
/**
* Generate a file name with full path for a temp file. Watch out on all
* platforms!
*/
inline std::string tempFileName()
{
// REGARDING THE COMPILER WARNING
// 1. mkstemp is only available for POSIX systems
// 2. reason: the warning generated here is due to a race condition
// while tmpnam invents the fileName it may be created by another process
// 3. file names like "/tmp/pansen" or "C:\pansen" are platform dependent
return std::string( std::tmpnam( NULL ) );
}
/**
* Checks if a given path already exists or not
*
* \param name Path to be checked on existence
*/
inline bool fileExists( const std::string& name )
{
return boost::filesystem::exists( boost::filesystem::path( name ) );
}
/**
* Generate a file name with full path for a temp file.
* \return The file name.
*/
boost::filesystem::path tempFileName();
/**
* Get the contens of a file as a string.
*
* \param path Filename of the file to read.
*
* \throw WFileNotFound If file cannot be opened for reading
*
* \note The string is copied, which may result in performance issues when files are getting big.
*
* \return The file content in as string.
*/
std::string OWCOMMON_EXPORT readFileIntoString( const boost::filesystem::path& path );
/**
* Get the contens of a file as a string.
* \param filename
* \return the file content in as string.
*/
std::string OWCOMMON_EXPORT getStringFromFile( const std::string& filename );
/**
* Get the contens of a file as a string.
*
* \param name Filename of the file to read.
*
* \throw WFileNotFound If file cannot be opened for reading
*
* \note The string is copied, which may result in performance issues when files are getting big.
*
* \return The file content in as string.
*/
std::string OWCOMMON_EXPORT readFileIntoString( const std::string& name );
/**
* Writes the contens of a string to the given path.
*
* \param path The path of the file where all is written to
* \param content Payload written into that file
*
* \throw WFileOpenFailed If file cannot be opened for writing
*/
void OWCOMMON_EXPORT writeStringIntoFile( const boost::filesystem::path& path, const std::string& content );
/**
* Writes the contens of a string to the given path.
*
* \param name The path of the file where all is written to
* \param content Payload written into that file
*
* \throw WFileOpenFailed If file cannot be opened for writing
*/
void OWCOMMON_EXPORT writeStringIntoFile( const std::string& name, const std::string& content );
} // end of namespace
#endif // WIOTOOLS_H
......@@ -26,17 +26,16 @@
#define WPREFERENCES_H
#include <string>
#include <iostream>
#include <fstream>
#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>
#include "WExportCommon.h"
#include "WIOTools.h"
#include "WProperties.h"
#include "WLogger.h"
#include "WProperties.h"
#include "WExportCommon.h"
/**
* Fetches and caches preferences set in file.
*/
......@@ -94,26 +93,24 @@ template< typename T > bool WPreferences::getPreference( std::string prefName, T
configurationDescription.add_options()
( prefName.c_str(), po::value< T >() );
std::string cfgFileName = m_preferenceFile.file_string();
boost::program_options::variables_map configuration;
if( wiotools::fileExists( cfgFileName ) )
if( boost::filesystem::exists( m_preferenceFile ) )
{
std::ifstream ifs( cfgFileName.c_str(), std::ifstream::in );
try
{
// since overloaded function "const char*" dont work in boost 1.42.0
std::ifstream ifs( m_preferenceFile.file_string().c_str(), std::ifstream::in );
po::store( po::parse_config_file( ifs, configurationDescription, true ), configuration );
}
catch( const po::error &e )
{
std::cerr << "Error in configuration file \"" << cfgFileName << "\": " << e.what() << std::endl;
wlog::error( "WPreferences" ) << "Invalid configuration file \"" << m_preferenceFile.file_string() << "\": " << e.what();
return false;
}
}
else
{
wlog::info( "Preferences" ) << "No Config file: " << cfgFileName << " found";
wlog::info( "WPreferences" ) << "No Config file: " << m_preferenceFile.file_string() << " found";
}
po::notify( configuration );
......
......@@ -25,12 +25,15 @@
#ifndef WIOTOOLS_TEST_H
#define WIOTOOLS_TEST_H
#include <string>
#include <fstream>
#include <cxxtest/TestSuite.h>
#include "../WIOTools.h"
/**
* Unit test helper functions in the wiotools namespace
* Unit test WIOTools functions.
*/
class WIOToolsTest : public CxxTest::TestSuite
{
......@@ -43,9 +46,9 @@ public:
{
uint32_t x = 1;
TS_ASSERT_EQUALS( x, 1 );
x = wiotools::switchByteOrder( x );
x = switchByteOrder( x );
TS_ASSERT_EQUALS( x, 16777216 );
x = wiotools::switchByteOrder( x );
x = switchByteOrder( x );
TS_ASSERT_EQUALS( x, 1 );
}
......@@ -56,9 +59,9 @@ public:
{
double x = 3.141592653589793238462643383279502884197169399375105820974;
double original = x;
x = wiotools::switchByteOrder( x );
x = switchByteOrder( x );
TS_ASSERT_DIFFERS( x, original );
x = wiotools::switchByteOrder( x );
x = switchByteOrder( x );
TS_ASSERT_EQUALS( x, original );
}
......@@ -68,7 +71,7 @@ public:
void testByteOrderSwitchingOnSingleBytes( void )
{
char x = 1;
TS_ASSERT_EQUALS( wiotools::switchByteOrder( x ), x );
TS_ASSERT_EQUALS( switchByteOrder( x ), x );
}
/**
......@@ -78,10 +81,38 @@ public:
void testByteOrderSwitchOnArray( void )
{
uint32_t x[] = { 1, 16777216 };
wiotools::switchByteOrderOfArray( x, 2 );
switchByteOrderOfArray( x, 2 );
TS_ASSERT_EQUALS( x[0], 16777216 );
TS_ASSERT_EQUALS( x[1], 1 );
}
/**
* Test reading a text file in a string.
*/
void testReadFileIntoString( void )
{
std::string expected = "Hello Pansen!\r\n";
std::string actual = readFileIntoString( boost::filesystem::path( "fixtures/hello.world" ) );
TS_ASSERT_EQUALS( expected, actual );
}
/**
* Writes a text file, and afterwards checks if its the same, by reading it.
*/
void testWriteStringIntoFile( void )
{
std::string content = "Hello Pansen!\r\n";
boost::filesystem::path fpath = tempFileName();
writeStringIntoFile( fpath, content );
std::ifstream input( fpath.file_string().c_str() );
std::string actual;
actual.assign( ( std::istreambuf_iterator< char >( input ) ), std::istreambuf_iterator< char >() );
input.close();
TS_ASSERT_EQUALS( content, actual );
TS_ASSERT( boost::filesystem::exists( fpath ) );
boost::filesystem::remove( fpath );
}
};
#endif // WIOTOOLS_TEST_H
......@@ -41,7 +41,7 @@ std::string WPagerEEG::getFileName() const
WPagerEEG::WPagerEEG( std::string fileName )
: m_fileName( fileName )
{
if( !wiotools::fileExists( m_fileName ) )
if( !fileExists( m_fileName ) )
{
throw WDHNoSuchFile( m_fileName + " doesn't exist" );
}
......
......@@ -36,7 +36,7 @@ WReader::WReader( std::string fname ) throw( WDHNoSuchFile )
void WReader::setFileName( std::string fname ) throw( WDHNoSuchFile )
{
m_fname = fname;
if( !wiotools::fileExists( m_fname ) )
if( !fileExists( m_fname ) )
{
throw WDHNoSuchFile( m_fname );
}
......
......@@ -119,7 +119,7 @@ void WReaderFiberVTK::readPoints()
float *pointData = new float[ 3 * numPoints ];
m_ifs->read( reinterpret_cast< char* >( pointData ), 3 * sizeof( float ) * numPoints );
wiotools::switchByteOrderOfArray( pointData, 3 * numPoints ); // all 4 bytes of each float are in wrong order we need to reorder them
switchByteOrderOfArray( pointData, 3 * numPoints ); // all 4 bytes of each float are in wrong order we need to reorder them
m_points = boost::shared_ptr< std::vector< float > >( new std::vector< float >( pointData, pointData + 3 * numPoints ) );
......@@ -149,7 +149,7 @@ void WReaderFiberVTK::readLines()
uint32_t *lineData = new uint32_t[ linesSize ];
m_ifs->read( reinterpret_cast<char*>( lineData ), linesSize * sizeof( uint32_t ) );
wiotools::switchByteOrderOfArray( lineData, linesSize );
switchByteOrderOfArray( lineData, linesSize );
m_fiberStartIndices = boost::shared_ptr< std::vector< size_t > >( new std::vector< size_t > );
m_fiberLengths = boost::shared_ptr< std::vector< size_t > >( new std::vector< size_t > );
......
......@@ -123,7 +123,7 @@ void WReaderMatrixSymVTK::readTable( boost::shared_ptr< std::vector< double > >
}
// all 4 bytes of each float are in wrong order we need to reorder them
wiotools::switchByteOrderOfArray( data, numDistances );
switchByteOrderOfArray( data, numDistances );
for( size_t i = 0; i < numDistances; ++i )
{
......
......@@ -337,7 +337,6 @@ boost::shared_ptr< WDataSet > WReaderNIfTI::load( DataSetType dataSetType )
wlog::debug( "WReaderNIfTI" ) << "Load as WDataSetRawHARDI";
std::string gradientFileName = m_fname;
using wiotools::getSuffix;
std::string suffix = getSuffix( m_fname );
if( suffix == ".gz" )
......
......@@ -24,6 +24,8 @@
#include <string>
#include <boost/filesystem.hpp>
#include "../../common/WIOTools.h"
#include "../exceptions/WDHIOFailure.h"
#include "WWriter.h"
......@@ -37,7 +39,7 @@ WWriter::WWriter( std::string fname, bool overwrite )
void WWriter::setFileName( std::string fname )
{
m_fname = fname;
if( !m_overwrite && wiotools::fileExists( m_fname ) )
if( !m_overwrite && boost::filesystem::exists( boost::filesystem::path( m_fname ) ) )
{
throw WDHIOFailure( std::string( "File '" + m_fname + "' already exists, skip writing" ) );
}
......
......@@ -86,8 +86,8 @@ void WWriterFiberVTK::writeFibs( boost::shared_ptr< const WDataSetFiberVector >
WAssert( pntPosOffset < ( ( numPoints * 3 ) + 1 ), "pOff < #pts" );
}
}
wiotools::switchByteOrderOfArray< float >( rawPointData, numPoints * 3 );
wiotools::switchByteOrderOfArray< unsigned int >( rawLineData, numLines + numPoints );
switchByteOrderOfArray< float >( rawPointData, numPoints * 3 );
switchByteOrderOfArray< unsigned int >( rawLineData, numLines + numPoints );
out.write( reinterpret_cast< char* >( rawPointData ), sizeof( float ) * numPoints * 3 );
out << lineDelimiter;
out << "LINES " << numLines << " " << numPoints + numLines << lineDelimiter;
......
......@@ -60,7 +60,7 @@ void WWriterMatrixSymVTK::writeTable( const std::vector< double > &table, size_t
}
data[ numDistances - 1 ] = static_cast< float >( dim );
wiotools::switchByteOrderOfArray< float >( data, numDistances );
switchByteOrderOfArray< float >( data, numDistances );
out.write( reinterpret_cast< char* >( data ), sizeof( float ) * numDistances );
out << std::endl;
out.close();
......
......@@ -727,14 +727,14 @@ void WMainWindow::openAboutQtDialog()
void WMainWindow::openAboutDialog()
{
std::string filename( WPathHelper::getAppPath().file_string() + "/../share/OpenWalnut/OpenWalnutAbout.html" );
std::string content = wiotools::getStringFromFile( filename );
std::string content = readFileIntoString( filename );
QMessageBox::about( this, "About OpenWalnut", content.c_str() );
}
void WMainWindow::openOpenWalnutHelpDialog()
{
std::string filename( WPathHelper::getAppPath().file_string() + "/../share/OpenWalnut/OpenWalnutHelp.html" );
std::string content = wiotools::getStringFromFile( filename );
std::string content = readFileIntoString( filename );
QMessageBox::information( this, "OpenWalnut Help", content.c_str() );
}
......
......@@ -53,7 +53,7 @@ void WModuleLoader::load( WSharedAssociativeContainer< std::set< boost::shared_p
i != boost::filesystem::directory_iterator(); ++i )
{
// all modules need to begin with this
std::string suffix = wiotools::getSuffix( i->leaf() );
std::string suffix = getSuffix( i->leaf() );
std::string stem = i->path().stem();
#ifdef _MSC_VER
......
......@@ -256,7 +256,6 @@ void WMData::moduleMain()
m_moduleState.setResetable( true, true );
m_moduleState.add( m_propCondition );
using wiotools::getSuffix;
std::string fileName = m_fileName.string();
debugLog() << "Loading data from \"" << fileName << "\".";
......
......@@ -189,7 +189,7 @@ void WMDetTractClustering::update()