VTK  9.7.1
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 <cassert>
12 #include <limits>
13 #include <memory>
14 #include <sstream>
15 #include <string>
16 #include <vector>
17 
18 namespace ensight_gold
19 {
20 VTK_ABI_NAMESPACE_BEGIN
21 
22 constexpr int MAX_LINE_LENGTH = 80;
23 // This is half the precision of an int.
24 constexpr int MAXIMUM_PART_ID = 65536;
25 
26 enum class FileType
27 {
28  Unknown,
29  ASCII,
30  CBinary,
31  FBinary
32 };
33 
34 enum class Endianness
35 {
36  Unknown,
37  Little,
38  Big
39 };
40 
42 {
44  std::vector<int> FileNameNumbers;
45  std::vector<double> TimeValues;
46 };
47 
48 using TimeSetInfoMapType = std::map<int, std::shared_ptr<TimeSetInfo>>;
49 
51 {
52  std::vector<int> NumberOfSteps;
53  std::vector<int> FileNameIndex;
54  std::vector<int> TimeStepIndexInFile;
55 };
56 
57 using FileSetInfoMapType = std::map<int, std::shared_ptr<FileSetInfo>>;
58 
64 {
67  int TimeSet = -1;
68  int FileSet = -1;
69  bool InBlockRead = false;
70 
71  EnSightFile();
72  ~EnSightFile();
73 
80  bool SetFileNamePattern(const std::string& filename, bool isCaseFile = false);
81 
85  void SetTimeAndFileSetInfo(int timeSet, int fileSet);
86 
90  void SetTimeSetInfo(std::shared_ptr<TimeSetInfo> info);
91  std::shared_ptr<TimeSetInfo> GetTimeSetInfo() { return this->TimeInfo; }
92 
96  void SetFileSetInfo(std::shared_ptr<FileSetInfo> info);
97 
106  bool SetTimeStepToRead(double ts);
107 
114 
120 
127 
132  std::pair<bool, std::string> ReadNextLine(int size = MAX_LINE_LENGTH);
133 
137  std::pair<bool, std::string> ReadLine(int size = MAX_LINE_LENGTH);
138 
144 
151  void SkipNLines(vtkIdType n);
152 
160  template <typename T>
161  void SkipNNumbers(vtkIdType n, int numsPerLine = 1);
162 
166  void GoBackOneLine();
167 
171  bool DetectByteOrder(int* result);
172 
176  template <typename T>
177  bool ReadNumber(T* result, bool padBeginning = true, bool padEnd = true);
178 
187  template <typename T>
188  bool ReadArray(
189  T* result, vtkIdType n, bool singleLine = false, bool padBeginning = true, bool padEnd = true);
190 
194  void MoveReadPosition(vtkTypeInt64 numBytes);
195 
199  std::streampos GetCurrentPosition();
200 
206 
211  bool OpenFile(const std::string& filename, bool isCaseFile = false);
212  bool OpenFile(bool isCaseFile = false);
213 
214 private:
215  std::string FileNamePattern;
216  std::string CurrentOpenFileName;
217  std::shared_ptr<TimeSetInfo> TimeInfo;
218  std::shared_ptr<FileSetInfo> FileInfo;
219 
220  // This map keeps track of the positions in the file
221  // where time steps begin
222  // file index to the vector of positions for that file
223  std::map<int, std::vector<std::streampos>> TimeStepBeginPositions;
224  int CurrentFileIndex = -1;
225 
226  int TimeStepIndex = -1;
227 
228  vtksys::ifstream* Stream;
229  bool HasBinaryHeader = false;
230  int FortranSkipBytes = 0;
231 
235  void ResetFile();
236 
240  void CloseFile();
241 
245  void MoveToPosition(std::streampos pos);
246 };
247 
248 template <typename T>
249 int getNumChars();
250 
251 template <typename T>
252 bool stringTo(const std::string& input, T& output);
253 
254 //------------------------------------------------------------------------------
255 template <typename T>
256 void EnSightFile::SkipNNumbers(vtkIdType n, int numsPerLine /* = 1 */)
257 {
258  // for ascii, n is number of numeric lines to skip
259  if (this->Format == FileType::ASCII)
260  {
261  // this->SkipNLines(n);
262  // so this format has max of 10 digits for integers
263  // for float, 12 characters total
264  // there's also white space allowed between numbers
265  int size = getNumChars<T>() * numsPerLine + 10 * numsPerLine;
266  vtkIdType lineIdx = 0;
267  while (lineIdx < n)
268  {
269  auto result = this->ReadLine(size);
270  lineIdx++;
271  if (!result.first)
272  {
273  vtkGenericWarningMacro("SkipNNumbers() the full ascii line was not read");
274  }
275  }
276  }
277  else
278  {
279  vtkTypeInt64 numBytes = n * sizeof(T) + this->FortranSkipBytes * 2;
280  this->MoveReadPosition(numBytes);
281  }
282 }
283 
284 //------------------------------------------------------------------------------
285 template <typename T>
286 bool EnSightFile::ReadNumber(T* result, bool padBeginning /* = true*/, bool padEnd /* = true*/)
287 {
288  if (this->Format == FileType::ASCII)
289  {
290  auto line = this->ReadNextLine();
291  stringTo(line.second, *result);
292  }
293  else
294  {
295  if (padBeginning)
296  {
297  assert(!this->InBlockRead);
298  this->MoveReadPosition(this->FortranSkipBytes);
299  }
300  if (!this->Stream->read((char*)result, sizeof(T)))
301  {
302  vtkGenericWarningMacro("read failed");
303  return false;
304  }
305  if (padEnd)
306  {
307  assert(!this->InBlockRead);
308  this->MoveReadPosition(this->FortranSkipBytes);
309  }
310  if (this->ByteOrder == Endianness::Little)
311  {
312  vtkByteSwap::Swap4LE(result);
313  }
314  else if (this->ByteOrder == Endianness::Big)
315  {
316  vtkByteSwap::Swap4BE(result);
317  }
318  }
319  return true;
320 }
321 
322 //------------------------------------------------------------------------------
323 template <typename T>
324 bool EnSightFile::ReadArray(T* result, vtkIdType n, bool singleLine /* = false*/,
325  bool padBeginning /* = true*/, bool padEnd /* = true*/)
326 {
327  if (n <= 0)
328  {
329  return true;
330  }
331 
332  if (this->Format == FileType::ASCII)
333  {
334  if (!singleLine)
335  {
336  for (int i = 0; i < n; i++)
337  {
338  this->ReadNumber(&result[i]);
339  }
340  }
341  else
342  {
343  int size = getNumChars<T>() * n + 10 * n;
344  auto lineResult = this->ReadLine(size);
345  if (!lineResult.first)
346  {
347  vtkGenericWarningMacro("ReadArray() the full ascii line was not read");
348  }
349 
350  std::stringstream ss(lineResult.second);
351  for (int i = 0; i < n; i++)
352  {
353  ss >> result[i];
354  }
355  }
356  }
357  else
358  {
359  // In some cases we want to read everything in a single fortran
360  // read into a single array, but sometimes we don't want to, so
361  // we have to handle the skip bytes appropriately
362  if (padBeginning && this->FortranSkipBytes > 0)
363  {
364  this->MoveReadPosition(this->FortranSkipBytes);
365  }
366  if (!this->Stream->read((char*)result, sizeof(T) * n))
367  {
368  vtkGenericWarningMacro("read array failed");
369  return false;
370  }
371  if (padEnd && this->FortranSkipBytes > 0)
372  {
373  this->MoveReadPosition(this->FortranSkipBytes);
374  }
375  if (this->ByteOrder == Endianness::Little)
376  {
377  vtkByteSwap::Swap4LERange(result, n);
378  }
379  else if (this->ByteOrder == Endianness::Big)
380  {
381  vtkByteSwap::Swap4BERange(result, n);
382  }
383  }
384  return true;
385 }
386 
387 VTK_ABI_NAMESPACE_END
388 } // end namespace ensight_gold
389 
390 #endif // end EnSightFile_h
void SetFileSetInfo(std::shared_ptr< FileSetInfo > info)
Set the file set info.
void MoveReadPosition(vtkTypeInt64 numBytes)
Move the read position ahead n bytes.
int GetCurrentOpenTimeStep()
This is used when change_coords_only is set, for determining if the file we currently have open is th...
static void Swap4LERange(void *p, size_t num)
Swap a block of 2-, 4-, or 8-byte segments for storage as Little Endian.
static void Swap4BE(void *p)
Swap 2, 4, or 8 bytes for storage as Big Endian.
int vtkIdType
Definition: vtkType.h:363
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...
std::map< int, std::shared_ptr< TimeSetInfo >> TimeSetInfoMapType
Definition: EnSightFile.h:48
void SetTimeSetInfo(std::shared_ptr< TimeSetInfo > info)
Set the time set info.
bool SetFileNamePattern(const std::string &filename, bool isCaseFile=false)
Set the filename.
constexpr int MAX_LINE_LENGTH
Definition: EnSightFile.h:22
std::vector< int > FileNameIndex
Definition: EnSightFile.h:53
std::vector< int > NumberOfSteps
Definition: EnSightFile.h:52
bool ReadNumber(T *result, bool padBeginning=true, bool padEnd=true)
Read a number from file and store it in result.
Definition: EnSightFile.h:286
static void Swap4BERange(void *p, size_t num)
Swap a block of 2-, 4-, or 8-byte segments for storage as Big Endian.
bool DetectByteOrder(int *result)
Attempts to determine the byte order given an int read from the file.
std::vector< double > TimeValues
Definition: EnSightFile.h:45
void CheckForBeginTimeStepLine()
Checks for a BEGIN TIME STEP line and ensures the file is at the correct position to continue reading...
void SetTimeAndFileSetInfo(int timeSet, int fileSet)
Set the time and file set ids.
std::pair< bool, std::string > ReadLine(int size=MAX_LINE_LENGTH)
Reads the next line up to size characters (ASCII) or size characters (binary)
bool OpenFile(const std::string &filename, bool isCaseFile=false)
Opens the file and performs some processing to determine the format of the file.
EnSightFile performs processing on a single file, whether it's a case file, geometry, etc.
Definition: EnSightFile.h:63
void SkipNLines(vtkIdType n)
Skip the specified number of non-numeric lines when reading.
std::vector< int > FileNameNumbers
Definition: EnSightFile.h:44
void SkipLine(vtkTypeInt64 size=std::numeric_limits< std::streamsize >::max())
Ignore the the next characters until either the line end delimiter is met or size characters have bee...
std::vector< int > TimeStepIndexInFile
Definition: EnSightFile.h:54
bool SetTimeStepToRead(double ts)
Set the time step to read.
std::shared_ptr< TimeSetInfo > GetTimeSetInfo()
Definition: EnSightFile.h:91
std::map< int, std::shared_ptr< FileSetInfo >> FileSetInfoMapType
Definition: EnSightFile.h:57
bool CheckForEndTimeStepLine()
Checks for a END TIME STEP line.
int getNumChars()
constexpr int MAXIMUM_PART_ID
Definition: EnSightFile.h:24
std::streampos GetCurrentPosition()
Get current position of reader in stream.
bool CheckForMultipleTimeSteps()
Checks if this file has multiple time steps or not.
void GoBackOneLine()
Move the read position of the file stream back by MAX_LINE_LENGTH characters.
bool ReadArray(T *result, vtkIdType n, bool singleLine=false, bool padBeginning=true, bool padEnd=true)
Read an array of size n.
Definition: EnSightFile.h:324
void SkipNNumbers(vtkIdType n, int numsPerLine=1)
Skip the specified number of numbers when reading.
Definition: EnSightFile.h:256
static void Swap4LE(void *p)
Swap 2, 4, or 8 bytes for storage as Little Endian.
#define max(a, b)
bool stringTo(const std::string &input, T &output)