VTK  9.5.20250805
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
18namespace ensight_gold
19{
20VTK_ABI_NAMESPACE_BEGIN
21
22constexpr int MAX_LINE_LENGTH = 80;
23// This is half the precision of an int.
24constexpr int MAXIMUM_PART_ID = 65536;
25
26enum class FileType
27{
28 Unknown,
29 ASCII,
30 CBinary,
32};
33
34enum class Endianness
35{
36 Unknown,
37 Little,
38 Big
39};
40
42{
44 std::vector<int> FileNameNumbers;
45 std::vector<double> TimeValues;
46};
47
48using 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
57using FileSetInfoMapType = std::map<int, std::shared_ptr<FileSetInfo>>;
58
64{
67 int TimeSet = -1;
68 int FileSet = -1;
69 bool InBlockRead = false;
70
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
143 void SkipLine(vtkTypeInt64 size = std::numeric_limits<std::streamsize>::max());
144
152
160 template <typename T>
161 void SkipNNumbers(vtkIdType n, int numsPerLine = 1);
162
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
214private:
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
248template <typename T>
250
251template <typename T>
252bool stringTo(const std::string& input, T& output);
253
254//------------------------------------------------------------------------------
255template <typename T>
256void 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//------------------------------------------------------------------------------
285template <typename T>
286bool 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//------------------------------------------------------------------------------
323template <typename T>
324bool 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
387VTK_ABI_NAMESPACE_END
388} // end namespace ensight_gold
389
390#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:48
int getNumChars()
constexpr int MAXIMUM_PART_ID
Definition EnSightFile.h:24
std::map< int, std::shared_ptr< FileSetInfo > > FileSetInfoMapType
Definition EnSightFile.h:57
constexpr int MAX_LINE_LENGTH
Definition EnSightFile.h:22
EnSightFile performs processing on a single file, whether it's a case file, geometry,...
Definition EnSightFile.h:64
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:91
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 MoveReadPosition(vtkTypeInt64 numBytes)
Move the read position ahead n bytes.
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.
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...
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.
bool DetectByteOrder(int *result)
Attempts to determine the byte order given an int read from the file.
std::vector< int > FileNameIndex
Definition EnSightFile.h:53
std::vector< int > TimeStepIndexInFile
Definition EnSightFile.h:54
std::vector< int > NumberOfSteps
Definition EnSightFile.h:52
std::vector< int > FileNameNumbers
Definition EnSightFile.h:44
std::vector< double > TimeValues
Definition EnSightFile.h:45
int vtkIdType
Definition vtkType.h:332