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 <Poco/File.h>
11#include <Poco/Path.h>
12
13#include <stdexcept>
14
15namespace Mantid::Kernel {
16//----------------------------------------------------------------------------------------------
17// Public static methods
18//----------------------------------------------------------------------------------------------
30bool FileDescriptor::isAscii(const std::string &filename, const size_t nbytes) {
31 std::ifstream data(filename.c_str(), std::ios::in | std::ios::binary);
32 if (!data) {
33 throw std::invalid_argument("FileDescriptor::isAscii() - Unable to open file '" + filename + "'");
34 }
35 return FileDescriptor::isAscii(data, nbytes);
36}
37
51bool FileDescriptor::isAscii(std::istream &data, const size_t nbytes) {
52 const std::streampos startPos = data.tellg();
53 char byte('\0');
54 size_t counter(0);
55 bool result(true);
56 while (counter < nbytes) {
57 data >> byte;
58 if (!data) // reading error
59 {
60 data.clear();
61 break;
62 }
63 auto ch = static_cast<unsigned long>(byte);
64 if (!(ch <= 0x7F)) // non-ascii
65 {
66 result = false;
67 break;
68 }
69 ++counter;
70 }
71
72 data.seekg(startPos);
73 return result;
74}
75
82bool FileDescriptor::isAscii(FILE *file, const size_t nbytes) {
83 // read the data and reset the seek index back to the beginning
84 auto data = new char[nbytes];
85 char *pend = &data[fread(data, 1, nbytes, file)];
86 int retval = fseek(file, 0, SEEK_SET);
87 if (retval < 0)
88 throw std::runtime_error("FileDescriptor::isAscii - Cannot change position "
89 "to the beginning of the file with fseek");
90
91 // Call it a binary file if we find a non-ascii character in the
92 // first nbytes bytes of the file.
93 bool result = true;
94 for (char *p = data; p < pend; ++p) {
95 auto ch = static_cast<unsigned long>(*p);
96 if (!(ch <= 0x7F)) {
97 result = false;
98 break;
99 }
100 }
101 delete[] data;
102
103 return result;
104}
105
111bool FileDescriptor::isEmpty(const std::string &filename) {
112 std::ifstream file(filename.c_str());
113
114 if (!file) {
115 throw std::invalid_argument("FileDescriptor::isEmpty() - Unable to open file '" + filename + "'");
116 }
117
118 return file.peek() == std::ifstream::traits_type::eof();
119}
120
121//----------------------------------------------------------------------------------------------
122// Public methods
123//----------------------------------------------------------------------------------------------
124
130FileDescriptor::FileDescriptor(const std::string &filename) : m_filename(), m_extension(), m_file(), m_ascii(false) {
131 if (filename.empty()) {
132 throw std::invalid_argument("FileDescriptor() - Empty filename '" + filename + "'");
133 }
134 if (!Poco::File(filename).exists()) {
135 throw std::invalid_argument("FileDescriptor() - File '" + filename + "' does not exist");
136 }
138}
139
144
151 m_file.close(); // reset all flags
152 // If the stream was closed, reopen it
153 if (!m_file.is_open()) {
154 m_file.open(m_filename.c_str(), std::ios::in | std::ios::binary);
155 } else {
156 m_file.seekg(0);
157 }
158}
159
168bool FileDescriptor::isXML() const { return (this->isAscii() && this->extension() == ".xml"); }
169
170//----------------------------------------------------------------------------------------------
171// Private methods
172//----------------------------------------------------------------------------------------------
173
178void FileDescriptor::initialize(const std::string &filename) {
180 m_extension = Mantid::Kernel::Strings::toLower("." + Poco::Path(filename).getExtension());
181
182 m_file.open(m_filename.c_str(), std::ios::in | std::ios::binary);
183 if (!m_file)
184 throw std::runtime_error("FileDescriptor::initialize - Cannot open file '" + filename + "' for reading");
185
187}
188
189} // 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.
bool exists(::NeXus::File &file, const std::string &name)
Based on the current group in the file, does the named sub-entry exist?
MANTID_KERNEL_DLL std::string toLower(const std::string &input)
Converts string to all lowercase.
Definition: Strings.cpp:116