diff --git a/Core/Code/IO/mitkIOUtil.cpp b/Core/Code/IO/mitkIOUtil.cpp index 961cda4c69..392351cb45 100644 --- a/Core/Code/IO/mitkIOUtil.cpp +++ b/Core/Code/IO/mitkIOUtil.cpp @@ -1,755 +1,763 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkIOUtil.h" #include "mitkDataNodeFactory.h" #include "mitkImageWriter.h" #include "mitkPointSetWriter.h" #include "mitkSurfaceVtkWriter.h" #include #include #include #include #include #include #include //ITK #include //VTK #include #include #include #include #include static std::string GetLastErrorStr() { #ifdef US_PLATFORM_POSIX return std::string(strerror(errno)); #else // Retrieve the system error message for the last-error code LPVOID lpMsgBuf; DWORD dw = GetLastError(); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); std::string errMsg((LPCTSTR)lpMsgBuf); LocalFree(lpMsgBuf); return errMsg; #endif } #ifdef US_PLATFORM_WINDOWS #include #include // make the posix flags point to the obsolte bsd types on windows #define S_IRUSR S_IREAD #define S_IWUSR S_IWRITE #else #include #include #include #endif #include #include static const char validLetters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; // A cross-platform version of the mkstemps function static int mkstemps_compat(char* tmpl, int suffixlen) { static unsigned long long value = 0; int savedErrno = errno; // Lower bound on the number of temporary files to attempt to generate. #define ATTEMPTS_MIN (62 * 62 * 62) /* The number of times to attempt to generate a temporary file. To conform to POSIX, this must be no smaller than TMP_MAX. */ #if ATTEMPTS_MIN < TMP_MAX const unsigned int attempts = TMP_MAX; #else const unsigned int attempts = ATTEMPTS_MIN; #endif const int len = strlen(tmpl); if ((len - suffixlen) < 6 || strncmp(&tmpl[len - 6 - suffixlen], "XXXXXX", 6)) { errno = EINVAL; return -1; } /* This is where the Xs start. */ char* XXXXXX = &tmpl[len - 6 - suffixlen]; /* Get some more or less random data. */ #ifdef US_PLATFORM_WINDOWS { SYSTEMTIME stNow; FILETIME ftNow; // get system time GetSystemTime(&stNow); stNow.wMilliseconds = 500; if (!SystemTimeToFileTime(&stNow, &ftNow)) { errno = -1; return -1; } unsigned long long randomTimeBits = ((static_cast(ftNow.dwHighDateTime) << 32) | static_cast(ftNow.dwLowDateTime)); value = randomTimeBits ^ static_cast(GetCurrentThreadId()); } #else { struct timeval tv; gettimeofday(&tv, NULL); unsigned long long randomTimeBits = ((static_cast(tv.tv_usec) << 32) | static_cast(tv.tv_sec)); value = randomTimeBits ^ static_cast(getpid()); } #endif for (unsigned int count = 0; count < attempts; value += 7777, ++count) { unsigned long long v = value; /* Fill in the random bits. */ XXXXXX[0] = validLetters[v % 62]; v /= 62; XXXXXX[1] = validLetters[v % 62]; v /= 62; XXXXXX[2] = validLetters[v % 62]; v /= 62; XXXXXX[3] = validLetters[v % 62]; v /= 62; XXXXXX[4] = validLetters[v % 62]; v /= 62; XXXXXX[5] = validLetters[v % 62]; int fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); if (fd >= 0) { errno = savedErrno; return fd; } else if (errno != EEXIST) { return -1; } } /* We got out of the loop because we ran out of combinations to try. */ errno = EEXIST; return -1; } // A cross-platform version of the POSIX mkdtemp function static char* mkdtemps_compat(char* tmpl, int suffixlen) { static unsigned long long value = 0; int savedErrno = errno; // Lower bound on the number of temporary dirs to attempt to generate. #define ATTEMPTS_MIN (62 * 62 * 62) /* The number of times to attempt to generate a temporary dir. To conform to POSIX, this must be no smaller than TMP_MAX. */ #if ATTEMPTS_MIN < TMP_MAX const unsigned int attempts = TMP_MAX; #else const unsigned int attempts = ATTEMPTS_MIN; #endif const int len = strlen(tmpl); if ((len - suffixlen) < 6 || strncmp(&tmpl[len - 6 - suffixlen], "XXXXXX", 6)) { errno = EINVAL; return NULL; } /* This is where the Xs start. */ char* XXXXXX = &tmpl[len - 6 - suffixlen]; /* Get some more or less random data. */ #ifdef US_PLATFORM_WINDOWS { SYSTEMTIME stNow; FILETIME ftNow; // get system time GetSystemTime(&stNow); stNow.wMilliseconds = 500; if (!SystemTimeToFileTime(&stNow, &ftNow)) { errno = -1; return NULL; } unsigned long long randomTimeBits = ((static_cast(ftNow.dwHighDateTime) << 32) | static_cast(ftNow.dwLowDateTime)); value = randomTimeBits ^ static_cast(GetCurrentThreadId()); } #else { struct timeval tv; gettimeofday(&tv, NULL); unsigned long long randomTimeBits = ((static_cast(tv.tv_usec) << 32) | static_cast(tv.tv_sec)); value = randomTimeBits ^ static_cast(getpid()); } #endif unsigned int count = 0; for (; count < attempts; value += 7777, ++count) { unsigned long long v = value; /* Fill in the random bits. */ XXXXXX[0] = validLetters[v % 62]; v /= 62; XXXXXX[1] = validLetters[v % 62]; v /= 62; XXXXXX[2] = validLetters[v % 62]; v /= 62; XXXXXX[3] = validLetters[v % 62]; v /= 62; XXXXXX[4] = validLetters[v % 62]; v /= 62; XXXXXX[5] = validLetters[v % 62]; #ifdef US_PLATFORM_WINDOWS int fd = _mkdir (tmpl); //, _S_IREAD | _S_IWRITE | _S_IEXEC); #else int fd = mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR); #endif if (fd >= 0) { errno = savedErrno; return tmpl; } else if (errno != EEXIST) { return NULL; } } /* We got out of the loop because we ran out of combinations to try. */ errno = EEXIST; return NULL; } //#endif namespace mitk { const std::string IOUtil::DEFAULTIMAGEEXTENSION = ".nrrd"; const std::string IOUtil::DEFAULTSURFACEEXTENSION = ".stl"; const std::string IOUtil::DEFAULTPOINTSETEXTENSION = ".mps"; #ifdef US_PLATFORM_WINDOWS std::string IOUtil::GetProgramPath() { char path[512]; std::size_t index = std::string(path, GetModuleFileName(NULL, path, 512)).find_last_of('\\'); return std::string(path, index); } #elif defined(US_PLATFORM_APPLE) #include std::string IOUtil::GetProgramPath() { char path[512]; uint32_t size = sizeof(path); if (_NSGetExecutablePath(path, &size) == 0) { std::size_t index = std::string(path).find_last_of('/'); std::string strPath = std::string(path, index); //const char* execPath = strPath.c_str(); //mitk::StandardFileLocations::GetInstance()->AddDirectoryForSearch(execPath,false); return strPath; } return std::string(); } #else #include #include #include std::string IOUtil::GetProgramPath() { std::stringstream ss; ss << "/proc/" << getpid() << "/exe"; char proc[512] = {0}; ssize_t ch = readlink(ss.str().c_str(), proc, 512); if (ch == -1) return std::string(); std::size_t index = std::string(proc).find_last_of('/'); return std::string(proc, index); } #endif std::string IOUtil::GetTempPath() { static std::string result; if (result.empty()) { #ifdef US_PLATFORM_WINDOWS char tempPathTestBuffer[1]; DWORD bufferLength = ::GetTempPath(1, tempPathTestBuffer); if (bufferLength == 0) { mitkThrow() << GetLastErrorStr(); } std::vector tempPath(bufferLength); bufferLength = ::GetTempPath(bufferLength, &tempPath[0]); if (bufferLength == 0) { mitkThrow() << GetLastErrorStr(); } result.assign(tempPath.begin(), tempPath.begin() + static_cast(bufferLength)); #else result = "/tmp/"; #endif } return result; } +std::string IOUtil::CreateTemporaryFile(const std::string& templateName, std::string path) +{ + ofstream tmpOutputStream; + std::string returnValue = CreateTemporaryFile(tmpOutputStream,templateName,path); + tmpOutputStream.close(); + return returnValue; +} + std::string IOUtil::CreateTemporaryFile(std::ofstream& f, const std::string& templateName, std::string path) { return CreateTemporaryFile(f, std::ios_base::out | std::ios_base::trunc, templateName, path); } std::string IOUtil::CreateTemporaryFile(std::ofstream& f, std::ios_base::openmode mode, const std::string& templateName, std::string path) { if (path.empty()) { path = GetTempPath(); } path += "/" + templateName; std::vector dst_path(path.begin(), path.end()); dst_path.push_back('\0'); std::size_t lastX = path.find_last_of('X'); std::size_t firstX = path.find_last_not_of('X', lastX); int firstNonX = firstX == std::string::npos ? - 1 : firstX - 1; while (lastX != std::string::npos && (lastX - firstNonX) < 6) { lastX = path.find_last_of('X', firstX); firstX = path.find_last_not_of('X', lastX); firstNonX = firstX == std::string::npos ? - 1 : firstX - 1; } std::size_t suffixlen = lastX == std::string::npos ? path.size() : path.size() - lastX - 1; int fd = mkstemps_compat(&dst_path[0], suffixlen); if(fd != -1) { path.assign(dst_path.begin(), dst_path.end() - 1); f.open(path.c_str(), mode | std::ios_base::out | std::ios_base::trunc); close(fd); } else { mitkThrow() << "Creating temporary file " << &dst_path[0] << " failed: " << GetLastErrorStr(); } return path; } std::string IOUtil::CreateTemporaryDirectory(const std::string& templateName, std::string path) { if (path.empty()) { path = GetTempPath(); } path += "/" + templateName; std::vector dst_path(path.begin(), path.end()); dst_path.push_back('\0'); std::size_t lastX = path.find_last_of('X'); std::size_t firstX = path.find_last_not_of('X', lastX); int firstNonX = firstX == std::string::npos ? - 1 : firstX - 1; while (lastX != std::string::npos && (lastX - firstNonX) < 6) { lastX = path.find_last_of('X', firstX); firstX = path.find_last_not_of('X', lastX); firstNonX = firstX == std::string::npos ? - 1 : firstX - 1; } std::size_t suffixlen = lastX == std::string::npos ? path.size() : path.size() - lastX - 1; if(mkdtemps_compat(&dst_path[0], suffixlen) == NULL) { mitkThrow() << "Creating temporary directory " << &dst_path[0] << " failed: " << GetLastErrorStr(); } path.assign(dst_path.begin(), dst_path.end() - 1); return path; } int IOUtil::LoadFiles(const std::vector &fileNames, DataStorage &ds) { // Get the set of registered mitk::IDataNodeReader services us::ModuleContext* context = us::GetModuleContext(); const std::vector > refs = context->GetServiceReferences(); std::vector services; services.reserve(refs.size()); for (std::vector >::const_iterator i = refs.begin(); i != refs.end(); ++i) { IDataNodeReader* s = context->GetService(*i); if (s != 0) { services.push_back(s); } } mitk::ProgressBar::GetInstance()->AddStepsToDo(2*fileNames.size()); // Iterate over all file names and use the IDataNodeReader services // to load them. int nodesRead = 0; for (std::vector::const_iterator i = fileNames.begin(); i != fileNames.end(); ++i) { for (std::vector::const_iterator readerIt = services.begin(); readerIt != services.end(); ++readerIt) { try { int n = (*readerIt)->Read(*i, ds); nodesRead += n; if (n > 0) break; } catch (const std::exception& e) { MITK_WARN << e.what(); } } mitk::ProgressBar::GetInstance()->Progress(2); } for (std::vector >::const_iterator i = refs.begin(); i != refs.end(); ++i) { context->UngetService(*i); } return nodesRead; } DataStorage::Pointer IOUtil::LoadFiles(const std::vector& fileNames) { mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New(); LoadFiles(fileNames, *ds); return ds.GetPointer(); } DataNode::Pointer IOUtil::LoadDataNode(const std::string path) { mitk::DataNodeFactory::Pointer reader = mitk::DataNodeFactory::New(); try { reader->SetFileName( path ); reader->Update(); if((reader->GetNumberOfOutputs()<1)) { MITK_ERROR << "Could not find data '" << path << "'"; mitkThrow() << "An exception occured during loading the file " << path << ". Exception says could not find data."; } mitk::DataNode::Pointer node = reader->GetOutput(); if(node.IsNull()) { MITK_ERROR << "Could not find path: '" << path << "'" << " datanode is NULL" ; mitkThrow() << "An exception occured during loading the file " << path << ". Exception says datanode is NULL."; } return reader->GetOutput( 0 ); } catch ( itk::ExceptionObject & e ) { MITK_ERROR << "Exception occured during load data of '" << path << "': Exception: " << e.what(); mitkThrow() << "An exception occured during loading the file " << path << ". Exception says: " << e.what(); } } Image::Pointer IOUtil::LoadImage(const std::string path) { mitk::DataNode::Pointer node = LoadDataNode(path); mitk::Image::Pointer image = dynamic_cast(node->GetData()); if(image.IsNull()) { MITK_ERROR << "Image is NULL '" << path << "'"; mitkThrow() << "An exception occured during loading the image " << path << ". Exception says: Image is NULL."; } return image; } Surface::Pointer IOUtil::LoadSurface(const std::string path) { mitk::DataNode::Pointer node = LoadDataNode(path); mitk::Surface::Pointer surface = dynamic_cast(node->GetData()); if(surface.IsNull()) { MITK_ERROR << "Surface is NULL '" << path << "'"; mitkThrow() << "An exception occured during loading the file " << path << ". Exception says: Surface is NULL."; } return surface; } PointSet::Pointer IOUtil::LoadPointSet(const std::string path) { mitk::DataNode::Pointer node = LoadDataNode(path); mitk::PointSet::Pointer pointset = dynamic_cast(node->GetData()); if(pointset.IsNull()) { MITK_ERROR << "PointSet is NULL '" << path << "'"; mitkThrow() << "An exception occured during loading the file " << path << ". Exception says: Pointset is NULL."; } return pointset; } bool IOUtil::SaveImage(mitk::Image::Pointer image, const std::string path) { std::string dir = itksys::SystemTools::GetFilenamePath( path ); std::string baseFilename = itksys::SystemTools::GetFilenameWithoutExtension( path ); std::string extension = itksys::SystemTools::GetFilenameExtension( path ); if (dir == "") dir = "."; std::string finalFileName = dir + "/" + baseFilename; mitk::ImageWriter::Pointer imageWriter = mitk::ImageWriter::New(); //check if an extension is given, else use the defaul extension if( extension == "" ) { MITK_WARN << extension << " extension is not set. Extension set to default: " << finalFileName << DEFAULTIMAGEEXTENSION; extension = DEFAULTIMAGEEXTENSION; } // check if extension is suitable for writing image data if (!imageWriter->IsExtensionValid(extension)) { MITK_WARN << extension << " extension is unknown. Extension set to default: " << finalFileName << DEFAULTIMAGEEXTENSION; extension = DEFAULTIMAGEEXTENSION; } try { //write the data imageWriter->SetInput(image); imageWriter->SetFileName(finalFileName.c_str()); imageWriter->SetExtension(extension.c_str()); imageWriter->Write(); } catch ( std::exception& e ) { MITK_ERROR << " during attempt to write '" << finalFileName + extension << "' Exception says:"; MITK_ERROR << e.what(); mitkThrow() << "An exception occured during writing the file " << finalFileName << ". Exception says " << e.what(); } return true; } bool IOUtil::SaveSurface(Surface::Pointer surface, const std::string path) { std::string dir = itksys::SystemTools::GetFilenamePath( path ); std::string baseFilename = itksys::SystemTools::GetFilenameWithoutLastExtension( path ); std::string extension = itksys::SystemTools::GetFilenameLastExtension( path ); if (dir == "") dir = "."; std::string finalFileName = dir + "/" + baseFilename; if (extension == "") // if no extension has been set we use the default extension { MITK_WARN << extension << " extension is not set. Extension set to default: " << finalFileName << DEFAULTSURFACEEXTENSION; extension = DEFAULTSURFACEEXTENSION; } try { finalFileName += extension; if(extension == ".stl" ) { mitk::SurfaceVtkWriter::Pointer surfaceWriter = mitk::SurfaceVtkWriter::New(); // check if surface actually consists of triangles; if not, the writer will not do anything; so, convert to triangles... vtkPolyData* polys = surface->GetVtkPolyData(); if( polys->GetNumberOfStrips() > 0 ) { vtkSmartPointer triangleFilter = vtkSmartPointer::New(); triangleFilter->SetInputData(polys); triangleFilter->Update(); polys = triangleFilter->GetOutput(); polys->Register(NULL); surface->SetVtkPolyData(polys); } surfaceWriter->SetInput( surface ); surfaceWriter->SetFileName( finalFileName.c_str() ); surfaceWriter->GetVtkWriter()->SetFileTypeToBinary(); surfaceWriter->Write(); } else if(extension == ".vtp") { mitk::SurfaceVtkWriter::Pointer surfaceWriter = mitk::SurfaceVtkWriter::New(); surfaceWriter->SetInput( surface ); surfaceWriter->SetFileName( finalFileName.c_str() ); surfaceWriter->GetVtkWriter()->SetDataModeToBinary(); surfaceWriter->Write(); } else if(extension == ".vtk") { mitk::SurfaceVtkWriter::Pointer surfaceWriter = mitk::SurfaceVtkWriter::New(); surfaceWriter->SetInput( surface ); surfaceWriter->SetFileName( finalFileName.c_str() ); surfaceWriter->Write(); } else { // file extension not suitable for writing specified data type MITK_ERROR << "File extension is not suitable for writing'" << finalFileName; mitkThrow() << "An exception occured during writing the file " << finalFileName << ". File extension " << extension << " is not suitable for writing."; } } catch(std::exception& e) { MITK_ERROR << " during attempt to write '" << finalFileName << "' Exception says:"; MITK_ERROR << e.what(); mitkThrow() << "An exception occured during writing the file " << finalFileName << ". Exception says " << e.what(); } return true; } bool IOUtil::SavePointSet(PointSet::Pointer pointset, const std::string path) { mitk::PointSetWriter::Pointer pointSetWriter = mitk::PointSetWriter::New(); std::string dir = itksys::SystemTools::GetFilenamePath( path ); std::string baseFilename = itksys::SystemTools::GetFilenameWithoutLastExtension( path ); std::string extension = itksys::SystemTools::GetFilenameLastExtension( path ); if (dir == "") dir = "."; std::string finalFileName = dir + "/" + baseFilename; if (extension == "") // if no extension has been entered manually into the filename { MITK_WARN << extension << " extension is not set. Extension set to default: " << finalFileName << DEFAULTPOINTSETEXTENSION; extension = DEFAULTPOINTSETEXTENSION; } // check if extension is valid if (!pointSetWriter->IsExtensionValid(extension)) { MITK_WARN << extension << " extension is unknown. Extension set to default: " << finalFileName << DEFAULTPOINTSETEXTENSION; extension = DEFAULTPOINTSETEXTENSION; } try { pointSetWriter->SetInput( pointset ); finalFileName += extension; pointSetWriter->SetFileName( finalFileName.c_str() ); pointSetWriter->Update(); } catch( std::exception& e ) { MITK_ERROR << " during attempt to write '" << finalFileName << "' Exception says:"; MITK_ERROR << e.what(); mitkThrow() << "An exception occured during writing the file " << finalFileName << ". Exception says " << e.what(); } return true; } bool IOUtil::SaveBaseData( mitk::BaseData* data, const std::string& path ) { if (data == NULL || path.empty()) return false; std::string dir = itksys::SystemTools::GetFilenamePath( path ); std::string baseFilename = itksys::SystemTools::GetFilenameWithoutExtension( path ); std::string extension = itksys::SystemTools::GetFilenameExtension( path ); if (dir == "") dir = "."; std::string fileNameWithoutExtension = dir + "/" + baseFilename; mitk::CoreObjectFactory::FileWriterList fileWriters = mitk::CoreObjectFactory::GetInstance()->GetFileWriters(); for (mitk::CoreObjectFactory::FileWriterList::iterator it = fileWriters.begin() ; it != fileWriters.end() ; ++it) { if ( (*it)->CanWriteBaseDataType(data) ) { // Ensure a valid filename if(baseFilename=="") { baseFilename = (*it)->GetDefaultFilename(); } // Check if an extension exists already and if not, append the default extension if (extension=="" ) { extension=(*it)->GetDefaultExtension(); } else { if (!(*it)->IsExtensionValid(extension)) { MITK_WARN << extension << " extension is unknown"; continue; } } std::string finalFileName = fileNameWithoutExtension + extension; try { (*it)->SetFileName( finalFileName.c_str() ); (*it)->DoWrite( data ); return true; } catch( const std::exception& e ) { MITK_ERROR << " during attempt to write '" << finalFileName << "' Exception says:"; MITK_ERROR << e.what(); mitkThrow() << "An exception occured during writing the file " << finalFileName << ". Exception says " << e.what(); } } } return false; } } diff --git a/Core/Code/IO/mitkIOUtil.h b/Core/Code/IO/mitkIOUtil.h index d2d4cdfd7c..c499b7feb2 100644 --- a/Core/Code/IO/mitkIOUtil.h +++ b/Core/Code/IO/mitkIOUtil.h @@ -1,236 +1,259 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKIOUTIL_H #define MITKIOUTIL_H #include #include #include #include #include #include namespace mitk { /** * \ingroup IO * * \brief A utility class to load and save data from/to the local file system. * * This method LoadFiles queries the MITK Micro Services registry for registered mitk::IDataNodeReader service * instances. The service instance with the highest ranking will be asked first to load the * given file. On error (exception thrown) or if no mitk::DataNode was constructed, the next * service instance is used. * * The methods LoadImage, LoadSurface, and LoadPointSet are convenience methods for general loading of * the three main data types in MITK. They all use the more generic method LoadDataNode. * * The methods SaveImage, SaveSurface, and SurfacePointSet are also meant for convenience (e.g. during testing). * Currently, there is no generic way to save a generic DataNode with an appropriate format. Thus, every method * initializes the corresponding instance of the special writer for the data type. * * \see mitk::IDataNodeReader */ class MITK_CORE_EXPORT IOUtil { public: /** * Get the file system path where the running executable is located. * * @return The location of the currently running executable, without the filename. */ static std::string GetProgramPath(); /** * Get the default temporary path. * * @return The default path for temporary data. */ static std::string GetTempPath(); /** * Create and open a temporary file. * * This method generates a unique temporary filename from \c templateName, creates * and opens the file using the output stream \c tmpStream and returns the name of * the newly create file. * * The \c templateName argument must contain six consective 'X' characters ("XXXXXX") * and these are replaced with a string that makes the filename unique. * * The file is created with read and write permissions for owner only. * * @param tmpStream The output stream for writing to the temporary file. * @param templateName An optional template for the filename. * @param path An optional path where the temporary file should be created. Defaults * to the default temp path as returned by GetTempPath(). * @return The filename of the created temporary file. * * @throw mitk::Exception if the temporary file could not be created. */ static std::string CreateTemporaryFile(std::ofstream& tmpStream, const std::string& templateName = "XXXXXX", std::string path = std::string()); /** * Create and open a temporary file. * * This method generates a unique temporary filename from \c templateName, creates * and opens the file using the output stream \c tmpStream and the specified open * mode \c mode and returns the name of the newly create file. The open mode is always * OR'd with \begin{code}std::ios_base::out | std::ios_base::trunc\end{code}. * * The \c templateName argument must contain six consective 'X' characters ("XXXXXX") * and these are replaced with a string that makes the filename unique. * * The file is created with read and write permissions for owner only. * * @param tmpStream The output stream for writing to the temporary file. * @param mode The open mode for the temporary file stream. * @param templateName An optional template for the filename. * @param path An optional path where the temporary file should be created. Defaults * to the default temp path as returned by GetTempPath(). * @return The filename of the created temporary file. * * @throw mitk::Exception if the temporary file could not be created. */ static std::string CreateTemporaryFile(std::ofstream& tmpStream, std::ios_base::openmode mode, const std::string& templateName = "XXXXXX", std::string path = std::string()); + /** + * Creates an empty temporary file. + * + * This method generates a unique temporary filename from \c templateName and creates + * this file. + * + * The file is created with read and write permissions for owner only. + * + * --- + * This version is potentially unsafe because the created temporary file is not kept open + * and could be used by another process between calling this method and opening the returned + * file path for reading or writing. + * --- + * + * @return The filename of the created temporary file. + * @param templateName An optional template for the filename. + * @param path An optional path where the temporary file should be created. Defaults + * to the default temp path as returned by GetTempPath(). + * @throw mitk::Exception if the temporary file could not be created. + */ + static std::string CreateTemporaryFile(const std::string& templateName = "XXXXXX", + std::string path = std::string()); + /** * Create a temporary directory. * * This method generates a uniquely named temporary directory from \c templateName. * The last set of six consecutive 'X' characters in \c templateName is replaced * with a string that makes the directory name unique. * * The directory is created with read, write and executable permissions for owner only. * * @param templateName An optional template for the directory name. * @param path An optional path where the temporary directory should be created. Defaults * to the default temp path as returned by GetTempPath(). * @return The filename of the created temporary file. * * @throw mitk::Exception if the temporary directory could not be created. */ static std::string CreateTemporaryDirectory(const std::string& templateName = "XXXXXX", std::string path = std::string()); /** * Load a files in fileNames and add the constructed mitk::DataNode instances * to the mitk::DataStorage storage * * \param fileNames A list (vector) of absolute file name paths. * \param storage The data storage to which the constructed data nodes are added. * \return The number of added mitk::DataNode instances. */ static int LoadFiles(const std::vector&fileNames, DataStorage& storage); /** * This method will create a new mitk::DataStorage instance and pass it to * LoadFiles(std::vector,DataStorage). * * \param fileNames A list (vector) of absolute file name paths. * \return The new mitk::DataStorage containing the constructed data nodes. * * \see LoadFiles(std::vector,DataStorage) */ static DataStorage::Pointer LoadFiles(const std::vector& fileNames); /** * @brief LoadDataNode Method to load an arbitrary DataNode. * @param path The path to the file including file name and file extension. * @throws mitk::Exception This exception is thrown when the DataNodeFactory is not able to read/find the file * or the DataNode is NULL. * @return Returns the DataNode. */ static mitk::DataNode::Pointer LoadDataNode(const std::string path); /** * @brief LoadImage Convenience method to load an arbitrary mitkImage. * @param path The path to the image including file name and file extension. * @throws mitk::Exception This exception is thrown when the Image is NULL. * @return Returns the mitkImage. */ static mitk::Image::Pointer LoadImage(const std::string path); /** * @brief LoadSurface Convenience method to load an arbitrary mitkSurface. * @param path The path to the surface including file name and file extension. * @throws mitk::Exception This exception is thrown when the Surface is NULL. * @return Returns the mitkSurface. */ static mitk::Surface::Pointer LoadSurface(const std::string path); /** * @brief LoadPointSet Convenience method to load an arbitrary mitkPointSet. * @param path The path to the pointset including file name and file extension (currently, only .mps is supported). * @throws mitk::Exception This exception is thrown when the PointSet is NULL. * @return Returns the mitkPointSet. */ static mitk::PointSet::Pointer LoadPointSet(const std::string path); /** * @brief SaveImage Convenience method to save an arbitrary mitkImage. * @param path The path to the image including file name and file extension. * If not extention is set, the default value (defined in DEFAULTIMAGEEXTENSION) is used. * @param image The image to save. * @throws mitk::Exception This exception is thrown when the writer is not able to write the image. * @return Returns true for success else false. */ static bool SaveImage(mitk::Image::Pointer image, const std::string path); /** * @brief SaveBaseData Convenience method to save arbitrary baseData. * @param path The path to the image including file name and file extension. * If not extention is set, the default value (defined in DEFAULTIMAGEEXTENSION) is used. * @param data The data to save. * @throws mitk::Exception This exception is thrown when the writer is not able to write the image. * @return Returns true for success else false. */ static bool SaveBaseData(mitk::BaseData* data, const std::string& path); /** * @brief SaveSurface Convenience method to save an arbitrary mitkSurface. * @param path The path to the surface including file name and file extension. * If not extention is set, the default value (defined in DEFAULTSURFACEEXTENSION) is used. * @throws mitk::Exception This exception is thrown when the writer is not able to write the surface. * or if the fileextension is not suitable for writing. * @return Returns true for success else false. */ static bool SaveSurface(mitk::Surface::Pointer surface, const std::string path); /** * @brief SavePointSet Convenience method to save an mitkPointSet. * @param path The path to the pointset including file name and file extension (currently, only .mps is supported). * If not extention is set, the default value (defined in DEFAULTPOINTSETEXTENSION) is used. * @throws mitk::Exception This exception is thrown when the writer is not able to write the pointset. * @return Returns true for success else false. */ static bool SavePointSet(mitk::PointSet::Pointer pointset, const std::string path); static const std::string DEFAULTIMAGEEXTENSION; static const std::string DEFAULTSURFACEEXTENSION; static const std::string DEFAULTPOINTSETEXTENSION; }; } #endif // MITKIOUTIL_H diff --git a/Core/Code/Testing/mitkIOUtilTest.cpp b/Core/Code/Testing/mitkIOUtilTest.cpp index 5eb29dcf85..062668d66a 100644 --- a/Core/Code/Testing/mitkIOUtilTest.cpp +++ b/Core/Code/Testing/mitkIOUtilTest.cpp @@ -1,174 +1,180 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkTestingMacros.h" #include #include #include #include #include class mitkIOUtilTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkIOUtilTestSuite); MITK_TEST(TestTempMethods); MITK_TEST(TestLoadAndSaveImage); MITK_TEST(TestLoadAndSavePointSet); MITK_TEST(TestLoadAndSaveSurface); CPPUNIT_TEST_SUITE_END(); private: std::string m_ImagePath; std::string m_SurfacePath; std::string m_PointSetPath; public: void setUp() { m_ImagePath = GetTestDataFilePath("Pic3D.nrrd"); m_SurfacePath = GetTestDataFilePath("binary.stl"); m_PointSetPath = GetTestDataFilePath("pointSet.mps"); } void TestTempMethods() { std::string tmpPath = mitk::IOUtil::GetTempPath(); CPPUNIT_ASSERT(!tmpPath.empty()); std::ofstream tmpFile; std::string tmpFilePath = mitk::IOUtil::CreateTemporaryFile(tmpFile); CPPUNIT_ASSERT(tmpFile && tmpFile.is_open()); CPPUNIT_ASSERT(tmpFilePath.size() > tmpPath.size()); CPPUNIT_ASSERT(tmpFilePath.substr(0, tmpPath.size()) == tmpPath); tmpFile.close(); CPPUNIT_ASSERT(std::remove(tmpFilePath.c_str()) == 0); std::string programPath = mitk::IOUtil::GetProgramPath(); CPPUNIT_ASSERT(!programPath.empty()); std::ofstream tmpFile2; std::string tmpFilePath2 = mitk::IOUtil::CreateTemporaryFile(tmpFile2, "my-XXXXXX", programPath); CPPUNIT_ASSERT(tmpFile2 && tmpFile2.is_open()); CPPUNIT_ASSERT(tmpFilePath2.size() > programPath.size()); CPPUNIT_ASSERT(tmpFilePath2.substr(0, programPath.size()) == programPath); tmpFile2.close(); CPPUNIT_ASSERT(std::remove(tmpFilePath2.c_str()) == 0); std::ofstream tmpFile3; std::string tmpFilePath3 = mitk::IOUtil::CreateTemporaryFile(tmpFile3, std::ios_base::binary, "my-XXXXXX.TXT", programPath); CPPUNIT_ASSERT(tmpFile3 && tmpFile3.is_open()); CPPUNIT_ASSERT(tmpFilePath3.size() > programPath.size()); CPPUNIT_ASSERT(tmpFilePath3.substr(0, programPath.size()) == programPath); CPPUNIT_ASSERT(tmpFilePath3.substr(tmpFilePath3.size() - 13, 3) == "my-"); CPPUNIT_ASSERT(tmpFilePath3.substr(tmpFilePath3.size() - 4) == ".TXT"); tmpFile3.close(); //CPPUNIT_ASSERT(std::remove(tmpFilePath3.c_str()) == 0) + std::string tmpFilePath4 = mitk::IOUtil::CreateTemporaryFile(); + std::ofstream file; + file.open(tmpFilePath4.c_str()); + CPPUNIT_ASSERT_MESSAGE("Testing if file exists after CreateTemporaryFile()",file.is_open()); + + CPPUNIT_ASSERT_THROW(mitk::IOUtil::CreateTemporaryFile(tmpFile2, "XX"), mitk::Exception); std::string tmpDir = mitk::IOUtil::CreateTemporaryDirectory(); CPPUNIT_ASSERT(tmpDir.size() > tmpPath.size()); CPPUNIT_ASSERT(tmpDir.substr(0, tmpPath.size()) == tmpPath); CPPUNIT_ASSERT(itksys::SystemTools::RemoveADirectory(tmpDir.c_str())); std::string tmpDir2 = mitk::IOUtil::CreateTemporaryDirectory("my-XXXXXX", programPath); CPPUNIT_ASSERT(tmpDir2.size() > programPath.size()); CPPUNIT_ASSERT(tmpDir2.substr(0, programPath.size()) == programPath); CPPUNIT_ASSERT(itksys::SystemTools::RemoveADirectory(tmpDir2.c_str())); } void TestLoadAndSaveImage() { mitk::Image::Pointer img1 = mitk::IOUtil::LoadImage(m_ImagePath); CPPUNIT_ASSERT( img1.IsNotNull()); std::ofstream tmpStream; std::string imagePath = mitk::IOUtil::CreateTemporaryFile(tmpStream, "diffpic3d-XXXXXX.nrrd"); tmpStream.close(); std::string imagePath2 = mitk::IOUtil::CreateTemporaryFile(tmpStream, "diffpic3d-XXXXXX.nii.gz"); tmpStream.close(); // the cases where no exception should be thrown CPPUNIT_ASSERT(mitk::IOUtil::SaveImage(img1, imagePath)); CPPUNIT_ASSERT(mitk::IOUtil::SaveBaseData(img1.GetPointer(), imagePath2)); //load data which does not exist CPPUNIT_ASSERT_THROW(mitk::IOUtil::LoadImage("fileWhichDoesNotExist.nrrd"), mitk::Exception); //delete the files after the test is done std::remove(imagePath.c_str()); std::remove(imagePath2.c_str()); mitk::Image::Pointer relativImage = mitk::ImageGenerator::GenerateGradientImage(4,4,4,1); std::string imagePath3 = mitk::IOUtil::CreateTemporaryFile(tmpStream, "XXXXXX.nrrd"); tmpStream.close(); mitk::IOUtil::SaveImage(relativImage, imagePath3); CPPUNIT_ASSERT_NO_THROW(mitk::IOUtil::LoadImage(imagePath3)); std::remove(imagePath3.c_str()); } void TestLoadAndSavePointSet() { mitk::PointSet::Pointer pointset = mitk::IOUtil::LoadPointSet(m_PointSetPath); CPPUNIT_ASSERT( pointset.IsNotNull()); std::ofstream tmpStream; std::string pointSetPath = mitk::IOUtil::CreateTemporaryFile(tmpStream, "XXXXXX.mps"); tmpStream.close(); std::string pointSetPathWithDefaultExtension = mitk::IOUtil::CreateTemporaryFile(tmpStream, "XXXXXX.mps"); tmpStream.close(); std::string pointSetPathWithoutDefaultExtension = mitk::IOUtil::CreateTemporaryFile(tmpStream, "XXXXXX.xXx"); tmpStream.close(); // the cases where no exception should be thrown CPPUNIT_ASSERT(mitk::IOUtil::SavePointSet(pointset, pointSetPathWithDefaultExtension)); // test if defaultextension is inserted if no extension is present CPPUNIT_ASSERT(mitk::IOUtil::SavePointSet(pointset, pointSetPathWithoutDefaultExtension.c_str())); //delete the files after the test is done std::remove(pointSetPath.c_str()); std::remove(pointSetPathWithDefaultExtension.c_str()); std::remove(pointSetPathWithoutDefaultExtension.c_str()); } void TestLoadAndSaveSurface() { mitk::Surface::Pointer surface = mitk::IOUtil::LoadSurface(m_SurfacePath); CPPUNIT_ASSERT( surface.IsNotNull()); std::ofstream tmpStream; std::string surfacePath = mitk::IOUtil::CreateTemporaryFile(tmpStream, "diffsurface-XXXXXX.stl"); // the cases where no exception should be thrown CPPUNIT_ASSERT(mitk::IOUtil::SaveSurface(surface, surfacePath)); // test if exception is thrown as expected on unknown extsension CPPUNIT_ASSERT_THROW(mitk::IOUtil::SaveSurface(surface,"testSurface.xXx"), mitk::Exception); //delete the files after the test is done std::remove(surfacePath.c_str()); } }; MITK_TEST_SUITE_REGISTRATION(mitkIOUtil) diff --git a/Modules/IGT/Testing/mitkNavigationToolStorageSerializerAndDeserializerTest.cpp b/Modules/IGT/Testing/mitkNavigationToolStorageSerializerAndDeserializerTest.cpp index ebbc2649e5..7a6bc032d5 100644 --- a/Modules/IGT/Testing/mitkNavigationToolStorageSerializerAndDeserializerTest.cpp +++ b/Modules/IGT/Testing/mitkNavigationToolStorageSerializerAndDeserializerTest.cpp @@ -1,475 +1,468 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkTestingConfig.h" #include #include #include #include #include #include #include #include #include #include //POCO #include #include #include static void TestInstantiationSerializer() { // let's create objects of our classes mitk::NavigationToolStorageSerializer::Pointer testSerializer = mitk::NavigationToolStorageSerializer::New(); MITK_TEST_CONDITION_REQUIRED(testSerializer.IsNotNull(),"Testing instantiation of NavigationToolStorageSerializer"); } static void TestInstantiationDeserializer() { mitk::DataStorage::Pointer tempStorage = dynamic_cast(mitk::StandaloneDataStorage::New().GetPointer()); //needed for deserializer! mitk::NavigationToolStorageDeserializer::Pointer testDeserializer = mitk::NavigationToolStorageDeserializer::New(tempStorage); MITK_TEST_CONDITION_REQUIRED(testDeserializer.IsNotNull(),"Testing instantiation of NavigationToolStorageDeserializer") } static void TestWriteSimpleToolStorage() { //create Tool Storage mitk::NavigationToolStorage::Pointer myStorage = mitk::NavigationToolStorage::New(); //first tool mitk::NavigationTool::Pointer myTool1 = mitk::NavigationTool::New(); myTool1->SetIdentifier("001"); myStorage->AddTool(myTool1); //second tool mitk::NavigationTool::Pointer myTool2 = mitk::NavigationTool::New(); myTool2->SetIdentifier("002"); myStorage->AddTool(myTool2); //third tool mitk::NavigationTool::Pointer myTool3 = mitk::NavigationTool::New(); myTool3->SetIdentifier("003"); myStorage->AddTool(myTool3); //create Serializer mitk::NavigationToolStorageSerializer::Pointer mySerializer = mitk::NavigationToolStorageSerializer::New(); //create filename std::string filename = std::string( MITK_TEST_OUTPUT_DIR )+Poco::Path::separator()+"TestStorage.storage"; //test serialization bool success = mySerializer->Serialize(filename,myStorage); MITK_TEST_CONDITION_REQUIRED(success,"Testing serialization of simple tool storage"); } static void TestWriteAndReadSimpleToolStorageWithToolLandmarks() { //create Tool Storage mitk::NavigationToolStorage::Pointer myStorage = mitk::NavigationToolStorage::New(); //first tool mitk::NavigationTool::Pointer myTool1 = mitk::NavigationTool::New(); myTool1->SetIdentifier("001"); mitk::PointSet::Pointer CalLandmarks1 = mitk::PointSet::New(); mitk::Point3D testPt1; mitk::FillVector3D(testPt1,1,2,3); CalLandmarks1->SetPoint(0,testPt1); mitk::PointSet::Pointer RegLandmarks1 = mitk::PointSet::New(); mitk::Point3D testPt2; mitk::FillVector3D(testPt2,4,5,6); RegLandmarks1->SetPoint(5,testPt2); myTool1->SetToolCalibrationLandmarks(CalLandmarks1); myTool1->SetToolRegistrationLandmarks(RegLandmarks1); mitk::Point3D toolTipPos; mitk::FillVector3D(toolTipPos,1.3423,2.323,4.332); mitk::Quaternion toolTipRot = mitk::Quaternion(0.1,0.2,0.3,0.4); myTool1->SetToolTipPosition(toolTipPos); myTool1->SetToolTipOrientation(toolTipRot); myStorage->AddTool(myTool1); //create Serializer mitk::NavigationToolStorageSerializer::Pointer mySerializer = mitk::NavigationToolStorageSerializer::New(); //create filename std::string filename = std::string( MITK_TEST_OUTPUT_DIR )+Poco::Path::separator()+"TestStorageToolReg.storage"; //test serialization bool success = mySerializer->Serialize(filename,myStorage); MITK_TEST_CONDITION_REQUIRED(success,"Testing serialization of tool storage with tool registrations"); mitk::DataStorage::Pointer tempStorage = dynamic_cast(mitk::StandaloneDataStorage::New().GetPointer()); //needed for deserializer! mitk::NavigationToolStorageDeserializer::Pointer myDeserializer = mitk::NavigationToolStorageDeserializer::New(tempStorage); mitk::NavigationToolStorage::Pointer readStorage = myDeserializer->Deserialize(std::string( MITK_TEST_OUTPUT_DIR )+Poco::Path::separator()+"TestStorageToolReg.storage"); MITK_TEST_CONDITION_REQUIRED(readStorage.IsNotNull(),"Testing deserialization of tool storage with tool registrations"); MITK_TEST_CONDITION_REQUIRED(readStorage->GetToolCount()==1," ..Testing number of tools in storage"); mitk::PointSet::Pointer readRegLandmarks = readStorage->GetTool(0)->GetToolRegistrationLandmarks(); mitk::PointSet::Pointer readCalLandmarks = readStorage->GetTool(0)->GetToolCalibrationLandmarks(); int val1 = readRegLandmarks->GetPoint(5)[0]; int val2 = readRegLandmarks->GetPoint(5)[1]; int val3 = readRegLandmarks->GetPoint(5)[2]; std::cout << val1 << val2 << val3 << std::endl; MITK_TEST_CONDITION_REQUIRED(((readRegLandmarks->GetPoint(5)[0] == 4)&&(readRegLandmarks->GetPoint(5)[1] == 5)&&(readRegLandmarks->GetPoint(5)[2] == 6)),"..Testing if tool registration landmarks have been stored and loaded correctly."); MITK_TEST_CONDITION_REQUIRED(((readCalLandmarks->GetPoint(0)[0] == 1)&&(readCalLandmarks->GetPoint(0)[1] == 2)&&(readCalLandmarks->GetPoint(0)[2] == 3)),"..Testing if tool calibration landmarks have been stored and loaded correctly."); mitk::Point3D readToolTipPos = readStorage->GetTool(0)->GetToolTipPosition(); mitk::Quaternion readToolTipRot = readStorage->GetTool(0)->GetToolTipOrientation(); MITK_TEST_CONDITION_REQUIRED(((float(readToolTipPos[0]) == float(1.3423))&& (float(readToolTipPos[1]) == float(2.323))&& (float(readToolTipPos[2]) == float(4.332))), "..Testing if tool tip position has been stored and loaded correctly."); MITK_TEST_CONDITION_REQUIRED(((float(readToolTipRot.x()) == float(0.1))&& (float(readToolTipRot.y()) == float(0.2))&& (float(readToolTipRot.z()) == float(0.3))&& (float(readToolTipRot.r()) == float(0.4))), "..Testing if tool tip orientation has been stored and loaded correctly."); } static void TestReadSimpleToolStorage() { mitk::DataStorage::Pointer tempStorage = dynamic_cast(mitk::StandaloneDataStorage::New().GetPointer()); //needed for deserializer! mitk::NavigationToolStorageDeserializer::Pointer myDeserializer = mitk::NavigationToolStorageDeserializer::New(tempStorage); mitk::NavigationToolStorage::Pointer readStorage = myDeserializer->Deserialize(std::string( MITK_TEST_OUTPUT_DIR )+Poco::Path::separator()+"TestStorage.storage"); MITK_TEST_CONDITION_REQUIRED(readStorage.IsNotNull(),"Testing deserialization of simple tool storage"); MITK_TEST_CONDITION_REQUIRED(readStorage->GetToolCount()==3," ..Testing number of tools in storage"); //TODO: why is the order of tools changed is save/load process?? bool foundtool1 = false; bool foundtool2 = false; bool foundtool3 = false; for(int i=0; i<3; i++) { if ((readStorage->GetTool(i)->GetIdentifier()=="001")) foundtool1 = true; else if ((readStorage->GetTool(i)->GetIdentifier()=="002")) foundtool2 = true; else if ((readStorage->GetTool(i)->GetIdentifier()=="003")) foundtool3 = true; } MITK_TEST_CONDITION_REQUIRED(foundtool1&&foundtool2&&foundtool3," ..Testing if identifiers of tools where saved / loaded successfully"); } static void CleanUp() { try { std::remove((std::string( MITK_TEST_OUTPUT_DIR )+Poco::Path::separator()+"TestStorage.storage").c_str()); std::remove((std::string( MITK_TEST_OUTPUT_DIR )+Poco::Path::separator()+"TestStorageToolReg.storage").c_str()); std::remove((std::string( MITK_TEST_OUTPUT_DIR )+Poco::Path::separator()+"TestStorage2.storage").c_str()); } catch(...) { MITK_INFO << "Warning: Error occured when deleting test file!"; } } static void TestWriteComplexToolStorage() { //create first tool mitk::Surface::Pointer testSurface; std::string toolFileName(MITK_IGT_DATA_DIR); toolFileName.append("/ClaronTool"); mitk::NavigationTool::Pointer myNavigationTool = mitk::NavigationTool::New(); myNavigationTool->SetCalibrationFile(toolFileName); mitk::DataNode::Pointer myNode = mitk::DataNode::New(); myNode->SetName("ClaronTool"); //load an stl File std::string pathToClaronTool(MITK_IGT_DATA_DIR); pathToClaronTool.append("/ClaronTool.stl"); testSurface = mitk::IOUtil::LoadSurface(pathToClaronTool); myNode->SetData(testSurface); myNavigationTool->SetDataNode(myNode); myNavigationTool->SetIdentifier("ClaronTool#1"); myNavigationTool->SetSerialNumber("0815"); myNavigationTool->SetTrackingDeviceType(mitk::ClaronMicron); myNavigationTool->SetType(mitk::NavigationTool::Fiducial); //create second tool mitk::NavigationTool::Pointer myNavigationTool2 = mitk::NavigationTool::New(); mitk::Surface::Pointer testSurface2; mitk::DataNode::Pointer myNode2 = mitk::DataNode::New(); myNode2->SetName("AuroraTool"); //load an stl File std::string pathToEMTool(MITK_IGT_DATA_DIR); pathToEMTool.append("/EMTool.stl"); testSurface2 = mitk::IOUtil::LoadSurface(pathToEMTool); myNode2->SetData(testSurface2); myNavigationTool2->SetDataNode(myNode2); myNavigationTool2->SetIdentifier("AuroraTool#1"); myNavigationTool2->SetSerialNumber("0816"); myNavigationTool2->SetTrackingDeviceType(mitk::NDIAurora); myNavigationTool2->SetType(mitk::NavigationTool::Instrument); //create navigation tool storage mitk::NavigationToolStorage::Pointer myStorage = mitk::NavigationToolStorage::New(); myStorage->AddTool(myNavigationTool); myStorage->AddTool(myNavigationTool2); //create Serializer mitk::NavigationToolStorageSerializer::Pointer mySerializer = mitk::NavigationToolStorageSerializer::New(); //create filename std::string filename = std::string( MITK_TEST_OUTPUT_DIR )+Poco::Path::separator()+"TestStorage2.storage"; //test serialization bool success = mySerializer->Serialize(filename,myStorage); MITK_TEST_CONDITION_REQUIRED(success,"Testing serialization of complex tool storage"); } static void TestReadComplexToolStorage() { mitk::DataStorage::Pointer tempStorage = dynamic_cast(mitk::StandaloneDataStorage::New().GetPointer()); //needed for deserializer! mitk::NavigationToolStorageDeserializer::Pointer myDeserializer = mitk::NavigationToolStorageDeserializer::New(tempStorage); mitk::NavigationToolStorage::Pointer readStorage = myDeserializer->Deserialize(std::string( MITK_TEST_OUTPUT_DIR )+Poco::Path::separator()+"TestStorage2.storage"); MITK_TEST_CONDITION_REQUIRED(readStorage.IsNotNull(),"Testing deserialization of complex tool storage"); MITK_TEST_CONDITION_REQUIRED(readStorage->GetToolCount()==2," ..Testing number of tools in storage"); } static void TestReadNotExistingStorage() { mitk::DataStorage::Pointer tempStorage = dynamic_cast(mitk::StandaloneDataStorage::New().GetPointer()); //needed for deserializer! mitk::NavigationToolStorageDeserializer::Pointer myDeserializer = mitk::NavigationToolStorageDeserializer::New(tempStorage); bool exceptionThrown = false; try { mitk::NavigationToolStorage::Pointer readStorage = myDeserializer->Deserialize("noStorage.tfl"); } catch (mitk::IGTException e) { exceptionThrown = true; } MITK_TEST_CONDITION_REQUIRED(exceptionThrown,"Testing if exception is thrown if a non existing storage is given for deserialization."); } static void TestReadStorageWithUnknownFiletype() { mitk::DataStorage::Pointer tempStorage = dynamic_cast(mitk::StandaloneDataStorage::New().GetPointer()); //needed for deserializer! std::string toolFileName(MITK_IGT_DATA_DIR); toolFileName.append("/ClaronTool.stl"); mitk::NavigationToolStorageDeserializer::Pointer myDeserializer = mitk::NavigationToolStorageDeserializer::New(tempStorage); bool exceptionThrown = false; try { mitk::NavigationToolStorage::Pointer readStorage = myDeserializer->Deserialize(toolFileName); } catch (mitk::IGTException e) { exceptionThrown = true; } MITK_TEST_CONDITION_REQUIRED(exceptionThrown,"Testing if exception is thrown if a wrong file type is given for deserialization."); } static void TestReadZipFileWithNoToolstorage() { mitk::DataStorage::Pointer tempStorage = dynamic_cast(mitk::StandaloneDataStorage::New().GetPointer()); //needed for deserializer! std::string toolFileName(MITK_IGT_DATA_DIR); toolFileName.append("/Empty.zip"); MITK_TEST_CONDITION(toolFileName.empty() == false, "Check if tool calibration of claron tool file exists"); mitk::NavigationToolStorageDeserializer::Pointer myDeserializer = mitk::NavigationToolStorageDeserializer::New(tempStorage); bool exceptionThrown = false; try { mitk::NavigationToolStorage::Pointer readStorage = myDeserializer->Deserialize(toolFileName); } catch (mitk::IGTException e) { exceptionThrown = true; } catch (std::exception& e) { MITK_ERROR << "Unexpected exception catched: " << e.what() << " / filename: " << toolFileName; } MITK_TEST_CONDITION_REQUIRED(exceptionThrown,"Testing if exception is thrown if a empty zip file is given for deserialization."); } static void TestWriteStorageToInvalidFile() { //create Tool Storage mitk::NavigationToolStorage::Pointer myStorage = mitk::NavigationToolStorage::New(); //first tool mitk::NavigationTool::Pointer myTool1 = mitk::NavigationTool::New(); myTool1->SetIdentifier("001"); myStorage->AddTool(myTool1); //second tool mitk::NavigationTool::Pointer myTool2 = mitk::NavigationTool::New(); myTool2->SetIdentifier("002"); myStorage->AddTool(myTool2); //third tool mitk::NavigationTool::Pointer myTool3 = mitk::NavigationTool::New(); myTool3->SetIdentifier("003"); myStorage->AddTool(myTool3); //create Serializer mitk::NavigationToolStorageSerializer::Pointer mySerializer = mitk::NavigationToolStorageSerializer::New(); //create filename #ifdef WIN32 std::string filename = "C:\342INVALIDFILE<>.storage"; //invalid filename for windows #else std::string filename = "/dsfdsf:$�$342INVALIDFILE.storage"; //invalid filename for linux #endif //test serialization bool exceptionThrown = false; try { mySerializer->Serialize(filename,myStorage); } catch(mitk::IGTException e) { exceptionThrown = true; } MITK_TEST_CONDITION_REQUIRED(exceptionThrown,"Testing if an exception is thrown if an invalid file is used."); } static void TestWriteEmptyToolStorage() { //create Tool Storage mitk::NavigationToolStorage::Pointer myStorage = mitk::NavigationToolStorage::New(); //create Serializer mitk::NavigationToolStorageSerializer::Pointer mySerializer = mitk::NavigationToolStorageSerializer::New(); std::string filename; - std::string optionDirectory; - std::string separator; try { //create filename - separator = Poco::Path::separator(); - optionDirectory = std::string( MITK_TEST_OUTPUT_DIR ); - mitk::UIDGenerator myGen = mitk::UIDGenerator(); - filename = std::string( MITK_TEST_OUTPUT_DIR )+Poco::Path::separator()+"TestStorage"+myGen.GetUID()+".storage"; + filename = mitk::IOUtil::CreateTemporaryFile(); } catch (std::exception& e) { MITK_ERROR << "File access Exception: " << e.what(); - MITK_INFO << "separator: " << separator; - MITK_INFO << "optionDirectory: " << optionDirectory; MITK_TEST_FAILED_MSG(<<"Could not create filename for Exceptiontest"); } //test serialization bool success = mySerializer->Serialize(filename,myStorage); MITK_TEST_CONDITION_REQUIRED(success,"Testing serialization of simple tool storage"); //clean up Poco::File file = Poco::File(filename); file.remove(); } //new tests for exception throwing of NavigationToolStorageSerializer static void TestSerializerForExceptions() { mitk::NavigationToolStorageSerializer::Pointer testSerializer = mitk::NavigationToolStorageSerializer::New(); mitk::NavigationToolStorage::Pointer myStorage = mitk::NavigationToolStorage::New(); //create an invalid filename std::string filename = std::string( MITK_TEST_OUTPUT_DIR )+Poco::Path::separator()+""; //now try to serialize an check if an exception is thrown bool ExceptionThrown = false; try { testSerializer->Serialize(filename,myStorage); } catch(mitk::IGTException) { ExceptionThrown = true; } MITK_TEST_CONDITION_REQUIRED(ExceptionThrown, "Testing serializer with invalid filename."); } //new tests for exception throwing of NavigationToolStorageDeserializer static void TestDeserializerForExceptions() { // Desearializing file with invalid name mitk::DataStorage::Pointer tempStorage = dynamic_cast(mitk::StandaloneDataStorage::New().GetPointer()); mitk::NavigationToolStorageDeserializer::Pointer testDeseralizer= mitk::NavigationToolStorageDeserializer::New(tempStorage); bool ExceptionThrown1 = false; try { mitk::NavigationToolStorage::Pointer readStorage = testDeseralizer->Deserialize("InvalidName"); } catch(mitk::IGTException) { ExceptionThrown1 = true; } MITK_TEST_CONDITION_REQUIRED(ExceptionThrown1, "Testing deserializer with invalid filename."); bool ExceptionThrown2 = false; // Deserializing of empty zip file mitk::NavigationToolStorageDeserializer::Pointer testDeseralizer2= mitk::NavigationToolStorageDeserializer::New(tempStorage); try { std::string filename(MITK_IGT_DATA_DIR); filename.append("/Empty2.zip"); mitk::NavigationToolStorage::Pointer readStorage = testDeseralizer2->Deserialize(filename); } catch(mitk::IGTException) { ExceptionThrown2 = true; } MITK_TEST_CONDITION_REQUIRED(ExceptionThrown2, "Testing deserializer method with empty zip file."); } /** This function is testing the TrackingVolume class. */ int mitkNavigationToolStorageSerializerAndDeserializerTest(int /* argc */, char* /*argv*/[]) { MITK_TEST_BEGIN("NavigationToolStorageSerializerAndDeserializer"); try{ TestInstantiationSerializer(); TestInstantiationDeserializer(); TestWriteSimpleToolStorage(); TestWriteAndReadSimpleToolStorageWithToolLandmarks(); TestReadSimpleToolStorage(); TestWriteComplexToolStorage(); TestReadComplexToolStorage(); TestReadNotExistingStorage(); TestReadStorageWithUnknownFiletype(); TestReadZipFileWithNoToolstorage(); TestWriteStorageToInvalidFile(); TestWriteEmptyToolStorage(); TestSerializerForExceptions(); TestDeserializerForExceptions(); } catch (std::exception& e) { MITK_ERROR << "exception:" << e.what(); MITK_TEST_FAILED_MSG(<<"Exception occured, test failed!"); } catch (...) { MITK_ERROR << "Unknown Exception?"; MITK_TEST_FAILED_MSG(<<"Exception occured, test failed!"); } CleanUp(); MITK_TEST_END(); }