Mercurial > hg > orthanc
diff OrthancFramework/Sources/SystemToolbox.cpp @ 4399:80fd140b12ba
New command-line option: "--openapi" to write the OpenAPI documentation of the REST API to a file
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 23 Dec 2020 12:21:03 +0100 |
parents | 52166629239f |
children | b651989194d3 |
line wrap: on
line diff
--- a/OrthancFramework/Sources/SystemToolbox.cpp Tue Dec 22 09:39:06 2020 +0100 +++ b/OrthancFramework/Sources/SystemToolbox.cpp Wed Dec 23 12:21:03 2020 +0100 @@ -213,30 +213,41 @@ log); } - boost::filesystem::ifstream f; - f.open(path, std::ifstream::in | std::ifstream::binary); - if (!f.good()) + try { - throw OrthancException(ErrorCode_InexistentFile, - "File not found: " + path, - log); - } + boost::filesystem::ifstream f; + f.open(path, std::ifstream::in | std::ifstream::binary); + if (!f.good()) + { + throw OrthancException(ErrorCode_InexistentFile, + "File not found: " + path, + log); + } - std::streamsize size = GetStreamSize(f); - content.resize(static_cast<size_t>(size)); + std::streamsize size = GetStreamSize(f); + content.resize(static_cast<size_t>(size)); - if (static_cast<std::streamsize>(content.size()) != size) - { - throw OrthancException(ErrorCode_InternalError, - "Reading a file that is too large for a 32bit architecture"); - } + if (static_cast<std::streamsize>(content.size()) != size) + { + throw OrthancException(ErrorCode_InternalError, + "Reading a file that is too large for a 32bit architecture"); + } - if (size != 0) + if (size != 0) + { + f.read(&content[0], size); + } + + f.close(); + } + catch (boost::filesystem::filesystem_error&) { - f.read(&content[0], size); + throw OrthancException(ErrorCode_InexistentFile); } - - f.close(); + catch (std::system_error&) + { + throw OrthancException(ErrorCode_InexistentFile); + } } @@ -256,38 +267,49 @@ "The path does not point to a regular file: " + path); } - boost::filesystem::ifstream f; - f.open(path, std::ifstream::in | std::ifstream::binary); - if (!f.good()) + try + { + boost::filesystem::ifstream f; + f.open(path, std::ifstream::in | std::ifstream::binary); + if (!f.good()) + { + throw OrthancException(ErrorCode_InexistentFile); + } + + bool full = true; + + { + std::streamsize size = GetStreamSize(f); + if (size <= 0) + { + headerSize = 0; + full = false; + } + else if (static_cast<size_t>(size) < headerSize) + { + headerSize = static_cast<size_t>(size); // Truncate to the size of the file + full = false; + } + } + + header.resize(headerSize); + if (headerSize != 0) + { + f.read(&header[0], headerSize); + } + + f.close(); + + return full; + } + catch (boost::filesystem::filesystem_error&) { throw OrthancException(ErrorCode_InexistentFile); } - - bool full = true; - + catch (std::system_error&) { - std::streamsize size = GetStreamSize(f); - if (size <= 0) - { - headerSize = 0; - full = false; - } - else if (static_cast<size_t>(size) < headerSize) - { - headerSize = static_cast<size_t>(size); // Truncate to the size of the file - full = false; - } + throw OrthancException(ErrorCode_InexistentFile); } - - header.resize(headerSize); - if (headerSize != 0) - { - f.read(&header[0], headerSize); - } - - f.close(); - - return full; } @@ -296,56 +318,67 @@ const std::string& path, bool callFsync) { - //boost::filesystem::ofstream f; - boost::iostreams::stream<boost::iostreams::file_descriptor_sink> f; + try + { + //boost::filesystem::ofstream f; + boost::iostreams::stream<boost::iostreams::file_descriptor_sink> f; - f.open(path, std::ofstream::out | std::ofstream::binary); - if (!f.good()) + f.open(path, std::ofstream::out | std::ofstream::binary); + if (!f.good()) + { + throw OrthancException(ErrorCode_CannotWriteFile); + } + + if (size != 0) + { + f.write(reinterpret_cast<const char*>(content), size); + + if (!f.good()) + { + f.close(); + throw OrthancException(ErrorCode_CannotWriteFile); + } + } + + if (callFsync) + { + // https://stackoverflow.com/a/23826489/881731 + f.flush(); + + bool success; + + /** + * "f->handle()" corresponds to "FILE*" (aka "HANDLE") on + * Microsoft Windows, and to "int" (file descriptor) on other + * systems: + * https://github.com/boostorg/iostreams/blob/develop/include/boost/iostreams/detail/file_handle.hpp + **/ + +#if defined(_WIN32) + // https://docs.microsoft.com/fr-fr/windows/win32/api/fileapi/nf-fileapi-flushfilebuffers + success = (::FlushFileBuffers(f->handle()) != 0); +#elif (_POSIX_C_SOURCE >= 199309L || _XOPEN_SOURCE >= 500) + success = (::fdatasync(f->handle()) == 0); +#else + success = (::fsync(f->handle()) == 0); +#endif + + if (!success) + { + throw OrthancException(ErrorCode_CannotWriteFile, "Cannot force flush to disk"); + } + } + + f.close(); + } + catch (boost::filesystem::filesystem_error&) { throw OrthancException(ErrorCode_CannotWriteFile); } - - if (size != 0) - { - f.write(reinterpret_cast<const char*>(content), size); - - if (!f.good()) - { - f.close(); - throw OrthancException(ErrorCode_FileStorageCannotWrite); - } - } - - if (callFsync) + catch (std::system_error&) { - // https://stackoverflow.com/a/23826489/881731 - f.flush(); - - bool success; - - /** - * "f->handle()" corresponds to "FILE*" (aka "HANDLE") on - * Microsoft Windows, and to "int" (file descriptor) on other - * systems: - * https://github.com/boostorg/iostreams/blob/develop/include/boost/iostreams/detail/file_handle.hpp - **/ - -#if defined(_WIN32) - // https://docs.microsoft.com/fr-fr/windows/win32/api/fileapi/nf-fileapi-flushfilebuffers - success = (::FlushFileBuffers(f->handle()) != 0); -#elif (_POSIX_C_SOURCE >= 199309L || _XOPEN_SOURCE >= 500) - success = (::fdatasync(f->handle()) == 0); -#else - success = (::fsync(f->handle()) == 0); -#endif - - if (!success) - { - throw OrthancException(ErrorCode_FileStorageCannotWrite, "Cannot force flush to disk"); - } + throw OrthancException(ErrorCode_CannotWriteFile); } - - f.close(); } @@ -396,6 +429,10 @@ { throw OrthancException(ErrorCode_InexistentFile); } + catch (std::system_error&) + { + throw OrthancException(ErrorCode_InexistentFile); + } } @@ -575,18 +612,16 @@ bool SystemToolbox::IsRegularFile(const std::string& path) { - namespace fs = boost::filesystem; - try { - if (fs::exists(path)) + if (boost::filesystem::exists(path)) { - fs::file_status status = fs::status(path); + boost::filesystem::file_status status = boost::filesystem::status(path); return (status.type() == boost::filesystem::regular_file || status.type() == boost::filesystem::reparse_file); // Fix BitBucket issue #11 } } - catch (fs::filesystem_error&) + catch (boost::filesystem::filesystem_error&) { }