You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2015/10/30 16:52:40 UTC

[44/52] [abbrv] ignite git commit: IGNITE-1770: Implemented constant-time field lookup on protocol level.

http://git-wip-us.apache.org/repos/asf/ignite/blob/b85fa171/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableReaderExImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableReaderExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableReaderExImpl.java
index 5d1460c..3d47cb0 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableReaderExImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableReaderExImpl.java
@@ -24,7 +24,9 @@ import org.apache.ignite.internal.util.GridEnumCache;
 import org.apache.ignite.internal.util.lang.GridMapEntry;
 import org.apache.ignite.internal.util.typedef.internal.SB;
 import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgniteBiTuple;
 import org.apache.ignite.portable.PortableException;
+import org.apache.ignite.portable.PortableIdMapper;
 import org.apache.ignite.portable.PortableInvalidClassException;
 import org.apache.ignite.portable.PortableObject;
 import org.apache.ignite.portable.PortableRawReader;
@@ -63,7 +65,6 @@ import static org.apache.ignite.internal.portable.GridPortableMarshaller.BYTE_AR
 import static org.apache.ignite.internal.portable.GridPortableMarshaller.CHAR;
 import static org.apache.ignite.internal.portable.GridPortableMarshaller.CHAR_ARR;
 import static org.apache.ignite.internal.portable.GridPortableMarshaller.CLASS;
-import static org.apache.ignite.internal.portable.GridPortableMarshaller.CLS_NAME_POS;
 import static org.apache.ignite.internal.portable.GridPortableMarshaller.COL;
 import static org.apache.ignite.internal.portable.GridPortableMarshaller.CONC_HASH_MAP;
 import static org.apache.ignite.internal.portable.GridPortableMarshaller.CONC_SKIP_LIST_SET;
@@ -97,7 +98,6 @@ import static org.apache.ignite.internal.portable.GridPortableMarshaller.OBJ_ARR
 import static org.apache.ignite.internal.portable.GridPortableMarshaller.OPTM_MARSH;
 import static org.apache.ignite.internal.portable.GridPortableMarshaller.PORTABLE_OBJ;
 import static org.apache.ignite.internal.portable.GridPortableMarshaller.PROPERTIES_MAP;
-import static org.apache.ignite.internal.portable.GridPortableMarshaller.RAW_DATA_OFF_POS;
 import static org.apache.ignite.internal.portable.GridPortableMarshaller.SHORT;
 import static org.apache.ignite.internal.portable.GridPortableMarshaller.SHORT_ARR;
 import static org.apache.ignite.internal.portable.GridPortableMarshaller.STRING;
@@ -133,25 +133,34 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
     private final ClassLoader ldr;
 
     /** */
-    private int off;
+    private PortableClassDescriptor desc;
 
-    /** */
-    private int rawOff;
+    /** Flag indicating that object header was parsed. */
+    private boolean hdrParsed;
 
-    /** */
-    private int len;
+    /** Type ID. */
+    private int typeId;
 
-    /** */
-    private PortableClassDescriptor desc;
+    /** Raw offset. */
+    private int rawOff;
 
     /** */
     private int hdrLen;
 
-    /** */
-    private int clsNameLen;
+    /** Footer start. */
+    private int footerStart;
 
-    /** */
-    private Integer typeId;
+    /** Footer end. */
+    private int footerEnd;
+
+    /** ID mapper. */
+    private PortableIdMapper idMapper;
+
+    /** Schema Id. */
+    private int schemaId;
+
+    /** Object schema. */
+    private PortableObjectSchema schema;
 
     /**
      * @param ctx Context.
@@ -186,49 +195,65 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
         this.ldr = ldr;
         this.rCtx = rCtx;
 
-        off = start;
-        rawOff = start;
+        in.position(start);
     }
 
     /**
      * Preloads typeId from the input array.
      */
