Mercurial > hg > orthanc
diff OrthancFramework/Sources/SystemToolbox.cpp @ 4342:52166629239f
SystemToolbox::ReadFileRange()
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 03 Dec 2020 18:48:06 +0100 |
parents | 785a2713323e |
children | 80fd140b12ba |
line wrap: on
line diff
--- a/OrthancFramework/Sources/SystemToolbox.cpp Thu Dec 03 18:15:47 2020 +0100 +++ b/OrthancFramework/Sources/SystemToolbox.cpp Thu Dec 03 18:48:06 2020 +0100 @@ -224,6 +224,13 @@ 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 (size != 0) { f.read(&content[0], size); @@ -807,4 +814,68 @@ return (base / relative).string(); } } + + + void SystemToolbox::ReadFileRange(std::string& content, + const std::string& path, + uint64_t start, // Inclusive + uint64_t end, // Exclusive + bool throwIfOverflow) + { + if (start > end) + { + throw OrthancException(ErrorCode_ParameterOutOfRange); + } + + if (!IsRegularFile(path)) + { + throw OrthancException(ErrorCode_RegularFileExpected, + "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()) + { + throw OrthancException(ErrorCode_InexistentFile, + "File not found: " + path); + } + + uint64_t fileSize = static_cast<uint64_t>(GetStreamSize(f)); + if (end > fileSize) + { + if (throwIfOverflow) + { + throw OrthancException(ErrorCode_ParameterOutOfRange, + "Reading beyond the end of a file"); + } + else + { + end = fileSize; + } + } + + if (start <= end) + { + content.resize(static_cast<size_t>(end - start)); + + if (static_cast<uint64_t>(content.size()) != (end - start)) + { + throw OrthancException(ErrorCode_InternalError, + "Reading a file that is too large for a 32bit architecture"); + } + + if (!content.empty()) + { + f.seekg(start, std::ios::beg); + f.read(&content[0], static_cast<std::streamsize>(content.size())); + } + } + else + { + content.clear(); + } + + f.close(); + } }