Arcane  4.2.1.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-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// Voir le fichier COPYRIGHT de niveau supérieur pour les détails.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* JSONReader.cc (C) 2000-2026 */
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, //!< objet
80 kArrayType = 4, //!< tableau
81 kStringType = 5, //!< chaîne de caractères
82 kNumberType = 6 //!< nombre
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 if (x->IsDouble())
197 return x->GetDouble();
198 if (x->GetType() == rapidjson::kStringType) {
199 // Convertir la chaîne en un réel
200 StringView s = this->valueAsStringView();
201 Real r = 0.0;
202 if (!Convert::Impl::StringViewToIntegral::getValue(r, s))
203 return r;
204 }
205 return 0.0;
206}
207
208/*---------------------------------------------------------------------------*/
209/*---------------------------------------------------------------------------*/
210
212valueAsUInt64() const
213{
214 if (!m_p)
215 return 0;
216 auto x = m_p->toValue();
217 if (x->IsUint64())
218 return x->GetUint64();
219 return 0;
220}
221
222/*---------------------------------------------------------------------------*/
223/*---------------------------------------------------------------------------*/
224
225JSONKeyValue JSONValue::
226keyValueChild(StringView name) const
227{
228 if (!m_p)
229 return JSONKeyValue();
230 auto d = m_p->toValue();
231 rapidjson::Value::MemberIterator x = d->FindMember((const char*)(name.bytes().data()));
232 if (x == d->MemberEnd())
233 return JSONKeyValue();
234 return JSONWrapperUtils::build(x);
235}
236
237/*---------------------------------------------------------------------------*/
238/*---------------------------------------------------------------------------*/
239
240JSONValue JSONValue::
241child(StringView name) const
242{
243 return keyValueChild(name).value();
244}
245
246/*---------------------------------------------------------------------------*/
247/*---------------------------------------------------------------------------*/
248
249JSONValue JSONValue::
250expectedChild(StringView name) const
251{
252 JSONKeyValue k = keyValueChild(name);
253 if (!k)
254 ARCCORE_FATAL("No key '{0}' found in json document", name);
255 return k.value();
256}
257
258/*---------------------------------------------------------------------------*/
259/*---------------------------------------------------------------------------*/
260
261JSONValueList JSONValue::
262children() const
263{
264 if (!m_p)
265 return JSONValueList();
266 auto d = m_p->toValue();
267 JSONValueList values;
268 if (!d->IsObject())
269 ARCCORE_FATAL("The value has to be of type 'object'");
270 for (auto& x : d->GetObject()) {
271 auto y = JSONWrapperUtils::build(&x);
272 values.add(y.value());
273 }
274 return values;
275}
276
277/*---------------------------------------------------------------------------*/
278/*---------------------------------------------------------------------------*/
279
280JSONValueList JSONValue::
281valueAsArray() const
282{
283 if (!m_p)
284 return JSONValueList();
285 auto d = m_p->toValue();
286 JSONValueList values;
287 if (!d->IsArray())
288 ARCCORE_FATAL("The value has to be of type 'array'");
289 for (rapidjson::SizeType i = 0; i < d->Size(); ++i) {
290 rapidjson::Value& x = (*d)[i];
291 auto y = JSONWrapperUtils::build(&x);
292 values.add(y);
293 }
294 return values;
295}
296
297/*---------------------------------------------------------------------------*/
298/*---------------------------------------------------------------------------*/
299
300bool JSONValue::
301isArray() const
302{
303 if (!m_p)
304 return false;
305 auto d = m_p->toValue();
306 return d->IsArray();
307}
308
309/*---------------------------------------------------------------------------*/
310/*---------------------------------------------------------------------------*/
311
312bool JSONValue::
313isObject() const
314{
315 if (!m_p)
316 return false;
317 auto d = m_p->toValue();
318 return d->IsObject();
319}
320
321/*---------------------------------------------------------------------------*/
322/*---------------------------------------------------------------------------*/
323
324JSONKeyValueList JSONValue::
325keyValueChildren() const
326{
327 if (!m_p)
328 return JSONKeyValueList();
329 auto d = m_p->toValue();
330 JSONKeyValueList values;
331 for (auto& x : d->GetObject()) {
332 auto y = JSONWrapperUtils::build(&x);
333 values.add(y);
334 }
335 return values;
336}
337
339isNull() const
340{
341 if (!m_p)
342 return true;
343 return m_p->toValue()->IsNull();
344}
345
347isBool() const
348{
349 if (!m_p)
350 return false;
351 return m_p->toValue()->IsBool();
352}
353
355isString() const
356{
357 if (!m_p)
358 return false;
359 return m_p->toValue()->IsString();
360}
361
363isNumber() const
364{
365 if (!m_p)
366 return false;
367 return m_p->toValue()->IsNumber();
368}
369
371isInt64() const
372{
373 if (!m_p)
374 return false;
375 return m_p->toValue()->IsInt64();
376}
377
379isUint64() const
380{
381 if (!m_p)
382 return false;
383 return m_p->toValue()->IsUint64();
384}
385
386/*---------------------------------------------------------------------------*/
387/*---------------------------------------------------------------------------*/
388
389/*---------------------------------------------------------------------------*/
390/*---------------------------------------------------------------------------*/
391
393{
394 public:
395
396 Impl()
397 : m_document()
398 {
399 }
400
401 public:
402
403 rapidjson::Document m_document;
404};
405
406/*---------------------------------------------------------------------------*/
407/*---------------------------------------------------------------------------*/
408
409JSONDocument::
410JSONDocument()
411{
412 m_p = new Impl();
413}
414
415JSONDocument::
416~JSONDocument()
417{
418 delete m_p;
419}
420
421namespace
422{
423 using namespace rapidjson;
424
425 const char*
426 _getErrorCodeString(ParseErrorCode c)
427 {
428 switch (c) {
429 case kParseErrorNone:
430 return "No error";
432 return "The document is empty";
434 return "The document root must not follow by other values";
436 return "Invalid value";
438 return "Missing a name for object member";
440 return "Missing a colon after a name of object member";
442 return "Missing a comma or '}' after an object member";
444 return "Missing a comma or ']' after an array element";
446 return "Incorrect hex digit after \\u escape in string";
448 return "The surrogate pair in string is invalid";
450 return "Invalid escape character in string";
452 return "Missing a closing quotation mark in string";
454 return "Invalid encoding in string";
456 return "Number too big to be stored in double";
458 return "Miss fraction part in number";
460 return "Miss exponent in number";
462 return "Parsing was terminated";
464 return "Unspecific syntax error";
465 default:
466 return "Unknown";
467 }
468 return "Unknown";
469 }
470} // namespace
471
472/*---------------------------------------------------------------------------*/
473/*---------------------------------------------------------------------------*/
474
477{
478 using namespace rapidjson;
479 Document& d = m_p->m_document;
480 ParseResult r = d.Parse((const char*)bytes.data(), bytes.size());
481 if (d.HasParseError()) {
482 std::cout << "ERROR: " << d.GetParseError() << "\n";
483 ARCCORE_FATAL("Parsing error file='{0}' ret={1} position={2} message='{3}'",
484 filename, d.GetParseError(),
485 r.Offset(), _getErrorCodeString(r.Code()));
486 }
487}
488
489/*---------------------------------------------------------------------------*/
490/*---------------------------------------------------------------------------*/
491
494{
495 parse(bytes, "(Unknown)");
496}
497
498/*---------------------------------------------------------------------------*/
499/*---------------------------------------------------------------------------*/
500
503{
504 parse(asBytes(bytes));
505}
506
507/*---------------------------------------------------------------------------*/
508/*---------------------------------------------------------------------------*/
509
511parse(Span<const Byte> bytes, StringView filename)
512{
513 parse(asBytes(bytes), filename);
514}
515
516/*---------------------------------------------------------------------------*/
517/*---------------------------------------------------------------------------*/
518
520root() const
521{
522 rapidjson::Value& d = m_p->m_document;
523 return JSONWrapperUtils::build(&d);
524}
525
526/*---------------------------------------------------------------------------*/
527/*---------------------------------------------------------------------------*/
528
529} // namespace Arcane
530
531/*---------------------------------------------------------------------------*/
532/*---------------------------------------------------------------------------*/
#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.
bool isUint64() const
Vrai si la valeur est un entier dans la plage 'UInt64'.
UInt64 valueAsUInt64() const
Valeur sous forme de UInt64. Retourn 0 si 'null()' est vrai.
Int32 valueAsInt32() const
Valeur sous forme de Int32. 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.
bool isInt64() const
Vrai si la valeur est un entier dans la plage 'Int64'.
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é.
bool isBool() const
Vrai si la valeur est un booléen.
bool isString() const
Vrai si la valeur est une chaîne de caractères.
bool isNull() const
Vrai si la valeur est de type 'null'.
JSONValue child(StringView name) const
Valeur fille de nom name. Retourne une valeur nulle si non trouvé.
bool isNumber() const
Vrai si la valeur est un nombre.
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::uint64_t UInt64
Type entier non signé sur 64 bits.
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)
Convertit la vue en un tableau d'octets non modifiables.
Definition Span.h:1028
unsigned char Byte
Type d'un octet.
Definition BaseTypes.h:42
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