-    private void readObjectTypeId(boolean skipObjByte) {
-        int pos = rawOff;
+    private void parseHeaderIfNeeded() {
+        if (hdrParsed)
+            return;
+
+        int retPos = in.position();
+
+        in.position(start);
+
+        byte hdr = in.readByte();
+
+        if (hdr != GridPortableMarshaller.OBJ)
+            throw new PortableException("Invalid header [pos=" + retPos + "expected=" + GridPortableMarshaller.OBJ +
+                ", actual=" + hdr + ']');
+
+        PortableUtils.checkProtocolVersion(in.readByte());
+
+        in.position(in.position() + 2); // Skip flags.
 
-        if (!skipObjByte)
-            // skip obj type byte
-            rawOff++;
+        typeId = in.readIntPositioned(start + GridPortableMarshaller.TYPE_ID_POS);
 
-        // Validate protocol version.
-        PortableUtils.checkProtocolVersion(doReadByte(true));
+        IgniteBiTuple<Integer, Integer> footer = PortableUtils.footerAbsolute(in, start);
 
-        // skip user flag
-        rawOff += 1;
+        footerStart = footer.get1();
+        footerEnd = footer.get2();
 
-        typeId = doReadInt(true);
+        schemaId = in.readIntPositioned(start + GridPortableMarshaller.SCHEMA_ID_POS);
+
+        rawOff = PortableUtils.rawOffsetAbsolute(in, start);
 
         if (typeId == UNREGISTERED_TYPE_ID) {
-            // skip hash code, length and raw offset
-            rawOff += 12;
+            // Skip to the class name position.
+            in.position(start + GridPortableMarshaller.DFLT_HDR_LEN);
 
-            int off = rawOff;
+            int off = in.position();
 
-            Class cls = doReadClass(true, typeId);
+            Class cls = doReadClass(typeId);
 
             // registers class by typeId, at least locally if the cache is not ready yet.
             PortableClassDescriptor desc = ctx.descriptorForClass(cls);
 
             typeId = desc.typeId();
 
-            clsNameLen = rawOff - off;
+            int clsNameLen = in.position() - off;
 
-            hdrLen = CLS_NAME_POS + clsNameLen;
+            hdrLen = DFLT_HDR_LEN + clsNameLen;
         }
         else
             hdrLen = DFLT_HDR_LEN;
 
-        in.position(rawOff = pos);
+        // Restore state.
+        in.position(retPos);
+
+        hdrParsed = true;
     }
 
     /**
@@ -243,29 +268,38 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException In case of error.
      */
     @Nullable Object unmarshal() throws PortableException {
-        return unmarshal(true);
+        return unmarshal(false);
     }
 
     /**
-     * @param fieldName Field name.
+     * @param offset Offset in the array.
      * @return Unmarshalled value.
      * @throws PortableException In case of error.
      */
-    @Nullable Object unmarshal(String fieldName) throws PortableException {
-        off = fieldOffset(fieldId(fieldName));
+    public Object unmarshal(int offset) throws PortableException {
+        in.position(offset);
 
-        return off >= 0 ? unmarshal(false) : null;
+        return in.position() >= 0 ? unmarshal() : null;
     }
 
     /**
-     * @param offset Offset in the array.
+     * @param fieldName Field name.
      * @return Unmarshalled value.
      * @throws PortableException In case of error.
      */
-    public Object unmarshal(int offset) throws PortableException {
-        off = offset;
+    @Nullable Object unmarshalField(String fieldName) throws PortableException {
+        return hasField(fieldName) ? unmarshal() : null;
+    }
 
-        return off >= 0 ? unmarshal(false) : null;
+    /**
+     * @param fieldId Field ID.
+     * @return Unmarshalled value.
+     * @throws PortableException In case of error.
+     */
+    @Nullable Object unmarshalField(int fieldId) throws PortableException {
+        parseHeaderIfNeeded();
+
+        return hasField(fieldId) ? unmarshal() : null;
     }
 
     /**
@@ -274,18 +308,11 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException In case of error.
      */
     @Nullable Byte readByte(int fieldId) throws PortableException {
-        off = fieldOffset(fieldId);
-
-        if (off >= 0) {
-            byte flag = doReadByte(false);
-
-            if (flag == NULL)
+        if (hasField(fieldId)) {
+            if (checkFlag(BYTE) == Flag.NULL)
                 return null;
 
-            if (flag != BYTE)
-                throw new PortableException("Invalid flag value: " + flag);
-
-            return doReadByte(false);
+            return in.readByte();
         }
         else
             return null;
@@ -297,18 +324,11 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException In case of error.
      */
     @Nullable Short readShort(int fieldId) throws PortableException {
-        off = fieldOffset(fieldId);
-
-        if (off >= 0) {
-            byte flag = doReadByte(false);
-
-            if (flag == NULL)
+        if (hasField(fieldId)) {
+            if (checkFlag(SHORT) == Flag.NULL)
                 return null;
 
-            if (flag != SHORT)
-                throw new PortableException("Invalid flag value: " + flag);
-
-            return doReadShort(false);
+            return in.readShort();
         }
         else
             return null;
@@ -320,18 +340,11 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException In case of error.
      */
     @Nullable Integer readInt(int fieldId) throws PortableException {
-        off = fieldOffset(fieldId);
-
-        if (off >= 0) {
-            byte flag = doReadByte(false);
-
-            if (flag == NULL)
+        if (hasField(fieldId)) {
+            if (checkFlag(INT) == Flag.NULL)
                 return null;
 
-            if (flag != INT)
-                throw new PortableException("Invalid flag value: " + flag);
-
-            return doReadInt(false);
+            return in.readInt();
         }
         else
             return null;
@@ -343,18 +356,11 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException In case of error.
      */
     @Nullable Long readLong(int fieldId) throws PortableException {
-        off = fieldOffset(fieldId);
-
-        if (off >= 0) {
-            byte flag = doReadByte(false);
-
-            if (flag == NULL)
+        if (hasField(fieldId)) {
+            if (checkFlag(LONG) == Flag.NULL)
                 return null;
 
-            if (flag != LONG)
-                throw new PortableException("Invalid flag value: " + flag);
-
-            return doReadLong(false);
+            return in.readLong();
         }
         else
             return null;
@@ -366,18 +372,11 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException In case of error.
      */
     @Nullable Float readFloat(int fieldId) throws PortableException {
-        off = fieldOffset(fieldId);
-
-        if (off >= 0) {
-            byte flag = doReadByte(false);
-
-            if (flag == NULL)
+        if (hasField(fieldId)) {
+            if (checkFlag(FLOAT) == Flag.NULL)
                 return null;
 
-            if (flag != FLOAT)
-                throw new PortableException("Invalid flag value: " + flag);
-
-            return doReadFloat(false);
+            return in.readFloat();
         }
         else
             return null;
@@ -389,18 +388,11 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException In case of error.
      */
     @Nullable Double readDouble(int fieldId) throws PortableException {
-        off = fieldOffset(fieldId);
-
-        if (off >= 0) {
-            byte flag = doReadByte(false);
-
-            if (flag == NULL)
+        if (hasField(fieldId)) {
+            if (checkFlag(DOUBLE) == Flag.NULL)
                 return null;
 
-            if (flag != DOUBLE)
-                throw new PortableException("Invalid flag value: " + flag);
-
-            return doReadDouble(false);
+            return in.readDouble();
         }
         else
             return null;
@@ -412,18 +404,11 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException In case of error.
      */
     @Nullable Character readChar(int fieldId) throws PortableException {
-        off = fieldOffset(fieldId);
-
-        if (off >= 0) {
-            byte flag = doReadByte(false);
-
-            if (flag == NULL)
+        if (hasField(fieldId)) {
+            if (checkFlag(CHAR) == Flag.NULL)
                 return null;
 
-            if (flag != CHAR)
-                throw new PortableException("Invalid flag value: " + flag);
-
-            return doReadChar(false);
+            return in.readChar();
         }
         else
             return null;
@@ -435,18 +420,11 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException In case of error.
      */
     @Nullable Boolean readBoolean(int fieldId) throws PortableException {
-        off = fieldOffset(fieldId);
-
-        if (off >= 0) {
-            byte flag = doReadByte(false);
-
-            if (flag == NULL)
+        if (hasField(fieldId)) {
+            if (checkFlag(BOOLEAN) == Flag.NULL)
                 return null;
 
-            if (flag != BOOLEAN)
-                throw new PortableException("Invalid flag value: " + flag);
-
-            return doReadBoolean(false);
+            return in.readBoolean();
         }
         else
             return null;
@@ -458,18 +436,11 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException In case of error.
      */
     @Nullable BigDecimal readDecimal(int fieldId) throws PortableException {
-        off = fieldOffset(fieldId);
-
-        if (off >= 0) {
-            byte flag = doReadByte(false);
-
-            if (flag == NULL)
+        if (hasField(fieldId)) {
+            if (checkFlag(DECIMAL) == Flag.NULL)
                 return null;
 
-            if (flag != DECIMAL)
-                throw new PortableException("Invalid flag value: " + flag);
-
-            return doReadDecimal(false);
+            return doReadDecimal();
         }
         else
             return null;
@@ -481,18 +452,11 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException In case of error.
      */
     @Nullable String readString(int fieldId) throws PortableException {
-        off = fieldOffset(fieldId);
-
-        if (off >= 0) {
-            byte flag = doReadByte(false);
-
-            if (flag == NULL)
+        if (hasField(fieldId)) {
+            if (checkFlag(STRING) == Flag.NULL)
                 return null;
 
-            if (flag != STRING)
-                throw new PortableException("Invalid flag value: " + flag);
-
-            return doReadString(false);
+            return doReadString();
         }
         else
             return null;
@@ -504,18 +468,11 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException In case of error.
      */
     @Nullable UUID readUuid(int fieldId) throws PortableException {
-        off = fieldOffset(fieldId);
-
-        if (off >= 0) {
-            byte flag = doReadByte(false);
-
-            if (flag == NULL)
+        if (hasField(fieldId)) {
+            if (checkFlag(UUID) == Flag.NULL)
                 return null;
 
-            if (flag != UUID)
-                throw new PortableException("Invalid flag value: " + flag);
-
-            return doReadUuid(false);
+            return doReadUuid();
         }
         else
             return null;
@@ -527,18 +484,11 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException In case of error.
      */
     @Nullable Date readDate(int fieldId) throws PortableException {
-        off = fieldOffset(fieldId);
-
-        if (off >= 0) {
-            byte flag = doReadByte(false);
-
-            if (flag == NULL)
+        if (hasField(fieldId)) {
+            if (checkFlag(DATE) == Flag.NULL)
                 return null;
 
-            if (flag != DATE)
-                throw new PortableException("Invalid flag value: " + flag);
-
-            return doReadDate(false);
+            return doReadDate();
         }
         else
             return null;
@@ -550,18 +500,11 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException In case of error.
      */
     @Nullable Timestamp readTimestamp(int fieldId) throws PortableException {
-        off = fieldOffset(fieldId);
-
-        if (off >= 0) {
-            byte flag = doReadByte(false);
-
-            if (flag == NULL)
+        if (hasField(fieldId)) {
+            if (checkFlag(TIMESTAMP) == Flag.NULL)
                 return null;
 
-            if (flag != TIMESTAMP)
-                throw new PortableException("Invalid flag value: " + flag);
-
-            return doReadTimestamp(false);
+            return doReadTimestamp();
         }
         else
             return null;
@@ -573,9 +516,7 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException In case of error.
      */
     @Nullable Object readObject(int fieldId) throws PortableException {
-        off = fieldOffset(fieldId);
-
-        return off >= 0 ? doReadObject(false) : null;
+        return hasField(fieldId) ? doReadObject() : null;
     }
 
     /**
@@ -584,24 +525,16 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException In case of error.
      */
     @Nullable byte[] readByteArray(int fieldId) throws PortableException {
-        off = fieldOffset(fieldId);
-
-        if (off >= 0) {
-            byte flag = doReadByte(false);
+        if (hasField(fieldId)) {
+            Flag flag = checkFlag(BYTE_ARR);
 
-            if (flag == NULL)
-                return null;
-
-            if (flag == HANDLE)
+            if (flag == Flag.NORMAL)
+                return doReadByteArray();
+            else if (flag == Flag.HANDLE)
                 return readHandleField();
-
-            if (flag != BYTE_ARR)
-                throw new PortableException("Invalid flag value: " + flag);
-
-            return doReadByteArray(false);
         }
-        else
-            return null;
+
+        return null;
     }
 
     /**
@@ -610,24 +543,16 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException In case of error.
      */
     @Nullable short[] readShortArray(int fieldId) throws PortableException {
-        off = fieldOffset(fieldId);
-
-        if (off >= 0) {
-            byte flag = doReadByte(false);
+        if (hasField(fieldId)) {
+            Flag flag = checkFlag(SHORT_ARR);
 
-            if (flag == NULL)
-                return null;
-
-            if (flag == HANDLE)
+            if (flag == Flag.NORMAL)
+                return doReadShortArray();
+            else if (flag == Flag.HANDLE)
                 return readHandleField();
-
-            if (flag != SHORT_ARR)
-                throw new PortableException("Invalid flag value: " + flag);
-
-            return doReadShortArray(false);
         }
-        else
-            return null;
+
+        return null;
     }
 
     /**
@@ -636,24 +561,16 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException In case of error.
      */
     @Nullable int[] readIntArray(int fieldId) throws PortableException {
-        off = fieldOffset(fieldId);
-
-        if (off >= 0) {
-            byte flag = doReadByte(false);
+        if (hasField(fieldId)) {
+            Flag flag = checkFlag(INT_ARR);
 
-            if (flag == NULL)
-                return null;
-
-            if (flag == HANDLE)
+            if (flag == Flag.NORMAL)
+                return doReadIntArray();
+            else if (flag == Flag.HANDLE)
                 return readHandleField();
-
-            if (flag != INT_ARR)
-                throw new PortableException("Invalid flag value: " + flag);
-
-            return doReadIntArray(false);
         }
-        else
-            return null;
+
+        return null;
     }
 
     /**
@@ -662,24 +579,16 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException In case of error.
      */
     @Nullable long[] readLongArray(int fieldId) throws PortableException {
-        off = fieldOffset(fieldId);
-
-        if (off >= 0) {
-            byte flag = doReadByte(false);
+        if (hasField(fieldId)) {
+            Flag flag = checkFlag(LONG_ARR);
 
-            if (flag == NULL)
-                return null;
-
-            if (flag == HANDLE)
+            if (flag == Flag.NORMAL)
+                return doReadLongArray();
+            else if (flag == Flag.HANDLE)
                 return readHandleField();
-
-            if (flag != LONG_ARR)
-                throw new PortableException("Invalid flag value: " + flag);
-
-            return doReadLongArray(false);
         }
-        else
-            return null;
+
+        return null;
     }
 
     /**
@@ -688,24 +597,16 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException In case of error.
      */
     @Nullable float[] readFloatArray(int fieldId) throws PortableException {
-        off = fieldOffset(fieldId);
-
-        if (off >= 0) {
-            byte flag = doReadByte(false);
+        if (hasField(fieldId)) {
+            Flag flag = checkFlag(FLOAT_ARR);
 
-            if (flag == NULL)
-                return null;
-
-            if (flag == HANDLE)
+            if (flag == Flag.NORMAL)
+                return doReadFloatArray();
+            else if (flag == Flag.HANDLE)
                 return readHandleField();
-
-            if (flag != FLOAT_ARR)
-                throw new PortableException("Invalid flag value: " + flag);
-
-            return doReadFloatArray(false);
         }
-        else
-            return null;
+
+        return null;
     }
 
     /**
@@ -714,24 +615,16 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException In case of error.
      */
     @Nullable double[] readDoubleArray(int fieldId) throws PortableException {
-        off = fieldOffset(fieldId);
-
-        if (off >= 0) {
-            byte flag = doReadByte(false);
+        if (hasField(fieldId)) {
+            Flag flag = checkFlag(DOUBLE_ARR);
 
-            if (flag == NULL)
-                return null;
-
-            if (flag == HANDLE)
+            if (flag == Flag.NORMAL)
+                return doReadDoubleArray();
+            else if (flag == Flag.HANDLE)
                 return readHandleField();
-
-            if (flag != DOUBLE_ARR)
-                throw new PortableException("Invalid flag value: " + flag);
-
-            return doReadDoubleArray(false);
         }
-        else
-            return null;
+
+        return null;
     }
 
     /**
@@ -740,24 +633,16 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException In case of error.
      */
     @Nullable char[] readCharArray(int fieldId) throws PortableException {
-        off = fieldOffset(fieldId);
-
-        if (off >= 0) {
-            byte flag = doReadByte(false);
-
-            if (flag == NULL)
-                return null;
+        if (hasField(fieldId)) {
+            Flag flag = checkFlag(CHAR_ARR);
 
-            if (flag == HANDLE)
+            if (flag == Flag.NORMAL)
+                return doReadCharArray();
+            else if (flag == Flag.HANDLE)
                 return readHandleField();
-
-            if (flag != CHAR_ARR)
-                throw new PortableException("Invalid flag value: " + flag);
-
-            return doReadCharArray(false);
         }
-        else
-            return null;
+
+        return null;
     }
 
     /**
@@ -766,24 +651,16 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException In case of error.
      */
     @Nullable boolean[] readBooleanArray(int fieldId) throws PortableException {
-        off = fieldOffset(fieldId);
-
-        if (off >= 0) {
-            byte flag = doReadByte(false);
+        if (hasField(fieldId)) {
+            Flag flag = checkFlag(BOOLEAN_ARR);
 
-            if (flag == NULL)
-                return null;
-
-            if (flag == HANDLE)
+            if (flag == Flag.NORMAL)
+                return doReadBooleanArray();
+            else if (flag == Flag.HANDLE)
                 return readHandleField();
-
-            if (flag != BOOLEAN_ARR)
-                throw new PortableException("Invalid flag value: " + flag);
-
-            return doReadBooleanArray(false);
         }
-        else
-            return null;
+
+        return null;
     }
 
     /**
@@ -792,24 +669,16 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException In case of error.
      */
     @Nullable BigDecimal[] readDecimalArray(int fieldId) throws PortableException {
-        off = fieldOffset(fieldId);
-
-        if (off >= 0) {
-            byte flag = doReadByte(false);
-
-            if (flag == NULL)
-                return null;
+        if (hasField(fieldId)) {
+            Flag flag = checkFlag(DECIMAL_ARR);
 
-            if (flag == HANDLE)
+            if (flag == Flag.NORMAL)
+                return doReadDecimalArray();
+            else if (flag == Flag.HANDLE)
                 return readHandleField();
-
-            if (flag != DECIMAL_ARR)
-                throw new PortableException("Invalid flag value: " + flag);
-
-            return doReadDecimalArray(false);
         }
-        else
-            return null;
+
+        return null;
     }
 
     /**
@@ -818,24 +687,16 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException In case of error.
      */
     @Nullable String[] readStringArray(int fieldId) throws PortableException {
-        off = fieldOffset(fieldId);
+        if (hasField(fieldId)) {
+            Flag flag = checkFlag(STRING_ARR);
 
-        if (off >= 0) {
-            byte flag = doReadByte(false);
-
-            if (flag == NULL)
-                return null;
-
-            if (flag == HANDLE)
+            if (flag == Flag.NORMAL)
+                return doReadStringArray();
+            else if (flag == Flag.HANDLE)
                 return readHandleField();
-
-            if (flag != STRING_ARR)
-                throw new PortableException("Invalid flag value: " + flag);
-
-            return doReadStringArray(false);
         }
-        else
-            return null;
+
+        return null;
     }
 
     /**
@@ -844,24 +705,16 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException In case of error.
      */
     @Nullable UUID[] readUuidArray(int fieldId) throws PortableException {
-        off = fieldOffset(fieldId);
-
-        if (off >= 0) {
-            byte flag = doReadByte(false);
-
-            if (flag == NULL)
-                return null;
+        if (hasField(fieldId)) {
+            Flag flag = checkFlag(UUID_ARR);
 
-            if (flag == HANDLE)
+            if (flag == Flag.NORMAL)
+                return doReadUuidArray();
+            else if (flag == Flag.HANDLE)
                 return readHandleField();
-
-            if (flag != UUID_ARR)
-                throw new PortableException("Invalid flag value: " + flag);
-
-            return doReadUuidArray(false);
         }
-        else
-            return null;
+
+        return null;
     }
 
     /**
@@ -870,24 +723,16 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException In case of error.
      */
     @Nullable Date[] readDateArray(int fieldId) throws PortableException {
-        off = fieldOffset(fieldId);
-
-        if (off >= 0) {
-            byte flag = doReadByte(false);
-
-            if (flag == NULL)
-                return null;
+        if (hasField(fieldId)) {
+            Flag flag = checkFlag(DATE_ARR);
 
-            if (flag == HANDLE)
+            if (flag == Flag.NORMAL)
+                return doReadDateArray();
+            else if (flag == Flag.HANDLE)
                 return readHandleField();
-
-            if (flag != DATE_ARR)
-                throw new PortableException("Invalid flag value: " + flag);
-
-            return doReadDateArray(false);
         }
-        else
-            return null;
+
+        return null;
     }
 
     /**
@@ -896,24 +741,16 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException In case of error.
      */
     @Nullable Timestamp[] readTimestampArray(int fieldId) throws PortableException {
-        off = fieldOffset(fieldId);
+        if (hasField(fieldId)) {
+            Flag flag = checkFlag(TIMESTAMP_ARR);
 
-        if (off >= 0) {
-            byte flag = doReadByte(false);
-
-            if (flag == NULL)
-                return null;
-
-            if (flag == HANDLE)
+            if (flag == Flag.NORMAL)
+                return doReadTimestampArray();
+            else if (flag == Flag.HANDLE)
                 return readHandleField();
-
-            if (flag != TIMESTAMP_ARR)
-                throw new PortableException("Invalid flag value: " + flag);
-
-            return doReadTimestampArray(false);
         }
-        else
-            return null;
+
+        return null;
     }
 
     /**
@@ -922,24 +759,16 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException In case of error.
      */
     @Nullable Object[] readObjectArray(int fieldId) throws PortableException {
-        off = fieldOffset(fieldId);
-
-        if (off >= 0) {
-            byte flag = doReadByte(false);
+        if (hasField(fieldId)) {
+            Flag flag = checkFlag(OBJ_ARR);
 
-            if (flag == NULL)
-                return null;
-
-            if (flag == HANDLE)
+            if (flag == Flag.NORMAL)
+                return doReadObjectArray(true);
+            else if (flag == Flag.HANDLE)
                 return readHandleField();
-
-            if (flag != OBJ_ARR)
-                throw new PortableException("Invalid flag value: " + flag);
-
-            return doReadObjectArray(false, true);
         }
-        else
-            return null;
+
+        return null;
     }
 
     /**
@@ -950,24 +779,16 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      */
     @Nullable <T> Collection<T> readCollection(int fieldId, @Nullable Class<? extends Collection> cls)
         throws PortableException {
-        off = fieldOffset(fieldId);
-
-        if (off >= 0) {
-            byte flag = doReadByte(false);
+        if (hasField(fieldId)) {
+            Flag flag = checkFlag(COL);
 
-            if (flag == NULL)
-                return null;
-
-            if (flag == HANDLE)
+            if (flag == Flag.NORMAL)
+                return (Collection<T>)doReadCollection(true, cls);
+            else if (flag == Flag.HANDLE)
                 return readHandleField();
-
-            if (flag != COL)
-                throw new PortableException("Invalid flag value: " + flag);
-
-            return (Collection<T>)doReadCollection(false, true, cls);
         }
-        else
-            return null;
+
+        return null;
     }
 
     /**
@@ -978,24 +799,16 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      */
     @Nullable Map<?, ?> readMap(int fieldId, @Nullable Class<? extends Map> cls)
         throws PortableException {
-        off = fieldOffset(fieldId);
-
-        if (off >= 0) {
-            byte flag = doReadByte(false);
+        if (hasField(fieldId)) {
+            Flag flag = checkFlag(MAP);
 
-            if (flag == NULL)
-                return null;
-
-            if (flag == HANDLE)
+            if (flag == Flag.NORMAL)
+                return doReadMap(true, cls);
+            else if (flag == Flag.HANDLE)
                 return readHandleField();
-
-            if (flag != MAP)
-                throw new PortableException("Invalid flag value: " + flag);
-
-            return doReadMap(false, true, cls);
         }
-        else
-            return null;
+
+        return null;
     }
 
     /**
@@ -1004,24 +817,16 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException On case of error.
      */
     @Nullable Map.Entry<?, ?> readMapEntry(int fieldId) throws PortableException {
-        off = fieldOffset(fieldId);
-
-        if (off >= 0) {
-            byte flag = doReadByte(false);
+        if (hasField(fieldId)) {
+            Flag flag = checkFlag(MAP_ENTRY);
 
-            if (flag == NULL)
-                return null;
-
-            if (flag == HANDLE)
+            if (flag == Flag.NORMAL)
+                return doReadMapEntry(true);
+            else if (flag == Flag.HANDLE)
                 return readHandleField();
-
-            if (flag != MAP_ENTRY)
-                throw new PortableException("Invalid flag value: " + flag);
-
-            return doReadMapEntry(false, true);
         }
-        else
-            return null;
+
+        return null;
     }
 
     /**
@@ -1030,18 +835,11 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException In case of error.
      */
     @Nullable PortableObject readPortableObject(int fieldId) throws PortableException {
-        off = fieldOffset(fieldId);
-
-        if (off >= 0) {
-            byte flag = doReadByte(false);
-
-            if (flag == NULL)
+        if (hasField(fieldId)) {
+            if (checkFlag(PORTABLE_OBJ) == Flag.NULL)
                 return null;
 
-            if (flag != PORTABLE_OBJ)
-                throw new PortableException("Invalid flag value: " + flag);
-
-            return new PortableObjectImpl(ctx, doReadByteArray(false), doReadInt(false));
+            return new PortableObjectImpl(ctx, doReadByteArray(), in.readInt());
         }
         else
             return null;
@@ -1054,26 +852,19 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException In case of error.
      */
     @Nullable Enum<?> readEnum(int fieldId, @Nullable Class<?> cls) throws PortableException {
-        off = fieldOffset(fieldId);
-
-        if (off >= 0) {
-            byte flag = doReadByte(false);
-
-            if (flag == NULL)
+        if (hasField(fieldId)) {
+            if (checkFlag(ENUM) == Flag.NULL)
                 return null;
 
-            if (flag != ENUM)
-                throw new PortableException("Invalid flag value: " + flag);
-
             // Revisit: why have we started writing Class for enums in their serialized form?
             if (cls == null)
-                cls = doReadClass(false);
+                cls = doReadClass();
             else
-                doReadClass(false);
+                doReadClass();
 
             Object[] vals = GridEnumCache.get(cls);
 
-            return (Enum<?>)vals[doReadInt(false)];
+            return (Enum<?>)vals[in.readInt()];
         }
         else
             return null;
@@ -1086,27 +877,22 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException In case of error.
      */
     @Nullable Object[] readEnumArray(int fieldId, @Nullable Class<?> cls) throws PortableException {
-        off = fieldOffset(fieldId);
-
-        if (off >= 0) {
-            byte flag = doReadByte(false);
-
-            if (flag == NULL)
-                return null;
+        if (hasField(fieldId)) {
+            Flag flag = checkFlag(ENUM_ARR);
 
-            if (flag != ENUM_ARR)
-                throw new PortableException("Invalid flag value: " + flag);
-
-            // Revisit: why have we started writing Class for enums in their serialized form?
-            if (cls == null)
-                cls = doReadClass(false);
-            else
-                doReadClass(false);
+            if (flag == Flag.NORMAL) {
+                if (cls == null)
+                    cls = doReadClass();
+                else
+                    doReadClass();
 
-            return doReadEnumArray(false, cls);
+                return doReadEnumArray(cls);
+            }
+            else if (flag == Flag.HANDLE)
+                return readHandleField();
         }
-        else
-            return null;
+
+        return null;
     }
 
     /**
@@ -1115,18 +901,11 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @throws PortableException In case of error.
      */
     @Nullable Class<?> readClass(int fieldId) throws PortableException {
-        off = fieldOffset(fieldId);
-
-        if (off >= 0) {
-            byte flag = doReadByte(false);
-
-            if (flag == NULL)
+        if (hasField(fieldId)) {
+            if (checkFlag(CLASS) == Flag.NULL)
                 return null;
 
-            if (flag != CLASS)
-                throw new PortableException("Invalid flag type: [flag=" + flag + ']');
-
-            return doReadClass(false);
+            return doReadClass();
         }
 
         return null;
@@ -1154,14 +933,14 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @return Field.
      */
     private <T> T readHandleField() {
-        int handle = (off - 1) - doReadInt(false);
+        int handle = (in.position() - 1) - in.readInt();
 
         Object obj = rCtx.getObjectByHandle(handle);
 
         if (obj == null) {
-            off = handle;
+            in.position(handle);
 
-            obj = doReadObject(false);
+            obj = doReadObject();
         }
 
         return (T)obj;
@@ -1175,7 +954,7 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
     /** {@inheritDoc} */
     @Override public byte readByte() throws PortableException {
-        return doReadByte(true);
+        return in.readByte();
     }
 
     /** {@inheritDoc} */
@@ -1187,7 +966,7 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
     /** {@inheritDoc} */
     @Override public short readShort() throws PortableException {
-        return doReadShort(true);
+        return in.readShort();
     }
 
     /** {@inheritDoc} */
@@ -1199,7 +978,7 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
     /** {@inheritDoc} */
     @Override public int readInt() throws PortableException {
-        return doReadInt(true);
+        return in.readInt();
     }
 
     /** {@inheritDoc} */
@@ -1211,7 +990,7 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
     /** {@inheritDoc} */
     @Override public long readLong() throws PortableException {
-        return doReadLong(true);
+        return in.readLong();
     }
 
     /** {@inheritDoc} */
@@ -1223,7 +1002,7 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
     /** {@inheritDoc} */
     @Override public float readFloat() throws PortableException {
-        return doReadFloat(true);
+        return in.readFloat();
     }
 
     /** {@inheritDoc} */
@@ -1235,7 +1014,7 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
     /** {@inheritDoc} */
     @Override public double readDouble() throws PortableException {
-        return doReadDouble(true);
+        return in.readDouble();
     }
 
     /** {@inheritDoc} */
@@ -1247,7 +1026,7 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
     /** {@inheritDoc} */
     @Override public char readChar() throws PortableException {
-        return doReadChar(true);
+        return in.readChar();
     }
 
     /** {@inheritDoc} */
@@ -1259,7 +1038,7 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
     /** {@inheritDoc} */
     @Override public boolean readBoolean() throws PortableException {
-        return doReadBoolean(true);
+        return in.readBoolean();
     }
 
     /** {@inheritDoc} */
@@ -1269,15 +1048,10 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
     /** {@inheritDoc} */
     @Override @Nullable public BigDecimal readDecimal() throws PortableException {
-        byte flag = doReadByte(true);
-
-        if (flag == NULL)
+        if (checkFlag(DECIMAL) == Flag.NULL)
             return null;
 
-        if (flag != DECIMAL)
-            throw new PortableException("Invalid flag value: " + flag);
-
-        return doReadDecimal(true);
+        return doReadDecimal();
     }
 
     /** {@inheritDoc} */
@@ -1287,15 +1061,10 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
     /** {@inheritDoc} */
     @Nullable @Override public String readString() throws PortableException {
-        byte flag = doReadByte(true);
-
-        if (flag == NULL)
+        if (checkFlag(STRING) == Flag.NULL)
             return null;
 
-        if (flag != STRING)
-            throw new PortableException("Invalid flag value: " + flag);
-
-        return doReadString(true);
+        return doReadString();
     }
 
     /** {@inheritDoc} */
@@ -1305,15 +1074,10 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
     /** {@inheritDoc} */
     @Nullable @Override public UUID readUuid() throws PortableException {
-        byte flag = doReadByte(true);
-
-        if (flag == NULL)
+        if (checkFlag(UUID) == Flag.NULL)
             return null;
 
-        if (flag != UUID)
-            throw new PortableException("Invalid flag value: " + flag);
-
-        return doReadUuid(true);
+        return doReadUuid();
     }
 
     /** {@inheritDoc} */
@@ -1323,15 +1087,10 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
     /** {@inheritDoc} */
     @Nullable @Override public Date readDate() throws PortableException {
-        byte flag = doReadByte(true);
-
-        if (flag == NULL)
+        if (checkFlag(DATE) == Flag.NULL)
             return null;
 
-        if (flag != DATE)
-            throw new PortableException("Invalid flag value: " + flag);
-
-        return doReadDate(true);
+        return doReadDate();
     }
 
     /** {@inheritDoc} */
@@ -1341,15 +1100,10 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
     /** {@inheritDoc} */
     @Nullable @Override public Timestamp readTimestamp() throws PortableException {
-        byte flag = doReadByte(true);
-
-        if (flag == NULL)
+        if (checkFlag(TIMESTAMP) == Flag.NULL)
             return null;
 
-        if (flag != TIMESTAMP)
-            throw new PortableException("Invalid flag value: " + flag);
-
-        return doReadTimestamp(true);
+        return doReadTimestamp();
     }
 
     /** {@inheritDoc} */
@@ -1360,12 +1114,12 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
     /** {@inheritDoc} */
     @Override public Object readObject() throws PortableException {
-        return doReadObject(true);
+        return doReadObject();
     }
 
     /** {@inheritDoc} */
     @Nullable @Override public Object readObjectDetached() throws PortableException {
-        return unmarshal(true, true);
+        return unmarshal(true);
     }
 
     /** {@inheritDoc} */
@@ -1375,15 +1129,10 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
     /** {@inheritDoc} */
     @Nullable @Override public byte[] readByteArray() throws PortableException {
-        byte flag = doReadByte(true);
-
-        if (flag == NULL)
+        if (checkFlag(BYTE_ARR) == Flag.NULL)
             return null;
 
-        if (flag != BYTE_ARR)
-            throw new PortableException("Invalid flag value: " + flag);
-
-        return doReadByteArray(true);
+        return doReadByteArray();
     }
 
     /** {@inheritDoc} */
@@ -1393,15 +1142,10 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
     /** {@inheritDoc} */
     @Nullable @Override public short[] readShortArray() throws PortableException {
-        byte flag = doReadByte(true);
-
-        if (flag == NULL)
+        if (checkFlag(SHORT_ARR) == Flag.NULL)
             return null;
 
-        if (flag != SHORT_ARR)
-            throw new PortableException("Invalid flag value: " + flag);
-
-        return doReadShortArray(true);
+        return doReadShortArray();
     }
 
     /** {@inheritDoc} */
@@ -1411,15 +1155,10 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
     /** {@inheritDoc} */
     @Nullable @Override public int[] readIntArray() throws PortableException {
-        byte flag = doReadByte(true);
-
-        if (flag == NULL)
+        if (checkFlag(INT_ARR) == Flag.NULL)
             return null;
 
-        if (flag != INT_ARR)
-            throw new PortableException("Invalid flag value: " + flag);
-
-        return doReadIntArray(true);
+        return doReadIntArray();
     }
 
     /** {@inheritDoc} */
@@ -1429,15 +1168,10 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
     /** {@inheritDoc} */
     @Nullable @Override public long[] readLongArray() throws PortableException {
-        byte flag = doReadByte(true);
-
-        if (flag == NULL)
+        if (checkFlag(LONG_ARR) == Flag.NULL)
             return null;
 
-        if (flag != LONG_ARR)
-            throw new PortableException("Invalid flag value: " + flag);
-
-        return doReadLongArray(true);
+        return doReadLongArray();
     }
 
     /** {@inheritDoc} */
@@ -1447,15 +1181,10 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
     /** {@inheritDoc} */
     @Nullable @Override public float[] readFloatArray() throws PortableException {
-        byte flag = doReadByte(true);
-
-        if (flag == NULL)
+        if (checkFlag(FLOAT_ARR) == Flag.NULL)
             return null;
 
-        if (flag != FLOAT_ARR)
-            throw new PortableException("Invalid flag value: " + flag);
-
-        return doReadFloatArray(true);
+        return doReadFloatArray();
     }
 
     /** {@inheritDoc} */
@@ -1465,15 +1194,10 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
     /** {@inheritDoc} */
     @Nullable @Override public double[] readDoubleArray() throws PortableException {
-        byte flag = doReadByte(true);
-
-        if (flag == NULL)
+        if (checkFlag(DOUBLE_ARR) == Flag.NULL)
             return null;
 
-        if (flag != DOUBLE_ARR)
-            throw new PortableException("Invalid flag value: " + flag);
-
-        return doReadDoubleArray(true);
+        return doReadDoubleArray();
     }
 
     /** {@inheritDoc} */
@@ -1483,15 +1207,10 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
     /** {@inheritDoc} */
     @Nullable @Override public char[] readCharArray() throws PortableException {
-        byte flag = doReadByte(true);
-
-        if (flag == NULL)
+        if (checkFlag(CHAR_ARR) == Flag.NULL)
             return null;
 
-        if (flag != CHAR_ARR)
-            throw new PortableException("Invalid flag value: " + flag);
-
-        return doReadCharArray(true);
+        return doReadCharArray();
     }
 
     /** {@inheritDoc} */
@@ -1501,15 +1220,10 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
     /** {@inheritDoc} */
     @Nullable @Override public boolean[] readBooleanArray() throws PortableException {
-        byte flag = doReadByte(true);
-
-        if (flag == NULL)
+        if (checkFlag(BOOLEAN_ARR) == Flag.NULL)
             return null;
 
-        if (flag != BOOLEAN_ARR)
-            throw new PortableException("Invalid flag value: " + flag);
-
-        return doReadBooleanArray(true);
+        return doReadBooleanArray();
     }
 
     /** {@inheritDoc} */
@@ -1519,15 +1233,10 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
     /** {@inheritDoc} */
     @Override @Nullable public BigDecimal[] readDecimalArray() throws PortableException {
-        byte flag = doReadByte(true);
-
-        if (flag == NULL)
+        if (checkFlag(DECIMAL_ARR) == Flag.NULL)
             return null;
 
-        if (flag != DECIMAL_ARR)
-            throw new PortableException("Invalid flag value: " + flag);
-
-        return doReadDecimalArray(true);
+        return doReadDecimalArray();
     }
 
     /** {@inheritDoc} */
@@ -1537,15 +1246,10 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
     /** {@inheritDoc} */
     @Nullable @Override public String[] readStringArray() throws PortableException {
-        byte flag = doReadByte(true);
-
-        if (flag == NULL)
+        if (checkFlag(STRING_ARR) == Flag.NULL)
             return null;
 
-        if (flag != STRING_ARR)
-            throw new PortableException("Invalid flag value: " + flag);
-
-        return doReadStringArray(true);
+        return doReadStringArray();
     }
 
     /** {@inheritDoc} */
@@ -1555,15 +1259,10 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
     /** {@inheritDoc} */
     @Nullable @Override public UUID[] readUuidArray() throws PortableException {
-        byte flag = doReadByte(true);
-
-        if (flag == NULL)
+        if (checkFlag(UUID_ARR) == Flag.NULL)
             return null;
 
-        if (flag != UUID_ARR)
-            throw new PortableException("Invalid flag value: " + flag);
-
-        return doReadUuidArray(true);
+        return doReadUuidArray();
     }
 
     /** {@inheritDoc} */
@@ -1578,28 +1277,18 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
     /** {@inheritDoc} */
     @Nullable @Override public Date[] readDateArray() throws PortableException {
-        byte flag = doReadByte(true);
-
-        if (flag == NULL)
+        if (checkFlag(DATE_ARR) == Flag.NULL)
             return null;
 
-        if (flag != DATE_ARR)
-            throw new PortableException("Invalid flag value: " + flag);
-
-        return doReadDateArray(true);
+        return doReadDateArray();
     }
 
     /** {@inheritDoc} */
     @Nullable @Override public Timestamp[] readTimestampArray() throws PortableException {
-        byte flag = doReadByte(true);
-
-        if (flag == NULL)
+        if (checkFlag(TIMESTAMP_ARR) == Flag.NULL)
             return null;
 
-        if (flag != TIMESTAMP_ARR)
-            throw new PortableException("Invalid flag value: " + flag);
-
-        return doReadTimestampArray(true);
+        return doReadTimestampArray();
     }
 
     /** {@inheritDoc} */
@@ -1609,15 +1298,10 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
     /** {@inheritDoc} */
     @Nullable @Override public Object[] readObjectArray() throws PortableException {
-        byte flag = doReadByte(true);
-
-        if (flag == NULL)
+        if (checkFlag(OBJ_ARR) == Flag.NULL)
             return null;
 
-        if (flag != OBJ_ARR)
-            throw new PortableException("Invalid flag value: " + flag);
-
-        return doReadObjectArray(true, true);
+        return doReadObjectArray(true);
     }
 
     /** {@inheritDoc} */
@@ -1627,15 +1311,10 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
     /** {@inheritDoc} */
     @Nullable @Override public <T> Collection<T> readCollection() throws PortableException {
-        byte flag = doReadByte(true);
-
-        if (flag == NULL)
+        if (checkFlag(COL) == Flag.NULL)
             return null;
 
-        if (flag != COL)
-            throw new PortableException("Invalid flag value: " + flag);
-
-        return (Collection<T>)doReadCollection(true, true, null);
+        return (Collection<T>)doReadCollection(true, null);
     }
 
     /** {@inheritDoc} */
@@ -1647,15 +1326,10 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
     /** {@inheritDoc} */
     @Nullable @Override public <T> Collection<T> readCollection(Class<? extends Collection<T>> colCls)
         throws PortableException {
-        byte flag = doReadByte(true);
-
-        if (flag == NULL)
+        if (checkFlag(COL) == Flag.NULL)
             return null;
 
-        if (flag != COL)
-            throw new PortableException("Invalid flag value: " + flag);
-
-        return (Collection<T>)doReadCollection(true, true, colCls);
+        return (Collection<T>)doReadCollection(true, colCls);
     }
 
     /** {@inheritDoc} */
@@ -1665,15 +1339,10 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
     /** {@inheritDoc} */
     @Nullable @Override public <K, V> Map<K, V> readMap() throws PortableException {
-        byte flag = doReadByte(true);
-
-        if (flag == NULL)
+        if (checkFlag(MAP) == Flag.NULL)
             return null;
 
-        if (flag != MAP)
-            throw new PortableException("Invalid flag value: " + flag);
-
-        return (Map<K, V>)doReadMap(true, true, null);
+        return (Map<K, V>)doReadMap(true, null);
     }
 
     /** {@inheritDoc} */
@@ -1685,15 +1354,10 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
     /** {@inheritDoc} */
     @Nullable @Override public <K, V> Map<K, V> readMap(Class<? extends Map<K, V>> mapCls)
         throws PortableException {
-        byte flag = doReadByte(true);
-
-        if (flag == NULL)
+        if (checkFlag(MAP) == Flag.NULL)
             return null;
 
-        if (flag != MAP)
-            throw new PortableException("Invalid flag value: " + flag);
-
-        return (Map<K, V>)doReadMap(true, true, mapCls);
+        return (Map<K, V>)doReadMap(true, mapCls);
     }
 
     /** {@inheritDoc} */
@@ -1704,17 +1368,12 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
     /** {@inheritDoc} */
     @Nullable @Override public <T extends Enum<?>> T readEnum() throws PortableException {
-        byte flag = doReadByte(true);
-
-        if (flag == NULL)
+        if (checkFlag(ENUM) == Flag.NULL)
             return null;
 
-        if (flag != ENUM)
-            throw new PortableException("Invalid flag value: " + flag);
+        Class cls = doReadClass();
 
-        Class cls = doReadClass(true);
-
-        return (T)doReadEnum(true, cls);
+        return (T)doReadEnum(cls);
     }
 
     /** {@inheritDoc} */
@@ -1725,17 +1384,36 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
     /** {@inheritDoc} */
     @Nullable @Override public <T extends Enum<?>> T[] readEnumArray() throws PortableException {
-        byte flag = doReadByte(true);
-
-        if (flag == NULL)
+        if (checkFlag(ENUM_ARR) == Flag.NULL)
             return null;
 
-        if (flag != ENUM_ARR)
-            throw new PortableException("Invalid flag value: " + flag);
+        Class cls = doReadClass();
+
+        return (T[])doReadEnumArray(cls);
+    }
+
+    /**
+     * Ensure that type flag is either null or contains expected value.
+     *
+     * @param expFlag Expected value.
+     * @return Flag.
+     * @throws PortableException If flag is neither null, nor expected.
+     */
+    private Flag checkFlag(byte expFlag) {
+        byte flag = in.readByte();
 
-        Class cls = doReadClass(true);
+        if (flag == NULL)
+            return Flag.NULL;
+        else if (flag == HANDLE)
+            return Flag.HANDLE;
+        else if (flag != expFlag) {
+            int pos = in.position() - 1;
+
+            throw new PortableException("Unexpected flag value [pos=" + pos + ", expected=" + expFlag +
+                ", actual=" + flag + ']');
+        }
 
-        return (T[])doReadEnumArray(true, cls);
+        return Flag.NORMAL;
     }
 
     /**
@@ -1743,51 +1421,43 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
      * @return {@code true} if field is set.
      */
     public boolean hasField(String fieldName) {
-        return fieldOffset(fieldId(fieldName)) != -1;
+        return hasField(fieldId(fieldName));
     }
 
     /** {@inheritDoc} */
     @Override public PortableRawReader rawReader() {
-        return this;
-    }
+        in.position(rawOff);
 
-    /**
-     * @param raw Raw flag.
-     * @return Unmarshalled value.
-     * @throws PortableException In case of error.
-     */
-    @Nullable private Object unmarshal(boolean raw) throws PortableException {
-        return unmarshal(raw, false);
+        return this;
     }
 
     /**
-     * @param raw Raw flag.
      * @return Unmarshalled value.
      * @throws PortableException In case of error.
      */
-    @Nullable private Object unmarshal(boolean raw, boolean detach) throws PortableException {
-        int start = raw ? rawOff : off;
+    @Nullable private Object unmarshal(boolean detach) throws PortableException {
+        int start = in.position();
 
-        byte flag = doReadByte(raw);
+        byte flag = in.readByte();
 
         switch (flag) {
             case NULL:
                 return null;
 
             case HANDLE:
-                int handle = start - doReadInt(raw);
+                int handle = start - in.readInt();
 
                 PortableObject handledPo = rCtx.getPortableByHandle(handle);
 
                 if (handledPo != null)
                     return handledPo;
 
-                off = handle;
+                in.position(handle);
 
-                return unmarshal(false);
+                return unmarshal();
 
             case OBJ:
-                PortableUtils.checkProtocolVersion(doReadByte(raw));
+                PortableUtils.checkProtocolVersion(in.readByte());
 
                 PortableObjectEx po;
 
@@ -1808,117 +1478,114 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
                 rCtx.setPortableHandler(start, po);
 
-                if (raw)
-                    rawOff = start + po.length();
-                else
-                    off = start + po.length();
+                in.position(start + po.length());
 
                 return po;
 
             case BYTE:
-                return doReadByte(raw);
+                return in.readByte();
 
             case SHORT:
-                return doReadShort(raw);
+                return in.readShort();
 
             case INT:
-                return doReadInt(raw);
+                return in.readInt();
 
             case LONG:
-                return doReadLong(raw);
+                return in.readLong();
 
             case FLOAT:
-                return doReadFloat(raw);
+                return in.readFloat();
 
             case DOUBLE:
-                return doReadDouble(raw);
+                return in.readDouble();
 
             case CHAR:
-                return doReadChar(raw);
+                return in.readChar();
 
             case BOOLEAN:
-                return doReadBoolean(raw);
+                return in.readBoolean();
 
             case DECIMAL:
-                return doReadDecimal(raw);
+                return doReadDecimal();
 
             case STRING:
-                return doReadString(raw);
+                return doReadString();
 
             case UUID:
-                return doReadUuid(raw);
+                return doReadUuid();
 
             case DATE:
-                return doReadDate(raw);
+                return doReadDate();
 
             case TIMESTAMP:
-                return doReadTimestamp(raw);
+                return doReadTimestamp();
 
             case BYTE_ARR:
-                return doReadByteArray(raw);
+                return doReadByteArray();
 
             case SHORT_ARR:
-                return doReadShortArray(raw);
+                return doReadShortArray();
 
             case INT_ARR:
-                return doReadIntArray(raw);
+                return doReadIntArray();
 
             case LONG_ARR:
-                return doReadLongArray(raw);
+                return doReadLongArray();
 
             case FLOAT_ARR:
-                return doReadFloatArray(raw);
+                return doReadFloatArray();
 
             case DOUBLE_ARR:
-                return doReadDoubleArray(raw);
+                return doReadDoubleArray();
 
             case CHAR_ARR:
-                return doReadCharArray(raw);
+                return doReadCharArray();
 
             case BOOLEAN_ARR:
-                return doReadBooleanArray(raw);
+                return doReadBooleanArray();
 
             case DECIMAL_ARR:
-                return doReadDecimalArray(raw);
+                return doReadDecimalArray();
 
             case STRING_ARR:
-                return doReadStringArray(raw);
+                return doReadStringArray();
 
             case UUID_ARR:
-                return doReadUuidArray(raw);
+                return doReadUuidArray();
 
             case DATE_ARR:
-                return doReadDateArray(raw);
+                return doReadDateArray();
 
             case TIMESTAMP_ARR:
-                return doReadTimestampArray(raw);
+                return doReadTimestampArray();
 
             case OBJ_ARR:
-                return doReadObjectArray(raw, false);
+                return doReadObjectArray(false);
 
             case COL:
-                return doReadCollection(raw, false, null);
+                return doReadCollection(false, null);
 
             case MAP:
-                return doReadMap(raw, false, null);
+                return doReadMap(false, null);
 
             case MAP_ENTRY:
-                return doReadMapEntry(raw, false);
+                return doReadMapEntry(false);
 
             case PORTABLE_OBJ:
-                return doReadPortableObject(raw);
+                return doReadPortableObject();
 
             case ENUM:
-                return doReadEnum(raw, doReadClass(raw));
+                return doReadEnum(doReadClass());
 
             case ENUM_ARR:
-                return doReadEnumArray(raw, doReadClass(raw));
+                return doReadEnumArray(doReadClass());
 
             case CLASS:
-                return doReadInt(raw);
+                return in.readInt();
 
             case OPTM_MARSH:
-                int len = doReadInt(true);
+                int len = in.readInt();
 
                 ByteArrayInputStream input = new ByteArrayInputStream(in.array(), in.position(), len);
 
@@ -1931,11 +1598,6 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
                     throw new PortableException("Failed to unmarshal object with optmMarsh marshaller", e);
                 }
 
-                if (raw)
-                    rawOff += len;
-                else
-                    off += len;
-
                 return obj;
 
             default:
@@ -1944,134 +1606,11 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
     }
 
     /**
-     * @param raw Raw flag.
      * @return Value.
      */
-    private byte doReadByte(boolean raw) {
-        in.position(raw ? rawOff++ : off++);
-
-        return in.readByte();
-    }
-
-    /**
-     * @param raw Raw flag.
-     * @return Value.
-     */
-    private short doReadShort(boolean raw) {
-        in.position(raw ? rawOff : off);
-
-        short val = in.readShort();
-
-        if (raw)
-            rawOff += 2;
-        else
-            off += 2;
-
-        return val;
-    }
-
-    /**
-     * @param raw Raw flag.
-     * @return Value.
-     */
-    private int doReadInt(boolean raw) {
-        in.position(raw ? rawOff : off);
-
-        int val = in.readInt();
-
-        if (raw)
-            rawOff += 4;
-        else
-            off += 4;
-
-        return val;
-    }
-
-    /**
-     * @param raw Raw flag.
-     * @return Value.
-     */
-    private long doReadLong(boolean raw) {
-        in.position(raw ? rawOff : off);
-
-        long val = in.readLong();
-
-        if (raw)
-            rawOff += 8;
-        else
-            off += 8;
-
-        return val;
-    }
-
-    /**
-     * @param raw Raw flag.
-     * @return Value.
-     */
-    private float doReadFloat(boolean raw) {
-        in.position(raw ? rawOff : off);
-
-        float val = in.readFloat();
-
-        if (raw)
-            rawOff += 4;
-        else
-            off += 4;
-
-        return val;
-    }
-
-    /**
-     * @param raw Raw flag.
-     * @return Value.
-     */
-    private double doReadDouble(boolean raw) {
-        in.position(raw ? rawOff : off);
-
-        double val = in.readDouble();
-
-        if (raw)
-            rawOff += 8;
-        else
-            off += 8;
-
-        return val;
-    }
-
-    /**
-     * @param raw Raw flag.
-     * @return Value.
-     */
-    private char doReadChar(boolean raw) {
-        in.position(raw ? rawOff : off);
-
-        char val = in.readChar();
-
-        if (raw)
-            rawOff += 2;
-        else
-            off += 2;
-
-        return val;
-    }
-
-    /**
-     * @param raw Raw flag.
-     * @return Value.
-     */
-    private boolean doReadBoolean(boolean raw) {
-        in.position(raw ? rawOff++ : off++);
-
-        return in.readBoolean();
-    }
-
-    /**
-     * @param raw Raw flag.
-     * @return Value.
-     */
-    private BigDecimal doReadDecimal(boolean raw) {
-        int scale = doReadInt(raw);
-        byte[] mag = doReadByteArray(raw);
+    private BigDecimal doReadDecimal() {
+        int scale = in.readInt();
+        byte[] mag = doReadByteArray();
 
         BigInteger intVal = new BigInteger(mag);
 
@@ -2085,55 +1624,48 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
     }
 
     /**
-     * @param raw Raw flag.
      * @return Value.
      */
-    private String doReadString(boolean raw) {
-        if (doReadBoolean(raw)) {
+    private String doReadString() {
+        if (in.readBoolean()) {
             if (!in.hasArray())
-                return new String(doReadByteArray(raw), UTF_8);
+                return new String(doReadByteArray(), UTF_8);
 
-            int strLen = doReadInt(raw);
-            int strOff = raw ? rawOff : off;
+            int strLen = in.readInt();
+            int strOff = in.position();
 
             String res = new String(in.array(), strOff, strLen, UTF_8);
 
-            if (raw)
-                rawOff += strLen;
-            else
-                off += strLen;
+            in.position(in.position() + strLen);
 
             return res;
         }
         else
-            return String.valueOf(doReadCharArray(raw));
+            return String.valueOf(doReadCharArray());
     }
 
     /**
-     * @param raw Raw flag.
      * @return Value.
      */
-    private UUID doReadUuid(boolean raw) {
-        return new UUID(doReadLong(raw), doReadLong(raw));
+    private UUID doReadUuid() {
+        return new UUID(in.readLong(), in.readLong());
     }
 
     /**
-     * @param raw Raw flag.
      * @return Value.
      */
-    private Date doReadDate(boolean raw) {
-        long time = doReadLong(raw);
+    private Date doReadDate() {
+        long time = in.readLong();
 
         return new Date(time);
     }
 
     /**
-     * @param raw Raw flag.
      * @return Value.
      */
-    private Timestamp doReadTimestamp(boolean raw) {
-        long time = doReadLong(raw);
-        int nanos = doReadInt(raw);
+    private Timestamp doReadTimestamp() {
+        long time = in.readLong();
+        int nanos = in.readInt();
 
         Timestamp ts = new Timestamp(time);
 
@@ -2143,21 +1675,13 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
     }
 
     /**
-     * @param raw Raw flag.
      * @return Object.
      * @throws PortableException In case of error.
      */
-    @Nullable private Object doReadObject(boolean raw) throws PortableException {
-        PortableReaderExImpl reader = new PortableReaderExImpl(ctx, in, raw ? rawOff : off, ldr, rCtx);
-
-        Object obj = reader.deserialize();
-
-        if (raw)
-            rawOff += reader.len;
-        else
-            off += reader.len;
+    @Nullable private Object doReadObject() throws PortableException {
+        PortableReaderExImpl reader = new PortableReaderExImpl(ctx, in, in.position(), ldr, rCtx);
 
-        return obj;
+        return reader.deserialize();
     }
 
     /**
@@ -2167,7 +1691,7 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
     @Nullable Object deserialize() throws PortableException {
         Object obj;
 
-        byte flag = doReadByte(true);
+        byte flag = in.readByte();
 
         switch (flag) {
             case NULL:
@@ -2176,196 +1700,201 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
                 break;
 
             case HANDLE:
-                int handle = start - doReadInt(true);
+                int handle = start - in.readInt();
 
                 obj = rCtx.getObjectByHandle(handle);
 
                 if (obj == null) {
-                    off = handle;
+                    int retPos = in.position();
+
+                    in.position(handle);
 
-                    obj = doReadObject(false);
+                    obj = doReadObject();
+
+                    in.position(retPos);
                 }
 
                 break;
 
             case OBJ:
-                if (typeId == null)
-                    readObjectTypeId(true);
+                parseHeaderIfNeeded();
 
                 assert typeId != UNREGISTERED_TYPE_ID;
 
-                PortableUtils.checkProtocolVersion(doReadByte(true));
+                PortableUtils.checkProtocolVersion(in.readByte());
 
-                boolean userType = doReadBoolean(true);
+                boolean userType = PortableUtils.isUserType(this.readShort());
 
                 // Skip typeId and hash code.
-                rawOff += 8;
+                in.position(in.position() + 8);
 
                 desc = ctx.descriptorForTypeId(userType, typeId, ldr);
 
-                len = doReadInt(true);
+                int len = in.readInt();
 
-                rawOff = start + doReadInt(true);
+                in.position(start + hdrLen);
 
                 if (desc == null)
                     throw new PortableInvalidClassException("Unknown type ID: " + typeId);
 
                 obj = desc.read(this);
 
+                in.position(start + len);
+
                 break;
 
             case BYTE:
-                obj = doReadByte(true);
+                obj = in.readByte();
 
                 break;
 
             case SHORT:
-                obj = doReadShort(true);
+                obj = in.readShort();
 
                 break;
 
             case INT:
-                obj = doReadInt(true);
+                obj = in.readInt();
 
                 break;
 
             case LONG:
-                obj = doReadLong(true);
+                obj = in.readLong();
 
                 break;
 
             case FLOAT:
-                obj = doReadFloat(true);
+                obj = in.readFloat();
 
                 break;
 
             case DOUBLE:
-                obj = doReadDouble(true);
+                obj = in.readDouble();
 
                 break;
 
             case CHAR:
-                obj = doReadChar(true);
+                obj = in.readChar();
 
                 break;
 
             case BOOLEAN:
-                obj = doReadBoolean(true);
+                obj = in.readBoolean();
 
                 break;
 
             case DECIMAL:
-                obj = doReadDecimal(true);
+                obj = doReadDecimal();
 
                 break;
 
             case STRING:
-                obj = doReadString(true);
+                obj = doReadString();
 
                 break;
 
             case UUID:
-                obj = doReadUuid(true);
+                obj = doReadUuid();
 
                 break;
 
             case DATE:
-                obj = doReadDate(true);
+                obj = doReadDate();
 
                 break;
 
             case TIMESTAMP:
-                obj = doReadTimestamp(true);
+                obj = doReadTimestamp();
 
                 break;
 
             case BYTE_ARR:
-                obj = doReadByteArray(true);
+                obj = doReadByteArray();
 
                 break;
 
             case SHORT_ARR:
-                obj = doReadShortArray(true);
+                obj = doReadShortArray();
 
                 break;
 
             case INT_ARR:
-                obj = doReadIntArray(true);
+                obj = doReadIntArray();
 
                 break;
 
             case LONG_ARR:
-                obj = doReadLongArray(true);
+                obj = doReadLongArray();
 
                 break;
 
             case FLOAT_ARR:
-                obj = doReadFloatArray(true);
+                obj = doReadFloatArray();
 
                 break;
 
             case DOUBLE_ARR:
-                obj = doReadDoubleArray(true);
+                obj = doReadDoubleArray();
 
                 break;
 
             case CHAR_ARR:
-                obj = doReadCharArray(true);
+                obj = doReadCharArray();
 
                 break;
 
             case BOOLEAN_ARR:
-                obj = doReadBooleanArray(true);
+                obj = doReadBooleanArray();
 
                 break;
 
             case DECIMAL_ARR:
-                obj = doReadDecimalArray(true);
+                obj = doReadDecimalArray();
 
                 break;
 
             case STRING_ARR:
-                obj = doReadStringArray(true);
+                obj = doReadStringArray();
 
                 break;
 
             case UUID_ARR:
-                obj = doReadUuidArray(true);
+                obj = doReadUuidArray();
 
                 break;
 
             case DATE_ARR:
-                obj = doReadDateArray(true);
+                obj = doReadDateArray();
 
                 break;
 
             case TIMESTAMP_ARR:
-                obj = doReadTimestampArray(true);
+                obj = doReadTimestampArray();
 
                 break;
 
             case OBJ_ARR:
-                obj = doReadObjectArray(true, true);
+                obj = doReadObjectArray(true);
 
                 break;
 
             case COL:
-                obj = doReadCollection(true, true, null);
+                obj = doReadCollection(true, null);
 
                 break;
 
             case MAP:
-                obj = doReadMap(true, true, null);
+                obj = doReadMap(true, null);
 
                 break;
 
             case MAP_ENTRY:
-                obj = doReadMapEntry(true, true);
+                obj = doReadMapEntry(true);
 
                 break;
 
             case PORTABLE_OBJ:
-                obj = doReadPortableObject(true);
+                obj = doReadPortableObject();
 
                 ((PortableObjectImpl)obj).context(ctx);
 
@@ -2375,24 +1904,24 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
                 break;
 
             case ENUM:
-                obj = doReadEnum(true, doReadClass(true));
+                obj = doReadEnum(doReadClass());
 
                 break;
 
             case ENUM_ARR:
-                obj = doReadEnumArray(true, doReadClass(true));
+                obj = doReadEnumArray(doReadClass());
 
                 break;
 
             case CLASS:
-                obj = doReadClass(true);
+                obj = doReadClass();
 
                 break;
 
             case OPTM_MARSH:
-                int len = doReadInt(true);
+                int dataLen = in.readInt();
 
-                ByteArrayInputStream input = new ByteArrayInputStream(in.array(), in.position(), len);
+                ByteArrayInputStream input = new ByteArrayInputStream(in.array(), in.position(), dataLen);
 
                 try {
                     obj = ctx.optimizedMarsh().unmarshal(input, null);
@@ -2401,7 +1930,7 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
                     throw new PortableException("Failed to unmarshal object with optimized marshaller", e);
                 }
 
-                rawOff += len;
+                in.position(in.position() + dataLen);
 
                 break;
 
@@ -2409,224 +1938,144 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
                 throw new PortableException("Invalid flag value: " + flag);
         }
 
-        if (len == 0)
-            len = rawOff - start;
-
         return obj;
     }
 
     /**
-     * @param raw Raw flag.
      * @return Value.
      */
-    private byte[] doReadByteArray(boolean raw) {
-        int hPos = (raw ? rawOff : off) - 1;
+    private byte[] doReadByteArray() {
+        int hPos = in.position() - 1;
 
-        int len = doReadInt(raw);
-
-        in.position(raw ? rawOff : off);
+        int len = in.readInt();
 
         byte[] arr = in.readByteArray(len);
 
         setHandler(arr, hPos);
 
-        if (raw)
-            rawOff += len;
-        else
-            off += len;
-
         return arr;
     }
 
     /**
-     * @param raw Raw flag.
      * @return Value.
      */
-    private short[] doReadShortArray(boolean raw) {
-        int hPos = (raw ? rawOff : off) - 1;
-
-        int len = doReadInt(raw);
+    private short[] doReadShortArray() {
+        int hPos = in.position() - 1;
 
-        in.position(raw ? rawOff : off);
+        int len = in.readInt();
 
         short[] arr = in.readShortArray(len);
 
         setHandler(arr, hPos);
 
-        int bytes = len << 1;
-
-        if (raw)
-            rawOff += bytes;
-        else
-            off += bytes;
-
         return arr;
     }
 
     /**
-     * @param raw Raw flag.
      * @return Value.
      */
-    private int[] doReadIntArray(boolean raw) {
-        int hPos = (raw ? rawOff : off) - 1;
-
-        int len = doReadInt(raw);
+    private int[] doReadIntArray() {
+        int hPos = in.position() - 1;
 
-        in.position(raw ? rawOff : off);
+        int len = in.readInt();
 
         int[] arr = in.readIntArray(len);
 
         setHandler(arr, hPos);
 
-        int bytes = len << 2;
-
-        if (raw)
-            rawOff += bytes;
-        else
-            off += bytes;
-
         return arr;
     }
 
     /**
-     * @param raw Raw flag.
      * @return Value.
      */
-    private long[] doReadLongArray(boolean raw) {
-        int hPos = (raw ? rawOff : off) - 1;
-
-        int len = doReadInt(raw);
+    private long[] doReadLongArray() {
+        int hPos = in.position() - 1;
 
-        in.position(raw ? rawOff : off);
+        int len = in.readInt();
 
         long[] arr = in.readLongArray(len);
 
         setHandler(arr, hPos);
 
-        int bytes = len << 3;
-
-        if (raw)
-            rawOff += bytes;
-        else
-            off += bytes;
-
         return arr;
     }
 
     /**
-     * @param raw Raw flag.
      * @return Value.
      */
-    private float[] doReadFloatArray(boolean raw) {
-        int hPos = (raw ? rawOff : off) - 1;
-
-        int len = doReadInt(raw);
+    private float[] doReadFloatArray() {
+        int hPos = in.position() - 1;
 
-        in.position(raw ? rawOff : off);
+        int len = in.readInt();
 
         float[] arr = in.readFloatArray(len);
 
         setHandler(arr, hPos);
 
-        int bytes = len << 2;
-
-        if (raw)
-            rawOff += bytes;
-        else
-            off += bytes;
-
         return arr;
     }
 
     /**
-     * @param raw Raw flag.
      * @return Value.
      */
-    private double[] doReadDoubleArray(boolean raw) {
-        int hPos = (raw ? rawOff : off) - 1;
-
-        int len = doReadInt(raw);
+    private double[] doReadDoubleArray() {
+        int hPos = in.position() - 1;
 
-        in.position(raw ? rawOff : off);
+        int len = in.readInt();
 
         double[] arr = in.readDoubleArray(len);
 
         setHandler(arr, hPos);
 
-        int bytes = len << 3;
-
-        if (raw)
-            rawOff += bytes;
-        else
-            off += bytes;
-
         return arr;
     }
 
     /**
-     * @param raw Raw flag.
      * @return Value.
      */
-    private char[] doReadCharArray(boolean raw) {
-        int hPos = (raw ? rawOff : off) - 1;
-
-        int len = doReadInt(raw);
+    private char[] doReadCharArray() {
+        int hPos = in.position() - 1;
 
-        in.position(raw ? rawOff : off);
+        int len = in.readInt();
 
         char[] arr = in.readCharArray(len);
 
         setHandler(arr, hPos);
 
-        int bytes = len << 1;
-
-        if (raw)
-            rawOff += bytes;
-        else
-            off += bytes;
-
         return arr;
     }
 
     /**
-     * @param raw Raw flag.
      * @return Value.
      */
-    private boolean[] doReadBooleanArray(boolean raw) {
-        int hPos = (raw ? rawOff : off) - 1;
-
-        int len = doReadInt(raw);
+    private boolean[] doReadBooleanArray() {
+        int hPos = in.position() - 1;
 
-        in.position(raw ? rawOff : off);
+        int len = in.readInt();
 
         boolean[] arr = in.readBooleanArray(len);
 
         setHandler(arr, hPos);
 
-        if (raw)
-            rawOff += len;
-        else
-            off += len;
-
         return arr;
     }
 
     /**
-     * @param raw Raw flag.
      * @return Value.
      * @throws PortableException In case of error.
      */
-    private BigDecimal[] doReadDecimalArray(boolean raw) throws PortableException {
-        int hPos = (raw ? rawOff : off) - 1;
+    private BigDecimal[] doReadDecimalArray() throws PortableException {
+        int hPos = in.position() - 1;
 
-        int len = doReadInt(raw);
+        int len = in.readInt();
 
         BigDecimal[] arr = new BigDecimal[len];
 
         setHandler(arr, hPos);
 
         for (int i = 0; i < len; i++) {
-            byte flag = doReadByte(raw);
+            byte flag = in.readByte();
 
             if (flag == NULL)
                 arr[i] = null;
@@ -2634,7 +2083,7 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
                 if (flag != DECIMAL)
                     throw new PortableException("Invalid flag value: " + flag);
 
-                arr[i] = doReadDecimal(raw);
+                arr[i] = doReadDecimal();
             }
         }
 
@@ -2642,21 +2091,20 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
     }
 
     /**
-     * @param raw Raw flag.
      * @return Value.
      * @throws PortableException In case of error.
      */
-    private String[] doReadStringArray(boolean raw) throws PortableException {
-        int hPos = (raw ? rawOff : off) - 1;
+    private String[] doReadStringArray() throws PortableException {
+        int hPos = in.position() - 1;
 
-        int len = doReadInt(raw);
+        int len = in.readInt();
 
         String[] arr = new String[len];
 
         setHandler(arr, hPos);
 
         for (int i = 0; i < len; i++) {
-            byte flag = doReadByte(raw);
+            byte flag = in.readByte();
 
             if (flag == NULL)
                 arr[i] = null;
@@ -2664,7 +2112,7 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
                 if (flag != STRING)
                     throw new PortableException("Invalid flag value: " + flag);
 
-                arr[i] = doReadString(raw);
+                arr[i] = doReadString();
             }
         }
 
@@ -2672,21 +2120,20 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
     }
 
     /**
-     * @param raw Raw flag.
      * @return Value.
      * @throws PortableException In case of error.
      */
-    private UUID[] doReadUuidArray(boolean raw) throws PortableException {
-        int hPos = (raw ? rawOff : off) - 1;
+    private UUID[] doReadUuidArray() throws PortableException {
+        int hPos = in.position() - 1;
 
-        int len = doReadInt(raw);
+        int len = in.readInt();
 
         UUID[] arr = new UUID[len];
 
         setHandler(arr, hPos);
 
         for (int i = 0; i < len; i++) {
-            byte flag = doReadByte(raw);
+            byte flag = in.readByte();
 
             if (flag == NULL)
                 arr[i] = null;
@@ -2694,7 +2141,7 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
                 if (flag != UUID)
                     throw new PortableException("Invalid flag value: " + flag);
 
-                arr[i] = doReadUuid(raw);
+                arr[i] = doReadUuid();
             }
         }
 
@@ -2702,21 +2149,20 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
     }
 
     /**
-     * @param raw Raw flag.
      * @return Value.
      * @throws PortableException In case of error.
      */
-    private Date[] doReadDateArray(boolean raw) throws PortableException {
-        int hPos = (raw ? rawOff : off) - 1;
+    private Date[] doReadDateArray() throws PortableException {
+        int hPos = in.position() - 1;
 
-        int len = doReadInt(raw);
+        int len = in.readInt();
 
         Date[] arr = new Date[len];
 
         setHandler(arr, hPos);
 
         for (int i = 0; i < len; i++) {
-            byte flag = doReadByte(raw);
+            byte flag = in.readByte();
 
             if (flag == NULL)
                 arr[i] = null;
@@ -2724,7 +2170,7 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
                 if (flag != DATE)
                     throw new PortableException("Invalid flag value: " + flag);
 
-                arr[i] = doReadDate(raw);
+                arr[i] = doReadDate();
             }
         }
 
@@ -2732,21 +2178,20 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
     }
 
     /**
-     * @param raw Raw flag.
      * @return Value.
      * @throws PortableException In case of error.
      */
-    private Timestamp[] doReadTimestampArray(boolean raw) throws PortableException {
-        int hPos = (raw ? rawOff : off) - 1;
+    private Timestamp[] doReadTimestampArray() throws PortableException {
+        int hPos = in.position() - 1;
 
-        int len = doReadInt(raw);
+        int len = in.readInt();
 
         Timestamp[] arr = new Timestamp[len];
 
         setHandler(arr, hPos);
 
         for (int i = 0; i < len; i++) {
-            byte flag = doReadByte(raw);
+            byte flag = in.readByte();
 
             if (flag == NULL)
                 arr[i] = null;
@@ -2754,7 +2199,7 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
                 if (flag != TIMESTAMP)
                     throw new PortableException("Invalid flag value: " + flag);
 
-                arr[i] = doReadTimestamp(raw);
+                arr[i] = doReadTimestamp();
             }
         }
 
@@ -2762,45 +2207,43 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
     }
 
     /**
-     * @param raw Raw flag.
      * @param deep Deep flag.
      * @return Value.
      * @throws PortableException In case of error.
      */
-    private Object[] doReadObjectArray(boolean raw, boolean deep) throws PortableException {
-        int hPos = (raw ? rawOff : off) - 1;
+    private Object[] doReadObjectArray(boolean deep) throws PortableException {
+        int hPos = in.position() - 1;
 
-        Class compType = doReadClass(raw);
+        Class compType = doReadClass();
 
-        int len = doReadInt(raw);
+        int len = in.readInt();
 
         Object[] arr = deep ? (Object[])Array.newInstance(compType, len) : new Object[len];
 
         setHandler(arr, hPos);
 
         for (int i = 0; i < len; i++)
-            arr[i] = deep ? doReadObject(raw) : unmarshal(raw);
+            arr[i] = deep ? doReadObject() : unmarshal();
 
         return arr;
     }
 
     /**
-     * @param raw Raw flag.
      * @param deep Deep flag.
      * @param cls Collection class.
      * @return Value.
      * @throws PortableException In case of error.
      */
     @SuppressWarnings("unchecked")
-    private Collection<?> doReadCollection(boolean raw, boolean deep, @Nullable Class<? extends Collection> cls)
+    private Collection<?> doReadCollection(boolean deep, @Nu

<TRUNCATED>