CircularBufferIO.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) 2022 OpenCFD Ltd.
9-------------------------------------------------------------------------------
10License
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\*---------------------------------------------------------------------------*/
27
28#include "List.H"
29#include "Istream.H"
30#include "contiguous.H"
31
32// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
33
34template<class T>
36{
37 this->readList(is);
38}
39
40
41// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
42
43template<class T>
45{
46 os << "size=" << size() << '/' << capacity()
47 << " begin=" << begin_
48 << " end=" << end_
51 << nl;
52
53 return os;
54}
55
56
57template<class T>
59{
60 // Clear list
61 storage_.clear();
62 begin_ = 0;
63 end_ = 0;
64
65 // More work than it should be. We avoid completely filled buffers!
66
68
69 token tok(is);
70
71 is.fatalCheck
72 (
73 "CircularBuffer<T>::readList(Istream&) : "
74 "reading first token"
75 );
76
77 if (tok.isCompound())
78 {
79 // Compound: simply transfer contents
80
81 storage_.transfer
82 (
84 (
86 )
87 );
88
89 end_ = storage_.size();
90 if (end_)
91 {
92 // Resize larger to avoid full buffer
93 storage_.resize(end_ + min_size());
94 }
95 }
96 else if (tok.isLabel())
97 {
98 // Label: could be int(..), int{...} or just a plain '0'
99
100 const label len = tok.labelToken();
101
102 end_ = len;
103 if (end_)
104 {
105 // Resize larger to avoid full buffer
106 storage_.resize(end_ + min_size());
107 }
108
109 // Dispatch to UList reading...
110
111 UList<T> list(storage_.data(), end_);
112
113 is.putBack(tok);
114 list.readList(is);
115 }
116 else if (tok.isPunctuation(token::BEGIN_LIST))
117 {
118 // "(...)" : read as SLList and transfer contents
119
120 is.putBack(tok); // Putback the opening bracket
121 SLList<T> sll(is); // Read as singly-linked list
122
123 const label len = sll.size();
124
125 end_ = len;
126 if (end_)
127 {
128 // Resize larger to avoid full buffer
129 storage_.resize(end_ + min_size());
130
131 // Move assign each list element
132 for (label i = 0; i < len; ++i)
133 {
134 storage_[i] = std::move(sll.removeHead());
135 }
136 }
137 }
138 else
139 {
141 << "incorrect first token, expected <int> or '(', found "
142 << tok.info() << nl
143 << exit(FatalIOError);
144 }
145
146 return is;
147}
148
149
150template<class T>
152(
153 Ostream& os,
154 const label shortLen
155) const
156{
157 const label len = this->size();
158 const auto list1 = this->array_one();
159 const auto list2 = this->array_two();
160
161 #ifdef FULLDEBUG
162 if (len != (list1.size() + list2.size()))
163 {
165 << "Size check failed"
166 << abort(FatalError);
167 }
168 #endif
169
170 if (os.format() == IOstream::BINARY && is_contiguous<T>::value)
171 {
172 // Binary and contiguous
173
174 os << nl << len << nl;
175
176 if (len)
177 {
178 // The TOTAL number of bytes to be written.
179 // - possibly add start delimiter
180 // This is much like IndirectListBase output
181
182 os.beginRawWrite(len*sizeof(T));
183
184 if (!list1.empty())
185 {
186 os.writeRaw(list1.cdata_bytes(), list1.size_bytes());
187 }
188 if (!list2.empty())
189 {
190 os.writeRaw(list2.cdata_bytes(), list2.size_bytes());
191 }
192
193 // End delimiter and/or cleanup.
194 os.endRawWrite();
195 }
196 }
197 else if
198 (
199 (len <= 1 || !shortLen)
200 ||
201 (
202 (len <= shortLen)
203 &&
204 (
207 )
208 )
209 )
210 {
211 // Single-line output
212
213 // Size and start delimiter
214 os << len << token::BEGIN_LIST;
215
216 // Contents
217 label i = 0;
218 for (const T& val : list1)
219 {
220 if (i++) os << token::SPACE;
221 os << val;
222 }
223 for (const T& val : list2)
224 {
225 if (i++) os << token::SPACE;
226 os << val;
227 }
228
229 // End delimiter
230 os << token::END_LIST;
231 }
232 else
233 {
234 // Multi-line output
235
236 // Size and start delimiter
237 os << nl << len << nl << token::BEGIN_LIST << nl;
238
239 // Contents
240 for (const T& val : list1)
241 {
242 os << val << nl;
243 }
244 for (const T& val : list2)
245 {
246 os << val << nl;
247 }
248
249 // End delimiter
250 os << token::END_LIST << nl;
251 }
252
253 os.check(FUNCTION_NAME);
254 return os;
255}
256
257
258// ************************************************************************* //
constexpr CircularBuffer() noexcept
Default construct, empty buffer without allocation.
Ostream & writeList(Ostream &os, const label shortLen=0) const
Istream & readList(Istream &is)
Read buffer contents from Istream.
bool fatalCheck(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:64
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:64
void putBack(const token &tok)
Put back a token. Only a single put back is permitted.
Definition: Istream.C:70
Template class for non-intrusive linked lists.
Definition: LList.H:79
T removeHead()
Remove and return first entry.
Definition: LList.H:265
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: List.H:77
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:62
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: UList.H:94
Istream & readList(Istream &is)
Read List contents from Istream.
Definition: UListIO.C:157
InfoProxy< ensightCells > info() const
Return info proxy.
Definition: ensightCells.H:254
A templated class for holding compound tokens.
Definition: token.H:250
A token holds an item read from Istream.
Definition: token.H:69
compound & transferCompoundToken()
Return reference to compound and mark internally as released.
Definition: token.C:90
bool isPunctuation() const noexcept
Token is PUNCTUATION.
Definition: tokenI.H:459
bool isLabel() const noexcept
Token is LABEL.
Definition: tokenI.H:497
label labelToken() const
Return label value.
Definition: tokenI.H:513
InfoProxy< token > info() const
Return info proxy for printing token information to a stream.
Definition: token.H:586
bool isCompound() const noexcept
Token is COMPOUND.
Definition: tokenI.H:716
const volScalarField & T
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
OBJstream os(runTime.globalPath()/outputName)
#define FUNCTION_NAME
errorManip< error > abort(error &err)
Definition: errorManip.H:144
IOerror FatalIOError
error FatalError
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
To & dynamicCast(From &r)
Definition: typeInfo.H:88
A template class to specify that a data type can be considered as being contiguous in memory.
Definition: contiguous.H:78