From 81bdcb1d6ee55234f7d9b1d2d7e32f30061044e7 Mon Sep 17 00:00:00 2001 From: sancar Date: Mon, 8 Feb 2016 15:23:09 +0200 Subject: [PATCH] CustomSerialized classes don't have to implement getTypeId inside class renamed getTypeId to getHazelcastTypeId to avoid collisions with user functuins Remove singleton usage of SerializationConstants to avoid thread safety issues getTypeId method should be provided as free function. This way, user can serialize classes that it can not change. CHECK_NULL in SerializationService header moved to source file since MACRO's can collide with users MACRO when defined in header. A example code is provided for custom serialization. Related test codes are modified for custom serialization. For threads safety, instance of SerializationConstants is created in global space. ClassCastException for portable identified and custom serializable is added. --- examples/serialization/CMakeLists.txt | 1 + examples/serialization/custom/CMakeLists.txt | 17 ++++ examples/serialization/custom/main.cpp | 89 +++++++++++++++++ .../IdentifiedDataSerializable.h | 10 +- .../client/serialization/ObjectDataInput.h | 9 +- .../client/serialization/ObjectDataOutput.h | 13 +-- .../hazelcast/client/serialization/Portable.h | 9 +- .../client/serialization/Serializer.h | 24 +++-- .../hazelcast/client/serialization/TypeIDS.h} | 21 ++-- .../serialization/pimpl/PortableContext.h | 9 +- .../pimpl/SerializationConstants.h | 54 +++++------ .../pimpl/SerializationService.h | 34 ++----- hazelcast/include/hazelcast/util/IOUtil.h | 12 --- ...tifiedDataSerializable.cpp => TypeIDS.cpp} | 16 ++-- .../client/serialization/pimpl/Data.cpp | 2 +- .../serialization/pimpl/PortableContext.cpp | 9 +- .../pimpl/SerializationConstants.cpp | 50 ++++------ .../pimpl/SerializationService.cpp | 95 ++++++++----------- .../serialization/pimpl/SerializerHolder.cpp | 2 +- .../TestCustomPersonSerializer.cpp | 2 +- .../TestCustomPersonSerializer.h | 2 +- .../TestCustomSerializerX.h | 2 +- .../TestCustomXSerializable.cpp | 4 +- .../TestCustomXSerializable.h | 12 +-- 24 files changed, 280 insertions(+), 218 deletions(-) create mode 100644 examples/serialization/custom/CMakeLists.txt create mode 100644 examples/serialization/custom/main.cpp rename hazelcast/{src/hazelcast/client/serialization/Portable.cpp => include/hazelcast/client/serialization/TypeIDS.h} (65%) rename hazelcast/src/hazelcast/client/serialization/{IdentifiedDataSerializable.cpp => TypeIDS.cpp} (68%) diff --git a/examples/serialization/CMakeLists.txt b/examples/serialization/CMakeLists.txt index 2331c5046f..5b7b676400 100644 --- a/examples/serialization/CMakeLists.txt +++ b/examples/serialization/CMakeLists.txt @@ -15,3 +15,4 @@ # add_subdirectory(identified-data-serializable) add_subdirectory(portable) +add_subdirectory(custom) diff --git a/examples/serialization/custom/CMakeLists.txt b/examples/serialization/custom/CMakeLists.txt new file mode 100644 index 0000000000..6a7f061bd0 --- /dev/null +++ b/examples/serialization/custom/CMakeLists.txt @@ -0,0 +1,17 @@ +# +# Copyright (c) 2008-2015, 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. +# +add_executable(custom ./main.cpp) + diff --git a/examples/serialization/custom/main.cpp b/examples/serialization/custom/main.cpp new file mode 100644 index 0000000000..395d2f46e2 --- /dev/null +++ b/examples/serialization/custom/main.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2008-2015, 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. + */ +#include +#include +#include +#include + +class Person { +public: + Person() { + } + + Person(const std::string& n) : name(n) { + } + + void setName(const std::string& n) { + name = n; + } + + + const std::string& getName() const { + return name; + } + +private: + std::string name; +}; + +int getHazelcastTypeId(const Person* p){ + return 666; +} + +class CustomSerializer : public hazelcast::client::serialization::Serializer { +public: + + void write(hazelcast::client::serialization::ObjectDataOutput & out, const Person& object) { + out.writeInt(666); + out.writeUTF(&(object.getName())); + out.writeInt(666); + } + + void read(hazelcast::client::serialization::ObjectDataInput & in, Person& object) { + int i = in.readInt(); + assert(i == 666); + object.setName(*(in.readUTF())); + i = in.readInt(); + assert(i == 666); + } + + int getHazelcastTypeId() const { + return 666; + }; +}; + +std::ostream &operator<<(std::ostream &out, const Person &p) { + const std::string & str = p.getName(); + out << str; + return out; +} + +int main() { + hazelcast::client::ClientConfig config; + hazelcast::client::SerializationConfig serializationConfig; + serializationConfig.registerSerializer(boost::shared_ptr(new CustomSerializer())); + config.setSerializationConfig(serializationConfig); + hazelcast::client::HazelcastClient hz(config); + + hazelcast::client::IMap map = hz.getMap("map"); + Person testPerson("bar"); + map.put("foo", testPerson); + std::cout << *(map.get("foo")) << std::endl; + std::cout << "Finished" << std::endl; + + return 0; +} + diff --git a/hazelcast/include/hazelcast/client/serialization/IdentifiedDataSerializable.h b/hazelcast/include/hazelcast/client/serialization/IdentifiedDataSerializable.h index 62e37b9b7e..4020f911e4 100644 --- a/hazelcast/include/hazelcast/client/serialization/IdentifiedDataSerializable.h +++ b/hazelcast/include/hazelcast/client/serialization/IdentifiedDataSerializable.h @@ -44,7 +44,9 @@ namespace hazelcast { /** * Destructor */ - virtual ~IdentifiedDataSerializable(); + virtual ~IdentifiedDataSerializable(){ + + } /** * @return factory id @@ -68,12 +70,6 @@ namespace hazelcast { */ virtual void readData(ObjectDataInput &reader) = 0; - /** - * Not public api. Do not override this method. - * @return serializer id - */ - virtual int getSerializerId() const; - }; } diff --git a/hazelcast/include/hazelcast/client/serialization/ObjectDataInput.h b/hazelcast/include/hazelcast/client/serialization/ObjectDataInput.h index 2998d1aa1c..f0eeed56c7 100644 --- a/hazelcast/include/hazelcast/client/serialization/ObjectDataInput.h +++ b/hazelcast/include/hazelcast/client/serialization/ObjectDataInput.h @@ -32,6 +32,7 @@ #include "hazelcast/client/exception/HazelcastSerializationException.h" #include "hazelcast/client/serialization/pimpl/SerializationConstants.h" #include "hazelcast/util/IOUtil.h" +#include "hazelcast/client/serialization/TypeIDS.h" #include #include #include @@ -196,13 +197,15 @@ namespace hazelcast { template boost::shared_ptr readObject() { int typeId = readInt(); - if (pimpl::SerializationConstants::getInstance()->CONSTANT_TYPE_NULL == typeId) { + const pimpl::SerializationConstants& constants = portableContext.getConstants(); + if (constants.CONSTANT_TYPE_NULL == typeId) { return boost::shared_ptr(static_cast(NULL)); } else { std::auto_ptr result(new T); - if (pimpl::SerializationConstants::getInstance()->CONSTANT_TYPE_DATA == typeId) { + constants.checkClassType(getHazelcastTypeId(result.get()) , typeId); + if (constants.CONSTANT_TYPE_DATA == typeId) { readDataSerializable(reinterpret_cast(result.get())); - } else if (pimpl::SerializationConstants::getInstance()->CONSTANT_TYPE_PORTABLE == typeId) { + } else if (constants.CONSTANT_TYPE_PORTABLE == typeId) { readPortable(reinterpret_cast(result.get())); } else { readInternal(typeId, result.get()); diff --git a/hazelcast/include/hazelcast/client/serialization/ObjectDataOutput.h b/hazelcast/include/hazelcast/client/serialization/ObjectDataOutput.h index ee942379b6..26ed50b2cb 100644 --- a/hazelcast/include/hazelcast/client/serialization/ObjectDataOutput.h +++ b/hazelcast/include/hazelcast/client/serialization/ObjectDataOutput.h @@ -25,6 +25,7 @@ #include "hazelcast/client/serialization/pimpl/PortableContext.h" #include "hazelcast/client/serialization/Serializer.h" #include "hazelcast/util/IOUtil.h" +#include "hazelcast/client/serialization/TypeIDS.h" #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) #pragma warning(push) @@ -168,9 +169,9 @@ namespace hazelcast { if (isEmpty) return; if (NULL == object) { - writeInt(pimpl::SerializationConstants::getInstance()->CONSTANT_TYPE_NULL); + writeInt(pimpl::SerializationConstants::CONSTANT_TYPE_NULL); } else { - writeInt(pimpl::SerializationConstants::getInstance()->CONSTANT_TYPE_PORTABLE); + writeInt(pimpl::SerializationConstants::CONSTANT_TYPE_PORTABLE); writeInt(object->getFactoryId()); writeInt(object->getClassId()); @@ -189,9 +190,9 @@ namespace hazelcast { if (isEmpty) return; if (NULL == object) { - writeInt(pimpl::SerializationConstants::getInstance()->CONSTANT_TYPE_NULL); + writeInt(pimpl::SerializationConstants::CONSTANT_TYPE_NULL); } else { - writeInt(pimpl::SerializationConstants::getInstance()->CONSTANT_TYPE_DATA); + writeInt(pimpl::SerializationConstants::CONSTANT_TYPE_DATA); context->getSerializerHolder().getDataSerializer().write(*this, *object); } } @@ -206,10 +207,10 @@ namespace hazelcast { if (isEmpty) return; if (NULL == serializable) { - writeInt(pimpl::SerializationConstants::getInstance()->CONSTANT_TYPE_NULL); + writeInt(pimpl::SerializationConstants::CONSTANT_TYPE_NULL); } else { const T *object = static_cast(serializable); - int type = object->getTypeId(); + int type = getHazelcastTypeId(object); writeInt(type); boost::shared_ptr serializer = context->getSerializerHolder().serializerFor(type); diff --git a/hazelcast/include/hazelcast/client/serialization/Portable.h b/hazelcast/include/hazelcast/client/serialization/Portable.h index 56cfd1c692..96adbef950 100644 --- a/hazelcast/include/hazelcast/client/serialization/Portable.h +++ b/hazelcast/include/hazelcast/client/serialization/Portable.h @@ -54,7 +54,9 @@ namespace hazelcast { /** * Destructor */ - virtual ~Portable(); + virtual ~Portable(){ + + } /** * @return factory id @@ -78,11 +80,6 @@ namespace hazelcast { */ virtual void readPortable(PortableReader& reader) = 0; - /** - * Not public api. Do not override this method. - * @return serializer id - */ - virtual int getSerializerId() const; }; } } diff --git a/hazelcast/include/hazelcast/client/serialization/Serializer.h b/hazelcast/include/hazelcast/client/serialization/Serializer.h index 361b08031b..8c3841775c 100644 --- a/hazelcast/include/hazelcast/client/serialization/Serializer.h +++ b/hazelcast/include/hazelcast/client/serialization/Serializer.h @@ -16,9 +16,6 @@ // // Created by sancar koyunlu on 6/7/13. - - - #ifndef HAZELCAST_TYPE_SERIALIZER #define HAZELCAST_TYPE_SERIALIZER @@ -43,13 +40,14 @@ namespace hazelcast { /** * unique type id for this serializer. It will be used to decide which serializer needs to be used - * for your classes. Also not that your serialized classes needs to implement + * for your classes. Also not that for your serialized classes you need to implement as free function + * in same namespace with your class * - * int getTypeId(); + * int getHazelcastTypeId(const MyClass*); * * which should return same id with its serializer. */ - virtual int getTypeId() const = 0; + virtual int getHazelcastTypeId() const = 0; }; /** @@ -64,7 +62,7 @@ namespace hazelcast { void read(serialization::ObjectDataInput & in, ExampleBaseClass& object); - int getTypeId() const; + int getHazelcastTypeId() const; }; } @@ -86,16 +84,24 @@ namespace hazelcast { //..... } - int getTypeId() const { + int getHazelcastTypeId() const { //.. } }; + * + * Along with serializer following function should be provided with same namespace that ExampleBaseClass + * belongs to + * + * int getHazelcastTypeId(const MyClass*); + * + * which should return same id with its serializer. * * User than can register serializer via SerializationConfig as follows * - clientConfig.getSerializationConfig().registerSerializer(new MyCustomSerializer()); + clientConfig.getSerializationConfig().registerSerializer( + boost::shared_ptr(new MyCustomSerializer()); */ template diff --git a/hazelcast/src/hazelcast/client/serialization/Portable.cpp b/hazelcast/include/hazelcast/client/serialization/TypeIDS.h similarity index 65% rename from hazelcast/src/hazelcast/client/serialization/Portable.cpp rename to hazelcast/include/hazelcast/client/serialization/TypeIDS.h index 188f82d32e..1f9c784cf4 100644 --- a/hazelcast/src/hazelcast/client/serialization/Portable.cpp +++ b/hazelcast/include/hazelcast/client/serialization/TypeIDS.h @@ -13,24 +13,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -// -// Created by sancar koyunlu on 8/12/13. +#ifndef HAZELCAST_TypeIDS +#define HAZELCAST_TypeIDS - -#include "hazelcast/client/serialization/Portable.h" -#include "hazelcast/client/serialization/pimpl/SerializationConstants.h" +#include "hazelcast/util/HazelcastDll.h" namespace hazelcast { namespace client { namespace serialization { - Portable::~Portable() { + class Portable; + class IdentifiedDataSerializable; + + int HAZELCAST_API getHazelcastTypeId(const Portable* portable); - } + int HAZELCAST_API getHazelcastTypeId(const IdentifiedDataSerializable* identifiedDataSerializable); - int Portable::getSerializerId() const { - return pimpl::SerializationConstants::getInstance()->CONSTANT_TYPE_PORTABLE; - } } } } + + +#endif //HAZELCAST_TypeIDS diff --git a/hazelcast/include/hazelcast/client/serialization/pimpl/PortableContext.h b/hazelcast/include/hazelcast/client/serialization/pimpl/PortableContext.h index 815ba79865..f3be3cb224 100644 --- a/hazelcast/include/hazelcast/client/serialization/pimpl/PortableContext.h +++ b/hazelcast/include/hazelcast/client/serialization/pimpl/PortableContext.h @@ -48,10 +48,12 @@ namespace hazelcast { class ClassDefinitionContext; + class SerializationConstants; + class HAZELCAST_API PortableContext { public: - PortableContext(int); + PortableContext(int version,const SerializationConstants& constants); int getClassVersion(int factoryId, int classId); @@ -69,6 +71,9 @@ namespace hazelcast { SerializerHolder &getSerializerHolder(); + + SerializationConstants const& getConstants() const; + private: PortableContext(const PortableContext &); @@ -80,7 +85,7 @@ namespace hazelcast { int contextVersion; util::SynchronizedMap classDefContextMap; SerializerHolder serializerHolder; - + const SerializationConstants& constants; }; } } diff --git a/hazelcast/include/hazelcast/client/serialization/pimpl/SerializationConstants.h b/hazelcast/include/hazelcast/client/serialization/pimpl/SerializationConstants.h index 8ed33201bf..42e0e80122 100644 --- a/hazelcast/include/hazelcast/client/serialization/pimpl/SerializationConstants.h +++ b/hazelcast/include/hazelcast/client/serialization/pimpl/SerializationConstants.h @@ -39,41 +39,39 @@ namespace hazelcast { namespace pimpl { class HAZELCAST_API SerializationConstants { public: - int const CONSTANT_TYPE_NULL; - int const CONSTANT_TYPE_PORTABLE; - int const CONSTANT_TYPE_DATA; - int const CONSTANT_TYPE_BYTE; - int const CONSTANT_TYPE_BOOLEAN; - int const CONSTANT_TYPE_CHAR; - int const CONSTANT_TYPE_SHORT; - int const CONSTANT_TYPE_INTEGER; - int const CONSTANT_TYPE_LONG; - int const CONSTANT_TYPE_FLOAT; - int const CONSTANT_TYPE_DOUBLE; - int const CONSTANT_TYPE_STRING; - int const CONSTANT_TYPE_BYTE_ARRAY; - int const CONSTANT_TYPE_BOOLEAN_ARRAY; - int const CONSTANT_TYPE_CHAR_ARRAY; - int const CONSTANT_TYPE_SHORT_ARRAY; - int const CONSTANT_TYPE_INTEGER_ARRAY; - int const CONSTANT_TYPE_LONG_ARRAY; - int const CONSTANT_TYPE_FLOAT_ARRAY; - int const CONSTANT_TYPE_DOUBLE_ARRAY; - int const CONSTANT_TYPE_STRING_ARRAY; + SerializationConstants(); + + static int const CONSTANT_TYPE_NULL = 0; + static int const CONSTANT_TYPE_PORTABLE = -1; + static int const CONSTANT_TYPE_DATA = -2; + static int const CONSTANT_TYPE_BYTE = -3; + static int const CONSTANT_TYPE_BOOLEAN = -4; + static int const CONSTANT_TYPE_CHAR = -5; + static int const CONSTANT_TYPE_SHORT = -6; + static int const CONSTANT_TYPE_INTEGER = -7; + static int const CONSTANT_TYPE_LONG = -8; + static int const CONSTANT_TYPE_FLOAT = -9; + static int const CONSTANT_TYPE_DOUBLE = -10; + static int const CONSTANT_TYPE_STRING = -11; + static int const CONSTANT_TYPE_BYTE_ARRAY = -12; + static int const CONSTANT_TYPE_BOOLEAN_ARRAY = -13; + static int const CONSTANT_TYPE_CHAR_ARRAY = -14; + static int const CONSTANT_TYPE_SHORT_ARRAY = -15; + static int const CONSTANT_TYPE_INTEGER_ARRAY = -16; + static int const CONSTANT_TYPE_LONG_ARRAY = -17; + static int const CONSTANT_TYPE_FLOAT_ARRAY = -18; + static int const CONSTANT_TYPE_DOUBLE_ARRAY = -19; + static int const CONSTANT_TYPE_STRING_ARRAY = -20; // ------------------------------------------------------------ - std::string typeIdToName(int typeId); + void checkClassType(int expectedType, int currentType) const; - static SerializationConstants *getInstance(); private: const int size; std::vector typeIdNameVector; - static SerializationConstants *instance; - - SerializationConstants(); - - int idToIndex(int id); + int idToIndex(int id) const; + std::string typeIdToName(int typeId) const; }; } } diff --git a/hazelcast/include/hazelcast/client/serialization/pimpl/SerializationService.h b/hazelcast/include/hazelcast/client/serialization/pimpl/SerializationService.h index f91421d8bd..1342ceb01c 100644 --- a/hazelcast/include/hazelcast/client/serialization/pimpl/SerializationService.h +++ b/hazelcast/include/hazelcast/client/serialization/pimpl/SerializationService.h @@ -56,10 +56,6 @@ namespace hazelcast { namespace pimpl { class HAZELCAST_API SerializationService { public: - #define CHECK_NULL(type) \ - if (isNullData(data)) { \ - return boost::shared_ptr(); \ - }\ SerializationService(const SerializationConfig& serializationConfig); @@ -77,7 +73,7 @@ namespace hazelcast { writeHash(output); - writeObject(dataOutput, object); + dataOutput.writeObject(object); Data data(output.toByteArray()); return data; @@ -93,46 +89,32 @@ namespace hazelcast { template inline boost::shared_ptr toObject(const Data &data) { - CHECK_NULL(T); + if (isNullData(data)) { + return boost::shared_ptr(); + } // Constant 4 is Data::TYPE_OFFSET. Windows DLL export does not // let usage of static member. DataInput dataInput(data.toByteArray(), 4); - return readObject(dataInput); + ObjectDataInput objectDataInput(dataInput, portableContext); + return objectDataInput.readObject(); } - PortableContext &getPortableContext(); - const byte getVersion() const; private: - template - inline boost::shared_ptr readObject(DataInput &data) { - ObjectDataInput dataInput(data, portableContext); - return dataInput.readObject(); - } - - template - inline void writeObject(ObjectDataOutput &dataOutput, const T *object) { - dataOutput.writeObject(object); - } - SerializerHolder &getSerializerHolder(); - boost::shared_ptr serializerFor(int typeId); - SerializationService(const SerializationService &); SerializationService &operator = (const SerializationService &); + SerializationConstants constants; PortableContext portableContext; - const SerializationConfig& serializationConfig; - void checkClassType(int expectedType, int currentType); - - static bool isNullData(const Data &data); + bool isNullData(const Data &data); void writeHash(DataOutput &out); }; diff --git a/hazelcast/include/hazelcast/util/IOUtil.h b/hazelcast/include/hazelcast/util/IOUtil.h index 0cd4cff168..2f5ccf91f0 100644 --- a/hazelcast/include/hazelcast/util/IOUtil.h +++ b/hazelcast/include/hazelcast/util/IOUtil.h @@ -48,18 +48,6 @@ namespace hazelcast { static void closeResource(Closeable *closable); - enum PRIMITIVE_ID { - PRIMITIVE_TYPE_BOOLEAN = 1, - PRIMITIVE_TYPE_BYTE = 2, - PRIMITIVE_TYPE_SHORT = 3, - PRIMITIVE_TYPE_INTEGER = 4, - PRIMITIVE_TYPE_LONG = 5, - PRIMITIVE_TYPE_FLOAT = 6, - PRIMITIVE_TYPE_DOUBLE = 7, - PRIMITIVE_TYPE_UTF = 8, - PRIMITIVE_TYPE_NULL = 9 - }; - }; } } diff --git a/hazelcast/src/hazelcast/client/serialization/IdentifiedDataSerializable.cpp b/hazelcast/src/hazelcast/client/serialization/TypeIDS.cpp similarity index 68% rename from hazelcast/src/hazelcast/client/serialization/IdentifiedDataSerializable.cpp rename to hazelcast/src/hazelcast/client/serialization/TypeIDS.cpp index e3365b251f..8590d0804b 100644 --- a/hazelcast/src/hazelcast/client/serialization/IdentifiedDataSerializable.cpp +++ b/hazelcast/src/hazelcast/client/serialization/TypeIDS.cpp @@ -14,23 +14,23 @@ * limitations under the License. */ // -// Created by sancar koyunlu on 8/12/13. - - -#include "hazelcast/client/serialization/IdentifiedDataSerializable.h" +#include "hazelcast/client/serialization/TypeIDS.h" #include "hazelcast/client/serialization/pimpl/SerializationConstants.h" +#include "hazelcast/client/serialization/IdentifiedDataSerializable.h" +#include "hazelcast/client/serialization/Portable.h" namespace hazelcast { namespace client { namespace serialization { - IdentifiedDataSerializable::~IdentifiedDataSerializable() { - + int getHazelcastTypeId(const Portable* portable) { + return pimpl::SerializationConstants::CONSTANT_TYPE_PORTABLE; } - int IdentifiedDataSerializable::getSerializerId() const { - return pimpl::SerializationConstants::getInstance()->CONSTANT_TYPE_DATA; + int getHazelcastTypeId(const IdentifiedDataSerializable* identifiedDataSerializable) { + return pimpl::SerializationConstants::CONSTANT_TYPE_DATA; } } } } + diff --git a/hazelcast/src/hazelcast/client/serialization/pimpl/Data.cpp b/hazelcast/src/hazelcast/client/serialization/pimpl/Data.cpp index cba4b570e0..3e809c9a04 100644 --- a/hazelcast/src/hazelcast/client/serialization/pimpl/Data.cpp +++ b/hazelcast/src/hazelcast/client/serialization/pimpl/Data.cpp @@ -96,7 +96,7 @@ namespace hazelcast { int Data::getType() const { if (totalSize() == 0) { - return SerializationConstants::getInstance()->CONSTANT_TYPE_NULL; + return SerializationConstants::CONSTANT_TYPE_NULL; } return Bits::readIntB(*data, Data::TYPE_OFFSET); } diff --git a/hazelcast/src/hazelcast/client/serialization/pimpl/PortableContext.cpp b/hazelcast/src/hazelcast/client/serialization/pimpl/PortableContext.cpp index 6afc53ce38..d1d9fbd8f8 100644 --- a/hazelcast/src/hazelcast/client/serialization/pimpl/PortableContext.cpp +++ b/hazelcast/src/hazelcast/client/serialization/pimpl/PortableContext.cpp @@ -38,8 +38,8 @@ namespace hazelcast { namespace client { namespace serialization { namespace pimpl { - PortableContext::PortableContext(int version) - : contextVersion(version), serializerHolder(*this){ + PortableContext::PortableContext(int version, const SerializationConstants& constants) + : contextVersion(version), serializerHolder(*this) , constants(constants){ } @@ -144,6 +144,11 @@ namespace hazelcast { return serializerHolder; } + + SerializationConstants const& PortableContext::getConstants() const { + return constants; + } + ClassDefinitionContext& PortableContext::getClassDefinitionContext(int factoryId) { boost::shared_ptr value = classDefContextMap.get(factoryId); if (value == NULL) { diff --git a/hazelcast/src/hazelcast/client/serialization/pimpl/SerializationConstants.cpp b/hazelcast/src/hazelcast/client/serialization/pimpl/SerializationConstants.cpp index 7d06466f0a..3b363d04ac 100644 --- a/hazelcast/src/hazelcast/client/serialization/pimpl/SerializationConstants.cpp +++ b/hazelcast/src/hazelcast/client/serialization/pimpl/SerializationConstants.cpp @@ -18,36 +18,16 @@ // #include "hazelcast/client/serialization/pimpl/SerializationConstants.h" +#include "hazelcast/util/Util.h" +#include "hazelcast/util/ILogger.h" +#include "hazelcast/client/exception/IClassCastException.h" namespace hazelcast { namespace client { namespace serialization { namespace pimpl { - SerializationConstants *SerializationConstants::instance = NULL; - SerializationConstants::SerializationConstants() - : CONSTANT_TYPE_NULL(0) - , CONSTANT_TYPE_PORTABLE(-1) - , CONSTANT_TYPE_DATA(-2) - , CONSTANT_TYPE_BYTE(-3) - , CONSTANT_TYPE_BOOLEAN(-4) - , CONSTANT_TYPE_CHAR(-5) - , CONSTANT_TYPE_SHORT(-6) - , CONSTANT_TYPE_INTEGER(-7) - , CONSTANT_TYPE_LONG(-8) - , CONSTANT_TYPE_FLOAT(-9) - , CONSTANT_TYPE_DOUBLE(-10) - , CONSTANT_TYPE_STRING(-11) - , CONSTANT_TYPE_BYTE_ARRAY(-12) - , CONSTANT_TYPE_BOOLEAN_ARRAY(-13) - , CONSTANT_TYPE_CHAR_ARRAY(-14) - , CONSTANT_TYPE_SHORT_ARRAY(-15) - , CONSTANT_TYPE_INTEGER_ARRAY(-16) - , CONSTANT_TYPE_LONG_ARRAY(-17) - , CONSTANT_TYPE_FLOAT_ARRAY(-18) - , CONSTANT_TYPE_DOUBLE_ARRAY(-19) - , CONSTANT_TYPE_STRING_ARRAY(-20) - , size(21) + : size(21) , typeIdNameVector(size){ typeIdNameVector[idToIndex(CONSTANT_TYPE_NULL)] = "null"; typeIdNameVector[idToIndex(CONSTANT_TYPE_PORTABLE)] = "portable"; @@ -72,23 +52,29 @@ namespace hazelcast { typeIdNameVector[idToIndex(CONSTANT_TYPE_STRING_ARRAY)] = "stringArray"; } - std::string SerializationConstants::typeIdToName(int typeId) { + std::string SerializationConstants::typeIdToName(int typeId) const{ int i = idToIndex(typeId); if (i < 0 || i >= size) return std::string("custom"); return typeIdNameVector[i]; } - int SerializationConstants::idToIndex(int id) { - return id + size - 1; - } + void SerializationConstants::checkClassType(int expectedType, int currentType) const{ + if (expectedType != currentType) { + char message[200]; + util::snprintf(message, 200, "Received data of type %s(%d) but expected data type %s(%d)", + typeIdToName(currentType).c_str(), currentType, + typeIdToName(expectedType).c_str(), expectedType); - SerializationConstants *SerializationConstants::getInstance() { - if (NULL == instance) { - instance = new SerializationConstants(); + util::ILogger::getLogger().severe(message); + throw exception::IClassCastException("SerializationConstants::checkClassType",message); } - return instance; } + + int SerializationConstants::idToIndex(int id) const{ + return id + size - 1; + } + } } } diff --git a/hazelcast/src/hazelcast/client/serialization/pimpl/SerializationService.cpp b/hazelcast/src/hazelcast/client/serialization/pimpl/SerializationService.cpp index 5abc3ec336..cbc9442d1a 100644 --- a/hazelcast/src/hazelcast/client/serialization/pimpl/SerializationService.cpp +++ b/hazelcast/src/hazelcast/client/serialization/pimpl/SerializationService.cpp @@ -31,8 +31,13 @@ namespace hazelcast { namespace client { namespace serialization { namespace pimpl { + #define CHECK_NULL(type) \ + if (isNullData(data)) { \ + return boost::shared_ptr(); \ + } + SerializationService::SerializationService(const SerializationConfig& serializationConfig) - : portableContext(serializationConfig.getPortableVersion()) + : portableContext(serializationConfig.getPortableVersion(), constants) , serializationConfig(serializationConfig) { std::vector > const& serializers = serializationConfig.getSerializers(); std::vector >::const_iterator it; @@ -42,10 +47,6 @@ namespace hazelcast { } } - PortableContext& SerializationService::getPortableContext() { - return portableContext; - } - SerializerHolder& SerializationService::getSerializerHolder() { return portableContext.getSerializerHolder(); } @@ -55,22 +56,8 @@ namespace hazelcast { return getSerializerHolder().registerSerializer(serializer); } - void SerializationService::checkClassType(int expectedType, int currentType) { - if (expectedType != currentType) { - char message[200]; - SerializationConstants *sc = SerializationConstants::getInstance(); - util::snprintf(message, 200, "Received data of type %s(%d) but expected data type %s(%d)", - sc->typeIdToName(currentType).c_str(), currentType, - sc->typeIdToName(expectedType).c_str(), expectedType); - - util::ILogger::getLogger().severe(message); - throw exception::IClassCastException("SerializationService::checkClassType", - message); - } - } - bool SerializationService::isNullData(const Data &data) { - return data.dataSize() == 0 && data.getType() == SerializationConstants::getInstance()->CONSTANT_TYPE_NULL; + return data.dataSize() == 0 && data.getType() == SerializationConstants::CONSTANT_TYPE_NULL; } void SerializationService::writeHash(DataOutput &out) { @@ -86,7 +73,7 @@ namespace hazelcast { writeHash(output); // write type - output.writeInt(SerializationConstants::getInstance()->CONSTANT_TYPE_BYTE); + output.writeInt(SerializationConstants::CONSTANT_TYPE_BYTE); output.writeByte(*object); @@ -103,7 +90,7 @@ namespace hazelcast { writeHash(output); // write type - output.writeInt(SerializationConstants::getInstance()->CONSTANT_TYPE_BOOLEAN); + output.writeInt(SerializationConstants::CONSTANT_TYPE_BOOLEAN); output.writeBoolean(*object); @@ -120,7 +107,7 @@ namespace hazelcast { writeHash(output); // write type - output.writeInt(SerializationConstants::getInstance()->CONSTANT_TYPE_CHAR); + output.writeInt(SerializationConstants::CONSTANT_TYPE_CHAR); output.writeChar(*object); @@ -137,7 +124,7 @@ namespace hazelcast { writeHash(output); // write type - output.writeInt(SerializationConstants::getInstance()->CONSTANT_TYPE_SHORT); + output.writeInt(SerializationConstants::CONSTANT_TYPE_SHORT); output.writeShort(*object); @@ -154,7 +141,7 @@ namespace hazelcast { writeHash(output); // write type - output.writeInt(SerializationConstants::getInstance()->CONSTANT_TYPE_INTEGER); + output.writeInt(SerializationConstants::CONSTANT_TYPE_INTEGER); output.writeInt(*object); @@ -171,7 +158,7 @@ namespace hazelcast { writeHash(output); // write type - output.writeInt(SerializationConstants::getInstance()->CONSTANT_TYPE_LONG); + output.writeInt(SerializationConstants::CONSTANT_TYPE_LONG); output.writeLong(*object); @@ -188,7 +175,7 @@ namespace hazelcast { writeHash(output); // write type - output.writeInt(SerializationConstants::getInstance()->CONSTANT_TYPE_FLOAT); + output.writeInt(SerializationConstants::CONSTANT_TYPE_FLOAT); output.writeFloat(*object); @@ -205,7 +192,7 @@ namespace hazelcast { writeHash(output); // write type - output.writeInt(SerializationConstants::getInstance()->CONSTANT_TYPE_DOUBLE); + output.writeInt(SerializationConstants::CONSTANT_TYPE_DOUBLE); output.writeDouble(*object); @@ -221,7 +208,7 @@ namespace hazelcast { writeHash(output); // write type - output.writeInt(SerializationConstants::getInstance()->CONSTANT_TYPE_CHAR_ARRAY); + output.writeInt(SerializationConstants::CONSTANT_TYPE_CHAR_ARRAY); output.writeCharArray(object); @@ -237,7 +224,7 @@ namespace hazelcast { writeHash(output); // write type - output.writeInt(SerializationConstants::getInstance()->CONSTANT_TYPE_BOOLEAN_ARRAY); + output.writeInt(SerializationConstants::CONSTANT_TYPE_BOOLEAN_ARRAY); output.writeBooleanArray(object); @@ -254,7 +241,7 @@ namespace hazelcast { writeHash(output); // write type - output.writeInt(SerializationConstants::getInstance()->CONSTANT_TYPE_SHORT_ARRAY); + output.writeInt(SerializationConstants::CONSTANT_TYPE_SHORT_ARRAY); output.writeShortArray(object); @@ -271,7 +258,7 @@ namespace hazelcast { writeHash(output); // write type - output.writeInt(SerializationConstants::getInstance()->CONSTANT_TYPE_INTEGER_ARRAY); + output.writeInt(SerializationConstants::CONSTANT_TYPE_INTEGER_ARRAY); output.writeIntArray(object); @@ -288,7 +275,7 @@ namespace hazelcast { writeHash(output); // write type - output.writeInt(SerializationConstants::getInstance()->CONSTANT_TYPE_LONG_ARRAY); + output.writeInt(SerializationConstants::CONSTANT_TYPE_LONG_ARRAY); output.writeLongArray(object); @@ -305,7 +292,7 @@ namespace hazelcast { writeHash(output); // write type - output.writeInt(SerializationConstants::getInstance()->CONSTANT_TYPE_FLOAT_ARRAY); + output.writeInt(SerializationConstants::CONSTANT_TYPE_FLOAT_ARRAY); output.writeFloatArray(object); @@ -322,7 +309,7 @@ namespace hazelcast { writeHash(output); // write type - output.writeInt(SerializationConstants::getInstance()->CONSTANT_TYPE_DOUBLE_ARRAY); + output.writeInt(SerializationConstants::CONSTANT_TYPE_DOUBLE_ARRAY); output.writeDoubleArray(object); @@ -339,7 +326,7 @@ namespace hazelcast { writeHash(output); // write type - output.writeInt(SerializationConstants::getInstance()->CONSTANT_TYPE_STRING); + output.writeInt(SerializationConstants::CONSTANT_TYPE_STRING); output.writeUTF(object); @@ -355,7 +342,7 @@ namespace hazelcast { writeHash(output); // write type - output.writeInt(SerializationConstants::getInstance()->CONSTANT_TYPE_STRING_ARRAY); + output.writeInt(SerializationConstants::CONSTANT_TYPE_STRING_ARRAY); output.writeUTFArray(object); @@ -371,7 +358,7 @@ namespace hazelcast { int typeId = data.getType(); - checkClassType(SerializationConstants::getInstance()->CONSTANT_TYPE_BYTE, typeId); + constants.checkClassType(SerializationConstants::CONSTANT_TYPE_BYTE, typeId); boost::shared_ptr object(new byte); @@ -388,7 +375,7 @@ namespace hazelcast { int typeId = data.getType(); - checkClassType(SerializationConstants::getInstance()->CONSTANT_TYPE_BOOLEAN, typeId); + constants.checkClassType(SerializationConstants::CONSTANT_TYPE_BOOLEAN, typeId); boost::shared_ptr object(new bool); @@ -405,7 +392,7 @@ namespace hazelcast { int typeId = data.getType(); - checkClassType(SerializationConstants::getInstance()->CONSTANT_TYPE_CHAR, typeId); + constants.checkClassType(SerializationConstants::CONSTANT_TYPE_CHAR, typeId); boost::shared_ptr object(new char); @@ -422,7 +409,7 @@ namespace hazelcast { int typeId = data.getType(); - checkClassType(SerializationConstants::getInstance()->CONSTANT_TYPE_SHORT, typeId); + constants.checkClassType(SerializationConstants::CONSTANT_TYPE_SHORT, typeId); boost::shared_ptr object(new short); @@ -439,7 +426,7 @@ namespace hazelcast { int typeId = data.getType(); - checkClassType(SerializationConstants::getInstance()->CONSTANT_TYPE_INTEGER, typeId); + constants.checkClassType(SerializationConstants::CONSTANT_TYPE_INTEGER, typeId); boost::shared_ptr object(new int); @@ -456,7 +443,7 @@ namespace hazelcast { int typeId = data.getType(); - checkClassType(SerializationConstants::getInstance()->CONSTANT_TYPE_LONG, typeId); + constants.checkClassType(SerializationConstants::CONSTANT_TYPE_LONG, typeId); boost::shared_ptr object(new long); @@ -473,7 +460,7 @@ namespace hazelcast { int typeId = data.getType(); - checkClassType(SerializationConstants::getInstance()->CONSTANT_TYPE_FLOAT, typeId); + constants.checkClassType(SerializationConstants::CONSTANT_TYPE_FLOAT, typeId); boost::shared_ptr object(new float); @@ -490,7 +477,7 @@ namespace hazelcast { int typeId = data.getType(); - checkClassType(SerializationConstants::getInstance()->CONSTANT_TYPE_DOUBLE, typeId); + constants.checkClassType(SerializationConstants::CONSTANT_TYPE_DOUBLE, typeId); boost::shared_ptr object(new double); @@ -507,7 +494,7 @@ namespace hazelcast { int typeId = data.getType(); - checkClassType(SerializationConstants::getInstance()->CONSTANT_TYPE_CHAR_ARRAY, typeId); + constants.checkClassType(SerializationConstants::CONSTANT_TYPE_CHAR_ARRAY, typeId); return boost::shared_ptr > (dataInput.readCharArray()); } @@ -520,7 +507,7 @@ namespace hazelcast { int typeId = data.getType(); - checkClassType(SerializationConstants::getInstance()->CONSTANT_TYPE_BOOLEAN_ARRAY, typeId); + constants.checkClassType(SerializationConstants::CONSTANT_TYPE_BOOLEAN_ARRAY, typeId); return boost::shared_ptr > (dataInput.readBooleanArray()); } @@ -533,7 +520,7 @@ namespace hazelcast { int typeId = data.getType(); - checkClassType(SerializationConstants::getInstance()->CONSTANT_TYPE_SHORT_ARRAY, typeId); + constants.checkClassType(SerializationConstants::CONSTANT_TYPE_SHORT_ARRAY, typeId); return boost::shared_ptr > (dataInput.readShortArray()); } @@ -546,7 +533,7 @@ namespace hazelcast { int typeId = data.getType(); - checkClassType(SerializationConstants::getInstance()->CONSTANT_TYPE_INTEGER_ARRAY, typeId); + constants.checkClassType(SerializationConstants::CONSTANT_TYPE_INTEGER_ARRAY, typeId); return boost::shared_ptr > (dataInput.readIntArray()); } @@ -559,7 +546,7 @@ namespace hazelcast { int typeId = data.getType(); - checkClassType(SerializationConstants::getInstance()->CONSTANT_TYPE_LONG_ARRAY, typeId); + constants.checkClassType(SerializationConstants::CONSTANT_TYPE_LONG_ARRAY, typeId); return boost::shared_ptr > (dataInput.readLongArray()); } @@ -572,7 +559,7 @@ namespace hazelcast { int typeId = data.getType(); - checkClassType(SerializationConstants::getInstance()->CONSTANT_TYPE_FLOAT_ARRAY, typeId); + constants.checkClassType(SerializationConstants::CONSTANT_TYPE_FLOAT_ARRAY, typeId); return boost::shared_ptr > (dataInput.readFloatArray()); } @@ -585,7 +572,7 @@ namespace hazelcast { int typeId = data.getType(); - checkClassType(SerializationConstants::getInstance()->CONSTANT_TYPE_DOUBLE_ARRAY, typeId); + constants.checkClassType(SerializationConstants::CONSTANT_TYPE_DOUBLE_ARRAY, typeId); return boost::shared_ptr > (dataInput.readDoubleArray()); } @@ -598,7 +585,7 @@ namespace hazelcast { int typeId = data.getType(); - checkClassType(SerializationConstants::getInstance()->CONSTANT_TYPE_STRING, typeId); + constants.checkClassType(SerializationConstants::CONSTANT_TYPE_STRING, typeId); return boost::shared_ptr (dataInput.readUTF()); } @@ -611,7 +598,7 @@ namespace hazelcast { int typeId = data.getType(); - checkClassType(SerializationConstants::getInstance()->CONSTANT_TYPE_STRING_ARRAY, typeId); + constants.checkClassType(SerializationConstants::CONSTANT_TYPE_STRING_ARRAY, typeId); return boost::shared_ptr > (dataInput.readUTFArray()); } diff --git a/hazelcast/src/hazelcast/client/serialization/pimpl/SerializerHolder.cpp b/hazelcast/src/hazelcast/client/serialization/pimpl/SerializerHolder.cpp index c55945f93b..ff445af3d1 100644 --- a/hazelcast/src/hazelcast/client/serialization/pimpl/SerializerHolder.cpp +++ b/hazelcast/src/hazelcast/client/serialization/pimpl/SerializerHolder.cpp @@ -31,7 +31,7 @@ namespace hazelcast { } bool SerializerHolder::registerSerializer(boost::shared_ptr serializer) { - boost::shared_ptr available = serializers.putIfAbsent(serializer->getTypeId(), serializer); + boost::shared_ptr available = serializers.putIfAbsent(serializer->getHazelcastTypeId(), serializer); return available.get() == NULL; } diff --git a/hazelcast/test/src/customSerialization/TestCustomPersonSerializer.cpp b/hazelcast/test/src/customSerialization/TestCustomPersonSerializer.cpp index 8dcb67fec6..f73b37a6e8 100644 --- a/hazelcast/test/src/customSerialization/TestCustomPersonSerializer.cpp +++ b/hazelcast/test/src/customSerialization/TestCustomPersonSerializer.cpp @@ -37,7 +37,7 @@ namespace hazelcast { assert(i == 999); } - int TestCustomPersonSerializer::getTypeId() const { + int TestCustomPersonSerializer::getHazelcastTypeId() const { return 999; } diff --git a/hazelcast/test/src/customSerialization/TestCustomPersonSerializer.h b/hazelcast/test/src/customSerialization/TestCustomPersonSerializer.h index f9b44b54c2..5638bfc029 100644 --- a/hazelcast/test/src/customSerialization/TestCustomPersonSerializer.h +++ b/hazelcast/test/src/customSerialization/TestCustomPersonSerializer.h @@ -35,7 +35,7 @@ namespace hazelcast { void read(serialization::ObjectDataInput & in, TestCustomPerson& object); - int getTypeId() const; + int getHazelcastTypeId() const; }; } } diff --git a/hazelcast/test/src/customSerialization/TestCustomSerializerX.h b/hazelcast/test/src/customSerialization/TestCustomSerializerX.h index 50495c3bfd..17560dab6d 100644 --- a/hazelcast/test/src/customSerialization/TestCustomSerializerX.h +++ b/hazelcast/test/src/customSerialization/TestCustomSerializerX.h @@ -48,7 +48,7 @@ namespace hazelcast { assert(i == 666); } - int getTypeId() const { + int getHazelcastTypeId() const { return 666; }; }; diff --git a/hazelcast/test/src/customSerialization/TestCustomXSerializable.cpp b/hazelcast/test/src/customSerialization/TestCustomXSerializable.cpp index ed02fcad7c..ba64705c30 100644 --- a/hazelcast/test/src/customSerialization/TestCustomXSerializable.cpp +++ b/hazelcast/test/src/customSerialization/TestCustomXSerializable.cpp @@ -39,7 +39,7 @@ namespace hazelcast { return !(*this == rhs); } - int TestCustomXSerializable::getTypeId() const { + int getHazelcastTypeId(TestCustomXSerializable const* param) { return 666; } @@ -71,7 +71,7 @@ namespace hazelcast { return name; } - int TestCustomPerson::getTypeId() const { + int getHazelcastTypeId(TestCustomPerson const* param) { return 999; } diff --git a/hazelcast/test/src/customSerialization/TestCustomXSerializable.h b/hazelcast/test/src/customSerialization/TestCustomXSerializable.h index 82a06d75a7..b474f79e2a 100644 --- a/hazelcast/test/src/customSerialization/TestCustomXSerializable.h +++ b/hazelcast/test/src/customSerialization/TestCustomXSerializable.h @@ -27,14 +27,12 @@ namespace hazelcast { namespace client { namespace test { - class TestCustomXSerializable : public serialization::SerializerBase { + class TestCustomXSerializable{ public: TestCustomXSerializable(); TestCustomXSerializable(int id); - int getTypeId() const; - bool operator ==(const TestCustomXSerializable & rhs) const; bool operator !=(const TestCustomXSerializable& m) const; @@ -42,7 +40,9 @@ namespace hazelcast { int id; }; - class TestCustomPerson : public serialization::SerializerBase { + int getHazelcastTypeId(const TestCustomXSerializable* ); + + class TestCustomPerson { public: TestCustomPerson(); @@ -52,8 +52,6 @@ namespace hazelcast { void setName(const std::string & name); - int getTypeId() const; - bool operator ==(const TestCustomPerson & rhs) const; bool operator !=(const TestCustomPerson& m) const; @@ -62,6 +60,8 @@ namespace hazelcast { private: std::string name; }; + + int getHazelcastTypeId(const TestCustomPerson* ); } } }