CSV.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-2017 OpenFOAM Foundation
9 Copyright (C) 2016-2021 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
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 "CSV.H"
30#include "DynamicList.H"
31#include "ListOps.H"
32
33// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
34
35template<class Type>
37(
38 const word& name,
39 const dictionary& dict
40)
41{
42 // Writing of columns was forced to be ASCII,
43 // do the same when reading
44
45 labelList cols;
46
47 ITstream& is = dict.lookup(name);
48 is.format(IOstream::ASCII);
49 is >> cols;
50 dict.checkITstream(is, name);
51
52 if (cols.size() != pTraits<Type>::nComponents)
53 {
55 << name << " with " << cols
56 << " does not have the expected length "
57 << pTraits<Type>::nComponents << nl
58 << exit(FatalIOError);
59 }
60
61 return cols;
62}
63
64
65// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
66
67template<>
69(
70 const List<string>& strings
71) const
72{
73 return readLabel(strings[componentColumns_[0]]);
74}
75
76
77template<>
79(
80 const List<string>& strings
81) const
82{
83 return readScalar(strings[componentColumns_[0]]);
84}
85
86
87template<class Type>
89(
90 const List<string>& strings
91) const
92{
93 Type result;
94
95 for (label i = 0; i < pTraits<Type>::nComponents; ++i)
96 {
97 result[i] = readScalar(strings[componentColumns_[i]]);
98 }
99
100 return result;
101}
102
103
104template<class Type>
106{
107 fileName expandedFile(fName_);
108 autoPtr<ISstream> isPtr(fileHandler().NewIFstream(expandedFile.expand()));
109 ISstream& is = isPtr();
110
111 if (!is.good())
112 {
114 << "Cannot open CSV file for reading."
115 << exit(FatalIOError);
116 }
117
118 const label maxEntry =
119 max(refColumn_, componentColumns_[findMax(componentColumns_)]);
120
121 string line;
122 label lineNo = 0;
123
124 // Skip header
125 for (label i = 0; i < nHeaderLine_; ++i)
126 {
127 is.getLine(line);
128 ++lineNo;
129 }
130
131 DynamicList<Tuple2<scalar, Type>> values;
132 DynamicList<string> strings(maxEntry+1); // reserve
133
134 while (is.good())
135 {
136 is.getLine(line);
137 ++lineNo;
138
139 strings.clear();
140
141 std::size_t pos = 0;
142
143 for
144 (
145 label n = 0;
146 (pos != std::string::npos) && (n <= maxEntry);
147 ++n
148 )
149 {
150 if (mergeSeparators_)
151 {
152 bool found = false;
153 while (!found)
154 {
155 const auto nPos = line.find(separator_, pos);
156
157 if ((nPos != std::string::npos) && (nPos - pos == 0))
158 {
159 pos = nPos + 1;
160 }
161 else
162 {
163 found = true;
164 }
165 }
166 }
167
168 const auto nPos = line.find(separator_, pos);
169
170 if (nPos == std::string::npos)
171 {
172 strings.append(line.substr(pos));
173 pos = nPos;
174 }
175 else
176 {
177 strings.append(line.substr(pos, nPos - pos));
178 pos = nPos + 1;
179 }
180 }
181
182 if (strings.size() <= 1)
183 {
184 break;
185 }
186
187 if (strings.size() <= maxEntry)
188 {
190 << "Not enough columns near line " << lineNo
191 << ". Require " << (maxEntry+1) << " but found "
192 << strings << nl
193 << exit(FatalError);
194 }
195
196 scalar x = readScalar(strings[refColumn_]);
197 Type value = readValue(strings);
198
199 values.append(Tuple2<scalar,Type>(x, value));
200 }
201
202 this->table_.transfer(values);
203}
204
205
206// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
207
208template<class Type>
210(
211 const word& entryName,
212 const dictionary& dict,
213 const objectRegistry* obrPtr,
214 const fileName& fName
215)
216:
217 TableBase<Type>(entryName, dict, obrPtr),
218 nHeaderLine_(dict.get<label>("nHeaderLine")),
219 refColumn_(dict.get<label>("refColumn")),
220 componentColumns_(getComponentColumns("componentColumns", dict)),
221 separator_(dict.getOrDefault<string>("separator", ",")[0]),
222 mergeSeparators_(dict.get<bool>("mergeSeparators")),
223 fName_(fName.empty() ? dict.get<fileName>("file") : fName)
224{
225 read();
226
228}
229
230
231template<class Type>
233:
234 TableBase<Type>(csv),
235 nHeaderLine_(csv.nHeaderLine_),
236 refColumn_(csv.refColumn_),
237 componentColumns_(csv.componentColumns_),
238 separator_(csv.separator_),
239 mergeSeparators_(csv.mergeSeparators_),
240 fName_(csv.fName_)
241{}
242
243
244// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
245
246template<class Type>
248{
249 return fName_;
250}
251
252
253template<class Type>
255{
256 // Note: for TableBase write the dictionary entries it needs but not
257 // the values themselves
259
260 os.writeEntry("nHeaderLine", nHeaderLine_);
261 os.writeEntry("refColumn", refColumn_);
262
263 // Force writing labelList in ASCII
264 const auto oldFmt = os.format(IOstream::ASCII);
265 os.writeEntry("componentColumns", componentColumns_);
266 os.format(oldFmt);
267
268 os.writeEntry("separator", string(separator_));
269 os.writeEntry("mergeSeparators", mergeSeparators_);
270 os.writeEntry("file", fName_);
271}
272
273
274template<class Type>
276{
278 os.endEntry();
279
280 os.beginBlock(word(this->name() + "Coeffs"));
281 writeEntries(os);
282 os.endBlock();
283}
284
285
286// ************************************************************************* //
Various functions to operate on Lists.
bool found
label n
Y[inertIndex] max(0.0)
Templated CSV function.
Definition: CSV.H:78
virtual const fileName & fName() const
Return const access to the file name.
Definition: CSV.C:247
virtual void writeEntries(Ostream &os) const
Write coefficient entries in dictionary format.
Definition: CSV.C:254
Base class for table with bounds handling, interpolation and integration.
Definition: TableBase.H:63
void initialise()
Check the table for size and consistency.
Definition: TableBase.C:110
virtual void writeEntries(Ostream &os) const
Write keywords only in dictionary format.
Definition: TableBase.C:348
Top level data entry class for use in dictionaries. Provides a mechanism to specify a variable as a c...
Definition: Function1.H:96
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:62
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
A class for handling file names.
Definition: fileName.H:76
Registry of regIOobjects.
A class for handling character strings derived from std::string.
Definition: string.H:79
A class for handling words, derived from Foam::string.
Definition: word.H:68
bool
Definition: EEqn.H:20
#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)
List< T > values(const HashTable< T, Key, Hash > &tbl, const bool doSort=false)
List of values from HashTable, optionally sorted.
Definition: HashOps.H:149
const fileOperation & fileHandler()
Get current file handler.
dimensionedScalar pos(const dimensionedScalar &ds)
List< label > labelList
A List of labels.
Definition: List.H:66
label readLabel(const char *buf)
Parse entire buffer as a label, skipping leading/trailing whitespace.
Definition: label.H:66
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
label findMax(const ListType &input, label start=0)
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
dictionary dict