ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From voze...@apache.org
Subject [01/11] ignite git commit: IGNITE-1364: Squashed commit from initial branch.
Date Thu, 03 Sep 2015 17:15:50 GMT
Repository: ignite
Updated Branches:
  refs/heads/ignite-1364-1 [created] 1fc06e013


http://git-wip-us.apache.org/repos/asf/ignite/blob/1fc06e01/modules/platform/src/main/cpp/core/src/impl/portable/portable_reader_impl.cpp
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/cpp/core/src/impl/portable/portable_reader_impl.cpp b/modules/platform/src/main/cpp/core/src/impl/portable/portable_reader_impl.cpp
new file mode 100644
index 0000000..753ec25
--- /dev/null
+++ b/modules/platform/src/main/cpp/core/src/impl/portable/portable_reader_impl.cpp
@@ -0,0 +1,683 @@
+/*
+ * 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/interop/interop.h"
+#include "ignite/impl/portable/portable_common.h"
+#include "ignite/impl/portable/portable_id_resolver.h"
+#include "ignite/impl/portable/portable_reader_impl.h"
+#include "ignite/impl/portable/portable_utils.h"
+#include "ignite/portable/portable_type.h"
+#include "ignite/ignite_error.h"
+
+using namespace ignite::impl::interop;
+using namespace ignite::impl::portable;
+using namespace ignite::portable;
+
+namespace ignite
+{
+    namespace impl
+    {
+        namespace portable
+        {
+            PortableReaderImpl::PortableReaderImpl(InteropInputStream* stream, PortableIdResolver* idRslvr,
+                int32_t pos, bool usrType, int32_t typeId, int32_t hashCode, int32_t len, int32_t rawOff) :
+                stream(stream), idRslvr(idRslvr), pos(pos), usrType(usrType), typeId(typeId), 
+                hashCode(hashCode), len(len), rawOff(rawOff), rawMode(false), 
+                elemIdGen(0), elemId(0), elemCnt(-1), elemRead(0)
+            {
+                // No-op.
+            }
+
+            PortableReaderImpl::PortableReaderImpl(InteropInputStream* stream) :
+                stream(stream), idRslvr(NULL), pos(0), usrType(false), typeId(0), hashCode(0), 
+                len(0), rawOff(0), rawMode(true),
+                elemIdGen(0), elemId(0), elemCnt(-1), elemRead(0)
+            {
+                // No-op.
+            }
+
+            int8_t PortableReaderImpl::ReadInt8()
+            {
+                return ReadRaw<int8_t>(PortableUtils::ReadInt8);                
+            }
+            
+            int32_t PortableReaderImpl::ReadInt8Array(int8_t* res, const int32_t len)
+            {
+                return ReadRawArray<int8_t>(res, len, PortableUtils::ReadInt8Array, IGNITE_TYPE_ARRAY_BYTE);
+            }
+
+            int8_t PortableReaderImpl::ReadInt8(const char* fieldName)
+            {
+                return Read(fieldName, PortableUtils::ReadInt8, IGNITE_TYPE_BYTE, static_cast<int8_t>(0));
+            }
+
+            int32_t PortableReaderImpl::ReadInt8Array(const char* fieldName, int8_t* res, const int32_t len)
+            {
+                return ReadArray<int8_t>(fieldName, res, len,PortableUtils::ReadInt8Array, IGNITE_TYPE_ARRAY_BYTE);
+            }
+
+            bool PortableReaderImpl::ReadBool()
+            {
+                return ReadRaw<bool>(PortableUtils::ReadBool);
+            }
+
+            int32_t PortableReaderImpl::ReadBoolArray(bool* res, const int32_t len)
+            {
+                return ReadRawArray<bool>(res, len, PortableUtils::ReadBoolArray, IGNITE_TYPE_ARRAY_BOOL);
+            }
+
+            bool PortableReaderImpl::ReadBool(const char* fieldName)
+            {
+                return Read(fieldName, PortableUtils::ReadBool, IGNITE_TYPE_BOOL, static_cast<bool>(0));
+            }
+
+            int32_t PortableReaderImpl::ReadBoolArray(const char* fieldName, bool* res, const int32_t len)
+            {
+                return ReadArray<bool>(fieldName, res, len,PortableUtils::ReadBoolArray, IGNITE_TYPE_ARRAY_BOOL);
+            }
+
+            int16_t PortableReaderImpl::ReadInt16()
+            {
+                return ReadRaw<int16_t>(PortableUtils::ReadInt16);
+            }
+
+            int32_t PortableReaderImpl::ReadInt16Array(int16_t* res, const int32_t len)
+            {
+                return ReadRawArray<int16_t>(res, len, PortableUtils::ReadInt16Array, IGNITE_TYPE_ARRAY_SHORT);
+            }
+
+            int16_t PortableReaderImpl::ReadInt16(const char* fieldName)
+            {
+                return Read(fieldName, PortableUtils::ReadInt16, IGNITE_TYPE_SHORT, static_cast<int16_t>(0));
+            }
+
+            int32_t PortableReaderImpl::ReadInt16Array(const char* fieldName, int16_t* res, const int32_t len)
+            {
+                return ReadArray<int16_t>(fieldName, res, len, PortableUtils::ReadInt16Array, IGNITE_TYPE_ARRAY_SHORT);
+            }
+
+            uint16_t PortableReaderImpl::ReadUInt16()
+            {
+                return ReadRaw<uint16_t>(PortableUtils::ReadUInt16);
+            }
+
+            int32_t PortableReaderImpl::ReadUInt16Array(uint16_t* res, const int32_t len)
+            {
+                return ReadRawArray<uint16_t>(res, len, PortableUtils::ReadUInt16Array, IGNITE_TYPE_ARRAY_CHAR);
+            }
+
+            uint16_t PortableReaderImpl::ReadUInt16(const char* fieldName)
+            {
+                return Read(fieldName, PortableUtils::ReadUInt16, IGNITE_TYPE_CHAR, static_cast<uint16_t>(0));
+            }
+
+            int32_t PortableReaderImpl::ReadUInt16Array(const char* fieldName, uint16_t* res, const int32_t len)
+            {
+                return ReadArray<uint16_t>(fieldName, res, len,PortableUtils::ReadUInt16Array, IGNITE_TYPE_ARRAY_CHAR);
+            }
+
+            int32_t PortableReaderImpl::ReadInt32()
+            {
+                return ReadRaw<int32_t>(PortableUtils::ReadInt32);
+            }
+
+            int32_t PortableReaderImpl::ReadInt32Array(int32_t* res, const int32_t len)
+            {
+                return ReadRawArray<int32_t>(res, len, PortableUtils::ReadInt32Array, IGNITE_TYPE_ARRAY_INT);
+            }
+
+            int32_t PortableReaderImpl::ReadInt32(const char* fieldName)
+            {
+                return Read(fieldName, PortableUtils::ReadInt32, IGNITE_TYPE_INT, static_cast<int32_t>(0));
+            }
+
+            int32_t PortableReaderImpl::ReadInt32Array(const char* fieldName, int32_t* res, const int32_t len)
+            {
+                return ReadArray<int32_t>(fieldName, res, len,PortableUtils::ReadInt32Array, IGNITE_TYPE_ARRAY_INT);
+            }
+
+            int64_t PortableReaderImpl::ReadInt64()
+            {
+                return ReadRaw<int64_t>(PortableUtils::ReadInt64);
+            }
+
+            int32_t PortableReaderImpl::ReadInt64Array(int64_t* res, const int32_t len)
+            {
+                return ReadRawArray<int64_t>(res, len, PortableUtils::ReadInt64Array, IGNITE_TYPE_ARRAY_LONG);
+            }
+
+            int64_t PortableReaderImpl::ReadInt64(const char* fieldName)
+            {
+                return Read(fieldName, PortableUtils::ReadInt64, IGNITE_TYPE_LONG, static_cast<int64_t>(0));
+            }
+
+            int32_t PortableReaderImpl::ReadInt64Array(const char* fieldName, int64_t* res, const int32_t len)
+            {
+                return ReadArray<int64_t>(fieldName, res, len,PortableUtils::ReadInt64Array, IGNITE_TYPE_ARRAY_LONG);
+            }
+
+            float PortableReaderImpl::ReadFloat()
+            {
+                return ReadRaw<float>(PortableUtils::ReadFloat);
+            }
+
+            int32_t PortableReaderImpl::ReadFloatArray(float* res, const int32_t len)
+            {
+                return ReadRawArray<float>(res, len, PortableUtils::ReadFloatArray, IGNITE_TYPE_ARRAY_FLOAT);
+            }
+
+            float PortableReaderImpl::ReadFloat(const char* fieldName)
+            {
+                return Read(fieldName, PortableUtils::ReadFloat, IGNITE_TYPE_FLOAT, static_cast<float>(0));
+            }
+
+            int32_t PortableReaderImpl::ReadFloatArray(const char* fieldName, float* res, const int32_t len)
+            {
+                return ReadArray<float>(fieldName, res, len,PortableUtils::ReadFloatArray, IGNITE_TYPE_ARRAY_FLOAT);
+            }
+
+            double PortableReaderImpl::ReadDouble()
+            {
+                return ReadRaw<double>(PortableUtils::ReadDouble);
+            }
+
+            int32_t PortableReaderImpl::ReadDoubleArray(double* res, const int32_t len)
+            {
+                return ReadRawArray<double>(res, len, PortableUtils::ReadDoubleArray, IGNITE_TYPE_ARRAY_DOUBLE);
+            }
+
+            double PortableReaderImpl::ReadDouble(const char* fieldName)
+            {
+                return Read(fieldName, PortableUtils::ReadDouble, IGNITE_TYPE_DOUBLE, static_cast<double>(0));
+            }
+
+            int32_t PortableReaderImpl::ReadDoubleArray(const char* fieldName, double* res, const int32_t len)
+            {
+                return ReadArray<double>(fieldName, res, len,PortableUtils::ReadDoubleArray, IGNITE_TYPE_ARRAY_DOUBLE);
+            }
+
+            Guid PortableReaderImpl::ReadGuid()
+            {
+                CheckRawMode(true);
+                CheckSingleMode(true);
+
+                return ReadNullable(stream, PortableUtils::ReadGuid, IGNITE_TYPE_UUID);
+            }
+
+            int32_t PortableReaderImpl::ReadGuidArray(Guid* res, const int32_t len)
+            {
+                CheckRawMode(true);
+                CheckSingleMode(true);
+
+                return ReadArrayInternal<Guid>(res, len, stream, ReadGuidArrayInternal, IGNITE_TYPE_ARRAY_UUID);
+            }
+
+            Guid PortableReaderImpl::ReadGuid(const char* fieldName)
+            {
+                CheckRawMode(false);
+                CheckSingleMode(true);
+
+                int32_t fieldId = idRslvr->GetFieldId(typeId, fieldName);
+                int32_t fieldLen = SeekField(fieldId);
+
+                if (fieldLen > 0)
+                    return ReadNullable(stream, PortableUtils::ReadGuid, IGNITE_TYPE_UUID);
+
+                return Guid();
+            }
+
+            int32_t PortableReaderImpl::ReadGuidArray(const char* fieldName, Guid* res, const int32_t len)
+            {
+                CheckRawMode(false);
+                CheckSingleMode(true);
+
+                int32_t pos = stream->Position();
+
+                int32_t fieldId = idRslvr->GetFieldId(typeId, fieldName);
+                int32_t fieldLen = SeekField(fieldId);
+
+                if (fieldLen > 0) {
+                    int32_t realLen = ReadArrayInternal<Guid>(res, len, stream, ReadGuidArrayInternal, IGNITE_TYPE_ARRAY_UUID);
+
+                    // If actual read didn't occur return to initial position so that we do not perform 
+                    // N jumps to find the field again, where N is total amount of fields.
+                    if (realLen != -1 && (!res || realLen > len))
+                        stream->Position(pos);
+
+                    return realLen;
+                }
+
+                return -1;
+            }
+
+            void PortableReaderImpl::ReadGuidArrayInternal(InteropInputStream* stream, Guid* res, const int32_t len)
+            {
+                for (int i = 0; i < len; i++)
+                    *(res + i) = ReadNullable<Guid>(stream, PortableUtils::ReadGuid, IGNITE_TYPE_UUID);
+            }
+
+            int32_t PortableReaderImpl::ReadString(char* res, const int32_t len)
+            {
+                CheckRawMode(true);
+                CheckSingleMode(true);
+
+                return ReadStringInternal(res, len);
+            }
+
+            int32_t PortableReaderImpl::ReadString(const char* fieldName, char* res, const int32_t len)
+            {
+                CheckRawMode(false);
+                CheckSingleMode(true);
+
+                int32_t pos = stream->Position();
+                
+                int32_t fieldId = idRslvr->GetFieldId(typeId, fieldName);
+                int32_t fieldLen = SeekField(fieldId);
+
+                if (fieldLen > 0) {
+                    int32_t realLen = ReadStringInternal(res, len);
+
+                    // If actual read didn't occur return to initial position so that we do not perform 
+                    // N jumps to find the field again, where N is total amount of fields.
+                    if (realLen != -1 && (!res || realLen > len))
+                        stream->Position(pos);
+
+                    return realLen;
+                }
+
+                return -1;
+            }
+
+            int32_t PortableReaderImpl::ReadStringArray(int32_t* size)
+            {
+                return StartContainerSession(true, IGNITE_TYPE_ARRAY_STRING, size);
+            }
+
+            int32_t PortableReaderImpl::ReadStringArray(const char* fieldName, int32_t* size)
+            {
+                CheckRawMode(false);
+                CheckSingleMode(true);
+
+                int32_t fieldId = idRslvr->GetFieldId(typeId, fieldName);
+                int32_t fieldLen = SeekField(fieldId);
+
+                if (fieldLen > 0)
+                    return StartContainerSession(false, IGNITE_TYPE_ARRAY_STRING, size);
+                else {
+                    *size = -1;
+
+                    return ++elemIdGen;
+                }
+            }
+
+            int32_t PortableReaderImpl::ReadStringElement(int32_t id, char* res, const int32_t len)
+            {
+                CheckSession(id);
+
+                int32_t posBefore = stream->Position();
+
+                int32_t realLen = ReadStringInternal(res, len);
+
+                int32_t posAfter = stream->Position();
+
+                if (posAfter > posBefore && ++elemRead == elemCnt) {
+                    elemId = 0;
+                    elemCnt = -1;
+                    elemRead = 0;
+                }
+
+                return realLen;
+            }
+
+            int32_t PortableReaderImpl::ReadStringInternal(char* res, const int32_t len)
+            {
+                int8_t hdr = stream->ReadInt8();
+
+                if (hdr == IGNITE_TYPE_STRING) {
+                    bool utf8Mode = stream->ReadBool();
+                    int32_t realLen = stream->ReadInt32();
+
+                    if (res && len >= realLen) {
+                        if (utf8Mode)
+                        {
+                            for (int i = 0; i < realLen; i++)
+                                *(res + i) = static_cast<char>(stream->ReadInt8());
+                        }
+                        else
+                        {
+                            for (int i = 0; i < realLen; i++)
+                                *(res + i) = static_cast<char>(stream->ReadUInt16());
+                        }
+
+                        if (len > realLen)
+                            *(res + realLen) = 0; // Set NULL terminator if possible.
+                    }
+                    else
+                        stream->Position(stream->Position() - 6);
+
+                    return realLen;
+                }
+                else if (hdr != IGNITE_HDR_NULL)
+                    ThrowOnInvalidHeader(IGNITE_TYPE_ARRAY, hdr);
+
+                return -1;
+            }
+
+            int32_t PortableReaderImpl::ReadArray(int32_t* size)
+            {
+                return StartContainerSession(true, IGNITE_TYPE_ARRAY, size);
+            }
+
+            int32_t PortableReaderImpl::ReadArray(const char* fieldName, int32_t* size)
+            {
+                CheckRawMode(false);
+                CheckSingleMode(true);
+
+                int32_t fieldId = idRslvr->GetFieldId(typeId, fieldName);
+                int32_t fieldLen = SeekField(fieldId);
+
+                if (fieldLen > 0)
+                    return StartContainerSession(false, IGNITE_TYPE_ARRAY, size);
+                else {
+                    *size = -1;
+
+                    return ++elemIdGen;
+                }
+            }
+
+            int32_t PortableReaderImpl::ReadCollection(CollectionType* typ, int32_t* size)
+            {
+                int32_t id = StartContainerSession(true, IGNITE_TYPE_COLLECTION, size);
+
+                if (*size == -1)
+                    *typ = IGNITE_COLLECTION_UNDEFINED;
+                else
+                    *typ = static_cast<CollectionType>(stream->ReadInt8());
+
+                return id;
+            }
+
+            int32_t PortableReaderImpl::ReadCollection(const char* fieldName, CollectionType* typ, int32_t* size)
+            {
+                CheckRawMode(false);
+                CheckSingleMode(true);
+
+                int32_t fieldId = idRslvr->GetFieldId(typeId, fieldName);
+                int32_t fieldLen = SeekField(fieldId);
+
+                if (fieldLen > 0)
+                {
+                    int32_t id = StartContainerSession(false, IGNITE_TYPE_COLLECTION, size);
+
+                    if (*size == -1)
+                        *typ = IGNITE_COLLECTION_UNDEFINED;
+                    else
+                        *typ = static_cast<CollectionType>(stream->ReadInt8());
+
+                    return id;
+                }                    
+                else {
+                    *typ = IGNITE_COLLECTION_UNDEFINED;
+                    *size = -1;
+
+                    return ++elemIdGen;
+                }
+            }
+
+            int32_t PortableReaderImpl::ReadMap(MapType* typ, int32_t* size)
+            {
+                int32_t id = StartContainerSession(true, IGNITE_TYPE_MAP, size);
+
+                if (*size == -1)
+                    *typ = IGNITE_MAP_UNDEFINED;
+                else
+                    *typ = static_cast<MapType>(stream->ReadInt8());
+
+                return id;
+            }
+
+            int32_t PortableReaderImpl::ReadMap(const char* fieldName, MapType* typ, int32_t* size)
+            {
+                CheckRawMode(false);
+                CheckSingleMode(true);
+
+                int32_t fieldId = idRslvr->GetFieldId(typeId, fieldName);
+                int32_t fieldLen = SeekField(fieldId);
+
+                if (fieldLen > 0)
+                {
+                    int32_t id = StartContainerSession(false, IGNITE_TYPE_MAP, size);
+
+                    if (*size == -1)
+                        *typ = IGNITE_MAP_UNDEFINED;
+                    else
+                        *typ = static_cast<MapType>(stream->ReadInt8());
+
+                    return id;
+                }
+                else {
+                    *typ = IGNITE_MAP_UNDEFINED;
+                    *size = -1;
+
+                    return ++elemIdGen;
+                }
+            }
+
+            bool PortableReaderImpl::HasNextElement(int32_t id)
+            {
+                return elemId == id && elemRead < elemCnt;
+            }
+
+            void PortableReaderImpl::SetRawMode()
+            {
+                CheckRawMode(false);
+                CheckSingleMode(true);
+
+                stream->Position(pos + rawOff);
+                rawMode = true;
+            }
+
+            template <>
+            int8_t PortableReaderImpl::ReadTopObject<int8_t>()
+            {
+                return ReadTopObject0(IGNITE_TYPE_BYTE, PortableUtils::ReadInt8, static_cast<int8_t>(0));
+            }
+
+            template <>
+            bool PortableReaderImpl::ReadTopObject<bool>()
+            {
+                return ReadTopObject0(IGNITE_TYPE_BOOL, PortableUtils::ReadBool, static_cast<bool>(0));
+            }
+
+            template <>
+            int16_t PortableReaderImpl::ReadTopObject<int16_t>()
+            {
+                return ReadTopObject0(IGNITE_TYPE_SHORT, PortableUtils::ReadInt16, static_cast<int16_t>(0));
+            }
+
+            template <>
+            uint16_t PortableReaderImpl::ReadTopObject<uint16_t>()
+            {
+                return ReadTopObject0(IGNITE_TYPE_CHAR, PortableUtils::ReadUInt16, static_cast<uint16_t>(0));
+            }
+
+            template <>
+            int32_t PortableReaderImpl::ReadTopObject<int32_t>()
+            {
+                return ReadTopObject0(IGNITE_TYPE_INT, PortableUtils::ReadInt32, static_cast<int32_t>(0));
+            }
+
+            template <>
+            int64_t PortableReaderImpl::ReadTopObject<int64_t>()
+            {
+                return ReadTopObject0(IGNITE_TYPE_LONG, PortableUtils::ReadInt64, static_cast<int64_t>(0));
+            }
+
+            template <>
+            float PortableReaderImpl::ReadTopObject<float>()
+            {
+                return ReadTopObject0(IGNITE_TYPE_FLOAT, PortableUtils::ReadFloat, static_cast<float>(0));
+            }
+
+            template <>
+            double PortableReaderImpl::ReadTopObject<double>()
+            {
+                return ReadTopObject0(IGNITE_TYPE_DOUBLE, PortableUtils::ReadDouble, static_cast<double>(0));
+            }
+
+            template <>
+            Guid PortableReaderImpl::ReadTopObject<Guid>()
+            {
+                int8_t typeId = stream->ReadInt8();
+
+                if (typeId == IGNITE_TYPE_UUID)
+                    return PortableUtils::ReadGuid(stream);
+                else if (typeId == IGNITE_HDR_NULL)
+                    return Guid();
+                else {
+                    int32_t pos = stream->Position() - 1;
+
+                    IGNITE_ERROR_FORMATTED_3(IgniteError::IGNITE_ERR_PORTABLE, "Invalid header", "position", pos, "expected", IGNITE_TYPE_UUID, "actual", typeId)
+                }
+            }
+
+            InteropInputStream* PortableReaderImpl::GetStream()
+            {
+                return stream;
+            }
+
+            int32_t PortableReaderImpl::SeekField(const int32_t fieldId)
+            {
+                // We assume that it is very likely that fields are read in the same
+                // order as they were initially written. So we start seeking field
+                // from current stream position making a "loop" up to this position.
+                int32_t marker = stream->Position();
+
+                for (int32_t curPos = marker; curPos < pos + rawOff;)
+                {
+                    int32_t curFieldId = stream->ReadInt32();
+                    int32_t curFieldLen = stream->ReadInt32();
+
+                    if (fieldId == curFieldId)
+                        return curFieldLen;
+                    else {
+                        curPos = stream->Position() + curFieldLen;
+
+                        stream->Position(curPos);
+                    }
+                }
+
+                stream->Position(pos + IGNITE_FULL_HDR_LEN);
+
+                for (int32_t curPos = stream->Position(); curPos < marker;)
+                {
+                    int32_t curFieldId = stream->ReadInt32();
+                    int32_t curFieldLen = stream->ReadInt32();
+
+                    if (fieldId == curFieldId)
+                        return curFieldLen;
+                    else {
+                        curPos = stream->Position() + curFieldLen;
+
+                        stream->Position(curPos);
+                    }
+                }
+
+                return -1;
+            }
+
+            void PortableReaderImpl::CheckRawMode(bool expected)
+            {
+                if (expected && !rawMode) {
+                    IGNITE_ERROR_1(IgniteError::IGNITE_ERR_PORTABLE, "Operation can be performed only in raw mode.")
+                }
+                else if (!expected && rawMode) {
+                    IGNITE_ERROR_1(IgniteError::IGNITE_ERR_PORTABLE, "Operation cannot be performed in raw mode.")
+                }
+            }
+
+            void PortableReaderImpl::CheckSingleMode(bool expected)
+            {
+                if (expected && elemId != 0) {
+                    IGNITE_ERROR_1(IgniteError::IGNITE_ERR_PORTABLE, "Operation cannot be performed when container is being read.");
+                }
+                else if (!expected && elemId == 0) {
+                    IGNITE_ERROR_1(IgniteError::IGNITE_ERR_PORTABLE, "Operation can be performed only when container is being read.");
+                }
+            }
+
+            int32_t PortableReaderImpl::StartContainerSession(bool expRawMode, int8_t expHdr, int32_t* size)
+            {
+                CheckRawMode(expRawMode);
+                CheckSingleMode(true);
+
+                int8_t hdr = stream->ReadInt8();
+
+                if (hdr == expHdr)
+                {
+                    int32_t cnt = stream->ReadInt32();
+
+                    if (cnt != 0) 
+                    {
+                        elemId = ++elemIdGen;
+                        elemCnt = cnt;
+                        elemRead = 0;
+
+                        *size = cnt;
+
+                        return elemId;
+                    }
+                    else
+                    {
+                        *size = 0;
+
+                        return ++elemIdGen;
+                    }
+                }
+                else if (hdr == IGNITE_HDR_NULL) {
+                    *size = -1;
+
+                    return ++elemIdGen;
+                }
+                else {
+                    ThrowOnInvalidHeader(expHdr, hdr);
+
+                    return 0;
+                }
+            }
+
+            void PortableReaderImpl::CheckSession(int32_t expSes)
+            {
+                if (elemId != expSes) {
+                    IGNITE_ERROR_1(IgniteError::IGNITE_ERR_PORTABLE, "Containter read session has been finished or is not started yet.");
+                }
+            }
+
+            void PortableReaderImpl::ThrowOnInvalidHeader(int32_t pos, int8_t expHdr, int8_t hdr)
+            {
+                IGNITE_ERROR_FORMATTED_3(IgniteError::IGNITE_ERR_PORTABLE, "Invalid header", "position", pos, "expected", expHdr, "actual", hdr)
+            }
+
+            void PortableReaderImpl::ThrowOnInvalidHeader(int8_t expHdr, int8_t hdr)
+            {
+                int32_t pos = stream->Position() - 1;
+
+                ThrowOnInvalidHeader(pos, expHdr, hdr);
+            }
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/1fc06e01/modules/platform/src/main/cpp/core/src/impl/portable/portable_utils.cpp
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/cpp/core/src/impl/portable/portable_utils.cpp b/modules/platform/src/main/cpp/core/src/impl/portable/portable_utils.cpp
new file mode 100644
index 0000000..2f9c259
--- /dev/null
+++ b/modules/platform/src/main/cpp/core/src/impl/portable/portable_utils.cpp
@@ -0,0 +1,214 @@
+/*
+ * 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/interop/interop.h"
+#include "ignite/impl/portable/portable_utils.h"
+
+using namespace ignite::impl::interop;
+using namespace ignite::impl::portable;
+
+namespace ignite
+{
+    namespace impl
+    {
+        namespace portable
+        {
+            int8_t PortableUtils::ReadInt8(InteropInputStream* stream)
+            {
+                return stream->ReadInt8();
+            }
+
+            void PortableUtils::WriteInt8(InteropOutputStream* stream, int8_t val)
+            {
+                stream->WriteInt8(val); 
+            }
+
+            void PortableUtils::ReadInt8Array(InteropInputStream* stream, int8_t* res, const int32_t len)
+            {
+                stream->ReadInt8Array(res, len);
+            }
+
+            void PortableUtils::WriteInt8Array(InteropOutputStream* stream, const int8_t* val, const int32_t len)
+            {
+                stream->WriteInt8Array(val, len);
+            }
+
+            bool PortableUtils::ReadBool(InteropInputStream* stream)
+            {
+                return stream->ReadBool();
+            }
+
+            void PortableUtils::WriteBool(InteropOutputStream* stream, bool val)
+            {
+                stream->WriteBool(val);
+            }
+
+            void PortableUtils::ReadBoolArray(InteropInputStream* stream, bool* res, const int32_t len)
+            {
+                stream->ReadBoolArray(res, len);
+            }
+
+            void PortableUtils::WriteBoolArray(InteropOutputStream* stream, const bool* val, const int32_t len)
+            {
+                stream->WriteBoolArray(val, len);
+            }
+
+            int16_t PortableUtils::ReadInt16(InteropInputStream* stream)
+            {
+                return stream->ReadInt16();
+            }
+
+            void PortableUtils::WriteInt16(InteropOutputStream* stream, int16_t val)
+            {
+                stream->WriteInt16(val);
+            }
+
+            void PortableUtils::ReadInt16Array(InteropInputStream* stream, int16_t* res, const int32_t len)
+            {
+                stream->ReadInt16Array(res, len);
+            }
+            
+            void PortableUtils::WriteInt16Array(InteropOutputStream* stream, const int16_t* val, const int32_t len)
+            {
+                stream->WriteInt16Array(val, len);
+            }
+
+            uint16_t PortableUtils::ReadUInt16(InteropInputStream* stream)
+            {
+                return stream->ReadUInt16();
+            }
+
+            void PortableUtils::WriteUInt16(InteropOutputStream* stream, uint16_t val)
+            {
+                stream->WriteUInt16(val);
+            }
+
+            void PortableUtils::ReadUInt16Array(InteropInputStream* stream, uint16_t* res, const int32_t len)
+            {
+                stream->ReadUInt16Array(res, len);
+            }
+
+            void PortableUtils::WriteUInt16Array(InteropOutputStream* stream, const uint16_t* val, const int32_t len)
+            {
+                stream->WriteUInt16Array(val, len);
+            }
+
+            int32_t PortableUtils::ReadInt32(InteropInputStream* stream)
+            {
+                return stream->ReadInt32();
+            }
+
+            void PortableUtils::WriteInt32(InteropOutputStream* stream, int32_t val)
+            {
+                stream->WriteInt32(val);
+            }
+
+            void PortableUtils::ReadInt32Array(InteropInputStream* stream, int32_t* res, const int32_t len)
+            {
+                stream->ReadInt32Array(res, len);
+            }
+
+            void PortableUtils::WriteInt32Array(InteropOutputStream* stream, const int32_t* val, const int32_t len)
+            {
+                stream->WriteInt32Array(val, len);
+            }
+
+            int64_t PortableUtils::ReadInt64(InteropInputStream* stream)
+            {
+                return stream->ReadInt64();
+            }
+
+            void PortableUtils::WriteInt64(InteropOutputStream* stream, int64_t val)
+            {
+                stream->WriteInt64(val);
+            }
+
+            void PortableUtils::ReadInt64Array(InteropInputStream* stream, int64_t* res, const int32_t len)
+            {
+                stream->ReadInt64Array(res, len);
+            }
+
+            void PortableUtils::WriteInt64Array(InteropOutputStream* stream, const int64_t* val, const int32_t len)
+            {
+                stream->WriteInt64Array(val, len);
+            }
+
+            float PortableUtils::ReadFloat(InteropInputStream* stream)
+            {
+                return stream->ReadFloat();
+            }
+
+            void PortableUtils::WriteFloat(InteropOutputStream* stream, float val)
+            {
+                stream->WriteFloat(val);
+            }
+
+            void PortableUtils::ReadFloatArray(InteropInputStream* stream, float* res, const int32_t len)
+            {
+                stream->ReadFloatArray(res, len);
+            }
+
+            void PortableUtils::WriteFloatArray(InteropOutputStream* stream, const float* val, const int32_t len)
+            {
+                stream->WriteFloatArray(val, len);
+            }
+
+            double PortableUtils::ReadDouble(InteropInputStream* stream)
+            {
+                return stream->ReadDouble();
+            }
+
+            void PortableUtils::WriteDouble(InteropOutputStream* stream, double val)
+            {
+                stream->WriteDouble(val);
+            }
+
+            void PortableUtils::ReadDoubleArray(InteropInputStream* stream, double* res, const int32_t len)
+            {
+                stream->ReadDoubleArray(res, len);
+            }
+
+            void PortableUtils::WriteDoubleArray(InteropOutputStream* stream, const double* val, const int32_t len)
+            {
+                stream->WriteDoubleArray(val, len);
+            }
+
+            Guid PortableUtils::ReadGuid(interop::InteropInputStream* stream)
+            {
+                int64_t most = stream->ReadInt64();
+                int64_t least = stream->ReadInt64();
+
+                return Guid(most, least);
+            }
+
+            void PortableUtils::WriteGuid(interop::InteropOutputStream* stream, const Guid val)
+            {
+                stream->WriteInt64(val.GetMostSignificantBits());
+                stream->WriteInt64(val.GetLeastSignificantBits());
+            }
+
+            void PortableUtils::WriteString(interop::InteropOutputStream* stream, const char* val, const int32_t len)
+            {
+                stream->WriteBool(false);
+                stream->WriteInt32(len);
+
+                for (int i = 0; i < len; i++)
+                    stream->WriteUInt16(*(val + i));
+            }
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/1fc06e01/modules/platform/src/main/cpp/core/src/impl/portable/portable_writer_impl.cpp
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/cpp/core/src/impl/portable/portable_writer_impl.cpp b/modules/platform/src/main/cpp/core/src/impl/portable/portable_writer_impl.cpp
new file mode 100644
index 0000000..93aacd9
--- /dev/null
+++ b/modules/platform/src/main/cpp/core/src/impl/portable/portable_writer_impl.cpp
@@ -0,0 +1,600 @@
+/*
+ * 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/portable/portable_writer_impl.h"
+#include "ignite/ignite_error.h"
+
+using namespace ignite::impl::interop;
+using namespace ignite::impl::portable;
+using namespace ignite::portable;
+
+namespace ignite
+{
+    namespace impl
+    {
+        namespace portable
+        {
+            PortableWriterImpl::PortableWriterImpl(InteropOutputStream* stream, PortableIdResolver* idRslvr, 
+                PortableMetadataManager* metaMgr, PortableMetadataHandler* metaHnd) :
+                stream(stream), idRslvr(idRslvr), metaMgr(metaMgr), metaHnd(metaHnd), typeId(idRslvr->GetTypeId()),
+                elemIdGen(0), elemId(0), elemCnt(0), elemPos(-1), rawPos(-1)
+            {
+                // No-op.
+            }
+            
+            PortableWriterImpl::PortableWriterImpl(InteropOutputStream* stream, PortableMetadataManager* metaMgr) :
+                stream(stream), idRslvr(NULL), metaMgr(metaMgr), metaHnd(NULL), typeId(0), 
+                elemIdGen(0), elemId(0), elemCnt(0), elemPos(-1), rawPos(0)
+            {
+                // No-op.
+            }
+
+            void PortableWriterImpl::WriteInt8(const int8_t val)
+            {
+                WritePrimitiveRaw<int8_t>(val, PortableUtils::WriteInt8);
+            }
+
+            void PortableWriterImpl::WriteInt8Array(const int8_t* val, const int32_t len)
+            {
+                WritePrimitiveArrayRaw<int8_t>(val, len, PortableUtils::WriteInt8Array, IGNITE_TYPE_ARRAY_BYTE);
+            }
+
+            void PortableWriterImpl::WriteInt8(const char* fieldName, const int8_t val)
+            {
+                WritePrimitive<int8_t>(fieldName, val, PortableUtils::WriteInt8, IGNITE_TYPE_BYTE, 1);
+            }
+
+            void PortableWriterImpl::WriteInt8Array(const char* fieldName, const int8_t* val, const int32_t len)
+            {
+                WritePrimitiveArray<int8_t>(fieldName, val, len, PortableUtils::WriteInt8Array, IGNITE_TYPE_ARRAY_BYTE, 0);
+            }
+
+            void PortableWriterImpl::WriteBool(const bool val)
+            {
+                WritePrimitiveRaw<bool>(val, PortableUtils::WriteBool);
+            }
+
+            void PortableWriterImpl::WriteBoolArray(const bool* val, const int32_t len)
+            {
+                WritePrimitiveArrayRaw<bool>(val, len, PortableUtils::WriteBoolArray, IGNITE_TYPE_ARRAY_BOOL);
+            }
+
+            void PortableWriterImpl::WriteBool(const char* fieldName, const bool val)
+            {
+                WritePrimitive<bool>(fieldName, val, PortableUtils::WriteBool, IGNITE_TYPE_BOOL, 1);
+            }
+
+            void PortableWriterImpl::WriteBoolArray(const char* fieldName, const bool* val, const int32_t len)
+            {
+                WritePrimitiveArray<bool>(fieldName, val, len, PortableUtils::WriteBoolArray, IGNITE_TYPE_ARRAY_BOOL, 0);
+            }
+
+            void PortableWriterImpl::WriteInt16(const int16_t val)
+            {
+                WritePrimitiveRaw<int16_t>(val, PortableUtils::WriteInt16);
+            }
+
+            void PortableWriterImpl::WriteInt16Array(const int16_t* val, const int32_t len)
+            {
+                WritePrimitiveArrayRaw<int16_t>(val, len, PortableUtils::WriteInt16Array, IGNITE_TYPE_ARRAY_SHORT);
+            }
+
+            void PortableWriterImpl::WriteInt16(const char* fieldName, const int16_t val)
+            {
+                WritePrimitive<int16_t>(fieldName, val, PortableUtils::WriteInt16, IGNITE_TYPE_SHORT, 2);
+            }
+
+            void PortableWriterImpl::WriteInt16Array(const char* fieldName, const int16_t* val, const int32_t len)
+            {
+                WritePrimitiveArray<int16_t>(fieldName, val, len, PortableUtils::WriteInt16Array, IGNITE_TYPE_ARRAY_SHORT, 1);
+            }
+
+            void PortableWriterImpl::WriteUInt16(const uint16_t val)
+            {
+                WritePrimitiveRaw<uint16_t>(val, PortableUtils::WriteUInt16);
+            }
+
+            void PortableWriterImpl::WriteUInt16Array(const uint16_t* val, const int32_t len)
+            {
+                WritePrimitiveArrayRaw<uint16_t>(val, len, PortableUtils::WriteUInt16Array, IGNITE_TYPE_ARRAY_CHAR);
+            }
+
+            void PortableWriterImpl::WriteUInt16(const char* fieldName, const uint16_t val)
+            {
+                WritePrimitive<uint16_t>(fieldName, val, PortableUtils::WriteUInt16, IGNITE_TYPE_CHAR, 2);
+            }
+
+            void PortableWriterImpl::WriteUInt16Array(const char* fieldName, const uint16_t* val, const int32_t len)
+            {
+                WritePrimitiveArray<uint16_t>(fieldName, val, len, PortableUtils::WriteUInt16Array, IGNITE_TYPE_ARRAY_CHAR, 1);
+            }
+
+            void PortableWriterImpl::WriteInt32(const int32_t val)
+            {
+                WritePrimitiveRaw<int32_t>(val, PortableUtils::WriteInt32);
+            }
+
+            void PortableWriterImpl::WriteInt32Array(const int32_t* val, const int32_t len)
+            {
+                WritePrimitiveArrayRaw<int32_t>(val, len, PortableUtils::WriteInt32Array, IGNITE_TYPE_ARRAY_INT);
+            }
+
+            void PortableWriterImpl::WriteInt32(const char* fieldName, const int32_t val)
+            {
+                WritePrimitive<int32_t>(fieldName, val, PortableUtils::WriteInt32, IGNITE_TYPE_INT, 4);
+            }
+
+            void PortableWriterImpl::WriteInt32Array(const char* fieldName, const int32_t* val, const int32_t len)
+            {
+                WritePrimitiveArray<int32_t>(fieldName, val, len, PortableUtils::WriteInt32Array, IGNITE_TYPE_ARRAY_INT, 2);
+            }
+
+            void PortableWriterImpl::WriteInt64(const int64_t val)
+            {
+                WritePrimitiveRaw<int64_t>(val, PortableUtils::WriteInt64);
+            }
+
+            void PortableWriterImpl::WriteInt64Array(const int64_t* val, const int32_t len)
+            {
+                WritePrimitiveArrayRaw<int64_t>(val, len, PortableUtils::WriteInt64Array, IGNITE_TYPE_ARRAY_LONG);
+            }
+
+            void PortableWriterImpl::WriteInt64(const char* fieldName, const int64_t val)
+            {
+                WritePrimitive<int64_t>(fieldName, val, PortableUtils::WriteInt64, IGNITE_TYPE_LONG, 8);
+            }
+
+            void PortableWriterImpl::WriteInt64Array(const char* fieldName, const int64_t* val, const int32_t len)
+            {
+                WritePrimitiveArray<int64_t>(fieldName, val, len, PortableUtils::WriteInt64Array, IGNITE_TYPE_ARRAY_LONG, 3);
+            }
+
+            void PortableWriterImpl::WriteFloat(const float val)
+            {
+                WritePrimitiveRaw<float>(val, PortableUtils::WriteFloat);
+            }
+
+            void PortableWriterImpl::WriteFloatArray(const float* val, const int32_t len)
+            {
+                WritePrimitiveArrayRaw<float>(val, len, PortableUtils::WriteFloatArray, IGNITE_TYPE_ARRAY_FLOAT);
+            }
+
+            void PortableWriterImpl::WriteFloat(const char* fieldName, const float val)
+            {
+                WritePrimitive<float>(fieldName, val, PortableUtils::WriteFloat, IGNITE_TYPE_FLOAT, 4);
+            }
+
+            void PortableWriterImpl::WriteFloatArray(const char* fieldName, const float* val, const int32_t len)
+            {
+                WritePrimitiveArray<float>(fieldName, val, len, PortableUtils::WriteFloatArray, IGNITE_TYPE_ARRAY_FLOAT, 2);
+            }
+
+            void PortableWriterImpl::WriteDouble(const double val)
+            {
+                WritePrimitiveRaw<double>(val, PortableUtils::WriteDouble);
+            }
+
+            void PortableWriterImpl::WriteDoubleArray(const double* val, const int32_t len)
+            {
+                WritePrimitiveArrayRaw<double>(val, len, PortableUtils::WriteDoubleArray, IGNITE_TYPE_ARRAY_DOUBLE);
+            }
+
+            void PortableWriterImpl::WriteDouble(const char* fieldName, const double val)
+            {
+                WritePrimitive<double>(fieldName, val, PortableUtils::WriteDouble, IGNITE_TYPE_DOUBLE, 8);
+            }
+
+            void PortableWriterImpl::WriteDoubleArray(const char* fieldName, const double* val, const int32_t len)
+            {
+                WritePrimitiveArray<double>(fieldName, val, len, PortableUtils::WriteDoubleArray, IGNITE_TYPE_ARRAY_DOUBLE, 3);
+            }
+
+            void PortableWriterImpl::WriteGuid(const Guid val)
+            {                
+                CheckRawMode(true);
+                CheckSingleMode(true);
+
+                stream->WriteInt8(IGNITE_TYPE_UUID);
+
+                PortableUtils::WriteGuid(stream, val);
+            }
+
+            void PortableWriterImpl::WriteGuidArray(const Guid* val, const int32_t len)
+            {
+                CheckRawMode(true);
+                CheckSingleMode(true);
+                
+                if (val)
+                {
+                    stream->WriteInt8(IGNITE_TYPE_ARRAY_UUID);
+                    stream->WriteInt32(len);
+
+                    for (int i = 0; i < len; i++)
+                    {
+                        Guid elem = *(val + i);
+
+                        stream->WriteInt8(IGNITE_TYPE_UUID);
+                        PortableUtils::WriteGuid(stream, elem);
+                    }
+                }
+                else
+                    stream->WriteInt8(IGNITE_HDR_NULL);
+            }
+
+            void PortableWriterImpl::WriteGuid(const char* fieldName, const Guid val)
+            {
+                CheckRawMode(false);
+                CheckSingleMode(true);
+
+                WriteFieldIdAndLength(fieldName, IGNITE_TYPE_UUID, 1 + 16);
+
+                stream->WriteInt8(IGNITE_TYPE_UUID);
+
+                PortableUtils::WriteGuid(stream, val);
+            }
+
+            void PortableWriterImpl::WriteGuidArray(const char* fieldName, const Guid* val, const int32_t len)
+            {
+                CheckRawMode(false);
+                CheckSingleMode(true);
+
+                WriteFieldId(fieldName, IGNITE_TYPE_ARRAY_UUID);
+
+                if (val)
+                {
+                    stream->WriteInt32(5 + len * 17);
+                    stream->WriteInt8(IGNITE_TYPE_ARRAY_UUID);
+                    stream->WriteInt32(len);
+
+                    for (int i = 0; i < len; i++)
+                    {
+                        Guid elem = *(val + i);
+
+                        WriteTopObject(elem);
+                    }
+                }
+                else
+                {
+                    stream->WriteInt32(1);
+                    stream->WriteInt8(IGNITE_HDR_NULL);
+                }
+            }
+
+            void PortableWriterImpl::WriteString(const char* val, const int32_t len)
+            {
+                CheckRawMode(true);
+                CheckSingleMode(true);
+
+                if (val) 
+                {
+                    stream->WriteInt8(IGNITE_TYPE_STRING);
+
+                    PortableUtils::WriteString(stream, val, len);
+                }
+                else
+                    stream->WriteInt8(IGNITE_HDR_NULL);
+            }
+
+            void PortableWriterImpl::WriteString(const char* fieldName, const char* val, const int32_t len)
+            {
+                CheckRawMode(false);
+                CheckSingleMode(true);
+
+                WriteFieldId(fieldName, IGNITE_TYPE_STRING);
+                
+                if (val)
+                {
+                    int32_t lenPos = stream->Position();
+                    stream->Position(lenPos + 4);
+
+                    stream->WriteInt8(IGNITE_TYPE_STRING);
+                    stream->WriteBool(false);
+                    stream->WriteInt32(len);
+
+                    for (int i = 0; i < len; i++)
+                        stream->WriteUInt16(*(val + i));
+
+                    stream->WriteInt32(lenPos, stream->Position() - lenPos - 4);
+                }
+                else
+                {
+                    stream->WriteInt32(1);
+                    stream->WriteInt8(IGNITE_HDR_NULL);
+                }
+            }
+
+            int32_t PortableWriterImpl::WriteStringArray()
+            {
+                StartContainerSession(true);
+
+                stream->WriteInt8(IGNITE_TYPE_ARRAY_STRING);
+                stream->Position(stream->Position() + 4);
+
+                return elemId;
+            }
+
+            int32_t PortableWriterImpl::WriteStringArray(const char* fieldName)
+            {
+                StartContainerSession(false);
+
+                WriteFieldIdSkipLength(fieldName, IGNITE_TYPE_ARRAY_STRING);
+
+                stream->WriteInt8(IGNITE_TYPE_ARRAY_STRING);
+                stream->Position(stream->Position() + 4);
+
+                return elemId;
+            }
+
+            void PortableWriterImpl::WriteStringElement(int32_t id, const char* val, int32_t len)
+            {
+                CheckSession(id);
+
+                if (val)
+                {
+                    stream->WriteInt8(IGNITE_TYPE_STRING);
+
+                    PortableUtils::WriteString(stream, val, len);
+                }
+                else
+                    stream->WriteInt8(IGNITE_HDR_NULL);
+
+                elemCnt++;
+            }
+
+            void PortableWriterImpl::WriteNull()
+            {
+                CheckRawMode(true);
+                CheckSingleMode(true);
+
+                stream->WriteInt8(IGNITE_HDR_NULL);
+            }
+
+            void PortableWriterImpl::WriteNull(const char* fieldName)
+            {
+                CheckRawMode(false);
+                CheckSingleMode(true);
+
+                WriteFieldIdAndLength(fieldName, IGNITE_TYPE_OBJECT, 1);
+                stream->WriteInt8(IGNITE_HDR_NULL);
+            }
+
+            int32_t PortableWriterImpl::WriteArray()
+            {
+                StartContainerSession(true);
+                
+                stream->WriteInt8(IGNITE_TYPE_ARRAY);
+                stream->Position(stream->Position() + 4);
+
+                return elemId;
+            }
+
+            int32_t PortableWriterImpl::WriteArray(const char* fieldName)
+            {
+                StartContainerSession(false);
+
+                WriteFieldIdSkipLength(fieldName, IGNITE_TYPE_ARRAY);
+
+                stream->WriteInt8(IGNITE_TYPE_ARRAY);
+                stream->Position(stream->Position() + 4);
+
+                return elemId;
+            }
+
+            int32_t PortableWriterImpl::WriteCollection(CollectionType typ)
+            {
+                StartContainerSession(true);
+
+                stream->WriteInt8(IGNITE_TYPE_COLLECTION);
+                stream->Position(stream->Position() + 4);
+                stream->WriteInt8(typ);
+
+                return elemId;
+            }
+
+            int32_t PortableWriterImpl::WriteCollection(const char* fieldName, CollectionType typ)
+            {
+                StartContainerSession(false);
+                
+                WriteFieldIdSkipLength(fieldName, IGNITE_TYPE_COLLECTION);
+
+                stream->WriteInt8(IGNITE_TYPE_COLLECTION);
+                stream->Position(stream->Position() + 4);
+                stream->WriteInt8(typ);
+
+                return elemId;
+            }
+
+            int32_t PortableWriterImpl::WriteMap(ignite::portable::MapType typ)
+            {
+                StartContainerSession(true);
+
+                stream->WriteInt8(IGNITE_TYPE_MAP);
+                stream->Position(stream->Position() + 4);
+                stream->WriteInt8(typ);
+
+                return elemId;
+            }
+
+            int32_t PortableWriterImpl::WriteMap(const char* fieldName, ignite::portable::MapType typ)
+            {
+                StartContainerSession(false);
+
+                WriteFieldIdSkipLength(fieldName, IGNITE_TYPE_MAP);
+                
+                stream->WriteInt8(IGNITE_TYPE_MAP);
+                stream->Position(stream->Position() + 4);
+                stream->WriteInt8(typ);
+
+                return elemId;
+            }
+
+            void PortableWriterImpl::CommitContainer(int32_t id)
+            {
+                CheckSession(id);
+
+                if (rawPos == -1)
+                {
+                    int32_t len = stream->Position() - elemPos - 4;
+
+                    stream->WriteInt32(elemPos + 4, len);
+                    stream->WriteInt32(elemPos + 9, elemCnt);
+                }
+                else
+                    stream->WriteInt32(elemPos + 1, elemCnt);
+
+                elemId = 0;
+                elemCnt = 0;
+                elemPos = -1;
+            }
+            
+            void PortableWriterImpl::SetRawMode()
+            {
+                CheckRawMode(false);
+                CheckSingleMode(true);
+
+                rawPos = stream->Position();
+            }
+
+            int32_t PortableWriterImpl::GetRawPosition()
+            {
+                return rawPos == -1 ? stream->Position() : rawPos;
+            }
+
+            void PortableWriterImpl::CheckRawMode(bool expected)
+            {
+                bool rawMode = rawPos != -1;
+
+                if (expected && !rawMode) {
+                    IGNITE_ERROR_1(IgniteError::IGNITE_ERR_PORTABLE, "Operation can be performed only in raw mode.");
+                }
+                else if (!expected && rawMode) {
+                    IGNITE_ERROR_1(IgniteError::IGNITE_ERR_PORTABLE, "Operation cannot be performed in raw mode.");
+                }
+            }
+
+            void PortableWriterImpl::CheckSingleMode(bool expected)
+            {
+                if (expected && elemId != 0) {
+                    IGNITE_ERROR_1(IgniteError::IGNITE_ERR_PORTABLE, "Operation cannot be performed when container is being written.");
+                }
+                else if (!expected && elemId == 0) {
+                    IGNITE_ERROR_1(IgniteError::IGNITE_ERR_PORTABLE, "Operation can be performed only when container is being written.");
+                }
+            }
+
+            void PortableWriterImpl::StartContainerSession(bool expRawMode)
+            {
+                CheckRawMode(expRawMode);
+                CheckSingleMode(true);
+
+                elemId = ++elemIdGen;
+                elemPos = stream->Position();
+            }
+
+            void PortableWriterImpl::CheckSession(int32_t expSes)
+            {
+                if (elemId != expSes) 
+                {
+                    IGNITE_ERROR_1(IgniteError::IGNITE_ERR_PORTABLE, "Containter write session has been finished or is not started yet.");
+                }
+            }
+
+            void PortableWriterImpl::WriteFieldId(const char* fieldName, int32_t fieldTypeId)
+            {
+                int32_t fieldId = idRslvr->GetFieldId(typeId, fieldName);
+                
+                stream->WriteInt32(fieldId);
+
+                if (metaHnd)
+                    metaHnd->OnFieldWritten(fieldId, fieldName, fieldTypeId);
+            }
+
+            void PortableWriterImpl::WriteFieldIdSkipLength(const char* fieldName, int32_t fieldTypeId)
+            {
+                WriteFieldId(fieldName, fieldTypeId);
+
+                stream->Position(stream->Position() + 4);
+            }
+
+            void PortableWriterImpl::WriteFieldIdAndLength(const char* fieldName, int32_t fieldTypeId, int32_t len)
+            {
+                WriteFieldId(fieldName, fieldTypeId);
+
+                stream->WriteInt32(len);
+            }
+            
+            template <>
+            void PortableWriterImpl::WriteTopObject<int8_t>(const int8_t& obj)
+            {
+                WriteTopObject0<int8_t>(obj, PortableUtils::WriteInt8, IGNITE_TYPE_BYTE);
+            }
+
+            template <>
+            void PortableWriterImpl::WriteTopObject<bool>(const bool& obj)
+            {
+                WriteTopObject0<bool>(obj, PortableUtils::WriteBool, IGNITE_TYPE_BOOL);
+            }
+
+            template <>
+            void PortableWriterImpl::WriteTopObject<int16_t>(const int16_t& obj)
+            {
+                WriteTopObject0<int16_t>(obj, PortableUtils::WriteInt16, IGNITE_TYPE_SHORT);
+            }
+
+            template <>
+            void PortableWriterImpl::WriteTopObject<uint16_t>(const uint16_t& obj)
+            {
+                WriteTopObject0<uint16_t>(obj, PortableUtils::WriteUInt16, IGNITE_TYPE_CHAR);
+            }
+
+            template <>
+            void PortableWriterImpl::WriteTopObject<int32_t>(const int32_t& obj)
+            {
+                WriteTopObject0<int32_t>(obj, PortableUtils::WriteInt32, IGNITE_TYPE_INT);
+            }
+
+            template <>
+            void PortableWriterImpl::WriteTopObject<int64_t>(const int64_t& obj)
+            {
+                WriteTopObject0<int64_t>(obj, PortableUtils::WriteInt64, IGNITE_TYPE_LONG);
+            }
+
+            template <>
+            void PortableWriterImpl::WriteTopObject<float>(const float& obj)
+            {
+                WriteTopObject0<float>(obj, PortableUtils::WriteFloat, IGNITE_TYPE_FLOAT);
+            }
+
+            template <>
+            void PortableWriterImpl::WriteTopObject<double>(const double& obj)
+            {
+                WriteTopObject0<double>(obj, PortableUtils::WriteDouble, IGNITE_TYPE_DOUBLE);
+            }
+
+            template <>
+            void PortableWriterImpl::WriteTopObject<Guid>(const Guid& obj)
+            {
+                WriteTopObject0<Guid>(obj, PortableUtils::WriteGuid, IGNITE_TYPE_UUID);
+            }
+
+            InteropOutputStream* PortableWriterImpl::GetStream()
+            {
+                return stream;
+            }
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/1fc06e01/modules/platform/src/main/cpp/core/src/portable/portable_containers.cpp
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/cpp/core/src/portable/portable_containers.cpp b/modules/platform/src/main/cpp/core/src/portable/portable_containers.cpp
new file mode 100644
index 0000000..8270a13
--- /dev/null
+++ b/modules/platform/src/main/cpp/core/src/portable/portable_containers.cpp
@@ -0,0 +1,76 @@
+/*
+ * 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/portable/portable_containers.h"
+
+using namespace ignite::impl::portable;
+
+namespace ignite
+{
+    namespace portable
+    {
+        PortableStringArrayWriter::PortableStringArrayWriter(PortableWriterImpl* impl, const int32_t id) : 
+            impl(impl), id(id)
+        {
+            // No-op.
+        }
+
+        void PortableStringArrayWriter::Write(const char* val)
+        {
+            if (val)
+                Write(val, static_cast<int32_t>(strlen(val)));
+            else
+                Write(NULL, -1);
+        }
+
+        void PortableStringArrayWriter::Write(const char* val, const int32_t len)
+        {
+            impl->WriteStringElement(id, val, len);
+        }
+
+        void PortableStringArrayWriter::Close()
+        {
+            impl->CommitContainer(id);
+        }
+
+        PortableStringArrayReader::PortableStringArrayReader(impl::portable::PortableReaderImpl* impl, 
+            int32_t id, int32_t size) : impl(impl), id(id), size(size)
+        {
+            // No-op.
+        }
+
+        bool PortableStringArrayReader::HasNext()
+        {
+            return impl->HasNextElement(id);
+        }
+
+        int32_t PortableStringArrayReader::GetNext(char* res, const int32_t len)
+        {
+            return impl->ReadStringElement(id, res, len);
+        }
+
+        int32_t PortableStringArrayReader::GetSize()
+        {
+            return size;
+        }
+
+        bool PortableStringArrayReader::IsNull()
+        {
+            return size == -1;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/1fc06e01/modules/platform/src/main/cpp/core/src/portable/portable_raw_reader.cpp
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/cpp/core/src/portable/portable_raw_reader.cpp b/modules/platform/src/main/cpp/core/src/portable/portable_raw_reader.cpp
new file mode 100644
index 0000000..f659913
--- /dev/null
+++ b/modules/platform/src/main/cpp/core/src/portable/portable_raw_reader.cpp
@@ -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.
+ */
+#include "ignite/impl/portable/portable_reader_impl.h"
+#include "ignite/portable/portable_raw_reader.h"
+
+using namespace ignite::impl::portable;
+
+namespace ignite
+{
+    namespace portable
+    {        
+        PortableRawReader::PortableRawReader(PortableReaderImpl* impl) : impl(impl)
+        {
+            // No-op.
+        }
+        
+        int8_t PortableRawReader::ReadInt8()
+        {
+            return impl->ReadInt8();
+        }
+
+        int32_t PortableRawReader::ReadInt8Array(int8_t* res, const int32_t len)
+        {
+            return impl->ReadInt8Array(res, len);
+        }
+        
+        bool PortableRawReader::ReadBool()
+        {
+            return impl->ReadBool();
+        }
+
+        int32_t PortableRawReader::ReadBoolArray(bool* res, const int32_t len)
+        {
+            return impl->ReadBoolArray(res, len);
+        }
+
+        int16_t PortableRawReader::ReadInt16()
+        {
+            return impl->ReadInt16();
+        }
+        
+        int32_t PortableRawReader::ReadInt16Array(int16_t* res, const int32_t len)
+        {
+            return impl->ReadInt16Array(res, len);
+        }
+
+        uint16_t PortableRawReader::ReadUInt16()
+        {
+            return impl->ReadUInt16();
+        }
+
+        int32_t PortableRawReader::ReadUInt16Array(uint16_t* res, const int32_t len)
+        {
+            return impl->ReadUInt16Array(res, len);
+        }
+
+        int32_t PortableRawReader::ReadInt32()
+        {
+            return impl->ReadInt32();
+        }
+        
+        int32_t PortableRawReader::ReadInt32Array(int32_t* res, const int32_t len)
+        {
+            return impl->ReadInt32Array(res, len);
+        }
+
+        int64_t PortableRawReader::ReadInt64()
+        {
+            return impl->ReadInt64();
+        }
+
+        int32_t PortableRawReader::ReadInt64Array(int64_t* res, const int32_t len)
+        {
+            return impl->ReadInt64Array(res, len);
+        }
+
+        float PortableRawReader::ReadFloat()
+        {
+            return impl->ReadFloat();
+        }
+        
+        int32_t PortableRawReader::ReadFloatArray(float* res, const int32_t len)
+        {
+            return impl->ReadFloatArray(res, len);
+        }
+
+        double PortableRawReader::ReadDouble()
+        {
+            return impl->ReadDouble();
+        }
+        
+        int32_t PortableRawReader::ReadDoubleArray(double* res, const int32_t len)
+        {
+            return impl->ReadDoubleArray(res, len);
+        }
+        
+        Guid PortableRawReader::ReadGuid()
+        {
+            return impl->ReadGuid();
+        }
+
+        int32_t PortableRawReader::ReadGuidArray(Guid* res, const int32_t len)
+        {
+            return impl->ReadGuidArray(res, len);
+        }        
+
+        int32_t PortableRawReader::ReadString(char* res, const int32_t len)
+        {
+            return impl->ReadString(res, len);
+        }
+
+        PortableStringArrayReader PortableRawReader::ReadStringArray()
+        {
+            int32_t size;
+
+            int32_t id = impl->ReadStringArray(&size);
+
+            return PortableStringArrayReader(impl, id, size);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/1fc06e01/modules/platform/src/main/cpp/core/src/portable/portable_raw_writer.cpp
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/cpp/core/src/portable/portable_raw_writer.cpp b/modules/platform/src/main/cpp/core/src/portable/portable_raw_writer.cpp
new file mode 100644
index 0000000..c682abe
--- /dev/null
+++ b/modules/platform/src/main/cpp/core/src/portable/portable_raw_writer.cpp
@@ -0,0 +1,147 @@
+/*
+ * 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/portable/portable_writer_impl.h"
+#include "ignite/portable/portable_raw_writer.h"
+
+using namespace ignite::impl::portable;
+
+namespace ignite
+{
+    namespace portable
+    {
+        PortableRawWriter::PortableRawWriter(PortableWriterImpl* impl) : impl(impl)
+        {
+            // No-op.
+        }
+
+        void PortableRawWriter::WriteInt8(const int8_t val)
+        {
+            impl->WriteInt8(val);
+        }
+
+        void PortableRawWriter::WriteInt8Array(const int8_t* val, const int32_t len)
+        {
+            impl->WriteInt8Array(val, len);
+        }
+
+        void PortableRawWriter::WriteBool(const bool val)
+        {
+            impl->WriteBool(val);
+        }
+
+        void PortableRawWriter::WriteBoolArray(const bool* val, const int32_t len)
+        {            
+            impl->WriteBoolArray(val, len);
+        }
+
+        void PortableRawWriter::WriteInt16(const int16_t val)
+        {
+            impl->WriteInt16(val);
+        }
+
+        void PortableRawWriter::WriteInt16Array(const int16_t* val, const int32_t len)
+        {
+            impl->WriteInt16Array(val, len);
+        }
+
+        void PortableRawWriter::WriteUInt16(const uint16_t val)
+        {
+            impl->WriteUInt16(val);
+        }
+
+        void PortableRawWriter::WriteUInt16Array(const uint16_t* val, const int32_t len)
+        {
+            impl->WriteUInt16Array(val, len);
+        }
+
+        void PortableRawWriter::WriteInt32(const int32_t val)
+        {
+            impl->WriteInt32(val);
+        }
+
+        void PortableRawWriter::WriteInt32Array(const int32_t* val, const int32_t len)
+        {
+            impl->WriteInt32Array(val, len);
+        }
+
+        void PortableRawWriter::WriteInt64(const int64_t val)
+        {
+            impl->WriteInt64(val);
+        }
+
+        void PortableRawWriter::WriteInt64Array(const int64_t* val, const int32_t len)
+        {
+            impl->WriteInt64Array(val, len);
+        }
+
+        void PortableRawWriter::WriteFloat(const float val)
+        {
+            impl->WriteFloat(val);
+        }
+
+        void PortableRawWriter::WriteFloatArray(const float* val, const int32_t len)
+        {
+            impl->WriteFloatArray(val, len);
+        }
+
+        void PortableRawWriter::WriteDouble(const double val)
+        {
+            impl->WriteDouble(val);
+        }
+
+        void PortableRawWriter::WriteDoubleArray(const double* val, const int32_t len)
+        {
+            impl->WriteDoubleArray(val, len);
+        }
+
+        void PortableRawWriter::WriteGuid(const Guid val)
+        {
+            impl->WriteGuid(val);
+        }
+
+        void PortableRawWriter::WriteGuidArray(const Guid* val, const int32_t len)
+        {
+            impl->WriteGuidArray(val, len);
+        }
+
+        void PortableRawWriter::WriteString(const char* val)
+        {
+            if (val)
+                WriteString(val, static_cast<int32_t>(strlen(val)));
+            else
+                WriteNull();
+        }
+
+        void PortableRawWriter::WriteString(const char* val, const int32_t len)
+        {
+            impl->WriteString(val, len);
+        }
+
+        PortableStringArrayWriter PortableRawWriter::WriteStringArray()
+        {
+            int32_t id = impl->WriteStringArray();
+
+            return PortableStringArrayWriter(impl, id);
+        }
+
+        void PortableRawWriter::WriteNull()
+        {
+            impl->WriteNull();
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/1fc06e01/modules/platform/src/main/cpp/core/src/portable/portable_reader.cpp
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/cpp/core/src/portable/portable_reader.cpp b/modules/platform/src/main/cpp/core/src/portable/portable_reader.cpp
new file mode 100644
index 0000000..515216d
--- /dev/null
+++ b/modules/platform/src/main/cpp/core/src/portable/portable_reader.cpp
@@ -0,0 +1,142 @@
+/*
+ * 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/portable/portable_reader_impl.h"
+#include "ignite/portable/portable_reader.h"
+
+using namespace ignite::impl::portable;
+
+namespace ignite
+{
+    namespace portable
+    {
+        PortableReader::PortableReader(PortableReaderImpl* impl) : impl(impl)
+        {
+            // No-op.
+        }
+        
+        int8_t PortableReader::ReadInt8(const char* fieldName)
+        {
+            return impl->ReadInt8(fieldName);
+        }
+
+        int32_t PortableReader::ReadInt8Array(const char* fieldName, int8_t* res, const int32_t len)
+        {
+            return impl->ReadInt8Array(fieldName, res, len);
+        }
+
+        bool PortableReader::ReadBool(const char* fieldName)
+        {
+            return impl->ReadBool(fieldName);
+        }
+
+        int32_t PortableReader::ReadBoolArray(const char* fieldName, bool* res, const int32_t len)
+        {
+            return impl->ReadBoolArray(fieldName, res, len);
+        }
+
+        int16_t PortableReader::ReadInt16(const char* fieldName)
+        {
+            return impl->ReadInt16(fieldName);
+        }
+
+        int32_t PortableReader::ReadInt16Array(const char* fieldName, int16_t* res, const int32_t len)
+        {
+            return impl->ReadInt16Array(fieldName, res, len);
+        }
+
+        uint16_t PortableReader::ReadUInt16(const char* fieldName)
+        {
+            return impl->ReadUInt16(fieldName);
+        }
+
+        int32_t PortableReader::ReadUInt16Array(const char* fieldName, uint16_t* res, const int32_t len)
+        {
+            return impl->ReadUInt16Array(fieldName, res, len);
+        }
+
+        int32_t PortableReader::ReadInt32(const char* fieldName)
+        {
+            return impl->ReadInt32(fieldName);
+        }
+
+        int32_t PortableReader::ReadInt32Array(const char* fieldName, int32_t* res, const int32_t len)
+        {
+            return impl->ReadInt32Array(fieldName, res, len);
+        }
+
+        int64_t PortableReader::ReadInt64(const char* fieldName)
+        {
+            return impl->ReadInt64(fieldName);
+        }
+
+        int32_t PortableReader::ReadInt64Array(const char* fieldName, int64_t* res, const int32_t len)
+        {
+            return impl->ReadInt64Array(fieldName, res, len);
+        }
+
+        float PortableReader::ReadFloat(const char* fieldName)
+        {
+            return impl->ReadFloat(fieldName);
+        }
+
+        int32_t PortableReader::ReadFloatArray(const char* fieldName, float* res, const int32_t len)
+        {
+            return impl->ReadFloatArray(fieldName, res, len);
+        }
+
+        double PortableReader::ReadDouble(const char* fieldName)
+        {
+            return impl->ReadDouble(fieldName);
+        }
+
+        int32_t PortableReader::ReadDoubleArray(const char* fieldName, double* res, const int32_t len)
+        {
+            return impl->ReadDoubleArray(fieldName, res, len);
+        }
+
+        Guid PortableReader::ReadGuid(const char* fieldName)
+        {
+            return impl->ReadGuid(fieldName);
+        }
+
+        int32_t PortableReader::ReadGuidArray(const char* fieldName, Guid* res, const int32_t len)
+        {
+            return impl->ReadGuidArray(fieldName, res, len);
+        }
+        
+        int32_t PortableReader::ReadString(const char* fieldName, char* res, const int32_t len)
+        {
+            return impl->ReadString(fieldName, res, len);
+        }
+
+        PortableStringArrayReader PortableReader::ReadStringArray(const char* fieldName)
+        {
+            int32_t size;
+
+            int32_t id = impl->ReadStringArray(fieldName, &size);
+
+            return PortableStringArrayReader(impl, id, size);
+        }
+
+        PortableRawReader PortableReader::RawReader()
+        {
+            impl->SetRawMode();
+
+            return PortableRawReader(impl);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/1fc06e01/modules/platform/src/main/cpp/core/src/portable/portable_type.cpp
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/cpp/core/src/portable/portable_type.cpp b/modules/platform/src/main/cpp/core/src/portable/portable_type.cpp
new file mode 100644
index 0000000..e22f869
--- /dev/null
+++ b/modules/platform/src/main/cpp/core/src/portable/portable_type.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/portable/portable_type.h"
+
+namespace ignite
+{
+    namespace portable
+    {
+        int32_t GetPortableStringHashCode(const char* val)
+        {
+            if (val)
+            {
+                int32_t hash = 0;
+
+                int i = 0;
+
+                while (true)
+                {
+                    char c = *(val + i++);
+
+                    if (c == '\0')
+                        break;
+
+                    if ('A' <= c && c <= 'Z')
+                        c = c | 0x20;
+
+                    hash = 31 * hash + c;
+                }
+
+                return hash;
+            }
+            else
+                return 0;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/1fc06e01/modules/platform/src/main/cpp/core/src/portable/portable_writer.cpp
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/cpp/core/src/portable/portable_writer.cpp b/modules/platform/src/main/cpp/core/src/portable/portable_writer.cpp
new file mode 100644
index 0000000..f31b9dd
--- /dev/null
+++ b/modules/platform/src/main/cpp/core/src/portable/portable_writer.cpp
@@ -0,0 +1,154 @@
+/*
+ * 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/portable/portable_writer_impl.h"
+#include "ignite/portable/portable_writer.h"
+
+using namespace ignite::impl::portable;
+
+namespace ignite
+{
+    namespace portable
+    {
+        PortableWriter::PortableWriter(PortableWriterImpl* impl) : impl(impl)
+        {
+            // No-op.
+        }
+
+        void PortableWriter::WriteInt8(const char* fieldName, const int8_t val)
+        {
+            impl->WriteInt8(fieldName, val);
+        }
+
+        void PortableWriter::WriteInt8Array(const char* fieldName, const int8_t* val, const int32_t len)
+        {
+            impl->WriteInt8Array(fieldName, val, len);
+        }
+
+        void PortableWriter::WriteBool(const char* fieldName, const bool val)
+        {
+            impl->WriteBool(fieldName, val);
+        }
+
+        void PortableWriter::WriteBoolArray(const char* fieldName, const bool* val, const int32_t len)
+        {
+            impl->WriteBoolArray(fieldName, val, len);
+        }
+
+        void PortableWriter::WriteInt16(const char* fieldName, const int16_t val)
+        {
+            impl->WriteInt16(fieldName, val);
+        }
+
+        void PortableWriter::WriteInt16Array(const char* fieldName, const int16_t* val, const int32_t len)
+        {
+            impl->WriteInt16Array(fieldName, val, len);
+        }
+
+        void PortableWriter::WriteUInt16(const char* fieldName, const uint16_t val)
+        {
+            impl->WriteUInt16(fieldName, val);
+        }
+
+        void PortableWriter::WriteUInt16Array(const char* fieldName, const uint16_t* val, const int32_t len)
+        {
+            impl->WriteUInt16Array(fieldName, val, len);
+        }
+
+        void PortableWriter::WriteInt32(const char* fieldName, const int32_t val)
+        {
+            impl->WriteInt32(fieldName, val);
+        }
+
+        void PortableWriter::WriteInt32Array(const char* fieldName, const int32_t* val, const int32_t len)
+        {
+            impl->WriteInt32Array(fieldName, val, len);
+        }
+
+        void PortableWriter::WriteInt64(const char* fieldName, const int64_t val)
+        {
+            impl->WriteInt64(fieldName, val);
+        }
+
+        void PortableWriter::WriteInt64Array(const char* fieldName, const int64_t* val, const int32_t len)
+        {
+            impl->WriteInt64Array(fieldName, val, len);
+        }
+
+        void PortableWriter::WriteFloat(const char* fieldName, const float val)
+        {
+            impl->WriteFloat(fieldName, val);
+        }
+
+        void PortableWriter::WriteFloatArray(const char* fieldName, const float* val, const int32_t len)
+        {
+            impl->WriteFloatArray(fieldName, val, len);
+        }
+
+        void PortableWriter::WriteDouble(const char* fieldName, const double val)
+        {
+            impl->WriteDouble(fieldName, val);
+        }
+
+        void PortableWriter::WriteDoubleArray(const char* fieldName, const double* val, const int32_t len)
+        {
+            impl->WriteDoubleArray(fieldName, val, len);
+        }
+
+        void PortableWriter::WriteGuid(const char* fieldName, const Guid val)
+        {
+            impl->WriteGuid(fieldName, val);
+        }
+
+        void PortableWriter::WriteGuidArray(const char* fieldName, const Guid* val, const int32_t len)
+        {
+            impl->WriteGuidArray(fieldName, val, len);
+        }
+
+        void PortableWriter::WriteString(const char* fieldName, const char* val)
+        {
+            if (val)
+                WriteString(fieldName, val, static_cast<int32_t>(strlen(val)));
+            else
+                WriteNull(fieldName);
+        }
+
+        void PortableWriter::WriteString(const char* fieldName, const char* val, const int32_t len)
+        {
+            impl->WriteString(fieldName, val, len);
+        }
+
+        PortableStringArrayWriter PortableWriter::WriteStringArray(const char* fieldName)
+        {
+            int32_t id = impl->WriteStringArray(fieldName);
+
+            return PortableStringArrayWriter(impl, id);
+        }
+
+        void PortableWriter::WriteNull(const char* fieldName)
+        {
+            impl->WriteNull(fieldName);
+        }
+
+        PortableRawWriter PortableWriter::RawWriter()
+        {
+            impl->SetRawMode();
+
+            return PortableRawWriter(impl);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/1fc06e01/parent/pom.xml
----------------------------------------------------------------------
diff --git a/parent/pom.xml b/parent/pom.xml
index ebe691f..d003cff 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -739,15 +739,19 @@
                                         <exclude>src/main/dotnet/Apache.Ignite.sln</exclude>
                                         <exclude>src/main/dotnet/Apache.Ignite.sln.DotSettings</exclude>
                                         <exclude>src/main/java/META-INF/services/org.apache.ignite.internal.processors.platform.PlatformBootstrapFactory</exclude>
+                                        <exclude>src/main/resources/META-INF/services/org.apache.ignite.internal.processors.platform.PlatformBootstrapFactory</exclude>
                                         <exclude>src/test/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj</exclude>
                                         <exclude>src/test/portables/repo/org/apache/ignite/portable/test1/1.1/test1-1.1.jar</exclude>
                                         <exclude>src/test/portables/repo/org/apache/ignite/portable/test2/1.1/test2-1.1.jar</exclude>
                                         <exclude>**/Makefile.am</exclude>
                                         <exclude>**/configure.ac</exclude>
+                                        <exclude>**/*.pc.in</exclude>
                                         <exclude>**/*.vcxproj</exclude>
+                                        <exclude>**/*.vcxprojrel</exclude>
                                         <exclude>**/*.vcxproj.filters</exclude>
+                                        <exclude>**/*.sln</exclude>
+                                        <exclude>**/*.slnrel</exclude>
                                         <exclude>**/module.def</exclude>
-                                        <exclude>**/ignite-common.pc.in</exclude>
                                     </excludes>
                                 </configuration>
                             </execution>


Mime
View raw message