Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
SimpleCsvReaderWriter.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* SimpleCsvReaderWriter.cc (C) 2000-2022 */
9/* */
10/* Class allowing reading and writing a file in CSV format. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/std/SimpleCsvReaderWriter.h"
15
16#include "arcane/utils/Iostream.h"
17
18#include "arcane/core/Directory.h"
19
20/*---------------------------------------------------------------------------*/
21/*---------------------------------------------------------------------------*/
22
23namespace Arcane
24{
25
26/*---------------------------------------------------------------------------*/
27/*---------------------------------------------------------------------------*/
28
30writeTable(const Directory& dst, const String& file_name)
31{
32 std::ofstream ofile((dst.file(file_name) + "." + fileType()).localstr());
33 if (ofile.fail())
34 return false;
35
36 _print(ofile);
37
38 ofile.close();
39 return true;
40}
41
43readTable(const Directory& src, const String& file_name)
44{
46
47 std::ifstream stream;
48
49 // If there is no file, we return false.
50 if (!_openFile(stream, src, file_name + "." + fileType())) {
51 return false;
52 }
53
54 std::string line;
55
56 // If there is no first line, we stop here.
57 // A file written by SimpleCsvOutput always has at least one line.
58 if (!std::getline(stream, line)) {
59 _closeFile(stream);
60 return false;
61 }
62
63 // Otherwise, we have the header line, containing the column names
64 // (and the table name).
65 String ligne(line);
66
67 {
69 ligne.split(tmp, m_separator);
70
71 if (tmp.size() == 0) {
72 _closeFile(stream);
73 return false;
74 }
75
76 m_simple_table_internal->m_table_name = tmp[0];
77 m_simple_table_internal->m_column_names = tmp.subConstView(1, tmp.size());
78 }
79
80 // If there are no other lines, it means there are only empty columns
81 // (or no columns) and no lines.
82 if (!std::getline(stream, line)) {
83 _closeFile(stream);
84 return true;
85 }
86
87 // Now that we have the number of columns, we can define dimension 2
88 // of the values array.
89 m_simple_table_internal->m_values.resize(1, m_simple_table_internal->m_column_names.size());
90
91 Integer compt_line = 0;
92
93 do {
94 // We don't know the number of lines in advance, so we must resize
95 // each time.
96 m_simple_table_internal->m_values.resize(compt_line + 1);
97
98 // We split the retrieved line.
99 StringUniqueArray splitted_line;
100 String ligne(line);
101 ligne.split(splitted_line, m_separator);
102
103 // If there is an empty line, we skip it.
104 if (splitted_line.size() == 0) {
105 continue;
106 }
107
108 // If the number of columns in the line does not match the number of
109 // column names, there is an error in the file.
110 if (splitted_line.size() != m_simple_table_internal->m_column_names.size() + 1) {
111 _closeFile(stream);
112 return false;
113 }
114
115 // The first element is the row name.
116 m_simple_table_internal->m_row_names.add(splitted_line[0]);
117
118 // The other elements are Reals.
119 for (Integer i = 1; i < splitted_line.size(); i++) {
120 std::string std_string = splitted_line[i].localstr();
121 std::size_t pos_comma = std_string.find(',');
122
123 if (pos_comma != std::string::npos) {
124 std_string[pos_comma] = '.';
125 }
126
127 m_simple_table_internal->m_values[compt_line][i - 1] = std::stod(std_string);
128 }
129
130 compt_line++;
131 } while (std::getline(stream, line));
132
133 _closeFile(stream);
134
135 // We haven't saved the row/column sizes so we set the max size
136 // for each row/column.
137 m_simple_table_internal->m_row_sizes.resize(m_simple_table_internal->m_row_names.size());
138 m_simple_table_internal->m_row_sizes.fill(m_simple_table_internal->m_values.dim2Size());
139
140 m_simple_table_internal->m_column_sizes.resize(m_simple_table_internal->m_column_names.size());
141 m_simple_table_internal->m_column_sizes.fill(m_simple_table_internal->m_values.dim1Size());
142
143 return true;
144}
145
148{
149 m_simple_table_internal->clear();
150}
151
153print()
154{
155 _print(std::cout);
156}
157
158/*---------------------------------------------------------------------------*/
159/*---------------------------------------------------------------------------*/
160
162precision()
163{
164 return m_precision_print;
165}
166
169{
170 if (precision < 1)
171 m_precision_print = 1;
172 else if (precision > (std::numeric_limits<Real>::max_digits10))
173 m_precision_print = (std::numeric_limits<Real>::max_digits10);
174 else
175 m_precision_print = precision;
176}
177
179isFixed()
180{
181 return m_is_fixed_print;
182}
183
185setFixed(bool fixed)
186{
187 m_is_fixed_print = fixed;
188}
189
192{
193 return m_scientific_notation;
194}
195
197setForcedToUseScientificNotation(bool use_scientific)
198{
199 m_scientific_notation = use_scientific;
200}
201
202/*---------------------------------------------------------------------------*/
203/*---------------------------------------------------------------------------*/
204
206internal()
207{
208 return m_simple_table_internal;
209}
210
212setInternal(const Ref<SimpleTableInternal>& simple_table_internal)
213{
214 if (simple_table_internal.isNull())
215 ARCANE_FATAL("The reference passed as a parameter is Null.");
216 m_simple_table_internal = simple_table_internal;
217}
218
219/*---------------------------------------------------------------------------*/
220/*---------------------------------------------------------------------------*/
221
222bool SimpleCsvReaderWriter::
223_openFile(std::ifstream& stream, Directory directory, const String& file)
224{
225 stream.open(directory.file(file).localstr(), std::ifstream::in);
226 return stream.good();
227}
228
229void SimpleCsvReaderWriter::
230_closeFile(std::ifstream& stream)
231{
232 stream.close();
233}
234
235void SimpleCsvReaderWriter::
236_print(std::ostream& stream)
237{
238 // We save the stream info to restore it at the end.
239 std::ios_base::fmtflags save_flags = stream.flags();
240 std::streamsize save_prec = stream.precision();
241
242 if (m_is_fixed_print) {
243 stream << std::setiosflags(std::ios::fixed);
244 }
245 if (m_scientific_notation) {
246 stream << std::scientific;
247 }
248 stream << std::setprecision(m_precision_print);
249
250 stream << m_simple_table_internal->m_table_name << m_separator;
251
252 for (Integer j = 0; j < m_simple_table_internal->m_column_names.size(); j++) {
253 stream << m_simple_table_internal->m_column_names[j] << m_separator;
254 }
255 stream << std::endl;
256
257 for (Integer i = 0; i < m_simple_table_internal->m_values.dim1Size(); i++) {
258 stream << m_simple_table_internal->m_row_names[i] << m_separator;
259 ConstArrayView<Real> view = m_simple_table_internal->m_values[i];
260 for (Integer j = 0; j < m_simple_table_internal->m_values.dim2Size(); j++) {
261 stream << view[j] << m_separator;
262 }
263 stream << std::endl;
264 }
265
266 stream.flags(save_flags);
267 stream.precision(save_prec);
268}
269
270/*---------------------------------------------------------------------------*/
271/*---------------------------------------------------------------------------*/
272
273} // End namespace Arcane
274
275/*---------------------------------------------------------------------------*/
276/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Integer size() const
Number of elements in the vector.
ConstArrayView< T > subConstView(Int64 abegin, Int32 asize) const
Sub-view starting from element abegin and containing asize elements.
Class managing a directory.
Definition Directory.h:36
String file(const String &file_name) const override
Returns the full path of the file file_name in the directory.
Definition Directory.cc:120
bool isNull() const
Indicates if the counter references a non-null instance.
Reference to an instance.
void setFixed(bool fixed) override
Method allowing setting or unsetting the 'std::fixed' flag.
void setInternal(const Ref< SimpleTableInternal > &simple_table_internal) override
Method allowing setting a reference to a SimpleTableInternal.
bool isForcedToUseScientificNotation() override
Method allowing checking if the 'std::scientific' flag is active or not for writing values.
void clearInternal() override
Method allowing clearing the content of the SimpleTableInternal object.
void setForcedToUseScientificNotation(bool use_scientific) override
Method allowing setting or unsetting the 'std::scientific' flag.
bool readTable(const Directory &src, const String &file_name) override
Method allowing reading a file containing a simple table.
String fileType() override
Method allowing retrieval of the file type that will be written by the implementation....
void print() override
Method allowing writing the table to the standard output.
bool isFixed() override
Method allowing checking if the 'std::fixed' flag is active or not for writing values.
Ref< SimpleTableInternal > internal() override
Method allowing retrieval of a reference to the SimpleTableInternal object used.
bool writeTable(const Directory &dst, const String &file_name) override
Method allowing writing a simple table to a file.
void setPrecision(Integer precision) override
Method allowing modification of the print precision.
Integer precision() override
Method allowing retrieval of the precision currently used for writing values.
const char * localstr() const
Returns the conversion of the instance into UTF-8 encoding.
Definition String.cc:229
void split(StringContainer &str_array, char c) const
Splits the string based on the character c.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 Integer
Type representing an integer.
UniqueArray< String > StringUniqueArray
Dynamic 1D array of strings.
Definition UtilsTypes.h:359