Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ namespace serialization {

enum class HAZELCAST_API field_kind
{
NOT_AVAILABLE = 0,
BOOLEAN = 1,
ARRAY_OF_BOOLEAN = 2,
INT8 = 3,
Expand Down
1,297 changes: 1,297 additions & 0 deletions hazelcast/include/hazelcast/client/serialization/generic_record.h

Large diffs are not rendered by default.

1,543 changes: 1,543 additions & 0 deletions hazelcast/include/hazelcast/client/serialization/generic_record_builder.h

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@
// serialization.h not in the beginning but later to avoid cyclic dependency.

#include <boost/thread/future.hpp>
#include <boost/property_tree/ptree.hpp>
#include <utility>
#include "hazelcast/util/export.h"
#include "hazelcast/client/serialization/serialization.h"
#include "hazelcast/util/SynchronizedMap.h"
#include "hazelcast/client/serialization/field_kind.h"
#include "hazelcast/client/serialization/pimpl/compact/default_schema_service.h"
#include "hazelcast/client/serialization/pimpl/compact/schema_writer.h"

#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
#pragma warning(push)
Expand Down Expand Up @@ -649,6 +651,11 @@ class HAZELCAST_API compact_reader
typename boost::optional<T>>::type
read();
template<typename T>
typename std::enable_if<
std::is_same<generic_record::generic_record, T>::value,
typename boost::optional<T>>::type
read();
template<typename T>
typename std::enable_if<
std::is_same<std::vector<bool>, typename std::remove_cv<T>::type>::value,
typename boost::optional<T>>::type
Expand Down Expand Up @@ -1335,6 +1342,12 @@ class HAZELCAST_API default_compact_writer
void>::type
write(const T& value);

template<typename T>
typename std::enable_if<
std::is_same<generic_record::generic_record, T>::value,
void>::type
write(const T& value);

template<typename T>
typename std::enable_if<std::is_same<std::vector<bool>, T>::value,
void>::type
Expand Down Expand Up @@ -1369,17 +1382,6 @@ class HAZELCAST_API default_compact_writer
} // namespace pimpl

namespace pimpl {
class HAZELCAST_API schema_writer
{
public:
explicit schema_writer(std::string type_name);
void add_field(std::string field_name, enum field_kind kind);
schema build() &&;

private:
std::unordered_map<std::string, field_descriptor> field_definition_map;
std::string type_name;
};

class HAZELCAST_API compact_stream_serializer
{
Expand All @@ -1389,33 +1391,57 @@ class HAZELCAST_API compact_stream_serializer
template<typename T>
T read(object_data_input& in);

generic_record::generic_record read_generic_record(object_data_input& in);

template<typename T>
void write(const T& object, object_data_output& out);

template<typename T>
static schema build_schema(const T& object);

void write_generic_record(const generic_record::generic_record& record,
object_data_output& out);

private:
default_schema_service& schema_service;
};

struct HAZELCAST_API field_kind_based_operations
{
using kind_size_in_bytes_fn = std::function<int()>;
using write_field_from_record_to_writer_fn =
std::function<void(default_compact_writer&,
const generic_record::generic_record&,
const std::string&)>;
using read_generic_record_or_primitive_fn =
std::function<void(compact::compact_reader&,
generic_record::generic_record_builder&,
const std::string&)>;
using write_json_formatted_field_fn =
std::function<void(boost::property_tree::ptree&,
const generic_record::generic_record&,
const std::string&)>;

static constexpr int VARIABLE_SIZE = -1;

static constexpr int DEFAULT_KIND_SIZE_IN_BYTES() { return VARIABLE_SIZE; }

field_kind_based_operations();

explicit field_kind_based_operations(
std::function<int()> kind_size_in_byte_func);
explicit field_kind_based_operations(kind_size_in_bytes_fn,
write_field_from_record_to_writer_fn,
read_generic_record_or_primitive_fn,
write_json_formatted_field_fn);

std::function<int()> kind_size_in_byte_func;
kind_size_in_bytes_fn kind_size_in_byte_func;
Comment thread
ihsandemir marked this conversation as resolved.
write_field_from_record_to_writer_fn write_field_from_record_to_writer;
read_generic_record_or_primitive_fn read_generic_record_or_primitive;
write_json_formatted_field_fn write_json_formatted_field;
};

struct HAZELCAST_API field_operations
{
static field_kind_based_operations get(enum field_kind field_kind);
static const field_kind_based_operations& get(enum field_kind field_kind);
};

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#pragma once

#include "hazelcast/client/serialization/pimpl/compact/compact.h"
#include "hazelcast/client/serialization/generic_record_builder.h"
#include "hazelcast/util/finally.h"
#include "hazelcast/util/IOUtil.h"
#include <type_traits>
Expand Down Expand Up @@ -173,6 +174,14 @@ compact_reader::read()
return compact_stream_serializer.template read<T>(object_data_input);
}

template<typename T>
typename std::enable_if<std::is_same<generic_record::generic_record, T>::value,
typename boost::optional<T>>::type
compact_reader::read()
{
return compact_stream_serializer.read_generic_record(object_data_input);
}

template<typename T>
typename std::enable_if<
std::is_same<std::vector<bool>, typename std::remove_cv<T>::type>::value,
Expand Down Expand Up @@ -522,6 +531,14 @@ default_compact_writer::write(const T& value)
compact_stream_serializer_.template write<T>(value, object_data_output_);
}

