This is an automated email from the ASF dual-hosted git repository.

ptupitsyn pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git


The following commit(s) were added to refs/heads/main by this push:
     new 706ce62713 IGNITE-20375 Remove arrayHeader and mapHeader usage from 
client protocol (#2564)
706ce62713 is described below

commit 706ce627131be2b636012f2b5e7e7c339b595a75
Author: Pavel Tupitsyn <[email protected]>
AuthorDate: Mon Sep 11 17:39:22 2023 +0300

    IGNITE-20375 Remove arrayHeader and mapHeader usage from client protocol 
(#2564)
    
    To make the client protocol consistent and simple, get rid of `arrayHeader` 
and `mapHeader`, use `int` instead.
    
    MsgPack arrays and maps are difficult to work with in some 
languages/libraries; may require the entire thing to be retrieved and stored in 
memory before accessing (no streaming access).
---
 .../internal/client/proto/ClientMessagePacker.java |  48 +-------
 .../client/proto/ClientMessageUnpacker.java        |  54 +--------
 .../jdbc/proto/event/JdbcBatchExecuteRequest.java  |   4 +-
 .../proto/event/JdbcBatchPreparedStmntRequest.java |   4 +-
 .../jdbc/proto/event/JdbcMetaColumnsResult.java    |   4 +-
 .../proto/event/JdbcMetaPrimaryKeysResult.java     |   4 +-
 .../jdbc/proto/event/JdbcMetaSchemasResult.java    |   4 +-
 .../jdbc/proto/event/JdbcMetaTablesRequest.java    |   4 +-
 .../jdbc/proto/event/JdbcPrimaryKeyMeta.java       |   4 +-
 .../jdbc/proto/event/JdbcQueryExecuteResult.java   |   4 +-
 .../jdbc/proto/event/JdbcQueryFetchResult.java     |   4 +-
 .../jdbc/proto/event/JdbcQuerySingleResult.java    |   4 +-
 .../client/proto/ClientMessagePackerTest.java      |  12 --
 .../client/proto/ClientMessageUnpackerTest.java    |  22 +---
 .../ignite/client/handler/ItClientHandlerTest.java |  12 +-
 .../client/handler/ItClientHandlerTestUtils.java   |   2 +-
 .../handler/ClientInboundMessageHandler.java       |   6 +-
 .../cluster/ClientClusterGetNodesRequest.java      |   4 +-
 .../compute/ClientComputeExecuteRequest.java       |   2 +-
 .../handler/requests/sql/ClientSqlCommon.java      |   2 +-
 .../requests/sql/ClientSqlExecuteRequest.java      |   6 +-
 .../requests/table/ClientSchemasGetRequest.java    |   6 +-
 .../handler/requests/table/ClientTableCommon.java  |   4 +-
 .../ClientTablePartitionAssignmentGetRequest.java  |   4 +-
 .../requests/table/ClientTablesGetRequest.java     |   2 +-
 .../ignite/internal/client/TcpClientChannel.java   |  11 +-
 .../ignite/internal/client/TcpIgniteClient.java    |   4 +-
 .../internal/client/compute/ClientCompute.java     |   2 +-
 .../internal/client/sql/ClientAsyncResultSet.java  |   2 +-
 .../internal/client/sql/ClientColumnMetadata.java  |   2 +-
 .../client/sql/ClientResultSetMetadata.java        |   2 +-
 .../ignite/internal/client/table/ClientTable.java  |  11 +-
 .../ignite/internal/client/table/ClientTables.java |   2 +-
 modules/platforms/cpp/DEVNOTES.md                  |  12 +-
 .../ignite/client/detail/compute/compute_impl.cpp  |   2 +-
 .../ignite/client/detail/ignite_client_impl.cpp    |  21 ++--
 .../cpp/ignite/client/detail/sql/result_set_impl.h |  63 +++++-----
 .../cpp/ignite/client/detail/table/schema.h        |  40 +++----
 .../cpp/ignite/client/detail/table/table_impl.cpp  |   8 +-
 .../cpp/ignite/client/detail/table/tables_impl.cpp |  16 +--
 .../platforms/cpp/ignite/odbc/query/data_query.cpp |  48 ++++----
 .../platforms/cpp/ignite/odbc/query/result_page.h  |   5 +-
 .../cpp/ignite/odbc/query/table_metadata_query.cpp |   2 +-
 modules/platforms/cpp/ignite/protocol/reader.h     | 132 ++++-----------------
 modules/platforms/cpp/ignite/protocol/utils.cpp    |  36 ++++--
 modules/platforms/cpp/ignite/protocol/utils.h      |  35 +++---
 modules/platforms/cpp/ignite/protocol/writer.h     |  13 +-
 .../cpp/tests/client-test/compute_test.cpp         |   6 +-
 .../tests/client-test/record_binary_view_test.cpp  |   1 +
 .../dotnet/Apache.Ignite.Tests/FakeServer.cs       |  44 +++----
 .../Proto/MsgPack/MsgPackReaderTests.cs            |  34 +-----
 .../Proto/MsgPack/MsgPackWriterTests.cs            |  26 ----
 .../RawSocketConnectionTests.cs                    |   2 +-
 .../dotnet/Apache.Ignite.Tests/Sql/SqlTests.cs     |   4 +-
 .../dotnet/Apache.Ignite/Internal/ClientSocket.cs  |   6 +-
 .../Apache.Ignite/Internal/Compute/Compute.cs      |   2 +-
 .../Apache.Ignite/Internal/IgniteClientInternal.cs |   4 +-
 .../Internal/Proto/MsgPack/MsgPackReader.cs        |  26 ----
 .../Internal/Proto/MsgPack/MsgPackWriter.cs        |  52 --------
 .../dotnet/Apache.Ignite/Internal/Sql/ResultSet.cs |  13 +-
 .../dotnet/Apache.Ignite/Internal/Table/Table.cs   |  10 +-
 .../dotnet/Apache.Ignite/Internal/Table/Tables.cs  |   2 +-
 .../dotnet/Apache.Ignite/Sql/IgniteDbDataReader.cs |   2 +-
 63 files changed, 296 insertions(+), 633 deletions(-)

diff --git 
a/modules/client-common/src/main/java/org/apache/ignite/internal/client/proto/ClientMessagePacker.java
 
b/modules/client-common/src/main/java/org/apache/ignite/internal/client/proto/ClientMessagePacker.java
index f4ef190be4..e2ef846964 100644
--- 
a/modules/client-common/src/main/java/org/apache/ignite/internal/client/proto/ClientMessagePacker.java
+++ 
b/modules/client-common/src/main/java/org/apache/ignite/internal/client/proto/ClientMessagePacker.java
@@ -339,52 +339,6 @@ public class ClientMessagePacker implements AutoCloseable {
         buf.writerIndex(endPos);
     }
 
-    /**
-     * Writes an array header value.
-     *
-     * @param arraySize array size.
-     */
-    public void packArrayHeader(int arraySize) {
-        assert !closed : "Packer is closed";
-
-        if (arraySize < 0) {
-            throw new IllegalArgumentException("array size must be >= 0");
-        }
-
-        if (arraySize < (1 << 4)) {
-            buf.writeByte((byte) (Code.FIXARRAY_PREFIX | arraySize));
-        } else if (arraySize < (1 << 16)) {
-            buf.writeByte(Code.ARRAY16);
-            buf.writeShort(arraySize);
-        } else {
-            buf.writeByte(Code.ARRAY32);
-            buf.writeInt(arraySize);
-        }
-    }
-
-    /**
-     * Writes a map header value.
-     *
-     * @param mapSize map size.
-     */
-    public void packMapHeader(int mapSize) {
-        assert !closed : "Packer is closed";
-
-        if (mapSize < 0) {
-            throw new IllegalArgumentException("map size must be >= 0");
-        }
-
-        if (mapSize < (1 << 4)) {
-            buf.writeByte((byte) (Code.FIXMAP_PREFIX | mapSize));
-        } else if (mapSize < (1 << 16)) {
-            buf.writeByte(Code.MAP16);
-            buf.writeShort(mapSize);
-        } else {
-            buf.writeByte(Code.MAP32);
-            buf.writeInt(mapSize);
-        }
-    }
-
     /**
      * Writes Extension value header.
      *
@@ -564,7 +518,7 @@ public class ClientMessagePacker implements AutoCloseable {
             return;
         }
 
-        packArrayHeader(arr.length);
+        packInt(arr.length);
 
         for (int i : arr) {
             packInt(i);
diff --git 
a/modules/client-common/src/main/java/org/apache/ignite/internal/client/proto/ClientMessageUnpacker.java
 
b/modules/client-common/src/main/java/org/apache/ignite/internal/client/proto/ClientMessageUnpacker.java
index 48cddaeee3..74ed2d7d2c 100644
--- 
a/modules/client-common/src/main/java/org/apache/ignite/internal/client/proto/ClientMessageUnpacker.java
+++ 
b/modules/client-common/src/main/java/org/apache/ignite/internal/client/proto/ClientMessageUnpacker.java
@@ -360,58 +360,6 @@ public class ClientMessageUnpacker implements 
AutoCloseable {
         }
     }
 
-    /**
-     * Reads an array header.
-     *
-     * @return Array size.
-     */
-    public int unpackArrayHeader() {
-        assert refCnt > 0 : "Unpacker is closed";
-
-        byte code = buf.readByte();
-
-        if (Code.isFixedArray(code)) { // fixarray
-            return code & 0x0f;
-        }
-
-        switch (code) {
-            case Code.ARRAY16:
-                return readLength16();
-
-            case Code.ARRAY32:
-                return readLength32();
-
-            default:
-                throw unexpected("Array", code);
-        }
-    }
-
-    /**
-     * Reads a map header.
-     *
-     * @return Map size.
-     */
-    public int unpackMapHeader() {
-        assert refCnt > 0 : "Unpacker is closed";
-
-        byte code = buf.readByte();
-
-        if (Code.isFixedMap(code)) { // fixmap
-            return code & 0x0f;
-        }
-
-        switch (code) {
-            case Code.MAP16:
-                return readLength16();
-
-            case Code.MAP32:
-                return readLength32();
-
-            default:
-                throw unexpected("Map", code);
-        }
-    }
-
     /**
      * Reads an extension type header.
      *
@@ -751,7 +699,7 @@ public class ClientMessageUnpacker implements AutoCloseable 
{
     public int[] unpackIntArray() {
         assert refCnt > 0 : "Unpacker is closed";
 
-        int size = unpackArrayHeader();
+        int size = unpackInt();
 
         if (size == 0) {
             return ArrayUtils.INT_EMPTY_ARRAY;
diff --git 
a/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcBatchExecuteRequest.java
 
b/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcBatchExecuteRequest.java
index 403b64f26c..089ebb7317 100644
--- 
a/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcBatchExecuteRequest.java
+++ 
b/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcBatchExecuteRequest.java
@@ -92,7 +92,7 @@ public class JdbcBatchExecuteRequest implements ClientMessage 
{
         packer.packBoolean(autoCommit);
         ClientMessageUtils.writeStringNullable(packer, schemaName);
 
-        packer.packArrayHeader(queries.size());
+        packer.packInt(queries.size());
 
         for (String q : queries) {
             packer.packString(q);
@@ -105,7 +105,7 @@ public class JdbcBatchExecuteRequest implements 
ClientMessage {
         autoCommit = unpacker.unpackBoolean();
         schemaName = ClientMessageUtils.readStringNullable(unpacker);
 
-        int n = unpacker.unpackArrayHeader();
+        int n = unpacker.unpackInt();
 
         queries = new ArrayList<>(n);
 
diff --git 
a/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcBatchPreparedStmntRequest.java
 
b/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcBatchPreparedStmntRequest.java
index 609f456cbf..a94093c4fe 100644
--- 
a/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcBatchPreparedStmntRequest.java
+++ 
b/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcBatchPreparedStmntRequest.java
@@ -109,7 +109,7 @@ public class JdbcBatchPreparedStmntRequest implements 
ClientMessage {
         ClientMessageUtils.writeStringNullable(packer, schemaName);
 
         packer.packString(query);
-        packer.packArrayHeader(args.size());
+        packer.packInt(args.size());
 
         for (Object[] arg : args) {
             packer.packObjectArrayAsBinaryTuple(arg);
@@ -124,7 +124,7 @@ public class JdbcBatchPreparedStmntRequest implements 
ClientMessage {
 
         query = unpacker.unpackString();
 
-        int n = unpacker.unpackArrayHeader();
+        int n = unpacker.unpackInt();
 
         args = new ArrayList<>(n);
 
diff --git 
a/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcMetaColumnsResult.java
 
b/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcMetaColumnsResult.java
index 0b0204c93e..48924ca59c 100644
--- 
a/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcMetaColumnsResult.java
+++ 
b/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcMetaColumnsResult.java
@@ -80,7 +80,7 @@ public class JdbcMetaColumnsResult extends Response {
             return;
         }
 
-        packer.packArrayHeader(meta.size());
+        packer.packInt(meta.size());
 
         for (JdbcColumnMeta m : meta) {
             m.writeBinary(packer);
@@ -96,7 +96,7 @@ public class JdbcMetaColumnsResult extends Response {
             return;
         }
 
-        int size = unpacker.unpackArrayHeader();
+        int size = unpacker.unpackInt();
 
         if (size == 0) {
             meta = Collections.emptyList();
diff --git 
a/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcMetaPrimaryKeysResult.java
 
b/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcMetaPrimaryKeysResult.java
index caa51c24a0..b42d0d2a56 100644
--- 
a/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcMetaPrimaryKeysResult.java
+++ 
b/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcMetaPrimaryKeysResult.java
@@ -67,7 +67,7 @@ public class JdbcMetaPrimaryKeysResult extends Response {
             return;
         }
 
-        packer.packArrayHeader(meta.size());
+        packer.packInt(meta.size());
 
         for (JdbcPrimaryKeyMeta keyMeta : meta) {
             keyMeta.writeBinary(packer);
@@ -89,7 +89,7 @@ public class JdbcMetaPrimaryKeysResult extends Response {
             return;
         }
 
-        int size = unpacker.unpackArrayHeader();
+        int size = unpacker.unpackInt();
 
         meta = new ArrayList<>(size);
 
diff --git 
a/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcMetaSchemasResult.java
 
b/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcMetaSchemasResult.java
index 60437071aa..eb00de8eef 100644
--- 
a/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcMetaSchemasResult.java
+++ 
b/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcMetaSchemasResult.java
@@ -59,7 +59,7 @@ public class JdbcMetaSchemasResult extends Response {
             return;
         }
 
-        packer.packArrayHeader(schemas.size());
+        packer.packInt(schemas.size());
 
         for (String schema : schemas) {
             packer.packString(schema);
@@ -75,7 +75,7 @@ public class JdbcMetaSchemasResult extends Response {
             return;
         }
 
-        int size = unpacker.unpackArrayHeader();
+        int size = unpacker.unpackInt();
 
         schemas = new ArrayList<>(size);
 
diff --git 
a/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcMetaTablesRequest.java
 
b/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcMetaTablesRequest.java
index 1ec697cdda..df3094dec7 100644
--- 
a/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcMetaTablesRequest.java
+++ 
b/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcMetaTablesRequest.java
@@ -93,7 +93,7 @@ public class JdbcMetaTablesRequest implements ClientMessage {
             return;
         }
 
-        packer.packArrayHeader(tblTypes.length);
+        packer.packInt(tblTypes.length);
 
         for (String type : tblTypes) {
             packer.packString(type);
@@ -110,7 +110,7 @@ public class JdbcMetaTablesRequest implements ClientMessage 
{
             return;
         }
 
-        int size = unpacker.unpackArrayHeader();
+        int size = unpacker.unpackInt();
 
         tblTypes = new String[size];
 
diff --git 
a/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcPrimaryKeyMeta.java
 
b/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcPrimaryKeyMeta.java
index 8d0daeba44..0585bb1ffb 100644
--- 
a/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcPrimaryKeyMeta.java
+++ 
b/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcPrimaryKeyMeta.java
@@ -111,7 +111,7 @@ public class JdbcPrimaryKeyMeta implements ClientMessage {
             packer.packNil();
         }
 
-        packer.packArrayHeader(fields.size());
+        packer.packInt(fields.size());
 
         for (String field : fields) {
             packer.packString(field);
@@ -131,7 +131,7 @@ public class JdbcPrimaryKeyMeta implements ClientMessage {
             return;
         }
 
-        int size = unpacker.unpackArrayHeader();
+        int size = unpacker.unpackInt();
 
         fields = new ArrayList<>(size);
 
diff --git 
a/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcQueryExecuteResult.java
 
b/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcQueryExecuteResult.java
index 771027a644..7bb2b10126 100644
--- 
a/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcQueryExecuteResult.java
+++ 
b/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcQueryExecuteResult.java
@@ -72,7 +72,7 @@ public class JdbcQueryExecuteResult extends Response {
             return;
         }
 
-        packer.packArrayHeader(results.size());
+        packer.packInt(results.size());
 
         for (JdbcQuerySingleResult result : results) {
             result.writeBinary(packer);
@@ -88,7 +88,7 @@ public class JdbcQueryExecuteResult extends Response {
             return;
         }
 
-        int size = unpacker.unpackArrayHeader();
+        int size = unpacker.unpackInt();
 
         if (size == 0) {
             results = Collections.emptyList();
diff --git 
a/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcQueryFetchResult.java
 
b/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcQueryFetchResult.java
index 81d044b1c4..329ed7a5e8 100644
--- 
a/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcQueryFetchResult.java
+++ 
b/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcQueryFetchResult.java
@@ -95,7 +95,7 @@ public class JdbcQueryFetchResult extends Response {
 
         packer.packBoolean(last);
 
-        packer.packArrayHeader(items.size());
+        packer.packInt(items.size());
 
         for (List<Object> item : items) {
             packer.packObjectArrayAsBinaryTuple(item.toArray());
@@ -113,7 +113,7 @@ public class JdbcQueryFetchResult extends Response {
 
         last = unpacker.unpackBoolean();
 
-        int size = unpacker.unpackArrayHeader();
+        int size = unpacker.unpackInt();
 
         items = new ArrayList<>(size);
 
diff --git 
a/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcQuerySingleResult.java
 
b/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcQuerySingleResult.java
index 7dcd768802..5c08d08e6f 100644
--- 
a/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcQuerySingleResult.java
+++ 
b/modules/client-common/src/main/java/org/apache/ignite/internal/jdbc/proto/event/JdbcQuerySingleResult.java
@@ -161,7 +161,7 @@ public class JdbcQuerySingleResult extends Response {
         packer.packLong(updateCnt);
         packer.packBoolean(last);
 
-        packer.packArrayHeader(items.size());
+        packer.packInt(items.size());
 
         for (List<Object> item : items) {
             packer.packObjectArrayAsBinaryTuple(item.toArray());
@@ -186,7 +186,7 @@ public class JdbcQuerySingleResult extends Response {
         updateCnt = unpacker.unpackLong();
         last = unpacker.unpackBoolean();
 
-        int size = unpacker.unpackArrayHeader();
+        int size = unpacker.unpackInt();
 
         items = new ArrayList<>(size);
 
diff --git 
a/modules/client-common/src/test/java/org/apache/ignite/internal/client/proto/ClientMessagePackerTest.java
 
b/modules/client-common/src/test/java/org/apache/ignite/internal/client/proto/ClientMessagePackerTest.java
index a28646e7c1..4368c668c0 100644
--- 
a/modules/client-common/src/test/java/org/apache/ignite/internal/client/proto/ClientMessagePackerTest.java
+++ 
b/modules/client-common/src/test/java/org/apache/ignite/internal/client/proto/ClientMessagePackerTest.java
@@ -140,18 +140,6 @@ public class ClientMessagePackerTest {
         }
     }
 
-    @ParameterizedTest
-    @ValueSource(ints = {0, 1, 255, 256, 65535, 65536, Integer.MAX_VALUE})
-    public void testPackArrayHeader(int i) {
-        testPacker(p -> p.packArrayHeader(i), p -> p.packArrayHeader(i));
-    }
-
-    @ParameterizedTest
-    @ValueSource(ints = {0, 1, 255, 256, 65535, 65536, Integer.MAX_VALUE})
-    public void testPackMapHeader(int i) {
-        testPacker(p -> p.packMapHeader(i), p -> p.packMapHeader(i));
-    }
-
     @ParameterizedTest
     @ValueSource(ints = {0, 1, 255, 256, 65535, 65536, Integer.MAX_VALUE})
     public void testPackExtensionTypeHeader(int i) {
diff --git 
a/modules/client-common/src/test/java/org/apache/ignite/internal/client/proto/ClientMessageUnpackerTest.java
 
b/modules/client-common/src/test/java/org/apache/ignite/internal/client/proto/ClientMessageUnpackerTest.java
index f355466aea..96f473d410 100644
--- 
a/modules/client-common/src/test/java/org/apache/ignite/internal/client/proto/ClientMessageUnpackerTest.java
+++ 
b/modules/client-common/src/test/java/org/apache/ignite/internal/client/proto/ClientMessageUnpackerTest.java
@@ -22,7 +22,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
-import java.util.UUID;
 import java.util.function.Consumer;
 import java.util.function.Function;
 import org.junit.jupiter.api.Test;
@@ -132,18 +131,6 @@ public class ClientMessageUnpackerTest {
         testUnpacker(p -> p.packString(s2), 
ClientMessageUnpacker::unpackString, s2);
     }
 
-    @ParameterizedTest
-    @ValueSource(ints = {0, 1, 255, 256, 65535, 65536, Integer.MAX_VALUE})
-    public void testUnpackArrayHeader(int i) {
-        testUnpacker(p -> p.packArrayHeader(i), 
ClientMessageUnpacker::unpackArrayHeader, i);
-    }
-
-    @ParameterizedTest
-    @ValueSource(ints = {0, 1, 255, 256, 65535, 65536, Integer.MAX_VALUE})
-    public void testUnpackMapHeader(int i) {
-        testUnpacker(p -> p.packMapHeader(i), 
ClientMessageUnpacker::unpackMapHeader, i);
-    }
-
     @ParameterizedTest
     @ValueSource(ints = {0, 1, 255, 256, 65535, 65536, Integer.MAX_VALUE})
     public void testUnpackExtensionTypeHeader(int i) {
@@ -177,13 +164,8 @@ public class ClientMessageUnpackerTest {
             p.packInt(123456);
             p.packBoolean(false);
 
-            p.packMapHeader(3);
-            p.packString("x");
-            p.packNil();
-            p.packUuid(UUID.randomUUID());
-            p.packLong(123);
-            p.packUuid(UUID.randomUUID());
-            p.packLong(UUID.randomUUID().getLeastSignificantBits());
+            p.packBinaryHeader(33);
+            p.writePayload(new byte[33]);
 
             p.packDouble(1.1);
             p.packDouble(2.2);
diff --git 
a/modules/client-handler/src/integrationTest/java/org/apache/ignite/client/handler/ItClientHandlerTest.java
 
b/modules/client-handler/src/integrationTest/java/org/apache/ignite/client/handler/ItClientHandlerTest.java
index cb0cda204a..b210e44388 100644
--- 
a/modules/client-handler/src/integrationTest/java/org/apache/ignite/client/handler/ItClientHandlerTest.java
+++ 
b/modules/client-handler/src/integrationTest/java/org/apache/ignite/client/handler/ItClientHandlerTest.java
@@ -105,7 +105,7 @@ public class ItClientHandlerTest extends 
BaseIgniteAbstractTest {
             packer.packInt(2); // Client type: general purpose.
 
             packer.packBinaryHeader(0); // Features.
-            packer.packMapHeader(0); // Extensions.
+            packer.packInt(0); // Extensions.
 
             out.write(packer.toByteArray());
             out.flush();
@@ -129,7 +129,7 @@ public class ItClientHandlerTest extends 
BaseIgniteAbstractTest {
             var featuresLen = unpacker.unpackBinaryHeader();
             unpacker.skipValue(featuresLen);
 
-            var extensionsLen = unpacker.unpackMapHeader();
+            var extensionsLen = unpacker.unpackInt();
             unpacker.skipValue(extensionsLen);
 
             assertArrayEquals(MAGIC, magic);
@@ -167,7 +167,7 @@ public class ItClientHandlerTest extends 
BaseIgniteAbstractTest {
             packer.packInt(2); // Client type: general purpose.
 
             packer.packBinaryHeader(0); // Features.
-            packer.packMapHeader(3); // Extensions.
+            packer.packInt(3); // Extensions.
             packer.packString("authn-type");
             packer.packString("basic");
             packer.packString("authn-identity");
@@ -197,7 +197,7 @@ public class ItClientHandlerTest extends 
BaseIgniteAbstractTest {
             var featuresLen = unpacker.unpackBinaryHeader();
             unpacker.skipValue(featuresLen);
 
-            var extensionsLen = unpacker.unpackMapHeader();
+            var extensionsLen = unpacker.unpackInt();
             unpacker.skipValue(extensionsLen);
 
             assertArrayEquals(MAGIC, magic);
@@ -235,7 +235,7 @@ public class ItClientHandlerTest extends 
BaseIgniteAbstractTest {
             packer.packInt(2); // Client type: general purpose.
 
             packer.packBinaryHeader(0); // Features.
-            packer.packMapHeader(0); // Extensions.
+            packer.packInt(0); // Extensions.
 
             out.write(packer.toByteArray());
             out.flush();
@@ -288,7 +288,7 @@ public class ItClientHandlerTest extends 
BaseIgniteAbstractTest {
             packer.packInt(2); // Client type: general purpose.
 
             packer.packBinaryHeader(0); // Features.
-            packer.packMapHeader(0); // Extensions.
+            packer.packInt(0); // Extensions.
 
             out.write(packer.toByteArray());
             out.flush();
diff --git 
a/modules/client-handler/src/integrationTest/java/org/apache/ignite/client/handler/ItClientHandlerTestUtils.java
 
b/modules/client-handler/src/integrationTest/java/org/apache/ignite/client/handler/ItClientHandlerTestUtils.java
index fcf6335cdb..01e7de1475 100644
--- 
a/modules/client-handler/src/integrationTest/java/org/apache/ignite/client/handler/ItClientHandlerTestUtils.java
+++ 
b/modules/client-handler/src/integrationTest/java/org/apache/ignite/client/handler/ItClientHandlerTestUtils.java
@@ -103,7 +103,7 @@ class ItClientHandlerTestUtils {
             packer.packInt(2); // Client type: general purpose.
 
             packer.packBinaryHeader(0); // Features.
-            packer.packMapHeader(0); // Extensions.
+            packer.packInt(0); // Extensions.
 
             out.write(packer.toByteArray());
             out.flush();
diff --git 
a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/ClientInboundMessageHandler.java
 
b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/ClientInboundMessageHandler.java
index 6ac1809e83..79866353b1 100644
--- 
a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/ClientInboundMessageHandler.java
+++ 
b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/ClientInboundMessageHandler.java
@@ -306,7 +306,7 @@ public class ClientInboundMessageHandler extends 
ChannelInboundHandlerAdapter im
             packer.packUuid(clusterId.join());
 
             packer.packBinaryHeader(0); // Features.
-            packer.packMapHeader(0); // Extensions.
+            packer.packInt(0); // Extensions.
 
             write(packer, ctx);
 
@@ -436,7 +436,7 @@ public class ClientInboundMessageHandler extends 
ChannelInboundHandlerAdapter im
 
         // Extensions.
         if (schemaVersionMismatchException != null) {
-            packer.packMapHeader(1);
+            packer.packInt(1);
             packer.packString(ErrorExtensions.EXPECTED_SCHEMA_VERSION);
             packer.packInt(schemaVersionMismatchException.expectedVersion());
         } else {
@@ -713,7 +713,7 @@ public class ClientInboundMessageHandler extends 
ChannelInboundHandlerAdapter im
 
     private static Map<HandshakeExtension, Object> 
extractExtensions(ClientMessageUnpacker unpacker) {
         EnumMap<HandshakeExtension, Object> extensions = new 
EnumMap<>(HandshakeExtension.class);
-        int mapSize = unpacker.unpackMapHeader();
+        int mapSize = unpacker.unpackInt();
         for (int i = 0; i < mapSize; i++) {
             HandshakeExtension handshakeExtension = 
HandshakeExtension.fromKey(unpacker.unpackString());
             if (handshakeExtension != null) {
diff --git 
a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/cluster/ClientClusterGetNodesRequest.java
 
b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/cluster/ClientClusterGetNodesRequest.java
index 4d3d137083..fac34d89da 100644
--- 
a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/cluster/ClientClusterGetNodesRequest.java
+++ 
b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/cluster/ClientClusterGetNodesRequest.java
@@ -39,10 +39,10 @@ public class ClientClusterGetNodesRequest {
             ClusterService clusterService) {
         Collection<ClusterNode> nodes = 
clusterService.topologyService().allMembers();
 
-        out.packArrayHeader(nodes.size());
+        out.packInt(nodes.size());
 
         for (ClusterNode node : nodes) {
-            out.packArrayHeader(4);
+            out.packInt(4);
 
             out.packString(node.id());
             out.packString(node.name());
diff --git 
a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/compute/ClientComputeExecuteRequest.java
 
b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/compute/ClientComputeExecuteRequest.java
index e6364f68ce..ee3d9ff8b1 100644
--- 
a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/compute/ClientComputeExecuteRequest.java
+++ 
b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/compute/ClientComputeExecuteRequest.java
@@ -81,7 +81,7 @@ public class ClientComputeExecuteRequest {
      * @return Deployment units.
      */
     static List<DeploymentUnit> unpackDeploymentUnits(ClientMessageUnpacker 
in) {
-        int size = in.tryUnpackNil() ? 0 : in.unpackArrayHeader();
+        int size = in.tryUnpackNil() ? 0 : in.unpackInt();
         List<DeploymentUnit> res = new ArrayList<>(size);
 
         for (int i = 0; i < size; i++) {
diff --git 
a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/sql/ClientSqlCommon.java
 
b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/sql/ClientSqlCommon.java
index 3000226923..42ed3480b2 100644
--- 
a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/sql/ClientSqlCommon.java
+++ 
b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/sql/ClientSqlCommon.java
@@ -35,7 +35,7 @@ class ClientSqlCommon {
 
         List<ColumnMetadata> cols = meta.columns();
 
-        out.packArrayHeader(asyncResultSet.currentPageSize());
+        out.packInt(asyncResultSet.currentPageSize());
 
         for (SqlRow row : asyncResultSet.currentPage()) {
             // TODO IGNITE-18922 Avoid conversion, copy BinaryTuple from SQL 
to client.
diff --git 
a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/sql/ClientSqlExecuteRequest.java
 
b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/sql/ClientSqlExecuteRequest.java
index 9159210ff1..d88519287c 100644
--- 
a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/sql/ClientSqlExecuteRequest.java
+++ 
b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/sql/ClientSqlExecuteRequest.java
@@ -193,12 +193,12 @@ public class ClientSqlExecuteRequest {
     private static void packMeta(ClientMessagePacker out, @Nullable 
ResultSetMetadata meta) {
         // TODO IGNITE-17179 metadata caching - avoid sending same meta over 
and over.
         if (meta == null || meta.columns() == null) {
-            out.packArrayHeader(0);
+            out.packInt(0);
             return;
         }
 
         List<ColumnMetadata> cols = meta.columns();
-        out.packArrayHeader(cols.size());
+        out.packInt(cols.size());
 
         // In many cases there are multiple columns from the same table.
         // Schema is the same for all columns in most cases.
@@ -211,7 +211,7 @@ public class ClientSqlExecuteRequest {
             ColumnOrigin origin = col.origin();
 
             int fieldsNum = origin == null ? 6 : 9;
-            out.packArrayHeader(fieldsNum);
+            out.packInt(fieldsNum);
 
             out.packString(col.name());
             out.packBoolean(col.nullable());
diff --git 
a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/table/ClientSchemasGetRequest.java
 
b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/table/ClientSchemasGetRequest.java
index 7505699ec6..e68d82306a 100644
--- 
a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/table/ClientSchemasGetRequest.java
+++ 
b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/table/ClientSchemasGetRequest.java
@@ -48,7 +48,7 @@ public class ClientSchemasGetRequest {
         return readTableAsync(in, tables).thenAccept(table -> {
             if (in.tryUnpackNil()) {
                 // Return the latest schema.
-                out.packMapHeader(1);
+                out.packInt(1);
 
                 var schema = table.schemaView().schema();
 
@@ -58,8 +58,8 @@ public class ClientSchemasGetRequest {
 
                 writeSchema(out, schema.version(), schema);
             } else {
-                var cnt = in.unpackArrayHeader();
-                out.packMapHeader(cnt);
+                var cnt = in.unpackInt();
+                out.packInt(cnt);
 
                 for (var i = 0; i < cnt; i++) {
                     var schemaVer = in.unpackInt();
diff --git 
a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/table/ClientTableCommon.java
 
b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/table/ClientTableCommon.java
index 98b2ccedf6..6c957bba4f 100644
--- 
a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/table/ClientTableCommon.java
+++ 
b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/table/ClientTableCommon.java
@@ -72,12 +72,12 @@ public class ClientTableCommon {
         }
 
         var colCnt = schema.columnNames().size();
-        packer.packArrayHeader(colCnt);
+        packer.packInt(colCnt);
 
         for (var colIdx = 0; colIdx < colCnt; colIdx++) {
             var col = schema.column(colIdx);
 
-            packer.packArrayHeader(7);
+            packer.packInt(7);
             packer.packString(col.name());
             packer.packInt(getColumnType(col.type().spec()).ordinal());
             packer.packBoolean(schema.isKeyColumn(colIdx));
diff --git 
a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/table/ClientTablePartitionAssignmentGetRequest.java
 
b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/table/ClientTablePartitionAssignmentGetRequest.java
index 1c89a27546..0d2331a941 100644
--- 
a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/table/ClientTablePartitionAssignmentGetRequest.java
+++ 
b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/table/ClientTablePartitionAssignmentGetRequest.java
@@ -46,11 +46,11 @@ public class ClientTablePartitionAssignmentGetRequest {
 
         return tables.assignmentsAsync(tableId).thenAccept(assignment -> {
             if (assignment == null) {
-                out.packArrayHeader(0);
+                out.packInt(0);
                 return;
             }
 
-            out.packArrayHeader(assignment.size());
+            out.packInt(assignment.size());
 
             for (String leaderNodeId : assignment) {
                 out.packString(leaderNodeId);
diff --git 
a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/table/ClientTablesGetRequest.java
 
b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/table/ClientTablesGetRequest.java
index cf478a09ef..89a39d17d6 100644
--- 
a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/table/ClientTablesGetRequest.java
+++ 
b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/table/ClientTablesGetRequest.java
@@ -38,7 +38,7 @@ public class ClientTablesGetRequest {
             IgniteTables igniteTables
     ) {
         return igniteTables.tablesAsync().thenAccept(tables -> {
-            out.packMapHeader(tables.size());
+            out.packInt(tables.size());
 
             for (var table : tables) {
                 var tableImpl = (TableImpl) table;
diff --git 
a/modules/client/src/main/java/org/apache/ignite/internal/client/TcpClientChannel.java
 
b/modules/client/src/main/java/org/apache/ignite/internal/client/TcpClientChannel.java
index abfe5ff432..14716bf942 100644
--- 
a/modules/client/src/main/java/org/apache/ignite/internal/client/TcpClientChannel.java
+++ 
b/modules/client/src/main/java/org/apache/ignite/internal/client/TcpClientChannel.java
@@ -444,7 +444,8 @@ class TcpClientChannel implements ClientChannel, 
ClientMessageHandler, ClientCon
         IgniteException causeWithStackTrace = unpacker.tryUnpackNil() ? null : 
new IgniteException(traceId, code, unpacker.unpackString());
 
         if (code == Table.SCHEMA_VERSION_MISMATCH_ERR) {
-            int extSize = unpacker.tryUnpackNil() ? 0 : 
unpacker.unpackMapHeader();
+            int extSize;
+            extSize = unpacker.tryUnpackNil() ? 0 : unpacker.unpackInt();
             int expectedSchemaVersion = -1;
 
             for (int i = 0; i < extSize; i++) {
@@ -571,7 +572,8 @@ class TcpClientChannel implements ClientChannel, 
ClientMessageHandler, ClientCon
         IgniteClientAuthenticator authenticator = 
cfg.clientConfiguration().authenticator();
 
         if (authenticator != null) {
-            req.packMapHeader(3); // Extensions.
+            // Extensions.
+            req.packInt(3);
 
             req.packString(HandshakeExtension.AUTHENTICATION_TYPE.key());
             req.packString(authenticator.type());
@@ -582,7 +584,8 @@ class TcpClientChannel implements ClientChannel, 
ClientMessageHandler, ClientCon
             req.packString(HandshakeExtension.AUTHENTICATION_SECRET.key());
             packAuthnObj(req, authenticator.secret());
         } else {
-            req.packMapHeader(0); // Extensions.
+            // Extensions.
+            req.packInt(0);
         }
 
         return write(req);
@@ -613,7 +616,7 @@ class TcpClientChannel implements ClientChannel, 
ClientMessageHandler, ClientCon
             var featuresLen = unpacker.unpackBinaryHeader();
             unpacker.skipValues(featuresLen);
 
-            var extensionsLen = unpacker.unpackMapHeader();
+            var extensionsLen = unpacker.unpackInt();
             unpacker.skipValues(extensionsLen);
 
             protocolCtx = new ProtocolContext(
diff --git 
a/modules/client/src/main/java/org/apache/ignite/internal/client/TcpIgniteClient.java
 
b/modules/client/src/main/java/org/apache/ignite/internal/client/TcpIgniteClient.java
index 8c77eba74d..4ba861d2e3 100644
--- 
a/modules/client/src/main/java/org/apache/ignite/internal/client/TcpIgniteClient.java
+++ 
b/modules/client/src/main/java/org/apache/ignite/internal/client/TcpIgniteClient.java
@@ -174,11 +174,11 @@ public class TcpIgniteClient implements IgniteClient {
     @Override
     public CompletableFuture<Collection<ClusterNode>> clusterNodesAsync() {
         return ch.serviceAsync(ClientOp.CLUSTER_GET_NODES, r -> {
-            int cnt = r.in().unpackArrayHeader();
+            int cnt = r.in().unpackInt();
             List<ClusterNode> res = new ArrayList<>(cnt);
 
             for (int i = 0; i < cnt; i++) {
-                int fieldCnt = r.in().unpackArrayHeader();
+                int fieldCnt = r.in().unpackInt();
                 assert fieldCnt == 4;
 
                 res.add(new ClientClusterNode(
diff --git 
a/modules/client/src/main/java/org/apache/ignite/internal/client/compute/ClientCompute.java
 
b/modules/client/src/main/java/org/apache/ignite/internal/client/compute/ClientCompute.java
index d5e120aeab..64bec1c2c0 100644
--- 
a/modules/client/src/main/java/org/apache/ignite/internal/client/compute/ClientCompute.java
+++ 
b/modules/client/src/main/java/org/apache/ignite/internal/client/compute/ClientCompute.java
@@ -328,7 +328,7 @@ public class ClientCompute implements IgniteCompute {
     }
 
     private static void packJob(ClientMessagePacker w, List<DeploymentUnit> 
units, String jobClassName, Object[] args) {
-        w.packArrayHeader(units.size());
+        w.packInt(units.size());
         for (DeploymentUnit unit : units) {
             w.packString(unit.name());
             w.packString(unit.version().render());
diff --git 
a/modules/client/src/main/java/org/apache/ignite/internal/client/sql/ClientAsyncResultSet.java
 
b/modules/client/src/main/java/org/apache/ignite/internal/client/sql/ClientAsyncResultSet.java
index f002cd5847..d38c641c44 100644
--- 
a/modules/client/src/main/java/org/apache/ignite/internal/client/sql/ClientAsyncResultSet.java
+++ 
b/modules/client/src/main/java/org/apache/ignite/internal/client/sql/ClientAsyncResultSet.java
@@ -207,7 +207,7 @@ class ClientAsyncResultSet<T> implements AsyncResultSet<T> {
     }
 
     private void readRows(ClientMessageUnpacker in) {
-        int size = in.unpackArrayHeader();
+        int size = in.unpackInt();
         int rowSize = metadata.columns().size();
 
         var res = new ArrayList<T>(size);
diff --git 
a/modules/client/src/main/java/org/apache/ignite/internal/client/sql/ClientColumnMetadata.java
 
b/modules/client/src/main/java/org/apache/ignite/internal/client/sql/ClientColumnMetadata.java
index ccdd88a097..397187e3ce 100644
--- 
a/modules/client/src/main/java/org/apache/ignite/internal/client/sql/ClientColumnMetadata.java
+++ 
b/modules/client/src/main/java/org/apache/ignite/internal/client/sql/ClientColumnMetadata.java
@@ -52,7 +52,7 @@ public class ClientColumnMetadata implements ColumnMetadata {
      * @param prevColumns Previous columns.
      */
     public ClientColumnMetadata(ClientMessageUnpacker unpacker, 
List<ColumnMetadata> prevColumns) {
-        var propCnt = unpacker.unpackArrayHeader();
+        var propCnt = unpacker.unpackInt();
 
         assert propCnt >= 6;
 
diff --git 
a/modules/client/src/main/java/org/apache/ignite/internal/client/sql/ClientResultSetMetadata.java
 
b/modules/client/src/main/java/org/apache/ignite/internal/client/sql/ClientResultSetMetadata.java
index 3077fec31b..b78352c8ce 100644
--- 
a/modules/client/src/main/java/org/apache/ignite/internal/client/sql/ClientResultSetMetadata.java
+++ 
b/modules/client/src/main/java/org/apache/ignite/internal/client/sql/ClientResultSetMetadata.java
@@ -42,7 +42,7 @@ class ClientResultSetMetadata implements ResultSetMetadata {
      * @param unpacker Unpacker.
      */
     public ClientResultSetMetadata(ClientMessageUnpacker unpacker) {
-        var size = unpacker.unpackArrayHeader();
+        var size = unpacker.unpackInt();
         assert size > 0 : "ResultSetMetadata should not be empty.";
 
         var columns = new ArrayList<ColumnMetadata>(size);
diff --git 
a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientTable.java
 
b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientTable.java
index 8e5cc5166e..94f8a3604a 100644
--- 
a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientTable.java
+++ 
b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientTable.java
@@ -173,11 +173,12 @@ public class ClientTable implements Table {
             if (ver == UNKNOWN_SCHEMA_VERSION) {
                 w.out().packNil();
             } else {
-                w.out().packArrayHeader(1);
+                w.out().packInt(1);
                 w.out().packInt(ver);
             }
         }, r -> {
-            int schemaCnt = r.in().unpackMapHeader();
+            ClientMessageUnpacker clientMessageUnpacker = r.in();
+            int schemaCnt = clientMessageUnpacker.unpackInt();
 
             if (schemaCnt == 0) {
                 log.warn("Schema not found [tableId=" + id + ", 
schemaVersion=" + ver + "]");
@@ -201,12 +202,12 @@ public class ClientTable implements Table {
 
     private ClientSchema readSchema(ClientMessageUnpacker in) {
         var schemaVer = in.unpackInt();
-        var colCnt = in.unpackArrayHeader();
+        var colCnt = in.unpackInt();
         var columns = new ClientColumn[colCnt];
         int colocationColumnCnt = 0;
 
         for (int i = 0; i < colCnt; i++) {
-            var propCnt = in.unpackArrayHeader();
+            var propCnt = in.unpackInt();
 
             assert propCnt >= 7;
 
@@ -533,7 +534,7 @@ public class ClientTable implements Table {
             partitionAssignment = 
ch.serviceAsync(ClientOp.PARTITION_ASSIGNMENT_GET,
                     w -> w.out().packInt(id),
                     r -> {
-                        int cnt = r.in().unpackArrayHeader();
+                        int cnt = r.in().unpackInt();
                         List<String> res = new ArrayList<>(cnt);
 
                         for (int i = 0; i < cnt; i++) {
diff --git 
a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientTables.java
 
b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientTables.java
index 314fc6363b..41eb027d8d 100644
--- 
a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientTables.java
+++ 
b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientTables.java
@@ -54,7 +54,7 @@ public class ClientTables implements IgniteTables {
     public CompletableFuture<List<Table>> tablesAsync() {
         return ch.serviceAsync(ClientOp.TABLES_GET, r -> {
             var in = r.in();
-            var cnt = in.unpackMapHeader();
+            var cnt = in.unpackInt();
             var res = new ArrayList<Table>(cnt);
 
             for (int i = 0; i < cnt; i++) {
diff --git a/modules/platforms/cpp/DEVNOTES.md 
b/modules/platforms/cpp/DEVNOTES.md
index 3530655fe6..a81bef9d4f 100644
--- a/modules/platforms/cpp/DEVNOTES.md
+++ b/modules/platforms/cpp/DEVNOTES.md
@@ -55,7 +55,7 @@ In this dir:
 ```shell
 mkdir cmake-build-debug
 cd cmake-build-debug
-cmake .. -DENABLE_TESTS=ON -DCMAKE_BUILD_TYPE=Debug
+cmake .. -DENABLE_TESTS=ON -DENABLE_ODBC=OFF -DCMAKE_BUILD_TYPE=Debug
 cmake --build . -j8
 ```
 
@@ -66,7 +66,7 @@ In this dir:
 ```shell
 mkdir cmake-build-release
 cd cmake-build-release
-cmake .. -DENABLE_TESTS=OFF -DCMAKE_BUILD_TYPE=Release
+cmake .. -DENABLE_TESTS=OFF -DENABLE_ODBC=OFF -DCMAKE_BUILD_TYPE=Release
 cmake --build . -j8
 ```
 
@@ -85,7 +85,7 @@ In this dir:
 ```shell
 mkdir cmake-build-debug
 cd cmake-build-debug
-cmake .. -DENABLE_TESTS=ON -DCMAKE_BUILD_TYPE=Debug
+cmake .. -DENABLE_TESTS=ON -DENABLE_ODBC=OFF -DCMAKE_BUILD_TYPE=Debug
 cmake --build . -j8
 ```
 
@@ -96,7 +96,7 @@ In this dir:
 ```shell
 mkdir cmake-build-release
 cd cmake-build-release
-cmake .. -DENABLE_TESTS=OFF -DCMAKE_BUILD_TYPE=Release
+cmake .. -DENABLE_TESTS=OFF -DENABLE_ODBC=OFF -DCMAKE_BUILD_TYPE=Release
 cmake --build . -j8
 ```
 
@@ -109,7 +109,7 @@ In this dir (using the ninja build system, other 
single-config systems can be us
 ```shell
 mkdir cmake-build-debug
 cd cmake-build-debug
-cmake .. -DENABLE_TESTS=ON -DCMAKE_BUILD_TYPE=Debug -GNinja
+cmake .. -DENABLE_TESTS=ON -DENABLE_ODBC=OFF -DCMAKE_BUILD_TYPE=Debug -GNinja
 cmake --build . -j8
 ```
 
@@ -120,7 +120,7 @@ In this dir (using the ninja build system, other 
single-config systems can be us
 ```shell
 mkdir cmake-build-release
 cd cmake-build-release
-cmake .. -DENABLE_TESTS=OFF -DCMAKE_BUILD_TYPE=Release -GNinja
+cmake .. -DENABLE_TESTS=OFF -DENABLE_ODBC=OFF -DCMAKE_BUILD_TYPE=Release 
-GNinja
 cmake --build . -j8
 ```
 
diff --git 
a/modules/platforms/cpp/ignite/client/detail/compute/compute_impl.cpp 
b/modules/platforms/cpp/ignite/client/detail/compute/compute_impl.cpp
index fcff1c9584..6eb2aeeff6 100644
--- a/modules/platforms/cpp/ignite/client/detail/compute/compute_impl.cpp
+++ b/modules/platforms/cpp/ignite/client/detail/compute/compute_impl.cpp
@@ -73,7 +73,7 @@ std::optional<primitive> 
read_primitive_from_binary_tuple(protocol::reader &read
  * @param units Units to write.
  */
 void write_units(protocol::writer &writer, const std::vector<deployment_unit> 
&units) {
-    writer.write_array_header(units.size());
+    writer.write(static_cast<int32_t>(units.size()));
     for (const auto &unit : units) {
         detail::arg_check::container_non_empty(unit.get_name(), "Deployment 
unit name");
         detail::arg_check::container_non_empty(unit.get_version(), "Deployment 
unit version");
diff --git a/modules/platforms/cpp/ignite/client/detail/ignite_client_impl.cpp 
b/modules/platforms/cpp/ignite/client/detail/ignite_client_impl.cpp
index 9d27d9a00b..6fefef48f6 100644
--- a/modules/platforms/cpp/ignite/client/detail/ignite_client_impl.cpp
+++ b/modules/platforms/cpp/ignite/client/detail/ignite_client_impl.cpp
@@ -24,19 +24,20 @@ namespace ignite::detail {
 void 
ignite_client_impl::get_cluster_nodes_async(ignite_callback<std::vector<cluster_node>>
 callback) {
     auto reader_func = [](protocol::reader &reader) -> 
std::vector<cluster_node> {
         std::vector<cluster_node> nodes;
-        nodes.reserve(reader.read_array_size());
+        auto size = reader.read_int32();
+        nodes.reserve(std::size_t(size));
 
-        reader.read_array_raw([&nodes](auto, const msgpack_object &object) {
-            auto fields = object.via.array;
-            assert(fields.size >= 4);
+        for (std::int32_t node_idx = 0; node_idx < size; ++node_idx) {
+            auto fields_count = reader.read_int32();
+            assert(fields_count >= 4);
 
-            auto id = protocol::unpack_object<std::string>(fields.ptr[0]);
-            auto name = protocol::unpack_object<std::string>(fields.ptr[1]);
-            auto host = protocol::unpack_object<std::string>(fields.ptr[2]);
-            auto port = protocol::unpack_object<std::int32_t>(fields.ptr[3]);
+            auto id = reader.read_string();
+            auto name = reader.read_string();
+            auto host = reader.read_string();
+            auto port = reader.read_uint16();
 
-            nodes.emplace_back(std::move(id), std::move(name), 
end_point{std::move(host), std::uint16_t(port)});
-        });
+            nodes.emplace_back(std::move(id), std::move(name), 
end_point{std::move(host), port});
+        }
 
         return nodes;
     };
diff --git a/modules/platforms/cpp/ignite/client/detail/sql/result_set_impl.h 
b/modules/platforms/cpp/ignite/client/detail/sql/result_set_impl.h
index 7fc0c8655f..2da6da6350 100644
--- a/modules/platforms/cpp/ignite/client/detail/sql/result_set_impl.h
+++ b/modules/platforms/cpp/ignite/client/detail/sql/result_set_impl.h
@@ -202,64 +202,60 @@ private:
      * @return Result set meta columns.
      */
     static std::vector<column_metadata> read_meta(protocol::reader &reader) {
-        auto size = reader.read_array_size();
+        auto size = reader.read_int32();
 
         std::vector<column_metadata> columns;
         columns.reserve(size);
 
-        reader.read_array_raw([&columns](std::uint32_t idx, const 
msgpack_object &obj) {
-            if (obj.type != MSGPACK_OBJECT_ARRAY)
-                throw ignite_error("Meta column expected to be serialized as 
array");
+        for (std::int32_t i = 0; i < size; ++i) {
+            auto fields_num = reader.read_int32();
+            assert(fields_num >= 6); // There should be at least six fields.
 
-            const msgpack_object_array &arr = obj.via.array;
+            auto name = reader.read_string();
+            auto nullable = reader.read_bool();
+            auto typ = ignite_type(reader.read_int32());
+            auto scale = reader.read_int32();
+            auto precision = reader.read_int32();
 
-            constexpr std::uint32_t min_count = 6;
-            assert(arr.size >= min_count);
-
-            auto name = protocol::unpack_object<std::string>(arr.ptr[0]);
-            auto nullable = protocol::unpack_object<bool>(arr.ptr[1]);
-            auto typ = 
ignite_type(protocol::unpack_object<std::int32_t>(arr.ptr[2]));
-            auto scale = protocol::unpack_object<std::int32_t>(arr.ptr[3]);
-            auto precision = protocol::unpack_object<std::int32_t>(arr.ptr[4]);
-
-            bool origin_present = protocol::unpack_object<bool>(arr.ptr[5]);
+            bool origin_present = reader.read_bool();
 
             if (!origin_present) {
                 columns.emplace_back(std::move(name), typ, precision, scale, 
nullable, column_origin{});
-                return;
+                continue;
             }
 
-            assert(arr.size >= min_count + 3);
-            auto origin_name =
-                arr.ptr[6].type == MSGPACK_OBJECT_NIL ? name : 
protocol::unpack_object<std::string>(arr.ptr[6]);
+            assert(fields_num >= 9); // There should be at least three more 
fields.
+            auto origin_name = reader.read_string_nullable();
+            if (!origin_name)
+                origin_name = name;
 
-            auto origin_schema_id = 
protocol::try_unpack_object<std::int32_t>(arr.ptr[7]);
+            auto origin_schema_id = reader.try_read_int32();
             std::string origin_schema;
             if (origin_schema_id) {
                 if (*origin_schema_id >= std::int32_t(columns.size())) {
                     throw ignite_error("Origin schema ID is too large: " + 
std::to_string(*origin_schema_id)
-                        + ", id=" + std::to_string(idx));
+                        + ", id=" + std::to_string(i));
                 }
                 origin_schema = 
columns[*origin_schema_id].origin().schema_name();
             } else {
-                origin_schema = 
protocol::unpack_object<std::string>(arr.ptr[7]);
+                origin_schema = reader.read_string();
             }
 
-            auto origin_table_id = 
protocol::try_unpack_object<std::int32_t>(arr.ptr[8]);
+            auto origin_table_id = reader.try_read_int32();
             std::string origin_table;
             if (origin_table_id) {
                 if (*origin_table_id >= std::int32_t(columns.size())) {
                     throw ignite_error("Origin table ID is too large: " + 
std::to_string(*origin_table_id)
-                        + ", id=" + std::to_string(idx));
+                        + ", id=" + std::to_string(i));
                 }
                 origin_table = columns[*origin_table_id].origin().table_name();
             } else {
-                origin_table = 
protocol::unpack_object<std::string>(arr.ptr[8]);
+                origin_table = reader.read_string();
             }
 
-            column_origin origin{std::move(origin_name), 
std::move(origin_table), std::move(origin_schema)};
+            column_origin origin{std::move(*origin_name), 
std::move(origin_table), std::move(origin_schema)};
             columns.emplace_back(std::move(name), typ, precision, scale, 
nullable, std::move(origin));
-        });
+        }
 
         return columns;
     }
@@ -271,24 +267,23 @@ private:
      * @return Page.
      */
     static std::vector<ignite_tuple> read_page(protocol::reader &reader, const 
result_set_metadata &meta) {
-        auto size = reader.read_array_size();
+        auto size = reader.read_int32();
 
         std::vector<ignite_tuple> page;
         page.reserve(size);
 
-        reader.read_array_raw([&columns = meta.columns(), 
&page](std::uint32_t, const msgpack_object &obj) {
-            auto tuple_data = protocol::unpack_binary(obj);
+        for (std::int32_t tuple_idx = 0; tuple_idx < size; ++tuple_idx) {
+            auto tuple_data = reader.read_binary();
 
-            auto columns_cnt = columns.size();
+            auto columns_cnt = meta.columns().size();
             ignite_tuple res(columns_cnt);
             binary_tuple_parser parser(std::int32_t(columns_cnt), tuple_data);
 
-            for (size_t i = 0; i < columns_cnt; ++i) {
-                auto &column = columns[i];
+            for (const auto &column : meta.columns()) {
                 res.set(column.name(), protocol::read_next_column(parser, 
column.type(), column.scale()));
             }
             page.emplace_back(std::move(res));
-        });
+        }
 
         return page;
     }
diff --git a/modules/platforms/cpp/ignite/client/detail/table/schema.h 
b/modules/platforms/cpp/ignite/client/detail/table/schema.h
index 696138a777..b277e991ee 100644
--- a/modules/platforms/cpp/ignite/client/detail/table/schema.h
+++ b/modules/platforms/cpp/ignite/client/detail/table/schema.h
@@ -19,7 +19,7 @@
 
 #include "ignite/common/ignite_error.h"
 #include "ignite/common/ignite_type.h"
-#include "ignite/protocol/utils.h"
+#include "ignite/protocol/reader.h"
 
 #include <msgpack.h>
 
@@ -46,21 +46,19 @@ struct column {
      * @param object MsgPack object.
      * @return Column value.
      */
-    [[nodiscard]] static column unpack(const msgpack_object &object) {
-        if (object.type != MSGPACK_OBJECT_ARRAY)
-            throw ignite_error("Schema column expected to be serialized as 
array");
-
-        const msgpack_object_array &arr = object.via.array;
-
-        constexpr std::uint32_t expectedCount = 6;
-        assert(arr.size >= expectedCount);
+    [[nodiscard]] static column read(protocol::reader &reader) {
+        auto fields_num = reader.read_int32();
+        assert(fields_num >= 7); // Expect at least six columns.
 
         column res{};
-        res.name = protocol::unpack_object<std::string>(arr.ptr[0]);
-        res.type = 
static_cast<ignite_type>(protocol::unpack_object<std::int32_t>(arr.ptr[1]));
-        res.is_key = protocol::unpack_object<bool>(arr.ptr[2]);
-        res.nullable = protocol::unpack_object<bool>(arr.ptr[3]);
-        res.scale = protocol::unpack_object<std::int32_t>(arr.ptr[5]);
+        res.name = reader.read_string();
+        res.type = static_cast<ignite_type>(reader.read_int32());
+        res.is_key = reader.read_bool();
+        res.nullable = reader.read_bool();
+        reader.skip(); // Colocation index.
+        res.scale = reader.read_int32();
+        reader.skip(); // Precision
+        reader.skip(fields_num - 7);
 
         return res;
     }
@@ -95,19 +93,21 @@ struct schema {
      * @param reader Reader to use.
      * @return Schema instance.
      */
-    static std::shared_ptr<schema> read(const msgpack_object_kv &object) {
-        auto schema_version = 
protocol::unpack_object<std::int32_t>(object.key);
+    static std::shared_ptr<schema> read(protocol::reader& reader) {
         std::int32_t key_column_count = 0;
+        auto schema_version = reader.read_int32();
 
+        auto columns_count = reader.read_int32();
         std::vector<column> columns;
-        columns.reserve(protocol::unpack_array_size(object.val));
+        columns.reserve(columns_count);
 
-        protocol::unpack_array_raw(object.val, [&columns, 
&key_column_count](const msgpack_object &object) {
-            auto val = column::unpack(object);
+        for (std::int32_t column_idx = 0; column_idx < columns_count; 
++column_idx) {
+            auto val = column::read(reader);
             if (val.is_key)
                 ++key_column_count;
+
             columns.emplace_back(std::move(val));
-        });
+        }
 
         return std::make_shared<schema>(schema_version, key_column_count, 
std::move(columns));
     }
diff --git a/modules/platforms/cpp/ignite/client/detail/table/table_impl.cpp 
b/modules/platforms/cpp/ignite/client/detail/table/table_impl.cpp
index e801be14d9..ca6c199b20 100644
--- a/modules/platforms/cpp/ignite/client/detail/table/table_impl.cpp
+++ b/modules/platforms/cpp/ignite/client/detail/table/table_impl.cpp
@@ -163,15 +163,15 @@ void 
table_impl::load_schema_async(ignite_callback<std::shared_ptr<schema>> call
 
     auto table = shared_from_this();
     auto reader_func = [table](protocol::reader &reader) mutable -> 
std::shared_ptr<schema> {
-        auto schema_cnt = reader.read_map_size();
+        auto schema_cnt = reader.read_int32();
         if (!schema_cnt)
             throw ignite_error("Schema not found");
 
         std::shared_ptr<schema> last;
-        reader.read_map_raw([&last, &table](const msgpack_object_kv &object) {
-            last = schema::read(object);
+        for (std::int32_t schema_idx = 0; schema_idx < schema_cnt; 
++schema_idx) {
+            last = schema::read(reader);
             table->add_schema(last);
-        });
+        }
 
         return last;
     };
diff --git a/modules/platforms/cpp/ignite/client/detail/table/tables_impl.cpp 
b/modules/platforms/cpp/ignite/client/detail/table/tables_impl.cpp
index dea54100ed..0eacd8d571 100644
--- a/modules/platforms/cpp/ignite/client/detail/table/tables_impl.cpp
+++ b/modules/platforms/cpp/ignite/client/detail/table/tables_impl.cpp
@@ -45,14 +45,14 @@ void 
tables_impl::get_tables_async(ignite_callback<std::vector<table>> callback)
             return {};
 
         std::vector<table> tables;
-        tables.reserve(reader.read_map_size());
-
-        reader.read_map<std::int32_t, std::string>([conn, &tables](auto &&id, 
auto &&name) {
-            auto table0 =
-                std::make_shared<table_impl>(std::forward<std::string>(name), 
std::forward<std::int32_t>(id), conn);
-            tables.push_back(table{table0});
-        });
-
+        auto size = reader.read_int32();
+        tables.reserve(size);
+
+        for (std::int32_t table_idx = 0; table_idx < size; ++table_idx) {
+            auto id = reader.read_int32();
+            auto name = reader.read_string();
+            
tables.emplace_back(table{std::make_shared<table_impl>(std::move(name), id, 
conn)});
+        }
         return tables;
     };
 
diff --git a/modules/platforms/cpp/ignite/odbc/query/data_query.cpp 
b/modules/platforms/cpp/ignite/odbc/query/data_query.cpp
index 210b86aeb1..28cd3a5a45 100644
--- a/modules/platforms/cpp/ignite/odbc/query/data_query.cpp
+++ b/modules/platforms/cpp/ignite/odbc/query/data_query.cpp
@@ -34,66 +34,58 @@ using namespace ignite;
  * @return Result set meta columns.
  */
 column_meta_vector read_meta(protocol::reader &reader) {
-    auto size = reader.read_array_size();
+    auto size = reader.read_int32();
 
     column_meta_vector columns;
     columns.reserve(size);
 
-    reader.read_array_raw([&columns](std::uint32_t idx, const msgpack_object 
&obj) {
-        if (obj.type != MSGPACK_OBJECT_ARRAY)
-            throw ignite_error("Meta column expected to be serialized as 
array");
+    for (std::int32_t column_idx = 0; column_idx < size; ++column_idx) {
+        auto fields_cnt = reader.read_int32();
 
-        const msgpack_object_array &arr = obj.via.array;
+        assert(fields_cnt >= 6); // Expect at least six fields.
 
-        constexpr std::uint32_t min_count = 6;
-        UNUSED_VALUE min_count; // For release builds
+        auto name = reader.read_string();
+        auto nullable = reader.read_bool();
+        auto typ = ignite_type(reader.read_int32());
+        auto scale = reader.read_int32();
+        auto precision = reader.read_int32();
 
-        assert(arr.size >= min_count);
-
-        auto name = protocol::unpack_object<std::string>(arr.ptr[0]);
-        auto nullable = protocol::unpack_object<bool>(arr.ptr[1]);
-        auto typ = 
ignite_type(protocol::unpack_object<std::int32_t>(arr.ptr[2]));
-        auto scale = protocol::unpack_object<std::int32_t>(arr.ptr[3]);
-        auto precision = protocol::unpack_object<std::int32_t>(arr.ptr[4]);
-
-        bool origin_present = protocol::unpack_object<bool>(arr.ptr[5]);
+        bool origin_present = reader.read_bool();
 
         if (!origin_present) {
             columns.emplace_back("", "", std::move(name), typ, precision, 
scale, nullable);
-            return;
+            break;
         }
 
-        assert(arr.size >= min_count + 3);
-        auto origin_name =
-            arr.ptr[6].type == MSGPACK_OBJECT_NIL ? name : 
protocol::unpack_object<std::string>(arr.ptr[6]);
-
-        auto origin_schema_id = 
protocol::try_unpack_object<std::int32_t>(arr.ptr[7]);
+        assert(fields_cnt >= 9); // Expect at least three more fields.
+        auto origin_name = reader.read_string_nullable();
+        auto origin_schema_id = reader.try_read_int32();
         std::string origin_schema;
         if (origin_schema_id) {
             if (*origin_schema_id >= std::int32_t(columns.size())) {
                 throw ignite_error("Origin schema ID is too large: " + 
std::to_string(*origin_schema_id)
-                    + ", id=" + std::to_string(idx));
+                    + ", id=" + std::to_string(column_idx));
             }
             origin_schema = columns[*origin_schema_id].get_schema_name();
         } else {
-            origin_schema = protocol::unpack_object<std::string>(arr.ptr[7]);
+            origin_schema = reader.read_string();
         }
 
-        auto origin_table_id = 
protocol::try_unpack_object<std::int32_t>(arr.ptr[8]);
+        auto origin_table_id = reader.try_read_int32();
         std::string origin_table;
         if (origin_table_id) {
             if (*origin_table_id >= std::int32_t(columns.size())) {
                 throw ignite_error("Origin table ID is too large: " + 
std::to_string(*origin_table_id)
-                    + ", id=" + std::to_string(idx));
+                    + ", id=" + std::to_string(column_idx));
             }
             origin_table = columns[*origin_table_id].get_table_name();
         } else {
-            origin_table = protocol::unpack_object<std::string>(arr.ptr[8]);
+            origin_table = reader.read_string();
         }
 
         columns.emplace_back(
             std::move(origin_schema), std::move(origin_table), 
std::move(name), typ, precision, scale, nullable);
-    });
+    }
 
     return columns;
 }
diff --git a/modules/platforms/cpp/ignite/odbc/query/result_page.h 
b/modules/platforms/cpp/ignite/odbc/query/result_page.h
index 6a8eb32aaf..e3b9bc3f3c 100644
--- a/modules/platforms/cpp/ignite/odbc/query/result_page.h
+++ b/modules/platforms/cpp/ignite/odbc/query/result_page.h
@@ -48,7 +48,7 @@ public:
     result_page(network::data_buffer_owning &&data, 
std::unique_ptr<protocol::reader> &&reader)
         : m_data(std::move(data))
         , m_reader(std::move(reader)) {
-        m_size = m_reader->read_array_size();
+        m_size = m_reader->read_int32();
     }
 
     /**
@@ -72,8 +72,7 @@ public:
     bytes_view get_row(std::uint32_t idx) {
         assert(idx < m_size);
 
-        auto elem = m_reader->get_array_element(idx);
-        return protocol::unpack_binary(elem);
+        return m_reader->read_binary();
     }
 
 private:
diff --git a/modules/platforms/cpp/ignite/odbc/query/table_metadata_query.cpp 
b/modules/platforms/cpp/ignite/odbc/query/table_metadata_query.cpp
index 96d6b8f7aa..b90b3f26a1 100644
--- a/modules/platforms/cpp/ignite/odbc/query/table_metadata_query.cpp
+++ b/modules/platforms/cpp/ignite/odbc/query/table_metadata_query.cpp
@@ -185,7 +185,7 @@ sql_result 
table_metadata_query::make_request_get_tables_meta() {
                 writer.write(m_schema);
                 writer.write(m_table);
 
-                writer.write_array_header(table_types.size());
+                writer.write(static_cast<int32_t>(table_types.size()));
                 for (auto table_type : table_types) {
                     writer.write(table_type);
                 }
diff --git a/modules/platforms/cpp/ignite/protocol/reader.h 
b/modules/platforms/cpp/ignite/protocol/reader.h
index 89cbb45bab..d5c5f80c25 100644
--- a/modules/platforms/cpp/ignite/protocol/reader.h
+++ b/modules/platforms/cpp/ignite/protocol/reader.h
@@ -133,6 +133,13 @@ public:
      */
     [[nodiscard]] std::int16_t read_int16() { return 
read_object<std::int16_t>(); }
 
+    /**
+     * Read uint16.
+     *
+     * @return Value.
+     */
+    [[nodiscard]] std::uint16_t read_uint16() { return 
read_object<std::uint16_t>(); }
+
     /**
      * Read int32.
      *
@@ -147,6 +154,13 @@ public:
      */
     [[nodiscard]] std::optional<std::int32_t> try_read_int32() { return 
try_read_object<std::int32_t>(); }
 
+    /**
+     * Read int32 or nullopt.
+     *
+     * @return Value or nullopt if the next value in stream is nil.
+     */
+    [[nodiscard]] std::optional<std::int32_t> read_int32_nullable() { return 
read_object_nullable<std::int32_t>(); }
+
     /**
      * Read int64 number.
      *
@@ -182,115 +196,6 @@ public:
      */
     [[nodiscard]] uuid read_uuid() { return read_object<uuid>(); }
 
-    /**
-     * Read Map size.
-     *
-     * @return Map size.
-     */
-    [[nodiscard]] uint32_t read_map_size() const {
-        check_data_in_stream();
-
-        if (m_current_val.data.type != MSGPACK_OBJECT_MAP)
-            throw ignite_error("The value in stream is not a Map");
-
-        return m_current_val.data.via.map.size;
-    }
-
-    /**
-     * Read Map raw.
-     *
-     * @param handler Pair handler.
-     */
-    void read_map_raw(const std::function<void(const msgpack_object_kv &)> 
&handler) {
-        auto size = read_map_size();
-        for (std::uint32_t i = 0; i < size; ++i) {
-            handler(m_current_val.data.via.map.ptr[i]);
-        }
-        next();
-    }
-
-    /**
-     * Read Map.
-     *
-     * @tparam K key type.
-     * @tparam V Value type.
-     * @param handler Pair handler.
-     */
-    template<typename K, typename V>
-    void read_map(const std::function<void(K &&, V &&)> &handler) {
-        auto size = read_map_size();
-        for (std::uint32_t i = 0; i < size; ++i) {
-            auto key = unpack_object<K>(m_current_val.data.via.map.ptr[i].key);
-            auto val = unpack_object<V>(m_current_val.data.via.map.ptr[i].val);
-            handler(std::move(key), std::move(val));
-        }
-        next();
-    }
-
-    /**
-     * Read array size.
-     *
-     * @return Array size.
-     */
-    [[nodiscard]] uint32_t read_array_size() const {
-        check_data_in_stream();
-
-        return unpack_array_size(m_current_val.data);
-    }
-
-    /**
-     * Read array.
-     *
-     * @param read_func Object read function.
-     */
-    void read_array_raw(const std::function<void(std::uint32_t idx, const 
msgpack_object &)> &read_func) {
-        auto size = read_array_size();
-        for (std::uint32_t i = 0; i < size; ++i) {
-            read_func(i, m_current_val.data.via.array.ptr[i]);
-        }
-        next();
-    }
-
-    /**
-     * Get array element.
-     *
-     * @param idx Index.
-     * @return Element reference.
-     */
-    [[nodiscard]] const msgpack_object &get_array_element(std::uint32_t idx) 
const {
-        return m_current_val.data.via.array.ptr[idx];
-    }
-
-    /**
-     * Read array.
-     *
-     * @tparam T Value type.
-     * @param unpack_func Object unpack function.
-     */
-    template<typename T>
-    [[nodiscard]] std::vector<T> read_array(const std::function<T(const 
msgpack_object &)> &unpack_func) {
-        auto size = read_array_size();
-        std::vector<T> res;
-        res.reserve(size);
-        for (std::uint32_t i = 0; i < size; ++i) {
-            auto val = unpack_func(m_current_val.data.via.array.ptr[i]);
-            res.emplace_back(std::move(val));
-        }
-        next();
-        return std::move(res);
-    }
-
-    /**
-     * Read array.
-     *
-     * @tparam T Value type.
-     * @param handler Value handler.
-     */
-    template<typename T>
-    [[nodiscard]] std::vector<T> read_array() {
-        return read_array<T>(unpack_object<T>);
-    }
-
     /**
      * Read array.
      *
@@ -314,6 +219,15 @@ public:
      */
     void skip() { next(); }
 
+    /**
+     * Skip next value.
+     */
+    void skip(int count) {
+        for (int i = 0; i < count; i++) {
+            skip();
+        }
+    }
+
     /**
      * Position.
      *
diff --git a/modules/platforms/cpp/ignite/protocol/utils.cpp 
b/modules/platforms/cpp/ignite/protocol/utils.cpp
index 184cd45d86..c937c9f59d 100644
--- a/modules/platforms/cpp/ignite/protocol/utils.cpp
+++ b/modules/platforms/cpp/ignite/protocol/utils.cpp
@@ -88,6 +88,17 @@ T unpack_int(const msgpack_object &object) {
     return T(i64_val);
 }
 
+template<typename T>
+T unpack_uint(const msgpack_object &object) {
+    static_assert(
+        std::numeric_limits<T>::is_integer && 
!std::numeric_limits<T>::is_signed, "Type T is not a unsigned integer type");
+
+    auto u64_val = unpack_object<std::uint64_t>(object);
+
+    check_int_fits<T>(u64_val);
+    return T(u64_val);
+}
+
 template<>
 std::optional<std::string> unpack_nullable(const msgpack_object &object) {
     if (object.type == MSGPACK_OBJECT_NIL)
@@ -104,6 +115,14 @@ std::int64_t unpack_object(const msgpack_object &object) {
     return object.via.i64;
 }
 
+template<>
+std::uint64_t unpack_object(const msgpack_object &object) {
+    if (object.type != MSGPACK_OBJECT_POSITIVE_INTEGER)
+        throw ignite_error("The value in stream is not a positive integer 
number : " + std::to_string(object.type));
+
+    return object.via.u64;
+}
+
 template<>
 std::int32_t unpack_object(const msgpack_object &object) {
     return unpack_int<std::int32_t>(object);
@@ -114,6 +133,11 @@ std::int16_t unpack_object(const msgpack_object &object) {
     return unpack_int<std::int16_t>(object);
 }
 
+template<>
+std::uint16_t unpack_object(const msgpack_object &object) {
+    return unpack_uint<std::uint16_t>(object);
+}
+
 template<>
 std::int8_t unpack_object(const msgpack_object &object) {
     return unpack_int<std::int8_t>(object);
@@ -151,18 +175,6 @@ bool unpack_object(const msgpack_object &object) {
     return object.via.boolean;
 }
 
-std::uint32_t unpack_array_size(const msgpack_object &object) {
-    if (object.type != MSGPACK_OBJECT_ARRAY)
-        throw ignite_error("The value in stream is not an Array : " + 
std::to_string(object.type));
-    return object.via.array.size;
-}
-
-void unpack_array_raw(const msgpack_object &object, const 
std::function<void(const msgpack_object &)> &read_func) {
-    auto size = unpack_array_size(object);
-    for (std::uint32_t i = 0; i < size; ++i)
-        read_func(object.via.array.ptr[i]);
-}
-
 bytes_view unpack_binary(const msgpack_object &object) {
     if (object.type != MSGPACK_OBJECT_BIN)
         throw ignite_error("The value in stream is not a Binary data : " + 
std::to_string(object.type));
diff --git a/modules/platforms/cpp/ignite/protocol/utils.h 
b/modules/platforms/cpp/ignite/protocol/utils.h
index 3b6c972689..79da16c15a 100644
--- a/modules/platforms/cpp/ignite/protocol/utils.h
+++ b/modules/platforms/cpp/ignite/protocol/utils.h
@@ -105,6 +105,16 @@ template<typename T>
 template<>
 [[nodiscard]] std::int64_t unpack_object(const msgpack_object &object);
 
+/**
+ * Unpack number.
+ *
+ * @param object MsgPack object.
+ * @return Number.
+ * @throw ignite_error if the object is not a number.
+ */
+template<>
+[[nodiscard]] std::uint64_t unpack_object(const msgpack_object &object);
+
 /**
  * Unpack number.
  *
@@ -125,6 +135,16 @@ template<>
 template<>
 [[nodiscard]] std::int16_t unpack_object(const msgpack_object &object);
 
+/**
+ * Unpack number.
+ *
+ * @param object MsgPack object.
+ * @return Number.
+ * @throw ignite_error if the object is not a number.
+ */
+template<>
+[[nodiscard]] std::uint16_t unpack_object(const msgpack_object &object);
+
 /**
  * Unpack number.
  *
@@ -165,21 +185,6 @@ template<>
 template<>
 [[nodiscard]] bool unpack_object(const msgpack_object &object);
 
-/**
- * Get array size.
- *
- * @param object Object.
- * @return Array size.
- */
-[[nodiscard]] std::uint32_t unpack_array_size(const msgpack_object &object);
-
-/**
- * Unpack array.
- *
- * @param object Object.
- */
-void unpack_array_raw(const msgpack_object &object, const 
std::function<void(const msgpack_object &)> &read_func);
-
 /**
  * Get binary data.
  *
diff --git a/modules/platforms/cpp/ignite/protocol/writer.h 
b/modules/platforms/cpp/ignite/protocol/writer.h
index 0ab4dd3d7a..39ff79e862 100644
--- a/modules/platforms/cpp/ignite/protocol/writer.h
+++ b/modules/platforms/cpp/ignite/protocol/writer.h
@@ -135,20 +135,13 @@ public:
      * @param values Map.
      */
     void write_map(const std::map<std::string, std::string> &values) {
-        msgpack_pack_map(m_packer.get(), values.size());
+        write(std::int32_t(values.size()));
         for (const auto &pair : values) {
-            msgpack_pack_str_with_body(m_packer.get(), pair.first.data(), 
pair.first.size());
-            msgpack_pack_str_with_body(m_packer.get(), pair.second.data(), 
pair.second.size());
+            write(pair.first);
+            write(pair.second);
         }
     }
 
-    /**
-     * Write array header.
-     *
-     * @param size Size of the array.
-     */
-    void write_array_header(std::size_t size) { 
msgpack_pack_array(m_packer.get(), size); }
-
     /**
      * Write bitset.
      *
diff --git a/modules/platforms/cpp/tests/client-test/compute_test.cpp 
b/modules/platforms/cpp/tests/client-test/compute_test.cpp
index b5c31a5021..5a1e6f6bd5 100644
--- a/modules/platforms/cpp/tests/client-test/compute_test.cpp
+++ b/modules/platforms/cpp/tests/client-test/compute_test.cpp
@@ -245,10 +245,10 @@ TEST_F(compute_test, execute_colocated) {
         SCOPED_TRACE("key=" + std::to_string(var.first) + ", node=" + 
var.second);
         auto key = get_tuple(var.first);
 
-        auto resNodeName = m_client.get_compute().execute_colocated(TABLE_1, 
key, {}, NODE_NAME_JOB, {});
-        auto expectedNodeName = PLATFORM_TEST_NODE_RUNNER + var.second;
+        auto res_node_name = m_client.get_compute().execute_colocated(TABLE_1, 
key, {}, NODE_NAME_JOB, {});
+        auto expected_node_name = PLATFORM_TEST_NODE_RUNNER + var.second;
 
-        EXPECT_EQ(expectedNodeName, resNodeName.value().get<std::string>());
+        EXPECT_EQ(expected_node_name, 
res_node_name.value().get<std::string>());
     }
 }
 
diff --git 
a/modules/platforms/cpp/tests/client-test/record_binary_view_test.cpp 
b/modules/platforms/cpp/tests/client-test/record_binary_view_test.cpp
index d9e29325dc..2c5823dcf5 100644
--- a/modules/platforms/cpp/tests/client-test/record_binary_view_test.cpp
+++ b/modules/platforms/cpp/tests/client-test/record_binary_view_test.cpp
@@ -986,6 +986,7 @@ TEST_F(record_binary_view_test, types_test) {
         } else if (column == "timestamp2") {
             EXPECT_EQ(res->get(column), primitive{ignite_timestamp(3875238472, 
248700000)});
         } else {
+            std::cout << "Column " + column << std::endl;
             EXPECT_EQ(res->get(column), inserted.get(column));
         }
     }
diff --git a/modules/platforms/dotnet/Apache.Ignite.Tests/FakeServer.cs 
b/modules/platforms/dotnet/Apache.Ignite.Tests/FakeServer.cs
index 0b11904c35..dce68fab3b 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Tests/FakeServer.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Tests/FakeServer.cs
@@ -164,7 +164,7 @@ namespace Apache.Ignite.Tests
             handshakeWriter.Write(Node.Name); // Node name (consistent id).
             handshakeWriter.Write(ClusterId);
             handshakeWriter.WriteBinaryHeader(0); // Features.
-            handshakeWriter.WriteMapHeader(0); // Extensions.
+            handshakeWriter.Write(0); // Extensions.
 
             var handshakeMem = handshakeBufferWriter.GetWrittenMemory();
             handler.Send(new byte[] { 0, 0, 0, (byte)handshakeMem.Length }); 
// Size.
@@ -196,8 +196,8 @@ namespace Apache.Ignite.Tests
                 switch (opCode)
                 {
                     case ClientOp.TablesGet:
-                        // Empty map.
-                        Send(handler, requestId, new byte[] { 128 
}.AsMemory());
+                        // Zero tables.
+                        Send(handler, requestId, new byte[] { 0 }.AsMemory());
                         continue;
 
                     case ClientOp.TableGet:
@@ -233,7 +233,7 @@ namespace Apache.Ignite.Tests
                     {
                         using var arrayBufferWriter = new PooledArrayBuffer();
                         var writer = new MsgPackWriter(arrayBufferWriter);
-                        writer.WriteArrayHeader(PartitionAssignment.Length);
+                        writer.Write(PartitionAssignment.Length);
 
                         foreach (var nodeId in PartitionAssignment)
                         {
@@ -371,7 +371,7 @@ namespace Apache.Ignite.Tests
             using var arrayBufferWriter = new PooledArrayBuffer();
             var writer = new MsgPackWriter(arrayBufferWriter);
 
-            writer.WriteArrayHeader(500); // Page size.
+            writer.Write(500); // Page size.
             for (int i = 0; i < 500; i++)
             {
                 using var tuple = new BinaryTupleBuilder(1);
@@ -447,9 +447,9 @@ namespace Apache.Ignite.Tests
                 writer.Write(false); // WasApplied.
                 writer.Write(0); // AffectedRows.
 
-                writer.WriteArrayHeader(2); // Meta.
+                writer.Write(2); // Meta.
 
-                writer.WriteArrayHeader(6); // Column props.
+                writer.Write(6); // Column props.
                 writer.Write("NAME"); // Column name.
                 writer.Write(false); // Nullable.
                 writer.Write((int)ColumnType.String);
@@ -457,7 +457,7 @@ namespace Apache.Ignite.Tests
                 writer.Write(0); // Precision.
                 writer.Write(false); // No origin.
 
-                writer.WriteArrayHeader(6); // Column props.
+                writer.Write(6); // Column props.
                 writer.Write("VAL"); // Column name.
                 writer.Write(false); // Nullable.
                 writer.Write((int)ColumnType.String);
@@ -465,7 +465,7 @@ namespace Apache.Ignite.Tests
                 writer.Write(0); // Precision.
                 writer.Write(false); // No origin.
 
-                writer.WriteArrayHeader(props.Count); // Page size.
+                writer.Write(props.Count); // Page size.
                 foreach (var (key, val) in props)
                 {
                     using var tuple = new BinaryTupleBuilder(2);
@@ -481,8 +481,8 @@ namespace Apache.Ignite.Tests
                 writer.Write(false); // WasApplied.
                 writer.Write(0); // AffectedRows.
 
-                writer.WriteArrayHeader(1); // Meta.
-                writer.WriteArrayHeader(6); // Column props.
+                writer.Write(1); // Meta.
+                writer.Write(6); // Column props.
                 writer.Write("ID"); // Column name.
                 writer.Write(false); // Nullable.
                 writer.Write((int)ColumnType.Int32);
@@ -490,7 +490,7 @@ namespace Apache.Ignite.Tests
                 writer.Write(0); // Precision.
                 writer.Write(false); // No origin.
 
-                writer.WriteArrayHeader(512); // Page size.
+                writer.Write(512); // Page size.
                 for (int i = 0; i < 512; i++)
                 {
                     using var tuple = new BinaryTupleBuilder(1);
@@ -508,13 +508,13 @@ namespace Apache.Ignite.Tests
 
             using var arrayBufferWriter = new PooledArrayBuffer();
             var writer = new MsgPackWriter(arrayBufferWriter);
-            writer.WriteMapHeader(1);
+            writer.Write(1);
             writer.Write(1); // Version.
 
             if (tableId == ExistingTableId)
             {
-                writer.WriteArrayHeader(1); // Columns.
-                writer.WriteArrayHeader(7); // Column props.
+                writer.Write(1); // Columns.
+                writer.Write(7); // Column props.
                 writer.Write("ID");
                 writer.Write((int)ColumnType.Int32);
                 writer.Write(true); // Key.
@@ -525,9 +525,9 @@ namespace Apache.Ignite.Tests
             }
             else if (tableId == CompositeKeyTableId)
             {
-                writer.WriteArrayHeader(2); // Columns.
+                writer.Write(2); // Columns.
 
-                writer.WriteArrayHeader(7); // Column props.
+                writer.Write(7); // Column props.
                 writer.Write("IdStr");
                 writer.Write((int)ColumnType.String);
                 writer.Write(true); // Key.
@@ -536,7 +536,7 @@ namespace Apache.Ignite.Tests
                 writer.Write(0); // Scale.
                 writer.Write(0); // Precision.
 
-                writer.WriteArrayHeader(7); // Column props.
+                writer.Write(7); // Column props.
                 writer.Write("IdGuid");
                 writer.Write((int)ColumnType.Uuid);
                 writer.Write(true); // Key.
@@ -547,9 +547,9 @@ namespace Apache.Ignite.Tests
             }
             else if (tableId == CustomColocationKeyTableId)
             {
-                writer.WriteArrayHeader(2); // Columns.
+                writer.Write(2); // Columns.
 
-                writer.WriteArrayHeader(7); // Column props.
+                writer.Write(7); // Column props.
                 writer.Write("IdStr");
                 writer.Write((int)ColumnType.String);
                 writer.Write(true); // Key.
@@ -558,7 +558,7 @@ namespace Apache.Ignite.Tests
                 writer.Write(0); // Scale.
                 writer.Write(0); // Precision.
 
-                writer.WriteArrayHeader(7); // Column props.
+                writer.Write(7); // Column props.
                 writer.Write("IdGuid");
                 writer.Write((int)ColumnType.Uuid);
                 writer.Write(true); // Key.
@@ -577,7 +577,7 @@ namespace Apache.Ignite.Tests
             // Else: node name.
             reader.Skip(colocated ? 4 : 1);
 
-            var unitsCount = reader.TryReadNil() ? 0 : 
reader.ReadArrayHeader();
+            var unitsCount = reader.TryReadNil() ? 0 : reader.ReadInt32();
             var units = new List<DeploymentUnit>(unitsCount);
             for (int i = 0; i < unitsCount; i++)
             {
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Tests/Proto/MsgPack/MsgPackReaderTests.cs
 
b/modules/platforms/dotnet/Apache.Ignite.Tests/Proto/MsgPack/MsgPackReaderTests.cs
index 4946efd058..839ad80f24 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite.Tests/Proto/MsgPack/MsgPackReaderTests.cs
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Tests/Proto/MsgPack/MsgPackReaderTests.cs
@@ -48,28 +48,6 @@ public class MsgPackReaderTests
         Guid.Empty, new(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), Guid.NewGuid()
     };
 
-    [Test]
-    public void TestReadArrayHeader()
-    {
-        var bufWriter = new ArrayBufferWriter<byte>();
-        var writer = new MessagePackWriter(bufWriter);
-        var numbers = GetNumbers(int.MaxValue / 2, unsignedOnly: 
true).ToList();
-
-        foreach (var num in numbers)
-        {
-            writer.WriteArrayHeader((uint)num);
-        }
-
-        writer.Flush();
-
-        var reader = new MsgPackReader(bufWriter.WrittenSpan);
-
-        foreach (var num in numbers)
-        {
-            Assert.AreEqual((uint)num, reader.ReadArrayHeader());
-        }
-    }
-
     [Test]
     public void TestTryReadNil()
     {
@@ -87,14 +65,14 @@ public class MsgPackReaderTests
     [Test]
     public void TestReadPastBufferEndThrows()
     {
-        var buf = new byte[] { MsgPackCode.Array16, 0, 0, 0, 0, 0, 0 };
+        var buf = new byte[] { MsgPackCode.Int16, 0, 0, 0, 0, 0, 0 };
 
         Assert.Throws<ArgumentOutOfRangeException>(() =>
         {
             // There is enough data in the array, but we take a smaller slice, 
which is not enough for Array16 header.
             var span = buf.AsSpan()[..2];
             var reader = new MsgPackReader(span);
-            reader.ReadArrayHeader();
+            reader.ReadInt32();
         });
     }
 
@@ -106,8 +84,8 @@ public class MsgPackReaderTests
         Test(m => new MsgPackReader(m.Span).ReadInt32());
         Test(m => new MsgPackReader(m.Span).ReadInt64());
         Test(m => new MsgPackReader(m.Span).ReadStringHeader());
-        Test(m => new MsgPackReader(m.Span).ReadArrayHeader());
-        Test(m => new MsgPackReader(m.Span).ReadMapHeader());
+        Test(m => new MsgPackReader(m.Span).ReadInt32());
+        Test(m => new MsgPackReader(m.Span).ReadInt32());
         Test(m => new MsgPackReader(m.Span).ReadBinaryHeader());
         Test(m => new MsgPackReader(m.Span).ReadGuid());
 
@@ -314,8 +292,8 @@ public class MsgPackReaderTests
         foreach (var num in GetNumbers(int.MaxValue / 2, unsignedOnly: true))
         {
             var res = WriteRead(
-                buf => buf.MessageWriter.WriteMapHeader((int)num),
-                m => new MsgPackReader(m.Span).ReadMapHeader());
+                buf => buf.MessageWriter.Write((int)num),
+                m => new MsgPackReader(m.Span).ReadInt32());
 
             Assert.AreEqual(num, res);
         }
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Tests/Proto/MsgPack/MsgPackWriterTests.cs
 
b/modules/platforms/dotnet/Apache.Ignite.Tests/Proto/MsgPack/MsgPackWriterTests.cs
index 10529f4916..314c9532a4 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite.Tests/Proto/MsgPack/MsgPackWriterTests.cs
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Tests/Proto/MsgPack/MsgPackWriterTests.cs
@@ -126,32 +126,6 @@ public class MsgPackWriterTests
         }
     }
 
-    [Test]
-    public void TestWriteArrayHeader()
-    {
-        foreach (var number in GetNumbers(int.MaxValue / 2, unsignedOnly: 
true))
-        {
-            var res = Write(x => 
x.MessageWriter.WriteArrayHeader((int)number));
-            var readRes = new 
MessagePackReader(res.AsMemory()).TryReadArrayHeader(out var len);
-
-            Assert.IsTrue(readRes);
-            Assert.AreEqual(number, len);
-        }
-    }
-
-    [Test]
-    public void TestWriteMapHeader()
-    {
-        foreach (var number in GetNumbers(int.MaxValue / 2, unsignedOnly: 
true))
-        {
-            var res = Write(x => x.MessageWriter.WriteMapHeader((int)number));
-            var readRes = new 
MessagePackReader(res.AsMemory()).TryReadMapHeader(out var len);
-
-            Assert.IsTrue(readRes);
-            Assert.AreEqual(number, len);
-        }
-    }
-
     [Test]
     public void TestWriteBinaryHeader()
     {
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Tests/RawSocketConnectionTests.cs 
b/modules/platforms/dotnet/Apache.Ignite.Tests/RawSocketConnectionTests.cs
index 5a511b0db9..6c00eee549 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Tests/RawSocketConnectionTests.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Tests/RawSocketConnectionTests.cs
@@ -108,7 +108,7 @@ namespace Apache.Ignite.Tests
             writer.Write(2); // Client type: general purpose.
 
             writer.WriteBinHeader(0); // Features.
-            writer.WriteMapHeader(0); // Extensions.
+            writer.Write(0); // Extensions.
 
             writer.Flush();
 
diff --git a/modules/platforms/dotnet/Apache.Ignite.Tests/Sql/SqlTests.cs 
b/modules/platforms/dotnet/Apache.Ignite.Tests/Sql/SqlTests.cs
index 1ae7b62c8f..7b31b57551 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Tests/Sql/SqlTests.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Tests/Sql/SqlTests.cs
@@ -116,9 +116,9 @@ namespace Apache.Ignite.Tests.Sql
         }
 
         [Test]
-        public async Task TestGetAllMultiplePages()
+        public async Task TestGetAllMultiplePages([Values(1, 2, 3, 4, 5, 6)] 
int pageSize)
         {
-            var statement = new SqlStatement("SELECT ID, VAL FROM TEST ORDER 
BY VAL", pageSize: 4);
+            var statement = new SqlStatement("SELECT ID, VAL FROM TEST ORDER 
BY VAL", pageSize: pageSize);
             await using var resultSet = await Client.Sql.ExecuteAsync(null, 
statement);
             var rows = await resultSet.ToListAsync();
 
diff --git a/modules/platforms/dotnet/Apache.Ignite/Internal/ClientSocket.cs 
b/modules/platforms/dotnet/Apache.Ignite/Internal/ClientSocket.cs
index fb26a2eb0a..2bb5d57a07 100644
--- a/modules/platforms/dotnet/Apache.Ignite/Internal/ClientSocket.cs
+++ b/modules/platforms/dotnet/Apache.Ignite/Internal/ClientSocket.cs
@@ -401,7 +401,7 @@ namespace Apache.Ignite.Internal
             string? javaStackTrace = reader.ReadStringNullable();
             var ex = ExceptionMapper.GetException(traceId, code, className, 
message, javaStackTrace);
 
-            int extensionCount = reader.TryReadNil() ? 0 : 
reader.ReadMapHeader();
+            int extensionCount = reader.TryReadNil() ? 0 : reader.ReadInt32();
             for (int i = 0; i < extensionCount; i++)
             {
                 var key = reader.ReadString();
@@ -512,7 +512,7 @@ namespace Apache.Ignite.Internal
 
             if (configuration.Authenticator != null)
             {
-                w.WriteMapHeader(3); // Extensions.
+                w.Write(3); // Extensions.
 
                 w.Write(HandshakeExtensions.AuthenticationType);
                 w.Write(configuration.Authenticator.Type);
@@ -525,7 +525,7 @@ namespace Apache.Ignite.Internal
             }
             else
             {
-                w.WriteMapHeader(0); // Extensions.
+                w.Write(0); // Extensions.
             }
         }
 
diff --git a/modules/platforms/dotnet/Apache.Ignite/Internal/Compute/Compute.cs 
b/modules/platforms/dotnet/Apache.Ignite/Internal/Compute/Compute.cs
index cc9662b021..3eed52ce96 100644
--- a/modules/platforms/dotnet/Apache.Ignite/Internal/Compute/Compute.cs
+++ b/modules/platforms/dotnet/Apache.Ignite/Internal/Compute/Compute.cs
@@ -153,7 +153,7 @@ namespace Apache.Ignite.Internal.Compute
 
             if (units.TryGetNonEnumeratedCount(out var count))
             {
-                w.WriteArrayHeader(count);
+                w.Write(count);
                 foreach (var unit in units)
                 {
                     if (string.IsNullOrEmpty(unit.Name))
diff --git 
a/modules/platforms/dotnet/Apache.Ignite/Internal/IgniteClientInternal.cs 
b/modules/platforms/dotnet/Apache.Ignite/Internal/IgniteClientInternal.cs
index 8eafc6d731..94eec8fc3e 100644
--- a/modules/platforms/dotnet/Apache.Ignite/Internal/IgniteClientInternal.cs
+++ b/modules/platforms/dotnet/Apache.Ignite/Internal/IgniteClientInternal.cs
@@ -83,12 +83,12 @@ namespace Apache.Ignite.Internal
             IList<IClusterNode> Read()
             {
                 var r = resBuf.GetReader();
-                var count = r.ReadArrayHeader();
+                var count = r.ReadInt32();
                 var res = new List<IClusterNode>(count);
 
                 for (var i = 0; i < count; i++)
                 {
-                    var fieldCount = r.ReadArrayHeader();
+                    var fieldCount = r.ReadInt32();
                     Debug.Assert(fieldCount == 4, "fieldCount == 4");
 
                     res.Add(new ClusterNode(
diff --git 
a/modules/platforms/dotnet/Apache.Ignite/Internal/Proto/MsgPack/MsgPackReader.cs
 
b/modules/platforms/dotnet/Apache.Ignite/Internal/Proto/MsgPack/MsgPackReader.cs
index d4dabf717b..e86f3defa1 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite/Internal/Proto/MsgPack/MsgPackReader.cs
+++ 
b/modules/platforms/dotnet/Apache.Ignite/Internal/Proto/MsgPack/MsgPackReader.cs
@@ -157,19 +157,6 @@ internal ref struct MsgPackReader
         return false;
     }
 
-    /// <summary>
-    /// Reads array header.
-    /// </summary>
-    /// <returns>Array size.</returns>
-    public int ReadArrayHeader() =>
-        _span[_pos++] switch
-        {
-            var code when MsgPackCode.IsFixArr(code) => code & 0x0F,
-            MsgPackCode.Array16 => 
BinaryPrimitives.ReadUInt16BigEndian(GetSpan(2)),
-            MsgPackCode.Array32 => 
checked((int)BinaryPrimitives.ReadUInt32BigEndian(GetSpan(4))),
-            var invalid => throw GetInvalidCodeException("array", invalid)
-        };
-
     /// <summary>
     /// Reads string header.
     /// </summary>
@@ -215,19 +202,6 @@ internal ref struct MsgPackReader
     /// <returns>Span of byte.</returns>
     public ReadOnlySpan<byte> ReadBinary() => GetSpan(ReadBinaryHeader());
 
-    /// <summary>
-    /// Reads map header.
-    /// </summary>
-    /// <returns>Map length.</returns>
-    public int ReadMapHeader() =>
-        _span[_pos++] switch
-        {
-            var code when MsgPackCode.IsFixMap(code) => code & 0x0F,
-            MsgPackCode.Map16 => 
BinaryPrimitives.ReadUInt16BigEndian(GetSpan(2)),
-            MsgPackCode.Map32 => 
checked((int)BinaryPrimitives.ReadUInt32BigEndian(GetSpan(4))),
-            var invalid => throw GetInvalidCodeException("map", invalid)
-        };
-
     /// <summary>
     /// Reads GUID value.
     /// </summary>
diff --git 
a/modules/platforms/dotnet/Apache.Ignite/Internal/Proto/MsgPack/MsgPackWriter.cs
 
b/modules/platforms/dotnet/Apache.Ignite/Internal/Proto/MsgPack/MsgPackWriter.cs
index 4476eab85b..5058eb234e 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite/Internal/Proto/MsgPack/MsgPackWriter.cs
+++ 
b/modules/platforms/dotnet/Apache.Ignite/Internal/Proto/MsgPack/MsgPackWriter.cs
@@ -32,8 +32,6 @@ internal readonly ref struct MsgPackWriter
     private const int MaxFixPositiveInt = 127;
     private const int MaxFixStringLength = 31;
     private const int MinFixNegativeInt = -32;
-    private const int MaxFixMapCount = 15;
-    private const int MaxFixArrayCount = 15;
 
     /// <summary>
     /// Initializes a new instance of the <see cref="MsgPackWriter"/> struct.
@@ -299,56 +297,6 @@ internal readonly ref struct MsgPackWriter
         }
     }
 
-    /// <summary>
-    /// Writes array header.
-    /// </summary>
-    /// <param name="count">Array element count.</param>
-    public void WriteArrayHeader(int count)
-    {
-        if (count <= MaxFixArrayCount)
-        {
-            Buf.GetSpanAndAdvance(1)[0] = (byte)(MsgPackCode.MinFixArray | 
count);
-        }
-        else if (count <= ushort.MaxValue)
-        {
-            var span = Buf.GetSpanAndAdvance(3);
-            span[0] = MsgPackCode.Array16;
-            BinaryPrimitives.WriteUInt16BigEndian(span[1..], (ushort)count);
-        }
-        else
-        {
-            var span = Buf.GetSpanAndAdvance(5);
-
-            span[0] = MsgPackCode.Array32;
-            BinaryPrimitives.WriteUInt32BigEndian(span[1..], (uint)count);
-        }
-    }
-
-    /// <summary>
-    /// Writes map header.
-    /// </summary>
-    /// <param name="count">Map element count.</param>
-    public void WriteMapHeader(int count)
-    {
-        if (count <= MaxFixMapCount)
-        {
-            Buf.GetSpanAndAdvance(1)[0] = (byte)(MsgPackCode.MinFixMap | 
count);
-        }
-        else if (count <= ushort.MaxValue)
-        {
-            var span = Buf.GetSpanAndAdvance(3);
-            span[0] = MsgPackCode.Map16;
-            BinaryPrimitives.WriteUInt16BigEndian(span[1..], (ushort)count);
-        }
-        else
-        {
-            var span = Buf.GetSpanAndAdvance(5);
-
-            span[0] = MsgPackCode.Map32;
-            BinaryPrimitives.WriteUInt32BigEndian(span[1..], (uint)count);
-        }
-    }
-
     /// <summary>
     /// Writes binary header.
     /// </summary>
diff --git a/modules/platforms/dotnet/Apache.Ignite/Internal/Sql/ResultSet.cs 
b/modules/platforms/dotnet/Apache.Ignite/Internal/Sql/ResultSet.cs
index dd08381ea1..3e764a5b85 100644
--- a/modules/platforms/dotnet/Apache.Ignite/Internal/Sql/ResultSet.cs
+++ b/modules/platforms/dotnet/Apache.Ignite/Internal/Sql/ResultSet.cs
@@ -78,7 +78,7 @@ namespace Apache.Ignite.Internal.Sql
             if (HasRowSet)
             {
                 _buffer = buf.Slice(reader.Consumed);
-                HasRows = reader.ReadArrayHeader() > 0;
+                HasRows = reader.ReadInt32() > 0;
             }
             else
             {
@@ -170,7 +170,7 @@ namespace Apache.Ignite.Internal.Sql
             void ReadPage(PooledBuffer buf)
             {
                 var reader = buf.GetReader();
-                var pageSize = reader.ReadArrayHeader();
+                var pageSize = reader.ReadInt32();
 
                 var capacity = hasMore ? pageSize * 2 : pageSize;
                 res ??= constructor(capacity);
@@ -271,7 +271,8 @@ namespace Apache.Ignite.Internal.Sql
             static bool HasMore(PooledBuffer buf)
             {
                 var reader = buf.GetReader();
-                reader.Skip();
+                var rowCount = reader.ReadInt32();
+                reader.Skip(rowCount);
 
                 return !reader.End && reader.ReadBoolean();
             }
@@ -279,13 +280,13 @@ namespace Apache.Ignite.Internal.Sql
 
         private static ResultSetMetadata ReadMeta(ref MsgPackReader reader)
         {
-            var size = reader.ReadArrayHeader();
+            var size = reader.ReadInt32();
 
             var columns = new List<IColumnMetadata>(size);
 
             for (int i = 0; i < size; i++)
             {
-                var propertyCount = reader.ReadArrayHeader();
+                var propertyCount = reader.ReadInt32();
                 const int minCount = 6;
 
                 Debug.Assert(propertyCount >= minCount, "propertyCount >= " + 
minCount);
@@ -348,7 +349,7 @@ namespace Apache.Ignite.Internal.Sql
             {
                 // ReSharper disable AccessToModifiedClosure
                 var reader = buf.GetReader(offset);
-                var pageSize = reader.ReadArrayHeader();
+                var pageSize = reader.ReadInt32();
                 offset += reader.Consumed;
 
                 for (var rowIdx = 0; rowIdx < pageSize; rowIdx++)
diff --git a/modules/platforms/dotnet/Apache.Ignite/Internal/Table/Table.cs 
b/modules/platforms/dotnet/Apache.Ignite/Internal/Table/Table.cs
index a6a98fe667..2c7cf5a709 100644
--- a/modules/platforms/dotnet/Apache.Ignite/Internal/Table/Table.cs
+++ b/modules/platforms/dotnet/Apache.Ignite/Internal/Table/Table.cs
@@ -290,7 +290,7 @@ namespace Apache.Ignite.Internal.Table
                 }
                 else
                 {
-                    w.WriteArrayHeader(1);
+                    w.Write(1);
                     w.Write(version);
                 }
             }
@@ -298,7 +298,7 @@ namespace Apache.Ignite.Internal.Table
             Schema Read()
             {
                 var r = resBuf.GetReader();
-                var schemaCount = r.ReadMapHeader();
+                var schemaCount = r.ReadInt32();
 
                 if (schemaCount == 0)
                 {
@@ -325,7 +325,7 @@ namespace Apache.Ignite.Internal.Table
         private Schema ReadSchema(ref MsgPackReader r)
         {
             var schemaVersion = r.ReadInt32();
-            var columnCount = r.ReadArrayHeader();
+            var columnCount = r.ReadInt32();
             var keyColumnCount = 0;
             var colocationColumnCount = 0;
 
@@ -333,7 +333,7 @@ namespace Apache.Ignite.Internal.Table
 
             for (var i = 0; i < columnCount; i++)
             {
-                var propertyCount = r.ReadArrayHeader();
+                var propertyCount = r.ReadInt32();
                 const int expectedCount = 7;
 
                 Debug.Assert(propertyCount >= expectedCount, "propertyCount >= 
" + expectedCount);
@@ -403,7 +403,7 @@ namespace Apache.Ignite.Internal.Table
             string[]? Read()
             {
                 var r = resBuf.GetReader();
-                var count = r.ReadArrayHeader();
+                var count = r.ReadInt32();
 
                 if (count == 0)
                 {
diff --git a/modules/platforms/dotnet/Apache.Ignite/Internal/Table/Tables.cs 
b/modules/platforms/dotnet/Apache.Ignite/Internal/Table/Tables.cs
index cde9b136ba..8d532fc222 100644
--- a/modules/platforms/dotnet/Apache.Ignite/Internal/Table/Tables.cs
+++ b/modules/platforms/dotnet/Apache.Ignite/Internal/Table/Tables.cs
@@ -65,7 +65,7 @@ namespace Apache.Ignite.Internal.Table
 
             IList<ITable> Read(MsgPackReader r)
             {
-                var len = r.ReadMapHeader();
+                var len = r.ReadInt32();
 
                 var res = new List<ITable>(len);
 
diff --git a/modules/platforms/dotnet/Apache.Ignite/Sql/IgniteDbDataReader.cs 
b/modules/platforms/dotnet/Apache.Ignite/Sql/IgniteDbDataReader.cs
index 06fd30835e..d415542b9d 100644
--- a/modules/platforms/dotnet/Apache.Ignite/Sql/IgniteDbDataReader.cs
+++ b/modules/platforms/dotnet/Apache.Ignite/Sql/IgniteDbDataReader.cs
@@ -537,7 +537,7 @@ public sealed class IgniteDbDataReader : DbDataReader, 
IDbColumnSchemaGenerator
         {
             var reader = _pageEnumerator.Current.GetReader();
 
-            _pageRowCount = reader.ReadArrayHeader();
+            _pageRowCount = reader.ReadInt32();
             _pageRowOffset = reader.Consumed;
             _pageRowIndex = 0;
             _pageRowSize = (_pageRowCount > 0 ? reader.ReadBinaryHeader() : 0) 
+ reader.Consumed - _pageRowOffset;

Reply via email to