IFstream.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2017-2024 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "IFstream.H"
30 #include "OSspecific.H" // For isFile(), fileSize()
31 
32 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33 
34 namespace Foam
35 {
37 }
38 
39 
40 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
41 
44 {
45  DynamicList<char> buffer;
46 
47  const auto inputSize = ifs.fileSize();
48 
49  if (inputSize <= 0)
50  {
51  // Nothing to read
52  }
53  else if (IOstreamOption::COMPRESSED == ifs.compression())
54  {
55  auto& iss = ifs.stdStream();
56 
57  // For compressed files, no idea how large the result will be.
58  // So read chunk-wise.
59  // Using the compressed size for the chunk size:
60  // 50% compression = 2 iterations
61  // 66% compression = 3 iterations
62  // ...
63 
64  const uint64_t chunkSize =
65  (
66  (inputSize <= 1024)
67  ? uint64_t(4096)
68  : uint64_t(2*inputSize)
69  );
70 
71  uint64_t beg = 0;
72 
73  for (int iter = 1; iter < 100000; ++iter)
74  {
75  // Manual resizing to use incremental vs doubling
76  buffer.setCapacity(label(iter * chunkSize));
77  buffer.resize(buffer.capacity());
78 
79  ifs.readRaw(buffer.data() + beg, chunkSize);
80  const std::streamsize nread = iss.gcount();
81 
82  if
83  (
84  nread < 0
86  )
87  {
88  // Failed, but treat as normal 'done'
89  buffer.resize(label(beg));
90  break;
91  }
92  else
93  {
94  beg += uint64_t(nread);
95  if (nread >= 0 && uint64_t(nread) < chunkSize)
96  {
97  // normalExit = true;
98  buffer.resize(label(beg));
99  break;
100  }
101  }
102  }
103  }
104  else
105  {
106  // UNCOMPRESSED
107  {
108  auto& iss = ifs.stdStream();
109 
110  buffer.setCapacity(label(inputSize));
111  buffer.resize(buffer.capacity());
112 
113  ifs.readRaw(buffer.data(), buffer.size_bytes());
114  const std::streamsize nread = iss.gcount();
115 
116  if
117  (
118  nread < 0
120  )
121  {
122  // Failed, but treat as normal 'done'
123  buffer.clear();
124  }
125  else
126  {
127  buffer.resize(label(nread)); // Safety
128  }
129  }
130  }
131 
132  return buffer;
133 }
134 
135 
137 Foam::IFstream::readContents(const fileName& pathname)
138 {
139  if (!pathname.empty())
140  {
141  IFstream ifs(pathname, IOstreamOption::BINARY);
142 
143  if (ifs.good())
144  {
145  return readContents(ifs);
146  }
147  }
148 
150 }
151 
152 
153 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
154 
156 (
157  const fileName& pathname,
158  IOstreamOption streamOpt
159 )
160 :
161  Foam::ifstreamPointer(pathname, streamOpt),
162  ISstream(*(ifstreamPointer::get()), pathname, streamOpt)
163 {
165 
166  setClosed();
167 
168  setState(ifstreamPointer::get()->rdstate());
169 
170  if (good())
171  {
172  setOpened();
173  }
174  else
175  {
176  setBad();
177  }
178 
179  lineNumber_ = 1;
180 
181  if (debug)
182  {
183  if (pathname.empty())
184  {
186  << "Cannot open empty file name"
187  << Foam::endl;
188  }
190  {
192  << "Decompressing " << (this->name() + ".gz") << Foam::endl;
193  }
194 
195  if (!opened())
196  {
198  << "Could not open file " << pathname
199  << " for input\n" << info() << Foam::endl;
200  }
201  }
202 }
203 
204 
205 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
206 
207 std::streamsize Foam::IFstream::fileSize() const
208 {
209  const std::istream* ptr = ifstreamPointer::get();
210 
211  if (!ptr || this->name().empty())
212  {
213  return std::streamsize(-1);
214  }
215 
216  off_t fileLen = -1;
217 
219  {
220  fileLen = Foam::fileSize(this->name() + ".gz");
221  }
222  else
223  {
224  // TBD: special handing for wrapped icharstream
225  // if
226  // (
227  // const Foam::icharstream* charstr
228  // = dynamic_cast<const Foam::icharstream*>(ptr)>(ptr)
229  // )
230  // {
231  // return charstr->capacity();
232  // }
233 
234  fileLen = Foam::fileSize(this->name());
235  }
236 
237  if (fileLen >= 0)
238  {
239  return std::streamsize(fileLen);
240  }
241 
242  return std::streamsize(-1);
243 }
244 
245 
246 std::istream& Foam::IFstream::stdStream()
247 {
248  std::istream* ptr = ifstreamPointer::get();
249 
250  if (!ptr)
251  {
253  << "No stream allocated\n"
255  }
256 
257  return *ptr;
258 }
259 
260 
261 const std::istream& Foam::IFstream::stdStream() const
262 {
263  const std::istream* ptr = ifstreamPointer::get();
264 
265  if (!ptr)
266  {
268  << "No stream allocated\n"
270  }
271 
272  return *ptr;
273 }
274 
275 
277 {
279  {
280  lineNumber_ = 1; // Reset line number
282  setState(ifstreamPointer::get()->rdstate());
283  }
284  else
285  {
287  }
288 }
289 
290 
291 void Foam::IFstream::print(Ostream& os) const
292 {
293  os << "IFstream: ";
295 }
296 
297 
298 // * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
299 
301 {
302  if (!good())
303  {
304  // Also checks .gz file
305  if (Foam::isFile(this->name(), true))
306  {
308  FatalIOError.exit();
309  }
310  else
311  {
313  << "File " << this->name() << " does not exist"
314  << exit(FatalIOError);
315  }
316  }
317 
318  return const_cast<IFstream&>(*this);
319 }
320 
321 
322 // ************************************************************************* //
List< ReturnType > get(const UPtrList< T > &list, const AccessOp &aop)
List of values generated by applying the access operation to each list item.
label lineNumber_
The file line.
Definition: IOstream.H:140
A wrapped std::ifstream with possible compression handling (igzstream) that behaves much like a std::...
bool opened() const noexcept
True if stream has been opened.
Definition: IOstream.H:265
IFstream(const fileName &pathname, IOstreamOption streamOpt=IOstreamOption())
Construct from pathname, default or specified stream options.
Definition: IFstream.C:149
virtual Istream & readRaw(char *data, std::streamsize count) override
Low-level raw binary read (without possible block delimiters). Reading into a null pointer behaves li...
Definition: ISstream.C:1037
A class for handling file names.
Definition: fileName.H:72
virtual void rewind() override
Rewind the stream so that it may be read again.
Definition: ISstream.C:1078
off_t fileSize(const fileName &name, const bool followLink=true)
Return size of file or -1 on failure (normally follows symbolic links).
Definition: POSIX.C:905
void setClosed() noexcept
Set stream closed.
Definition: IOstream.H:158
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:608
void setState(std::ios_base::iostate state) noexcept
Set stream state.
Definition: IOstream.H:166
IOstreamOption::compressionType whichCompression() const
Which compression type?
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:40
T * data() noexcept
Return pointer to the underlying array serving as data storage.
Definition: UListI.H:265
void resize(const label len)
Alter addressable list size, allocating new space if required while recovering old content...
Definition: DynamicListI.H:353
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
InfoProxy< IOstream > info() const noexcept
Return info proxy, used to print IOstream information to a stream.
Definition: IOstream.H:532
void reopen_gz(const std::string &pathname)
Special &#39;rewind&#39; method for compressed stream.
void setCapacity(const label len)
Alter the size of the underlying storage.
Definition: DynamicListI.H:303
A simple container for options an IOstream can normally have.
label capacity() const noexcept
Size of the underlying storage.
Definition: DynamicList.H:225
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
virtual void rewind() override
Rewind the stream so that it may be read again.
Definition: IFstream.C:269
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
std::istream * get() noexcept
The stream pointer (ifstream or igzstream)
virtual const fileName & name() const override
The name of the input serial stream. (eg, the name of the Fstream file name)
Definition: ISstream.H:147
errorManip< error > abort(error &err)
Definition: errorManip.H:139
virtual std::istream & stdStream() override
Access to underlying std::istream.
Definition: IFstream.C:239
void exit(const int errNo=1)
Exit : can be called for any error to exit program.
Definition: IOerror.C:240
int debug
Static debugging option.
OBJstream os(runTime.globalPath()/outputName)
#define FUNCTION_NAME
defineTypeNameAndDebug(combustionModel, 0)
compressionType compression() const noexcept
Get the stream compression.
Input from file stream as an ISstream, normally using std::ifstream for the actual input...
Definition: IFstream.H:51
static void check(const int retVal, const char *what)
void clear() noexcept
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicListI.H:405
std::streamsize fileSize() const
Return the size of the underlying file (-1 on error). This corresponds to Foam::fileSize() but with e...
Definition: IFstream.C:200
bool isFile(const fileName &name, const bool checkGzip=true, const bool followLink=true)
Does the name exist as a FILE in the file system?
Definition: POSIX.C:877
Generic input stream using a standard (STL) stream.
Definition: ISstream.H:51
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:637
bool good() const noexcept
True if next operation might succeed.
Definition: IOstream.H:281
static DynamicList< char > readContents(const fileName &pathname)
Get file contents from specified file (compressed/uncompressed). Returns an empty list if the file ca...
Definition: IFstream.C:130
IFstream & operator()() const
Return a non-const reference to const IFstream.
Definition: IFstream.C:293
void setOpened() noexcept
Set stream opened.
Definition: IOstream.H:150
virtual void print(Ostream &os) const override
Print stream description.
Definition: IFstream.C:284
virtual void print(Ostream &os) const override
Print stream description to Ostream.
Definition: SstreamsPrint.C:30
std::streamsize size_bytes() const noexcept
Number of contiguous bytes for the List data.
Definition: UListI.H:286
void setBad() noexcept
Set stream state to be &#39;bad&#39;.
Definition: IOstream.H:469
Namespace for OpenFOAM.
IOerror FatalIOError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL IO ERROR&#39; header text and ...
#define InfoInFunction
Report an information message using Foam::Info.