Hazelcast C++ Client
Hazelcast C++ Client Library
Loading...
Searching...
No Matches
serialization.h
1/*
2 * Copyright (c) 2008-2025, Hazelcast, Inc. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#pragma once
17
18#include <unordered_map>
19#include <unordered_set>
20#include <type_traits>
21
22#include <boost/any.hpp>
23#include <boost/optional.hpp>
24#include <boost/optional/optional_io.hpp>
25#include <boost/uuid/uuid.hpp>
26
27#include "hazelcast/client/hazelcast_json_value.h"
28#include "hazelcast/client/serialization/pimpl/data_input.h"
29#include "hazelcast/client/serialization/pimpl/data.h"
30#include "hazelcast/client/serialization/pimpl/data_output.h"
31#include "hazelcast/client/serialization/generic_record.h"
32#include "hazelcast/client/serialization_config.h"
33#include "hazelcast/client/partition_aware.h"
34#include "hazelcast/util/SynchronizedMap.h"
35#include "hazelcast/util/Disposable.h"
36#include "hazelcast/client/big_decimal.h"
37#include "hazelcast/client/local_time.h"
38#include "hazelcast/client/local_date.h"
39#include "hazelcast/client/local_date_time.h"
40#include "hazelcast/client/offset_date_time.h"
41
42#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
43#pragma warning(push)
44#pragma warning(disable : 4251) // for dll export
45#endif
46
47namespace hazelcast {
48namespace client {
50
51namespace serialization {
53namespace pimpl {
54// forward declarations
55class PortableContext;
56class ClassDefinitionContext;
57class ClassDefinitionWriter;
58class DefaultPortableWriter;
59class DefaultPortableReader;
60class MorphingPortableReader;
61class PortableSerializer;
62class DataSerializer;
63class SerializationService;
64class default_compact_writer;
65namespace offset_reader {
66template<typename OFFSET_TYPE>
67int32_t
68get_offset(serialization::object_data_input& in,
69 uint32_t variable_offsets_pos,
70 uint32_t index);
71}
72enum struct HAZELCAST_API serialization_constants
73{
74 CONSTANT_TYPE_NULL = 0,
75 CONSTANT_TYPE_PORTABLE = -1,
76 CONSTANT_TYPE_DATA = -2,
77 CONSTANT_TYPE_BYTE = -3,
78 CONSTANT_TYPE_BOOLEAN = -4,
79 CONSTANT_TYPE_CHAR = -5,
80 CONSTANT_TYPE_SHORT = -6,
81 CONSTANT_TYPE_INTEGER = -7,
82 CONSTANT_TYPE_LONG = -8,
83 CONSTANT_TYPE_FLOAT = -9,
84 CONSTANT_TYPE_DOUBLE = -10,
85 CONSTANT_TYPE_STRING = -11,
86 CONSTANT_TYPE_BYTE_ARRAY = -12,
87 CONSTANT_TYPE_BOOLEAN_ARRAY = -13,
88 CONSTANT_TYPE_CHAR_ARRAY = -14,
89 CONSTANT_TYPE_SHORT_ARRAY = -15,
90 CONSTANT_TYPE_INTEGER_ARRAY = -16,
91 CONSTANT_TYPE_LONG_ARRAY = -17,
92 CONSTANT_TYPE_FLOAT_ARRAY = -18,
93 CONSTANT_TYPE_DOUBLE_ARRAY = -19,
94 CONSTANT_TYPE_STRING_ARRAY = -20,
95 CONSTANT_TYPE_UUID = -21,
96 CONSTANT_TYPE_COMPACT = -55,
97 JAVASCRIPT_JSON_SERIALIZATION_TYPE = -130,
98
99 CONSTANT_TYPE_GLOBAL = INT32_MIN
100 // ------------------------------------------------------------
101};
102
119struct HAZELCAST_API object_type
120{
121 object_type();
122
123 serialization_constants type_id;
124 int32_t factory_id;
125 int32_t class_id;
126};
127
128std::ostream HAZELCAST_API&
129operator<<(std::ostream& os, const object_type& type);
130} // namespace pimpl
131} // namespace serialization
132
137class HAZELCAST_API typed_data
138{
139public:
140 typed_data();
141
142 typed_data(
143 serialization::pimpl::data d,
144 serialization::pimpl::SerializationService& serialization_service);
145
150 serialization::pimpl::object_type get_type() const;
151
163 template<typename T>
164 boost::optional<T> get() const;
165
170 const serialization::pimpl::data& get_data() const;
171
172private:
173 serialization::pimpl::data data_;
174 serialization::pimpl::SerializationService* ss_;
175};
176
177bool HAZELCAST_API
178operator<(const typed_data& lhs, const typed_data& rhs);
179
180namespace serialization {
181class object_data_input;
182class object_data_output;
183class portable_reader;
184struct compact_serializer;
185
186namespace pimpl {
187// forward declarations
188class PortableContext;
189class ClassDefinitionContext;
190class ClassDefinitionWriter;
191class DefaultPortableWriter;
192class DefaultPortableReader;
193class MorphingPortableReader;
194class PortableSerializer;
195class compact_stream_serializer;
196class DataSerializer;
197class SerializationService;
198} // namespace pimpl
199
200template<typename T>
202{};
203
205{};
206
208{};
209
211{
212 virtual ~global_serializer() = default;
213
214 static pimpl::serialization_constants get_type_id()
215 {
216 return pimpl::serialization_constants::CONSTANT_TYPE_GLOBAL;
217 }
218
219 virtual void write(const boost::any& object, object_data_output& out) = 0;
220
221 virtual boost::any read(object_data_input& in) = 0;
222};
223
234
245
248
249template<>
250struct HAZELCAST_API hz_serializer<byte> : public builtin_serializer
251{
252public:
253 static inline pimpl::serialization_constants get_type_id()
254 {
255 return pimpl::serialization_constants::CONSTANT_TYPE_BYTE;
256 }
257};
258
259template<>
260struct HAZELCAST_API hz_serializer<bool> : public builtin_serializer
261{
262public:
263 static inline pimpl::serialization_constants get_type_id()
264 {
265 return pimpl::serialization_constants::CONSTANT_TYPE_BOOLEAN;
266 }
267};
268
269template<>
270struct HAZELCAST_API hz_serializer<char> : public builtin_serializer
271{
272public:
273 static inline pimpl::serialization_constants get_type_id()
274 {
275 return pimpl::serialization_constants::CONSTANT_TYPE_CHAR;
276 }
277};
278
279template<>
280struct HAZELCAST_API hz_serializer<char16_t> : public builtin_serializer
281{
282public:
283 static inline pimpl::serialization_constants get_type_id()
284 {
285 return pimpl::serialization_constants::CONSTANT_TYPE_CHAR;
286 }
287};
288
289template<>
290struct HAZELCAST_API hz_serializer<int16_t> : public builtin_serializer
291{
292public:
293 static inline pimpl::serialization_constants get_type_id()
294 {
295 return pimpl::serialization_constants::CONSTANT_TYPE_SHORT;
296 }
297};
298
299template<>
300struct HAZELCAST_API hz_serializer<int32_t> : public builtin_serializer
301{
302public:
303 static inline pimpl::serialization_constants get_type_id()
304 {
305 return pimpl::serialization_constants::CONSTANT_TYPE_INTEGER;
306 }
307};
308
309template<>
310struct HAZELCAST_API hz_serializer<int64_t> : public builtin_serializer
311{
312public:
313 static inline pimpl::serialization_constants get_type_id()
314 {
315 return pimpl::serialization_constants::CONSTANT_TYPE_LONG;
316 }
317};
318
319template<>
320struct HAZELCAST_API hz_serializer<float> : public builtin_serializer
321{
322public:
323 static inline pimpl::serialization_constants get_type_id()
324 {
325 return pimpl::serialization_constants::CONSTANT_TYPE_FLOAT;
326 }
327};
328
329template<>
330struct HAZELCAST_API hz_serializer<double> : public builtin_serializer
331{
332public:
333 static inline pimpl::serialization_constants get_type_id()
334 {
335 return pimpl::serialization_constants::CONSTANT_TYPE_DOUBLE;
336 }
337};
338
339template<>
340struct HAZELCAST_API hz_serializer<std::string> : public builtin_serializer
341{
342public:
343 static inline pimpl::serialization_constants get_type_id()
344 {
345 return pimpl::serialization_constants::CONSTANT_TYPE_STRING;
346 }
347};
348
349template<>
351 : public builtin_serializer
352{
353public:
354 static inline pimpl::serialization_constants get_type_id()
355 {
356 return pimpl::serialization_constants::
357 JAVASCRIPT_JSON_SERIALIZATION_TYPE;
358 }
359};
360
361template<>
362struct HAZELCAST_API hz_serializer<std::vector<byte>>
363 : public builtin_serializer
364{
365public:
366 static inline pimpl::serialization_constants get_type_id()
367 {
368 return pimpl::serialization_constants::CONSTANT_TYPE_BYTE_ARRAY;
369 }
370};
371
372template<>
373struct HAZELCAST_API hz_serializer<std::vector<bool>>
374 : public builtin_serializer
375{
376public:
377 static inline pimpl::serialization_constants get_type_id()
378 {
379 return pimpl::serialization_constants::CONSTANT_TYPE_BOOLEAN_ARRAY;
380 }
381};
382
383template<>
384struct HAZELCAST_API hz_serializer<std::vector<char>>
385 : public builtin_serializer
386{
387public:
388 static inline pimpl::serialization_constants get_type_id()
389 {
390 return pimpl::serialization_constants::CONSTANT_TYPE_CHAR_ARRAY;
391 }
392};
393
394template<>
395struct HAZELCAST_API hz_serializer<std::vector<int16_t>>
396 : public builtin_serializer
397{
398public:
399 static inline pimpl::serialization_constants get_type_id()
400 {
401 return pimpl::serialization_constants::CONSTANT_TYPE_SHORT_ARRAY;
402 }
403};
404
405template<>
406struct HAZELCAST_API hz_serializer<std::vector<int32_t>>
407 : public builtin_serializer
408{
409public:
410 static inline pimpl::serialization_constants get_type_id()
411 {
412 return pimpl::serialization_constants::CONSTANT_TYPE_INTEGER_ARRAY;
413 }
414};
415
416template<>
417struct HAZELCAST_API hz_serializer<std::vector<int64_t>>
418 : public builtin_serializer
419{
420public:
421 static inline pimpl::serialization_constants get_type_id()
422 {
423 return pimpl::serialization_constants::CONSTANT_TYPE_LONG_ARRAY;
424 }
425};
426
427template<>
428struct HAZELCAST_API hz_serializer<std::vector<float>>
429 : public builtin_serializer
430{
431public:
432 static inline pimpl::serialization_constants get_type_id()
433 {
434 return pimpl::serialization_constants::CONSTANT_TYPE_FLOAT_ARRAY;
435 }
436};
437
438template<>
439struct HAZELCAST_API hz_serializer<std::vector<double>>
440 : public builtin_serializer
441{
442public:
443 static inline pimpl::serialization_constants get_type_id()
444 {
445 return pimpl::serialization_constants::CONSTANT_TYPE_DOUBLE_ARRAY;
446 }
447};
448
449template<>
450struct HAZELCAST_API hz_serializer<std::vector<std::string>>
451 : public builtin_serializer
452{
453public:
454 static inline pimpl::serialization_constants get_type_id()
455 {
456 return pimpl::serialization_constants::CONSTANT_TYPE_STRING_ARRAY;
457 }
458};
459
460template<>
461struct HAZELCAST_API hz_serializer<boost::uuids::uuid>
462 : public builtin_serializer
463{
464public:
465 static inline pimpl::serialization_constants get_type_id()
466 {
467 return pimpl::serialization_constants::CONSTANT_TYPE_UUID;
468 }
469};
470
471enum struct field_type
472{
473 TYPE_PORTABLE = 0,
474 TYPE_BYTE = 1,
475 TYPE_BOOLEAN = 2,
476 TYPE_CHAR = 3,
477 TYPE_SHORT = 4,
478 TYPE_INT = 5,
479 TYPE_LONG = 6,
480 TYPE_FLOAT = 7,
481 TYPE_DOUBLE = 8,
482 TYPE_STRING = 9,
483 TYPE_PORTABLE_ARRAY = 10,
484 TYPE_BYTE_ARRAY = 11,
485 TYPE_BOOLEAN_ARRAY = 12,
486 TYPE_CHAR_ARRAY = 13,
487 TYPE_SHORT_ARRAY = 14,
488 TYPE_INT_ARRAY = 15,
489 TYPE_LONG_ARRAY = 16,
490 TYPE_FLOAT_ARRAY = 17,
491 TYPE_DOUBLE_ARRAY = 18,
492 TYPE_STRING_ARRAY = 19
493};
494
505class HAZELCAST_API FieldDefinition
506{
507public:
512
516 FieldDefinition(int,
517 const std::string&,
518 field_type const& type,
519 int version);
520
524 FieldDefinition(int index,
525 const std::string& field_name,
526 field_type const& type,
527 int factory_id,
528 int class_id,
529 int version);
530
534 const field_type& get_type() const;
535
539 std::string get_name() const;
540
544 int get_index() const;
545
549 int get_factory_id() const;
550
554 int get_class_id() const;
555
559 void write_data(pimpl::data_output& data_output);
560
564 void read_data(object_data_input& data_input);
565
566 bool operator==(const FieldDefinition& rhs) const;
567
568 bool operator!=(const FieldDefinition& rhs) const;
569
570 friend std::ostream& operator<<(std::ostream& os,
571 const FieldDefinition& definition);
572
573private:
574 int index_;
575 std::string field_name_;
576 field_type type_;
577 int class_id_;
578 int factory_id_;
579 int version_;
580};
581
582class HAZELCAST_API ClassDefinition
583{
584public:
589
596 ClassDefinition(int factory_id, int class_id, int version);
597
602 void add_field_def(FieldDefinition& field_definition);
603
609 bool has_field(const std::string& field_name) const;
610
616 const FieldDefinition& get_field(const std::string& field_name) const;
617
623 field_type get_field_type(const std::string& field_name) const;
624
628 int get_field_count() const;
629
633 int get_factory_id() const;
634
638 int get_class_id() const;
639
643 int get_version() const;
644
649 void set_version_if_not_set(int new_version);
650
655 void write_data(pimpl::data_output& data_output);
656
661 void read_data(object_data_input& data_input);
662
663 bool operator==(const ClassDefinition& rhs) const;
664
665 bool operator!=(const ClassDefinition& rhs) const;
666
667 friend std::ostream& operator<<(std::ostream& os,
668 const ClassDefinition& definition);
669
670private:
671 int factory_id_;
672 int class_id_;
673 int version_;
674
675 ClassDefinition(const ClassDefinition&) = delete;
676
677 ClassDefinition& operator=(const ClassDefinition& rhs) = delete;
678
679 std::unordered_map<std::string, FieldDefinition> field_definitions_map_;
680
681 std::unique_ptr<std::vector<byte>> binary_;
682};
683
691class HAZELCAST_API ClassDefinitionBuilder
692{
693public:
694 ClassDefinitionBuilder(int factory_id, int class_id, int version);
695
696 ClassDefinitionBuilder& add_portable_field(
697 const std::string& field_name,
698 std::shared_ptr<ClassDefinition> def);
699
700 ClassDefinitionBuilder& add_portable_array_field(
701 const std::string& field_name,
702 std::shared_ptr<ClassDefinition> def);
703
704 ClassDefinitionBuilder& add_field(FieldDefinition& field_definition);
705
706 void add_field(const std::string& field_name, field_type const& field_type);
707
708 std::shared_ptr<ClassDefinition> build();
709
710 int get_factory_id();
711
712 int get_class_id();
713
714 int get_version();
715
716private:
717 int factory_id_;
718 int class_id_;
719 int version_;
720 int index_;
721 bool done_;
722
723 std::vector<FieldDefinition> field_definitions_;
724
725 void check();
726};
727
729{
730public:
731 template<typename T>
732 static inline typename std::enable_if<
733 std::is_base_of<versioned_portable_serializer, hz_serializer<T>>::value,
734 int>::type
735 get_version(int)
736 {
738 }
739
740 template<typename T>
741 static inline typename std::enable_if<
742 !std::is_base_of<versioned_portable_serializer, hz_serializer<T>>::value,
743 int>::type
744 get_version(int default_version)
745 {
746 return default_version;
747 }
748};
749
750namespace compact {
751class compact_writer;
752class compact_reader;
753class compact_serializer;
754} // namespace compact
755
756class HAZELCAST_API object_data_input
757 : public pimpl::data_input<std::vector<byte>>
758{
759 template<typename OFFSET_TYPE>
760 friend int32_t pimpl::offset_reader::get_offset(
762 uint32_t variable_offsets_pos,
763 uint32_t index);
764
765 friend class compact::compact_reader;
766 friend class portable_reader;
767
768public:
773 boost::endian::order byte_order,
774 const std::vector<byte>& buffer,
775 int offset,
776 pimpl::PortableSerializer& portable_ser,
777 pimpl::compact_stream_serializer& compact_ser,
778 pimpl::DataSerializer& data_ser,
779 std::shared_ptr<serialization::global_serializer> global_serializer);
780
785 template<typename T>
786 typename std::enable_if<
787 !(std::is_array<T>::value &&
788 std::is_same<typename std::remove_all_extents<T>::type, char>::value),
789 boost::optional<T>>::type inline read_object();
790
791 template<typename T>
792 typename std::enable_if<
793 std::is_array<T>::value &&
794 std::is_same<typename std::remove_all_extents<T>::type, char>::value,
795 boost::optional<std::string>>::type inline read_object();
796
797 template<typename T>
798 typename std::enable_if<
799 std::is_base_of<identified_data_serializer, hz_serializer<T>>::value,
800 boost::optional<T>>::type inline read_object(int32_t type_id);
801
802 template<typename T>
803 typename std::enable_if<
804 std::is_base_of<portable_serializer, hz_serializer<T>>::value,
805 boost::optional<T>>::type inline read_object(int32_t type_id);
806
807 template<typename T>
808 typename std::enable_if<
809 std::is_base_of<compact::compact_serializer, hz_serializer<T>>::value,
810 boost::optional<T>>::type inline read_object(int32_t type_id);
811
812 template<typename T>
813 typename std::enable_if<
814 std::is_base_of<builtin_serializer, hz_serializer<T>>::value,
815 boost::optional<T>>::type inline read_object(int32_t type_id);
816
817 template<typename T>
818 typename std::enable_if<
819 std::is_base_of<custom_serializer, hz_serializer<T>>::value,
820 boost::optional<T>>::type inline read_object(int32_t type_id);
821
822 template<typename T>
823 typename std::enable_if<
824 std::is_same<generic_record::generic_record, T>::value,
825 boost::optional<T>>::type
826 read_object(int32_t type_id);
827
834 template<typename T>
835 typename std::enable_if<
836 !(std::is_base_of<identified_data_serializer, hz_serializer<T>>::value ||
837 std::is_base_of<portable_serializer, hz_serializer<T>>::value ||
838 std::is_base_of<compact::compact_serializer, hz_serializer<T>>::value ||
839 std::is_base_of<builtin_serializer, hz_serializer<T>>::value ||
840 std::is_base_of<custom_serializer, hz_serializer<T>>::value ||
841 std::is_same<generic_record::generic_record, T>::value),
842 boost::optional<T>>::type inline read_object(int32_t type_id);
843
844private:
845 pimpl::PortableSerializer& portable_serializer_;
846 pimpl::compact_stream_serializer& compact_serializer_;
847 pimpl::DataSerializer& data_serializer_;
848 std::shared_ptr<serialization::global_serializer> global_serializer_;
849};
850
851class HAZELCAST_API object_data_output : public pimpl::data_output
852{
853 friend pimpl::DefaultPortableWriter;
854 friend pimpl::default_compact_writer;
855
856public:
860 explicit object_data_output(
861 boost::endian::order byte_order,
862 bool dont_write = false,
863 pimpl::PortableSerializer* portable_ser = nullptr,
864 pimpl::compact_stream_serializer* compact_ser = nullptr,
865 std::shared_ptr<serialization::global_serializer> global_serializer =
866 nullptr);
867
868 template<typename T>
869 void write_object(const T* object);
870
871 /* enable_if needed here since 'boost::optional<char [5]>' can not be
872 * composed this template match */
873 template<typename T>
874 typename std::enable_if<
875 !(std::is_array<T>::value &&
876 std::is_same<typename std::remove_all_extents<T>::type, char>::value),
877 void>::type
878 write_object(const boost::optional<T>& object);
879
880 template<typename T>
881 typename std::enable_if<
882 std::is_array<T>::value &&
883 std::is_same<typename std::remove_all_extents<T>::type, char>::value,
884 void>::type inline write_object(const T& object);
885
886 template<typename T>
887 typename std::enable_if<
888 std::is_base_of<builtin_serializer, hz_serializer<T>>::value,
889 void>::type inline write_object(const T& object);
890
891 template<typename T>
892 typename std::enable_if<
893 std::is_base_of<identified_data_serializer, hz_serializer<T>>::value,
894 void>::type inline write_object(const T& object);
895
896 template<typename T>
897 typename std::enable_if<
898 std::is_base_of<portable_serializer, hz_serializer<T>>::value,
899 void>::type inline write_object(const T& object);
900
901 template<typename T>
902 typename std::enable_if<
903 std::is_same<generic_record::generic_record, T>::value>::type
904 write_object(const T& object);
905
906 template<typename T>
907 typename std::enable_if<
908 std::is_base_of<compact::compact_serializer, hz_serializer<T>>::value,
909 void>::type inline write_object(const T& object);
910
911 template<typename T>
912 typename std::enable_if<
913 std::is_base_of<custom_serializer, hz_serializer<T>>::value,
914 void>::type inline write_object(const T& object);
915
916 template<typename T>
917 typename std::enable_if<
918 !(std::is_base_of<builtin_serializer, hz_serializer<T>>::value ||
919 std::is_base_of<identified_data_serializer, hz_serializer<T>>::value ||
920 std::is_base_of<portable_serializer, hz_serializer<T>>::value ||
921 std::is_base_of<compact::compact_serializer, hz_serializer<T>>::value ||
922 std::is_base_of<custom_serializer, hz_serializer<T>>::value ||
923 std::is_same<generic_record::generic_record, T>::value ||
924 (std::is_array<T>::value &&
925 std::is_same<typename std::remove_all_extents<T>::type, char>::value)),
926 void>::type inline write_object(const T object);
927
928 void write_objects() {}
929
930 template<typename FirstObjectType, typename... OtherObjects>
931 inline void write_objects(const FirstObjectType& object,
932 const OtherObjects&... objects)
933 {
934 write_object(object);
935 write_objects(objects...);
936 }
937
938 template<typename T>
939 inline void write_bytes(const T& s)
940 {
941 for (auto c : s) {
942 output_stream_.push_back(c);
943 }
944 }
945
946private:
947 using schemas_t = std::vector<pimpl::schema>;
948
949 friend class pimpl::compact_stream_serializer;
950 friend class pimpl::SerializationService;
951
952 schemas_t schemas_will_be_replicated_;
953 pimpl::PortableSerializer* portable_serializer_;
954 pimpl::compact_stream_serializer* compact_serializer_;
955 std::shared_ptr<serialization::global_serializer> global_serializer_;
956};
957
958template<>
959void HAZELCAST_API
960object_data_output::write_object(const char* object);
961
962namespace pimpl {
963class HAZELCAST_API serialization_util
964{
965public:
966 template<typename T>
967 static typename std::enable_if<
968 std::is_same<boost::multiprecision::cpp_int,
969 typename std::remove_cv<T>::type>::value,
970 T>::type
972 {
973 int32_t size = object_data_input.read<int32_t>();
974 std::vector<int8_t> bytes(size);
975 object_data_input.read_fully(bytes);
976 return client::pimpl::from_bytes(std::move(bytes));
977 }
978
979 template<typename T>
980 static typename std::enable_if<
981 std::is_same<boost::multiprecision::cpp_int,
982 typename std::remove_cv<T>::type>::value,
983 void>::type
984 write(client::serialization::object_data_output& object_data_output,
985 const T& value)
986 {
987 auto v = hazelcast::client::pimpl::to_bytes(value);
988 object_data_output.write(v);
989 }
990
991 template<typename T>
992 static typename std::enable_if<
993 std::is_same<client::big_decimal,
994 typename std::remove_cv<T>::type>::value,
995 T>::type
996 read(client::serialization::object_data_input& object_data_input)
997 {
998 auto cpp_int = read<boost::multiprecision::cpp_int>(object_data_input);
999 int32_t scale = object_data_input.read<int32_t>();
1000 return client::big_decimal{ std::move(cpp_int), scale };
1001 }
1002
1003 template<typename T>
1004 static typename std::enable_if<
1005 std::is_same<client::big_decimal,
1006 typename std::remove_cv<T>::type>::value,
1007 void>::type
1008 write(client::serialization::object_data_output& object_data_output,
1009 const T& value)
1010 {
1011 write(object_data_output, value.unscaled);
1012 object_data_output.write(value.scale);
1013 }
1014
1015 template<typename T>
1016 static typename std::enable_if<
1017 std::is_same<client::local_time, typename std::remove_cv<T>::type>::value,
1018 T>::type
1019 read(client::serialization::object_data_input& object_data_input)
1020 {
1021 byte hour = object_data_input.read<byte>();
1022 byte minute = object_data_input.read<byte>();
1023 byte second = object_data_input.read<byte>();
1024 int32_t nano = object_data_input.read<int32_t>();
1025 return client::local_time{ hour, minute, second, nano };
1026 }
1027
1028 template<typename T>
1029 static typename std::enable_if<
1030 std::is_same<client::local_time, typename std::remove_cv<T>::type>::value,
1031 void>::type
1032 write(client::serialization::object_data_output& object_data_output,
1033 const T& value)
1034 {
1035 object_data_output.write<byte>(value.hours);
1036 object_data_output.write<byte>(value.minutes);
1037 object_data_output.write<byte>(value.seconds);
1038 object_data_output.write<int32_t>(value.nanos);
1039 }
1040
1041 template<typename T>
1042 static typename std::enable_if<
1043 std::is_same<client::local_date, typename std::remove_cv<T>::type>::value,
1044 T>::type
1045 read(client::serialization::object_data_input& object_data_input)
1046 {
1047 int32_t year = object_data_input.read<int32_t>();
1048 byte month = object_data_input.read<byte>();
1049 byte dayOfMonth = object_data_input.read<byte>();
1050 return client::local_date{ year, month, dayOfMonth };
1051 }
1052
1053 template<typename T>
1054 static typename std::enable_if<
1055 std::is_same<client::local_date, typename std::remove_cv<T>::type>::value,
1056 void>::type
1057 write(client::serialization::object_data_output& object_data_output,
1058 const T& value)
1059 {
1060 object_data_output.write<int32_t>(value.year);
1061 object_data_output.write<byte>(value.month);
1062 object_data_output.write<byte>(value.day_of_month);
1063 }
1064
1065 template<typename T>
1066 static typename std::enable_if<
1067 std::is_same<client::local_date_time,
1068 typename std::remove_cv<T>::type>::value,
1069 T>::type
1070 read(client::serialization::object_data_input& object_data_input)
1071 {
1072 auto date = read<client::local_date>(object_data_input);
1073 auto time = read<client::local_time>(object_data_input);
1074 return client::local_date_time{ date, time };
1075 }
1076
1077 template<typename T>
1078 static typename std::enable_if<
1079 std::is_same<client::local_date_time,
1080 typename std::remove_cv<T>::type>::value,
1081 void>::type
1082 write(client::serialization::object_data_output& object_data_output,
1083 const T& value)
1084 {
1085 write(object_data_output, value.date);
1086 write(object_data_output, value.time);
1087 }
1088
1089 template<typename T>
1090 static typename std::enable_if<
1091 std::is_same<client::offset_date_time,
1092 typename std::remove_cv<T>::type>::value,
1093 T>::type
1094 read(client::serialization::object_data_input& object_data_input)
1095 {
1096 auto local_date_time = read<client::local_date_time>(object_data_input);
1097 int32_t zoneTotalSeconds = object_data_input.read<int32_t>();
1098 return client::offset_date_time{ local_date_time, zoneTotalSeconds };
1099 }
1100
1101 template<typename T>
1102 static typename std::enable_if<
1103 std::is_same<client::offset_date_time,
1104 typename std::remove_cv<T>::type>::value,
1105 void>::type
1106 write(client::serialization::object_data_output& object_data_output,
1107 const T& value)
1108 {
1109 write(object_data_output, value.date_time);
1110 object_data_output.write<int32_t>(value.zone_offset_in_seconds);
1111 }
1112};
1113
1114class HAZELCAST_API PortableContext
1115{
1116public:
1117 PortableContext(const serialization_config& serialization_conf);
1118
1119 int get_class_version(int factory_id, int class_id);
1120
1121 void set_class_version(int factory_id, int class_id, int version);
1122
1123 std::shared_ptr<ClassDefinition> lookup_class_definition(int factory_id,
1124 int class_id,
1125 int version);
1126
1127 std::shared_ptr<ClassDefinition> register_class_definition(
1128 std::shared_ptr<ClassDefinition>);
1129
1130 template<typename T>
1131 std::shared_ptr<ClassDefinition> lookup_or_register_class_definition(
1132 const T& portable);
1133
1134 int get_version();
1135
1136 std::shared_ptr<ClassDefinition> read_class_definition(
1137 object_data_input& input,
1138 int id,
1139 int class_id,
1140 int version);
1141
1142 const serialization_config& get_serialization_config() const;
1143
1144 template<typename T>
1145 typename std::enable_if<
1146 std::is_same<byte, typename std::remove_cv<T>::type>::value,
1147 field_type>::type static get_type()
1148 {
1149 return field_type::TYPE_BYTE;
1150 }
1151
1152 template<typename T>
1153 typename std::enable_if<
1154 std::is_same<char, typename std::remove_cv<T>::type>::value,
1155 field_type>::type static get_type()
1156 {
1157 return field_type::TYPE_CHAR;
1158 }
1159
1160 template<typename T>
1161 typename std::enable_if<
1162 std::is_same<char16_t, typename std::remove_cv<T>::type>::value,
1163 field_type>::type static get_type()
1164 {
1165 return field_type::TYPE_CHAR;
1166 }
1167
1168 template<typename T>
1169 typename std::enable_if<
1170 std::is_same<bool, typename std::remove_cv<T>::type>::value,
1171 field_type>::type static get_type()
1172 {
1173 return field_type::TYPE_BOOLEAN;
1174 }
1175
1176 template<typename T>
1177 typename std::enable_if<
1178 std::is_same<int16_t, typename std::remove_cv<T>::type>::value,
1179 field_type>::type static get_type()
1180 {
1181 return field_type::TYPE_SHORT;
1182 }
1183
1184 template<typename T>
1185 typename std::enable_if<
1186 std::is_same<int32_t, typename std::remove_cv<T>::type>::value,
1187 field_type>::type static get_type()
1188 {
1189 return field_type::TYPE_INT;
1190 }
1191
1192 template<typename T>
1193 typename std::enable_if<
1194 std::is_same<int64_t, typename std::remove_cv<T>::type>::value,
1195 field_type>::type static get_type()
1196 {
1197 return field_type::TYPE_LONG;
1198 }
1199
1200 template<typename T>
1201 typename std::enable_if<
1202 std::is_same<float, typename std::remove_cv<T>::type>::value,
1203 field_type>::type static get_type()
1204 {
1205 return field_type::TYPE_FLOAT;
1206 }
1207
1208 template<typename T>
1209 typename std::enable_if<
1210 std::is_same<double, typename std::remove_cv<T>::type>::value,
1211 field_type>::type static get_type()
1212 {
1213 return field_type::TYPE_DOUBLE;
1214 }
1215
1216 template<typename T>
1217 typename std::enable_if<
1218 std::is_same<std::string, typename std::remove_cv<T>::type>::value,
1219 field_type>::type static get_type()
1220 {
1221 return field_type::TYPE_STRING;
1222 }
1223
1224 template<typename T>
1225 typename std::enable_if<
1226 std::is_same<std::vector<byte>, typename std::remove_cv<T>::type>::value,
1227 field_type>::type static get_type()
1228 {
1229 return field_type::TYPE_BYTE_ARRAY;
1230 }
1231
1232 template<typename T>
1233 typename std::enable_if<
1234 std::is_same<std::vector<char>, typename std::remove_cv<T>::type>::value,
1235 field_type>::type static get_type()
1236 {
1237 return field_type::TYPE_CHAR_ARRAY;
1238 }
1239
1240 template<typename T>
1241 typename std::enable_if<
1242 std::is_same<std::vector<bool>, typename std::remove_cv<T>::type>::value,
1243 field_type>::type static get_type()
1244 {
1245 return field_type::TYPE_BOOLEAN_ARRAY;
1246 }
1247
1248 template<typename T>
1249 typename std::enable_if<
1250 std::is_same<std::vector<int16_t>,
1251 typename std::remove_cv<T>::type>::value,
1252 field_type>::type static get_type()
1253 {
1254 return field_type::TYPE_SHORT_ARRAY;
1255 }
1256
1257 template<typename T>
1258 typename std::enable_if<
1259 std::is_same<std::vector<int32_t>,
1260 typename std::remove_cv<T>::type>::value,
1261 field_type>::type static get_type()
1262 {
1263 return field_type::TYPE_INT_ARRAY;
1264 }
1265
1266 template<typename T>
1267 typename std::enable_if<
1268 std::is_same<std::vector<int64_t>,
1269 typename std::remove_cv<T>::type>::value,
1270 field_type>::type static get_type()
1271 {
1272 return field_type::TYPE_LONG_ARRAY;
1273 }
1274
1275 template<typename T>
1276 typename std::enable_if<
1277 std::is_same<std::vector<float>, typename std::remove_cv<T>::type>::value,
1278 field_type>::type static get_type()
1279 {
1280 return field_type::TYPE_FLOAT_ARRAY;
1281 }
1282
1283 template<typename T>
1284 typename std::enable_if<
1285 std::is_same<std::vector<double>,
1286 typename std::remove_cv<T>::type>::value,
1287 field_type>::type static get_type()
1288 {
1289 return field_type::TYPE_DOUBLE_ARRAY;
1290 }
1291
1292 template<typename T>
1293 typename std::enable_if<
1294 std::is_same<std::vector<std::string>,
1295 typename std::remove_cv<T>::type>::value,
1296 field_type>::type static get_type()
1297 {
1298 return field_type::TYPE_STRING_ARRAY;
1299 }
1300
1301private:
1302 PortableContext(const PortableContext&) = delete;
1303
1304 ClassDefinitionContext& get_class_definition_context(int factory_id);
1305
1306 void operator=(const PortableContext&) = delete;
1307
1308 util::SynchronizedMap<int, ClassDefinitionContext> class_def_context_map_;
1309 const serialization_config& serialization_config_;
1310};
1311
1312class ClassDefinitionContext
1313{
1314public:
1315 ClassDefinitionContext(int portable_context, PortableContext* p_context);
1316
1317 int get_class_version(int class_id);
1318
1319 void set_class_version(int class_id, int version);
1320
1321 std::shared_ptr<ClassDefinition> lookup(int, int);
1322
1323 std::shared_ptr<ClassDefinition> register_class_definition(
1324 std::shared_ptr<ClassDefinition>);
1325
1326private:
1327 int64_t combine_to_long(int x, int y) const;
1328
1329 const int factory_id_;
1330 util::SynchronizedMap<long long, ClassDefinition> versioned_definitions_;
1331 util::SynchronizedMap<int, int> current_class_versions_;
1332 PortableContext* portable_context_;
1333};
1334
1335class HAZELCAST_API ClassDefinitionWriter
1336{
1337public:
1338 ClassDefinitionWriter(PortableContext& portable_context,
1339 ClassDefinitionBuilder& builder);
1340
1341 template<typename T>
1342 void write(const std::string& field_name, T value)
1343 {
1344 typedef typename std::remove_pointer<typename std::remove_reference<
1345 typename std::remove_cv<T>::type>::type>::type value_type;
1346 builder_.add_field(field_name, PortableContext::get_type<value_type>());
1347 }
1348
1349 template<typename T>
1350 void write_null_portable(const std::string& field_name)
1351 {
1352 T portable;
1353 int32_t factoryId = hz_serializer<T>::get_factory_id();
1354 int32_t classId = hz_serializer<T>::get_class_id();
1355 std::shared_ptr<ClassDefinition> nestedClassDef =
1356 context_.lookup_class_definition(
1357 factoryId, classId, context_.get_version());
1358 if (!nestedClassDef) {
1359 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
1360 "ClassDefWriter::write_null_portable",
1361 "Cannot write null portable without explicitly registering class "
1362 "definition!"));
1363 }
1364 builder_.add_portable_field(field_name, nestedClassDef);
1365 }
1366
1367 template<typename T>
1368 void write_portable(const std::string& field_name, const T* portable)
1369 {
1370 if (NULL == portable) {
1371 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
1372 "ClassDefinitionWriter::write_portable",
1373 "Cannot write null portable without explicitly registering class "
1374 "definition!"));
1375 }
1376
1377 std::shared_ptr<ClassDefinition> nestedClassDef =
1378 create_nested_class_def(*portable);
1379 builder_.add_portable_field(field_name, nestedClassDef);
1380 }
1381
1382 template<typename T>
1383 void write_portable_array(const std::string& field_name,
1384 const std::vector<T>* portables)
1385 {
1386 if (NULL == portables || portables->size() == 0) {
1387 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
1388 "ClassDefinitionWriter::write_portableArray",
1389 "Cannot write null portable array without explicitly registering "
1390 "class definition!"));
1391 }
1392 std::shared_ptr<ClassDefinition> nestedClassDef =
1393 create_nested_class_def((*portables)[0]);
1394 builder_.add_portable_array_field(field_name, nestedClassDef);
1395 }
1396
1397 std::shared_ptr<ClassDefinition> register_and_get();
1398
1399 object_data_output& get_raw_data_output();
1400
1401 void end();
1402
1403private:
1404 template<typename T>
1405 std::shared_ptr<ClassDefinition> create_nested_class_def(const T& portable);
1406
1407 ClassDefinitionBuilder& builder_;
1408 PortableContext& context_;
1409 object_data_output empty_data_output_;
1410};
1411
1412class HAZELCAST_API PortableReaderBase
1413{
1414public:
1415 PortableReaderBase(PortableSerializer& portable_ser,
1416 object_data_input& input,
1417 std::shared_ptr<ClassDefinition> cd);
1418
1419 template<typename T>
1420 typename std::enable_if<
1421 std::is_same<byte, typename std::remove_cv<T>::type>::value ||
1422 std::is_same<char, typename std::remove_cv<T>::type>::value ||
1423 std::is_same<char16_t, typename std::remove_cv<T>::type>::value ||
1424 std::is_same<bool, typename std::remove_cv<T>::type>::value ||
1425 std::is_same<int16_t, typename std::remove_cv<T>::type>::value ||
1426 std::is_same<int32_t, typename std::remove_cv<T>::type>::value ||
1427 std::is_same<int64_t, typename std::remove_cv<T>::type>::value ||
1428 std::is_same<float, typename std::remove_cv<T>::type>::value ||
1429 std::is_same<double, typename std::remove_cv<T>::type>::value ||
1430 std::is_same<std::string, typename std::remove_cv<T>::type>::value,
1431 T>::type
1432 read(const std::string& field_name)
1433 {
1434 set_position(field_name, PortableContext::get_type<T>());
1435 return data_input_->read<T>();
1436 }
1437
1438 template<typename T>
1439 typename std::enable_if<
1440 std::is_same<boost::optional<std::string>,
1441 typename std::remove_cv<T>::type>::value,
1442 T>::type
1443 read(const std::string& field_name)
1444 {
1445 set_position(field_name, PortableContext::get_type<T>());
1446 return data_input_->read<T>();
1447 }
1448
1449 template<typename T>
1450 typename std::enable_if<
1451 std::is_same<std::vector<byte>,
1452 typename std::remove_cv<T>::type>::value ||
1453 std::is_same<std::vector<char>,
1454 typename std::remove_cv<T>::type>::value ||
1455 std::is_same<std::vector<bool>,
1456 typename std::remove_cv<T>::type>::value ||
1457 std::is_same<std::vector<int16_t>,
1458 typename std::remove_cv<T>::type>::value ||
1459 std::is_same<std::vector<int32_t>,
1460 typename std::remove_cv<T>::type>::value ||
1461 std::is_same<std::vector<int64_t>,
1462 typename std::remove_cv<T>::type>::value ||
1463 std::is_same<std::vector<float>,
1464 typename std::remove_cv<T>::type>::value ||
1465 std::is_same<std::vector<double>,
1466 typename std::remove_cv<T>::type>::value ||
1467 std::is_same<std::vector<std::string>,
1468 typename std::remove_cv<T>::type>::value,
1469 boost::optional<T>>::type
1470 read(const std::string& field_name)
1471 {
1472 set_position(field_name, PortableContext::get_type<T>());
1473 return data_input_->read<T>();
1474 }
1475
1476 object_data_input& get_raw_data_input();
1477
1478 void end();
1479
1480protected:
1481 void set_position(const std::string& field_name,
1482 field_type const& field_type);
1483
1484 void check_factory_and_class(FieldDefinition fd,
1485 int factory_id,
1486 int class_id) const;
1487
1488 template<typename T>
1489 boost::optional<T> get_portable_instance(const std::string& field_name);
1490
1491 std::shared_ptr<ClassDefinition> cd_;
1492 object_data_input* data_input_;
1493 PortableSerializer* portable_serializer_;
1494
1495private:
1496 int final_position_;
1497 int offset_;
1498 bool raw_;
1499};
1500
1501class HAZELCAST_API DefaultPortableReader : public PortableReaderBase
1502{
1503public:
1504 DefaultPortableReader(PortableSerializer& portable_ser,
1505 object_data_input& input,
1506 std::shared_ptr<ClassDefinition> cd);
1507
1508 template<typename T>
1509 boost::optional<T> read_portable(const std::string& field_name);
1510
1511 template<typename T>
1512 boost::optional<std::vector<T>> read_portable_array(
1513 const std::string& field_name);
1514};
1515
1516class HAZELCAST_API MorphingPortableReader : public PortableReaderBase
1517{
1518public:
1519 MorphingPortableReader(PortableSerializer& portable_ser,
1520 object_data_input& input,
1521 std::shared_ptr<ClassDefinition> cd);
1522
1523 template<typename T>
1524 typename std::enable_if<
1525 std::is_same<int16_t, typename std::remove_cv<T>::type>::value ||
1526 std::is_same<int32_t, typename std::remove_cv<T>::type>::value ||
1527 std::is_same<int64_t, typename std::remove_cv<T>::type>::value ||
1528 std::is_same<float, typename std::remove_cv<T>::type>::value ||
1529 std::is_same<double, typename std::remove_cv<T>::type>::value,
1530 T>::type
1531 read(const std::string& field_name)
1532 {
1533 if (!cd_->has_field(field_name)) {
1534 return 0;
1535 }
1536 const field_type& currentFieldType = cd_->get_field_type(field_name);
1537 return read_morphing<T>(currentFieldType, field_name);
1538 }
1539
1540 template<typename T>
1541 typename std::enable_if<
1542 std::is_same<byte, typename std::remove_cv<T>::type>::value ||
1543 std::is_same<char, typename std::remove_cv<T>::type>::value ||
1544 std::is_same<char16_t, typename std::remove_cv<T>::type>::value ||
1545 std::is_same<bool, typename std::remove_cv<T>::type>::value,
1546 T>::type
1547 read(const std::string& field_name)
1548 {
1549 if (!cd_->has_field(field_name)) {
1550 return 0;
1551 }
1552 return PortableReaderBase::read<T>(field_name);
1553 }
1554
1555 template<typename T>
1556 typename std::enable_if<
1557 std::is_same<std::string, typename std::remove_cv<T>::type>::value,
1558 T>::type
1559 read(const std::string& field_name)
1560 {
1561 if (!cd_->has_field(field_name)) {
1562 return std::string();
1563 }
1564 return PortableReaderBase::read<T>(field_name);
1565 }
1566
1567 template<typename T>
1568 typename std::enable_if<
1569 std::is_same<boost::optional<std::string>,
1570 typename std::remove_cv<T>::type>::value,
1571 T>::type
1572 read(const std::string& field_name)
1573 {
1574 if (!cd_->has_field(field_name)) {
1575 return boost::none;
1576 }
1577 return PortableReaderBase::read<T>(field_name);
1578 }
1579
1580 template<typename T>
1581 typename std::enable_if<
1582 std::is_same<std::vector<byte>,
1583 typename std::remove_cv<T>::type>::value ||
1584 std::is_same<std::vector<char>,
1585 typename std::remove_cv<T>::type>::value ||
1586 std::is_same<std::vector<bool>,
1587 typename std::remove_cv<T>::type>::value ||
1588 std::is_same<std::vector<int16_t>,
1589 typename std::remove_cv<T>::type>::value ||
1590 std::is_same<std::vector<int32_t>,
1591 typename std::remove_cv<T>::type>::value ||
1592 std::is_same<std::vector<int64_t>,
1593 typename std::remove_cv<T>::type>::value ||
1594 std::is_same<std::vector<float>,
1595 typename std::remove_cv<T>::type>::value ||
1596 std::is_same<std::vector<double>,
1597 typename std::remove_cv<T>::type>::value ||
1598 std::is_same<std::vector<std::string>,
1599 typename std::remove_cv<T>::type>::value,
1600 boost::optional<T>>::type
1601 read(const std::string& field_name)
1602 {
1603 if (!cd_->has_field(field_name)) {
1604 return boost::none;
1605 }
1606 return PortableReaderBase::read<T>(field_name);
1607 }
1608
1609 template<typename T>
1610 boost::optional<T> read_portable(const std::string& field_name);
1611
1612 template<typename T>
1613 boost::optional<std::vector<T>> read_portable_array(
1614 const std::string& field_name);
1615
1616private:
1617 template<typename T>
1618 typename std::enable_if<
1619 std::is_same<int16_t, typename std::remove_cv<T>::type>::value,
1620 T>::type
1621 read_morphing(field_type current_field_type, const std::string& field_name)
1622 {
1623 switch (current_field_type) {
1624 case field_type::TYPE_BYTE:
1625 return PortableReaderBase::read<byte>(field_name);
1626 case field_type::TYPE_SHORT:
1627 return PortableReaderBase::read<int16_t>(field_name);
1628 default:
1629 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
1630 "MorphingPortableReader::*", "IncompatibleClassChangeError"));
1631 }
1632 }
1633
1634 template<typename T>
1635 typename std::enable_if<
1636 std::is_same<int32_t, typename std::remove_cv<T>::type>::value,
1637 T>::type
1638 read_morphing(field_type current_field_type, const std::string& field_name)
1639 {
1640 switch (current_field_type) {
1641 case field_type::TYPE_INT:
1642 return PortableReaderBase::read<int32_t>(field_name);
1643 case field_type::TYPE_CHAR:
1644 return PortableReaderBase::read<char>(field_name);
1645 default:
1646 return read_morphing<int16_t>(current_field_type, field_name);
1647 }
1648 }
1649
1650 template<typename T>
1651 typename std::enable_if<
1652 std::is_same<int64_t, typename std::remove_cv<T>::type>::value,
1653 T>::type
1654 read_morphing(field_type current_field_type, const std::string& field_name)
1655 {
1656 switch (current_field_type) {
1657 case field_type::TYPE_LONG:
1658 return PortableReaderBase::read<int64_t>(field_name);
1659 default:
1660 return read_morphing<int32_t>(current_field_type, field_name);
1661 }
1662 }
1663
1664 template<typename T>
1665 typename std::enable_if<
1666 std::is_same<float, typename std::remove_cv<T>::type>::value,
1667 T>::type
1668 read_morphing(field_type current_field_type, const std::string& field_name)
1669 {
1670 switch (current_field_type) {
1671 case field_type::TYPE_FLOAT:
1672 return PortableReaderBase::read<float>(field_name);
1673 default:
1674 return static_cast<float>(
1675 read_morphing<int32_t>(current_field_type, field_name));
1676 }
1677 }
1678
1679 template<typename T>
1680 typename std::enable_if<
1681 std::is_same<double, typename std::remove_cv<T>::type>::value,
1682 T>::type
1683 read_morphing(field_type current_field_type, const std::string& field_name)
1684 {
1685 switch (current_field_type) {
1686 case field_type::TYPE_DOUBLE:
1687 return PortableReaderBase::read<double>(field_name);
1688 case field_type::TYPE_FLOAT:
1689 return PortableReaderBase::read<float>(field_name);
1690 default:
1691 return static_cast<double>(
1692 read_morphing<int64_t>(current_field_type, field_name));
1693 }
1694 }
1695};
1696
1697class DefaultPortableWriter;
1698class HAZELCAST_API PortableSerializer
1699{
1700 friend DefaultPortableWriter;
1701
1702public:
1703 PortableSerializer(PortableContext& portable_context);
1704
1705 template<typename T>
1706 T read_object(object_data_input& in);
1707
1708 template<typename T>
1709 T read(object_data_input& in, int32_t factory_id, int32_t class_id);
1710
1711 template<typename T>
1712 void write(const T& object, object_data_output& out);
1713
1714private:
1715 PortableContext& context_;
1716
1717 template<typename T>
1718 int find_portable_version(int factory_id, int class_id) const;
1719
1720 portable_reader create_reader(object_data_input& input,
1721 int factory_id,
1722 int class_id,
1723 int version,
1724 int portable_version);
1725
1726 int32_t read_int(object_data_input& in) const;
1727
1728 template<typename T>
1729 void write_internal(const T& object, object_data_output& out);
1730
1731 template<typename T>
1732 void write_internal(const T& object,
1733 std::shared_ptr<ClassDefinition>& cd,
1734 object_data_output& out);
1735
1736 template<typename T>
1737 std::shared_ptr<ClassDefinition> lookup_or_register_class_definition(
1738 const T& portable);
1739};
1740
1741class HAZELCAST_API DataSerializer
1742{
1743public:
1744 template<typename T>
1745 static boost::optional<T> read_object(object_data_input& in)
1746 {
1747 bool identified = in.read<bool>();
1748 if (!identified) {
1749 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
1750 "object_data_input::read_object<identified_data_serializer>",
1751 "Received data is not identified data serialized."));
1752 }
1753
1754 int32_t expectedFactoryId = hz_serializer<T>::get_factory_id();
1755 int32_t expectedClassId = hz_serializer<T>::get_class_id();
1756 int32_t factoryId = in.read<int32_t>();
1757 int32_t classId = in.read<int32_t>();
1758 if (expectedFactoryId != factoryId || expectedClassId != classId) {
1759 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
1760 "object_data_input::read_object<identified_data_serializer>",
1761 (boost::format("Factory id %1% and class id %2% of data do not "
1762 "match expected "
1763 "factory id %3% and class id %4%!") %
1764 factoryId % classId % expectedFactoryId % expectedClassId)
1765 .str()));
1766 }
1767
1768 return boost::make_optional(hz_serializer<T>::read_data(in));
1769 }
1770
1771 template<typename T>
1772 static void write(const T& object, object_data_output& out);
1773
1774private:
1775 int32_t read_int(object_data_input& in) const;
1776};
1777
1778class HAZELCAST_API DefaultPortableWriter
1779{
1780public:
1781 DefaultPortableWriter(PortableSerializer& portable_ser,
1782 std::shared_ptr<ClassDefinition> cd,
1783 object_data_output& output);
1784
1785 object_data_output& get_raw_data_output();
1786
1787 template<typename T>
1788 void write(const std::string& field_name, T value)
1789 {
1790 typedef typename std::remove_pointer<typename std::remove_reference<
1791 typename std::remove_cv<T>::type>::type>::type value_type;
1792 set_position(field_name, PortableContext::get_type<value_type>());
1793 object_data_output_.write(value);
1794 }
1795
1796 void end();
1797
1798 template<typename T>
1799 void write_null_portable(const std::string& field_name);
1800
1801 template<typename T>
1802 void write_portable(const std::string& field_name, const T* portable);
1803
1804 template<typename T>
1805 void write_portable_array(const std::string& field_name,
1806 const std::vector<T>* values);
1807
1808private:
1809 FieldDefinition const& set_position(const std::string& field_name,
1810 field_type field_type);
1811
1812 template<typename T>
1813 void check_portable_attributes(const FieldDefinition& fd);
1814
1815 bool raw_;
1816 PortableSerializer& portable_serializer_;
1817 object_data_output& object_data_output_;
1818 size_t begin_;
1819 size_t offset_;
1820 std::unordered_set<std::string> written_fields_;
1821 std::shared_ptr<ClassDefinition> cd_;
1822};
1823} // namespace pimpl
1824} // namespace serialization
1825} // namespace client
1826} // namespace hazelcast
1827
1828#include "hazelcast/client/serialization/pimpl/compact/compact.h"
1829
1830namespace hazelcast {
1831namespace client {
1832namespace serialization {
1833namespace pimpl {
1834class HAZELCAST_API SerializationService : public util::Disposable
1835{
1836public:
1837 SerializationService(const serialization_config& config,
1838 default_schema_service&);
1839
1840 PortableSerializer& get_portable_serializer();
1841
1842 compact_stream_serializer& get_compact_serializer();
1843
1844 DataSerializer& get_data_serializer();
1845
1846 template<typename T>
1847 inline data to_data(const T* object)
1848 {
1849 object_data_output output(
1850 serialization_config_.get_byte_order(),
1851 false,
1852 &portable_serializer_,
1853 &compact_serializer_,
1854 serialization_config_.get_global_serializer());
1855
1856 write_hash<T>(object, output);
1857
1858 output.write_object<T>(object);
1859
1860 return { std::move(output).to_byte_array(),
1861 std::move(output.schemas_will_be_replicated_) };
1862 }
1863
1864 template<typename T>
1865 inline data to_data(const T& object)
1866 {
1867 object_data_output output(
1868 serialization_config_.get_byte_order(),
1869 false,
1870 &portable_serializer_,
1871 &compact_serializer_,
1872 serialization_config_.get_global_serializer());
1873
1874 write_hash<T>(&object, output);
1875
1876 output.write_object<T>(object);
1877
1878 return { std::move(output).to_byte_array(),
1879 std::move(output.schemas_will_be_replicated_) };
1880 }
1881
1882 template<typename T>
1883 inline std::shared_ptr<data> to_shared_data(const T* object)
1884 {
1885 if (NULL == object) {
1886 return std::shared_ptr<data>();
1887 }
1888 return std::shared_ptr<data>(new data(to_data<T>(object)));
1889 }
1890
1891 template<typename T>
1892 inline boost::optional<T> to_object(const data* data)
1893 {
1894 if (!data) {
1895 return boost::none;
1896 }
1897 return to_object<T>(*data);
1898 }
1899
1900 template<typename T>
1901 typename std::enable_if<
1902 !(std::is_same<T, const char*>::value ||
1903 std::is_same<T, const char*>::value ||
1904 std::is_same<T, typed_data>::value),
1905 boost::optional<T>>::type inline to_object(const data& data)
1906 {
1907 if (is_null_data(data)) {
1908 return boost::none;
1909 }
1910
1911 int32_t typeId = data.get_type();
1912
1913 // Constant 8 is Data::DATA_OFFSET. Windows DLL export does not
1914 // let usage of static member.
1915 object_data_input objectDataInput(
1916 serialization_config_.get_byte_order(),
1917 data.to_byte_array(),
1918 8,
1919 portable_serializer_,
1920 compact_serializer_,
1921 data_serializer_,
1922 serialization_config_.get_global_serializer());
1923 return objectDataInput.read_object<T>(typeId);
1924 }
1925
1926 template<typename T>
1927 typename std::enable_if<
1928 std::is_same<T, typed_data>::value,
1929 boost::optional<T>>::type inline to_object(const data& d)
1930 {
1931 return boost::make_optional(typed_data(data(d), *this));
1932 }
1933
1934 template<typename T>
1935 typename std::enable_if<
1936 std::is_same<T, const char*>::value,
1937 boost::optional<std::string>>::type inline to_object(const data& data)
1938 {
1939 return to_object<std::string>(data);
1940 }
1941
1942 template<typename T>
1943 typename std::enable_if<
1944 std::is_array<T>::value &&
1945 std::is_same<typename std::remove_all_extents<T>::type, char>::value,
1946 boost::optional<std::string>>::type inline to_object(const data& data)
1947 {
1948 return to_object<std::string>(data);
1949 }
1950
1951 template<typename T>
1952 inline std::shared_ptr<data> to_shared_object(
1953 const std::shared_ptr<data>& data)
1954 {
1955 return data;
1956 }
1957
1958 byte get_version() const;
1959
1960 object_type get_object_type(const data* data);
1961
1965 void dispose() override;
1966
1967 object_data_output new_output_stream();
1968
1969private:
1970 SerializationService(const SerializationService&) = delete;
1971
1972 SerializationService& operator=(const SerializationService&) = delete;
1973
1974 const serialization_config& serialization_config_;
1975 PortableContext portable_context_;
1976 serialization::pimpl::PortableSerializer portable_serializer_;
1977 serialization::pimpl::compact_stream_serializer compact_serializer_;
1978 serialization::pimpl::DataSerializer data_serializer_;
1979
1980 static bool is_null_data(const data& data);
1981
1982 template<typename T>
1983 void write_hash(const partition_aware_marker* obj, data_output& out)
1984 {
1985 typedef typename T::KEY_TYPE PK_TYPE;
1986 const partition_aware<PK_TYPE>* partitionAwareObj =
1987 static_cast<const partition_aware<PK_TYPE>*>(obj);
1988 const PK_TYPE* pk = partitionAwareObj->get_partition_key();
1989 if (pk != NULL) {
1990 data partitionKey = to_data<PK_TYPE>(pk);
1991 out.write<int32_t>(partitionKey.get_partition_hash());
1992 }
1993 }
1994
1995 template<typename T>
1996 void write_hash(const void* /* obj */, data_output& out)
1997 {
1998 out.write(0, boost::endian::order::big);
1999 }
2000};
2001
2002template<>
2003data HAZELCAST_API
2004SerializationService::to_data(const char* object);
2005} // namespace pimpl
2006
2012class HAZELCAST_API portable_reader
2013{
2014public:
2015 portable_reader(pimpl::PortableSerializer& portable_ser,
2016 object_data_input& data_input,
2017 const std::shared_ptr<ClassDefinition>& cd,
2018 bool is_default_reader);
2019
2024 template<typename T>
2025 typename std::enable_if<
2026 std::is_same<int16_t, typename std::remove_cv<T>::type>::value ||
2027 std::is_same<int32_t, typename std::remove_cv<T>::type>::value ||
2028 std::is_same<int64_t, typename std::remove_cv<T>::type>::value ||
2029 std::is_same<float, typename std::remove_cv<T>::type>::value ||
2030 std::is_same<double, typename std::remove_cv<T>::type>::value ||
2031 std::is_same<byte, typename std::remove_cv<T>::type>::value ||
2032 std::is_same<char, typename std::remove_cv<T>::type>::value ||
2033 std::is_same<char16_t, typename std::remove_cv<T>::type>::value ||
2034 std::is_same<bool, typename std::remove_cv<T>::type>::value ||
2035 std::is_same<std::string, typename std::remove_cv<T>::type>::value,
2036 T>::type
2037 read(const std::string& field_name)
2038 {
2039 if (is_default_reader_)
2040 return default_portable_reader_->read<T>(field_name);
2041 return morphing_portable_reader_->read<T>(field_name);
2042 }
2043
2048 template<typename T>
2049 typename std::enable_if<
2050 std::is_same<std::vector<byte>,
2051 typename std::remove_cv<T>::type>::value ||
2052 std::is_same<std::vector<char>,
2053 typename std::remove_cv<T>::type>::value ||
2054 std::is_same<std::vector<bool>,
2055 typename std::remove_cv<T>::type>::value ||
2056 std::is_same<std::vector<int16_t>,
2057 typename std::remove_cv<T>::type>::value ||
2058 std::is_same<std::vector<int32_t>,
2059 typename std::remove_cv<T>::type>::value ||
2060 std::is_same<std::vector<int64_t>,
2061 typename std::remove_cv<T>::type>::value ||
2062 std::is_same<std::vector<float>,
2063 typename std::remove_cv<T>::type>::value ||
2064 std::is_same<std::vector<double>,
2065 typename std::remove_cv<T>::type>::value ||
2066 std::is_same<std::vector<std::string>,
2067 typename std::remove_cv<T>::type>::value,
2068 boost::optional<T>>::type
2069 read(const std::string& field_name)
2070 {
2071 if (is_default_reader_)
2072 return default_portable_reader_->read<T>(field_name);
2073 return morphing_portable_reader_->read<T>(field_name);
2074 }
2075
2081 template<typename T>
2082 boost::optional<T> read_portable(const std::string& field_name);
2083
2089 template<typename T>
2090 boost::optional<std::vector<T>> read_portable_array(
2091 const std::string& field_name);
2092
2102 object_data_input& get_raw_data_input();
2103
2107 void end();
2108
2109private:
2110 bool is_default_reader_;
2111 boost::optional<pimpl::DefaultPortableReader> default_portable_reader_;
2112 boost::optional<pimpl::MorphingPortableReader> morphing_portable_reader_;
2113};
2114
2120class HAZELCAST_API portable_writer
2121{
2122public:
2126 portable_writer(pimpl::DefaultPortableWriter* default_portable_writer);
2127
2131 portable_writer(pimpl::ClassDefinitionWriter* class_definition_writer);
2132
2133 template<typename T>
2134 void write(const std::string& field_name, T value)
2135 {
2136 if (is_default_writer_) {
2137 default_portable_writer_->write(field_name, value);
2138 } else {
2139 class_definition_writer_->write(field_name, value);
2140 }
2141 }
2142
2146 void end();
2147
2156 template<typename T>
2157 void write_null_portable(const std::string& field_name);
2158
2165 template<typename T>
2166 void write_portable(const std::string& field_name, const T* portable);
2167
2174 template<typename T>
2175 void write_portable_array(const std::string& field_name,
2176 const std::vector<T>* values);
2177
2188
2189private:
2190 pimpl::DefaultPortableWriter* default_portable_writer_;
2191 pimpl::ClassDefinitionWriter* class_definition_writer_;
2192 bool is_default_writer_;
2193};
2194
2195template<typename T>
2196boost::optional<T>
2197portable_reader::read_portable(const std::string& field_name)
2198{
2199 if (is_default_reader_)
2200 return default_portable_reader_->read_portable<T>(field_name);
2201 return morphing_portable_reader_->read_portable<T>(field_name);
2202}
2203
2210template<typename T>
2211boost::optional<std::vector<T>>
2212portable_reader::read_portable_array(const std::string& field_name)
2213{
2214 if (is_default_reader_)
2215 return default_portable_reader_->read_portable_array<T>(field_name);
2216 return morphing_portable_reader_->read_portable_array<T>(field_name);
2217};
2218
2219template<typename T>
2220void
2221portable_writer::write_null_portable(const std::string& field_name)
2222{
2223 if (is_default_writer_)
2224 return default_portable_writer_->write_null_portable<T>(field_name);
2225 return class_definition_writer_->write_null_portable<T>(field_name);
2226}
2227
2234template<typename T>
2235void
2236portable_writer::write_portable(const std::string& field_name,
2237 const T* portable)
2238{
2239 if (is_default_writer_)
2240 return default_portable_writer_->write_portable(field_name, portable);
2241 return class_definition_writer_->write_portable(field_name, portable);
2242}
2243
2250template<typename T>
2251void
2252portable_writer::write_portable_array(const std::string& field_name,
2253 const std::vector<T>* values)
2254{
2255 if (is_default_writer_)
2256 return default_portable_writer_->write_portable_array(field_name,
2257 values);
2258 return class_definition_writer_->write_portable_array(field_name, values);
2259}
2260
2261template<typename T>
2262void
2263object_data_output::write_object(const T* object)
2264{
2265 if (is_no_write_) {
2266 return;
2267 }
2268 if (!object) {
2269 write(static_cast<int32_t>(
2270 pimpl::serialization_constants::CONSTANT_TYPE_NULL),
2271 boost::endian::order::big);
2272 return;
2273 }
2274
2275 write_object<T>(*object);
2276}
2277
2278template<typename T>
2279typename std::enable_if<
2280 !(std::is_array<T>::value &&
2281 std::is_same<typename std::remove_all_extents<T>::type, char>::value),
2282 void>::type
2283object_data_output::write_object(const boost::optional<T>& object)
2284{
2285 if (is_no_write_) {
2286 return;
2287 }
2288 if (!object) {
2289 write(static_cast<int32_t>(
2290 pimpl::serialization_constants::CONSTANT_TYPE_NULL),
2291 boost::endian::order::big);
2292 return;
2293 }
2294
2295 write_object<T>(object.value());
2296}
2297
2298template<typename T>
2299typename std::enable_if<
2300 std::is_base_of<identified_data_serializer, hz_serializer<T>>::value,
2301 void>::type inline object_data_output::write_object(const T& object)
2302{
2303 if (is_no_write_) {
2304 return;
2305 }
2306 write(
2307 static_cast<int32_t>(pimpl::serialization_constants::CONSTANT_TYPE_DATA),
2308 boost::endian::order::big);
2309 pimpl::DataSerializer::write<T>(object, *this);
2310}
2311
2312template<typename T>
2313typename std::enable_if<
2314 std::is_base_of<portable_serializer, hz_serializer<T>>::value,
2315 void>::type inline object_data_output::write_object(const T& object)
2316{
2317 if (is_no_write_) {
2318 return;
2319 }
2320 write(static_cast<int32_t>(
2321 pimpl::serialization_constants::CONSTANT_TYPE_PORTABLE),
2322 boost::endian::order::big);
2323 portable_serializer_->write<T>(object, *this);
2324}
2325
2326template<typename T>
2327typename std::enable_if<
2328 std::is_base_of<compact::compact_serializer, hz_serializer<T>>::value,
2329 void>::type inline object_data_output::write_object(const T& object)
2330{
2331 if (is_no_write_) {
2332 return;
2333 }
2334 write(static_cast<int32_t>(
2335 pimpl::serialization_constants::CONSTANT_TYPE_COMPACT),
2336 boost::endian::order::big);
2337 compact_serializer_->write<T>(object, *this);
2338}
2339
2340template<typename T>
2341typename std::enable_if<
2342 std::is_base_of<builtin_serializer, hz_serializer<T>>::value,
2343 void>::type inline object_data_output::write_object(const T& object)
2344{
2345 if (is_no_write_) {
2346 return;
2347 }
2348 write(static_cast<int32_t>((hz_serializer<T>::get_type_id())),
2349 boost::endian::order::big);
2350 write<T>(object);
2351}
2352
2353template<typename T>
2354typename std::enable_if<
2355 std::is_array<T>::value &&
2356 std::is_same<typename std::remove_all_extents<T>::type, char>::value,
2357 void>::type inline object_data_output::write_object(const T& object)
2358{
2359 write_object(std::string(object));
2360}
2361
2362template<typename T>
2363typename std::enable_if<
2364 std::is_base_of<custom_serializer, hz_serializer<T>>::value,
2365 void>::type inline object_data_output::write_object(const T& object)
2366{
2367 if (is_no_write_) {
2368 return;
2369 }
2370 static_assert(hz_serializer<T>::get_type_id() > 0,
2371 "Custom serializer type id can not be negative!");
2372 write(hz_serializer<T>::get_type_id(), boost::endian::order::big);
2373 hz_serializer<T>::write(object, *this);
2374}
2375
2376template<typename T>
2377typename std::enable_if<
2378 std::is_same<generic_record::generic_record, T>::value>::type
2379object_data_output::write_object(const T& object)
2380{
2381 if (is_no_write_) {
2382 return;
2383 }
2384
2385 const auto& record =
2386 static_cast<const generic_record::generic_record&>(object);
2387
2388 write(static_cast<int32_t>(
2389 pimpl::serialization_constants::CONSTANT_TYPE_COMPACT),
2390 boost::endian::order::big);
2391 compact_serializer_->write_generic_record(record, *this);
2392}
2393
2400template<typename T>
2401typename std::enable_if<
2402 !(std::is_base_of<builtin_serializer, hz_serializer<T>>::value ||
2403 std::is_base_of<identified_data_serializer, hz_serializer<T>>::value ||
2404 std::is_base_of<portable_serializer, hz_serializer<T>>::value ||
2405 std::is_base_of<compact::compact_serializer, hz_serializer<T>>::value ||
2406 std::is_base_of<custom_serializer, hz_serializer<T>>::value ||
2407 std::is_same<generic_record::generic_record, T>::value ||
2408 (std::is_array<T>::value &&
2409 std::is_same<typename std::remove_all_extents<T>::type, char>::value)),
2410 void>::type inline object_data_output::write_object(const T object)
2411{
2412 if (!global_serializer_) {
2413 throw exception::hazelcast_serialization(
2414 "object_data_output::write_object",
2415 (boost::format("No serializer found for type(%1%).") %
2416 typeid(T).name())
2417 .str());
2418 }
2419 if (is_no_write_) {
2420 return;
2421 }
2422 write(static_cast<int32_t>(global_serializer::get_type_id()),
2423 boost::endian::order::big);
2424 global_serializer_->write(boost::any(std::move(object)), *this);
2425}
2426
2427template<typename T>
2428typename std::enable_if<
2429 !(std::is_array<T>::value &&
2430 std::is_same<typename std::remove_all_extents<T>::type, char>::value),
2431 boost::optional<T>>::type inline object_data_input::read_object()
2432{
2433 int32_t typeId = read(boost::endian::order::big);
2434 if (static_cast<int32_t>(
2435 pimpl::serialization_constants::CONSTANT_TYPE_NULL) == typeId) {
2436 return boost::none;
2437 }
2438 return read_object<T>(typeId);
2439}
2440
2441template<typename T>
2442typename std::enable_if<
2443 std::is_array<T>::value &&
2444 std::is_same<typename std::remove_all_extents<T>::type, char>::value,
2445 boost::optional<std::string>>::type inline object_data_input::read_object()
2446{
2447 return read_object<std::string>();
2448}
2449
2450template<typename T>
2451typename std::enable_if<
2452 std::is_base_of<identified_data_serializer, hz_serializer<T>>::value,
2453 boost::optional<T>>::type inline object_data_input::read_object(int32_t
2454 type_id)
2455{
2456 if (type_id != static_cast<int32_t>(
2457 pimpl::serialization_constants::CONSTANT_TYPE_DATA)) {
2458 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
2459 "object_data_input::read_object<identified_data_serializer>",
2460 (boost::format("The associated serializer Serializer<T> is "
2461 "identified_data_serializer "
2462 "but received data type id is %1%") %
2463 type_id)
2464 .str()));
2465 }
2466
2467 return data_serializer_.read_object<T>(*this);
2468}
2469
2470template<typename T>
2471typename std::enable_if<
2472 std::is_base_of<portable_serializer, hz_serializer<T>>::value,
2473 boost::optional<T>>::type inline object_data_input::read_object(int32_t
2474 type_id)
2475{
2476 if (type_id != static_cast<int32_t>(
2477 pimpl::serialization_constants::CONSTANT_TYPE_PORTABLE)) {
2478 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
2479 "object_data_input::read_object<portable_serializer>",
2480 (boost::format(
2481 "The associated serializer Serializer<T> is portable_serializer "
2482 "but received data type id is %1%") %
2483 type_id)
2484 .str()));
2485 }
2486
2487 return portable_serializer_.read_object<T>(*this);
2488}
2489
2490template<typename T>
2491typename std::enable_if<
2492 std::is_base_of<compact::compact_serializer, hz_serializer<T>>::value,
2493 boost::optional<T>>::type inline object_data_input::read_object(int32_t
2494 type_id)
2495{
2496 return compact_serializer_.template read<T>(*this);
2497}
2498
2499template<typename T>
2500typename std::enable_if<
2501 std::is_base_of<custom_serializer, hz_serializer<T>>::value,
2502 boost::optional<T>>::type inline object_data_input::read_object(int32_t
2503 type_id)
2504{
2505 if (type_id != hz_serializer<T>::get_type_id()) {
2506 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
2507 "object_data_input::read_object<>",
2508 (boost::format("The associated serializer Serializer<T> type id %1% "
2509 "does not match "
2510 "received data type id is %2%") %
2511 hz_serializer<T>::get_type_id() % type_id)
2512 .str()));
2513 }
2514
2515 return boost::optional<T>(hz_serializer<T>::read(*this));
2516}
2517
2518template<typename T>
2519typename std::enable_if<
2520 std::is_base_of<builtin_serializer, hz_serializer<T>>::value,
2521 boost::optional<T>>::type inline object_data_input::read_object(int32_t
2522 type_id)
2523{
2524 assert(type_id == static_cast<int32_t>(hz_serializer<T>::get_type_id()));
2525 (void)type_id;
2526
2527 return boost::optional<T>(read<T>());
2528}
2529
2530template<typename T>
2531typename std::enable_if<std::is_same<generic_record::generic_record, T>::value,
2532 boost::optional<T>>::type
2533object_data_input::read_object(int32_t type_id)
2534{
2535 return compact_serializer_.read_generic_record(*this);
2536}
2537
2538template<typename T>
2539typename std::enable_if<
2540 !(std::is_base_of<identified_data_serializer, hz_serializer<T>>::value ||
2541 std::is_base_of<portable_serializer, hz_serializer<T>>::value ||
2542 std::is_base_of<compact::compact_serializer, hz_serializer<T>>::value ||
2543 std::is_base_of<builtin_serializer, hz_serializer<T>>::value ||
2544 std::is_base_of<custom_serializer, hz_serializer<T>>::value ||
2545 std::is_same<generic_record::generic_record, T>::value),
2546 boost::optional<T>>::type inline object_data_input::read_object(int32_t
2547 type_id)
2548{
2549 if (!global_serializer_) {
2550 throw exception::hazelcast_serialization(
2551 "object_data_input::read_object",
2552 (boost::format("No serializer found for type %1%.") %
2553 typeid(T).name())
2554 .str());
2555 }
2556
2557 if (type_id != static_cast<int32_t>(global_serializer_->get_type_id())) {
2558 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
2559 "object_data_input::read_object<>",
2560 (boost::format("The global serializer type id %1% does not match "
2561 "received data type id is %2%") %
2562 static_cast<int32_t>(global_serializer_->get_type_id()) % type_id)
2563 .str()));
2564 }
2565
2566 return boost::optional<T>(
2567 boost::any_cast<T>(std::move(global_serializer_->read(*this))));
2568}
2569
2570namespace pimpl {
2571template<>
2572data
2573SerializationService::to_data(const typed_data* object);
2574
2575template<typename T>
2576boost::optional<T>
2577DefaultPortableReader::read_portable(const std::string& field_name)
2578{
2579 return get_portable_instance<T>(field_name);
2580}
2581
2582template<typename T>
2583boost::optional<std::vector<T>>
2584DefaultPortableReader::read_portable_array(const std::string& field_name)
2585{
2586 PortableReaderBase::set_position(field_name,
2587 field_type::TYPE_PORTABLE_ARRAY);
2588
2589 data_input_->read<int32_t>();
2590 std::vector<T> portables;
2591
2592 set_position(field_name, field_type::TYPE_PORTABLE_ARRAY);
2593
2594 int32_t len = data_input_->read<int32_t>();
2595 if (len == util::Bits::NULL_ARRAY) {
2596 return boost::none;
2597 }
2598 int32_t factoryId = data_input_->read<int32_t>();
2599 int32_t classId = data_input_->read<int32_t>();
2600
2601 check_factory_and_class(cd_->get_field(field_name), factoryId, classId);
2602
2603 if (len > 0) {
2604 int offset = data_input_->position();
2605 for (int i = 0; i < len; i++) {
2606 data_input_->position(offset + i * util::Bits::INT_SIZE_IN_BYTES);
2607 int32_t start = data_input_->read<int32_t>();
2608 data_input_->position(start);
2609
2610 portables.push_back(
2611 portable_serializer_->read<T>(*data_input_, factoryId, classId));
2612 }
2613 }
2614 return portables;
2615}
2616
2617template<typename T>
2618boost::optional<T>
2619MorphingPortableReader::read_portable(const std::string& field_name)
2620{
2621 return get_portable_instance<T>(field_name);
2622}
2623
2624template<typename T>
2625boost::optional<std::vector<T>>
2626MorphingPortableReader::read_portable_array(const std::string& field_name)
2627{
2628 PortableReaderBase::set_position(field_name,
2629 field_type::TYPE_PORTABLE_ARRAY);
2630
2631 data_input_->read<int32_t>();
2632 std::vector<T> portables;
2633
2634 set_position(field_name, field_type::TYPE_PORTABLE_ARRAY);
2635
2636 int32_t len = data_input_->read<int32_t>();
2637 if (len == util::Bits::NULL_ARRAY) {
2638 return boost::none;
2639 }
2640 int32_t factoryId = data_input_->read<int32_t>();
2641 int32_t classId = data_input_->read<int32_t>();
2642
2643 check_factory_and_class(cd_->get_field(field_name), factoryId, classId);
2644
2645 if (len > 0) {
2646 portables.reserve(static_cast<size_t>(len));
2647 int offset = data_input_->position();
2648 for (int i = 0; i < len; i++) {
2649 data_input_->position(offset + i * util::Bits::INT_SIZE_IN_BYTES);
2650 int32_t start = data_input_->read<int32_t>();
2651 data_input_->position(start);
2652
2653 portables.emplace_back(
2654 portable_serializer_->read<T>(*data_input_, factoryId, classId));
2655 }
2656 }
2657
2658 return boost::make_optional(std::move(portables));
2659}
2660
2661template<typename T>
2662T
2663PortableSerializer::read_object(object_data_input& in)
2664{
2665 int32_t factoryId = read_int(in);
2666 int32_t classId = read_int(in);
2667
2668 if (factoryId != hz_serializer<T>::get_factory_id() ||
2669 classId != hz_serializer<T>::get_class_id()) {
2670 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
2671 "PortableSerializer::read_object",
2672 (boost::format("Received data (factory-class id)=(%1%, %2%) does not "
2673 "match expected factory-class id (%3%, %4%)") %
2674 factoryId % classId % hz_serializer<T>::get_factory_id() %
2675 hz_serializer<T>::get_class_id())
2676 .str()));
2677 }
2678 return read<T>(in, factoryId, classId);
2679}
2680
2681template<typename T>
2682T
2683PortableSerializer::read(object_data_input& in,
2684 int32_t factory_id,
2685 int32_t class_id)
2686{
2687 int version = in.read<int32_t>();
2688
2689 int portableVersion = find_portable_version<T>(factory_id, class_id);
2690
2691 portable_reader reader =
2692 create_reader(in, factory_id, class_id, version, portableVersion);
2693 T result = hz_serializer<T>::read_portable(reader);
2694 reader.end();
2695 return result;
2696}
2697
2698template<typename T>
2699void
2700PortableSerializer::write(const T& object, object_data_output& out)
2701{
2702 out.write<int32_t>(hz_serializer<T>::get_factory_id());
2703 out.write<int32_t>(hz_serializer<T>::get_class_id());
2704
2705 write_internal(object, out);
2706}
2707
2708template<typename T>
2709void
2710PortableSerializer::write_internal(const T& object, object_data_output& out)
2711{
2712 auto cd = context_.lookup_or_register_class_definition<T>(object);
2713 write_internal(object, cd, out);
2714}
2715
2716template<typename T>
2717void
2718PortableSerializer::write_internal(const T& object,
2719 std::shared_ptr<ClassDefinition>& cd,
2720 object_data_output& out)
2721{
2722 out.write<int32_t>(cd->get_version());
2723
2724 DefaultPortableWriter dpw(*this, cd, out);
2725 portable_writer portableWriter(&dpw);
2726 hz_serializer<T>::write_portable(object, portableWriter);
2727 portableWriter.end();
2728}
2729
2730template<typename T>
2731std::shared_ptr<ClassDefinition>
2732PortableSerializer::lookup_or_register_class_definition(const T& portable)
2733{
2734 return context_.lookup_or_register_class_definition<T>(portable);
2735}
2736
2737template<typename T>
2738int
2739PortableSerializer::find_portable_version(int factory_id, int class_id) const
2740{
2741 int currentVersion = context_.get_class_version(factory_id, class_id);
2742 if (currentVersion < 0) {
2743 currentVersion =
2744 PortableVersionHelper::get_version<T>(context_.get_version());
2745 if (currentVersion > 0) {
2746 context_.set_class_version(factory_id, class_id, currentVersion);
2747 }
2748 }
2749 return currentVersion;
2750}
2751
2752template<typename T>
2753void
2754DataSerializer::write(const T& object, object_data_output& out)
2755{
2756 out.write<bool>(true);
2757 out.write<int32_t>(hz_serializer<T>::get_factory_id());
2758 out.write<int32_t>(hz_serializer<T>::get_class_id());
2759 hz_serializer<T>::write_data(object, out);
2760}
2761
2762template<typename T>
2763std::shared_ptr<ClassDefinition>
2764PortableContext::lookup_or_register_class_definition(const T& portable)
2765{
2766 int portableVersion = PortableVersionHelper::get_version<T>(
2767 serialization_config_.get_portable_version());
2768 std::shared_ptr<ClassDefinition> cd =
2769 lookup_class_definition(hz_serializer<T>::get_factory_id(),
2770 hz_serializer<T>::get_class_id(),
2771 portableVersion);
2772 if (cd.get() == NULL) {
2773 ClassDefinitionBuilder classDefinitionBuilder(
2774 hz_serializer<T>::get_factory_id(),
2775 hz_serializer<T>::get_class_id(),
2776 portableVersion);
2777 ClassDefinitionWriter cdw(*this, classDefinitionBuilder);
2778 portable_writer portableWriter(&cdw);
2779 hz_serializer<T>::write_portable(portable, portableWriter);
2780 cd = cdw.register_and_get();
2781 }
2782 return cd;
2783}
2784
2785template<typename T>
2786boost::optional<T>
2787PortableReaderBase::get_portable_instance(const std::string& field_name)
2788{
2789 set_position(field_name, field_type::TYPE_PORTABLE);
2790
2791 bool isNull = data_input_->read<bool>();
2792 int32_t factoryId = data_input_->read<int32_t>();
2793 int32_t classId = data_input_->read<int32_t>();
2794
2795 check_factory_and_class(cd_->get_field(field_name), factoryId, classId);
2796
2797 if (isNull) {
2798 return boost::none;
2799 } else {
2800 return portable_serializer_->read<T>(*data_input_, factoryId, classId);
2801 }
2802}
2803
2804template<typename T>
2805void
2806DefaultPortableWriter::write_null_portable(const std::string& field_name)
2807{
2808 set_position(field_name, field_type::TYPE_PORTABLE);
2809 object_data_output_.write<bool>(true);
2810 object_data_output_.write<int32_t>(hz_serializer<T>::get_factory_id());
2811 object_data_output_.write<int32_t>(hz_serializer<T>::get_class_id());
2812}
2813
2814template<typename T>
2815void
2816DefaultPortableWriter::write_portable(const std::string& field_name,
2817 const T* portable)
2818{
2819 FieldDefinition const& fd =
2820 set_position(field_name, field_type::TYPE_PORTABLE);
2821 bool isNull = (nullptr == portable);
2822 object_data_output_.write<bool>(isNull);
2823
2824 object_data_output_.write<int32_t>(hz_serializer<T>::get_factory_id());
2825 object_data_output_.write<int32_t>(hz_serializer<T>::get_class_id());
2826
2827 if (!isNull) {
2828 check_portable_attributes<T>(fd);
2829 portable_serializer_.write_internal(*portable, object_data_output_);
2830 }
2831
2832 portable_serializer_.write(*portable, object_data_output_);
2833}
2834
2835template<typename T>
2836void
2837DefaultPortableWriter::write_portable_array(const std::string& field_name,
2838 const std::vector<T>* values)
2839{
2840 FieldDefinition const& fd =
2841 set_position(field_name, field_type::TYPE_PORTABLE_ARRAY);
2842 check_portable_attributes<T>(fd);
2843
2844 int32_t len =
2845 (values ? static_cast<int32_t>(values->size()) : util::Bits::NULL_ARRAY);
2846 object_data_output_.write<int32_t>(len);
2847
2848 object_data_output_.write<int32_t>(fd.get_factory_id());
2849 object_data_output_.write<int32_t>(fd.get_class_id());
2850
2851 if (len > 0) {
2852 std::shared_ptr<ClassDefinition> classDefinition =
2853 portable_serializer_.lookup_or_register_class_definition<T>(
2854 (*values)[0]);
2855 size_t currentOffset = object_data_output_.position();
2856 object_data_output_.position(currentOffset +
2857 len * util::Bits::INT_SIZE_IN_BYTES);
2858 for (int32_t i = 0; i < len; i++) {
2859 size_t position = object_data_output_.position();
2860 object_data_output_.write_at(currentOffset +
2861 i * util::Bits::INT_SIZE_IN_BYTES,
2862 static_cast<int32_t>(position));
2863 portable_serializer_.write_internal(
2864 (*values)[i], classDefinition, object_data_output_);
2865 }
2866 }
2867}
2868
2869template<typename T>
2870void
2871DefaultPortableWriter::check_portable_attributes(const FieldDefinition& fd)
2872{
2873 if (fd.get_factory_id() != hz_serializer<T>::get_factory_id()) {
2874 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
2875 "DefaultPortableWriter::::checkPortableAttributes",
2876 (boost::format("Wrong Portable type! Expected factory-id: %1%, "
2877 "Actual factory-id: %2%") %
2878 fd.get_factory_id() % hz_serializer<T>::get_factory_id())
2879 .str()));
2880 }
2881 if (fd.get_class_id() != hz_serializer<T>::get_class_id()) {
2882 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
2883 "DefaultPortableWriter::::checkPortableAttributes",
2884 (boost::format("Wrong Portable type! Expected class-id: %1%, Actual "
2885 "class-id: %2%") %
2886 fd.get_class_id() % hz_serializer<T>::get_class_id())
2887 .str()));
2888 }
2889}
2890
2891template<typename T>
2892std::shared_ptr<ClassDefinition>
2893ClassDefinitionWriter::create_nested_class_def(const T& portable)
2894{
2895 int version = PortableVersionHelper::get_version<T>(context_.get_version());
2896 ClassDefinitionBuilder definitionBuilder(hz_serializer<T>::get_factory_id(),
2897 hz_serializer<T>::get_class_id(),
2898 version);
2899
2900 ClassDefinitionWriter nestedWriter(context_, definitionBuilder);
2901 portable_writer portableWriter(&nestedWriter);
2902 hz_serializer<T>::write_portable(portable, portableWriter);
2903 return context_.register_class_definition(definitionBuilder.build());
2904}
2905} // namespace pimpl
2906} // namespace serialization
2907
2908template<typename T>
2909boost::optional<T>
2911{
2912 return ss_->to_object<T>(data_);
2913}
2914} // namespace client
2915} // namespace hazelcast
2916
2917#include "hazelcast/client/serialization/pimpl/compact/compact_impl.h"
2918
2919#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
2920#pragma warning(pop)
2921#endif
hazelcast_json_value is a wrapper for Json formatted strings.
void add_field_def(FieldDefinition &field_definition)
Internal API.
field_type get_field_type(const std::string &field_name) const
void write_data(pimpl::data_output &data_output)
Internal API.
const FieldDefinition & get_field(const std::string &field_name) const
void read_data(object_data_input &data_input)
Internal API.
void set_version_if_not_set(int new_version)
Internal API.
bool has_field(const std::string &field_name) const
ClassDefinition defines a class schema for portable classes.
void write_data(pimpl::data_output &data_output)
void read_data(object_data_input &data_input)
std::enable_if<!(std::is_base_of< identified_data_serializer, hz_serializer< T > >::value||std::is_base_of< portable_serializer, hz_serializer< T > >::value||std::is_base_of< compact::compact_serializer, hz_serializer< T > >::value||std::is_base_of< builtin_serializer, hz_serializer< T > >::value||std::is_base_of< custom_serializer, hz_serializer< T > >::value||std::is_same< generic_record::generic_record, T >::value), boost::optional< T > >::type read_object(int32_t type_id)
Global serialization.
object_data_input(boost::endian::order byte_order, const std::vector< byte > &buffer, int offset, pimpl::PortableSerializer &portable_ser, pimpl::compact_stream_serializer &compact_ser, pimpl::DataSerializer &data_ser, std::shared_ptr< serialization::global_serializer > global_serializer)
Internal API.
std::enable_if<!(std::is_array< T >::value &&std::is_same< typenamestd::remove_all_extents< T >::type, char >::value), boost::optional< T > >::type read_object()
object_data_output(boost::endian::order byte_order, bool dont_write=false, pimpl::PortableSerializer *portable_ser=nullptr, pimpl::compact_stream_serializer *compact_ser=nullptr, std::shared_ptr< serialization::global_serializer > global_serializer=nullptr)
Internal API Constructor.
std::enable_if< std::is_same< int16_t, typenamestd::remove_cv< T >::type >::value||std::is_same< int32_t, typenamestd::remove_cv< T >::type >::value||std::is_same< int64_t, typenamestd::remove_cv< T >::type >::value||std::is_same< float, typenamestd::remove_cv< T >::type >::value||std::is_same< double, typenamestd::remove_cv< T >::type >::value||std::is_same< byte, typenamestd::remove_cv< T >::type >::value||std::is_same< char, typenamestd::remove_cv< T >::type >::value||std::is_same< char16_t, typenamestd::remove_cv< T >::type >::value||std::is_same< bool, typenamestd::remove_cv< T >::type >::value||std::is_same< std::string, typenamestd::remove_cv< T >::type >::value, T >::type read(const std::string &field_name)
boost::optional< std::vector< T > > read_portable_array(const std::string &field_name)
std::enable_if< std::is_same< std::vector< byte >, typenamestd::remove_cv< T >::type >::value||std::is_same< std::vector< char >, typenamestd::remove_cv< T >::type >::value||std::is_same< std::vector< bool >, typenamestd::remove_cv< T >::type >::value||std::is_same< std::vector< int16_t >, typenamestd::remove_cv< T >::type >::value||std::is_same< std::vector< int32_t >, typenamestd::remove_cv< T >::type >::value||std::is_same< std::vector< int64_t >, typenamestd::remove_cv< T >::type >::value||std::is_same< std::vector< float >, typenamestd::remove_cv< T >::type >::value||std::is_same< std::vector< double >, typenamestd::remove_cv< T >::type >::value||std::is_same< std::vector< std::string >, typenamestd::remove_cv< T >::type >::value, boost::optional< T > >::type read(const std::string &field_name)
boost::optional< T > read_portable(const std::string &field_name)
void write_null_portable(const std::string &field_name)
To write a null portable value.
object_data_output & get_raw_data_output()
After writing portable fields, one can write remaining fields in old fashioned way consecutively at t...
void end()
Internal api , should not be called by end user.
void write_portable_array(const std::string &field_name, const std::vector< T > *values)
portable_writer(pimpl::DefaultPortableWriter *default_portable_writer)
Internal api constructor.
void write_portable(const std::string &field_name, const T *portable)
typed_data class is a wrapper class for the serialized binary data.
const serialization::pimpl::data & get_data() const
Internal API.
boost::optional< T > get() const
Deserializes the underlying binary data and produces the object of type T.
serialization::pimpl::object_type get_type() const
STL namespace.
An arbitrary precision and scale floating point number.
Definition big_decimal.h:44
Classes derived from this class should implement the following static methods: static int32_t get_cla...
Classes derived from this class should implement the following static methods: static int32_t get_cla...