VTK  9.4.20241016
EnSightFile.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2// SPDX-License-Identifier: BSD-3-Clause
3
4#ifndef EnSightFile_h
5#define EnSightFile_h
6
7#include "vtkByteSwap.h"
8
9#include "vtksys/FStream.hxx"
10
11#include <memory>
12#include <sstream>
13#include <string>
14#include <vector>
15
16namespace ensight_gold
17{
18VTK_ABI_NAMESPACE_BEGIN
19
20constexpr int MAX_LINE_LENGTH = 80;
21// This is half the precision of an int.
22constexpr int MAXIMUM_PART_ID = 65536;
23
24enum class FileType
25{
26 Unknown,
27 ASCII,
28 CBinary,
30};
31
32enum class Endianness
33{
34 Unknown,
35 Little,
36 Big
37};
38
40{
42 std::vector<int> FileNameNumbers;
43 std::vector<double> TimeValues;
44};
45
46using TimeSetInfoMapType = std::map<int, std::shared_ptr<TimeSetInfo>>;
47
49{
50 std::vector<int> NumberOfSteps;
51 std::vector<int> FileNameIndex;
52 std::vector<int> TimeStepIndexInFile;
53};
54
55using FileSetInfoMapType = std::map<int, std::shared_ptr<FileSetInfo>>;
56
62{
65 int TimeSet = -1;
66 int FileSet = -1;
67
70
77 bool SetFileNamePattern(const std::string& filename, bool isCaseFile = false);
78
82 void SetTimeAndFileSetInfo(int timeSet, int fileSet);
83
87 void SetTimeSetInfo(std::shared_ptr<TimeSetInfo> info);
88 std::shared_ptr<TimeSetInfo> GetTimeSetInfo() { return this->TimeInfo; }
89
93 void SetFileSetInfo(std::shared_ptr<FileSetInfo> info);
94
103 bool SetTimeStepToRead(double ts);
104
111
117
124
129 std::pair<bool, std::string> ReadNextLine(int size = MAX_LINE_LENGTH);
130
134 std::pair<bool, std::string> ReadLine(int size = MAX_LINE_LENGTH);
135
143
151 template <typename T>
152 void SkipNNumbers(vtkIdType n, int numsPerLine = 1);
153
158
162 bool DetectByteOrder(int* result);
163
167 template <typename T>
168 bool ReadNumber(T* result, bool padBeginning = true, bool padEnd = true);
169
178 template <typename T>
179 bool ReadArray(
180 T* result, vtkIdType n, bool singleLine = false, bool padBeginning = true, bool padEnd = true);
181
185 void MoveReadPosition(int numBytes);
186
190 std::streampos GetCurrentPosition();
191
197
202 bool OpenFile(const std::string& filename, bool isCaseFile = false);
203 bool OpenFile(bool isCaseFile = false);
204
205private:
206 std::string FileNamePattern;
207 std::string CurrentOpenFileName;
208 std::shared_ptr<TimeSetInfo> TimeInfo;
209 std::shared_ptr<FileSetInfo> FileInfo;
210
211 // This map keeps track of the positions in the file
212 // where time steps begin
213 // file index to the vector of positions for that file
214 std::map<int, std::vector<std::streampos>> TimeStepBeginPositions;
215 int CurrentFileIndex = -1;
216
217 int TimeStepIndex = -1;
218
219 vtksys::ifstream* Stream;
220 bool HasBinaryHeader = false;
221 int FortranSkipBytes = 0;
222
226 void ResetFile();
227
231 void CloseFile();
232
236 void MoveToPosition(std::streampos pos);
237};
238
239template <typename T>
241
242template <typename T>
243bool stringTo(const std::string& input, T& output);
244
245//------------------------------------------------------------------------------
246template <typename T>
247void EnSightFile::SkipNNumbers(vtkIdType n, int numsPerLine /* = 1 */)
248{
249 // for ascii, n is number of numeric lines to skip
250 if (this->Format == FileType::ASCII)
251 {
252 // this->SkipNLines(n);
253 // so this format has max of 10 digits for integers
254 // for float, 12 characters total
255 // there's also white space allowed between numbers
256 int size = getNumChars<T>() * numsPerLine + 10 * numsPerLine;
257 int lineIdx = 0;
258 while (lineIdx < n)
259 {
260 auto result = this->ReadLine(size);
261 lineIdx++;
262 if (!result.first)
263 {
264 vtkGenericWarningMacro("SkipNNumbers() the full ascii line was not read");
265 }
266 }
267 }
268 else
269 {
270 int numBytes = n * static_cast<int>(sizeof(T)) + this->FortranSkipBytes * 2;
271 this->MoveReadPosition(numBytes);
272 }
273}
274
275//------------------------------------------------------------------------------
276template <typename T>
277bool EnSightFile::ReadNumber(T* result, bool padBeginning /* = true*/, bool padEnd /* = true*/)
278{
279 if (this->Format == FileType::ASCII)
280 {
281 auto line = this->ReadNextLine();
282 stringTo(line.second, *result);
283 }
284 else
285 {
286 if (padBeginning)
287 {
288 this->MoveReadPosition(this->FortranSkipBytes);
289 }
290 if (!this->Stream->read((char*)result, sizeof(T)))
291 {
292 vtkGenericWarningMacro("read failed");
293 return false;
294 }
295 if (padEnd)
296 {
297 this->MoveReadPosition(this->FortranSkipBytes);
298 }
299 if (this->ByteOrder == Endianness::Little)
300 {
301 vtkByteSwap::Swap4LE(result);
302 }
303 else if (this->ByteOrder == Endianness::Big)
304 {
305 vtkByteSwap::Swap4BE(result);
306 }
307 }
308 return true;
309}
310
311//------------------------------------------------------------------------------
312template <typename T>
313bool EnSightFile::ReadArray(T* result, vtkIdType n, bool singleLine /* = false*/,
314 bool padBeginning /* = true*/, bool padEnd /* = true*/)
315{
316 if (n <= 0)
317 {
318 return true;
319 }
320
321 if (this->Format == FileType::ASCII)
322 {
323 if (!singleLine)
324 {
325 for (int i = 0; i < n; i++)
326 {
327 this->ReadNumber(&result[i]);
328 }
329 }
330 else
331 {
332 int size = getNumChars<T>() * n + 10 * n;
333 auto lineResult = this->ReadLine(size);
334 if (!lineResult.first)
335 {
336 vtkGenericWarningMacro("ReadArray() the full ascii line was not read");
337 }
338
339 std::stringstream ss(lineResult.second);
340 for (int i = 0; i < n; i++)
341 {
342 ss >> result[i];
343 }
344 }
345 }
346 else
347 {
348 // In some cases we want to read everything in a single fortran
349 // read into a single array, but sometimes we don't want to, so
350 // we have to handle the skip bytes appropriately
351 if (padBeginning && this->FortranSkipBytes > 0)
352 {
353 this->MoveReadPosition(this->FortranSkipBytes);
354 }
355 if (!this->Stream->read((char*)result, sizeof(T) * n))
356 {
357 vtkGenericWarningMacro("read array failed");
358 return false;
359 }
360 if (padEnd && this->FortranSkipBytes > 0)
361 {
362 this->MoveReadPosition(this->FortranSkipBytes);
363 }
364 if (this->ByteOrder == Endianness::Little)
365 {
366 vtkByteSwap::Swap4LERange(result, n);
367 }
368 else if (this->ByteOrder == Endianness::Big)
369 {
370 vtkByteSwap::Swap4BERange(result, n);
371 }
372 }
373 return true;
374}
375
376VTK_ABI_NAMESPACE_END
377} // end namespace ensight_gold
378
379#endif // end EnSightFile_h
static void Swap4BERange(void *p, size_t num)
Swap a block of 2-, 4-, or 8-byte segments for storage as Big Endian.
static void Swap4BE(void *p)
Swap 2, 4, or 8 bytes for storage as Big Endian.
static void Swap4LE(void *p)
Swap 2, 4, or 8 bytes for storage as Little Endian.
static void Swap4LERange(void *p, size_t num)
Swap a block of 2-, 4-, or 8-byte segments for storage as Little Endian.
bool stringTo(const std::string &input, T &output)
std::map< int, std::shared_ptr< TimeSetInfo > > TimeSetInfoMapType
Definition EnSightFile.h:46
int getNumChars()
constexpr int MAXIMUM_PART_ID
Definition EnSightFile.h:22
std::map< int, std::shared_ptr< FileSetInfo > > FileSetInfoMapType
Definition EnSightFile.h:55
constexpr int MAX_LINE_LENGTH
Definition EnSightFile.h:20
EnSightFile performs processing on a single file, whether it's a case file, geometry,...
Definition EnSightFile.h:62
void SetTimeSetInfo(std::shared_ptr< TimeSetInfo > info)
Set the time set info.
std::pair< bool, std::string > ReadLine(int size=MAX_LINE_LENGTH)
Reads the next line up to size characters (ASCII) or size characters (binary)
std::shared_ptr< TimeSetInfo > GetTimeSetInfo()
Definition EnSightFile.h:88
void SetTimeAndFileSetInfo(int timeSet, int fileSet)
Set the time and file set ids.
int GetCurrentOpenTimeStep()
This is used when change_coords_only is set, for determining if the file we currently have open is th...
bool OpenFile(const std::string &filename, bool isCaseFile=false)
Opens the file and performs some processing to determine the format of the file.
void CheckForBeginTimeStepLine()
Checks for a BEGIN TIME STEP line and ensures the file is at the correct position to continue reading...
std::pair< bool, std::string > ReadNextLine(int size=MAX_LINE_LENGTH)
For ASCII files, reads the next line while skipping lines that contain only whitespace or a comment.
void SkipNNumbers(vtkIdType n, int numsPerLine=1)
Skip the specified number of numbers when reading.
std::streampos GetCurrentPosition()
Get current position of reader in stream.
bool CheckForEndTimeStepLine()
Checks for a END TIME STEP line.
bool SetTimeStepToRead(double ts)
Set the time step to read.
void GoBackOneLine()
Move the read position of the file stream back by MAX_LINE_LENGTH characters.
bool CheckForMultipleTimeSteps()
Checks if this file has multiple time steps or not.
bool ReadNumber(T *result, bool padBeginning=true, bool padEnd=true)
Read a number from file and store it in result.
bool ReadArray(T *result, vtkIdType n, bool singleLine=false, bool padBeginning=true, bool padEnd=true)
Read an array of size n.
void SkipNLines(vtkIdType n)
Skip the specified number of non-numeric lines when reading.
bool OpenFile(bool isCaseFile=false)
bool SetFileNamePattern(const std::string &filename, bool isCaseFile=false)
Set the filename.
void SetFileSetInfo(std::shared_ptr< FileSetInfo > info)
Set the file set info.
void MoveReadPosition(int numBytes)
Move the read position ahead n bytes.
bool DetectByteOrder(int *result)
Attempts to determine the byte order given an int read from the file.
std::vector< int > FileNameIndex
Definition EnSightFile.h:51
std::vector< int > TimeStepIndexInFile
Definition EnSightFile.h:52
std::vector< int > NumberOfSteps
Definition EnSightFile.h:50
std::vector< int > FileNameNumbers
Definition EnSightFile.h:42
std::vector< double > TimeValues
Definition EnSightFile.h:43
int vtkIdType
Definition vtkType.h:315