From b49dc42f1453bf2edf151be957d233446a5cc62a Mon Sep 17 00:00:00 2001 From: sancar Date: Mon, 8 Feb 2016 10:59:06 +0200 Subject: [PATCH] Backported fixes from master(#37) 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. These fixes are backported from #37 Remove singleton usage of SerializationConstants to avoid thread safety issues. --- examples/serialization/CMakeLists.txt | 1 + examples/serialization/custom/CMakeLists.txt | 17 ++++ examples/serialization/custom/main.cpp | 91 ++++++++++++++++++ .../IdentifiedDataSerializable.h | 4 +- .../client/serialization/ObjectDataInput.h | 8 +- .../client/serialization/ObjectDataOutput.h | 10 +- .../hazelcast/client/serialization/Portable.h | 4 +- .../client/serialization/Serializer.h | 3 +- .../serialization/pimpl/PortableContext.h | 9 +- .../pimpl/SerializationConstants.h | 55 ++++++----- .../pimpl/SerializationService.h | 34 ++----- hazelcast/include/hazelcast/util/IOUtil.h | 12 --- .../IdentifiedDataSerializable.cpp | 4 +- .../client/serialization/Portable.cpp | 4 +- .../client/serialization/pimpl/Data.cpp | 2 +- .../serialization/pimpl/PortableContext.cpp | 8 +- .../pimpl/SerializationConstants.cpp | 70 ++++++++------ .../pimpl/SerializationService.cpp | 95 ++++++++----------- 18 files changed, 258 insertions(+), 173 deletions(-) create mode 100644 examples/serialization/custom/CMakeLists.txt create mode 100644 examples/serialization/custom/main.cpp 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..be2b9e01ed --- /dev/null +++ b/examples/serialization/custom/main.cpp @@ -0,0 +1,91 @@ +/* + * 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; + } + + int getTypeId() const{ + return 666; + } + +private: + std::string name; +}; + + + +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 getTypeId() 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..42c94f9a16 100644 --- a/hazelcast/include/hazelcast/client/serialization/IdentifiedDataSerializable.h +++ b/hazelcast/include/hazelcast/client/serialization/IdentifiedDataSerializable.h @@ -70,9 +70,9 @@ namespace hazelcast { /** * Not public api. Do not override this method. - * @return serializer id + * @return type id */ - virtual int getSerializerId() const; + virtual int getTypeId() const; }; } diff --git a/hazelcast/include/hazelcast/client/serialization/ObjectDataInput.h b/hazelcast/include/hazelcast/client/serialization/ObjectDataInput.h index 2998d1aa1c..c1d033d548 100644 --- a/hazelcast/include/hazelcast/client/serialization/ObjectDataInput.h +++ b/hazelcast/include/hazelcast/client/serialization/ObjectDataInput.h @@ -196,13 +196,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(result->getTypeId() , 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..da00c124a7 100644 --- a/hazelcast/include/hazelcast/client/serialization/ObjectDataOutput.h +++ b/hazelcast/include/hazelcast/client/serialization/ObjectDataOutput.h @@ -168,9 +168,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 +189,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,7 +206,7 @@ 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(); diff --git a/hazelcast/include/hazelcast/client/serialization/Portable.h b/hazelcast/include/hazelcast/client/serialization/Portable.h index 56cfd1c692..962a054a20 100644 --- a/hazelcast/include/hazelcast/client/serialization/Portable.h +++ b/hazelcast/include/hazelcast/client/serialization/Portable.h @@ -80,9 +80,9 @@ namespace hazelcast { /** * Not public api. Do not override this method. - * @return serializer id + * @return type id */ - virtual int getSerializerId() const; + virtual int getTypeId() const; }; } } diff --git a/hazelcast/include/hazelcast/client/serialization/Serializer.h b/hazelcast/include/hazelcast/client/serialization/Serializer.h index 361b08031b..5da2eb469d 100644 --- a/hazelcast/include/hazelcast/client/serialization/Serializer.h +++ b/hazelcast/include/hazelcast/client/serialization/Serializer.h @@ -95,7 +95,8 @@ namespace hazelcast { * 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/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..9eab923268 100644 --- a/hazelcast/include/hazelcast/client/serialization/pimpl/SerializationConstants.h +++ b/hazelcast/include/hazelcast/client/serialization/pimpl/SerializationConstants.h @@ -39,41 +39,40 @@ 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; + static int const CONSTANT_TYPE_PORTABLE; + static int const CONSTANT_TYPE_DATA; + static int const CONSTANT_TYPE_BYTE; + static int const CONSTANT_TYPE_BOOLEAN; + static int const CONSTANT_TYPE_CHAR; + static int const CONSTANT_TYPE_SHORT; + static int const CONSTANT_TYPE_INTEGER; + static int const CONSTANT_TYPE_LONG; + static int const CONSTANT_TYPE_FLOAT; + static int const CONSTANT_TYPE_DOUBLE; + static int const CONSTANT_TYPE_STRING; + static int const CONSTANT_TYPE_BYTE_ARRAY; + static int const CONSTANT_TYPE_BOOLEAN_ARRAY; + static int const CONSTANT_TYPE_CHAR_ARRAY; + static int const CONSTANT_TYPE_SHORT_ARRAY; + static int const CONSTANT_TYPE_INTEGER_ARRAY; + static int const CONSTANT_TYPE_LONG_ARRAY; + static int const CONSTANT_TYPE_FLOAT_ARRAY; + static int const CONSTANT_TYPE_DOUBLE_ARRAY; + static int const CONSTANT_TYPE_STRING_ARRAY; + // ------------------------------------------------------------ - 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/IdentifiedDataSerializable.cpp index e3365b251f..4d86540f6f 100644 --- a/hazelcast/src/hazelcast/client/serialization/IdentifiedDataSerializable.cpp +++ b/hazelcast/src/hazelcast/client/serialization/IdentifiedDataSerializable.cpp @@ -28,8 +28,8 @@ namespace hazelcast { } - int IdentifiedDataSerializable::getSerializerId() const { - return pimpl::SerializationConstants::getInstance()->CONSTANT_TYPE_DATA; + int IdentifiedDataSerializable::getTypeId() const { + return pimpl::SerializationConstants::CONSTANT_TYPE_DATA; } } } diff --git a/hazelcast/src/hazelcast/client/serialization/Portable.cpp b/hazelcast/src/hazelcast/client/serialization/Portable.cpp index 188f82d32e..ec74bacabc 100644 --- a/hazelcast/src/hazelcast/client/serialization/Portable.cpp +++ b/hazelcast/src/hazelcast/client/serialization/Portable.cpp @@ -28,8 +28,8 @@ namespace hazelcast { } - int Portable::getSerializerId() const { - return pimpl::SerializationConstants::getInstance()->CONSTANT_TYPE_PORTABLE; + int Portable::getTypeId() const { + return pimpl::SerializationConstants::CONSTANT_TYPE_PORTABLE; } } } 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..454f27e128 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,10 @@ 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..580da941e2 100644 --- a/hazelcast/src/hazelcast/client/serialization/pimpl/SerializationConstants.cpp +++ b/hazelcast/src/hazelcast/client/serialization/pimpl/SerializationConstants.cpp @@ -18,36 +18,38 @@ // #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; + int const SerializationConstants::CONSTANT_TYPE_NULL = 0; + int const SerializationConstants::CONSTANT_TYPE_PORTABLE=-1; + int const SerializationConstants::CONSTANT_TYPE_DATA=-2; + int const SerializationConstants::CONSTANT_TYPE_BYTE=-3; + int const SerializationConstants::CONSTANT_TYPE_BOOLEAN=-4; + int const SerializationConstants::CONSTANT_TYPE_CHAR=-5; + int const SerializationConstants::CONSTANT_TYPE_SHORT=-6; + int const SerializationConstants::CONSTANT_TYPE_INTEGER=-7; + int const SerializationConstants::CONSTANT_TYPE_LONG=-8; + int const SerializationConstants::CONSTANT_TYPE_FLOAT=-9; + int const SerializationConstants::CONSTANT_TYPE_DOUBLE=-10; + int const SerializationConstants::CONSTANT_TYPE_STRING=-11; + int const SerializationConstants::CONSTANT_TYPE_BYTE_ARRAY=-12; + int const SerializationConstants::CONSTANT_TYPE_BOOLEAN_ARRAY=-13; + int const SerializationConstants::CONSTANT_TYPE_CHAR_ARRAY=-14; + int const SerializationConstants::CONSTANT_TYPE_SHORT_ARRAY=-15; + int const SerializationConstants::CONSTANT_TYPE_INTEGER_ARRAY=-16; + int const SerializationConstants::CONSTANT_TYPE_LONG_ARRAY=-17; + int const SerializationConstants::CONSTANT_TYPE_FLOAT_ARRAY=-18; + int const SerializationConstants::CONSTANT_TYPE_DOUBLE_ARRAY=-19; + int const SerializationConstants::CONSTANT_TYPE_STRING_ARRAY=-20; 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 +74,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()); }