Arcane  v4.1.2.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
JSONReader.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 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/* JSONReader.cc (C) 2000-2025 */
9/* */
10/* Lecteur au format JSON. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arccore/common/JSONReader.h"
15
16#include "arccore/base/FatalErrorException.h"
17#include "arccore/base/CheckedConvert.h"
18#include "arccore/base/internal/ConvertInternal.h"
19
20#define RAPIDJSON_HAS_STDSTRING 1
22#include "arccore/common/internal/json/rapidjson/stringbuffer.h"
23
24#include <iostream>
25
26/*---------------------------------------------------------------------------*/
27/*---------------------------------------------------------------------------*/
28
29namespace Arcane
30{
31
32/*---------------------------------------------------------------------------*/
33/*---------------------------------------------------------------------------*/
34
36{
37 public:
38
39 rapidjson::Value::Member* toMember() const
40 {
41 return (rapidjson::Value::Member*)(this);
42 }
43};
44
46{
47 public:
48
49 rapidjson::Value* toValue() const
50 {
51 return (rapidjson::Value*)(this);
52 }
53};
54
56{
57 public:
58
60 {
61 return JSONKeyValue((JSONKeyValue::Impl*)(v));
62 }
64 {
65 return JSONKeyValue((JSONKeyValue::Impl*)&(*v));
66 }
67 static JSONValue build(rapidjson::Value* v)
68 {
69 return JSONValue((JSONValue::Impl*)(v));
70 }
71};
72
73/*
74 * Types définis par rapidjson.
75 enum Type {
76 kNullType = 0, //!< null
77 kFalseType = 1, //!< false
78 kTrueType = 2, //!< true
79 kObjectType = 3, //!< object
80 kArrayType = 4, //!< array
81 kStringType = 5, //!< string
82 kNumberType = 6 //!< number
83};
84*/
85
86/*---------------------------------------------------------------------------*/
87/*---------------------------------------------------------------------------*/
88
89StringView JSONKeyValue::
90name() const
91{
92 if (!m_p)
93 return StringView();
94 auto& x = m_p->toMember()->name;
95 if (x.IsString())
96 return StringView(Span<const Byte>((const Byte*)x.GetString(), x.GetStringLength()));
97 return StringView();
98}
99
100/*---------------------------------------------------------------------------*/
101/*---------------------------------------------------------------------------*/
102
103JSONValue JSONKeyValue::
104value() const
105{
106 if (!m_p)
107 return JSONValue();
108 auto& x = m_p->toMember()->value;
109 return JSONWrapperUtils::build(&x);
110}
111
112/*---------------------------------------------------------------------------*/
113/*---------------------------------------------------------------------------*/
114
116value() const
117{
118 if (!m_p)
119 return String();
120 auto x = m_p->toValue();
121 if (x->IsString())
122 return String(Span<const Byte>((const Byte*)x->GetString(), x->GetStringLength()));
123 return String();
124}
125
126/*---------------------------------------------------------------------------*/
127/*---------------------------------------------------------------------------*/
128
130valueAsStringView() const
131{
132 if (!m_p)
133 return StringView();
134 auto x = m_p->toValue();
135 if (x->IsString())
136 return StringView(Span<const Byte>((const Byte*)x->GetString(), x->GetStringLength()));
137 return StringView();
138}
139
140/*---------------------------------------------------------------------------*/
141/*---------------------------------------------------------------------------*/
142
143StringView JSONValue::
144valueAsString() const
145{
146 return valueAsStringView();
147}
148
149/*---------------------------------------------------------------------------*/
150/*---------------------------------------------------------------------------*/
151
153valueAsInt64() const
154{
155 if (!m_p)
156 return 0;
157 auto x = m_p->toValue();
158 if (x->IsInt64())
159 return x->GetInt64();
160 return 0;
161}
162
163/*---------------------------------------------------------------------------*/
164/*---------------------------------------------------------------------------*/
165
167valueAsBool() const
168{
169 if (!m_p)
170 return false;
171 auto x = m_p->toValue();
172 if (x->IsBool())
173 return x->GetBool();
174 return false;
175}
176
177/*---------------------------------------------------------------------------*/
178/*---------------------------------------------------------------------------*/
179
181valueAsInt32() const
182{
183 Int64 v = valueAsInt64();
184 return CheckedConvert::toInt32(v);
185}
186
187/*---------------------------------------------------------------------------*/
188/*---------------------------------------------------------------------------*/
189
191valueAsReal() const
192{
193 if (!m_p)
194 return 0;
195 auto x = m_p->toValue();
196 std::cout << "TYPE=" << x->GetType() << "\n";
197 if (x->IsDouble())
198 return x->GetDouble();
199 if (x->GetType() == rapidjson::kStringType) {
200 // Convertie la chaîne de caractères en un réél
201 StringView s = this->valueAsStringView();
202 Real r = 0.0;
203 if (!Convert::Impl::StringViewToIntegral::getValue(r, s))
204 return r;
205 }
206 return 0.0;
207}
208
209/*---------------------------------------------------------------------------*/
210/*---------------------------------------------------------------------------*/
211
212JSONKeyValue JSONValue::
213keyValueChild(StringView name) const
214{
215 if (!m_p)
216 return JSONKeyValue();
217 auto d = m_p->toValue();
218 rapidjson::Value::MemberIterator x = d->FindMember((const char*)(name.bytes().data()));
219 if (x == d->MemberEnd())
220 return JSONKeyValue();
221 return JSONWrapperUtils::build(x);
222}
223
224/*---------------------------------------------------------------------------*/
225/*---------------------------------------------------------------------------*/
226
227JSONValue JSONValue::
228child(StringView name) const
229{
230 return keyValueChild(name).value();
231}
232
233/*---------------------------------------------------------------------------*/
234/*---------------------------------------------------------------------------*/
235
236JSONValue JSONValue::
237expectedChild(StringView name) const
238{
239 JSONKeyValue k = keyValueChild(name);
240 if (!k)
241 ARCCORE_FATAL("No key '{0}' found in json document", name);
242 return k.value();
243}
244
245/*---------------------------------------------------------------------------*/
246/*---------------------------------------------------------------------------*/
247
248JSONValueList JSONValue::
249children() const
250{
251 if (!m_p)
252 return JSONValueList();
253 auto d = m_p->toValue();
254 JSONValueList values;
255 if (!d->IsObject())
256 ARCCORE_FATAL("The value has to be of type 'object'");
257 for (auto& x : d->GetObject()) {
258 auto y = JSONWrapperUtils::build(&x);
259 values.add(y.value());
260 }
261 return values;
262}
263
264/*---------------------------------------------------------------------------*/
265/*---------------------------------------------------------------------------*/
266
267JSONValueList JSONValue::
268valueAsArray() const
269{
270 if (!m_p)
271 return JSONValueList();
272 auto d = m_p->toValue();
273 JSONValueList values;
274 if (!d->IsArray())
275 ARCCORE_FATAL("The value has to be of type 'array'");
276 for (rapidjson::SizeType i = 0; i < d->Size(); ++i) {
277 rapidjson::Value& x = (*d)[i];
278 auto y = JSONWrapperUtils::build(&x);
279 values.add(y);
280 }
281 return values;
282}
283
284/*---------------------------------------------------------------------------*/
285/*---------------------------------------------------------------------------*/
286
287bool JSONValue::
288isArray() const
289{
290 if (!m_p)
291 return false;
292 auto d = m_p->toValue();
293 return d->IsArray();
294}
295
296/*---------------------------------------------------------------------------*/
297/*---------------------------------------------------------------------------*/
298
299bool JSONValue::
300isObject() const
301{
302 if (!m_p)
303 return false;
304 auto d = m_p->toValue();
305 return d->IsObject();
306}
307
308/*---------------------------------------------------------------------------*/
309/*---------------------------------------------------------------------------*/
310
311JSONKeyValueList JSONValue::
312keyValueChildren() const
313{
314 if (!m_p)
315 return JSONKeyValueList();
316 auto d = m_p->toValue();
317 JSONKeyValueList values;
318 for (auto& x : d->GetObject()) {
319 auto y = JSONWrapperUtils::build(&x);
320 values.add(y);
321 }
322 return values;
323}
324
325/*---------------------------------------------------------------------------*/
326/*---------------------------------------------------------------------------*/
327
328/*---------------------------------------------------------------------------*/
329/*---------------------------------------------------------------------------*/
330
332{
333 public:
334
335 Impl()
336 : m_document()
337 {
338 }
339
340 public:
341
342 rapidjson::Document m_document;
343};
344
345/*---------------------------------------------------------------------------*/
346/*---------------------------------------------------------------------------*/
347
348JSONDocument::
349JSONDocument()
350: m_p(nullptr)
351{
352 m_p = new Impl();
353}
354
355JSONDocument::
356~JSONDocument()
357{
358 delete m_p;
359}
360
361namespace
362{
363 using namespace rapidjson;
364
365 const char*
366 _getErrorCodeString(ParseErrorCode c)
367 {
368 switch (c) {
369 case kParseErrorNone:
370 return "No error";
372 return "The document is empty";
374 return "The document root must not follow by other values";
376 return "Invalid value";
378 return "Missing a name for object member";
380 return "Missing a colon after a name of object member";
382 return "Missing a comma or '}' after an object member";
384 return "Missing a comma or ']' after an array element";
386 return "Incorrect hex digit after \\u escape in string";
388 return "The surrogate pair in string is invalid";
390 return "Invalid escape character in string";
392 return "Missing a closing quotation mark in string";
394 return "Invalid encoding in string";
396 return "Number too big to be stored in double";
398 return "Miss fraction part in number";
400 return "Miss exponent in number";
402 return "Parsing was terminated";
404 return "Unspecific syntax error";
405 default:
406 return "Unknown";
407 }
408 return "Unknown";
409 }
410} // namespace
411
412/*---------------------------------------------------------------------------*/
413/*---------------------------------------------------------------------------*/
414
417{
418 using namespace rapidjson;
419 Document& d = m_p->m_document;
420 ParseResult r = d.Parse((const char*)bytes.data(), bytes.size());
421 if (d.HasParseError()) {
422 std::cout << "ERROR: " << d.GetParseError() << "\n";
423 ARCCORE_FATAL("Parsing error file='{0}' ret={1} position={2} message='{3}'",
424 filename, d.GetParseError(),
425 r.Offset(), _getErrorCodeString(r.Code()));
426 }
427}
428
429/*---------------------------------------------------------------------------*/
430/*---------------------------------------------------------------------------*/
431
434{
435 parse(bytes, "(Unknown)");
436}
437
438/*---------------------------------------------------------------------------*/
439/*---------------------------------------------------------------------------*/
440
443{
444 parse(asBytes(bytes));
445}
446
447/*---------------------------------------------------------------------------*/
448/*---------------------------------------------------------------------------*/
449
451parse(Span<const Byte> bytes, StringView filename)
452{
453 parse(asBytes(bytes), filename);
454}
455
456/*---------------------------------------------------------------------------*/
457/*---------------------------------------------------------------------------*/
458
460root() const
461{
462 rapidjson::Value& d = m_p->m_document;
463 return JSONWrapperUtils::build(&d);
464}
465
466/*---------------------------------------------------------------------------*/
467/*---------------------------------------------------------------------------*/
468
469} // namespace Arcane
470
471/*---------------------------------------------------------------------------*/
472/*---------------------------------------------------------------------------*/
#define ARCCORE_FATAL(...)
Macro envoyant une exception FatalErrorException.
void parse(Span< const Byte > bytes)
Lit le fichier au format UTF-8.
JSONValue root() const
Elément racine.
Liste de (clé,valeur) d'un document JSON.
Représente une paire (clé,valeur) de JSON.
String value() const
Valeur sous forme de String. La chaîne retournée est nulle si 'null()' est vrai.
Int32 valueAsInt32() const
Valeur sous forme de Int64. Retourn 0 si 'null()' est vrai.
Real valueAsReal() const
Valeur sous forme de Real. Retourn 0.0 si 'null()' est vrai.
bool valueAsBool() const
Valeur sous forme de booléen. Retourn false si 'null()' est vrai.
Int64 valueAsInt64() const
Valeur sous forme de Int64. Retourn 0 si 'null()' est vrai.
StringView valueAsStringView() const
Valeur sous forme de StringView. La chaîne est vide si 'null()' est vrai.
JSONValue expectedChild(StringView name) const
Valeur fille de nom name. Lance une exception si non trouvé.
JSONValue child(StringView name) const
Valeur fille de nom name. Retourne une valeur nulle si non trouvé.
constexpr __host__ __device__ pointer data() const noexcept
Pointeur sur le début de la vue.
Definition Span.h:537
constexpr __host__ __device__ SizeType size() const noexcept
Retourne la taille du tableau.
Definition Span.h:325
Vue d'un tableau d'éléments de type T.
Definition Span.h:633
Vue sur une chaîne de caractères UTF-8.
Definition StringView.h:47
constexpr Span< const Byte > bytes() const ARCCORE_NOEXCEPT
Retourne la conversion de l'instance dans l'encodage UTF-8.
Definition StringView.h:96
Chaîne de caractères unicode.
constexpr __host__ __device__ pointer data() const noexcept
Pointeur sur le début de la vue.
Definition Span.h:537
bool HasParseError() const
Whether a parse error has occurred in the last parsing.
Definition document.h:2773
GenericDocument & Parse(const typename SourceEncoding::Ch *str)
Parse JSON text from a read-only string (with Encoding conversion)
Definition document.h:2710
ParseErrorCode GetParseError() const
Get the ParseErrorCode of last parsing.
Definition document.h:2776
GenericValue< Encoding, Allocator > name
name of member (must be a string)
Definition document.h:123
GenericValue< Encoding, Allocator > value
value of member.
Definition document.h:124
GenericMemberIterator< false, UTF8<>, RAPIDJSON_DEFAULT_ALLOCATOR >::Iterator MemberIterator
Definition document.h:677
GenericMember< UTF8<>, RAPIDJSON_DEFAULT_ALLOCATOR > Member
Definition document.h:672
GenericMemberIterator< true, UTF8<>, RAPIDJSON_DEFAULT_ALLOCATOR >::Iterator ConstMemberIterator
Definition document.h:678
GenericDocument< UTF8<> > Document
GenericDocument with UTF8 encoding.
Definition document.h:2891
ParseErrorCode
Error code of parsing.
Definition error.h:65
@ kParseErrorDocumentEmpty
The document is empty.
Definition error.h:68
@ kParseErrorNumberMissFraction
Miss fraction part in number.
Definition error.h:86
@ kParseErrorStringInvalidEncoding
Invalid encoding in string.
Definition error.h:83
@ kParseErrorValueInvalid
Invalid value.
Definition error.h:71
@ kParseErrorDocumentRootNotSingular
The document root must not follow by other values.
Definition error.h:69
@ kParseErrorUnspecificSyntaxError
Unspecific syntax error.
Definition error.h:90
@ kParseErrorObjectMissCommaOrCurlyBracket
Missing a comma or '}' after an object member.
Definition error.h:75
@ kParseErrorObjectMissColon
Missing a colon after a name of object member.
Definition error.h:74
@ kParseErrorStringMissQuotationMark
Missing a closing quotation mark in string.
Definition error.h:82
@ kParseErrorTermination
Parsing was terminated.
Definition error.h:89
@ kParseErrorNumberMissExponent
Miss exponent in number.
Definition error.h:87
@ kParseErrorStringEscapeInvalid
Invalid escape character in string.
Definition error.h:81
@ kParseErrorArrayMissCommaOrSquareBracket
Missing a comma or ']' after an array element.
Definition error.h:77
@ kParseErrorNone
No error.
Definition error.h:66
@ kParseErrorStringUnicodeSurrogateInvalid
The surrogate pair in string is invalid.
Definition error.h:80
@ kParseErrorObjectMissName
Missing a name for object member.
Definition error.h:73
@ kParseErrorNumberTooBig
Number too big to be stored in double.
Definition error.h:85
@ kParseErrorStringUnicodeEscapeInvalidHex
Incorrect hex digit after \u escape in string.
Definition error.h:79
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
std::int64_t Int64
Type entier signé sur 64 bits.
double Real
Type représentant un réel.
Impl::SpanTypeFromSize< conststd::byte, SizeType >::SpanType asBytes(const SpanImpl< DataType, SizeType, Extent > &s)
Converti la vue en un tableau d'octets non modifiables.
Definition Span.h:1022
unsigned char Byte
Type d'un octet.
Definition BaseTypes.h:43
std::int32_t Int32
Type entier signé sur 32 bits.
main RapidJSON namespace
Result of parsing (wraps ParseErrorCode)
Definition error.h:107
ParseErrorCode Code() const
Get the error code.
Definition error.h:117
size_t Offset() const
Get the error offset, if IsError(), 0 otherwise.
Definition error.h:119