Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
JSONReader.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2023 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-2023 */
9/* */
10/* Lecteur au format JSON. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/JSONReader.h"
15#include "arcane/utils/FatalErrorException.h"
16#include "arcane/utils/ValueConvert.h"
17#include "arcane/utils/CheckedConvert.h"
18
19#define RAPIDJSON_HAS_STDSTRING 1
20#include "arcane/utils/internal/json/rapidjson/document.h"
21#include "arcane/utils/internal/json/rapidjson/stringbuffer.h"
22
23#include <iostream>
24
25/*---------------------------------------------------------------------------*/
26/*---------------------------------------------------------------------------*/
27
28namespace Arcane
29{
30
31/*---------------------------------------------------------------------------*/
32/*---------------------------------------------------------------------------*/
33
35{
36 public:
37 rapidjson::Value::Member* toMember() const
38 {
39 return (rapidjson::Value::Member*)(this);
40 }
41};
42
44{
45 public:
46 rapidjson::Value* toValue() const
47 {
48 return (rapidjson::Value*)(this);
49 }
50};
51
53{
54 public:
55 static JSONKeyValue build(rapidjson::Value::Member* v)
56 {
57 return JSONKeyValue((JSONKeyValue::Impl*)(v));
58 }
59 static JSONKeyValue build(rapidjson::Value::ConstMemberIterator v)
60 {
61 return JSONKeyValue((JSONKeyValue::Impl*)&(*v));
62 }
63 static JSONValue build(rapidjson::Value* v)
64 {
65 return JSONValue((JSONValue::Impl*)(v));
66 }
67};
68
69/*
70 * Types définis par rapidjson.
71 enum Type {
72 kNullType = 0, //!< null
73 kFalseType = 1, //!< false
74 kTrueType = 2, //!< true
75 kObjectType = 3, //!< object
76 kArrayType = 4, //!< array
77 kStringType = 5, //!< string
78 kNumberType = 6 //!< number
79};
80*/
81
82/*---------------------------------------------------------------------------*/
83/*---------------------------------------------------------------------------*/
84
85StringView JSONKeyValue::
86name() const
87{
88 if (!m_p)
89 return StringView();
90 auto& x = m_p->toMember()->name;
91 if (x.IsString())
92 return StringView(Span<const Byte>((const Byte*)x.GetString(),x.GetStringLength()));
93 return StringView();
94}
95
96/*---------------------------------------------------------------------------*/
97/*---------------------------------------------------------------------------*/
98
99JSONValue JSONKeyValue::
100value() const
101{
102 if (!m_p)
103 return JSONValue();
104 auto& x = m_p->toMember()->value;
105 return JSONWrapperUtils::build(&x);
106}
107
108/*---------------------------------------------------------------------------*/
109/*---------------------------------------------------------------------------*/
110
112value() const
113{
114 if (!m_p)
115 return String();
116 auto x = m_p->toValue();
117 if (x->IsString())
118 return String(Span<const Byte>((const Byte*)x->GetString(),x->GetStringLength()));
119 return String();
120}
121
122/*---------------------------------------------------------------------------*/
123/*---------------------------------------------------------------------------*/
124
126valueAsStringView() const
127{
128 if (!m_p)
129 return StringView();
130 auto x = m_p->toValue();
131 if (x->IsString())
132 return StringView(Span<const Byte>((const Byte*)x->GetString(),x->GetStringLength()));
133 return StringView();
134}
135
136/*---------------------------------------------------------------------------*/
137/*---------------------------------------------------------------------------*/
138
139StringView JSONValue::
140valueAsString() const
141{
142 return valueAsStringView();
143}
144
145/*---------------------------------------------------------------------------*/
146/*---------------------------------------------------------------------------*/
147
149valueAsInt64() const
150{
151 if (!m_p)
152 return 0;
153 auto x = m_p->toValue();
154 if (x->IsInt64())
155 return x->GetInt64();
156 return 0;
157}
158
159/*---------------------------------------------------------------------------*/
160/*---------------------------------------------------------------------------*/
161
163valueAsBool() const
164{
165 if (!m_p)
166 return false;
167 auto x = m_p->toValue();
168 if (x->IsBool())
169 return x->GetBool();
170 return false;
171}
172
173/*---------------------------------------------------------------------------*/
174/*---------------------------------------------------------------------------*/
175
177valueAsInt32() const
178{
179 Int64 v = valueAsInt64();
180 return CheckedConvert::toInt32(v);
181}
182
183/*---------------------------------------------------------------------------*/
184/*---------------------------------------------------------------------------*/
185
187valueAsReal() const
188{
189 if (!m_p)
190 return 0;
191 auto x = m_p->toValue();
192 std::cout << "TYPE=" << x->GetType() << "\n";
193 if (x->IsDouble())
194 return x->GetDouble();
195 if (x->GetType()==rapidjson::kStringType){
196 // Convertie la chaîne de caractères en un réél
197 StringView s = this->valueAsStringView();
198 Real r = 0.0;
199 if (!builtInGetValue(r,s))
200 return r;
201 }
202 return 0.0;
203}
204
205/*---------------------------------------------------------------------------*/
206/*---------------------------------------------------------------------------*/
207
208JSONKeyValue JSONValue::
209keyValueChild(StringView name) const
210{
211 if (!m_p)
212 return JSONKeyValue();
213 auto d = m_p->toValue();
214 rapidjson::Value::MemberIterator x = d->FindMember((const char*)(name.bytes().data()));
215 if (x==d->MemberEnd())
216 return JSONKeyValue();
217 return JSONWrapperUtils::build(x);
218}
219
220/*---------------------------------------------------------------------------*/
221/*---------------------------------------------------------------------------*/
222
224child(StringView name) const
225{
226 return keyValueChild(name).value();
227}
228
229/*---------------------------------------------------------------------------*/
230/*---------------------------------------------------------------------------*/
231
233expectedChild(StringView name) const
234{
235 JSONKeyValue k = keyValueChild(name);
236 if (!k)
237 ARCANE_FATAL("No key '{0}' found in json document",name);
238 return k.value();
239}
240
241/*---------------------------------------------------------------------------*/
242/*---------------------------------------------------------------------------*/
243
244JSONValueList JSONValue::
245children() const
246{
247 if (!m_p)
248 return JSONValueList();
249 auto d = m_p->toValue();
250 JSONValueList values;
251 if (!d->IsObject())
252 ARCANE_FATAL("The value has to be of type 'object'");
253 for( auto& x : d->GetObject()){
254 auto y = JSONWrapperUtils::build(&x);
255 values.add(y.value());
256 }
257 return values;
258}
259
260/*---------------------------------------------------------------------------*/
261/*---------------------------------------------------------------------------*/
262
263JSONValueList JSONValue::
264valueAsArray() const
265{
266 if (!m_p)
267 return JSONValueList();
268 auto d = m_p->toValue();
269 JSONValueList values;
270 if (!d->IsArray())
271 ARCANE_FATAL("The value has to be of type 'array'");
272 for( rapidjson::SizeType i = 0; i < d->Size(); ++i ){
273 rapidjson::Value& x = (*d)[i];
274 auto y = JSONWrapperUtils::build(&x);
275 values.add(y);
276 }
277 return values;
278}
279
280/*---------------------------------------------------------------------------*/
281/*---------------------------------------------------------------------------*/
282
283bool JSONValue::
284isArray() const
285{
286 if (!m_p)
287 return false;
288 auto d = m_p->toValue();
289 return d->IsArray();
290}
291
292/*---------------------------------------------------------------------------*/
293/*---------------------------------------------------------------------------*/
294
295bool JSONValue::
296isObject() const
297{
298 if (!m_p)
299 return false;
300 auto d = m_p->toValue();
301 return d->IsObject();
302}
303
304/*---------------------------------------------------------------------------*/
305/*---------------------------------------------------------------------------*/
306
307JSONKeyValueList JSONValue::
308keyValueChildren() const
309{
310 if (!m_p)
311 return JSONKeyValueList();
312 auto d = m_p->toValue();
313 JSONKeyValueList values;
314 for( auto& x : d->GetObject()){
315 auto y = JSONWrapperUtils::build(&x);
316 values.add(y);
317 }
318 return values;
319}
320
321/*---------------------------------------------------------------------------*/
322/*---------------------------------------------------------------------------*/
323
324/*---------------------------------------------------------------------------*/
325/*---------------------------------------------------------------------------*/
326
328{
329 public:
330 Impl() : m_document()
331 {
332 }
333 public:
334 rapidjson::Document m_document;
335};
336
337/*---------------------------------------------------------------------------*/
338/*---------------------------------------------------------------------------*/
339
340JSONDocument::
341JSONDocument()
342: m_p(nullptr)
343{
344 m_p = new Impl();
345}
346
347JSONDocument::
348~JSONDocument()
349{
350 delete m_p;
351}
352
353namespace
354{
355using namespace rapidjson;
356
357const char*
358_getErrorCodeString(ParseErrorCode c)
359{
360 switch(c) {
361 case kParseErrorNone: return "No error";
362 case kParseErrorDocumentEmpty: return "The document is empty";
363 case kParseErrorDocumentRootNotSingular: return "The document root must not follow by other values";
364 case kParseErrorValueInvalid: return "Invalid value";
365 case kParseErrorObjectMissName: return "Missing a name for object member";
366 case kParseErrorObjectMissColon: return "Missing a colon after a name of object member";
367 case kParseErrorObjectMissCommaOrCurlyBracket: return "Missing a comma or '}' after an object member";
368 case kParseErrorArrayMissCommaOrSquareBracket: return "Missing a comma or ']' after an array element";
369 case kParseErrorStringUnicodeEscapeInvalidHex: return "Incorrect hex digit after \\u escape in string";
370 case kParseErrorStringUnicodeSurrogateInvalid: return "The surrogate pair in string is invalid";
371 case kParseErrorStringEscapeInvalid: return "Invalid escape character in string";
372 case kParseErrorStringMissQuotationMark: return "Missing a closing quotation mark in string";
373 case kParseErrorStringInvalidEncoding: return "Invalid encoding in string";
374 case kParseErrorNumberTooBig: return "Number too big to be stored in double";
375 case kParseErrorNumberMissFraction: return "Miss fraction part in number";
376 case kParseErrorNumberMissExponent: return "Miss exponent in number";
377 case kParseErrorTermination: return "Parsing was terminated";
378 case kParseErrorUnspecificSyntaxError: return "Unspecific syntax error";
379 default:
380 return "Unknown";
381 }
382 return "Unknown";
383}
384}
385
386/*---------------------------------------------------------------------------*/
387/*---------------------------------------------------------------------------*/
388
391{
392 using namespace rapidjson;
393 Document& d = m_p->m_document;
394 ParseResult r = d.Parse((const char*)bytes.data(),bytes.size());
395 if (d.HasParseError()){
396 std::cout << "ERROR: " << d.GetParseError() << "\n";
397 ARCANE_FATAL("Parsing error file='{0}' ret={1} position={2} message='{3}'",
398 filename,d.GetParseError(),
399 r.Offset(),_getErrorCodeString(r.Code()));
400 }
401}
402
403/*---------------------------------------------------------------------------*/
404/*---------------------------------------------------------------------------*/
405
408{
409 parse(bytes,"(Unknown)");
410}
411
412/*---------------------------------------------------------------------------*/
413/*---------------------------------------------------------------------------*/
414
417{
418 parse(asBytes(bytes));
419}
420
421/*---------------------------------------------------------------------------*/
422/*---------------------------------------------------------------------------*/
423
425parse(Span<const Byte> bytes,StringView filename)
426{
427 parse(asBytes(bytes),filename);
428}
429
430/*---------------------------------------------------------------------------*/
431/*---------------------------------------------------------------------------*/
432
434root() const
435{
436 rapidjson::Value& d = m_p->m_document;
437 return JSONWrapperUtils::build(&d);
438}
439
440/*---------------------------------------------------------------------------*/
441/*---------------------------------------------------------------------------*/
442
443} // End namespace Arcane
444
445/*---------------------------------------------------------------------------*/
446/*---------------------------------------------------------------------------*/
447
#define ARCANE_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 valeurs d'un document JSON.
Definition JSONReader.h:199
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__ SizeType size() const noexcept
Retourne la taille du tableau.
Definition Span.h:209
constexpr __host__ __device__ pointer data() const noexcept
Pointeur sur le début de la vue.
Definition Span.h:419
Vue d'un tableau d'éléments de type T.
Definition Span.h:510
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.
Int32 toInt32(Int64 v)
Converti un Int64 en un Int32.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
unsigned char Byte
Type d'un octet.
Definition UtilsTypes.h:142