foamVtkFormatter.H
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) 2016-2025 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 Class
27  Foam::vtk::formatter
28 
29 Description
30  Abstract class for a VTK output stream formatter.
31 
32  Includes simple support for writing XML elements.
33  By default uses single-quoting for XML attributes.
34 
35 SourceFiles
36  foamVtkFormatter.C
37  foamVtkFormatterTemplates.C
38 
39 \*---------------------------------------------------------------------------*/
40 
41 #ifndef Foam_vtk_formatter_H
42 #define Foam_vtk_formatter_H
43 
44 #include "int.H"
45 #include "label.H"
46 #include "uint64.H"
47 #include "direction.H"
48 #include "word.H"
49 #include "List.H"
50 #include "DynamicList.H"
51 #include "foamVtkCore.H"
52 #include "foamVtkPTraits.H"
53 
54 #include <iostream>
55 
56 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
57 
58 namespace Foam
59 {
60 namespace vtk
61 {
62 
63 class outputOptions;
64 
65 /*---------------------------------------------------------------------------*\
66  Class vtk::formatter Declaration
67 \*---------------------------------------------------------------------------*/
68 
69 class formatter
70 {
71 public:
72 
73  //- Quoting for XML attributes
74  enum quoteChar : char
75  {
76  DOUBLE_QUOTE = '\"',
77  SINGLE_QUOTE = '\'',
78  };
79 
80 
81 protected:
82 
83  // Private Data
84 
85  //- The output stream for the formatter
86  std::ostream& os_;
87 
88  //- LIFO stack of current XML tags
90 
91  //- Tag open/closed/ended state
92  mutable bool inTag_;
93 
94  //- Quoting character for XML attributes
95  char quote_;
96 
97 
98 protected:
99 
100  // Protected Member Functions
101 
102  //- Can write XML key/value attribute pair when inside a tag.
103  //- Emit warning and return false if this condition is not met.
104  bool canWriteAttr(const word& k) const;
105 
106  //- Can write tag-like top-level content (eg, comment, ...)
107  //- when not already inside a tag.
108  //- Emit warning and return false if this condition is not met.
109  bool canWriteToplevel(const char* what) const;
110 
111  //- Write XML key/value attribute pair (implementation).
112  template<class Type>
113  inline void writeAttr(const word& k, const Type& v);
114 
115  //- No-op write XML attribute (for templating code).
116  // \return formatter for chaining
117  inline formatter& xmlAttr();
118 
119  //- Loop/output XML comments
120  template<class... Args>
121  inline void xmlCommentLoop(const std::string& text, Args&&... args);
122 
123  //- Open XML tag (implementation), checking if not already inside
124  //- another tag.
125  //- Emit warning and return false if this condition is not met.
126  bool openTagImpl(const word& tagName);
127 
128 
129  // Constructors
130 
131  //- Construct and attach to an output stream
132  inline explicit formatter(std::ostream& os);
133 
134 
135 public:
136 
137  // Public typedefs
138 
139  //- The header data is vtk UInt64
140  typedef uint64_t headerType;
141 
142  //- Out of range position or size.
143  static constexpr uint64_t npos = uint64_t(-1);
144 
145 
146  //- Destructor
147  virtual ~formatter() = default;
148 
149 
150  // Member Functions
151 
152  // Access
153 
154  //- Access to the underlying output stream
155  inline std::ostream& os() noexcept;
156 
157  //- The format-type / output options.
158  virtual const vtk::outputOptions& opts() const = 0;
159 
160  //- Name for the XML output type or the legacy output type.
161  virtual const char* name() const = 0;
163  //- Name for the XML append encoding
164  virtual const char* encoding() const = 0;
165 
166  //- Change quoting char for XML attributes (default: SINGLE_QUOTE)
167  void quoting(const quoteChar quote);
168 
169  //- Increase the append data offset by numbytes and sizeof(uint64_t).
170  // The additional (uint64_t) size information is consistent with
171  // writeSize()
172  //
173  // \return The previous data offset or formatter::npos for formats
174  // that do not support appending data.
175  virtual uint64_t offset(const uint64_t numbytes);
176 
177  //- The encoded length for binary output is pass-through.
178  virtual std::size_t encodedLength(std::size_t n) const;
179 
180  //- Write leading size for binary output
181  // \return True if used by the formatter.
182  virtual bool writeSize(const uint64_t numbytes) = 0;
183 
184  virtual void write(const uint8_t val) = 0;
185  virtual void write(const label val) = 0;
186  virtual void write(const float val) = 0;
187  virtual void write(const double val) = 0;
188 
189  //- Flush encoding, write newline etc.
190  virtual void flush() = 0;
191 
192 
193  // General Output
194 
195  //- Add indenting according to the current XML tag depth
196  // Two spaces per depth.
197  inline void indent();
198 
199  //- Add indenting of n spaces.
200  inline void indent(label n);
201 
202  //- Write XML header
203  // \return formatter for chaining
204  inline formatter& xmlHeader();
205 
206  //- Write XML comment (at the current indentation level)
207  // \return formatter for chaining
208  template<class... Args>
209  inline formatter& xmlComment(const std::string& text, Args&&... args);
210 
211 
212  //- Start an XML tag, optionally with attributes
213  // \return formatter for chaining
214  template<class... Args>
215  inline formatter& openTag(const word& tagName, Args&&... args);
216 
217  //- Start an XML tag, optionally with attributes
218  // \return formatter for chaining
219  template<class... Args>
220  inline formatter& openTag(vtk::fileTag t, Args&&... args);
221 
222  //- Finish an XML tag, optional as an empty container.
223  // Always adds a trailing newline.
224  // \return formatter for chaining
225  formatter& closeTag(const bool isEmpty = false);
226 
227  //- An end XML tag, optional with sanity check
228  // Always adds a trailing newline.
229  // \return formatter for chaining
230  formatter& endTag(const word& tagName = word::null);
231 
232  //- An end XML tag with sanity check
233  // Always adds a trailing newline.
234  // \return formatter for chaining
235  inline virtual formatter& endTag(vtk::fileTag t);
236 
237  //- Write XML tag without any attributes. Combines openTag/closeTag.
238  // \return formatter for chaining
239  template<class... Args>
240  inline formatter& tag(const word& t, Args&&... args);
241 
242  //- Write XML tag without any attributes. Combines openTag/closeTag.
243  // \return formatter for chaining
244  template<class... Args>
245  inline formatter& tag(vtk::fileTag t, Args&&... args);
246 
247 
248  //- Add a "VTKFile" XML tag for contentType, followed by a tag for
249  //- the contentType itself.
250  // \param leaveOpen Leave tag open for additional attributes.
251  // \return formatter for chaining
253  (
254  const word& contentType,
255  const word& contentVersion,
256  const bool leaveOpen = false
257  );
258 
259  //- Add a "VTKFile" XML tag for contentType, followed by a tag for
260  //- the contentType itself.
261  // \param leaveOpen Leave tag open for additional attributes.
262  // \return formatter for chaining
263  inline formatter& beginVTKFile
264  (
265  vtk::fileTag contentType,
266  const word& contentVersion,
267  const bool leaveOpen = false
268  );
269 
270  //- Add a "VTKFile" XML tag for contentType, followed by a tag for
271  //- the contentType itself.
272  // \param leaveOpen Leave tag open for additional attributes.
273  // \return formatter for chaining
274  inline formatter& beginVTKFile
275  (
276  vtk::fileTag contentType,
277  const bool leaveOpen = false
278  );
279 
280  //- Add a "VTKFile" XML tag for contentType, followed by a tag for
281  //- the contentType itself.
282  // \param leaveOpen Leave tag open for additional attributes.
283  // \return formatter for chaining
284  template<vtk::fileTag ContentType>
285  inline formatter& beginVTKFile(bool leaveOpen = false);
286 
287  //- Add a "AppendedData" XML tag with the current encoding and output
288  //- the requisite '_' prefix.
289  // \return formatter for chaining
291 
292  //- Begin "Block" XML section.
293  // \param index The index of the block
294  // \param name The name of the block (ignored if empty)
295  // \return formatter for chaining
296  formatter& beginBlock(label index, std::string name = "");
297 
298  //- End "Block" XML section.
299  // \return formatter for chaining
300  inline formatter& endBlock();
301 
302  //- Begin "Piece" XML section.
303  // \param index The index of the piece
304  // \param name The name of the piece (ignored if empty)
305  // \return formatter for chaining
306  formatter& beginPiece(label index, std::string name = "");
307 
308  //- End "Piece" XML section.
309  // \return formatter for chaining
310  inline virtual formatter& endPiece();
311 
312  //- Insert a single "DataSet" XML entry tag.
313  // \param index The index of the DataSet
314  // \param file The file name for the data (ignored if empty)
315  // \param autoName The name for the data extracted from the file name
316  // (without extension)
317  // \return formatter for chaining
319  (
320  label index,
321  std::string file = "",
322  bool autoName = true
323  );
324 
325  //- Insert a single "DataSet" XML entry tag.
326  // \param index The index of the DataSet
327  // \param file The file name for the data (ignored if empty)
328  // \param name The name for the dataset
329  // \return formatter for chaining
331  (
332  label index,
333  std::string file,
334  std::string name
335  );
336 
337  //- Begin "DataArray" XML section.
338  //
339  // \param dataName The name of the DataArray
340  // \param payLoad Additional payLoad information to increment
341  // the offset for an append formatter and add the "offset"
342  // attribute accordingly.
343  // \param leaveOpen Leave tag open for additional attributes.
344  //
345  // \return formatter for chaining
346  template<class Type, direction nComp=1, int nTuple=0>
348  (
349  const word& dataName,
350  uint64_t payLoad = npos,
351  bool leaveOpen = false
352  );
353 
354  //- Begin "DataArray" XML section.
355  //
356  // \param dataName The name of the DataArray as an enumeration
357  // \param payLoad Additional payLoad information to increment
358  // the offset for an append formatter and add the "offset"
359  // attribute accordingly.
360  // \param leaveOpen Leave tag open for additional attributes.
361  //
362  // \return formatter for chaining
363  template<class Type, direction nComp=1, int nTuple=0>
364  inline formatter& beginDataArray
365  (
366  const vtk::dataArrayAttr& dataName,
367  uint64_t payLoad = npos,
368  bool leaveOpen = false
369  );
370 
371  //- End "DataArray" XML section
372  // \return formatter for chaining
373  inline virtual formatter& endDataArray();
374 
375  //- Insert a single "PDataArray" XML entry tag.
376  // For some entries, the name is optional.
377  // \return formatter for chaining
378  template<class Type, direction nComp=1, int nTuple=0>
379  formatter& PDataArray(const word& dataName);
380 
381 
382  //- Begin "FieldData" XML section.
383  inline formatter& beginFieldData();
384 
385  //- Begin "CellData" XML section.
386  inline formatter& beginCellData();
387 
388  //- Begin "PointData" XML section.
389  inline formatter& beginPointData();
390 
391  //- End "FieldData" XML section.
392  inline virtual formatter& endFieldData();
393 
394  //- End "CellData" XML section.
395  inline virtual formatter& endCellData();
396 
397  //- End "PointData" XML section.
398  inline virtual formatter& endPointData();
399 
400 
401  //- End "AppendedData" XML section
402  // \return formatter for chaining
404 
405  //- End "VTKFile" XML section.
406  // \return formatter for chaining
407  inline virtual formatter& endVTKFile();
408 
409 
410  //- Emit "TimeValue" for FieldData (name as per Catalyst output)
411  formatter& writeTimeValue(scalar timeValue);
412 
413 
414  // XML Attributes
415 
416  //- Pair-wise write of XML key/value attributes
417  // \return formatter for chaining
418  template<class... Args>
419  inline formatter& xmlAttr
420  (
421  const word& k,
422  const std::string& v,
423  Args&&... args
424  );
425 
426  //- Pair-wise write of XML key/value attributes
427  // \return formatter for chaining
428  template<class... Args>
429  inline formatter& xmlAttr
430  (
431  const word& k,
432  const int32_t v,
433  Args&&... args
434  );
435 
436  //- Pair-wise write of XML key/value attributes
437  // \return formatter for chaining
438  template<class... Args>
439  inline formatter& xmlAttr
440  (
441  const word& k,
442  const int64_t v,
443  Args&&... args
444  );
445 
446  //- Pair-wise write of XML key/value attributes
447  // \return formatter for chaining
448  template<class... Args>
449  inline formatter& xmlAttr
450  (
451  const word& k,
452  const uint64_t v,
453  Args&&... args
454  );
455 
456  //- Pair-wise write of XML key/value attributes
457  // \return formatter for chaining
458  template<class... Args>
459  inline formatter& xmlAttr
460  (
461  const word& k,
462  const scalar v,
463  Args&&... args
464  );
465 
466  //- Pair-wise write of XML key/value attributes
467  // \return formatter for chaining
468  template<class... Args>
469  inline formatter& xmlAttr
470  (
471  const vtk::fileAttr& k,
472  const std::string& v,
473  Args&&... args
474  );
475 
476  //- Pair-wise write of XML key/value attributes
477  // \return formatter for chaining
478  template<class... Args>
479  inline formatter& xmlAttr
480  (
481  const vtk::fileAttr& k,
482  const int32_t v,
483  Args&&... args
484  );
485 
486  //- Pair-wise write of XML key/value attributes
487  // \return formatter for chaining
488  template<class... Args>
489  inline formatter& xmlAttr
490  (
491  const vtk::fileAttr& k,
492  const int64_t v,
493  Args&&... args
494  );
495 
496  //- Pair-wise write of XML key/value attributes
497  // \return formatter for chaining
498  template<class... Args>
499  inline formatter& xmlAttr
500  (
501  const vtk::fileAttr& k,
502  const uint64_t v,
503  Args&&... args
504  );
505 
506  //- Pair-wise write of XML key/value attributes
507  // \return formatter for chaining
508  template<class... Args>
509  inline formatter& xmlAttr
510  (
511  const vtk::fileAttr& k,
512  const scalar v,
513  Args&&... args
514  );
515 
516 
517  // Housekeeping
518 
519  //- Open "DataArray" XML tag and leave open (requires a closeTag).
520  // \deprecated Use beginDataArray instead (SEPT-2018)
521  template<class Type, direction nComp=1, int nTuple=0>
522  formatter& openDataArray(const word& dataName)
523  {
524  return beginDataArray<Type, nComp, nTuple>
525  (
526  dataName, formatter::npos, true
527  );
528  }
529 
530  //- Open "DataArray" XML tag and leave open (requires a closeTag).
531  // \deprecated Use beginDataArray instead (SEPT-2018)
532  template<class Type, direction nComp=1, int nTuple=0>
533  formatter& openDataArray(const vtk::dataArrayAttr& dataName)
534  {
535  return beginDataArray<Type, nComp, nTuple>
536  (
537  dataName, formatter::npos, true
538  );
539  }
540 };
541 
542 
543 // Global Functions
544 
545 //- Commonly used calculation for header and payload sizes
546 template<class Type, direction nComp=1>
547 inline uint64_t sizeofData(label count)
548 {
549  return (count * nComp * sizeof(Type));
550 }
551 
552 
553 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
554 
555 } // End namespace vtk
556 } // End namespace Foam
557 
558 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
559 
560 #include "foamVtkFormatterI.H"
561 
562 #ifdef NoRepository
563  #include "foamVtkFormatterTemplates.C"
564 #endif
565 
566 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
567 
568 #endif
569 
570 // ************************************************************************* //
formatter & beginPointData()
Begin "PointData" XML section.
Double-quote XML attributes.
System signed integer.
uint8_t direction
Definition: direction.H:46
formatter & endTag(const word &tagName=word::null)
An end XML tag, optional with sanity check.
bool inTag_
Tag open/closed/ended state.
Abstract class for a VTK output stream formatter.
quoteChar
Quoting for XML attributes.
virtual void flush()=0
Flush encoding, write newline etc.
formatter(std::ostream &os)
Construct and attach to an output stream.
formatter & endAppendedData()
End "AppendedData" XML section.
virtual formatter & endPointData()
End "PointData" XML section.
virtual const vtk::outputOptions & opts() const =0
The format-type / output options.
char quote_
Quoting character for XML attributes.
formatter & closeTag(const bool isEmpty=false)
Finish an XML tag, optional as an empty container.
formatter & xmlComment(const std::string &text, Args &&... args)
Write XML comment (at the current indentation level)
void indent()
Add indenting according to the current XML tag depth.
formatter & PDataArray(const word &dataName)
Insert a single "PDataArray" XML entry tag.
virtual formatter & endFieldData()
End "FieldData" XML section.
virtual uint64_t offset(const uint64_t numbytes)
Increase the append data offset by numbytes and sizeof(uint64_t).
label k
Boltzmann constant.
formatter & beginDataArray(const word &dataName, uint64_t payLoad=npos, bool leaveOpen=false)
Begin "DataArray" XML section.
uint64_t sizeofData(label count)
Commonly used calculation for header and payload sizes.
virtual formatter & endPiece()
End "Piece" XML section.
virtual bool writeSize(const uint64_t numbytes)=0
Write leading size for binary output.
formatter & writeTimeValue(scalar timeValue)
Emit "TimeValue" for FieldData (name as per Catalyst output)
virtual const char * encoding() const =0
Name for the XML append encoding.
64bit unsigned integer
Encapsulated combinations of output format options. This is primarily useful when defining the output...
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of &#39;true&#39; entries.
Definition: BitOps.H:73
std::ostream & os() noexcept
Access to the underlying output stream.
fileAttr
Some common XML attributes for vtk files.
Definition: foamVtkCore.H:160
std::ostream & os_
The output stream for the formatter.
formatter & beginFieldData()
Begin "FieldData" XML section.
DynamicList< word > xmlTags_
LIFO stack of current XML tags.
A class for handling words, derived from Foam::string.
Definition: word.H:63
static constexpr uint64_t npos
Out of range position or size.
formatter & beginCellData()
Begin "CellData" XML section.
virtual std::size_t encodedLength(std::size_t n) const
The encoded length for binary output is pass-through.
dataArrayAttr
Some common names for XML DataArray entries.
Definition: foamVtkCore.H:180
formatter & beginBlock(label index, std::string name="")
Begin "Block" XML section.
formatter & openDataArray(const word &dataName)
Open "DataArray" XML tag and leave open (requires a closeTag).
const direction noexcept
Definition: scalarImpl.H:255
formatter & beginVTKFile(const word &contentType, const word &contentVersion, const bool leaveOpen=false)
Add a "VTKFile" XML tag for contentType, followed by a tag for the contentType itself.
formatter & DataSet(label index, std::string file="", bool autoName=true)
Insert a single "DataSet" XML entry tag.
Direction is an 8-bit unsigned integer type used to represent Cartesian directions, components etc.
virtual formatter & endDataArray()
End "DataArray" XML section.
fileTag
Some common XML tags for vtk files.
Definition: foamVtkCore.H:122
virtual void write(const uint8_t val)=0
virtual formatter & endVTKFile()
End "VTKFile" XML section.
Single-quote XML attributes.
void writeAttr(const word &k, const Type &v)
Write XML key/value attribute pair (implementation).
virtual formatter & endCellData()
End "CellData" XML section.
label n
formatter & beginPiece(label index, std::string name="")
Begin "Piece" XML section.
virtual const char * name() const =0
Name for the XML output type or the legacy output type.
formatter & openTag(const word &tagName, Args &&... args)
Start an XML tag, optionally with attributes.
virtual ~formatter()=default
Destructor.
bool canWriteToplevel(const char *what) const
Can write tag-like top-level content (eg, comment, ...) when not already inside a tag...
void xmlCommentLoop(const std::string &text, Args &&... args)
Loop/output XML comments.
formatter & xmlHeader()
Write XML header.
formatter & endBlock()
End "Block" XML section.
Foam::argList args(argc, argv)
uint64_t headerType
The header data is vtk UInt64.
formatter & tag(const word &t, Args &&... args)
Write XML tag without any attributes. Combines openTag/closeTag.
formatter & xmlAttr()
No-op write XML attribute (for templating code).
bool openTagImpl(const word &tagName)
Open XML tag (implementation), checking if not already inside another tag. Emit warning and return fa...
Namespace for OpenFOAM.
formatter & beginAppendedData()
Add a "AppendedData" XML tag with the current encoding and output the requisite &#39;_&#39; prefix...
void quoting(const quoteChar quote)
Change quoting char for XML attributes (default: SINGLE_QUOTE)
bool canWriteAttr(const word &k) const
Can write XML key/value attribute pair when inside a tag. Emit warning and return false if this condi...