JSONformatter.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) 2023-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 \*---------------------------------------------------------------------------*/
27 
28 #include "JSONformatter.H"
29 
30 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
31 
32 namespace Foam
33 {
34  defineTypeNameAndDebug(JSONformatter, 0);
35 }
36 
37 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
38 
39 bool Foam::JSONformatter::writeToken(const token& t)
40 {
41  bool ok = true;
42  switch (t.type())
43  {
44  case token::tokenType::BOOL:
45  write(t.boolToken());
46  break;
47 
48  case token::tokenType::INTEGER_32 :
49  write(t.int32Token());
50  break;
51 
52  case token::tokenType::INTEGER_64 :
53  write(t.int64Token());
54  break;
55 
56  case token::tokenType::FLOAT:
57  case token::tokenType::DOUBLE:
58  write(t.scalarToken());
59  break;
60 
61  case token::tokenType::WORD:
62  case token::tokenType::DIRECTIVE:
63  write(t.wordToken());
64  break;
65 
66  case token::tokenType::STRING:
67  case token::tokenType::EXPRESSION:
68  case token::tokenType::VARIABLE:
69  case token::tokenType::VERBATIM:
70  case token::tokenType::CHAR_DATA:
71  write(t.stringToken());
72  break;
73 
74  default:
75  DebugInfo
76  << "Problem converting token to JSON:" << nl
77  << " " << Foam::name(int(t.type()))
78  << " - treating as null" << endl;
79 
80  os_ << "null";
81 
82  ok = false;
83  break;
84  }
85 
86  return ok;
87 }
88 
89 
90 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
91 
93 :
94  os_(os)
95 {}
96 
97 
98 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
99 
101 (
102  const keyType& keyword
103 )
104 {
105  return os_.writeQuoted(keyword);
106 }
107 
108 
110 {
111  if (dict.empty())
112  {
113  os_ << "{}";
114  return os_;
115  }
116 
117  os_ << '{' << nl << incrIndent;
118 
119  const auto openBrace = [](const token& t){
120  return t == token::BEGIN_LIST || t == token::BEGIN_SQR;
121  };
122  const auto closeBrace = [](const token& t){
123  return t == token::END_LIST || t == token::END_SQR;
124  };
125 
126  label entryi = 0;
127  for (const entry& e : dict)
128  {
129  if (entryi)
130  {
131  os_ << ',' << nl;
132  }
133 
134  const word& keyword = e.keyword();
135 
136  os_ << indent;
137  os_.writeQuoted(keyword) << " : ";
138 
139  if (e.isDict())
140  {
141  writeDict(e.dict());
142 
143  ++entryi;
144 
145  continue;
146  }
147 
148  const auto& tokens = e.stream();
149 
150  if (tokens.empty())
151  {
153  << "Empty entry for keyword " << keyword << nl
154  << " - treating value as null" << endl;
155 
156  os_ << "null";
157  }
158  else if (tokens.size() == 1)
159  {
160  writeToken(tokens[0]);
161  }
162  else
163  {
164  label offset = 0;
165  if (tokens[0].isLabel() && openBrace(tokens[1]))
166  {
167  offset = 1; // reading 'size (value0 value1 ... valueN)
168  }
169 
170  const token& t = tokens[offset];
171  if (openBrace(t))
172  {
173  // Assume array-type
174  label i = 0;
175  for (label tokeni=offset; tokeni<tokens.size(); ++tokeni)
176  {
177  const token& tk = tokens[tokeni];
178 
179  if (openBrace(tk))
180  {
181  if (i) os_ << ',';
182  os_ << '[';
183  i = 0;
184  }
185  else if (closeBrace(tk))
186  {
187  os_ << ']';
188  }
189  else
190  {
191  if (i) os_ << ',';
192  if (writeToken(tk)) ++i;
193 
194  if (i % 10 == 0) os_ << nl;
195  }
196  }
197  }
198  else
199  {
200  // Unknown type - convert to string representation
201  os_ << '"';
202  forAll(tokens, tokeni)
203  {
204  if (tokeni) os_ << ' ';
205  os_ << tokens[tokeni];
206  }
207  os_ << '"';
208  }
209  }
210 
211  ++entryi;
212  }
214  os_ << nl << decrIndent << indent << '}';
215 
216  return os_;
217 }
218 
219 
221 {
222  os_ << (val ? "true" : "false");
223  return os_;
224 }
225 
226 
228 {
229  os_ << val;
230  return os_;
231 }
232 
233 
235 {
236  os_ << val;
237  return os_;
238 }
239 
240 
242 {
243  os_ << val;
244  return os_;
245 }
246 
247 
249 {
250  os_ << val;
251  return os_;
252 }
253 
256 {
257  return os_.writeQuoted(str);
258 }
259 
261 Foam::Ostream& Foam::JSONformatter::write(const std::string& str)
262 {
263  return os_.writeQuoted(str);
264 }
265 
266 
268 {
269  os_ << c;
270  return os_;
271 }
272 
273 
274 // ************************************************************************* //
A class for handling keywords in dictionaries.
Definition: keyType.H:66
dictionary dict
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:480
virtual Ostream & writeKeyword(const keyType &keyword)
Write JSON keyword.
Definition: JSONformatter.C:94
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:130
Begin dimensions [isseparator].
Definition: token.H:176
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:518
Begin list [isseparator].
Definition: token.H:174
virtual Ostream & writeDict(const dictionary &dict)
Write OpenFOAM dictionary to JSON dictionary.
virtual Ostream & writeQuoted(const char *str, std::streamsize len, const bool quoted=true)=0
Write character/string content, with/without surrounding quotes.
End dimensions [isseparator].
Definition: token.H:177
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:400
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
A class for handling words, derived from Foam::string.
Definition: word.H:63
JSONformatter(Ostream &os)
Construct from Ostream.
Definition: JSONformatter.C:85
End list [isseparator].
Definition: token.H:175
#define DebugInfo
Report an information message using Foam::Info.
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
defineTypeNameAndDebug(combustionModel, 0)
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
Definition: Ostream.H:498
#define WarningInFunction
Report a warning using Foam::Warning.
const dimensionedScalar c
Speed of light in a vacuum.
Ostream & incrIndent(Ostream &os)
Increment the indent level.
Definition: Ostream.H:489
Namespace for OpenFOAM.
virtual Ostream & write(const bool val)