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))
36hazelcast_json_value::~hazelcast_json_value() =
default;
47 return json_string_ == rhs.json_string_;
51hazelcast_json_value::operator!=(
const hazelcast_json_value& rhs)
const
53 return !(rhs == *
this);
57hazelcast_json_value::operator<(
const hazelcast_json_value& rhs)
const
59 return json_string_ < rhs.json_string_;
65 os <<
"jsonString: " << value.json_string_;
69typed_data::typed_data()
73typed_data::typed_data(
74 serialization::pimpl::data d,
75 serialization::pimpl::SerializationService& serialization_service)
77 , ss_(&serialization_service)
80serialization::pimpl::object_type
83 return ss_->get_object_type(&data_);
86const 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;
101namespace 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();
132ClassDefinitionBuilder::ClassDefinitionBuilder(
int factory_id,
135 : factory_id_(factory_id)
136 , class_id_(class_id)
142ClassDefinitionBuilder&
143ClassDefinitionBuilder::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);
162ClassDefinitionBuilder&
163ClassDefinitionBuilder::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);
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);
204std::shared_ptr<ClassDefinition>
205ClassDefinitionBuilder::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);
220ClassDefinitionBuilder::check()
223 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
224 "ClassDefinitionBuilder::check",
225 "ClassDefinition is already built for " +
226 util::IOUtil::to_string(class_id_)));
231ClassDefinitionBuilder::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);
240ClassDefinitionBuilder::get_factory_id()
246ClassDefinitionBuilder::get_class_id()
252ClassDefinitionBuilder::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_;
349FieldDefinition::operator!=(
const FieldDefinition& rhs)
const
351 return !(rhs == *
this);
355operator<<(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)
394portable_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();
419object_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_;
553ClassDefinition::operator!=(
const ClassDefinition& rhs)
const
555 return !(rhs == *
this);
559operator<<(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_) {
574ClassDefinitionWriter::ClassDefinitionWriter(PortableContext& portable_context,
575 ClassDefinitionBuilder& builder)
577 , context_(portable_context)
578 , empty_data_output_(
579 portable_context.get_serialization_config().get_byte_order(),
583std::shared_ptr<ClassDefinition>
584ClassDefinitionWriter::register_and_get()
586 std::shared_ptr<ClassDefinition> cd = builder_.build();
587 return context_.register_class_definition(cd);
591ClassDefinitionWriter::get_raw_data_output()
593 return empty_data_output_;
597ClassDefinitionWriter::end()
600data_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);
613data_output::write(
byte i)
618 output_stream_.push_back(i);
623data_output::write(
char i)
631data_output::write(
char16_t i)
638data_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);
654data_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);
671data_output::write(int32_t value)
673 write(value, byte_order_);
678data_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);
695data_output::write(
float x)
711data_output::write(
double v)
727data_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);
744data_output::write(
bool value)
754data_output::write(int8_t value)
764data_output::write(
const std::string& str)
770 write<int32_t>(str.size());
771 output_stream_.insert(output_stream_.end(), str.begin(), str.end());
776data_output::write(
const hazelcast_json_value& value)
781 write<std::string>(value.to_string());
785data_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()));
803data_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;
820object_type::object_type()
821 : type_id(serialization_constants::CONSTANT_TYPE_NULL)
827operator<<(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;
837 return in.read<int32_t>();
840PortableContext::PortableContext(
const serialization_config& serialization_conf)
841 : serialization_config_(serialization_conf)
845PortableContext::get_class_version(
int factory_id,
int class_id)
847 return get_class_definition_context(factory_id).get_class_version(class_id);
851PortableContext::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);
857std::shared_ptr<ClassDefinition>
858PortableContext::lookup_class_definition(
int factory_id,
862 return get_class_definition_context(factory_id).lookup(class_id, version);
865std::shared_ptr<ClassDefinition>
871 bool shouldRegister =
true;
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;
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;
937std::shared_ptr<ClassDefinition>
938PortableContext::register_class_definition(std::shared_ptr<ClassDefinition> cd)
940 return get_class_definition_context(cd->get_factory_id())
941 .register_class_definition(cd);
945PortableContext::get_version()
947 return serialization_config_.get_portable_version();
950ClassDefinitionContext&
951PortableContext::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) {
967const serialization_config&
968PortableContext::get_serialization_config()
const
970 return serialization_config_;
973SerializationService::SerializationService(
974 const serialization_config& config,
975 default_schema_service& schema_service)
976 : serialization_config_(config)
977 , portable_context_(serialization_config_)
978 , portable_serializer_(portable_context_)
979 , compact_serializer_(schema_service)
982DefaultPortableWriter::DefaultPortableWriter(
983 PortableSerializer& portable_ser,
984 std::shared_ptr<ClassDefinition> cd,
987 , portable_serializer_(portable_ser)
988 , object_data_output_(output)
989 , begin_(object_data_output_.position())
993 object_data_output_.write<int32_t>(0);
995 object_data_output_.write<int32_t>(cd->get_field_count());
997 offset_ = object_data_output_.position();
999 int fieldIndexesLength =
1000 (cd->get_field_count() + 1) * util::Bits::INT_SIZE_IN_BYTES;
1001 object_data_output_.write_zero_bytes(fieldIndexesLength);
1005DefaultPortableWriter::set_position(
const std::string& field_name,
1006 field_type field_type)
1009 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
1010 "PortableWriter::setPosition",
1011 "Cannot write Portable fields after getRawDataOutput() is called!"));
1017 if (written_fields_.find(field_name) != written_fields_.end()) {
1018 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
1019 "PortableWriter::setPosition",
1020 "Field '" + std::string(field_name) +
1021 "' has already been written!"));
1024 written_fields_.insert(field_name);
1025 size_t pos = object_data_output_.position();
1027 object_data_output_.write_at(offset_ +
1028 index * util::Bits::INT_SIZE_IN_BYTES,
1029 static_cast<int32_t
>(pos));
1030 object_data_output_.write(
static_cast<int16_t
>(field_name.size()));
1031 object_data_output_.write_bytes(field_name);
1032 object_data_output_.write<
byte>(
static_cast<byte>(field_type));
1036 }
catch (exception::illegal_argument& iae) {
1037 std::stringstream error;
1038 error <<
"hazelcast_serialization_exception( Invalid field name: '"
1040 error <<
"' for ClassDefinition {class id: "
1041 << util::IOUtil::to_string(cd_->get_class_id());
1042 error <<
", factoryId:" +
1043 util::IOUtil::to_string(cd_->get_factory_id());
1044 error <<
", version: " << util::IOUtil::to_string(cd_->get_version())
1046 error << iae.what();
1048 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
1049 "PortableWriter::setPosition", error.str()));
1054DefaultPortableWriter::get_raw_data_output()
1057 size_t pos = object_data_output_.position();
1058 int32_t index = cd_->get_field_count();
1059 object_data_output_.write_at(offset_ +
1060 index * util::Bits::INT_SIZE_IN_BYTES,
1061 static_cast<int32_t
>(pos));
1064 return object_data_output_;
1068DefaultPortableWriter::end()
1070 object_data_output_.write_at(
1071 begin_,
static_cast<int32_t
>(object_data_output_.position()));
1075SerializationService::is_null_data(
const data& data)
1077 return data.data_size() == 0 &&
1079 static_cast<int32_t
>(serialization_constants::CONSTANT_TYPE_NULL);
1084SerializationService::to_data(
const char*
object)
1087 return to_data<std::string>(
nullptr);
1089 std::string str(
object);
1090 return to_data<std::string>(str);
1094SerializationService::get_version()
const
1100SerializationService::get_object_type(
const data* data)
1105 type.type_id = serialization_constants::CONSTANT_TYPE_NULL;
1109 type.type_id =
static_cast<serialization_constants
>(data->get_type());
1111 if (serialization_constants::CONSTANT_TYPE_DATA == type.type_id ||
1112 serialization_constants::CONSTANT_TYPE_PORTABLE == type.type_id) {
1114 data_input<std::vector<byte>> dataInput(
1115 serialization_config_.get_byte_order(), data->to_byte_array(), 8);
1117 if (serialization_constants::CONSTANT_TYPE_DATA == type.type_id) {
1118 bool identified = dataInput.read<
bool>();
1120 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
1121 "SerializationService::getObjectType",
1122 " DataSerializable is not 'identified data'"));
1126 type.factory_id = dataInput.read<int32_t>();
1127 type.class_id = dataInput.read<int32_t>();
1134SerializationService::dispose()
1138SerializationService::get_portable_serializer()
1140 return portable_serializer_;
1143compact_stream_serializer&
1144SerializationService::get_compact_serializer()
1146 return compact_serializer_;
1150SerializationService::get_data_serializer()
1152 return data_serializer_;
1156SerializationService::new_output_stream()
1160 &portable_serializer_,
1161 &compact_serializer_,
1162 serialization_config_.get_global_serializer());
1167SerializationService::to_data(
const typed_data*
object)
1173 return object->get_data();
1177unsigned int data::PARTITION_HASH_OFFSET = 0;
1179unsigned int data::TYPE_OFFSET =
1180 data::PARTITION_HASH_OFFSET + util::Bits::INT_SIZE_IN_BYTES;
1182unsigned int data::DATA_OFFSET =
1183 data::TYPE_OFFSET + util::Bits::INT_SIZE_IN_BYTES;
1185unsigned int data::DATA_OVERHEAD = data::DATA_OFFSET;
1188 : cached_hash_value_(-1)
1191data::data(std::vector<byte> buffer, schemas_t s)
1192 : data_(std::move(buffer))
1193 , cached_hash_value_(-1)
1194 , schemas_will_be_replicated_{ std::move(s) }
1196 size_t size = data_.size();
1197 if (size > 0 && size < data::DATA_OVERHEAD) {
1198 throw(exception::exception_builder<exception::illegal_argument>(
1200 <<
"Provided buffer should be either empty or should contain "
1202 << data::DATA_OVERHEAD <<
" bytes! Provided buffer size:" << size)
1206 cached_hash_value_ = calculate_hash();
1210data::data_size()
const
1212 return (
size_t)std::max<int>((
int)total_size() - (
int)data::DATA_OVERHEAD,
1217data::total_size()
const
1219 return data_.size();
1223data::get_partition_hash()
const
1225 return cached_hash_value_;
1229data::has_partition_hash()
const
1231 return data_.size() >= data::DATA_OVERHEAD &&
1232 *
reinterpret_cast<const int32_t*
>(&data_[PARTITION_HASH_OFFSET]) !=
1236const std::vector<byte>&
1237data::to_byte_array()
const
1243data::get_type()
const
1245 if (total_size() == 0) {
1246 return static_cast<int32_t
>(
1247 serialization_constants::CONSTANT_TYPE_NULL);
1249 return boost::endian::
1250 endian_load<boost::uint32_t, 4, boost::endian::order::big>(
1251 &data_[data::TYPE_OFFSET]);
1254const data::schemas_t&
1255data::schemas_will_be_replicated()
const
1257 return schemas_will_be_replicated_;
1263 return cached_hash_value_;
1267data::calculate_hash()
const
1269 size_t size = data_size();
1274 if (has_partition_hash()) {
1275 return boost::endian::
1276 endian_load<boost::uint32_t, 4, boost::endian::order::big>(
1277 &data_[data::PARTITION_HASH_OFFSET]);
1280 return util::murmur_hash3_x86_32((
void*)&((data_)[data::DATA_OFFSET]),
1285data::operator<(
const data& rhs)
const
1287 return cached_hash_value_ < rhs.cached_hash_value_;
1291operator==(
const data& lhs,
const data& rhs)
1293 return lhs.data_ == rhs.data_;
1296ClassDefinitionContext::ClassDefinitionContext(
1298 PortableContext* portable_context)
1299 : factory_id_(factory_id)
1300 , portable_context_(portable_context)
1304ClassDefinitionContext::get_class_version(
int class_id)
1306 std::shared_ptr<int> version = current_class_versions_.get(class_id);
1307 return version != NULL ? *version : -1;
1311ClassDefinitionContext::set_class_version(
int class_id,
int version)
1313 std::shared_ptr<int> current = current_class_versions_.put_if_absent(
1314 class_id, std::shared_ptr<int>(
new int(version)));
1315 if (current != NULL && *current != version) {
1316 std::stringstream error;
1317 error <<
"Class-id: " << class_id <<
" is already registered!";
1318 BOOST_THROW_EXCEPTION(exception::illegal_argument(
1319 "ClassDefinitionContext::setClassVersion", error.str()));
1323std::shared_ptr<ClassDefinition>
1324ClassDefinitionContext::lookup(
int class_id,
int version)
1326 long long key = combine_to_long(class_id, version);
1327 return versioned_definitions_.get(key);
1330std::shared_ptr<ClassDefinition>
1331ClassDefinitionContext::register_class_definition(
1332 std::shared_ptr<ClassDefinition> cd)
1334 if (cd.get() == NULL) {
1335 return std::shared_ptr<ClassDefinition>();
1337 if (cd->get_factory_id() != factory_id_) {
1338 throw(exception::exception_builder<exception::hazelcast_serialization>(
1339 "ClassDefinitionContext::registerClassDefinition")
1340 <<
"Invalid factory-id! " << factory_id_ <<
" -> " << cd)
1344 cd->set_version_if_not_set(portable_context_->get_version());
1346 long long versionedClassId =
1347 combine_to_long(cd->get_class_id(), cd->get_version());
1348 std::shared_ptr<ClassDefinition> currentCd =
1349 versioned_definitions_.put_if_absent(versionedClassId, cd);
1350 if (currentCd.get() == NULL) {
1354 if (currentCd.get() != cd.get() && *currentCd != *cd) {
1355 throw(exception::exception_builder<exception::hazelcast_serialization>(
1356 "ClassDefinitionContext::registerClassDefinition")
1357 <<
"Incompatible class-definitions with same class-id: " << *cd
1358 <<
" VS " << *currentCd)
1366ClassDefinitionContext::combine_to_long(
int x,
int y)
const
1368 return ((int64_t)x) << 32 | (((int64_t)y) & 0xFFFFFFFL);
1371DefaultPortableReader::DefaultPortableReader(
1372 PortableSerializer& portable_ser,
1374 std::shared_ptr<ClassDefinition> cd)
1375 : PortableReaderBase(portable_ser, input, cd)
1378PortableReaderBase::PortableReaderBase(PortableSerializer& portable_ser,
1380 std::shared_ptr<ClassDefinition> cd)
1382 , data_input_(&input)
1383 , portable_serializer_(&portable_ser)
1389 final_position_ = input.read<int32_t>();
1391 fieldCount = input.read<int32_t>();
1392 }
catch (exception::iexception& e) {
1393 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
1394 "[PortableReaderBase::PortableReaderBase]", e.what()));
1396 if (fieldCount != cd->get_field_count()) {
1398 util::hz_snprintf(msg,
1400 "Field count[%d] in stream does not match %d",
1402 cd->get_field_count());
1403 BOOST_THROW_EXCEPTION(exception::illegal_state(
1404 "[PortableReaderBase::PortableReaderBase]", msg));
1406 this->offset_ = input.position();
1410PortableReaderBase::set_position(
const std::string& field_name,
1411 field_type
const& field_type)
1414 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
1415 "PortableReader::getPosition ",
1416 "Cannot read Portable fields after getRawDataInput() is called!"));
1418 if (!cd_->has_field(field_name)) {
1421 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
1422 "PortableReader::getPosition ",
1423 "Don't have a field named " + std::string(field_name)));
1426 if (cd_->get_field_type(field_name) != field_type) {
1427 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
1428 "PortableReader::getPosition ",
1429 "Field type did not matched for " + std::string(field_name)));
1432 data_input_->position(offset_ + cd_->get_field(field_name).get_index() *
1433 util::Bits::INT_SIZE_IN_BYTES);
1434 int32_t pos = data_input_->read<int32_t>();
1436 data_input_->position(pos);
1437 int16_t len = data_input_->read<int16_t>();
1440 data_input_->position(pos + util::Bits::SHORT_SIZE_IN_BYTES + len + 1);
1443hazelcast::client::serialization::object_data_input&
1444PortableReaderBase::get_raw_data_input()
1447 data_input_->position(offset_ + cd_->get_field_count() *
1448 util::Bits::INT_SIZE_IN_BYTES);
1449 int32_t pos = data_input_->read<int32_t>();
1450 data_input_->position(pos);
1453 return *data_input_;
1457PortableReaderBase::end()
1459 data_input_->position(final_position_);
1465 int32_t class_id)
const
1467 if (factory_id != fd.get_factory_id()) {
1469 util::hz_snprintf(msg,
1471 "Invalid factoryId! Expected: %d, Current: %d",
1472 fd.get_factory_id(),
1474 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
1475 "DefaultPortableReader::checkFactoryAndClass ", std::string(msg)));
1477 if (class_id != fd.get_class_id()) {
1479 util::hz_snprintf(msg,
1481 "Invalid classId! Expected: %d, Current: %d",
1484 BOOST_THROW_EXCEPTION(exception::hazelcast_serialization(
1485 "DefaultPortableReader::checkFactoryAndClass ", std::string(msg)));
1489MorphingPortableReader::MorphingPortableReader(
1490 PortableSerializer& portable_ser,
1492 std::shared_ptr<ClassDefinition> cd)
1493 : PortableReaderBase(portable_ser, input, cd)
1496PortableSerializer::PortableSerializer(PortableContext& portable_context)
1497 : context_(portable_context)
1505 int portable_version)
1508 int effectiveVersion = version;
1510 effectiveVersion = context_.get_version();
1513 std::shared_ptr<ClassDefinition> cd =
1514 context_.lookup_class_definition(factory_id, class_id, effectiveVersion);
1515 if (cd ==
nullptr) {
1516 int begin = input.position();
1517 cd = context_.read_class_definition(
1518 input, factory_id, class_id, effectiveVersion);
1519 input.position(begin);
1523 *
this, input, cd, effectiveVersion == portable_version);
1529 return in.read<int32_t>();
1539hash<hazelcast::client::hazelcast_json_value>::operator()(
1540 const hazelcast::client::hazelcast_json_value&
object)
const noexcept
1542 return std::hash<std::string>{}(
object.to_string());
1546hash<hazelcast::client::serialization::pimpl::data>::operator()(
1547 const hazelcast::client::serialization::pimpl::data& val)
const noexcept
1549 return std::hash<int>{}(val.hash());
1553hash<std::shared_ptr<hazelcast::client::serialization::pimpl::data>>::
1554operator()(
const std::shared_ptr<hazelcast::client::serialization::pimpl::data>&
1558 return std::hash<int>{}(-1);
1560 return std::hash<int>{}(val->hash());
1564equal_to<std::shared_ptr<hazelcast::client::serialization::pimpl::data>>::
1566 std::shared_ptr<hazelcast::client::serialization::pimpl::data>
const& lhs,
1567 std::shared_ptr<hazelcast::client::serialization::pimpl::data>
const& rhs)
1578 return lhs->to_byte_array() == rhs->to_byte_array();
1582less<std::shared_ptr<hazelcast::client::serialization::pimpl::data>>::
1584 const std::shared_ptr<hazelcast::client::serialization::pimpl::data>& lhs,
1585 const std::shared_ptr<hazelcast::client::serialization::pimpl::data>& rhs)
1588 const hazelcast::client::serialization::pimpl::data* leftPtr = lhs.get();
1589 const hazelcast::client::serialization::pimpl::data* rightPtr = rhs.
get();
1590 if (leftPtr == rightPtr) {
1594 if (leftPtr == NULL) {
1598 if (rightPtr == NULL) {
1602 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.
ClassDefinitionBuilder is used to build and register ClassDefinitions manually.
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.
Provides a mean of reading portable fields from a binary in form of java primitives arrays of java pr...
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