You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2017/01/26 12:02:10 UTC
ignite git commit: IGNITE-1466: CPP: Added initial BinaryObject
implementation. This closes #1448.
Repository: ignite
Updated Branches:
refs/heads/master 58b49b6c2 -> 9d64a281b
IGNITE-1466: CPP: Added initial BinaryObject implementation. This closes #1448.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/9d64a281
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/9d64a281
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/9d64a281
Branch: refs/heads/master
Commit: 9d64a281b89d447c92fc8181190d0554ea3f5755
Parents: 58b49b6
Author: isapego <ig...@gmail.com>
Authored: Thu Jan 26 15:02:03 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Thu Jan 26 15:02:03 2017 +0300
----------------------------------------------------------------------
modules/platforms/cpp/binary/Makefile.am | 2 +
.../platforms/cpp/binary/include/Makefile.am | 3 +
.../cpp/binary/include/ignite/binary/binary.h | 15 +-
.../include/ignite/binary/binary_object.h | 77 +++++
.../ignite/impl/binary/binary_object_header.h | 250 ++++++++++++++++
.../ignite/impl/binary/binary_object_impl.h | 102 +++++++
.../include/ignite/impl/binary/binary_schema.h | 2 +-
.../include/ignite/impl/binary/binary_utils.h | 61 ++++
.../cpp/binary/project/vs/binary.vcxproj | 5 +
.../binary/project/vs/binary.vcxproj.filters | 15 +
.../src/impl/binary/binary_object_header.cpp | 51 ++++
.../src/impl/binary/binary_object_impl.cpp | 52 ++++
.../cpp/binary/src/impl/binary/binary_utils.cpp | 83 ++++++
.../src/impl/binary/binary_writer_impl.cpp | 2 +-
modules/platforms/cpp/core-test/Makefile.am | 1 +
.../core-test/include/ignite/binary_test_defs.h | 25 ++
.../cpp/core-test/include/ignite/complex_type.h | 135 +++++++++
.../cpp/core-test/include/ignite/test_type.h | 186 ++++++++++++
.../cpp/core-test/project/vs/core-test.vcxproj | 3 +
.../project/vs/core-test.vcxproj.filters | 16 +-
.../cpp/core-test/src/binary_object_test.cpp | 282 +++++++++++++++++++
21 files changed, 1357 insertions(+), 11 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d64a281/modules/platforms/cpp/binary/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/Makefile.am b/modules/platforms/cpp/binary/Makefile.am
index 5ffc4fd..cee87cd 100644
--- a/modules/platforms/cpp/binary/Makefile.am
+++ b/modules/platforms/cpp/binary/Makefile.am
@@ -60,6 +60,8 @@ libignite_binary_la_SOURCES = \
src/impl/binary/binary_type_updater.cpp \
src/impl/binary/binary_schema.cpp \
src/impl/binary/binary_type_snapshot.cpp \
+ src/impl/binary/binary_object_header.cpp \
+ src/impl/binary/binary_object_impl.cpp \
src/impl/interop/interop_memory.cpp \
src/impl/interop/interop_output_stream.cpp \
src/impl/interop/interop_input_stream.cpp
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d64a281/modules/platforms/cpp/binary/include/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/include/Makefile.am b/modules/platforms/cpp/binary/include/Makefile.am
index d3211a3..2795cbc 100644
--- a/modules/platforms/cpp/binary/include/Makefile.am
+++ b/modules/platforms/cpp/binary/include/Makefile.am
@@ -26,6 +26,7 @@ nobase_include_HEADERS = \
ignite/binary/binary.h \
ignite/binary/binary_consts.h \
ignite/binary/binary_type.h \
+ ignite/binary/binary_object.h \
ignite/impl/binary/binary_type_handler.h \
ignite/impl/binary/binary_id_resolver.h \
ignite/impl/binary/binary_type_manager.h \
@@ -36,6 +37,8 @@ nobase_include_HEADERS = \
ignite/impl/binary/binary_reader_impl.h \
ignite/impl/binary/binary_schema.h \
ignite/impl/binary/binary_utils.h \
+ ignite/impl/binary/binary_object_header.h \
+ ignite/impl/binary/binary_object_impl.h \
ignite/impl/interop/interop_memory.h \
ignite/impl/interop/interop.h \
ignite/impl/interop/interop_stream_position_guard.h \
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d64a281/modules/platforms/cpp/binary/include/ignite/binary/binary.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/include/ignite/binary/binary.h b/modules/platforms/cpp/binary/include/ignite/binary/binary.h
index bfe23f4..d8c5404 100644
--- a/modules/platforms/cpp/binary/include/ignite/binary/binary.h
+++ b/modules/platforms/cpp/binary/include/ignite/binary/binary.h
@@ -23,12 +23,13 @@
#ifndef _IGNITE_BINARY_BINARY
#define _IGNITE_BINARY_BINARY
-#include "ignite/binary/binary_consts.h"
-#include "ignite/binary/binary_containers.h"
-#include "ignite/binary/binary_type.h"
-#include "ignite/binary/binary_raw_reader.h"
-#include "ignite/binary/binary_raw_writer.h"
-#include "ignite/binary/binary_reader.h"
-#include "ignite/binary/binary_writer.h"
+#include <ignite/binary/binary_consts.h>
+#include <ignite/binary/binary_containers.h>
+#include <ignite/binary/binary_type.h>
+#include <ignite/binary/binary_object.h>
+#include <ignite/binary/binary_raw_reader.h>
+#include <ignite/binary/binary_raw_writer.h>
+#include <ignite/binary/binary_reader.h>
+#include <ignite/binary/binary_writer.h>
#endif //_IGNITE_BINARY_BINARY
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d64a281/modules/platforms/cpp/binary/include/ignite/binary/binary_object.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/include/ignite/binary/binary_object.h b/modules/platforms/cpp/binary/include/ignite/binary/binary_object.h
new file mode 100644
index 0000000..41907d0
--- /dev/null
+++ b/modules/platforms/cpp/binary/include/ignite/binary/binary_object.h
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+/**
+ * @file
+ * Declares ignite::binary::BinaryObject class.
+ */
+
+#ifndef _IGNITE_BINARY_BINARY_OBJECT
+#define _IGNITE_BINARY_BINARY_OBJECT
+
+#include <stdint.h>
+
+#include <ignite/impl/interop/interop.h>
+#include <ignite/impl/binary/binary_reader_impl.h>
+#include <ignite/impl/binary/binary_object_impl.h>
+
+namespace ignite
+{
+ namespace binary
+ {
+ /**
+ * Binary object.
+ *
+ * This is a thin wrapper over the memory area that contains serialized
+ * binary object. Provides method that allows deserialize object.
+ */
+ class IGNITE_IMPORT_EXPORT BinaryObject : private impl::binary::BinaryObjectImpl
+ {
+ public:
+ /// @cond INTERNAL
+ /**
+ * Constructor.
+ *
+ * @param mem Binary object memory.
+ * @param start Object starting position in memory.
+ */
+ BinaryObject(impl::interop::InteropMemory& mem, int32_t start) :
+ BinaryObjectImpl(mem, start)
+ {
+ // No-op.
+ };
+ /// @endcond
+
+ /**
+ * Deserialize object.
+ * @throw IgniteError if the object can not be deserialized to specified type.
+ *
+ * @return Deserialized value.
+ */
+ template<typename T>
+ T Deserialize() const
+ {
+ return impl::binary::BinaryObjectImpl::Deserialize<T>();
+ }
+
+ private:
+ IGNITE_NO_COPY_ASSIGNMENT(BinaryObject)
+ };
+ }
+}
+
+#endif //_IGNITE_BINARY_BINARY_OBJECT
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d64a281/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_object_header.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_object_header.h b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_object_header.h
new file mode 100644
index 0000000..5ba1960
--- /dev/null
+++ b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_object_header.h
@@ -0,0 +1,250 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+/**
+ * @file
+ * Declares ignite::impl::binary::BinaryObjectHeader class.
+ */
+
+#ifndef _IGNITE_IMPL_BINARY_BINARY_OBJECT_HEADER
+#define _IGNITE_IMPL_BINARY_BINARY_OBJECT_HEADER
+
+#include <stdint.h>
+
+#include <ignite/common/common.h>
+
+#include <ignite/impl/binary/binary_common.h>
+#include <ignite/impl/interop/interop_memory.h>
+
+namespace ignite
+{
+ namespace impl
+ {
+ namespace binary
+ {
+
+ // This is a packed structure - we do not want padding for our fields here.
+#pragma pack(push, 1)
+
+ /**
+ * Binary object header layout.
+ */
+ struct IGNITE_IMPORT_EXPORT BinaryObjectHeaderLayout
+ {
+ int8_t headerType;
+ int8_t version;
+ int16_t flags;
+ int32_t typeId;
+ int32_t hashCode;
+ int32_t length;
+ int32_t schemaId;
+ int32_t schemaOffset;
+ };
+
+#pragma pack(pop)
+
+ /**
+ * Binary object header class.
+ *
+ * @note Most methods are defined in header to encourage inlining.
+ */
+ class IGNITE_IMPORT_EXPORT BinaryObjectHeader
+ {
+ public:
+ // Header size in bytes.
+ enum { SIZE = sizeof(BinaryObjectHeaderLayout) };
+
+ /**
+ * Create from InteropMemory instance.
+ * @throw IgniteError if the memory at the specified offset
+ * is not a valid BinaryObject.
+ *
+ * @param mem Memory.
+ * @param offset Offset in memory.
+ * @return New BinaryObjectHeader instance.
+ */
+ static BinaryObjectHeader FromMemory(interop::InteropMemory& mem, int32_t offset);
+
+ /**
+ * Constructor.
+ *
+ * @param mem Pointer to header memory.
+ */
+ BinaryObjectHeader(void* mem) :
+ header(reinterpret_cast<BinaryObjectHeaderLayout*>(mem))
+ {
+ // No-op.
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param other Instance to copy.
+ */
+ BinaryObjectHeader(const BinaryObjectHeader& other) :
+ header(other.header)
+ {
+ // No-op.
+ }
+
+ /**
+ * Assingment operator.
+ *
+ * @param other Other instance.
+ * @return Reference to this.
+ */
+ BinaryObjectHeader& operator=(const BinaryObjectHeader& other)
+ {
+ header = other.header;
+
+ return *this;
+ }
+
+ /**
+ * Get header type.
+ *
+ * @return Header type.
+ */
+ int8_t GetType() const
+ {
+ return header->headerType;
+ }
+
+ /**
+ * Get version.
+ *
+ * @return Binary object layout version.
+ */
+ int8_t GetVersion() const
+ {
+ return header->version;
+ }
+
+ /**
+ * Get flags.
+ *
+ * @return Flags.
+ */
+ int16_t GetFlags() const
+ {
+ return header->flags;
+ }
+
+ /**
+ * Get type ID.
+ *
+ * @return Type ID.
+ */
+ int32_t GetTypeId() const
+ {
+ return header->typeId;
+ }
+
+ /**
+ * Get hash code.
+ *
+ * @return Hash code.
+ */
+ int32_t GetHashCode() const
+ {
+ return header->hashCode;
+ }
+
+ /**
+ * Get object length.
+ *
+ * @return Object length.
+ */
+ int32_t GetLength() const
+ {
+ return header->length;
+ }
+
+ /**
+ * Get schema ID.
+ *
+ * @return Schema ID.
+ */
+ int32_t GetSchemaId() const
+ {
+ return header->schemaId;
+ }
+
+ /**
+ * Get schema offset.
+ *
+ * @return Schema offset.
+ */
+ int32_t GetSchemaOffset() const
+ {
+ return header->schemaOffset;
+ }
+
+ /**
+ * Check if the binary object has schema.
+ *
+ * @return True if the binary object has schema.
+ */
+ bool HasSchema() const
+ {
+ return (header->flags & IGNITE_BINARY_FLAG_HAS_SCHEMA) != 0;
+ }
+
+ /**
+ * Check if the binary object is of user-defined type.
+ *
+ * @return True if the binary object is of user-defined type.
+ */
+ bool IsUserType() const
+ {
+ return (header->flags & IGNITE_BINARY_FLAG_USER_TYPE) != 0;
+ }
+
+ /**
+ * Get footer offset.
+ *
+ * @return Footer offset.
+ */
+ int32_t GetFooterOffset() const
+ {
+ // No schema: all we have is data. There is no offset in last 4 bytes.
+ if (!HasSchema())
+ return GetLength();
+
+ // There is schema. Regardless of raw data presence, footer starts with schema.
+ return GetSchemaOffset();
+ }
+
+ /**
+ * Get size of data without header and footer.
+ *
+ * @return Data length.
+ */
+ int32_t GetDataLength() const
+ {
+ return GetFooterOffset() - SIZE;
+ }
+
+ private:
+ /** Header layout */
+ BinaryObjectHeaderLayout* header;
+ };
+ }
+ }
+}
+
+#endif //_IGNITE_IMPL_BINARY_BINARY_OBJECT_HEADER
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d64a281/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_object_impl.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_object_impl.h b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_object_impl.h
new file mode 100644
index 0000000..288ba26
--- /dev/null
+++ b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_object_impl.h
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+/**
+ * @file
+ * Declares ignite::binary::BinaryObject class.
+ */
+
+#ifndef _IGNITE_IMPL_BINARY_BINARY_OBJECT_IMPL
+#define _IGNITE_IMPL_BINARY_BINARY_OBJECT_IMPL
+
+#include <stdint.h>
+
+#include <ignite/impl/interop/interop.h>
+#include <ignite/impl/binary/binary_reader_impl.h>
+
+namespace ignite
+{
+ namespace impl
+ {
+ namespace binary
+ {
+ /**
+ * Binary object implementation.
+ *
+ * This is a thin wrapper over the memory area that contains serialized
+ * binary object. Provides some methods that allow to access object's
+ * data without deserialization. Also provides method that allows
+ * deserialize object.
+ */
+ class IGNITE_IMPORT_EXPORT BinaryObjectImpl
+ {
+ public:
+ /**
+ * Constructor.
+ *
+ * @param mem Binary object memory.
+ * @param start Object starting position in memory.
+ */
+ BinaryObjectImpl(interop::InteropMemory& mem, int32_t start);
+
+ /**
+ * Deserialize object.
+ * @throw IgniteError if the object can not be deserialized to specified type.
+ *
+ * @return Deserialized value.
+ */
+ template<typename T>
+ T Deserialize() const
+ {
+ interop::InteropInputStream stream(&mem);
+
+ stream.Position(start);
+ BinaryReaderImpl reader(&stream);
+
+ return reader.ReadObject<T>();
+ }
+
+ /**
+ * Get object data.
+ * @throw IgniteError if the object is not in a valid state.
+ *
+ * @return Pointer to object data.
+ */
+ const int8_t* GetData() const;
+
+ /**
+ * Get object length.
+ * @throw IgniteError if the object is not in a valid state.
+ *
+ * @return Object length.
+ */
+ int32_t GetLength() const;
+
+ private:
+ IGNITE_NO_COPY_ASSIGNMENT(BinaryObjectImpl)
+
+ /** Underlying object memory. */
+ interop::InteropMemory& mem;
+
+ /** Object starting position in memory. */
+ int32_t start;
+ };
+ }
+ }
+}
+
+#endif //_IGNITE_IMPL_BINARY_BINARY_OBJECT_IMPL
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d64a281/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_schema.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_schema.h b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_schema.h
index 756a3f7..cf97f8d 100644
--- a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_schema.h
+++ b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_schema.h
@@ -67,7 +67,7 @@ namespace ignite
/**
* Add another field to schema.
*
- * @param id Field id.
+ * @param fieldId Field id.
* @param offset Field offset.
*/
void AddField(int32_t fieldId, int32_t offset);
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d64a281/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_utils.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_utils.h b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_utils.h
index 3abd651..9599fce 100644
--- a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_utils.h
+++ b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_utils.h
@@ -36,6 +36,7 @@ namespace ignite
{
class InteropInputStream;
class InteropOutputStream;
+ class InteropMemory;
}
namespace binary
@@ -55,6 +56,26 @@ namespace ignite
static int8_t ReadInt8(interop::InteropInputStream* stream);
/**
+ * Utility method to read signed 8-bit integer from memory.
+ * @throw IgniteError if there is not enough memory.
+ *
+ * @param mem Memory.
+ * @param pos Position in memory.
+ * @return Value.
+ */
+ static int8_t ReadInt8(interop::InteropMemory& mem, int32_t pos);
+
+ /**
+ * Utility method to read signed 8-bit integer from memory.
+ * @warning Does not check if there is enough data in memory to read.
+ *
+ * @param mem Memory.
+ * @param pos Position in memory.
+ * @return Value.
+ */
+ static int8_t UnsafeReadInt8(interop::InteropMemory& mem, int32_t pos);
+
+ /**
* Utility method to write signed 8-bit integer to stream.
*
* @param stream Stream.
@@ -123,6 +144,26 @@ namespace ignite
static int16_t ReadInt16(interop::InteropInputStream* stream);
/**
+ * Utility method to read signed 16-bit integer from memory.
+ * @throw IgniteError if there is not enough memory.
+ *
+ * @param mem Memory.
+ * @param pos Position in memory.
+ * @return Value.
+ */
+ static int16_t ReadInt16(interop::InteropMemory& mem, int32_t pos);
+
+ /**
+ * Utility method to read signed 16-bit integer from memory.
+ * @warning Does not check if there is enough data in memory to read.
+ *
+ * @param mem Memory.
+ * @param pos Position in memory.
+ * @return Value.
+ */
+ static int16_t UnsafeReadInt16(interop::InteropMemory& mem, int32_t pos);
+
+ /**
* Utility method to write signed 16-bit integer to stream.
*
* @param stream Stream.
@@ -191,6 +232,26 @@ namespace ignite
static int32_t ReadInt32(interop::InteropInputStream* stream);
/**
+ * Utility method to read signed 32-bit integer from memory.
+ * @throw IgniteError if there is not enough memory.
+ *
+ * @param mem Memory.
+ * @param pos Position in memory.
+ * @return Value.
+ */
+ static int32_t ReadInt32(interop::InteropMemory& mem, int32_t pos);
+
+ /**
+ * Utility method to read signed 32-bit integer from memory.
+ * @warning Does not check if there is enough data in memory to read.
+ *
+ * @param mem Memory.
+ * @param pos Position in memory.
+ * @return Value.
+ */
+ static int32_t UnsafeReadInt32(interop::InteropMemory& mem, int32_t pos);
+
+ /**
* Utility method to write signed 32-bit integer to stream.
*
* @param stream Stream.
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d64a281/modules/platforms/cpp/binary/project/vs/binary.vcxproj
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/project/vs/binary.vcxproj b/modules/platforms/cpp/binary/project/vs/binary.vcxproj
index a29b361..887eb96 100644
--- a/modules/platforms/cpp/binary/project/vs/binary.vcxproj
+++ b/modules/platforms/cpp/binary/project/vs/binary.vcxproj
@@ -180,6 +180,7 @@
<ClInclude Include="..\..\include\ignite\binary\binary.h" />
<ClInclude Include="..\..\include\ignite\binary\binary_consts.h" />
<ClInclude Include="..\..\include\ignite\binary\binary_containers.h" />
+ <ClInclude Include="..\..\include\ignite\binary\binary_object.h" />
<ClInclude Include="..\..\include\ignite\binary\binary_raw_reader.h" />
<ClInclude Include="..\..\include\ignite\binary\binary_raw_writer.h" />
<ClInclude Include="..\..\include\ignite\binary\binary_reader.h" />
@@ -187,6 +188,8 @@
<ClInclude Include="..\..\include\ignite\binary\binary_writer.h" />
<ClInclude Include="..\..\include\ignite\impl\binary\binary_common.h" />
<ClInclude Include="..\..\include\ignite\impl\binary\binary_id_resolver.h" />
+ <ClInclude Include="..\..\include\ignite\impl\binary\binary_object_header.h" />
+ <ClInclude Include="..\..\include\ignite\impl\binary\binary_object_impl.h" />
<ClInclude Include="..\..\include\ignite\impl\binary\binary_reader_impl.h" />
<ClInclude Include="..\..\include\ignite\impl\binary\binary_schema.h" />
<ClInclude Include="..\..\include\ignite\impl\binary\binary_type_handler.h" />
@@ -208,6 +211,8 @@
<ClCompile Include="..\..\src\binary\binary_reader.cpp" />
<ClCompile Include="..\..\src\binary\binary_type.cpp" />
<ClCompile Include="..\..\src\binary\binary_writer.cpp" />
+ <ClCompile Include="..\..\src\impl\binary\binary_object_header.cpp" />
+ <ClCompile Include="..\..\src\impl\binary\binary_object_impl.cpp" />
<ClCompile Include="..\..\src\impl\binary\binary_reader_impl.cpp" />
<ClCompile Include="..\..\src\impl\binary\binary_schema.cpp" />
<ClCompile Include="..\..\src\impl\binary\binary_type_handler.cpp" />
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d64a281/modules/platforms/cpp/binary/project/vs/binary.vcxproj.filters
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/project/vs/binary.vcxproj.filters b/modules/platforms/cpp/binary/project/vs/binary.vcxproj.filters
index 09aca58..a1a83ef 100644
--- a/modules/platforms/cpp/binary/project/vs/binary.vcxproj.filters
+++ b/modules/platforms/cpp/binary/project/vs/binary.vcxproj.filters
@@ -88,6 +88,15 @@
<ClInclude Include="..\..\include\ignite\impl\interop\interop_stream_position_guard.h">
<Filter>Code\impl\interop</Filter>
</ClInclude>
+ <ClInclude Include="..\..\include\ignite\binary\binary_object.h">
+ <Filter>Code\binary</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\ignite\impl\binary\binary_object_header.h">
+ <Filter>Code\impl\binary</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\ignite\impl\binary\binary_object_impl.h">
+ <Filter>Code\impl\binary</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\binary\binary_containers.cpp">
@@ -141,5 +150,11 @@
<ClCompile Include="..\..\src\impl\interop\interop_output_stream.cpp">
<Filter>Code\impl\interop</Filter>
</ClCompile>
+ <ClCompile Include="..\..\src\impl\binary\binary_object_header.cpp">
+ <Filter>Code\impl\binary</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\impl\binary\binary_object_impl.cpp">
+ <Filter>Code\impl\binary</Filter>
+ </ClCompile>
</ItemGroup>
</Project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d64a281/modules/platforms/cpp/binary/src/impl/binary/binary_object_header.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/src/impl/binary/binary_object_header.cpp b/modules/platforms/cpp/binary/src/impl/binary/binary_object_header.cpp
new file mode 100644
index 0000000..aef095f
--- /dev/null
+++ b/modules/platforms/cpp/binary/src/impl/binary/binary_object_header.cpp
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 <ignite/ignite_error.h>
+
+#include <ignite/impl/binary/binary_object_header.h>
+
+namespace ignite
+{
+ namespace impl
+ {
+ namespace binary
+ {
+ BinaryObjectHeader BinaryObjectHeader::FromMemory(interop::InteropMemory& mem, int32_t offset)
+ {
+ if ((mem.Length() - offset) < SIZE)
+ {
+ IGNITE_ERROR_FORMATTED_3(ignite::IgniteError::IGNITE_ERR_MEMORY,
+ "Not enough data in the binary object", "memPtr", mem.PointerLong(),
+ "len", mem.Length(), "headerLen", SIZE);
+ }
+
+ BinaryObjectHeader hdr(mem.Data() + offset);
+
+ int8_t type = hdr.GetType();
+ if (type != impl::binary::IGNITE_TYPE_OBJECT)
+ {
+ IGNITE_ERROR_FORMATTED_3(ignite::IgniteError::IGNITE_ERR_MEMORY,
+ "Not enough data in the binary object", "memPtr", mem.PointerLong(),
+ "type", type, "expected", impl::binary::IGNITE_TYPE_OBJECT);
+ }
+
+ return hdr;
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d64a281/modules/platforms/cpp/binary/src/impl/binary/binary_object_impl.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/src/impl/binary/binary_object_impl.cpp b/modules/platforms/cpp/binary/src/impl/binary/binary_object_impl.cpp
new file mode 100644
index 0000000..652d54d
--- /dev/null
+++ b/modules/platforms/cpp/binary/src/impl/binary/binary_object_impl.cpp
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 <ignite/impl/binary/binary_object_header.h>
+#include <ignite/impl/binary/binary_object_impl.h>
+
+using namespace ignite::impl::binary;
+
+namespace ignite
+{
+ namespace impl
+ {
+ namespace binary
+ {
+ BinaryObjectImpl::BinaryObjectImpl(impl::interop::InteropMemory& mem, int32_t start) :
+ mem(mem),
+ start(start)
+ {
+ // No-op.
+ }
+
+ const int8_t* BinaryObjectImpl::GetData() const
+ {
+ // Creating header here to validate object header layout.
+ BinaryObjectHeader header = BinaryObjectHeader::FromMemory(mem, start);
+
+ return mem.Data() + start + BinaryObjectHeader::SIZE;
+ }
+
+ int32_t BinaryObjectImpl::GetLength() const
+ {
+ BinaryObjectHeader header = BinaryObjectHeader::FromMemory(mem, start);
+
+ return header.GetDataLength();
+ }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d64a281/modules/platforms/cpp/binary/src/impl/binary/binary_utils.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/src/impl/binary/binary_utils.cpp b/modules/platforms/cpp/binary/src/impl/binary/binary_utils.cpp
index 22738ef..bffd038 100644
--- a/modules/platforms/cpp/binary/src/impl/binary/binary_utils.cpp
+++ b/modules/platforms/cpp/binary/src/impl/binary/binary_utils.cpp
@@ -17,12 +17,65 @@
#include <time.h>
+#include "ignite/ignite_error.h"
+
#include "ignite/impl/interop/interop.h"
#include "ignite/impl/binary/binary_utils.h"
using namespace ignite::impl::interop;
using namespace ignite::impl::binary;
+namespace
+{
+ /**
+ * Check if there is enough data in memory.
+ * @throw IgniteError if there is not enough memory.
+ *
+ * @param mem Memory.
+ * @param pos Position.
+ * @param len Data to read.
+ */
+ inline void CheckEnoughData(InteropMemory& mem, int32_t pos, int32_t len)
+ {
+ if (mem.Length() < (pos + len))
+ {
+ IGNITE_ERROR_FORMATTED_4(ignite::IgniteError::IGNITE_ERR_MEMORY, "Not enough data in "
+ "the binary object", "memPtr", mem.PointerLong(), "len", mem.Length(), "pos", pos,
+ "requested", len);
+ }
+ }
+
+ /**
+ * Read primitive int type from the specific place in memory.
+ * @throw IgniteError if there is not enough memory.
+ *
+ * @param mem Memory.
+ * @param pos Position.
+ * @return Primitive.
+ */
+ template<typename T>
+ inline T ReadPrimitive(InteropMemory& mem, int32_t pos)
+ {
+ CheckEnoughData(mem, pos, sizeof(T));
+
+ return *reinterpret_cast<T*>(mem.Data() + pos);
+ }
+
+ /**
+ * Read primitive int type from the specific place in memory.
+ * @warning Does not check if there is enough data in memory to read.
+ *
+ * @param mem Memory.
+ * @param pos Position.
+ * @return Primitive.
+ */
+ template<typename T>
+ inline T UnsafeReadPrimitive(InteropMemory& mem, int32_t pos)
+ {
+ return *reinterpret_cast<T*>(mem.Data() + pos);
+ }
+}
+
namespace ignite
{
namespace impl
@@ -34,6 +87,16 @@ namespace ignite
return stream->ReadInt8();
}
+ int8_t BinaryUtils::ReadInt8(InteropMemory& mem, int32_t pos)
+ {
+ return ReadPrimitive<int8_t>(mem, pos);
+ }
+
+ int8_t BinaryUtils::UnsafeReadInt8(interop::InteropMemory& mem, int32_t pos)
+ {
+ return UnsafeReadPrimitive<int8_t>(mem, pos);
+ }
+
void BinaryUtils::WriteInt8(InteropOutputStream* stream, int8_t val)
{
stream->WriteInt8(val);
@@ -74,6 +137,16 @@ namespace ignite
return stream->ReadInt16();
}
+ int16_t BinaryUtils::ReadInt16(interop::InteropMemory& mem, int32_t pos)
+ {
+ return ReadPrimitive<int16_t>(mem, pos);
+ }
+
+ int16_t BinaryUtils::UnsafeReadInt16(interop::InteropMemory& mem, int32_t pos)
+ {
+ return UnsafeReadPrimitive<int16_t>(mem, pos);
+ }
+
void BinaryUtils::WriteInt16(InteropOutputStream* stream, int16_t val)
{
stream->WriteInt16(val);
@@ -114,6 +187,16 @@ namespace ignite
return stream->ReadInt32();
}
+ int32_t BinaryUtils::ReadInt32(interop::InteropMemory& mem, int32_t pos)
+ {
+ return ReadPrimitive<int32_t>(mem, pos);
+ }
+
+ int32_t BinaryUtils::UnsafeReadInt32(interop::InteropMemory& mem, int32_t pos)
+ {
+ return UnsafeReadPrimitive<int32_t>(mem, pos);
+ }
+
void BinaryUtils::WriteInt32(InteropOutputStream* stream, int32_t val)
{
stream->WriteInt32(val);
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d64a281/modules/platforms/cpp/binary/src/impl/binary/binary_writer_impl.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/src/impl/binary/binary_writer_impl.cpp b/modules/platforms/cpp/binary/src/impl/binary/binary_writer_impl.cpp
index 5df0c2a..20fb74d 100644
--- a/modules/platforms/cpp/binary/src/impl/binary/binary_writer_impl.cpp
+++ b/modules/platforms/cpp/binary/src/impl/binary/binary_writer_impl.cpp
@@ -736,7 +736,7 @@ namespace ignite
int32_t length = stream->Position() - start;
flags |= IGNITE_BINARY_FLAG_HAS_SCHEMA;
-
+
if (schemaType == OFFSET_TYPE_ONE_BYTE)
flags |= IGNITE_BINARY_FLAG_OFFSET_ONE_BYTE;
else if (schemaType == OFFSET_TYPE_TWO_BYTES)
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d64a281/modules/platforms/cpp/core-test/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/Makefile.am b/modules/platforms/cpp/core-test/Makefile.am
index a5a60ed..4af2850 100644
--- a/modules/platforms/cpp/core-test/Makefile.am
+++ b/modules/platforms/cpp/core-test/Makefile.am
@@ -64,6 +64,7 @@ ignite_tests_SOURCES = \
src/handle_registry_test.cpp \
src/ignite_error_test.cpp \
src/binary_test_defs.cpp \
+ src/binary_object_test.cpp \
src/binary_reader_writer_raw_test.cpp \
src/binary_reader_writer_test.cpp \
src/binary_session_test.cpp \
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d64a281/modules/platforms/cpp/core-test/include/ignite/binary_test_defs.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/include/ignite/binary_test_defs.h b/modules/platforms/cpp/core-test/include/ignite/binary_test_defs.h
index 00b17e2..42f4539 100644
--- a/modules/platforms/cpp/core-test/include/ignite/binary_test_defs.h
+++ b/modules/platforms/cpp/core-test/include/ignite/binary_test_defs.h
@@ -76,6 +76,31 @@ namespace ignite_test
{
// No-op.
}
+
+ friend bool operator==(const BinaryFields& one, const BinaryFields& two)
+ {
+ return one.val1 == two.val1 && one.val2 == two.val2 &&
+ one.rawVal1 == two.rawVal1 &&one.rawVal2 == two.rawVal2;
+ }
+ };
+
+ class DummyIdResolver : public ignite::impl::binary::BinaryIdResolver
+ {
+ public:
+ virtual ~DummyIdResolver()
+ {
+ // No-op.
+ }
+
+ virtual int32_t GetTypeId()
+ {
+ return 0;
+ }
+
+ virtual int32_t GetFieldId(const int32_t, const char*)
+ {
+ return 0;
+ }
};
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d64a281/modules/platforms/cpp/core-test/include/ignite/complex_type.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/include/ignite/complex_type.h b/modules/platforms/cpp/core-test/include/ignite/complex_type.h
new file mode 100644
index 0000000..cb4a8a1
--- /dev/null
+++ b/modules/platforms/cpp/core-test/include/ignite/complex_type.h
@@ -0,0 +1,135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+#ifndef _IGNITE_ODBC_TEST_COMPLEX_TYPE
+#define _IGNITE_ODBC_TEST_COMPLEX_TYPE
+
+#include <string>
+
+#include "ignite/ignite.h"
+#include "ignite/ignition.h"
+
+namespace ignite
+{
+ struct InnerObject
+ {
+ InnerObject() :
+ f1(412),
+ f2("Lorem ipsum")
+ {
+ // No-op.
+ }
+
+ friend bool operator==(const InnerObject& one, const InnerObject& two)
+ {
+ return one.f1 == two.f1 &&
+ one.f2 == two.f2;
+ }
+
+ int32_t f1;
+ std::string f2;
+ };
+
+ struct ComplexType
+ {
+ ComplexType() :
+ i32Field(0)
+ {
+ // No-op.
+ }
+
+ friend bool operator==(const ComplexType& one, const ComplexType& two)
+ {
+ return one.i32Field == two.i32Field &&
+ one.objField == two.objField &&
+ one.strField == two.strField;
+ }
+
+ int32_t i32Field;
+ InnerObject objField;
+ std::string strField;
+ };
+}
+
+namespace ignite
+{
+ namespace binary
+ {
+
+ IGNITE_BINARY_TYPE_START(ignite::InnerObject)
+
+ typedef ignite::InnerObject InnerObject;
+
+ IGNITE_BINARY_GET_TYPE_ID_AS_HASH(InnerObject)
+ IGNITE_BINARY_GET_TYPE_NAME_AS_IS(InnerObject)
+ IGNITE_BINARY_GET_FIELD_ID_AS_HASH
+ IGNITE_BINARY_GET_HASH_CODE_ZERO(InnerObject)
+ IGNITE_BINARY_IS_NULL_FALSE(InnerObject)
+ IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(InnerObject)
+
+ void Write(BinaryWriter& writer, InnerObject obj)
+ {
+ writer.WriteInt32("f1", obj.f1);
+ writer.WriteString("f2", obj.f2);
+ }
+
+ InnerObject Read(BinaryReader& reader)
+ {
+ InnerObject obj;
+
+ obj.f1 = reader.ReadInt32("f1");
+ obj.f2 = reader.ReadString("f2");
+
+ return obj;
+ }
+
+ IGNITE_BINARY_TYPE_END
+
+ IGNITE_BINARY_TYPE_START(ignite::ComplexType)
+
+ typedef ignite::ComplexType ComplexType;
+
+ IGNITE_BINARY_GET_TYPE_ID_AS_HASH(ComplexType)
+ IGNITE_BINARY_GET_TYPE_NAME_AS_IS(ComplexType)
+ IGNITE_BINARY_GET_FIELD_ID_AS_HASH
+ IGNITE_BINARY_GET_HASH_CODE_ZERO(ComplexType)
+ IGNITE_BINARY_IS_NULL_FALSE(ComplexType)
+ IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(ComplexType)
+
+ void Write(BinaryWriter& writer, ComplexType obj)
+ {
+ writer.WriteInt32("i32Field", obj.i32Field);
+ writer.WriteObject("objField", obj.objField);
+ writer.WriteString("strField", obj.strField);
+ }
+
+ ComplexType Read(BinaryReader& reader)
+ {
+ ComplexType obj;
+
+ obj.i32Field = reader.ReadInt32("i32Field");
+ obj.objField = reader.ReadObject<InnerObject>("objField");
+ obj.strField = reader.ReadString("strField");
+
+ return obj;
+ }
+
+ IGNITE_BINARY_TYPE_END
+ }
+};
+
+#endif // _IGNITE_ODBC_TEST_COMPLEX_TYPE
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d64a281/modules/platforms/cpp/core-test/include/ignite/test_type.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/include/ignite/test_type.h b/modules/platforms/cpp/core-test/include/ignite/test_type.h
new file mode 100644
index 0000000..b399afe
--- /dev/null
+++ b/modules/platforms/cpp/core-test/include/ignite/test_type.h
@@ -0,0 +1,186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+#ifndef _IGNITE_ODBC_TEST_TEST_TYPE
+#define _IGNITE_ODBC_TEST_TEST_TYPE
+
+#include <string>
+
+#include "ignite/ignite.h"
+#include "ignite/ignition.h"
+
+namespace ignite
+{
+ struct TestType
+ {
+ TestType() :
+ allNulls(false),
+ i8Field(0),
+ i16Field(0),
+ i32Field(0),
+ i64Field(0),
+ floatField(0.0f),
+ doubleField(0.0),
+ boolField(false),
+ dateField(),
+ timestampField()
+ {
+ // No-op.
+ }
+
+ TestType(int8_t i8Field, int16_t i16Field, int32_t i32Field,
+ int64_t i64Field, const std::string& strField, float floatField,
+ double doubleField, bool boolField, const Guid& guidField,
+ const Date& dateField, const Timestamp& timestampField) :
+ allNulls(false),
+ i8Field(i8Field),
+ i16Field(i16Field),
+ i32Field(i32Field),
+ i64Field(i64Field),
+ strField(strField),
+ floatField(floatField),
+ doubleField(doubleField),
+ boolField(boolField),
+ guidField(guidField),
+ dateField(dateField),
+ timestampField(timestampField)
+ {
+ // No-op.
+ }
+
+ friend bool operator==(const TestType& one, const TestType& two)
+ {
+ return
+ one.allNulls == two.allNulls &&
+ one.i8Field == two.i8Field &&
+ one.i16Field == two.i16Field &&
+ one.i32Field == two.i32Field &&
+ one.i64Field == two.i64Field &&
+ one.strField == two.strField &&
+ one.floatField == two.floatField &&
+ one.doubleField == two.doubleField &&
+ one.boolField == two.boolField &&
+ one.guidField == two.guidField &&
+ one.dateField == two.dateField &&
+ one.timestampField == two.timestampField &&
+ one.i8ArrayField == two.i8ArrayField;
+ }
+
+ bool allNulls;
+ int8_t i8Field;
+ int16_t i16Field;
+ int32_t i32Field;
+ int64_t i64Field;
+ std::string strField;
+ float floatField;
+ double doubleField;
+ bool boolField;
+ Guid guidField;
+ Date dateField;
+ Timestamp timestampField;
+ std::vector<int8_t> i8ArrayField;
+ };
+}
+
+namespace ignite
+{
+ namespace binary
+ {
+ IGNITE_BINARY_TYPE_START(ignite::TestType)
+
+ typedef ignite::TestType TestType;
+
+ IGNITE_BINARY_GET_TYPE_ID_AS_HASH(TestType)
+ IGNITE_BINARY_GET_TYPE_NAME_AS_IS(TestType)
+ IGNITE_BINARY_GET_FIELD_ID_AS_HASH
+ IGNITE_BINARY_GET_HASH_CODE_ZERO(TestType)
+ IGNITE_BINARY_IS_NULL_FALSE(TestType)
+ IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(TestType)
+
+ void Write(BinaryWriter& writer, TestType obj)
+ {
+ if (!obj.allNulls)
+ {
+ writer.WriteInt8("i8Field", obj.i8Field);
+ writer.WriteInt16("i16Field", obj.i16Field);
+ writer.WriteInt32("i32Field", obj.i32Field);
+ writer.WriteInt64("i64Field", obj.i64Field);
+ writer.WriteString("strField", obj.strField);
+ writer.WriteFloat("floatField", obj.floatField);
+ writer.WriteDouble("doubleField", obj.doubleField);
+ writer.WriteBool("boolField", obj.boolField);
+ writer.WriteGuid("guidField", obj.guidField);
+ writer.WriteDate("dateField", obj.dateField);
+ writer.WriteTimestamp("timestampField", obj.timestampField);
+ if (obj.i8ArrayField.empty())
+ {
+ writer.WriteNull("i8ArrayField");
+ }
+ else
+ {
+ writer.WriteInt8Array("i8ArrayField", &obj.i8ArrayField[0], static_cast<int32_t>(obj.i8ArrayField.size()));
+ }
+ }
+ else
+ {
+ writer.WriteNull("i8Field");
+ writer.WriteNull("i16Field");
+ writer.WriteNull("i32Field");
+ writer.WriteNull("i64Field");
+ writer.WriteNull("strField");
+ writer.WriteNull("floatField");
+ writer.WriteNull("doubleField");
+ writer.WriteNull("boolField");
+ writer.WriteNull("guidField");
+ writer.WriteNull("dateField");
+ writer.WriteNull("timestampField");
+ writer.WriteNull("i8ArrayField");
+ }
+ }
+
+ TestType Read(BinaryReader& reader)
+ {
+ int8_t i8Field = reader.ReadInt8("i8Field");
+ int16_t i16Field = reader.ReadInt16("i16Field");
+ int32_t i32Field = reader.ReadInt32("i32Field");
+ int64_t i64Field = reader.ReadInt64("i64Field");
+ std::string strField = reader.ReadString("strField");
+ float floatField = reader.ReadFloat("floatField");
+ double doubleField = reader.ReadDouble("doubleField");
+ bool boolField = reader.ReadBool("boolField");
+ Guid guidField = reader.ReadGuid("guidField");
+ Date dateField = reader.ReadDate("dateField");
+ Timestamp timestampField = reader.ReadTimestamp("timestampField");
+
+ TestType result(i8Field, i16Field, i32Field, i64Field, strField,
+ floatField, doubleField, boolField, guidField, dateField,
+ timestampField);
+
+ int32_t len = reader.ReadInt8Array("i8ArrayField", 0, 0);
+ if (len > 0)
+ {
+ result.i8ArrayField.resize(len);
+ reader.ReadInt8Array("i8ArrayField", &result.i8ArrayField[0], len);
+ }
+ return result;
+ }
+
+ IGNITE_BINARY_TYPE_END
+ }
+};
+
+#endif // _IGNITE_ODBC_TEST_TEST_TYPE
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d64a281/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj b/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj
index a41d8f8..634ede2 100644
--- a/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj
+++ b/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj
@@ -38,6 +38,7 @@
<None Include="..\..\config\invalid.xml" />
</ItemGroup>
<ItemGroup>
+ <ClCompile Include="..\..\src\binary_object_test.cpp" />
<ClCompile Include="..\..\src\cache_test.cpp" />
<ClCompile Include="..\..\src\concurrent_test.cpp" />
<ClCompile Include="..\..\src\decimal_test.cpp" />
@@ -63,6 +64,8 @@
<ItemGroup>
<ClInclude Include="..\..\include\ignite\binary_test_defs.h" />
<ClInclude Include="..\..\include\ignite\binary_test_utils.h" />
+ <ClInclude Include="..\..\include\ignite\complex_type.h" />
+ <ClInclude Include="..\..\include\ignite\test_type.h" />
<ClInclude Include="..\..\include\teamcity_messages.h" />
</ItemGroup>
<PropertyGroup Label="Globals">
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d64a281/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj.filters
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj.filters b/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj.filters
index a95e3a4..906a9d4 100644
--- a/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj.filters
+++ b/modules/platforms/cpp/core-test/project/vs/core-test.vcxproj.filters
@@ -64,15 +64,24 @@
<ClCompile Include="..\..\src\reference_test.cpp">
<Filter>Code</Filter>
</ClCompile>
+ <ClCompile Include="..\..\src\binary_object_test.cpp">
+ <Filter>Code</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\include\teamcity_messages.h">
<Filter>TeamCity</Filter>
</ClInclude>
- <ClInclude Include="..\..\include\ignite\binary_test_defs.h">
+ <ClInclude Include="..\..\include\ignite\binary_test_utils.h">
<Filter>Code</Filter>
</ClInclude>
- <ClInclude Include="..\..\include\ignite\binary_test_utils.h">
+ <ClInclude Include="..\..\include\ignite\complex_type.h">
+ <Filter>Code\Types</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\ignite\test_type.h">
+ <Filter>Code\Types</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\ignite\binary_test_defs.h">
<Filter>Code</Filter>
</ClInclude>
</ItemGroup>
@@ -86,6 +95,9 @@
<Filter Include="TeamCity">
<UniqueIdentifier>{76bceab0-e251-445f-88c3-3f6f8739423b}</UniqueIdentifier>
</Filter>
+ <Filter Include="Code\Types">
+ <UniqueIdentifier>{fb43524e-3694-44ee-b153-770cd9cf6c7a}</UniqueIdentifier>
+ </Filter>
</ItemGroup>
<ItemGroup>
<None Include="..\..\config\cache-test.xml">
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d64a281/modules/platforms/cpp/core-test/src/binary_object_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/src/binary_object_test.cpp b/modules/platforms/cpp/core-test/src/binary_object_test.cpp
new file mode 100644
index 0000000..0ae7136
--- /dev/null
+++ b/modules/platforms/cpp/core-test/src/binary_object_test.cpp
@@ -0,0 +1,282 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+#ifndef _MSC_VER
+# define BOOST_TEST_DYN_LINK
+#endif
+
+#include <boost/test/unit_test.hpp>
+
+#include <ignite/common/fixed_size_array.h>
+#include <ignite/binary/binary_object.h>
+#include <ignite/binary/binary_writer.h>
+
+#include "ignite/binary_test_defs.h"
+#include "ignite/test_type.h"
+#include "ignite/complex_type.h"
+
+using namespace ignite;
+using namespace ignite::binary;
+using namespace ignite::impl::interop;
+using namespace ignite::impl::binary;
+using namespace ignite_test::core::binary;
+
+template<typename T>
+void FillMem(InteropMemory& mem, const T& value)
+{
+ InteropOutputStream stream(&mem);
+ BinaryWriterImpl writer(&stream, 0);
+
+ writer.WriteObject<T>(value);
+
+ stream.Synchronize();
+}
+
+template<typename T>
+void CheckSimple(const T& value)
+{
+ InteropUnpooledMemory mem(1024);
+
+ FillMem<T>(mem, value);
+
+ BinaryObject obj(mem, 0);
+
+ T actual = obj.Deserialize<T>();
+
+ BOOST_REQUIRE_EQUAL(value, actual);
+}
+
+template<typename T>
+void CheckSimpleNP(const T& value)
+{
+ InteropUnpooledMemory mem(1024);
+
+ FillMem<T>(mem, value);
+
+ BinaryObject obj(mem, 0);
+
+ T actual = obj.Deserialize<T>();
+
+ BOOST_REQUIRE(value == actual);
+}
+
+template<typename T>
+void GetObjectData(const T& obj, common::FixedSizeArray<int8_t>& data)
+{
+ DummyIdResolver idResolver;
+
+ InteropUnpooledMemory mem(1024);
+ InteropOutputStream stream(&mem);
+ BinaryWriterImpl writerImpl(&stream, &idResolver, 0, 0, 0);
+ BinaryWriter writer(&writerImpl);
+
+ BinaryType<T> bt;
+
+ bt.Write(writer, obj);
+
+ data.Assign(mem.Data(), stream.Position());
+}
+
+template<typename T>
+void CheckData(const T& obj)
+{
+ common::FixedSizeArray<int8_t> objData;
+ GetObjectData<T>(obj, objData);
+
+ InteropUnpooledMemory mem(1024);
+ FillMem<T>(mem, obj);
+
+ BinaryObjectImpl binObj(mem, 0);
+
+ BOOST_REQUIRE_EQUAL(binObj.GetLength(), objData.GetSize());
+
+ common::FixedSizeArray<int8_t> binObjData(binObj.GetData(), binObj.GetLength());
+
+ for (int32_t i = 0; i < objData.GetSize(); ++i)
+ BOOST_CHECK_EQUAL(objData[i], binObjData[i]);
+}
+
+BOOST_AUTO_TEST_SUITE(BinaryObjectTestSuite)
+
+#ifdef CHECK_BINARY_OBJECT_WITH_PRIMITIVES
+
+BOOST_AUTO_TEST_CASE(PrimitiveInt8)
+{
+ CheckSimple<int8_t>(0);
+ CheckSimple<int8_t>(INT8_MAX);
+ CheckSimple<int8_t>(INT8_MIN);
+ CheckSimple<int8_t>(42);
+ CheckSimple<int8_t>(-12);
+ CheckSimple<int8_t>(0x7D);
+}
+
+BOOST_AUTO_TEST_CASE(PrimitiveInt16)
+{
+ CheckSimple<int32_t>(0);
+ CheckSimple<int32_t>(INT16_MAX);
+ CheckSimple<int32_t>(INT16_MIN);
+ CheckSimple<int32_t>(42);
+ CheckSimple<int32_t>(12321);
+ CheckSimple<int32_t>(0x7AB0);
+}
+
+BOOST_AUTO_TEST_CASE(PrimitiveInt32)
+{
+ CheckSimple<int32_t>(0);
+ CheckSimple<int32_t>(INT32_MAX);
+ CheckSimple<int32_t>(INT32_MIN);
+ CheckSimple<int32_t>(42);
+ CheckSimple<int32_t>(1337);
+ CheckSimple<int32_t>(0xA2496BC9);
+}
+
+BOOST_AUTO_TEST_CASE(PrimitiveInt64)
+{
+ CheckSimple<int64_t>(0);
+ CheckSimple<int64_t>(INT64_MAX);
+ CheckSimple<int64_t>(INT64_MIN);
+ CheckSimple<int64_t>(42);
+ CheckSimple<int64_t>(13371337133713371337LL);
+ CheckSimple<int64_t>(0xA928673F501CC09E);
+}
+
+BOOST_AUTO_TEST_CASE(PrimitiveBool)
+{
+ CheckSimple<bool>(true);
+ CheckSimple<bool>(false);
+}
+
+BOOST_AUTO_TEST_CASE(PrimitiveFloat)
+{
+ CheckSimple<float>(0.0);
+ CheckSimple<float>(1E38f);
+ CheckSimple<float>(-1E38f);
+ CheckSimple<float>(1E-38f);
+ CheckSimple<float>(-1E-38f);
+ CheckSimple<float>(42.0f);
+ CheckSimple<float>(42.42f);
+ CheckSimple<float>(1337.1337f);
+}
+
+BOOST_AUTO_TEST_CASE(PrimitiveDouble)
+{
+ CheckSimple<double>(0);
+ CheckSimple<double>(1E127);
+ CheckSimple<double>(-1E127);
+ CheckSimple<double>(1E-127);
+ CheckSimple<double>(-1E-127);
+ CheckSimple<double>(42);
+ CheckSimple<double>(42.42);
+ CheckSimple<double>(1337.1337 * 1337.1337);
+}
+
+BOOST_AUTO_TEST_CASE(PrimitiveString)
+{
+ CheckSimple<std::string>("");
+ CheckSimple<std::string>("Lorem ipsum");
+ CheckSimple<std::string>("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do "
+ "eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, "
+ "quis nostrud exercitation");
+
+ CheckSimple<std::string>(std::string(1000, '.'));
+}
+
+BOOST_AUTO_TEST_CASE(PrimitiveGuid)
+{
+ CheckSimple<Guid>(Guid(0, 0));
+ CheckSimple<Guid>(Guid(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF));
+ CheckSimple<Guid>(Guid(0x4F9039DEF0FB8000, 0x905AE8A2D6FD49C1));
+}
+
+BOOST_AUTO_TEST_CASE(PrimitiveDate)
+{
+ CheckSimpleNP<Date>(Date(0));
+ CheckSimpleNP<Date>(BinaryUtils::MakeDateGmt(1998, 12, 3, 18, 32, 01));
+ CheckSimpleNP<Date>(BinaryUtils::MakeDateGmt(2017, 1, 18, 20, 50, 41));
+ CheckSimpleNP<Date>(BinaryUtils::MakeDateLocal(1998, 12, 3, 18, 32, 01));
+}
+
+BOOST_AUTO_TEST_CASE(PrimitiveTimestamp)
+{
+ CheckSimpleNP<Timestamp>(Timestamp(0));
+ CheckSimpleNP<Timestamp>(BinaryUtils::MakeTimestampGmt(1998, 12, 3, 18, 32, 01, 593846589));
+ CheckSimpleNP<Timestamp>(BinaryUtils::MakeTimestampGmt(2017, 1, 18, 20, 50, 41, 920700532));
+ CheckSimpleNP<Timestamp>(BinaryUtils::MakeTimestampLocal(1998, 12, 3, 18, 32, 01, 2385));
+}
+
+#endif //CHECK_BINARY_OBJECT_WITH_PRIMITIVES
+
+BOOST_AUTO_TEST_CASE(UserTestType)
+{
+ CheckSimpleNP(TestType());
+ CheckSimpleNP(TestType(1, 2, 3, 4, "5", 6.0f, 7.0, true, Guid(8, 9),
+ BinaryUtils::MakeDateGmt(1987, 6, 5),
+ BinaryUtils::MakeTimestampGmt(1998, 12, 27, 1, 2, 3, 456)));
+}
+
+BOOST_AUTO_TEST_CASE(UserComplexType)
+{
+ CheckSimpleNP(ComplexType());
+
+ ComplexType nonDefault;
+
+ nonDefault.i32Field = 589630659;
+ nonDefault.strField = "Some string value";
+ nonDefault.objField.f1 = 403685016;
+ nonDefault.objField.f2 = "Whatever";
+
+ CheckSimpleNP(nonDefault);
+}
+
+BOOST_AUTO_TEST_CASE(UserBinaryFields)
+{
+ CheckSimpleNP(BinaryFields());
+
+ BinaryFields nonDefault(423425, 961851, 18946, 180269165);
+
+ CheckSimpleNP(nonDefault);
+}
+
+BOOST_AUTO_TEST_CASE(UserComplexTypeGetData)
+{
+ CheckData(ComplexType());
+
+ ComplexType nonDefault;
+
+ nonDefault.i32Field = 589630659;
+ nonDefault.strField = "Some string value";
+ nonDefault.objField.f1 = 403685016;
+ nonDefault.objField.f2 = "Whatever";
+
+ CheckData(nonDefault);
+}
+
+BOOST_AUTO_TEST_CASE(UserTestTypeGetData)
+{
+ CheckData(TestType());
+ CheckData(TestType(1, 2, 3, 4, "5", 6.0f, 7.0, true, Guid(8, 9),
+ BinaryUtils::MakeDateGmt(1987, 6, 5),
+ BinaryUtils::MakeTimestampGmt(1998, 12, 27, 1, 2, 3, 456)));
+}
+
+BOOST_AUTO_TEST_CASE(UserBinaryFieldsGetData)
+{
+ CheckData(BinaryFields());
+ CheckData(BinaryFields(423425, 961851, 18946, 180269165));
+}
+
+BOOST_AUTO_TEST_SUITE_END()
\ No newline at end of file