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