17 #include <boost/concept_check.hpp>
20 #include "hazelcast/client/serialization/serialization.h"
21 #include "hazelcast/client/hazelcast_json_value.h"
22 #include "hazelcast/client/serialization/serialization.h"
23 #include "hazelcast/util/Util.h"
24 #include "hazelcast/util/IOUtil.h"
25 #include "hazelcast/util/Bits.h"
26 #include "hazelcast/util/MurmurHash3.h"
27 #include "hazelcast/client/spi/ClientContext.h"
28 #include "hazelcast/client/client_config.h"
33 : json_string_(std::move(json_string))
36 hazelcast_json_value::~hazelcast_json_value() =
default;
47 return json_string_ == rhs.json_string_;
51 hazelcast_json_value::operator!=(
const hazelcast_json_value& rhs)
const
53 return !(rhs == *
this);
57 hazelcast_json_value::operator<(
const hazelcast_json_value& rhs)
const
59 return json_string_ < rhs.json_string_;
63 operator<<(std::ostream& os,
const hazelcast_json_value& value)
65 os <<
"jsonString: " << value.json_string_;
69 typed_data::typed_data()
73 typed_data::typed_data(
74 serialization::pimpl::data d,
75 serialization::pimpl::SerializationService& serialization_service)
77 , ss_(&serialization_service)
80 serialization::pimpl::object_type
83 return ss_->get_object_type(&data_);
86 const serialization::pimpl::data&
95 const auto& lhs_data = lhs.
get_data();
96 const auto& rhs_data = rhs.
get_data();
98 return lhs_data < rhs_data;
101 namespace serialization {
103 pimpl::DefaultPortableWriter* default_portable_writer)
104 : default_portable_writer_(default_portable_writer)
105 , class_definition_writer_(nullptr)
106 , is_default_writer_(true)
110 pimpl::ClassDefinitionWriter* class_definition_writer)
111 : default_portable_writer_(nullptr)
112 , class_definition_writer_(class_definition_writer)
113 , is_default_writer_(false)
119 if (is_default_writer_)
120 return default_portable_writer_->end();
121 return class_definition_writer_->end();
127 if (is_default_writer_)
128 return default_portable_writer_->get_raw_data_output();
129 return class_definition_writer_->get_raw_data_output();
132 ClassDefinitionBuilder::ClassDefinitionBuilder(
int factory_id,
135 : factory_id_(factory_id)
136 , class_id_(class_id)
142 ClassDefinitionBuilder&
143 ClassDefinitionBuilder::add_portable_field(
const std::string& field_name,
144 std::shared_ptr<ClassDefinition> def)
147 if (def->get_class_id() == 0) {
148 BOOST_THROW_EXCEPTION(exception::illegal_argument(
149 "ClassDefinitionBuilder::addPortableField",
150 "Portable class id cannot be zero!"));
152 FieldDefinition fieldDefinition(index_++,
154 field_type::TYPE_PORTABLE,
155 def->get_factory_id(),
158 field_definitions_.push_back(fieldDefinition);
162 ClassDefinitionBuilder&
163 ClassDefinitionBuilder::add_portable_array_field(
164 const std::string& field_name,
165 std::shared_ptr<ClassDefinition> def)
168 if (def->get_class_id() == 0) {
169 BOOST_THROW_EXCEPTION(exception::illegal_argument(
170 "ClassDefinitionBuilder::addPortableField",
171 "Portable class id cannot be zero!"));
173 FieldDefinition fieldDefinition(index_++,
175 field_type::TYPE_PORTABLE_ARRAY,
176 def->get_factory_id(),
179 field_definitions_.push_back(fieldDefinition);
183 ClassDefinitionBuilder&
184 ClassDefinitionBuilder::add_field(FieldDefinition& field_definition)
187 int defIndex = field_definition.get_index();
188 if (index_ != defIndex) {
190 util::hz_snprintf(buf,
192 "Invalid field index. Index in definition:%d, being "
196 BOOST_THROW_EXCEPTION(
197 exception::illegal_argument(
"ClassDefinitionBuilder::addField", buf));
200 field_definitions_.push_back(field_definition);
204 std::shared_ptr<ClassDefinition>
205 ClassDefinitionBuilder::build()
208 std::shared_ptr<ClassDefinition> cd(
209 new ClassDefinition(factory_id_, class_id_, version_));
211 std::vector<FieldDefinition>::iterator fdIt;
212 for (fdIt = field_definitions_.begin(); fdIt != field_definitions_.end();
214 cd->add_field_def(*fdIt);
220 ClassDefinitionBuilder::check()
223 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
224 "ClassDefinitionBuilder::check",
225 "ClassDefinition is already built for " +
226 util::IOUtil::to_string(class_id_)));
231 ClassDefinitionBuilder::add_field(
const std::string& field_name,
232 field_type
const& field_type)
235 FieldDefinition fieldDefinition(index_++, field_name, field_type, version_);
236 field_definitions_.push_back(fieldDefinition);
240 ClassDefinitionBuilder::get_factory_id()
246 ClassDefinitionBuilder::get_class_id()
252 ClassDefinitionBuilder::get_version()
265 const std::string& field_name,
266 field_type
const& type,
269 , field_name_(field_name)
277 const std::string& field_name,
278 field_type
const& type,
283 , field_name_(field_name)
285 , class_id_(class_id)
286 , factory_id_(factory_id)
323 data_output.write<int32_t>(index_);
324 data_output.write<std::string>(field_name_);
325 data_output.write<
byte>(
static_cast<int32_t
>(type_));
326 data_output.write<int32_t>(factory_id_);
327 data_output.write<int32_t>(class_id_);
333 index_ = data_input.read<int32_t>();
334 field_name_ = data_input.read<std::string>();
335 type_ =
static_cast<field_type
>(data_input.read<
byte>());
336 factory_id_ = data_input.read<int32_t>();
337 class_id_ = data_input.read<int32_t>();
343 return field_name_ == rhs.field_name_ && type_ == rhs.type_ &&
344 class_id_ == rhs.class_id_ && factory_id_ == rhs.factory_id_ &&
345 version_ == rhs.version_;
349 FieldDefinition::operator!=(
const FieldDefinition& rhs)
const
351 return !(rhs == *
this);
355 operator<<(std::ostream& os,
const FieldDefinition& definition)
357 os <<
"FieldDefinition{"
358 <<
"index: " << definition.index_
359 <<
" fieldName: " << definition.field_name_
360 <<
" type: " <<
static_cast<int32_t
>(definition.type_)
361 <<
" classId: " << definition.class_id_
362 <<
" factoryId: " << definition.factory_id_
363 <<
" version: " << definition.version_;
368 boost::endian::order byte_order,
369 const std::vector<byte>& buffer,
371 pimpl::PortableSerializer& portable_ser,
372 pimpl::compact_stream_serializer& compact_ser,
373 pimpl::DataSerializer& data_ser,
375 : pimpl::data_input<std::vector<byte>>(byte_order, buffer, offset)
376 , portable_serializer_(portable_ser)
377 , compact_serializer_(compact_ser)
378 , data_serializer_(data_ser)
383 boost::endian::order byte_order,
385 pimpl::PortableSerializer* portable_ser,
386 pimpl::compact_stream_serializer* compact_ser,
388 : data_output(byte_order, dont_write)
389 , portable_serializer_(portable_ser)
390 , compact_serializer_(compact_ser)
394 portable_reader::portable_reader(pimpl::PortableSerializer& portable_ser,
396 const std::shared_ptr<ClassDefinition>& cd,
397 bool is_default_reader)
398 : is_default_reader_(is_default_reader)
400 if (is_default_reader) {
401 default_portable_reader_ = boost::make_optional(
402 pimpl::DefaultPortableReader(portable_ser, input, cd));
404 morphing_portable_reader_ = boost::make_optional(
405 pimpl::MorphingPortableReader(portable_ser, input, cd));
412 if (is_default_reader_)
413 return default_portable_reader_->get_raw_data_input();
414 return morphing_portable_reader_->get_raw_data_input();
419 object_data_output::write_object(
const char*
object)
422 write<int32_t>(
static_cast<int32_t
>(
423 pimpl::serialization_constants::CONSTANT_TYPE_NULL));
426 write_object<std::string>(std::string(
object));
432 if (is_default_reader_)
433 return default_portable_reader_->end();
434 return morphing_portable_reader_->end();
441 , binary_(new std::vector<byte>)
445 : factory_id_(factory_id)
446 , class_id_(class_id)
448 , binary_(new std::vector<byte>)
454 field_definitions_map_[fd.
get_name()] = fd;
460 auto it = field_definitions_map_.find(name);
461 if (it != field_definitions_map_.end()) {
464 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
465 "ClassDefinition::getField",
466 (boost::format(
"Invalid field name: '%1%' for ClassDefinition {id: %2%, "
468 name % class_id_ % version_)
475 return field_definitions_map_.find(field_name) !=
476 field_definitions_map_.end();
489 return (
int)field_definitions_map_.size();
514 this->version_ = new_version;
521 data_output.write<int32_t>(factory_id_);
522 data_output.write<int32_t>(class_id_);
523 data_output.write<int32_t>(version_);
524 data_output.write<int16_t>(field_definitions_map_.size());
525 for (
auto& entry : field_definitions_map_) {
526 entry.second.write_data(data_output);
533 factory_id_ = data_input.read<int32_t>();
534 class_id_ = data_input.read<int32_t>();
535 version_ = data_input.read<int32_t>();
536 int size = data_input.read<int16_t>();
537 for (
int i = 0; i < size; i++) {
547 return factory_id_ == rhs.factory_id_ && class_id_ == rhs.class_id_ &&
548 version_ == rhs.version_ &&
549 field_definitions_map_ == rhs.field_definitions_map_;
553 ClassDefinition::operator!=(
const ClassDefinition& rhs)
const
555 return !(rhs == *
this);
559 operator<<(std::ostream& os,
const ClassDefinition& definition)
561 os <<
"ClassDefinition{"
562 <<
"factoryId: " << definition.factory_id_
563 <<
" classId: " << definition.class_id_
564 <<
" version: " << definition.version_ <<
" fieldDefinitions: {";
566 for (
auto& entry : definition.field_definitions_map_) {
574 ClassDefinitionWriter::ClassDefinitionWriter(PortableContext& portable_context,
575 ClassDefinitionBuilder& builder)
577 , context_(portable_context)
578 , empty_data_output_(
579 portable_context.get_serialization_config().get_byte_order(),
583 std::shared_ptr<ClassDefinition>
584 ClassDefinitionWriter::register_and_get()
586 std::shared_ptr<ClassDefinition> cd = builder_.build();
587 return context_.register_class_definition(cd);
591 ClassDefinitionWriter::get_raw_data_output()
593 return empty_data_output_;
597 ClassDefinitionWriter::end()
600 data_output::data_output(boost::endian::order byte_order,
bool dont_write)
601 : byte_order_(byte_order)
602 , is_no_write_(dont_write)
605 output_stream_.reserve(0);
607 output_stream_.reserve(DEFAULT_SIZE);
613 data_output::write(
byte i)
618 output_stream_.push_back(i);
623 data_output::write(
char i)
631 data_output::write(char16_t i)
638 data_output::write(int16_t value)
643 if (byte_order_ == boost::endian::order::big) {
644 boost::endian::native_to_big_inplace(value);
646 boost::endian::native_to_little_inplace(value);
648 output_stream_.insert(output_stream_.end(),
650 (
byte*)&value + util::Bits::SHORT_SIZE_IN_BYTES);
654 data_output::write(int32_t value, boost::endian::order byte_order)
659 if (byte_order == boost::endian::order::big) {
660 boost::endian::native_to_big_inplace(value);
662 boost::endian::native_to_little_inplace(value);
664 output_stream_.insert(output_stream_.end(),
666 (
byte*)&value + util::Bits::INT_SIZE_IN_BYTES);
671 data_output::write(int32_t value)
673 write(value, byte_order_);
678 data_output::write(int64_t value)
683 if (byte_order_ == boost::endian::order::big) {
684 boost::endian::native_to_big_inplace(value);
686 boost::endian::native_to_little_inplace(value);
688 output_stream_.insert(output_stream_.end(),
690 (
byte*)&value + util::Bits::LONG_SIZE_IN_BYTES);
695 data_output::write(
float x)
711 data_output::write(
double v)
727 data_output::write(boost::uuids::uuid v)
732 if (byte_order_ == boost::endian::order::little) {
733 boost::endian::endian_reverse_inplace<int64_t>(
734 *
reinterpret_cast<int64_t*
>(v.data));
735 boost::endian::endian_reverse_inplace<int64_t>(
736 *
reinterpret_cast<int64_t*
>(&v.data[util::Bits::LONG_SIZE_IN_BYTES]));
738 output_stream_.insert(
739 output_stream_.end(), v.data, v.data + util::Bits::UUID_SIZE_IN_BYTES);
744 data_output::write(
bool value)
754 data_output::write(int8_t value)
764 data_output::write(
const std::string& str)
770 write<int32_t>(str.size());
771 output_stream_.insert(output_stream_.end(), str.begin(), str.end());
776 data_output::write(
const hazelcast_json_value& value)
781 write<std::string>(value.to_string());
785 data_output::check_available(
size_t index,
int requested_length)
788 BOOST_THROW_EXCEPTION(exception::illegal_argument(
789 "DataOutput::checkAvailable",
790 (boost::format(
"Negative pos! -> %1%") % index).str()));
793 size_t available = output_stream_.size() - index;
795 if (requested_length > (
int)available) {
796 BOOST_THROW_EXCEPTION(exception::illegal_argument(
797 "DataOutput::checkAvailable",
798 (boost::format(
"Cannot write %1% bytes!") % requested_length).str()));
803 data_output::write_boolean_bit_at(
size_t index,
804 size_t offset_in_bits,
810 check_available(index, 1);
811 byte b = output_stream_[index];
813 b = (byte)(b | (1 << offset_in_bits));
815 b = (byte)(b & ~(1 << offset_in_bits));
817 output_stream_[index] = b;
820 object_type::object_type()
821 : type_id(serialization_constants::CONSTANT_TYPE_NULL)
827 operator<<(std::ostream& os,
const object_type& type)
829 os <<
"typeId: " <<
static_cast<int32_t
>(type.type_id)
830 <<
" factoryId: " << type.factory_id <<
" classId: " << type.class_id;
835 DataSerializer::read_int(object_data_input& in)
const
837 return in.read<int32_t>();
840 PortableContext::PortableContext(
const serialization_config& serialization_conf)
841 : serialization_config_(serialization_conf)
845 PortableContext::get_class_version(
int factory_id,
int class_id)
847 return get_class_definition_context(factory_id).get_class_version(class_id);
851 PortableContext::set_class_version(
int factory_id,
int class_id,
int version)
853 get_class_definition_context(factory_id)
854 .set_class_version(class_id, version);
857 std::shared_ptr<ClassDefinition>
858 PortableContext::lookup_class_definition(
int factory_id,
862 return get_class_definition_context(factory_id).lookup(class_id, version);
865 std::shared_ptr<ClassDefinition>
866 PortableContext::read_class_definition(object_data_input& in,
871 bool shouldRegister =
true;
872 ClassDefinitionBuilder builder(factory_id, class_id, version);
878 int fieldCount = in.read<int32_t>();
879 int offset = in.position();
880 for (
int i = 0; i < fieldCount; i++) {
881 in.position(offset + i * util::Bits::INT_SIZE_IN_BYTES);
882 int pos = in.read<int32_t>();
885 short len = in.read<int16_t>();
886 std::vector<byte> chars(len);
887 in.read_fully(chars);
888 chars.push_back(
'\0');
890 field_type type(
static_cast<field_type
>(in.read<
byte>()));
891 std::string name((
char*)&(chars[0]));
892 int fieldFactoryId = 0;
893 int fieldClassId = 0;
894 int fieldVersion = version;
895 if (type == field_type::TYPE_PORTABLE) {
897 if (in.read<
bool>()) {
898 shouldRegister =
false;
900 fieldFactoryId = in.read<int32_t>();
901 fieldClassId = in.read<int32_t>();
904 if (shouldRegister) {
905 fieldVersion = in.read<int32_t>();
906 read_class_definition(
907 in, fieldFactoryId, fieldClassId, fieldVersion);
909 }
else if (type == field_type::TYPE_PORTABLE_ARRAY) {
910 int k = in.read<int32_t>();
912 fieldFactoryId = in.read<int32_t>();
913 fieldClassId = in.read<int32_t>();
915 int p = in.read<int32_t>();
919 fieldVersion = in.read<int32_t>();
920 read_class_definition(
921 in, fieldFactoryId, fieldClassId, fieldVersion);
923 shouldRegister =
false;
926 FieldDefinition fieldDef(
927 i, name, type, fieldFactoryId, fieldClassId, fieldVersion);
928 builder.add_field(fieldDef);
930 std::shared_ptr<ClassDefinition> classDefinition = builder.build();
931 if (shouldRegister) {
932 classDefinition = register_class_definition(classDefinition);
934 return classDefinition;
937 std::shared_ptr<ClassDefinition>
938 PortableContext::register_class_definition(std::shared_ptr<ClassDefinition> cd)
940 return get_class_definition_context(cd->get_factory_id())
941 .register_class_definition(cd);
945 PortableContext::get_version()
947 return serialization_config_.get_portable_version();
950 ClassDefinitionContext&
951 PortableContext::get_class_definition_context(
int factory_id)
953 std::shared_ptr<ClassDefinitionContext> value =
954 class_def_context_map_.get(factory_id);
956 value = std::shared_ptr<ClassDefinitionContext>(
957 new ClassDefinitionContext(factory_id,
this));
958 std::shared_ptr<ClassDefinitionContext> current =
959 class_def_context_map_.put_if_absent(factory_id, value);
960 if (current != NULL) {
967 const serialization_config&
968 PortableContext::get_serialization_config()
const
970 return serialization_config_;
973 SerializationService::SerializationService(
const serialization_config& config)
974 : serialization_config_(config)
975 , portable_context_(serialization_config_)
976 , portable_serializer_(portable_context_)
977 , compact_serializer_()
980 DefaultPortableWriter::DefaultPortableWriter(
981 PortableSerializer& portable_ser,
982 std::shared_ptr<ClassDefinition> cd,
983 object_data_output& output)
985 , portable_serializer_(portable_ser)
986 , object_data_output_(output)
987 , begin_(object_data_output_.position())
991 object_data_output_.write<int32_t>(0);
993 object_data_output_.write<int32_t>(cd->get_field_count());
995 offset_ = object_data_output_.position();
997 int fieldIndexesLength =
998 (cd->get_field_count() + 1) * util::Bits::INT_SIZE_IN_BYTES;
999 object_data_output_.write_zero_bytes(fieldIndexesLength);
1002 FieldDefinition
const&
1003 DefaultPortableWriter::set_position(
const std::string& field_name,
1004 field_type field_type)
1007 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
1008 "PortableWriter::setPosition",
1009 "Cannot write Portable fields after getRawDataOutput() is called!"));
1013 FieldDefinition
const& fd = cd_->get_field(field_name);
1015 if (written_fields_.find(field_name) != written_fields_.end()) {
1016 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
1017 "PortableWriter::setPosition",
1018 "Field '" + std::string(field_name) +
1019 "' has already been written!"));
1022 written_fields_.insert(field_name);
1023 size_t pos = object_data_output_.position();
1024 int32_t index = fd.get_index();
1025 object_data_output_.write_at(offset_ +
1026 index * util::Bits::INT_SIZE_IN_BYTES,
1027 static_cast<int32_t
>(pos));
1028 object_data_output_.write(
static_cast<int16_t
>(field_name.size()));
1029 object_data_output_.write_bytes(field_name);
1030 object_data_output_.write<
byte>(
static_cast<byte>(field_type));
1034 }
catch (exception::illegal_argument& iae) {
1035 std::stringstream error;
1036 error <<
"hazelcast_serialization_exception( Invalid field name: '"
1038 error <<
"' for ClassDefinition {class id: "
1039 << util::IOUtil::to_string(cd_->get_class_id());
1040 error <<
", factoryId:" +
1041 util::IOUtil::to_string(cd_->get_factory_id());
1042 error <<
", version: " << util::IOUtil::to_string(cd_->get_version())
1044 error << iae.what();
1046 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
1047 "PortableWriter::setPosition", error.str()));
1052 DefaultPortableWriter::get_raw_data_output()
1055 size_t pos = object_data_output_.position();
1056 int32_t index = cd_->get_field_count();
1057 object_data_output_.write_at(offset_ +
1058 index * util::Bits::INT_SIZE_IN_BYTES,
1059 static_cast<int32_t
>(pos));
1062 return object_data_output_;
1066 DefaultPortableWriter::end()
1068 object_data_output_.write_at(
1069 begin_,
static_cast<int32_t
>(object_data_output_.position()));
1073 SerializationService::is_null_data(
const data& data)
1075 return data.data_size() == 0 &&
1077 static_cast<int32_t
>(serialization_constants::CONSTANT_TYPE_NULL);
1082 SerializationService::to_data(
const char*
object)
1085 return to_data<std::string>(
nullptr);
1087 std::string str(
object);
1088 return to_data<std::string>(str);
1092 SerializationService::get_version()
const
1098 SerializationService::get_object_type(
const data* data)
1103 type.type_id = serialization_constants::CONSTANT_TYPE_NULL;
1107 type.type_id =
static_cast<serialization_constants
>(data->get_type());
1109 if (serialization_constants::CONSTANT_TYPE_DATA == type.type_id ||
1110 serialization_constants::CONSTANT_TYPE_PORTABLE == type.type_id) {
1112 data_input<std::vector<byte>> dataInput(
1113 serialization_config_.get_byte_order(), data->to_byte_array(), 8);
1115 if (serialization_constants::CONSTANT_TYPE_DATA == type.type_id) {
1116 bool identified = dataInput.read<
bool>();
1118 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
1119 "SerializationService::getObjectType",
1120 " DataSerializable is not 'identified data'"));
1124 type.factory_id = dataInput.read<int32_t>();
1125 type.class_id = dataInput.read<int32_t>();
1132 SerializationService::dispose()
1136 SerializationService::get_portable_serializer()
1138 return portable_serializer_;
1141 compact_stream_serializer&
1142 SerializationService::get_compact_serializer()
1144 return compact_serializer_;
1148 SerializationService::get_data_serializer()
1150 return data_serializer_;
1154 SerializationService::new_output_stream()
1156 return object_data_output(serialization_config_.get_byte_order(),
1158 &portable_serializer_,
1159 &compact_serializer_,
1160 serialization_config_.get_global_serializer());
1165 SerializationService::to_data(
const typed_data*
object)
1171 return object->get_data();
1175 unsigned int data::PARTITION_HASH_OFFSET = 0;
1177 unsigned int data::TYPE_OFFSET =
1178 data::PARTITION_HASH_OFFSET + util::Bits::INT_SIZE_IN_BYTES;
1180 unsigned int data::DATA_OFFSET =
1181 data::TYPE_OFFSET + util::Bits::INT_SIZE_IN_BYTES;
1183 unsigned int data::DATA_OVERHEAD = data::DATA_OFFSET;
1186 : cached_hash_value_(-1)
1189 data::data(std::vector<byte> buffer)
1190 : data_(std::move(buffer))
1191 , cached_hash_value_(-1)
1193 size_t size = data_.size();
1194 if (size > 0 && size < data::DATA_OVERHEAD) {
1195 throw(exception::exception_builder<exception::illegal_argument>(
1197 <<
"Provided buffer should be either empty or should contain "
1199 << data::DATA_OVERHEAD <<
" bytes! Provided buffer size:" << size)
1203 cached_hash_value_ = calculate_hash();
1207 data::data_size()
const
1209 return (
size_t)std::max<int>((
int)total_size() - (
int)data::DATA_OVERHEAD,
1214 data::total_size()
const
1216 return data_.size();
1220 data::get_partition_hash()
const
1222 return cached_hash_value_;
1226 data::has_partition_hash()
const
1228 return data_.size() >= data::DATA_OVERHEAD &&
1229 *
reinterpret_cast<const int32_t*
>(&data_[PARTITION_HASH_OFFSET]) !=
1233 const std::vector<byte>&
1234 data::to_byte_array()
const
1240 data::get_type()
const
1242 if (total_size() == 0) {
1243 return static_cast<int32_t
>(
1244 serialization_constants::CONSTANT_TYPE_NULL);
1246 return boost::endian::
1247 endian_load<boost::uint32_t, 4, boost::endian::order::big>(
1248 &data_[data::TYPE_OFFSET]);
1254 return cached_hash_value_;
1258 data::calculate_hash()
const
1260 size_t size = data_size();
1265 if (has_partition_hash()) {
1266 return boost::endian::
1267 endian_load<boost::uint32_t, 4, boost::endian::order::big>(
1268 &data_[data::PARTITION_HASH_OFFSET]);
1271 return util::murmur_hash3_x86_32((
void*)&((data_)[data::DATA_OFFSET]),
1276 data::operator<(
const data& rhs)
const
1278 return cached_hash_value_ < rhs.cached_hash_value_;
1282 operator==(
const data& lhs,
const data& rhs)
1284 return lhs.data_ == rhs.data_;
1287 ClassDefinitionContext::ClassDefinitionContext(
1289 PortableContext* portable_context)
1290 : factory_id_(factory_id)
1291 , portable_context_(portable_context)
1295 ClassDefinitionContext::get_class_version(
int class_id)
1297 std::shared_ptr<int> version = current_class_versions_.get(class_id);
1298 return version != NULL ? *version : -1;
1302 ClassDefinitionContext::set_class_version(
int class_id,
int version)
1304 std::shared_ptr<int> current = current_class_versions_.put_if_absent(
1305 class_id, std::shared_ptr<int>(
new int(version)));
1306 if (current != NULL && *current != version) {
1307 std::stringstream error;
1308 error <<
"Class-id: " << class_id <<
" is already registered!";
1309 BOOST_THROW_EXCEPTION(exception::illegal_argument(
1310 "ClassDefinitionContext::setClassVersion", error.str()));
1314 std::shared_ptr<ClassDefinition>
1315 ClassDefinitionContext::lookup(
int class_id,
int version)
1317 long long key = combine_to_long(class_id, version);
1318 return versioned_definitions_.get(key);
1321 std::shared_ptr<ClassDefinition>
1322 ClassDefinitionContext::register_class_definition(
1323 std::shared_ptr<ClassDefinition> cd)
1325 if (cd.get() == NULL) {
1326 return std::shared_ptr<ClassDefinition>();
1328 if (cd->get_factory_id() != factory_id_) {
1329 throw(exception::exception_builder<exception::hazelcast_serialization>(
1330 "ClassDefinitionContext::registerClassDefinition")
1331 <<
"Invalid factory-id! " << factory_id_ <<
" -> " << cd)
1335 cd->set_version_if_not_set(portable_context_->get_version());
1337 long long versionedClassId =
1338 combine_to_long(cd->get_class_id(), cd->get_version());
1339 std::shared_ptr<ClassDefinition> currentCd =
1340 versioned_definitions_.put_if_absent(versionedClassId, cd);
1341 if (currentCd.get() == NULL) {
1345 if (currentCd.get() != cd.get() && *currentCd != *cd) {
1346 throw(exception::exception_builder<exception::hazelcast_serialization>(
1347 "ClassDefinitionContext::registerClassDefinition")
1348 <<
"Incompatible class-definitions with same class-id: " << *cd
1349 <<
" VS " << *currentCd)
1357 ClassDefinitionContext::combine_to_long(
int x,
int y)
const
1359 return ((int64_t)x) << 32 | (((int64_t)y) & 0xFFFFFFFL);
1362 DefaultPortableReader::DefaultPortableReader(
1363 PortableSerializer& portable_ser,
1364 object_data_input& input,
1365 std::shared_ptr<ClassDefinition> cd)
1366 : PortableReaderBase(portable_ser, input, cd)
1369 PortableReaderBase::PortableReaderBase(PortableSerializer& portable_ser,
1370 object_data_input& input,
1371 std::shared_ptr<ClassDefinition> cd)
1373 , data_input_(&input)
1374 , portable_serializer_(&portable_ser)
1380 final_position_ = input.read<int32_t>();
1382 fieldCount = input.read<int32_t>();
1383 }
catch (exception::iexception& e) {
1384 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
1385 "[PortableReaderBase::PortableReaderBase]", e.what()));
1387 if (fieldCount != cd->get_field_count()) {
1389 util::hz_snprintf(msg,
1391 "Field count[%d] in stream does not match %d",
1393 cd->get_field_count());
1394 BOOST_THROW_EXCEPTION(exception::illegal_state(
1395 "[PortableReaderBase::PortableReaderBase]", msg));
1397 this->offset_ = input.position();
1401 PortableReaderBase::set_position(
const std::string& field_name,
1402 field_type
const& field_type)
1405 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
1406 "PortableReader::getPosition ",
1407 "Cannot read Portable fields after getRawDataInput() is called!"));
1409 if (!cd_->has_field(field_name)) {
1412 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
1413 "PortableReader::getPosition ",
1414 "Don't have a field named " + std::string(field_name)));
1417 if (cd_->get_field_type(field_name) != field_type) {
1418 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
1419 "PortableReader::getPosition ",
1420 "Field type did not matched for " + std::string(field_name)));
1423 data_input_->position(offset_ + cd_->get_field(field_name).get_index() *
1424 util::Bits::INT_SIZE_IN_BYTES);
1425 int32_t pos = data_input_->read<int32_t>();
1427 data_input_->position(pos);
1428 int16_t len = data_input_->read<int16_t>();
1431 data_input_->position(pos + util::Bits::SHORT_SIZE_IN_BYTES + len + 1);
1435 PortableReaderBase::get_raw_data_input()
1438 data_input_->position(offset_ + cd_->get_field_count() *
1439 util::Bits::INT_SIZE_IN_BYTES);
1440 int32_t pos = data_input_->read<int32_t>();
1441 data_input_->position(pos);
1444 return *data_input_;
1448 PortableReaderBase::end()
1450 data_input_->position(final_position_);
1454 PortableReaderBase::check_factory_and_class(FieldDefinition fd,
1456 int32_t class_id)
const
1458 if (factory_id != fd.get_factory_id()) {
1460 util::hz_snprintf(msg,
1462 "Invalid factoryId! Expected: %d, Current: %d",
1463 fd.get_factory_id(),
1465 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
1466 "DefaultPortableReader::checkFactoryAndClass ", std::string(msg)));
1468 if (class_id != fd.get_class_id()) {
1470 util::hz_snprintf(msg,
1472 "Invalid classId! Expected: %d, Current: %d",
1475 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
1476 "DefaultPortableReader::checkFactoryAndClass ", std::string(msg)));
1480 MorphingPortableReader::MorphingPortableReader(
1481 PortableSerializer& portable_ser,
1482 object_data_input& input,
1483 std::shared_ptr<ClassDefinition> cd)
1484 : PortableReaderBase(portable_ser, input, cd)
1487 PortableSerializer::PortableSerializer(PortableContext& portable_context)
1488 : context_(portable_context)
1492 PortableSerializer::create_reader(object_data_input& input,
1496 int portable_version)
1499 int effectiveVersion = version;
1501 effectiveVersion = context_.get_version();
1504 std::shared_ptr<ClassDefinition> cd =
1505 context_.lookup_class_definition(factory_id, class_id, effectiveVersion);
1506 if (cd ==
nullptr) {
1507 int begin = input.position();
1508 cd = context_.read_class_definition(
1509 input, factory_id, class_id, effectiveVersion);
1510 input.position(begin);
1513 return portable_reader(
1514 *
this, input, cd, effectiveVersion == portable_version);
1518 PortableSerializer::read_int(object_data_input& in)
const
1520 return in.read<int32_t>();
1530 hash<hazelcast::client::hazelcast_json_value>::operator()(
1533 return std::hash<std::string>{}(
object.to_string());
1537 hash<hazelcast::client::serialization::pimpl::data>::operator()(
1538 const hazelcast::client::serialization::pimpl::data& val)
const noexcept
1540 return std::hash<int>{}(val.hash());
1544 hash<std::shared_ptr<hazelcast::client::serialization::pimpl::data>>::
1545 operator()(
const std::shared_ptr<hazelcast::client::serialization::pimpl::data>&
1549 return std::hash<int>{}(-1);
1551 return std::hash<int>{}(val->hash());
1555 equal_to<std::shared_ptr<hazelcast::client::serialization::pimpl::data>>::
1557 std::shared_ptr<hazelcast::client::serialization::pimpl::data>
const& lhs,
1558 std::shared_ptr<hazelcast::client::serialization::pimpl::data>
const& rhs)
1569 return lhs->to_byte_array() == rhs->to_byte_array();
1573 less<std::shared_ptr<hazelcast::client::serialization::pimpl::data>>::
1575 const std::shared_ptr<hazelcast::client::serialization::pimpl::data>& lhs,
1576 const std::shared_ptr<hazelcast::client::serialization::pimpl::data>& rhs)
1579 const hazelcast::client::serialization::pimpl::data* leftPtr = lhs.
get();
1580 const hazelcast::client::serialization::pimpl::data* rightPtr = rhs.
get();
1581 if (leftPtr == rightPtr) {
1585 if (leftPtr == NULL) {
1589 if (rightPtr == NULL) {
1593 return lhs->hash() < rhs->hash();
hazelcast_json_value is a wrapper for Json formatted strings.
hazelcast_json_value(std::string json_string)
Create a hazelcast_json_value from a string.
const std::string & to_string() const
This method returns a Json representation of the object.
ClassDefinition()
Constructor.
void add_field_def(FieldDefinition &field_definition)
Internal API.
field_type get_field_type(const std::string &field_name) const
void write_data(pimpl::data_output &data_output)
Internal API.
const FieldDefinition & get_field(const std::string &field_name) const
void read_data(object_data_input &data_input)
Internal API.
int get_field_count() const
void set_version_if_not_set(int new_version)
Internal API.
bool has_field(const std::string &field_name) const
int get_factory_id() const
ClassDefinition defines a class schema for portable classes.
std::string get_name() const
FieldDefinition()
Constructor.
void write_data(pimpl::data_output &data_output)
void read_data(object_data_input &data_input)
const field_type & get_type() const
int get_factory_id() const
object_data_output(boost::endian::order byte_order, bool dont_write=false, pimpl::PortableSerializer *portable_ser=nullptr, pimpl::compact_stream_serializer *compact_ser=nullptr, std::shared_ptr< serialization::global_serializer > global_serializer=nullptr)
Internal API Constructor.
object_data_input & get_raw_data_input()
object_data_output & get_raw_data_output()
After writing portable fields, one can write remaining fields in old fashioned way consecutively at t...
void end()
Internal api , should not be called by end user.
portable_writer(pimpl::DefaultPortableWriter *default_portable_writer)
Internal api constructor.
typed_data class is a wrapper class for the serialized binary data.
const serialization::pimpl::data & get_data() const
Internal API.
boost::optional< T > get() const
Deserializes the underlying binary data and produces the object of type T.
serialization::pimpl::object_type get_type() const