template<typename T>
typename std::enable_if<std::is_same<generic_record::generic_record, T>::value,
void>::type
default_compact_writer::write(const T& value)
{
compact_stream_serializer_.write_generic_record(value, object_data_output_);
}

template<typename T>
typename std::enable_if<std::is_same<std::vector<bool>, T>::value, void>::type
default_compact_writer::write(const T& value)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2008-2023, Hazelcast, Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once

#include "hazelcast/client/exception/protocol_exceptions.h"

namespace hazelcast {
namespace client {
namespace serialization {
namespace pimpl {

struct compact_util
{
compact_util() = delete;

static exception::hazelcast_serialization
exception_for_unexpected_null_value(const std::string& field_name,
const std::string& method_prefix,
const std::string& method_suffix);

static exception::hazelcast_serialization
exception_for_unexpected_null_value_in_array(
const std::string& field_name,
const std::string& method_prefix,
const std::string& method_suffix);
};

} // namespace pimpl
} // namespace serialization
} // namespace client
} // namespace hazelcast
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ class HAZELCAST_API schema
size_t fixed_size_fields_length() const;
const std::string& type_name() const;
const std::unordered_map<std::string, field_descriptor>& fields() const;
boost::optional<field_descriptor> get_field(
const std::string& field_name) const;

private:
std::string type_name_;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (c) 2008-2023, Hazelcast, Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#include "hazelcast/client/serialization/pimpl/compact/schema.h"

namespace hazelcast {
namespace client {
namespace serialization {
namespace pimpl {

class HAZELCAST_API schema_writer
{
public:
explicit schema_writer(std::string type_name);
void add_field(std::string field_name, enum field_kind kind);
schema build() &&;

private:
std::unordered_map<std::string, field_descriptor> field_definition_map_;
std::string type_name_;
};

} // namespace pimpl
} // namespace serialization
} // namespace client
} // namespace hazelcast
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "hazelcast/client/serialization/pimpl/data_input.h"
#include "hazelcast/client/serialization/pimpl/data.h"
#include "hazelcast/client/serialization/pimpl/data_output.h"
#include "hazelcast/client/serialization/generic_record.h"
#include "hazelcast/client/serialization_config.h"
#include "hazelcast/client/partition_aware.h"
#include "hazelcast/util/SynchronizedMap.h"
Expand Down Expand Up @@ -818,6 +819,12 @@ class HAZELCAST_API object_data_input
std::is_base_of<custom_serializer, hz_serializer<T>>::value,
boost::optional<T>>::type inline read_object(int32_t type_id);

template<typename T>
Comment thread
akeles85 marked this conversation as resolved.
typename std::enable_if<
std::is_same<generic_record::generic_record, T>::value,
boost::optional<T>>::type
read_object(int32_t type_id);

