Mantid
Loading...
Searching...
No Matches
FileDescriptor.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
9
10#include <filesystem>
11#include <stdexcept>
12
13namespace Mantid::Kernel {
14//----------------------------------------------------------------------------------------------
15// Public static methods
16//----------------------------------------------------------------------------------------------
28bool FileDescriptor::isAscii(const std::string &filename, const size_t nbytes) {
29 std::ifstream dataStream(filename.c_str(), std::ios::in | std::ios::binary);
30 if (!dataStream) {
31 throw std::invalid_argument("FileDescriptor::isAscii() - Unable to open file '" + filename + "'");
32 }
33 return FileDescriptor::isAscii(dataStream, nbytes);
34}
35
49bool FileDescriptor::isAscii(std::istream &data, const size_t nbytes) {
50 const std::streampos startPos = data.tellg();
51 char byte('\0');
52 size_t counter(0);
53 bool result(true);
54 while (counter < nbytes) {
55 data >> byte;
56 if (!data) // reading error
57 {
58 data.clear();
59 break;
60 }
61 auto ch = static_cast<unsigned long>(byte);
62 if (!(ch <= 0x7F)) // non-ascii
63 {
64 result = false;
65 break;
66 }
67 ++counter;
68 }
69
70 data.seekg(startPos);
71 return result;
72}
73
80bool FileDescriptor::isAscii(FILE *file, const size_t nbytes) {
81 // read the data and reset the seek index back to the beginning
82 auto dataArray = new char[nbytes];
83 const char *pend = &dataArray[fread(dataArray, 1, nbytes, file)];
84 int retval = fseek(file, 0, SEEK_SET);
85 if (retval < 0)
86 throw std::runtime_error("FileDescriptor::isAscii - Cannot change position "
87 "to the beginning of the file with fseek");
88
89 // Call it a binary file if we find a non-ascii character in the
90 // first nbytes bytes of the file.
91 bool result = true;
92 for (char *p = dataArray; p < pend; ++p) {
93 auto ch = static_cast<unsigned long>(*p);
94 if (!(ch <= 0x7F)) {
95 result = false;
96 break;
97 }
98 }
99 delete[] dataArray;
100
101 return result;
102}
103
109bool FileDescriptor::isEmpty(const std::string &filename) {
110 std::ifstream file(filename.c_str());
111
112 if (!file) {
113 throw std::invalid_argument("FileDescriptor::isEmpty() - Unable to open file '" + filename + "'");
114 }
115
116 return file.peek() == std::ifstream::traits_type::eof();
117}
118
119//----------------------------------------------------------------------------------------------
120// Public methods
121//----------------------------------------------------------------------------------------------
122
128FileDescriptor::FileDescriptor(const std::string &filename) : m_filename(), m_extension(), m_file(), m_ascii(false) {
129 if (filename.empty()) {
130 throw std::invalid_argument("FileDescriptor() - Empty filename '" + filename + "'");
131 }
132 if (!std::filesystem::exists(filename)) {
133 throw std::invalid_argument("FileDescriptor() - File '" + filename + "' does not exist");
134 }
136}
137
142
149 m_file.close(); // reset all flags
150 // If the stream was closed, reopen it
151 if (!m_file.is_open()) {
152 m_file.open(m_filename.c_str(), std::ios::in | std::ios::binary);
153 } else {
154 m_file.seekg(0);
155 }
156}
157
166bool FileDescriptor::isXML() const { return (this->isAscii() && this->extension() == ".xml"); }
167
168//----------------------------------------------------------------------------------------------
169// Private methods
170//----------------------------------------------------------------------------------------------
171
176void FileDescriptor::initialize(const std::string &filename) {
178 m_extension = Mantid::Kernel::Strings::toLower(std::filesystem::path(filename).extension().string());
179
180 m_file.open(m_filename.c_str(), std::ios::in | std::ios::binary);
181 if (!m_file)
182 throw std::runtime_error("FileDescriptor::initialize - Cannot open file '" + filename + "' for reading");
183
185}
186
187} // namespace Mantid::Kernel
std::string m_extension
Extension.
bool isAscii() const
Returns true if the descriptor is looking at an ascii file.
void resetStreamToStart()
Reset the file stream to the start of the file.
static bool isEmpty(const std::string &filename)
Returns true if the file is empty.
FileDescriptor()=delete
Disable default constructor.
const std::string & filename() const
Access the filename.
void initialize(const std::string &filename)
Open the file and cache description elements.
std::istream & data()
Access the open file stream.
bool isXML() const
Returns true if the descriptor is looking at an XML file.
const std::string & extension() const
Access the file extension.
std::string m_filename
Full filename.
bool m_ascii
Flag indicating the file is pure ascii.
std::ifstream m_file
Open file stream.
MANTID_KERNEL_DLL std::string toLower(const std::string &input)
Converts string to all lowercase.
Definition Strings.cpp:129