Hazelcast C++ Client
Hazelcast C++ Client Library
serialization.h
1 /*
2  * Copyright (c) 2008-2021, 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 
36 #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
37 #pragma warning(push)
38 #pragma warning(disable: 4251) //for dll export
39 #endif
40 
41 namespace hazelcast {
42  namespace client {
43  class hazelcast_client;
44 
45  namespace serialization {
46  namespace pimpl {
47  // forward declarations
48  class PortableContext;
49 
50  class ClassDefinitionContext;
51 
52  class ClassDefinitionWriter;
53 
54  class DefaultPortableWriter;
55 
56  class DefaultPortableReader;
57 
58  class MorphingPortableReader;
59 
60  class PortableSerializer;
61 
62  class DataSerializer;
63 
64  class SerializationService;
65 
66  enum struct HAZELCAST_API serialization_constants {
67  CONSTANT_TYPE_NULL = 0,
68  CONSTANT_TYPE_PORTABLE = -1,
69  CONSTANT_TYPE_DATA = -2,
70  CONSTANT_TYPE_BYTE = -3,
71  CONSTANT_TYPE_BOOLEAN = -4,
72  CONSTANT_TYPE_CHAR = -5,
73  CONSTANT_TYPE_SHORT = -6,
74  CONSTANT_TYPE_INTEGER = -7,
75  CONSTANT_TYPE_LONG = -8,
76  CONSTANT_TYPE_FLOAT = -9,
77  CONSTANT_TYPE_DOUBLE = -10,
78  CONSTANT_TYPE_STRING = -11,
79  CONSTANT_TYPE_BYTE_ARRAY = -12,
80  CONSTANT_TYPE_BOOLEAN_ARRAY = -13,
81  CONSTANT_TYPE_CHAR_ARRAY = -14,
82  CONSTANT_TYPE_SHORT_ARRAY = -15,
83  CONSTANT_TYPE_INTEGER_ARRAY = -16,
84  CONSTANT_TYPE_LONG_ARRAY = -17,
85  CONSTANT_TYPE_FLOAT_ARRAY = -18,
86  CONSTANT_TYPE_DOUBLE_ARRAY = -19,
87  CONSTANT_TYPE_STRING_ARRAY = -20,
88  CONSTANT_TYPE_UUID = -21,
89  JAVASCRIPT_JSON_SERIALIZATION_TYPE = -130,
90 
91  CONSTANT_TYPE_GLOBAL = INT32_MIN
92  // ------------------------------------------------------------
93  };
94 
109  struct HAZELCAST_API object_type {
110  object_type();
111 
112  serialization_constants type_id;
113  int32_t factory_id;
114  int32_t class_id;
115 
116  };
117 
118  std::ostream HAZELCAST_API &operator<<(std::ostream &os, const object_type &type);
119  }
120  }
121 
126  class HAZELCAST_API typed_data {
127  public:
128  typed_data();
129 
130  typed_data(serialization::pimpl::data d,
131  serialization::pimpl::SerializationService &serialization_service);
132 
137  serialization::pimpl::object_type get_type() const;
138 
148  template <typename T>
149  boost::optional<T> get() const;
150 
155  const serialization::pimpl::data &get_data() const;
156 
157  private:
158  serialization::pimpl::data data_;
159  serialization::pimpl::SerializationService *ss_;
160  };
161 
162  bool HAZELCAST_API operator<(const typed_data &lhs, const typed_data &rhs);
163 
164  namespace serialization {
165  class object_data_input;
166  class object_data_output;
167  class portable_reader;
168 
169  namespace pimpl {
170  // forward declarations
171  class PortableContext;
172  class ClassDefinitionContext;
173  class ClassDefinitionWriter;
174  class DefaultPortableWriter;
175  class DefaultPortableReader;
176  class MorphingPortableReader;
177  class PortableSerializer;
178  class DataSerializer;
179  class SerializationService;
180  }
181 
182  template<typename T>
183  struct hz_serializer {};
184 
186 
187  struct custom_serializer {};
188 
190  virtual ~global_serializer() = default;
191 
192  static pimpl::serialization_constants get_type_id() {
193  return pimpl::serialization_constants::CONSTANT_TYPE_GLOBAL;
194  }
195 
196  virtual void write(const boost::any &object, object_data_output &out) = 0;
197 
198  virtual boost::any read(object_data_input &in) = 0;
199  };
200 
209  };
210 
219  };
220 
222  };
223 
224  template<>
225  struct HAZELCAST_API hz_serializer<byte> : public builtin_serializer {
226  public:
227  static inline pimpl::serialization_constants get_type_id() {
228  return pimpl::serialization_constants::CONSTANT_TYPE_BYTE;
229  }
230  };
231 
232  template<>
233  struct HAZELCAST_API hz_serializer<bool> : public builtin_serializer {
234  public:
235  static inline pimpl::serialization_constants get_type_id() {
236  return pimpl::serialization_constants::CONSTANT_TYPE_BOOLEAN;
237  }
238  };
239 
240  template<>
241  struct HAZELCAST_API hz_serializer<char> : public builtin_serializer {
242  public:
243  static inline pimpl::serialization_constants get_type_id() {
244  return pimpl::serialization_constants::CONSTANT_TYPE_CHAR;
245  }
246  };
247 
248  template<>
249  struct HAZELCAST_API hz_serializer<char16_t> : public builtin_serializer {
250  public:
251  static inline pimpl::serialization_constants get_type_id() {
252  return pimpl::serialization_constants::CONSTANT_TYPE_CHAR;
253  }
254  };
255 
256  template<>
257  struct HAZELCAST_API hz_serializer<int16_t> : public builtin_serializer {
258  public:
259  static inline pimpl::serialization_constants get_type_id() {
260  return pimpl::serialization_constants::CONSTANT_TYPE_SHORT;
261  }
262  };
263 
264  template<>
265  struct HAZELCAST_API hz_serializer<int32_t> : public builtin_serializer {
266  public:
267  static inline pimpl::serialization_constants get_type_id() {
268  return pimpl::serialization_constants::CONSTANT_TYPE_INTEGER;
269  }
270  };
271 
272  template<>
273  struct HAZELCAST_API hz_serializer<int64_t> : public builtin_serializer {
274  public:
275  static inline pimpl::serialization_constants get_type_id() {
276  return pimpl::serialization_constants::CONSTANT_TYPE_LONG;
277  }
278  };
279 
280  template<>
281  struct HAZELCAST_API hz_serializer<float> : public builtin_serializer {
282  public:
283  static inline pimpl::serialization_constants get_type_id() {
284  return pimpl::serialization_constants::CONSTANT_TYPE_FLOAT;
285  }
286  };
287 
288  template<>
289  struct HAZELCAST_API hz_serializer<double> : public builtin_serializer {
290  public:
291  static inline pimpl::serialization_constants get_type_id() {
292  return pimpl::serialization_constants::CONSTANT_TYPE_DOUBLE;
293  }
294  };
295 
296  template<>
297  struct HAZELCAST_API hz_serializer<std::string> : public builtin_serializer {
298  public:
299  static inline pimpl::serialization_constants get_type_id() {
300  return pimpl::serialization_constants::CONSTANT_TYPE_STRING;
301  }
302  };
303 
304 
305  template<>
306  struct HAZELCAST_API hz_serializer<hazelcast_json_value> : public builtin_serializer {
307  public:
308  static inline pimpl::serialization_constants get_type_id() {
309  return pimpl::serialization_constants::JAVASCRIPT_JSON_SERIALIZATION_TYPE;
310  }
311  };
312 
313  template<>
314  struct HAZELCAST_API hz_serializer<std::vector<byte>> : public builtin_serializer {
315  public:
316  static inline pimpl::serialization_constants get_type_id() {
317  return pimpl::serialization_constants::CONSTANT_TYPE_BYTE_ARRAY;
318  }
319  };
320 
321  template<>
322  struct HAZELCAST_API hz_serializer<std::vector<bool>> : public builtin_serializer {
323  public:
324  static inline pimpl::serialization_constants get_type_id() {
325  return pimpl::serialization_constants::CONSTANT_TYPE_BOOLEAN_ARRAY;
326  }
327  };
328 
329  template<>
330  struct HAZELCAST_API hz_serializer<std::vector<char>> : public builtin_serializer {
331  public:
332  static inline pimpl::serialization_constants get_type_id() {
333  return pimpl::serialization_constants::CONSTANT_TYPE_CHAR_ARRAY;
334  }
335  };
336 
337  template<>
338  struct HAZELCAST_API hz_serializer<std::vector<int16_t>> : public builtin_serializer {
339  public:
340  static inline pimpl::serialization_constants get_type_id() {
341  return pimpl::serialization_constants::CONSTANT_TYPE_SHORT_ARRAY;
342  }
343  };
344 
345  template<>
346  struct HAZELCAST_API hz_serializer<std::vector<int32_t>> : public builtin_serializer {
347  public:
348  static inline pimpl::serialization_constants get_type_id() {
349  return pimpl::serialization_constants::CONSTANT_TYPE_INTEGER_ARRAY;
350  }
351  };
352 
353  template<>
354  struct HAZELCAST_API hz_serializer<std::vector<int64_t>> : public builtin_serializer {
355  public:
356  static inline pimpl::serialization_constants get_type_id() {
357  return pimpl::serialization_constants::CONSTANT_TYPE_LONG_ARRAY;
358  }
359  };
360 
361  template<>
362  struct HAZELCAST_API hz_serializer<std::vector<float>> : public builtin_serializer {
363  public:
364  static inline pimpl::serialization_constants get_type_id() {
365  return pimpl::serialization_constants::CONSTANT_TYPE_FLOAT_ARRAY;
366  }
367  };
368 
369  template<>
370  struct HAZELCAST_API hz_serializer<std::vector<double>> : public builtin_serializer {
371  public:
372  static inline pimpl::serialization_constants get_type_id() {
373  return pimpl::serialization_constants::CONSTANT_TYPE_DOUBLE_ARRAY;
374  }
375  };
376 
377  template<>
378  struct HAZELCAST_API hz_serializer<std::vector<std::string>> : public builtin_serializer {
379  public:
380  static inline pimpl::serialization_constants get_type_id() {
381  return pimpl::serialization_constants::CONSTANT_TYPE_STRING_ARRAY;
382  }
383  };
384 
385  template<>
386  struct HAZELCAST_API hz_serializer<boost::uuids::uuid> : public builtin_serializer {
387  public:
388  static inline pimpl::serialization_constants get_type_id() {
389  return pimpl::serialization_constants::CONSTANT_TYPE_UUID;
390  }
391  };
392 
393  enum struct field_type {
394  TYPE_PORTABLE = 0,
395  TYPE_BYTE = 1,
396  TYPE_BOOLEAN = 2,
397  TYPE_CHAR = 3,
398  TYPE_SHORT = 4,
399  TYPE_INT = 5,
400  TYPE_LONG = 6,
401  TYPE_FLOAT = 7,
402  TYPE_DOUBLE = 8,
403  TYPE_STRING = 9,
404  TYPE_PORTABLE_ARRAY = 10,
405  TYPE_BYTE_ARRAY = 11,
406  TYPE_BOOLEAN_ARRAY = 12,
407  TYPE_CHAR_ARRAY = 13,
408  TYPE_SHORT_ARRAY = 14,
409  TYPE_INT_ARRAY = 15,
410  TYPE_LONG_ARRAY = 16,
411  TYPE_FLOAT_ARRAY = 17,
412  TYPE_DOUBLE_ARRAY = 18,
413  TYPE_STRING_ARRAY = 19
414  };
415 
426  class HAZELCAST_API FieldDefinition {
427  public:
428 
432  FieldDefinition();
433 
437  FieldDefinition(int, const std::string &, field_type const &type, int version);
438 
442  FieldDefinition(int index, const std::string &field_name, field_type const &type, int factory_id,
443  int class_id, int version);
444 
448  const field_type &get_type() const;
449 
453  std::string get_name() const;
454 
458  int get_index() const;
459 
463  int get_factory_id() const;
464 
468  int get_class_id() const;
469 
473  void write_data(pimpl::data_output &data_output);
474 
478  void read_data(object_data_input &data_input);
479 
480  bool operator==(const FieldDefinition &rhs) const;
481 
482  bool operator!=(const FieldDefinition &rhs) const;
483 
484  friend std::ostream &operator<<(std::ostream &os, const FieldDefinition &definition);
485 
486  private:
487  int index_;
488  std::string field_name_;
489  field_type type_;
490  int class_id_;
491  int factory_id_;
492  int version_;
493  };
494 
495  class HAZELCAST_API ClassDefinition {
496  public:
497 
501  ClassDefinition();
502 
509  ClassDefinition(int factory_id, int class_id, int version);
510 
515  void add_field_def(FieldDefinition &field_definition);
516 
521  bool has_field(const std::string &field_name) const;
522 
528  const FieldDefinition &get_field(const std::string &field_name) const;
529 
535  field_type get_field_type(const std::string &field_name) const;
536 
540  int get_field_count() const;
541 
545  int get_factory_id() const;
546 
550  int get_class_id() const;
551 
555  int get_version() const;
556 
561  void set_version_if_not_set(int new_version);
562 
567  void write_data(pimpl::data_output &data_output);
568 
573  void read_data(object_data_input &data_input);
574 
575  bool operator==(const ClassDefinition &rhs) const;
576 
577  bool operator!=(const ClassDefinition &rhs) const;
578 
579  friend std::ostream &operator<<(std::ostream &os, const ClassDefinition &definition);
580 
581  private:
582  int factory_id_;
583  int class_id_;
584  int version_;
585 
586  ClassDefinition(const ClassDefinition &) = delete;
587 
588  ClassDefinition &operator=(const ClassDefinition &rhs) = delete;
589 
590  std::unordered_map<std::string, FieldDefinition> field_definitions_map_;
591 
592  std::unique_ptr<std::vector<byte> > binary_;
593 
594  };
595 
602  class HAZELCAST_API ClassDefinitionBuilder {
603  public:
604  ClassDefinitionBuilder(int factory_id, int class_id, int version);
605 
607  add_portable_field(const std::string &field_name, std::shared_ptr<ClassDefinition> def);
608 
610  add_portable_array_field(const std::string &field_name, std::shared_ptr<ClassDefinition> def);
611 
612  ClassDefinitionBuilder &add_field(FieldDefinition &field_definition);
613 
614  void add_field(const std::string &field_name, field_type const &field_type);
615 
616  std::shared_ptr<ClassDefinition> build();
617 
618  int get_factory_id();
619 
620  int get_class_id();
621 
622  int get_version();
623  private:
624  int factory_id_;
625  int class_id_;
626  int version_;
627  int index_;
628  bool done_;
629 
630  std::vector<FieldDefinition> field_definitions_;
631 
632  void check();
633  };
634 
636  public:
637  template<typename T>
638  static inline typename std::enable_if<std::is_base_of<versioned_portable_serializer, hz_serializer<T>>::value, int>::type
639  get_version(int) {
641  }
642 
643  template<typename T>
644  static inline typename std::enable_if<!std::is_base_of<versioned_portable_serializer, hz_serializer<T>>::value, int>::type
645  get_version(int default_version) {
646  return default_version;
647  }
648  };
649 
650  class HAZELCAST_API object_data_input : public pimpl::data_input<std::vector<byte>> {
651  public:
655  object_data_input(boost::endian::order byte_order, const std::vector<byte> &buffer, int offset,
656  pimpl::PortableSerializer &portable_ser, pimpl::DataSerializer &data_ser,
657  std::shared_ptr<serialization::global_serializer> global_serializer);
658 
663  template<typename T>
664  typename std::enable_if<!(std::is_array<T>::value &&
665  std::is_same<typename std::remove_all_extents<T>::type, char>::value), boost::optional<T>>::type
666  inline read_object();
667 
668  template<typename T>
669  typename std::enable_if<std::is_array<T>::value &&
670  std::is_same<typename std::remove_all_extents<T>::type, char>::value, boost::optional<std::string>>::type
671  inline read_object();
672 
673  template<typename T>
674  typename std::enable_if<std::is_base_of<identified_data_serializer, hz_serializer<T>>::value, boost::optional<T>>::type
675  inline read_object(int32_t type_id);
676 
677  template<typename T>
678  typename std::enable_if<std::is_base_of<portable_serializer, hz_serializer<T>>::value, boost::optional<T>>::type
679  inline read_object(int32_t type_id);
680 
681  template<typename T>
682  typename std::enable_if<std::is_base_of<builtin_serializer, hz_serializer<T>>::value, boost::optional<T>>::type
683  inline read_object(int32_t type_id);
684 
685  template<typename T>
686  typename std::enable_if<std::is_base_of<custom_serializer, hz_serializer<T>>::value, boost::optional<T>>::type
687  inline read_object(int32_t type_id);
688 
695  template<typename T>
696  typename std::enable_if<!(std::is_base_of<identified_data_serializer, hz_serializer<T>>::value ||
697  std::is_base_of<portable_serializer, hz_serializer<T>>::value ||
698  std::is_base_of<builtin_serializer, hz_serializer<T>>::value ||
699  std::is_base_of<custom_serializer, hz_serializer<T>>::value), boost::optional<T>>::type
700  inline read_object(int32_t type_id);
701 
702  private:
703  pimpl::PortableSerializer &portable_serializer_;
704  pimpl::DataSerializer &data_serializer_;
705  std::shared_ptr<serialization::global_serializer> global_serializer_;
706  };
707 
708  class HAZELCAST_API object_data_output : public pimpl::data_output {
709  friend pimpl::DefaultPortableWriter;
710  public:
714  explicit object_data_output(boost::endian::order byte_order, bool dont_write = false,
715  pimpl::PortableSerializer *portable_ser = nullptr,
716  std::shared_ptr<serialization::global_serializer> global_serializer = nullptr);
717 
718  template<typename T>
719  void write_object(const T *object);
720 
721  /* enable_if needed here since 'boost::optional<char [5]>' can not be composed this template match */
722  template<typename T>
723  typename std::enable_if<!(std::is_array<T>::value && std::is_same<typename std::remove_all_extents<T>::type, char>::value), void>::type
724  write_object(const boost::optional<T> &object);
725 
726  template<typename T>
727  typename std::enable_if<std::is_array<T>::value && std::is_same<typename std::remove_all_extents<T>::type, char>::value, void>::type
728  inline write_object(const T &object);
729 
730  template<typename T>
731  typename std::enable_if<std::is_base_of<builtin_serializer, hz_serializer<T>>::value, void>::type
732  inline write_object(const T &object);
733 
734  template<typename T>
735  typename std::enable_if<std::is_base_of<identified_data_serializer, hz_serializer<T>>::value, void>::type
736  inline write_object(const T &object);
737 
738  template<typename T>
739  typename std::enable_if<std::is_base_of<portable_serializer, hz_serializer<T>>::value, void>::type
740  inline write_object(const T &object);
741 
742  template<typename T>
743  typename std::enable_if<std::is_base_of<custom_serializer, hz_serializer<T>>::value, void>::type
744  inline write_object(const T &object);
745 
746  template<typename T>
747  typename std::enable_if<!(std::is_base_of<builtin_serializer, hz_serializer<T>>::value ||
748  std::is_base_of<identified_data_serializer, hz_serializer<T>>::value ||
749  std::is_base_of<portable_serializer, hz_serializer<T>>::value ||
750  std::is_base_of<custom_serializer, hz_serializer<T>>::value ||
751  (std::is_array<T>::value &&
752  std::is_same<typename std::remove_all_extents<T>::type, char>::value)), void>::type
753  inline write_object(const T object);
754 
755  void write_objects() {}
756 
757  template<typename FirstObjectType, typename ...OtherObjects>
758  inline void write_objects(const FirstObjectType &object, const OtherObjects &...objects) {
759  write_object(object);
760  write_objects(objects...);
761  }
762 
763  template<typename T>
764  inline void write_bytes(const T &s) {
765  for (auto c : s) {
766  output_stream_.push_back(c);
767  }
768  }
769 
770  private:
771  pimpl::PortableSerializer *portable_serializer_;
772  std::shared_ptr<serialization::global_serializer> global_serializer_;
773  };
774 
775  template<>
776  void HAZELCAST_API object_data_output::write_object(const char *object);
777 
778  namespace pimpl {
779  class HAZELCAST_API PortableContext {
780  public:
781  PortableContext(const serialization_config &serialization_conf);
782 
783  int get_class_version(int factory_id, int class_id);
784 
785  void set_class_version(int factory_id, int class_id, int version);
786 
787  std::shared_ptr<ClassDefinition> lookup_class_definition(int factory_id, int class_id, int version);
788 
789  std::shared_ptr<ClassDefinition> register_class_definition(std::shared_ptr<ClassDefinition>);
790 
791  template<typename T>
792  std::shared_ptr<ClassDefinition> lookup_or_register_class_definition(const T &portable);
793 
794  int get_version();
795 
796  std::shared_ptr<ClassDefinition> read_class_definition(object_data_input &input, int id, int class_id,
797  int version);
798 
799  const serialization_config &get_serialization_config() const;
800 
801  template<typename T>
802  typename std::enable_if<std::is_same<byte, typename std::remove_cv<T>::type>::value, field_type>::type
803  static get_type() { return field_type::TYPE_BYTE; }
804 
805  template<typename T>
806  typename std::enable_if<std::is_same<char, typename std::remove_cv<T>::type>::value, field_type>::type
807  static get_type() { return field_type::TYPE_CHAR; }
808 
809 
810  template<typename T>
811  typename std::enable_if<std::is_same<char16_t, typename std::remove_cv<T>::type>::value, field_type>::type
812  static get_type() { return field_type::TYPE_CHAR; }
813 
814  template<typename T>
815  typename std::enable_if<std::is_same<bool, typename std::remove_cv<T>::type>::value, field_type>::type
816  static get_type() { return field_type::TYPE_BOOLEAN; }
817 
818  template<typename T>
819  typename std::enable_if<std::is_same<int16_t, typename std::remove_cv<T>::type>::value, field_type>::type
820  static get_type() { return field_type::TYPE_SHORT; }
821 
822  template<typename T>
823  typename std::enable_if<std::is_same<int32_t, typename std::remove_cv<T>::type>::value, field_type>::type
824  static get_type() { return field_type::TYPE_INT; }
825 
826  template<typename T>
827  typename std::enable_if<std::is_same<int64_t, typename std::remove_cv<T>::type>::value, field_type>::type
828  static get_type() { return field_type::TYPE_LONG; }
829 
830  template<typename T>
831  typename std::enable_if<std::is_same<float, typename std::remove_cv<T>::type>::value, field_type>::type
832  static get_type() { return field_type::TYPE_FLOAT; }
833 
834  template<typename T>
835  typename std::enable_if<std::is_same<double, typename std::remove_cv<T>::type>::value, field_type>::type
836  static get_type() { return field_type::TYPE_DOUBLE; }
837 
838  template<typename T>
839  typename std::enable_if<std::is_same<std::string, typename std::remove_cv<T>::type>::value, field_type>::type
840  static get_type() { return field_type::TYPE_STRING; }
841 
842 
843  template<typename T>
844  typename std::enable_if<std::is_same<std::vector<byte>, typename std::remove_cv<T>::type>::value, field_type>::type
845  static get_type() { return field_type::TYPE_BYTE_ARRAY; }
846 
847  template<typename T>
848  typename std::enable_if<std::is_same<std::vector<char>, typename std::remove_cv<T>::type>::value, field_type>::type
849  static get_type() { return field_type::TYPE_CHAR_ARRAY; }
850 
851  template<typename T>
852  typename std::enable_if<std::is_same<std::vector<bool>, typename std::remove_cv<T>::type>::value, field_type>::type
853  static get_type() { return field_type::TYPE_BOOLEAN_ARRAY; }
854 
855  template<typename T>
856  typename std::enable_if<std::is_same<std::vector<int16_t>, typename std::remove_cv<T>::type>::value, field_type>::type
857  static get_type() { return field_type::TYPE_SHORT_ARRAY; }
858 
859  template<typename T>
860  typename std::enable_if<std::is_same<std::vector<int32_t>, typename std::remove_cv<T>::type>::value, field_type>::type
861  static get_type() { return field_type::TYPE_INT_ARRAY; }
862 
863  template<typename T>
864  typename std::enable_if<std::is_same<std::vector<int64_t>, typename std::remove_cv<T>::type>::value, field_type>::type
865  static get_type() { return field_type::TYPE_LONG_ARRAY; }
866 
867  template<typename T>
868  typename std::enable_if<std::is_same<std::vector<float>, typename std::remove_cv<T>::type>::value, field_type>::type
869  static get_type() { return field_type::TYPE_FLOAT_ARRAY; }
870 
871  template<typename T>
872  typename std::enable_if<std::is_same<std::vector<double>, typename std::remove_cv<T>::type>::value, field_type>::type
873  static get_type() { return field_type::TYPE_DOUBLE_ARRAY; }
874 
875  template<typename T>
876  typename std::enable_if<std::is_same<std::vector<std::string>, typename std::remove_cv<T>::type>::value, field_type>::type
877  static get_type() { return field_type::TYPE_STRING_ARRAY; }
878 
879  private:
880  PortableContext(const PortableContext &) = delete;
881 
882  ClassDefinitionContext &get_class_definition_context(int factory_id);
883 
884  void operator=(const PortableContext &) = delete;
885 
886  util::SynchronizedMap<int, ClassDefinitionContext> class_def_context_map_;
887  const serialization_config &serialization_config_;
888  };
889 
890  class ClassDefinitionContext {
891  public:
892 
893  ClassDefinitionContext(int portable_context, PortableContext *p_context);
894 
895  int get_class_version(int class_id);
896 
897  void set_class_version(int class_id, int version);
898 
899  std::shared_ptr<ClassDefinition> lookup(int, int);
900 
901  std::shared_ptr<ClassDefinition> register_class_definition(std::shared_ptr<ClassDefinition>);
902 
903  private:
904  int64_t combine_to_long(int x, int y) const;
905 
906  const int factory_id_;
907  util::SynchronizedMap<long long, ClassDefinition> versioned_definitions_;
908  util::SynchronizedMap<int, int> current_class_versions_;
909  PortableContext *portable_context_;
910  };
911 
912  class HAZELCAST_API ClassDefinitionWriter {
913  public:
914  ClassDefinitionWriter(PortableContext &portable_context, ClassDefinitionBuilder &builder);
915 
916  template <typename T>
917  void write(const std::string &field_name, T value) {
918  typedef typename std::remove_pointer<typename std::remove_reference<typename std::remove_cv<T>::type>::type>::type value_type;
919  builder_.add_field(field_name, PortableContext::get_type<value_type>());
920  }
921 
922  template<typename T>
923  void write_null_portable(const std::string &field_name) {
924  T portable;
925  int32_t factoryId = hz_serializer<T>::getFactoryId();
926  int32_t classId = hz_serializer<T>::getClassId();
927  std::shared_ptr<ClassDefinition> nestedClassDef = context_.lookup_class_definition(factoryId,
928  classId,
929  context_.get_version());
930  if (!nestedClassDef) {
931  BOOST_THROW_EXCEPTION(
932  exception::hazelcast_serialization("ClassDefWriter::write_null_portable",
933  "Cannot write null portable without explicitly registering class definition!"));
934  }
935  builder_.add_portable_field(field_name, nestedClassDef);
936  }
937 
938  template<typename T>
939  void write_portable(const std::string &field_name, const T *portable) {
940  if (NULL == portable) {
941  BOOST_THROW_EXCEPTION(
942  exception::hazelcast_serialization("ClassDefinitionWriter::write_portable",
943  "Cannot write null portable without explicitly registering class definition!"));
944  }
945 
946  std::shared_ptr<ClassDefinition> nestedClassDef = create_nested_class_def(*portable);
947  builder_.add_portable_field(field_name, nestedClassDef);
948  };
949 
950  template<typename T>
951  void write_portable_array(const std::string &field_name, const std::vector<T> *portables) {
952  if (NULL == portables || portables->size() == 0) {
953  BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
954  "ClassDefinitionWriter::write_portableArray",
955  "Cannot write null portable array without explicitly registering class definition!"));
956  }
957  std::shared_ptr<ClassDefinition> nestedClassDef = create_nested_class_def((*portables)[0]);
958  builder_.add_portable_array_field(field_name, nestedClassDef);
959  };
960 
961  std::shared_ptr<ClassDefinition> register_and_get();
962 
963  object_data_output &get_raw_data_output();
964 
965  void end();
966 
967  private:
968  template<typename T>
969  std::shared_ptr<ClassDefinition> create_nested_class_def(const T &portable);
970 
971  ClassDefinitionBuilder &builder_;
972  PortableContext &context_;
973  object_data_output empty_data_output_;
974  };
975 
976  class HAZELCAST_API PortableReaderBase {
977  public:
978  PortableReaderBase(PortableSerializer &portable_ser,
979  object_data_input &input,
980  std::shared_ptr<ClassDefinition> cd);
981 
982  template <typename T>
983  typename std::enable_if<std::is_same<byte, typename std::remove_cv<T>::type>::value ||
984  std::is_same<char, typename std::remove_cv<T>::type>::value ||
985  std::is_same<char16_t, typename std::remove_cv<T>::type>::value ||
986  std::is_same<bool, typename std::remove_cv<T>::type>::value ||
987  std::is_same<int16_t, typename std::remove_cv<T>::type>::value ||
988  std::is_same<int32_t, typename std::remove_cv<T>::type>::value ||
989  std::is_same<int64_t, typename std::remove_cv<T>::type>::value ||
990  std::is_same<float, typename std::remove_cv<T>::type>::value ||
991  std::is_same<double, typename std::remove_cv<T>::type>::value ||
992  std::is_same<std::string, typename std::remove_cv<T>::type>::value, T>::type
993  read(const std::string &field_name) {
994  set_position(field_name, PortableContext::get_type<T>());
995  return data_input_->read<T>();
996  }
997 
998  template <typename T>
999  typename std::enable_if<std::is_same<boost::optional<std::string>, typename std::remove_cv<T>::type>::value, T>::type
1000  read(const std::string &field_name) {
1001  set_position(field_name, PortableContext::get_type<T>());
1002  return data_input_->read<T>();
1003  }
1004 
1005  template <typename T>
1006  typename std::enable_if<std::is_same<std::vector<byte>, typename std::remove_cv<T>::type>::value ||
1007  std::is_same<std::vector<char>, typename std::remove_cv<T>::type>::value ||
1008  std::is_same<std::vector<bool>, typename std::remove_cv<T>::type>::value ||
1009  std::is_same<std::vector<int16_t>, typename std::remove_cv<T>::type>::value ||
1010  std::is_same<std::vector<int32_t>, typename std::remove_cv<T>::type>::value ||
1011  std::is_same<std::vector<int64_t>, typename std::remove_cv<T>::type>::value ||
1012  std::is_same<std::vector<float>, typename std::remove_cv<T>::type>::value ||
1013  std::is_same<std::vector<double>, typename std::remove_cv<T>::type>::value ||
1014  std::is_same<std::vector<std::string>, typename std::remove_cv<T>::type>::value, boost::optional<T>>::type
1015  read(const std::string &field_name) {
1016  set_position(field_name, PortableContext::get_type<T>());
1017  return data_input_->read<T>();
1018  }
1019 
1020  object_data_input &get_raw_data_input();
1021 
1022  void end();
1023 
1024  protected:
1025  void set_position(const std::string &field_name, field_type const &field_type);
1026 
1027  void check_factory_and_class(FieldDefinition fd, int factory_id, int class_id) const;
1028 
1029  template<typename T>
1030  boost::optional<T> get_portable_instance(const std::string &field_name);
1031 
1032  std::shared_ptr<ClassDefinition> cd_;
1033  object_data_input *data_input_;
1034  PortableSerializer *portable_serializer_;
1035  private:
1036  int final_position_;
1037  int offset_;
1038  bool raw_;
1039 
1040  };
1041 
1042  class HAZELCAST_API DefaultPortableReader : public PortableReaderBase {
1043  public:
1044  DefaultPortableReader(PortableSerializer &portable_ser,
1045  object_data_input &input, std::shared_ptr<ClassDefinition> cd);
1046 
1047  template<typename T>
1048  boost::optional<T> read_portable(const std::string &field_name);
1049 
1050  template<typename T>
1051  boost::optional<std::vector<T>> read_portable_array(const std::string &field_name);
1052  };
1053 
1054  class HAZELCAST_API MorphingPortableReader : public PortableReaderBase {
1055  public:
1056  MorphingPortableReader(PortableSerializer &portable_ser, object_data_input &input,
1057  std::shared_ptr<ClassDefinition> cd);
1058 
1059  template <typename T>
1060  typename std::enable_if<std::is_same<int16_t, typename std::remove_cv<T>::type>::value ||
1061  std::is_same<int32_t, typename std::remove_cv<T>::type>::value ||
1062  std::is_same<int64_t, typename std::remove_cv<T>::type>::value ||
1063  std::is_same<float, typename std::remove_cv<T>::type>::value ||
1064  std::is_same<double, typename std::remove_cv<T>::type>::value, T>::type
1065  read(const std::string &field_name) {
1066  if (!cd_->has_field(field_name)) {
1067  return 0;
1068  }
1069  const field_type &currentFieldType = cd_->get_field_type(field_name);
1070  return read_morphing<T>(currentFieldType, field_name);
1071  }
1072 
1073  template <typename T>
1074  typename std::enable_if<std::is_same<byte, typename std::remove_cv<T>::type>::value ||
1075  std::is_same<char, typename std::remove_cv<T>::type>::value ||
1076  std::is_same<char16_t, typename std::remove_cv<T>::type>::value ||
1077  std::is_same<bool, typename std::remove_cv<T>::type>::value, T>::type
1078  read(const std::string &field_name) {
1079  if (!cd_->has_field(field_name)) {
1080  return 0;
1081  }
1082  return PortableReaderBase::read<T>(field_name);
1083  }
1084 
1085  template <typename T>
1086  typename std::enable_if<std::is_same<std::string, typename std::remove_cv<T>::type>::value, T>::type
1087  read(const std::string &field_name) {
1088  if (!cd_->has_field(field_name)) {
1089  return std::string();
1090  }
1091  return PortableReaderBase::read<T>(field_name);
1092  }
1093 
1094  template <typename T>
1095  typename std::enable_if<std::is_same<boost::optional<std::string>, typename std::remove_cv<T>::type>::value, T>::type
1096  read(const std::string &field_name) {
1097  if (!cd_->has_field(field_name)) {
1098  return boost::none;
1099  }
1100  return PortableReaderBase::read<T>(field_name);
1101  }
1102 
1103  template <typename T>
1104  typename std::enable_if<std::is_same<std::vector<byte>, typename std::remove_cv<T>::type>::value ||
1105  std::is_same<std::vector<char>, typename std::remove_cv<T>::type>::value ||
1106  std::is_same<std::vector<bool>, typename std::remove_cv<T>::type>::value ||
1107  std::is_same<std::vector<int16_t>, typename std::remove_cv<T>::type>::value ||
1108  std::is_same<std::vector<int32_t>, typename std::remove_cv<T>::type>::value ||
1109  std::is_same<std::vector<int64_t>, typename std::remove_cv<T>::type>::value ||
1110  std::is_same<std::vector<float>, typename std::remove_cv<T>::type>::value ||
1111  std::is_same<std::vector<double>, typename std::remove_cv<T>::type>::value ||
1112  std::is_same<std::vector<std::string>, typename std::remove_cv<T>::type>::value, boost::optional<T>>::type
1113  read(const std::string &field_name) {
1114  if (!cd_->has_field(field_name)) {
1115  return boost::none;
1116  }
1117  return PortableReaderBase::read<T>(field_name);
1118  }
1119 
1120  template<typename T>
1121  boost::optional<T> read_portable(const std::string &field_name);
1122 
1123  template<typename T>
1124  boost::optional<std::vector<T>> read_portable_array(const std::string &field_name);
1125 
1126  private:
1127  template <typename T>
1128  typename std::enable_if<std::is_same<int16_t, typename std::remove_cv<T>::type>::value, T>::type
1129  read_morphing(field_type current_field_type, const std::string &field_name) {
1130  switch(current_field_type) {
1131  case field_type::TYPE_BYTE:
1132  return PortableReaderBase::read<byte>(field_name);
1133  case field_type::TYPE_SHORT:
1134  return PortableReaderBase::read<int16_t>(field_name);
1135  default:
1136  BOOST_THROW_EXCEPTION(exception::hazelcast_serialization("MorphingPortableReader::*",
1137  "IncompatibleClassChangeError"));
1138  }
1139  }
1140 
1141  template <typename T>
1142  typename std::enable_if<std::is_same<int32_t, typename std::remove_cv<T>::type>::value, T>::type
1143  read_morphing(field_type current_field_type, const std::string &field_name) {
1144  switch(current_field_type) {
1145  case field_type::TYPE_INT:
1146  return PortableReaderBase::read<int32_t>(field_name);
1147  case field_type::TYPE_CHAR:
1148  return PortableReaderBase::read<char>(field_name);
1149  default:
1150  return read_morphing<int16_t>(current_field_type, field_name);
1151  }
1152  }
1153 
1154  template <typename T>
1155  typename std::enable_if<std::is_same<int64_t, typename std::remove_cv<T>::type>::value, T>::type
1156  read_morphing(field_type current_field_type, const std::string &field_name) {
1157  switch(current_field_type) {
1158  case field_type::TYPE_LONG:
1159  return PortableReaderBase::read<int64_t>(field_name);
1160  default:
1161  return read_morphing<int32_t>(current_field_type, field_name);
1162  }
1163  }
1164 
1165  template <typename T>
1166  typename std::enable_if<std::is_same<float, typename std::remove_cv<T>::type>::value, T>::type
1167  read_morphing(field_type current_field_type, const std::string &field_name) {
1168  switch(current_field_type) {
1169  case field_type::TYPE_FLOAT:
1170  return PortableReaderBase::read<float>(field_name);
1171  default:
1172  return static_cast<float>(read_morphing<int32_t>(current_field_type, field_name));
1173  }
1174  }
1175 
1176  template <typename T>
1177  typename std::enable_if<std::is_same<double, typename std::remove_cv<T>::type>::value, T>::type
1178  read_morphing(field_type current_field_type, const std::string &field_name) {
1179  switch(current_field_type) {
1180  case field_type::TYPE_DOUBLE:
1181  return PortableReaderBase::read<double>(field_name);
1182  case field_type::TYPE_FLOAT:
1183  return PortableReaderBase::read<float>(field_name);
1184  default:
1185  return static_cast<double>(read_morphing<int64_t>(current_field_type, field_name));
1186  }
1187  }
1188  };
1189 
1190  class DefaultPortableWriter;
1191  class HAZELCAST_API PortableSerializer {
1192  friend DefaultPortableWriter;
1193  public:
1194  PortableSerializer(PortableContext &portable_context);
1195 
1196  template<typename T>
1197  T read_object(object_data_input &in);
1198 
1199  template<typename T>
1200  T read(object_data_input &in, int32_t factory_id, int32_t class_id);
1201 
1202  template<typename T>
1203  void write(const T &object, object_data_output &out);
1204 
1205  private:
1206  PortableContext &context_;
1207 
1208  template<typename T>
1209  int find_portable_version(int factory_id, int class_id) const;
1210 
1211  portable_reader create_reader(object_data_input &input, int factory_id, int class_id, int version,
1212  int portable_version);
1213 
1214  int32_t read_int(object_data_input &in) const;
1215 
1216  template<typename T>
1217  void write_internal(const T &object, object_data_output &out);
1218 
1219  template<typename T>
1220  void write_internal(const T &object, std::shared_ptr<ClassDefinition> &cd, object_data_output &out);
1221 
1222  template<typename T>
1223  std::shared_ptr<ClassDefinition> lookup_or_register_class_definition(const T &portable);
1224  };
1225 
1226  class HAZELCAST_API DataSerializer {
1227  public:
1228  template<typename T>
1229  static boost::optional<T> read_object(object_data_input &in) {
1230  bool identified = in.read<bool>();
1231  if (!identified) {
1232  BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
1233  "object_data_input::read_object<identified_data_serializer>",
1234  "Received data is not identified data serialized."));
1235  }
1236 
1237  int32_t expectedFactoryId = hz_serializer<T>::get_factory_id();
1238  int32_t expectedClassId = hz_serializer<T>::get_class_id();
1239  int32_t factoryId = in.read<int32_t>();
1240  int32_t classId = in.read<int32_t>();
1241  if (expectedFactoryId != factoryId || expectedClassId != classId) {
1242  BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
1243  "object_data_input::read_object<identified_data_serializer>",
1244  (boost::format(
1245  "Factory id %1% and class id %2% of data do not match expected "
1246  "factory id %3% and class id %4%!") %
1247  factoryId % classId % expectedFactoryId %
1248  expectedClassId).str())
1249  );
1250  }
1251 
1252  return boost::make_optional(hz_serializer<T>::read_data(in));
1253  }
1254 
1255  template<typename T>
1256  static void write(const T &object, object_data_output &out);
1257 
1258  private:
1259  int32_t read_int(object_data_input &in) const;
1260  };
1261 
1262  class HAZELCAST_API DefaultPortableWriter {
1263  public:
1264  DefaultPortableWriter(PortableSerializer &portable_ser, std::shared_ptr<ClassDefinition> cd,
1265  object_data_output &output);
1266 
1267  object_data_output &get_raw_data_output();
1268 
1269  template <typename T>
1270  void write(const std::string &field_name, T value) {
1271  typedef typename std::remove_pointer<typename std::remove_reference<typename std::remove_cv<T>::type>::type>::type value_type;
1272  set_position(field_name, PortableContext::get_type<value_type>());
1273  object_data_output_.write(value);
1274  }
1275 
1276  void end();
1277 
1278  template<typename T>
1279  void write_null_portable(const std::string &field_name);
1280 
1281  template<typename T>
1282  void write_portable(const std::string &field_name, const T *portable);
1283 
1284  template<typename T>
1285  void write_portable_array(const std::string &field_name, const std::vector<T> *values);
1286 
1287  private:
1288  FieldDefinition const &set_position(const std::string &field_name, field_type field_type);
1289 
1290  template<typename T>
1291  void check_portable_attributes(const FieldDefinition &fd);
1292 
1293  bool raw_;
1294  PortableSerializer &portable_serializer_;
1295  object_data_output &object_data_output_;
1296  size_t begin_;
1297  size_t offset_;
1298  std::unordered_set<std::string> written_fields_;
1299  std::shared_ptr<ClassDefinition> cd_;
1300  };
1301 
1302  class HAZELCAST_API SerializationService : public util::Disposable {
1303  public:
1304  SerializationService(const serialization_config &config);
1305 
1306  PortableSerializer &get_portable_serializer();
1307 
1308  DataSerializer &get_data_serializer();
1309 
1310  template<typename T>
1311  inline data to_data(const T *object) {
1312  object_data_output output(serialization_config_.get_byte_order(), false, &portable_serializer_, serialization_config_.get_global_serializer());
1313 
1314  write_hash<T>(object, output);
1315 
1316  output.write_object<T>(object);
1317 
1318  return {std::move(output).to_byte_array()};
1319  }
1320 
1321  template<typename T>
1322  inline data to_data(const T &object) {
1323  object_data_output output(serialization_config_.get_byte_order(), false, &portable_serializer_, serialization_config_.get_global_serializer());
1324 
1325  write_hash<T>(&object, output);
1326 
1327  output.write_object<T>(object);
1328 
1329  return {std::move(output).to_byte_array()};
1330  }
1331 
1332  template<typename T>
1333  inline std::shared_ptr<data> to_shared_data(const T *object) {
1334  if (NULL == object) {
1335  return std::shared_ptr<data>();
1336  }
1337  return std::shared_ptr<data>(new data(to_data<T>(object)));
1338  }
1339 
1340  template<typename T>
1341  inline boost::optional<T> to_object(const data *data) {
1342  if (!data) {
1343  return boost::none;
1344  }
1345  return to_object<T>(*data);
1346  }
1347 
1348  template<typename T>
1349  typename std::enable_if<!(std::is_same<T, const char *>::value ||
1350  std::is_same<T, const char *>::value ||
1351  std::is_same<T, typed_data>::value), boost::optional<T>>::type
1352  inline to_object(const data &data) {
1353  if (is_null_data(data)) {
1354  return boost::none;
1355  }
1356 
1357  int32_t typeId = data.get_type();
1358 
1359  // Constant 8 is Data::DATA_OFFSET. Windows DLL export does not
1360  // let usage of static member.
1361  object_data_input objectDataInput(serialization_config_.get_byte_order(), data.to_byte_array(),
1362  8, portable_serializer_, data_serializer_,
1363  serialization_config_.get_global_serializer());
1364  return objectDataInput.read_object<T>(typeId);
1365  }
1366 
1367  template<typename T>
1368  typename std::enable_if<std::is_same<T, typed_data>::value, boost::optional<T>>::type
1369  inline to_object(const data &d) {
1370  return boost::make_optional(typed_data(data(d), *this));
1371  }
1372 
1373  template<typename T>
1374  typename std::enable_if<std::is_same<T, const char *>::value, boost::optional<std::string>>::type
1375  inline to_object(const data &data) {
1376  return to_object<std::string>(data);
1377  }
1378 
1379  template<typename T>
1380  typename std::enable_if<std::is_array<T>::value &&
1381  std::is_same<typename std::remove_all_extents<T>::type, char>::value, boost::optional<std::string>>::type
1382  inline to_object(const data &data) {
1383  return to_object<std::string>(data);
1384  }
1385 
1386  template<typename T>
1387  inline std::shared_ptr<data> to_shared_object(const std::shared_ptr<data> &data) {
1388  return data;
1389  }
1390 
1391  const byte get_version() const;
1392 
1393  object_type get_object_type(const data *data);
1394 
1398  void dispose() override;
1399 
1400  object_data_output new_output_stream();
1401  private:
1402  SerializationService(const SerializationService &) = delete;
1403 
1404  SerializationService &operator=(const SerializationService &) = delete;
1405 
1406  const serialization_config &serialization_config_;
1407  PortableContext portable_context_;
1408  serialization::pimpl::PortableSerializer portable_serializer_;
1409  serialization::pimpl::DataSerializer data_serializer_;
1410 
1411  static bool is_null_data(const data &data);
1412 
1413  template<typename T>
1414  void write_hash(const partition_aware_marker *obj, data_output &out) {
1415  typedef typename T::KEY_TYPE PK_TYPE;
1416  const partition_aware<PK_TYPE> *partitionAwareObj = static_cast<const partition_aware<PK_TYPE> *>(obj);
1417  const PK_TYPE *pk = partitionAwareObj->get_partition_key();
1418  if (pk != NULL) {
1419  data partitionKey = to_data<PK_TYPE>(pk);
1420  out.write<int32_t>(partitionKey.get_partition_hash());
1421  }
1422  }
1423 
1424  template<typename T>
1425  void write_hash(const void *obj, data_output &out) {
1426  out.write(0, boost::endian::order::big);
1427  }
1428  };
1429 
1430  template<>
1431  data HAZELCAST_API SerializationService::to_data(const char *object);
1432  }
1433 
1438  class HAZELCAST_API portable_reader {
1439  public:
1440  portable_reader(pimpl::PortableSerializer &portable_ser, object_data_input &data_input,
1441  const std::shared_ptr<ClassDefinition>& cd, bool is_default_reader);
1442 
1447  template <typename T>
1448  typename std::enable_if<std::is_same<int16_t, typename std::remove_cv<T>::type>::value ||
1449  std::is_same<int32_t, typename std::remove_cv<T>::type>::value ||
1450  std::is_same<int64_t, typename std::remove_cv<T>::type>::value ||
1451  std::is_same<float, typename std::remove_cv<T>::type>::value ||
1452  std::is_same<double, typename std::remove_cv<T>::type>::value ||
1453  std::is_same<byte, typename std::remove_cv<T>::type>::value ||
1454  std::is_same<char, typename std::remove_cv<T>::type>::value ||
1455  std::is_same<char16_t, typename std::remove_cv<T>::type>::value ||
1456  std::is_same<bool, typename std::remove_cv<T>::type>::value ||
1457  std::is_same<std::string, typename std::remove_cv<T>::type>::value, T>::type
1458  read(const std::string &field_name) {
1459  if (is_default_reader_)
1460  return default_portable_reader_->read<T>(field_name);
1461  return morphing_portable_reader_->read<T>(field_name);
1462  }
1463 
1468  template<typename T>
1469  typename std::enable_if<std::is_same<std::vector<byte>, typename std::remove_cv<T>::type>::value ||
1470  std::is_same<std::vector<char>, typename std::remove_cv<T>::type>::value ||
1471  std::is_same<std::vector<bool>, typename std::remove_cv<T>::type>::value ||
1472  std::is_same<std::vector<int16_t>, typename std::remove_cv<T>::type>::value ||
1473  std::is_same<std::vector<int32_t>, typename std::remove_cv<T>::type>::value ||
1474  std::is_same<std::vector<int64_t>, typename std::remove_cv<T>::type>::value ||
1475  std::is_same<std::vector<float>, typename std::remove_cv<T>::type>::value ||
1476  std::is_same<std::vector<double>, typename std::remove_cv<T>::type>::value ||
1477  std::is_same<std::vector<std::string>, typename std::remove_cv<T>::type>::value, boost::optional<T>>::type
1478  read(const std::string &field_name) {
1479  if (is_default_reader_)
1480  return default_portable_reader_->read<T>(field_name);
1481  return morphing_portable_reader_->read<T>(field_name);
1482  }
1483 
1489  template<typename T>
1490  boost::optional<T> read_portable(const std::string &field_name);
1491 
1497  template<typename T>
1498  boost::optional<std::vector<T>> read_portable_array(const std::string &field_name);
1499 
1509  object_data_input &get_raw_data_input();
1510 
1514  void end();
1515 
1516  private:
1517  bool is_default_reader_;
1518  boost::optional<pimpl::DefaultPortableReader> default_portable_reader_;
1519  boost::optional<pimpl::MorphingPortableReader> morphing_portable_reader_;
1520  };
1521 
1526  class HAZELCAST_API portable_writer {
1527  public:
1531  portable_writer(pimpl::DefaultPortableWriter *default_portable_writer);
1532 
1536  portable_writer(pimpl::ClassDefinitionWriter *class_definition_writer);
1537 
1538  template <typename T>
1539  void write(const std::string &field_name, T value) {
1540  if(is_default_writer_) {
1541  default_portable_writer_->write(field_name, value);
1542  } else {
1543  class_definition_writer_->write(field_name, value);
1544  }
1545  }
1546 
1550  void end();
1551 
1560  template<typename T>
1561  void write_null_portable(const std::string &field_name);
1562 
1569  template<typename T>
1570  void write_portable(const std::string &field_name, const T *portable);
1571 
1578  template<typename T>
1579  void write_portable_array(const std::string &field_name, const std::vector<T> *values);
1580 
1589  object_data_output &get_raw_data_output();
1590 
1591  private:
1592  pimpl::DefaultPortableWriter *default_portable_writer_;
1593  pimpl::ClassDefinitionWriter *class_definition_writer_;
1594  bool is_default_writer_;
1595  };
1596 
1597  template<typename T>
1598  boost::optional<T> portable_reader::read_portable(const std::string &field_name) {
1599  if (is_default_reader_)
1600  return default_portable_reader_->read_portable<T>(field_name);
1601  return morphing_portable_reader_->read_portable<T>(field_name);
1602  }
1603 
1610  template<typename T>
1611  boost::optional<std::vector<T>> portable_reader::read_portable_array(const std::string &field_name) {
1612  if (is_default_reader_)
1613  return default_portable_reader_->read_portable_array<T>(field_name);
1614  return morphing_portable_reader_->read_portable_array<T>(field_name);
1615  };
1616 
1617  template<typename T>
1618  void portable_writer::write_null_portable(const std::string &field_name) {
1619  if (is_default_writer_)
1620  return default_portable_writer_->write_null_portable<T>(field_name);
1621  return class_definition_writer_->write_null_portable<T>(field_name);
1622  }
1623 
1630  template<typename T>
1631  void portable_writer::write_portable(const std::string &field_name, const T *portable) {
1632  if (is_default_writer_)
1633  return default_portable_writer_->write_portable(field_name, portable);
1634  return class_definition_writer_->write_portable(field_name, portable);
1635 
1636  }
1637 
1644  template<typename T>
1645  void portable_writer::write_portable_array(const std::string &field_name, const std::vector<T> *values) {
1646  if (is_default_writer_)
1647  return default_portable_writer_->write_portable_array(field_name, values);
1648  return class_definition_writer_->write_portable_array(field_name, values);
1649  }
1650 
1651  template<typename T>
1652  void object_data_output::write_object(const T *object) {
1653  if (is_no_write_) { return; }
1654  if (!object) {
1655  write(static_cast<int32_t>(pimpl::serialization_constants::CONSTANT_TYPE_NULL),
1656  boost::endian::order::big);
1657  return;
1658  }
1659 
1660  write_object<T>(*object);
1661  }
1662 
1663  template<typename T>
1664  typename std::enable_if<!(std::is_array<T>::value && std::is_same<typename std::remove_all_extents<T>::type, char>::value), void>::type
1665  object_data_output::write_object(const boost::optional<T> &object) {
1666  if (is_no_write_) { return; }
1667  if (!object) {
1668  write(static_cast<int32_t>(pimpl::serialization_constants::CONSTANT_TYPE_NULL),
1669  boost::endian::order::big);
1670  return;
1671  }
1672 
1673  write_object<T>(object.value());
1674  }
1675 
1676  template<typename T>
1677  typename std::enable_if<std::is_base_of<identified_data_serializer, hz_serializer<T>>::value, void>::type
1678  inline object_data_output::write_object(const T &object) {
1679  if (is_no_write_) { return; }
1680  write(static_cast<int32_t>(pimpl::serialization_constants::CONSTANT_TYPE_DATA),
1681  boost::endian::order::big);
1682  pimpl::DataSerializer::write<T>(object, *this);
1683  }
1684 
1685  template<typename T>
1686  typename std::enable_if<std::is_base_of<portable_serializer, hz_serializer<T>>::value, void>::type
1687  inline object_data_output::write_object(const T &object) {
1688  if (is_no_write_) { return; }
1689  write(static_cast<int32_t>(pimpl::serialization_constants::CONSTANT_TYPE_PORTABLE),
1690  boost::endian::order::big);
1691  portable_serializer_->write<T>(object, *this);
1692  }
1693 
1694  template<typename T>
1695  typename std::enable_if<std::is_base_of<builtin_serializer, hz_serializer<T>>::value, void>::type
1696  inline object_data_output::write_object(const T &object) {
1697  if (is_no_write_) { return; }
1698  write(static_cast<int32_t>((hz_serializer<T>::get_type_id())), boost::endian::order::big);
1699  write < T > (object);
1700  }
1701 
1702  template<typename T>
1703  typename std::enable_if<std::is_array<T>::value && std::is_same<typename std::remove_all_extents<T>::type, char>::value, void>::type
1704  inline object_data_output::write_object(const T &object) {
1705  write_object(std::string(object));
1706  }
1707 
1708  template<typename T>
1709  typename std::enable_if<std::is_base_of<custom_serializer, hz_serializer<T>>::value, void>::type
1710  inline object_data_output::write_object(const T &object) {
1711  if (is_no_write_) { return; }
1712  static_assert(hz_serializer<T>::get_type_id() > 0, "Custom serializer type id can not be negative!");
1713  write(hz_serializer<T>::get_type_id(), boost::endian::order::big);
1714  hz_serializer<T>::write(object, *this);
1715  }
1716 
1723  template<typename T>
1724  typename std::enable_if<!(std::is_base_of<builtin_serializer, hz_serializer<T>>::value ||
1725  std::is_base_of<identified_data_serializer, hz_serializer<T>>::value ||
1726  std::is_base_of<portable_serializer, hz_serializer<T>>::value ||
1727  std::is_base_of<custom_serializer, hz_serializer<T>>::value ||
1728  (std::is_array<T>::value &&
1729  std::is_same<typename std::remove_all_extents<T>::type, char>::value)), void>::type
1730  inline object_data_output::write_object(const T object) {
1731  if (!global_serializer_) {
1732  throw exception::hazelcast_serialization("object_data_output::write_object",
1733  (boost::format("No serializer found for type(%1%).") %typeid(T).name()).str());
1734  }
1735  if (is_no_write_) { return; }
1736  write(static_cast<int32_t>(global_serializer::get_type_id()), boost::endian::order::big);
1737  global_serializer_->write(boost::any(std::move(object)), *this);
1738  }
1739 
1740  template<typename T>
1741  typename std::enable_if<!(std::is_array<T>::value &&
1742  std::is_same<typename std::remove_all_extents<T>::type, char>::value), boost::optional<T>>::type
1744  int32_t typeId = read(boost::endian::order::big);
1745  if (static_cast<int32_t>(pimpl::serialization_constants::CONSTANT_TYPE_NULL) == typeId) {
1746  return boost::none;
1747  }
1748  return read_object<T>(typeId);
1749  }
1750 
1751  template<typename T>
1752  typename std::enable_if<std::is_array<T>::value &&
1753  std::is_same<typename std::remove_all_extents<T>::type, char>::value, boost::optional<std::string>>::type
1755  return read_object<std::string>();
1756  }
1757 
1758  template<typename T>
1759  typename std::enable_if<std::is_base_of<identified_data_serializer, hz_serializer<T>>::value, boost::optional<T>>::type
1760  inline object_data_input::read_object(int32_t type_id) {
1761  if (type_id != static_cast<int32_t>(pimpl::serialization_constants::CONSTANT_TYPE_DATA)) {
1762  BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
1763  "object_data_input::read_object<identified_data_serializer>",
1764  (boost::format(
1765  "The associated serializer Serializer<T> is identified_data_serializer "
1766  "but received data type id is %1%") % type_id).str()));
1767  }
1768 
1769  return data_serializer_.read_object<T>(*this);
1770  }
1771 
1772  template<typename T>
1773  typename std::enable_if<std::is_base_of<portable_serializer, hz_serializer<T>>::value, boost::optional<T>>::type
1774  inline object_data_input::read_object(int32_t type_id) {
1775  if (type_id != static_cast<int32_t>(pimpl::serialization_constants::CONSTANT_TYPE_PORTABLE)) {
1776  BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
1777  "object_data_input::read_object<portable_serializer>",
1778  (boost::format(
1779  "The associated serializer Serializer<T> is portable_serializer "
1780  "but received data type id is %1%") % type_id).str()));
1781  }
1782 
1783  return portable_serializer_.read_object<T>(*this);
1784  }
1785 
1786  template<typename T>
1787  typename std::enable_if<std::is_base_of<custom_serializer, hz_serializer<T>>::value, boost::optional<T>>::type
1788  inline object_data_input::read_object(int32_t type_id) {
1789  if (type_id != hz_serializer<T>::get_type_id()) {
1790  BOOST_THROW_EXCEPTION(exception::hazelcast_serialization("object_data_input::read_object<>",
1791  (boost::format(
1792  "The associated serializer Serializer<T> type id %1% does not match "
1793  "received data type id is %2%") %
1794  hz_serializer<T>::get_type_id() %
1795  type_id).str()));
1796  }
1797 
1798  return boost::optional<T>(hz_serializer<T>::read(*this));
1799  }
1800 
1801  template<typename T>
1802  typename std::enable_if<std::is_base_of<builtin_serializer, hz_serializer<T>>::value, boost::optional<T>>::type
1803  inline object_data_input::read_object(int32_t type_id) {
1804  assert(type_id == static_cast<int32_t>(hz_serializer<T>::get_type_id()));
1805 
1806  return boost::optional<T>(read<T>());
1807  }
1808 
1809  template<typename T>
1810  typename std::enable_if<!(std::is_base_of<identified_data_serializer, hz_serializer<T>>::value ||
1811  std::is_base_of<portable_serializer, hz_serializer<T>>::value ||
1812  std::is_base_of<builtin_serializer, hz_serializer<T>>::value ||
1813  std::is_base_of<custom_serializer, hz_serializer<T>>::value), boost::optional<T>>::type
1814  inline object_data_input::read_object(int32_t type_id) {
1815  if (!global_serializer_) {
1816  throw exception::hazelcast_serialization("object_data_input::read_object",
1817  (boost::format("No serializer found for type %1%.") %typeid(T).name()).str());
1818  }
1819 
1820  if (type_id != static_cast<int32_t>(global_serializer_->get_type_id())) {
1821  BOOST_THROW_EXCEPTION(exception::hazelcast_serialization("object_data_input::read_object<>",
1822  (boost::format(
1823  "The global serializer type id %1% does not match "
1824  "received data type id is %2%") %
1825  static_cast<int32_t>(global_serializer_->get_type_id()) %
1826  type_id).str()));
1827  }
1828 
1829  return boost::optional<T>(boost::any_cast<T>(std::move(global_serializer_->read(*this))));
1830  }
1831 
1832  namespace pimpl {
1833  template<>
1834  data SerializationService::to_data(const typed_data *object);
1835 
1836  template<typename T>
1837  boost::optional<T> DefaultPortableReader::read_portable(const std::string &field_name) {
1838  return get_portable_instance<T>(field_name);
1839  }
1840 
1841  template<typename T>
1842  boost::optional<std::vector<T>> DefaultPortableReader::read_portable_array(const std::string &field_name) {
1843  PortableReaderBase::set_position(field_name, field_type::TYPE_PORTABLE_ARRAY);
1844 
1845  data_input_->read<int32_t>();
1846  std::vector<T> portables;
1847 
1848  set_position(field_name, field_type::TYPE_PORTABLE_ARRAY);
1849 
1850  int32_t len = data_input_->read<int32_t>();
1851  if (len == util::Bits::NULL_ARRAY) {
1852  return boost::none;
1853  }
1854  int32_t factoryId = data_input_->read<int32_t>();
1855  int32_t classId = data_input_->read<int32_t>();
1856 
1857  check_factory_and_class(cd_->get_field(field_name), factoryId, classId);
1858 
1859  if (len > 0) {
1860  int offset = data_input_->position();
1861  for (int i = 0; i < len; i++) {
1862  data_input_->position(offset + i * util::Bits::INT_SIZE_IN_BYTES);
1863  int32_t start = data_input_->read<int32_t>();
1864  data_input_->position(start);
1865 
1866  portables.push_back(portable_serializer_->read<T>(*data_input_, factoryId, classId));
1867  }
1868  }
1869  return portables;
1870  }
1871 
1872  template<typename T>
1873  boost::optional<T> MorphingPortableReader::read_portable(const std::string &field_name) {
1874  return get_portable_instance<T>(field_name);
1875  }
1876 
1877  template<typename T>
1878  boost::optional<std::vector<T>> MorphingPortableReader::read_portable_array(const std::string &field_name) {
1879  PortableReaderBase::set_position(field_name, field_type::TYPE_PORTABLE_ARRAY);
1880 
1881  data_input_->read<int32_t>();
1882  std::vector<T> portables;
1883 
1884  set_position(field_name, field_type::TYPE_PORTABLE_ARRAY);
1885 
1886  int32_t len = data_input_->read<int32_t>();
1887  if (len == util::Bits::NULL_ARRAY) {
1888  return boost::none;
1889  }
1890  int32_t factoryId = data_input_->read<int32_t>();
1891  int32_t classId = data_input_->read<int32_t>();
1892 
1893  check_factory_and_class(cd_->get_field(field_name), factoryId, classId);
1894 
1895  if (len > 0) {
1896  portables.reserve(static_cast<size_t>(len));
1897  int offset = data_input_->position();
1898  for (int i = 0; i < len; i++) {
1899  data_input_->position(offset + i * util::Bits::INT_SIZE_IN_BYTES);
1900  int32_t start = data_input_->read<int32_t>();
1901  data_input_->position(start);
1902 
1903  portables.emplace_back(portable_serializer_->read<T>(*data_input_, factoryId, classId));
1904  }
1905  }
1906 
1907  return boost::make_optional(std::move(portables));
1908  }
1909 
1910  template<typename T>
1911  T PortableSerializer::read_object(object_data_input &in) {
1912  int32_t factoryId = read_int(in);
1913  int32_t classId = read_int(in);
1914 
1915  if (factoryId != hz_serializer<T>::get_factory_id() || classId != hz_serializer<T>::get_class_id()) {
1916  BOOST_THROW_EXCEPTION(
1917  exception::hazelcast_serialization("PortableSerializer::read_object",
1918  (boost::format("Received data (factory-class id)=(%1%, %2%) does not match expected factory-class id (%3%, %4%)") %
1919  factoryId % classId %
1920  hz_serializer<T>::get_factory_id() %
1921  hz_serializer<T>::get_class_id()).str()));
1922  }
1923  return read<T>(in, factoryId, classId);
1924  }
1925 
1926  template<typename T>
1927  T PortableSerializer::read(object_data_input &in, int32_t factory_id, int32_t class_id) {
1928  int version = in.read<int32_t>();
1929 
1930  int portableVersion = find_portable_version<T>(factory_id, class_id);
1931 
1932  portable_reader reader = create_reader(in, factory_id, class_id, version, portableVersion);
1933  T result = hz_serializer<T>::read_portable(reader);
1934  reader.end();
1935  return result;
1936  }
1937 
1938  template<typename T>
1939  void PortableSerializer::write(const T &object, object_data_output &out) {
1940  out.write<int32_t>(hz_serializer<T>::get_factory_id());
1941  out.write<int32_t>(hz_serializer<T>::get_class_id());
1942 
1943  write_internal(object, out);
1944  }
1945 
1946  template<typename T>
1947  void PortableSerializer::write_internal(const T &object, object_data_output &out) {
1948  auto cd = context_.lookup_or_register_class_definition<T>(object);
1949  write_internal(object, cd, out);
1950  }
1951 
1952  template<typename T>
1953  void PortableSerializer::write_internal(const T &object, std::shared_ptr<ClassDefinition> &cd,
1954  object_data_output &out) {
1955  out.write<int32_t>(cd->get_version());
1956 
1957  DefaultPortableWriter dpw(*this, cd, out);
1958  portable_writer portableWriter(&dpw);
1959  hz_serializer<T>::write_portable(object, portableWriter);
1960  portableWriter.end();
1961  }
1962 
1963  template<typename T>
1964  std::shared_ptr<ClassDefinition> PortableSerializer::lookup_or_register_class_definition(const T &portable) {
1965  return context_.lookup_or_register_class_definition<T>(portable);
1966  }
1967 
1968  template<typename T>
1969  int PortableSerializer::find_portable_version(int factory_id, int class_id) const {
1970  int currentVersion = context_.get_class_version(factory_id, class_id);
1971  if (currentVersion < 0) {
1972  currentVersion = PortableVersionHelper::get_version<T>(context_.get_version());
1973  if (currentVersion > 0) {
1974  context_.set_class_version(factory_id, class_id, currentVersion);
1975  }
1976  }
1977  return currentVersion;
1978  }
1979 
1980  template<typename T>
1981  void DataSerializer::write(const T &object, object_data_output &out) {
1982  out.write<bool>(true);
1983  out.write<int32_t>(hz_serializer<T>::get_factory_id());
1984  out.write<int32_t>(hz_serializer<T>::get_class_id());
1985  hz_serializer<T>::write_data(object, out);
1986  }
1987 
1988  template<typename T>
1989  std::shared_ptr<ClassDefinition>
1990  PortableContext::lookup_or_register_class_definition(const T &portable) {
1991  int portableVersion = PortableVersionHelper::get_version<T>(
1992  serialization_config_.get_portable_version());
1993  std::shared_ptr<ClassDefinition> cd = lookup_class_definition(hz_serializer<T>::get_factory_id(),
1994  hz_serializer<T>::get_class_id(),
1995  portableVersion);
1996  if (cd.get() == NULL) {
1997  ClassDefinitionBuilder classDefinitionBuilder(hz_serializer<T>::get_factory_id(),
1998  hz_serializer<T>::get_class_id(), portableVersion);
1999  ClassDefinitionWriter cdw(*this, classDefinitionBuilder);
2000  portable_writer portableWriter(&cdw);
2001  hz_serializer<T>::write_portable(portable, portableWriter);
2002  cd = cdw.register_and_get();
2003  }
2004  return cd;
2005  }
2006 
2007  template<typename T>
2008  boost::optional<T> PortableReaderBase::get_portable_instance(const std::string &field_name) {
2009  set_position(field_name, field_type::TYPE_PORTABLE);
2010 
2011  bool isNull = data_input_->read<bool>();
2012  int32_t factoryId = data_input_->read<int32_t>();
2013  int32_t classId = data_input_->read<int32_t>();
2014 
2015  check_factory_and_class(cd_->get_field(field_name), factoryId, classId);
2016 
2017  if (isNull) {
2018  return boost::none;
2019  } else {
2020  return portable_serializer_->read<T>(*data_input_, factoryId, classId);
2021  }
2022  }
2023 
2024  template<typename T>
2025  void DefaultPortableWriter::write_null_portable(const std::string &field_name) {
2026  set_position(field_name, field_type::TYPE_PORTABLE);
2027  object_data_output_.write<bool>(true);
2028  object_data_output_.write<int32_t>(hz_serializer<T>::getFactoryId());
2029  object_data_output_.write<int32_t>(hz_serializer<T>::getClassId());
2030  }
2031 
2032  template<typename T>
2033  void DefaultPortableWriter::write_portable(const std::string &field_name, const T *portable) {
2034  FieldDefinition const &fd = set_position(field_name, field_type::TYPE_PORTABLE);
2035  bool isNull = (nullptr == portable);
2036  object_data_output_.write<bool>(isNull);
2037 
2038  object_data_output_.write<int32_t>(hz_serializer<T>::get_factory_id());
2039  object_data_output_.write<int32_t>(hz_serializer<T>::get_class_id());
2040 
2041  if (!isNull) {
2042  check_portable_attributes<T>(fd);
2043  portable_serializer_.write_internal(*portable, object_data_output_);
2044  }
2045 
2046  portable_serializer_.write(*portable, object_data_output_);
2047  }
2048 
2049  template<typename T>
2050  void DefaultPortableWriter::write_portable_array(const std::string &field_name, const std::vector<T> *values) {
2051  FieldDefinition const &fd = set_position(field_name, field_type::TYPE_PORTABLE_ARRAY);
2052  check_portable_attributes<T>(fd);
2053 
2054  int32_t len = (values ? static_cast<int32_t>(values->size()) : util::Bits::NULL_ARRAY);
2055  object_data_output_.write<int32_t>(len);
2056 
2057  object_data_output_.write<int32_t>(fd.get_factory_id());
2058  object_data_output_.write<int32_t>(fd.get_class_id());
2059 
2060  if (len > 0) {
2061  std::shared_ptr<ClassDefinition> classDefinition = portable_serializer_.lookup_or_register_class_definition<T>(
2062  (*values)[0]);
2063  size_t currentOffset = object_data_output_.position();
2064  object_data_output_.position(currentOffset + len * util::Bits::INT_SIZE_IN_BYTES);
2065  for (int32_t i = 0; i < len; i++) {
2066  size_t position = object_data_output_.position();
2067  object_data_output_.write_at(currentOffset + i * util::Bits::INT_SIZE_IN_BYTES, static_cast<int32_t>(position));
2068  portable_serializer_.write_internal((*values)[i], classDefinition, object_data_output_);
2069  }
2070  }
2071  }
2072 
2073  template<typename T>
2074  void DefaultPortableWriter::check_portable_attributes(const FieldDefinition &fd) {
2075  if (fd.get_factory_id() != hz_serializer<T>::get_factory_id()) {
2076  BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
2077  "DefaultPortableWriter::::checkPortableAttributes", (boost::format(
2078  "Wrong Portable type! Expected factory-id: %1%, Actual factory-id: %2%")
2079  %fd.get_factory_id() %hz_serializer<T>::get_factory_id()).str()));
2080  }
2081  if (fd.get_class_id() != hz_serializer<T>::get_class_id()) {
2082  BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
2083  "DefaultPortableWriter::::checkPortableAttributes", (boost::format(
2084  "Wrong Portable type! Expected class-id: %1%, Actual class-id: %2%")
2085  %fd.get_class_id() %hz_serializer<T>::get_class_id()).str()));
2086  }
2087  }
2088 
2089  template<typename T>
2090  std::shared_ptr<ClassDefinition> ClassDefinitionWriter::create_nested_class_def(const T &portable) {
2091  int version = PortableVersionHelper::get_version<T>(context_.get_version());
2092  ClassDefinitionBuilder definitionBuilder(hz_serializer<T>::get_factory_id(), hz_serializer<T>::get_class_id(),
2093  version);
2094 
2095  ClassDefinitionWriter nestedWriter(context_, definitionBuilder);
2096  portable_writer portableWriter(&nestedWriter);
2097  hz_serializer<T>::write_portable(portable, portableWriter);
2098  return context_.register_class_definition(definitionBuilder.build());
2099  }
2100  }
2101  }
2102 
2103  template <typename T>
2104  boost::optional<T> typed_data::get() const {
2105  return ss_->to_object<T>(data_);
2106  }
2107  }
2108 }
2109 
2110 #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
2111 #pragma warning(pop)
2112 #endif
2113 
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< 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)
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< std::vector< T > > read_portable_array(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)
SerializationConfig is used to.
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.
Classes derived from this class should implement the following static methods: static int32_t getClas...
Classes derived from this class should implement the following static methods: static int32_t getClas...