Arcane  v4.1.0.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
SerializedData.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2024 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/* SerializedData.cc (C) 2000-2024 */
9/* */
10/* Donnée sérialisée. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/ISerializedData.h"
15
17
18#include "arcane/utils/Ref.h"
19#include "arcane/utils/NotImplementedException.h"
20#include "arcane/utils/NotSupportedException.h"
21#include "arcane/utils/FatalErrorException.h"
22#include "arcane/utils/IHashAlgorithm.h"
23#include "arcane/utils/CheckedConvert.h"
24#include "arcane/utils/Array.h"
25#include "arcane/utils/ArrayShape.h"
26
27#include "arcane/ISerializer.h"
28
29/*---------------------------------------------------------------------------*/
30/*---------------------------------------------------------------------------*/
31
32namespace Arcane
33{
34
35namespace
36{
37 const Int64 SERIALIZE_MAGIC_NUMBER = 0x6b90ac81;
38}
39
40/*---------------------------------------------------------------------------*/
41/*---------------------------------------------------------------------------*/
46class SerializedData
48, public ISerializedData
49{
50 ARCCORE_DEFINE_REFERENCE_COUNTED_INCLASS_METHODS();
51
52 public:
53
54 SerializedData();
55 SerializedData(eDataType base_data_type, Int64 memory_size,
56 Integer nb_dimension, Int64 nb_element, Int64 nb_base_element,
57 bool is_multi_size, Int64ConstArrayView extents, const ArrayShape& shape);
58
59 public:
60
61 eDataType baseDataType() const override { return m_base_data_type; }
62 Integer nbDimension() const override { return m_nb_dimension; }
63 Int64 nbElement() const override { return m_nb_element; }
64 bool isMultiSize() const override { return m_is_multi_size; }
65 Int64 memorySize() const override { return m_memory_size; }
66 Int64ConstArrayView extents() const override { return m_extents; }
67 ArrayShape shape() const override { return m_shape; }
68 Int64 nbBaseElement() const override { return m_nb_base_element; }
69 ByteConstArrayView buffer() const override { return m_const_buffer.constSmallView(); }
70 ByteArrayView buffer() override { return m_buffer.smallView(); }
71 Span<const Byte> bytes() const override { return m_const_buffer; }
72 Span<const Byte> constBytes() const override { return m_const_buffer; }
73 Span<Byte> bytes() override { return m_buffer; }
74 void setBuffer(ByteArrayView buffer) override;
75 void setBuffer(ByteConstArrayView buffer) override;
78 Span<Byte> writableBytes() override { return m_buffer; }
79 void setWritableBytes(Span<Byte> bytes) override;
81 void allocateMemory(Int64 size) override;
82
83 public:
84
85 void serialize(ISerializer* buffer) override;
86 void serialize(ISerializer* buffer) const override;
87
88 public:
89
90 void computeHash(IHashAlgorithm* algo, ByteArray& output) const override;
91
92 private:
93
94 eDataType m_base_data_type;
95 Int64 m_memory_size;
96 Integer m_nb_dimension;
97 Int64 m_nb_element;
98 Int64 m_nb_base_element;
99 bool m_is_multi_size;
100 // TODO: supprimer le champs 'm_dimensions' mais cela implique de
101 // changer la valeur de computeHash() donc à voir le meilleur moment
102 // pour le faire.
103 UniqueArray<Int32> m_dimensions;
104 UniqueArray<Int64> m_extents;
105 Int64 m_element_size;
106 Span<Byte> m_buffer;
107 Span<const Byte> m_const_buffer;
108 UniqueArray<Byte> m_stored_buffer;
109 ArrayShape m_shape;
110
111 private:
112
113 void _serialize(ISerializer* sbuf) const;
114 void _serializeRead(ISerializer* sbuf);
115 void _copyExtentsToDimensions();
116};
117
118/*---------------------------------------------------------------------------*/
119/*---------------------------------------------------------------------------*/
120
121SerializedData::
122SerializedData()
123: m_base_data_type(DT_Unknown)
124, m_memory_size(0)
125, m_nb_dimension(0)
126, m_nb_element(0)
127, m_nb_base_element(0)
128, m_is_multi_size(false)
129, m_element_size(0)
130{
131}
132
133/*---------------------------------------------------------------------------*/
134/*---------------------------------------------------------------------------*/
135
136SerializedData::
137SerializedData(eDataType base_data_type, Int64 memory_size,
138 Integer nb_dimension, Int64 nb_element, Int64 nb_base_element,
139 bool is_multi_size, Int64ConstArrayView extents, const ArrayShape& shape)
140: m_base_data_type(base_data_type)
141, m_memory_size(memory_size)
142, m_nb_dimension(nb_dimension)
143, m_nb_element(nb_element)
144, m_nb_base_element(nb_base_element)
145, m_is_multi_size(is_multi_size)
146, m_extents(extents)
147, m_element_size(dataTypeSize(m_base_data_type))
148, m_shape(shape)
149{
150 _copyExtentsToDimensions();
151 if (!is_multi_size && shape.nbDimension() == 0) {
152 if (nb_dimension == 1) {
153 m_shape.setNbDimension(1);
154 m_shape.setDimension(0, 1);
155 }
156 else if (nb_dimension > 1) {
157 m_shape.setNbDimension(nb_dimension - 1);
158 for (Int32 i = 1; i < nb_dimension; ++i)
159 m_shape.setDimension(i - 1, CheckedConvert::toInt32(extents[i]));
160 }
161 }
162}
163
164/*---------------------------------------------------------------------------*/
165/*---------------------------------------------------------------------------*/
166
167void SerializedData::
168_copyExtentsToDimensions()
169{
170 Integer n = m_extents.size();
171 m_dimensions.resize(n);
172 // Il ne faut pas lever d'exceptions si on dépasse les bornes sinon
173 // le code lèvera une exception dès que le nombre d'éléments du tableau
174 // dépasse 32 bits. Cela n'est pas très grave si les valeurs de 'm_dimensions'
175 // ne sont pas valide car ce n'est plus utilisé que dans computeHash() pour
176 // garder la valeur compatible.
177 for (Integer i = 0; i < n; ++i)
178 m_dimensions[i] = static_cast<Int32>(m_extents[i]);
179}
180
181/*---------------------------------------------------------------------------*/
182/*---------------------------------------------------------------------------*/
183
186{
187 setBytes(Span<Byte>(buffer));
188}
189
190/*---------------------------------------------------------------------------*/
191/*---------------------------------------------------------------------------*/
192
198
199/*---------------------------------------------------------------------------*/
200/*---------------------------------------------------------------------------*/
201
204{
205 m_buffer = buffer;
206 m_const_buffer = buffer;
207 m_stored_buffer.clear();
208 m_memory_size = buffer.size();
209}
210
211/*---------------------------------------------------------------------------*/
212/*---------------------------------------------------------------------------*/
213
216{
217 m_const_buffer = buffer;
218 m_buffer = Span<Byte>();
219 m_stored_buffer.clear();
220 m_memory_size = buffer.size();
221}
222
223/*---------------------------------------------------------------------------*/
224/*---------------------------------------------------------------------------*/
225
228{
229 m_stored_buffer = UniqueArray<Byte>(size);
230 m_buffer = m_stored_buffer;
231 m_const_buffer = m_stored_buffer.view();
232 m_memory_size = size;
233}
234
235/*---------------------------------------------------------------------------*/
236/*---------------------------------------------------------------------------*/
237
239computeHash(IHashAlgorithm* algo, ByteArray& output) const
240{
241 // TODO: faire avec le support 64 bits mais cela change le hash.
242 algo->computeHash64(m_const_buffer, output);
243 const Byte* ptr = reinterpret_cast<const Byte*>(m_dimensions.data());
244 Integer msize = CheckedConvert::multiply(m_dimensions.size(), (Integer)sizeof(Integer));
245 ByteConstArrayView dim_bytes(msize, ptr);
246 algo->computeHash64(dim_bytes, output);
247}
248
249/*---------------------------------------------------------------------------*/
250/*---------------------------------------------------------------------------*/
258serialize(ISerializer* sbuf) const
259{
260 _serialize(sbuf);
261}
262
263/*---------------------------------------------------------------------------*/
264/*---------------------------------------------------------------------------*/
265
268{
269 ISerializer::eMode mode = sbuf->mode();
270
271 switch (mode) {
272 case ISerializer::ModeReserve:
273 _serialize(sbuf);
274 break;
276 _serialize(sbuf);
277 break;
279 switch (sbuf->readMode()) {
281 _serializeRead(sbuf);
282 break;
285 break;
286 }
287 break;
288 }
289}
290
291/*---------------------------------------------------------------------------*/
292/*---------------------------------------------------------------------------*/
293
294void SerializedData::
295_serializeRead(ISerializer* sbuf)
296{
297 Int64 magic_number = sbuf->getInt64(); // Valeur magique pour vérification
298 if (magic_number != SERIALIZE_MAGIC_NUMBER)
299 ARCANE_FATAL("Bad magic number for SerializedData '{0}", magic_number);
300
301 Int32 version = sbuf->getInt32(); // Pour le numéro de version
302 if (version != 1)
303 ARCANE_FATAL("Bad magic number for SerializedData '{0}", magic_number);
304
305 m_base_data_type = (eDataType)sbuf->getInteger(); // Pour le m_base_data_type
306 m_memory_size = sbuf->getInt64(); // Pour le m_memory_size
307 m_nb_dimension = sbuf->getInteger(); // Pour le m_nb_dimension
308 m_nb_element = sbuf->getInt64(); // Pour le m_nb_element
309 m_nb_base_element = sbuf->getInt64(); // Pour le m_nb_base_element
310 m_is_multi_size = sbuf->getInteger(); // Pour le m_is_multi_size
311 m_element_size = sbuf->getInt64(); // Pour le m_element_size
312
313 // Lecture des dimensions
314 Int64 dimensions_size = sbuf->getInt64();
315 m_extents.resize(dimensions_size);
316 sbuf->getSpan(m_extents);
317 _copyExtentsToDimensions();
318
319 // Lecture de 'm_shape'
320 Int32 shape_nb_dim = sbuf->getInt32(); // Pour m_shape.nbDimension()
321 std::array<Int32,ArrayShape::MAX_NB_DIMENSION> shape_dims_buf;
322 Span<Int32> shape_dims(shape_dims_buf.data(),shape_nb_dim);
323 sbuf->getSpan(shape_dims); // Pour les dimensions
324 m_shape.setDimensions(shape_dims);
325
326 Int64 buffer_size = sbuf->getInt64();
327 m_stored_buffer.resize(buffer_size);
328 sbuf->getSpan(m_stored_buffer); // Pour les données
329 m_buffer = m_stored_buffer;
330 m_const_buffer = m_buffer;
331}
332
333/*---------------------------------------------------------------------------*/
334/*---------------------------------------------------------------------------*/
342_serialize(ISerializer* sbuf) const
343{
344 ISerializer::eMode mode = sbuf->mode();
345 if (m_extents.size() != m_dimensions.size())
346 ARCANE_FATAL("Incoherence between extents ({0}) and dimensions ({1})",
347 m_extents.size(), m_dimensions.size());
348
349 switch (mode) {
350 case ISerializer::ModeReserve:
351 sbuf->reserveInt64(1); // Valeur magique pour vérification
352 sbuf->reserveInt32(1); // Numéro de version
353 sbuf->reserveInteger(1); // Pour le m_base_data_type
354 sbuf->reserveInt64(1); // Pour le m_memory_size
355 sbuf->reserveInteger(1); // Pour le m_nb_dimension
356 sbuf->reserveInt64(1); // Pour le m_nb_element
357 sbuf->reserveInt64(1); // Pour le m_nb_base_element
358 sbuf->reserveInteger(1); // Pour le m_is_multi_size
359 sbuf->reserveInt64(1); // Pour le m_element_size
360
361 sbuf->reserveInt64(1); // Pour le m_extents.size()
362 sbuf->reserveSpan(eBasicDataType::Int64, m_extents.size()); // Pour les dimensions
363
364 sbuf->reserveInt32(1); // Pour le nombre de valeur de 'm_shape'
365 sbuf->reserveSpan(eBasicDataType::Int32, m_shape.nbDimension()); // Pour les données de 'm_shape'
366
367 sbuf->reserveInt64(1); // Pour le m_const_buffer.size()
368 sbuf->reserveSpan(eBasicDataType::Byte, m_const_buffer.size()); // Pour les données
369 break;
371 sbuf->putInt64(SERIALIZE_MAGIC_NUMBER); // Valeur magique pour vérification
372 sbuf->putInt32(1); // Numéro de version
373 sbuf->putInteger(m_base_data_type); // Pour le m_base_data_type
374 sbuf->putInt64(m_memory_size); // Pour le m_memory_size
375 sbuf->putInteger(m_nb_dimension); // Pour le m_nb_dimension
376 sbuf->putInt64(m_nb_element); // Pour le m_nb_element
377 sbuf->putInt64(m_nb_base_element); // Pour le m_nb_base_element
378 sbuf->putInteger(m_is_multi_size); // Pour le m_is_multi_size
379 sbuf->putInt64(m_element_size); // Pour le m_element_size
380
381 sbuf->putInt64(m_extents.size()); // Pour le m_extents.size()
382 sbuf->putSpan(m_extents); // Pour les dimensions
383
384 sbuf->putInt32(m_shape.nbDimension()); // Pour m_shape.nbDimension()
385 sbuf->putSpan(m_shape.dimensions()); // Pour les dimensions
386
387 sbuf->putInt64(m_const_buffer.size()); // Pour le m_const_buffer.size()
388 sbuf->putSpan(m_const_buffer); // Pour les données
389 break;
391 ARCANE_THROW(NotSupportedException, "ModeGet in const method");
392 }
393}
394
395/*---------------------------------------------------------------------------*/
396/*---------------------------------------------------------------------------*/
397
398extern "C++" ARCANE_CORE_EXPORT
401 Integer nb_dim, Int64 nb_element, Int64 nb_base_element,
402 bool is_multi_size, Int64ConstArrayView dimensions, const ArrayShape& shape)
403{
404 return createRef<SerializedData>(data_type, memory_size, nb_dim, nb_element,
405 nb_base_element, is_multi_size, dimensions, shape);
406}
407
408/*---------------------------------------------------------------------------*/
409/*---------------------------------------------------------------------------*/
410
411extern "C++" ARCANE_CORE_EXPORT
412Ref<ISerializedData>
414 Integer nb_dim, Int64 nb_element, Int64 nb_base_element,
415 bool is_multi_size, Int64ConstArrayView dimensions)
416{
417 return arcaneCreateSerializedDataRef(data_type, memory_size, nb_dim, nb_element,
418 nb_base_element, is_multi_size, dimensions, ArrayShape());
419}
420
421/*---------------------------------------------------------------------------*/
422/*---------------------------------------------------------------------------*/
423
424extern "C++" ARCANE_CORE_EXPORT
425Ref<ISerializedData>
430
431/*---------------------------------------------------------------------------*/
432/*---------------------------------------------------------------------------*/
433
434} // End namespace Arcane
435
436/*---------------------------------------------------------------------------*/
437/*---------------------------------------------------------------------------*/
#define ARCANE_THROW(exception_class,...)
Macro pour envoyer une exception avec formattage.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Forme d'un tableau.
Definition ArrayShape.h:40
void setDimensions(Span< const Int32 > dims)
Positionne le nombre et la valeur des dimensions.
Definition ArrayShape.cc:64
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
Interface d'un algorithme de hashage.
virtual void computeHash64(Span< const Byte > input, ByteArray &output)
Calcule la valeur du hash pour le tableau input.
Interface d'une donnée sérialisée.
virtual Integer getInteger()=0
Récupère une taille.
eMode
Mode de fonctionnement du sérialiseur.
@ ModePut
Le sérialiseur attend des reserve()
virtual Int64 getInt64()=0
Récupère une taille.
virtual void putInteger(Integer value)=0
Ajoute l'entier value.
virtual eReadMode readMode() const =0
Mode de lecture.
virtual void putInt32(Int32 value)=0
Ajoute l'entier value.
virtual void putSpan(Span< const Real > values)
Ajoute le tableau values.
virtual eMode mode() const =0
Mode de fonctionnement actuel.
@ ReadReplace
Replace les éléments actuels par ceux lus.
@ ReadAdd
Ajoute aux éléments actuels ceux lus.
virtual void getSpan(Span< Real > values)
Récupère le tableau values.
virtual Int32 getInt32()=0
Récupère un entier naturel.
virtual void reserveSpan(eBasicDataType dt, Int64 n)=0
Réserve de la mémoire pour n valeurs de dt.
virtual void putInt64(Int64 value)=0
Ajoute l'entier value.
Exception lorsqu'une fonction n'est pas implémentée.
Exception lorsqu'une opération n'est pas supportée.
Référence à une instance.
Implémentation thread-safe d'un compteur de référence.
void serialize(ISerializer *buffer) override
Serialize en lecture ou écriture la donnée.
void computeHash(IHashAlgorithm *algo, ByteArray &output) const override
Calcul une clé de hashage sur cette donnée.
Int64ConstArrayView extents() const override
Tableau contenant le nombre d'éléments pour chaque dimension.
Span< Byte > writableBytes() override
Vue sur les valeurs sérialisées.
void setConstBytes(Span< const Byte > bytes) override
Positionne les valeurs de sérialisation pour la lecture.
void allocateMemory(Int64 size) override
Alloue un tableaux pour contenir les éléments sérialisés.
Integer nbDimension() const override
Dimension. 0 pour un scalaire, 1 pour un tableau mono-dim, ...
Span< const Byte > constBytes() const override
Valeurs sérialisées.
void _serialize(ISerializer *sbuf) const
Int64 nbBaseElement() const override
Nombre d'éléments du type de base.
void setBytes(Span< Byte > bytes) override
Positionne les valeurs de sérialisation.
Span< Byte > bytes() override
Valeurs sérialisées.
eDataType baseDataType() const override
Type de la donnée.
bool isMultiSize() const override
Indique s'il s'agit d'un tableau multi-taille. (pertinent uniquement si nbDimension()>1)
void setWritableBytes(Span< Byte > bytes) override
Positionne les valeurs de sérialisation.
Int64 memorySize() const override
Indique le nombre d'octets qu'il faut allouer pour stocker ou lire les données.
void setBytes(Span< const Byte > bytes) override
Positionne les valeurs de sérialisation.
void setBuffer(ByteArrayView buffer) override
Positionne les valeurs de sérialisation.
Int64 nbElement() const override
Nombre d'éléments.
Span< const Byte > bytes() const override
Valeurs sérialisées.
ArrayShape shape() const override
Forme du tableau associé aux données.
Vue d'un tableau d'éléments de type T.
Definition Span.h:612
Vecteur 1D de données avec sémantique par valeur (style STL).
constexpr view_type smallView()
Vue constante sur cette vue.
Definition Span.h:369
constexpr ConstArrayView< value_type > constSmallView() const
Vue constante sur cette vue.
Definition Span.h:378
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
ARCANE_DATATYPE_EXPORT Integer dataTypeSize(eDataType type)
Taille du type de donnée type (qui doit être différent de DT_String)
Definition DataTypes.cc:109
Ref< ISerializedData > arcaneCreateSerializedDataRef(eDataType data_type, Int64 memory_size, Integer nb_dim, Int64 nb_element, Int64 nb_base_element, bool is_multi_size, Int64ConstArrayView dimensions)
Créé des données sérialisées.
Ref< TrueType > createRef(Args &&... args)
Créé une instance de type TrueType avec les arguments Args et retourne une référence dessus.
ArrayView< Byte > ByteArrayView
Equivalent C d'un tableau à une dimension de caractères.
Definition UtilsTypes.h:463
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
Array< Byte > ByteArray
Tableau dynamique à une dimension de caractères.
Definition UtilsTypes.h:137
ConstArrayView< Int64 > Int64ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:496
Ref< ISerializedData > arcaneCreateEmptySerializedDataRef()
Créé des données sérialisées.
ConstArrayView< Byte > ByteConstArrayView
Equivalent C d'un tableau à une dimension de caractères.
Definition UtilsTypes.h:492
unsigned char Byte
Type d'un octet.
Definition BaseTypes.h:43
eDataType
Type d'une donnée.
Definition DataTypes.h:39
@ DT_Unknown
Donnée de type inconnue ou non initialisée.
Definition DataTypes.h:56
std::int32_t Int32
Type entier signé sur 32 bits.