/**
* Global serialization
* @tparam T The type to be deserialized to
Expand All @@ -830,7 +837,8 @@ class HAZELCAST_API object_data_input
std::is_base_of<portable_serializer, hz_serializer<T>>::value ||
std::is_base_of<compact::compact_serializer, hz_serializer<T>>::value ||
std::is_base_of<builtin_serializer, hz_serializer<T>>::value ||
std::is_base_of<custom_serializer, hz_serializer<T>>::value),
std::is_base_of<custom_serializer, hz_serializer<T>>::value ||
std::is_same<generic_record::generic_record, T>::value),
boost::optional<T>>::type inline read_object(int32_t type_id);

private:
Expand Down Expand Up @@ -890,6 +898,11 @@ class HAZELCAST_API object_data_output : public pimpl::data_output
std::is_base_of<portable_serializer, hz_serializer<T>>::value,
void>::type inline write_object(const T& object);

template<typename T>
typename std::enable_if<
std::is_same<generic_record::generic_record, T>::value>::type
write_object(const T& object);

template<typename T>
typename std::enable_if<
std::is_base_of<compact::compact_serializer, hz_serializer<T>>::value,
Expand All @@ -907,6 +920,7 @@ class HAZELCAST_API object_data_output : public pimpl::data_output
std::is_base_of<portable_serializer, hz_serializer<T>>::value ||
std::is_base_of<compact::compact_serializer, hz_serializer<T>>::value ||
std::is_base_of<custom_serializer, hz_serializer<T>>::value ||
std::is_same<generic_record::generic_record, T>::value ||
(std::is_array<T>::value &&
std::is_same<typename std::remove_all_extents<T>::type, char>::value)),
void>::type inline write_object(const T object);
Expand Down Expand Up @@ -2359,6 +2373,24 @@ typename std::enable_if<
hz_serializer<T>::write(object, *this);
}

template<typename T>
typename std::enable_if<
std::is_same<generic_record::generic_record, T>::value>::type
object_data_output::write_object(const T& object)
{
if (is_no_write_) {
return;
}

const auto& record =
static_cast<const generic_record::generic_record&>(object);

write(static_cast<int32_t>(
pimpl::serialization_constants::CONSTANT_TYPE_COMPACT),
boost::endian::order::big);
compact_serializer_->write_generic_record(record, *this);
}

/**
* Global serialization if configured
* @tparam T
Expand All @@ -2372,6 +2404,7 @@ typename std::enable_if<
std::is_base_of<portable_serializer, hz_serializer<T>>::value ||
std::is_base_of<compact::compact_serializer, hz_serializer<T>>::value ||
std::is_base_of<custom_serializer, hz_serializer<T>>::value ||
std::is_same<generic_record::generic_record, T>::value ||
(std::is_array<T>::value &&
std::is_same<typename std::remove_all_extents<T>::type, char>::value)),
void>::type inline object_data_output::write_object(const T object)
Expand Down Expand Up @@ -2493,13 +2526,22 @@ typename std::enable_if<
return boost::optional<T>(read<T>());
}

template<typename T>
typename std::enable_if<std::is_same<generic_record::generic_record, T>::value,
boost::optional<T>>::type
object_data_input::read_object(int32_t type_id)
{
return compact_serializer_.read_generic_record(*this);
}

template<typename T>
typename std::enable_if<
!(std::is_base_of<identified_data_serializer, hz_serializer<T>>::value ||
std::is_base_of<portable_serializer, hz_serializer<T>>::value ||
std::is_base_of<compact::compact_serializer, hz_serializer<T>>::value ||
std::is_base_of<builtin_serializer, hz_serializer<T>>::value ||
std::is_base_of<custom_serializer, hz_serializer<T>>::value),
std::is_base_of<custom_serializer, hz_serializer<T>>::value ||
std::is_same<generic_record::generic_record, T>::value),
boost::optional<T>>::type inline object_data_input::read_object(int32_t
type_id)
{
Expand Down
Loading