Arcane  4.1.12.0
User documentation
Loading...
Searching...
No Matches
JSONWriter.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/* JSONWriter.cc (C) 2000-2025 */
9/* */
10/* JSON format writer. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arccore/common/JSONWriter.h"
16#include "arccore/base/String.h"
17#include "arccore/base/FatalErrorException.h"
18#include <limits>
19
20// The following two lines allow using 64-bit indices
21// instead of the default 32-bit ones.
22#define RAPIDJSON_NO_SIZETYPEDEFINE
23namespace rapidjson
24{
25typedef ::std::size_t SizeType;
26}
27
28#define RAPIDJSON_HAS_STDSTRING 1
29#include "arccore/common/internal/json/rapidjson/writer.h"
30#include "arccore/common/internal/json/rapidjson/prettywriter.h"
31#include "arccore/common/internal/json/rapidjson/document.h"
32#include "arccore/common/internal/json/rapidjson/stringbuffer.h"
33
34#include <sstream>
35#include <iomanip>
36
37/*---------------------------------------------------------------------------*/
38/*---------------------------------------------------------------------------*/
39
40namespace Arcane
41{
42
43/*---------------------------------------------------------------------------*/
44/*---------------------------------------------------------------------------*/
45
47{
48 public:
49
50 Impl(bool use_hex_float)
51 : m_writer(m_buffer)
52 , m_use_hex_float(use_hex_float)
53 {
54 m_writer.SetIndent(' ', 1);
55 m_writer.SetFormatOptions(rapidjson::kFormatSingleLineArray);
56 m_real_ostr.precision(std::numeric_limits<Real>::max_digits10);
57 }
58
59 public:
60
61 void writeKey(StringView key)
62 {
63 Span<const Byte> bytes = key.bytes();
64 Int64 size = bytes.size();
65 if (size == 0)
66 ARCCORE_FATAL("null size");
67 // TODO: check if we always need to put 'true' and thus make a copy.
68 m_writer.Key((const char*)bytes.data(), size, true);
69 }
70 void writeStringValue(StringView value)
71 {
72 Span<const Byte> bytes = value.bytes();
73 Int64 size = bytes.size();
74 if (size == 0) {
75 m_writer.Null();
76 return;
77 }
78 // TODO: check if we always need to put 'true' and thus make a copy.
79 m_writer.String((const char*)bytes.data(), size, true);
80 }
81 void writeStringValue(const std::string& value)
82 {
83 m_writer.String(value);
84 }
85 void write(StringView key, const char* v);
86 void write(StringView key, Real v)
87 {
88 writeKey(key);
89 if (m_use_hex_float) {
90 char buf[32];
91 sprintf(buf, "%a", v);
92 m_writer.String(buf);
93 }
94 else
95 m_writer.Double(v);
96 }
97 void write(StringView key, Span<const Real> view)
98 {
99 writeKey(key);
100 {
101 m_real_ostr.str(std::string());
102 // NOTE: with C++11, we can use std::hexfloat as a modifier
103 // to write directly in floating hexadecimal. However, it only works
104 // starting from GCC 5.0 or Visual Studio 2015.
105 // ostr << std::hexfloat;
106 char buf[32];
107 for (Int64 i = 0, n = view.size(); i < n; ++i) {
108 if (i != 0)
109 m_real_ostr << ' ';
110 if (m_use_hex_float) {
111 sprintf(buf, "%a", view[i]);
112 m_real_ostr << buf;
113 }
114 else
115 m_real_ostr << view[i];
116 }
117 writeStringValue(m_real_ostr.str());
118 }
119 }
120
121 public:
122
123 rapidjson::StringBuffer m_buffer;
124 rapidjson::PrettyWriter<rapidjson::StringBuffer> m_writer;
125 bool m_use_hex_float;
126 std::ostringstream m_real_ostr;
127};
128
129/*---------------------------------------------------------------------------*/
130/*---------------------------------------------------------------------------*/
131
132JSONWriter::
133JSONWriter(FormatFlags format_flags)
134: m_p(nullptr)
135{
136 bool use_hex_float = (int)format_flags & (int)FormatFlags::HexFloat;
137 m_p = new Impl(use_hex_float);
138}
139
140JSONWriter::
141~JSONWriter()
142{
143 delete m_p;
144}
145
146void JSONWriter::
147beginObject()
148{
149 m_p->m_writer.StartObject();
150}
151void JSONWriter::
152endObject()
153{
154 m_p->m_writer.EndObject();
155}
156void JSONWriter::
157writeKey(StringView key)
158{
159 m_p->writeKey(key);
160}
161void JSONWriter::
162beginArray()
163{
164 m_p->m_writer.StartArray();
165}
166void JSONWriter::
167endArray()
168{
169 m_p->m_writer.EndArray();
170}
171
172void JSONWriter::
173writeValue(StringView str)
174{
175 m_p->writeStringValue(str);
176}
177void JSONWriter::
178write(StringView key, bool v)
179{
180 m_p->writeKey(key);
181 m_p->m_writer.Bool(v);
182}
183void JSONWriter::
184_writeInt64(StringView key, Int64 v)
185{
186 m_p->writeKey(key);
187 m_p->m_writer.Int64(v);
188}
189void JSONWriter::
190_writeUInt64(StringView key, UInt64 v)
191{
192 m_p->writeKey(key);
193 m_p->m_writer.Uint64(v);
194}
195void JSONWriter::
196write(StringView key, Real v)
197{
198 m_p->write(key, v);
199}
200void JSONWriter::
201write(StringView key, StringView str)
202{
203 m_p->writeKey(key);
204 m_p->writeStringValue(str);
205}
206void JSONWriter::
207write(StringView key, const char* v)
208{
209 m_p->writeKey(key);
210 m_p->writeStringValue(StringView(v));
211}
212void JSONWriter::
213write(StringView key, std::string_view v)
214{
215 m_p->writeKey(key);
216 m_p->writeStringValue(v);
217}
218void JSONWriter::
219writeIfNotNull(StringView key, const String& str)
220{
221 if (str.null())
222 return;
223 m_p->writeKey(key);
224 m_p->writeStringValue(str);
225}
226
227void JSONWriter::
228write(StringView key, Span<const Int32> view)
229{
230 m_p->writeKey(key);
231 m_p->m_writer.StartArray();
232 for (Int64 i = 0, n = view.size(); i < n; ++i)
233 m_p->m_writer.Int(view[i]);
234 m_p->m_writer.EndArray();
235}
236
237void JSONWriter::
238write(StringView key, Span<const Int64> view)
239{
240 m_p->writeKey(key);
241 m_p->m_writer.StartArray();
242 for (Int64 i = 0, n = view.size(); i < n; ++i)
243 m_p->m_writer.Int64(view[i]);
244 m_p->m_writer.EndArray();
245}
246
247void JSONWriter::
248write(StringView key, Span<const Real> view)
249{
250 m_p->write(key, view);
251}
252
253/*---------------------------------------------------------------------------*/
254/*---------------------------------------------------------------------------*/
255
256StringView JSONWriter::
257getBuffer() const
258{
259 const Byte* buf_chars = reinterpret_cast<const Byte*>(m_p->m_buffer.GetString());
260 Span<const Byte> bytes(buf_chars, m_p->m_buffer.GetSize());
261 return StringView(bytes);
262}
263
264/*---------------------------------------------------------------------------*/
265/*---------------------------------------------------------------------------*/
266
267} // namespace Arcane
268
269/*---------------------------------------------------------------------------*/
270/*---------------------------------------------------------------------------*/
#define ARCCORE_FATAL(...)
Macro throwing a FatalErrorException.
Types and functions associated with the classes ArrayView and ConstArrayView.
constexpr __host__ __device__ pointer data() const noexcept
Pointer to the start of the view.
Definition Span.h:539
constexpr __host__ __device__ SizeType size() const noexcept
Returns the size of the array.
Definition Span.h:327
View of an array of elements of type T.
Definition Span.h:635
View of a UTF-8 character string.
Definition StringView.h:44
constexpr Span< const Byte > bytes() const ARCCORE_NOEXCEPT
Returns the conversion of the instance in UTF-8 encoding.
Definition StringView.h:93
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
std::uint64_t UInt64
Unsigned integer type of 64 bits.
std::int64_t Int64
Signed integer type of 64 bits.
double Real
Type representing a real number.
unsigned char Byte
Type of a byte.
Definition BaseTypes.h:43