FixedListIO.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-2022 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 "FixedList.H"
30 #include "Istream.H"
31 #include "Ostream.H"
32 #include "token.H"
33 
34 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
35 
36 template<class T, unsigned N>
38 {
39  const word tag("List<" + word(pTraits<T>::typeName) + '>');
40  if (token::compound::isCompound(tag))
41  {
42  os << tag << token::SPACE;
43  if (os.format() == IOstreamOption::BINARY && is_contiguous<T>::value)
44  {
45  // Need the size too so that List<Type>::readList parses correctly
46  os << static_cast<label>(N);
47  }
48  }
49  os << *this;
50 }
51 
52 
53 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
54 
55 template<class T, unsigned N>
57 {
58  this->readList(is);
59 }
60 
61 
62 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
63 
64 template<class T, unsigned N>
66 (
67  const word& keyword,
68  Ostream& os
69 ) const
70 {
71  if (keyword.size())
72  {
73  os.writeKeyword(keyword);
74  }
75  writeEntry(os);
76  os << token::END_STATEMENT << endl;
77 }
78 
79 
80 template<class T, unsigned N>
82 (
83  Ostream& os,
84  const label shortLen
85 ) const
86 {
87  const FixedList<T, N>& list = *this;
88 
89  // Unlike UList, no compact ascii output since a FixedList is generally
90  // small and we prefer a consistent appearance.
91  // Eg, FixedList<T,2> or Pair<T> as "(-1 -1)", never as "2{-1}"
92 
93  if (os.format() == IOstreamOption::BINARY && is_contiguous<T>::value)
94  {
95  // Binary and contiguous. Size is always non-zero
96 
97  // write(...) includes surrounding start/end delimiters
98  os.write(list.cdata_bytes(), list.size_bytes());
99  }
100  else if
101  (
102  (N <= 1 || !shortLen)
103  ||
104  (
105  (N <= unsigned(shortLen))
106  &&
107  (
108  is_contiguous<T>::value
109  || Detail::ListPolicy::no_linebreak<T>::value
110  )
111  )
112  )
113  {
114  // Single-line output
115 
116  // Start delimiter
117  os << token::BEGIN_LIST;
118 
119  // Contents
120  for (unsigned i=0; i<N; ++i)
121  {
122  if (i) os << token::SPACE;
123  os << list[i];
124  }
125 
126  // End delimiter
127  os << token::END_LIST;
128  }
129  else
130  {
131  // Multi-line output
132 
133  // Start delimiter
134  os << nl << token::BEGIN_LIST << nl;
135 
136  // Contents
137  for (unsigned i=0; i<N; ++i)
138  {
139  os << list[i] << nl;
140  }
141 
142  // End delimiter
143  os << token::END_LIST << nl;
144  }
145 
147  return os;
148 }
149 
150 
151 template<class T, unsigned N>
153 (
154  Istream& is
155 )
156 {
157  FixedList<T, N>& list = *this;
158 
160 
161  if (is.format() == IOstreamOption::BINARY && is_contiguous<T>::value)
162  {
163  // Binary and contiguous. Length is non-zero
164 
165  Detail::readContiguous<T>
166  (
167  is,
168  list.data_bytes(),
169  list.size_bytes()
170  );
171 
172  is.fatalCheck
173  (
174  "FixedList<T, N>::readList(Istream&) : "
175  "reading the binary block"
176  );
177  return is;
178  }
179  else
180  {
181  token tok(is);
182 
183  is.fatalCheck
184  (
185  "FixedList<T, N>::readList(Istream&) : "
186  "reading first token"
187  );
188 
189  if (tok.isCompound())
190  {
191  // Compound: transfer contents
192  // - in practice probably never reach this branch
193  list = dynamicCast<token::Compound<List<T>>>
194  (
195  tok.transferCompoundToken(is)
196  );
197  return is;
198  }
199  else if (tok.isLabel())
200  {
201  // List lengths must match
202  list.checkSize(tok.labelToken());
203  }
204  else if (!tok.isPunctuation())
205  {
207  << "incorrect first token, expected <label> or '(' , found "
208  << tok.info() << nl
209  << exit(FatalIOError);
210  }
211  else
212  {
213  // Putback the opening bracket
214  is.putBack(tok);
215  }
216 
217  // Begin of contents marker
218  const char delimiter = is.readBeginList("FixedList");
219 
220  if (delimiter == token::BEGIN_LIST)
221  {
222  for (unsigned i=0; i<N; ++i)
223  {
224  is >> list[i];
225 
226  is.fatalCheck
227  (
228  "FixedList<T, N>::readList(Istream&) : "
229  "reading entry"
230  );
231  }
232  }
233  else
234  {
235  // Uniform content (delimiter == token::BEGIN_BLOCK)
236  // - compatibility for v1812 and earlier (see issue #1160)
237 
238  T elem;
239  is >> elem;
240 
241  is.fatalCheck
242  (
243  "FixedList<T, N>::readList(Istream&) : "
244  "reading the single entry"
245  );
246 
247  for (unsigned i=0; i<N; ++i)
248  {
249  list[i] = elem; // Copy the value
250  }
251  }
252 
253  // End of contents marker
254  is.readEndList("FixedList");
255  }
256 
257  return is;
258 }
259 
260 
261 // ************************************************************************* //
const char * cdata_bytes() const noexcept
Return pointer to the underlying array serving as data storage,.
Definition: FixedListI.H:177
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
A 1D vector of objects of type <T> with a fixed length <N>.
Definition: HashTable.H:101
char readEndList(const char *funcName)
End read of list data, ends with &#39;)&#39; or &#39;}&#39;.
Definition: Istream.C:162
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:49
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:487
A traits class, which is primarily used for primitives.
Definition: pTraits.H:50
void writeEntry(Ostream &os) const
Write the FixedList with its compound type.
Definition: FixedListIO.C:30
void putBack(const token &tok)
Put back a token. Only a single put back is permitted.
Definition: Istream.C:63
A class for handling words, derived from Foam::string.
Definition: word.H:63
static std::streamsize size_bytes() noexcept
Number of contiguous bytes for the list data,.
Definition: FixedListI.H:192
Ostream & writeList(Ostream &os, const label shortLen=0) const
Write List, with line-breaks in ASCII when length exceeds shortLen.
Definition: FixedListIO.C:75
char readBeginList(const char *funcName)
Begin read of list data, starts with &#39;(&#39; or &#39;{&#39;.
Definition: Istream.C:141
char * data_bytes() noexcept
Return pointer to the underlying array serving as data storage,.
Definition: FixedListI.H:185
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:55
void checkSize(const label size) const
Check size is identical to template parameter N.
Definition: FixedListI.H:300
OBJstream os(runTime.globalPath()/outputName)
#define FUNCTION_NAME
const volScalarField & T
const Vector< label > N(dict.get< Vector< label >>("N"))
bool fatalCheck(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:51
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:607
A template class to specify that a data type can be considered as being contiguous in memory...
Definition: contiguous.H:71
Istream & readList(Istream &is)
Read from Istream, discarding contents of existing List.
Definition: FixedListIO.C:146
streamFormat format() const noexcept
Get the current stream format.
FixedList()=default
Default construct.
IOerror FatalIOError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL IO ERROR&#39; header text and ...