コード例 #1
0
        //-------------------------------------------------------
        // Private methods.
        //-------------------------------------------------------

        /// <summary>
        /// Issue request and set results buffer. This method is used internally.
        /// The static request methods should be used instead.
        /// </summary>
        /// <param name="conn">socket connection to server node</param>
        /// <exception cref="AerospikeException">if socket send or receive fails</exception>
        private void SendCommand(Connection conn)
        {
            try
            {
                // Write size field.
                ulong size = ((ulong)offset - 8L) | (2L << 56) | (1L << 48);
                ByteUtil.LongToBytes(size, buffer, 0);

                // Write.
                conn.Write(buffer, offset);

                // Read - reuse input buffer.
                conn.ReadFully(buffer, 8);

                size   = (ulong)ByteUtil.BytesToLong(buffer, 0);
                length = (int)(size & 0xFFFFFFFFFFFFL);
                ResizeBuffer(length);
                conn.ReadFully(buffer, length);
                offset = 0;
            }
            catch (SocketException se)
            {
                throw new AerospikeException(se);
            }
        }
コード例 #2
0
 public long GetLongBig(int offset)
 {
     if (offset < 0 || offset + 8 > this.length)
     {
         return(0);
     }
     return(ByteUtil.BytesToLong(bytes, offset));
 }
コード例 #3
0
        private void ReceiveEvent()
        {
            //Log.Info("Receive Event: " + eventArgs.BytesTransferred + "," + dataOffset + "," + dataLength + "," + inHeader);

            if (eventArgs.BytesTransferred <= 0)
            {
                FailOnNetworkError(new AerospikeException.Connection("Connection closed"));
                return;
            }

            dataOffset += eventArgs.BytesTransferred;

            if (dataOffset < dataLength)
            {
                eventArgs.SetBuffer(dataOffset, dataLength - dataOffset);
                Receive();
                return;
            }
            dataOffset = 0;

            if (inHeader)
            {
                dataLength = (int)(ByteUtil.BytesToLong(dataBuffer, 0) & 0xFFFFFFFFFFFFL);

                if (dataLength <= 0)
                {
                    ReceiveBegin();
                    return;
                }

                inHeader = false;

                if (dataLength > dataBuffer.Length)
                {
                    ResizeBuffer();
                }
                eventArgs.SetBuffer(dataBuffer, dataOffset, dataLength);
                Receive();
            }
            else
            {
                if (inAuthenticate)
                {
                    inAuthenticate = false;
                    inHeader       = true;

                    int resultCode = dataBuffer[1];

                    if (resultCode != 0)
                    {
                        throw new AerospikeException(resultCode);
                    }
                    ConnectionReady();
                    return;
                }
                ParseCommand();
            }
        }
コード例 #4
0
        protected internal override void ParseResult(Connection conn)
        {
            // Read header.
            conn.ReadFully(dataBuffer, MSG_TOTAL_HEADER_SIZE);

            long sz           = ByteUtil.BytesToLong(dataBuffer, 0);
            byte headerLength = dataBuffer[8];
            int  resultCode   = dataBuffer[13];
            int  generation   = ByteUtil.BytesToInt(dataBuffer, 14);
            int  expiration   = ByteUtil.BytesToInt(dataBuffer, 18);
            int  fieldCount   = ByteUtil.BytesToShort(dataBuffer, 26);          // almost certainly 0
            int  opCount      = ByteUtil.BytesToShort(dataBuffer, 28);
            int  receiveSize  = ((int)(sz & 0xFFFFFFFFFFFFL)) - headerLength;

            // Read remaining message bytes.
            if (receiveSize > 0)
            {
                SizeBuffer(receiveSize);
                conn.ReadFully(dataBuffer, receiveSize);
            }

            if (resultCode == 0)
            {
                if (opCount == 0)
                {
                    // Bin data was not returned.
                    record = new Record(null, generation, expiration);
                    return;
                }
                record = ParseRecord(opCount, fieldCount, generation, expiration);
                return;
            }

            if (resultCode == ResultCode.KEY_NOT_FOUND_ERROR)
            {
                HandleNotFound(resultCode);
                return;
            }

            if (resultCode == ResultCode.FILTERED_OUT)
            {
                if (policy.failOnFilteredOut)
                {
                    throw new AerospikeException(resultCode);
                }
                return;
            }

            if (resultCode == ResultCode.UDF_BAD_RESPONSE)
            {
                record = ParseRecord(opCount, fieldCount, generation, expiration);
                HandleUdfError(resultCode);
                return;
            }

            throw new AerospikeException(resultCode);
        }
コード例 #5
0
        protected internal void EmptySocket(Connection conn)
        {
            // There should not be any more bytes.
            // Empty the socket to be safe.
            long sz           = ByteUtil.BytesToLong(dataBuffer, 0);
            int  headerLength = dataBuffer[8];
            int  receiveSize  = ((int)(sz & 0xFFFFFFFFFFFFL)) - headerLength;

            // Read remaining message bytes.
            if (receiveSize > 0)
            {
                SizeBuffer(receiveSize);
                conn.ReadFully(dataBuffer, receiveSize);
            }
        }
コード例 #6
0
        private int ReadBlocks(Connection conn)
        {
            int status = 0;

            while (status == 0)
            {
                conn.ReadFully(dataBuffer, 8);
                long size        = ByteUtil.BytesToLong(dataBuffer, 0);
                int  receiveSize = ((int)(size & 0xFFFFFFFFFFFFL));

                if (receiveSize > 0)
                {
                    if (receiveSize > dataBuffer.Length)
                    {
                        dataBuffer = ThreadLocalData.ResizeBuffer(receiveSize);
                    }
                    conn.ReadFully(dataBuffer, receiveSize);
                    status = ParseBlock(receiveSize);
                }
            }
            return(status);
        }
コード例 #7
0
        protected internal sealed override void ParseResult(Connection conn)
        {
            // Read socket into receive buffer one record at a time.  Do not read entire receive size
            // because the thread local receive buffer would be too big.  Also, scan callbacks can nest
            // further database commands which contend with the receive buffer.
            bconn = new BufferedConnection(conn, 8192);
            bool status = true;

            while (status)
            {
                // Read header.
                ReadBytes(8);

                long size        = ByteUtil.BytesToLong(dataBuffer, 0);
                int  receiveSize = ((int)(size & 0xFFFFFFFFFFFFL));

                if (receiveSize > 0)
                {
                    status = ParseGroup(receiveSize);
                }
            }
        }
コード例 #8
0
        protected internal override void ParseResult(Connection conn)
        {
            // Read header.
            conn.ReadFully(dataBuffer, 8);

            long sz          = ByteUtil.BytesToLong(dataBuffer, 0);
            int  receiveSize = (int)(sz & 0xFFFFFFFFFFFFL);

            if (receiveSize <= 0)
            {
                throw new AerospikeException("Invalid receive size: " + receiveSize);
            }

            SizeBuffer(receiveSize);
            conn.ReadFully(dataBuffer, receiveSize);
            conn.UpdateLastUsed();

            ulong type = (ulong)((sz >> 48) & 0xff);

            if (type == Command.AS_MSG_TYPE)
            {
                dataOffset = 5;
            }
            else if (type == Command.MSG_TYPE_COMPRESSED)
            {
                int    usize = (int)ByteUtil.BytesToLong(dataBuffer, 0);
                byte[] ubuf  = new byte[usize];

                ByteUtil.Decompress(dataBuffer, 8, receiveSize, ubuf, usize);
                dataBuffer = ubuf;
                dataOffset = 13;
            }
            else
            {
                throw new AerospikeException("Invalid proto type: " + type + " Expected: " + Command.AS_MSG_TYPE);
            }

            int resultCode = dataBuffer[dataOffset];

            dataOffset++;
            int generation = ByteUtil.BytesToInt(dataBuffer, dataOffset);

            dataOffset += 4;
            int expiration = ByteUtil.BytesToInt(dataBuffer, dataOffset);

            dataOffset += 8;
            int fieldCount = ByteUtil.BytesToShort(dataBuffer, dataOffset);

            dataOffset += 2;
            int opCount = ByteUtil.BytesToShort(dataBuffer, dataOffset);

            dataOffset += 2;

            if (resultCode == 0)
            {
                if (opCount == 0)
                {
                    // Bin data was not returned.
                    record = new Record(null, generation, expiration);
                    return;
                }
                record = ParseRecord(opCount, fieldCount, generation, expiration);
                return;
            }

            if (resultCode == ResultCode.KEY_NOT_FOUND_ERROR)
            {
                HandleNotFound(resultCode);
                return;
            }

            if (resultCode == ResultCode.FILTERED_OUT)
            {
                if (policy.failOnFilteredOut)
                {
                    throw new AerospikeException(resultCode);
                }
                return;
            }

            if (resultCode == ResultCode.UDF_BAD_RESPONSE)
            {
                record = ParseRecord(opCount, fieldCount, generation, expiration);
                HandleUdfError(resultCode);
                return;
            }

            throw new AerospikeException(resultCode);
        }
コード例 #9
0
        internal void ReceiveEvent()
        {
            if (eventArgs.BytesTransferred <= 0)
            {
                Fail("Connection closed");
                return;
            }

            dataOffset += eventArgs.BytesTransferred;

            if (dataOffset < dataLength)
            {
                eventArgs.SetBuffer(dataOffset, dataLength - dataOffset);
                Receive();
                return;
            }
            dataOffset = 0;

            if (inHeader)
            {
                long proto  = ByteUtil.BytesToLong(dataBuffer, dataOffset);
                int  length = (int)(proto & 0xFFFFFFFFFFFFL);

                if (length <= 0)
                {
                    ReceiveBegin();
                    return;
                }

                inHeader = false;

                if (length > dataBuffer.Length)
                {
                    Fail("Invalid auth response");
                    return;
                }
                eventArgs.SetBuffer(dataOffset, length);
                dataLength = dataOffset + length;
                Receive();
            }
            else
            {
                int resultCode = dataBuffer[dataOffset + 1];

                if (resultCode != 0 && resultCode != ResultCode.SECURITY_NOT_ENABLED)
                {
                    // Authentication failed. Session token probably expired.
                    // Signal tend thread to perform node login, so future
                    // transactions do not fail.
                    node.SignalLogin();

                    // This is a rare event because the client tracks session
                    // expiration and will relogin before session expiration.
                    // Do not try to login on same socket because login can take
                    // a long time and thousands of simultaneous logins could
                    // overwhelm server.
                    Fail("Failed to authenticate: " + resultCode);
                    return;
                }
                ConnectionReady();
            }
        }
コード例 #10
0
        private void ReceiveEvent()
        {
            //Log.Info("Receive Event: " + eventArgs.BytesTransferred + "," + dataOffset + "," + dataLength + "," + inHeader);
            if (usingSocketTimeout)
            {
                eventReceived = true;
            }

            if (eventArgs.BytesTransferred <= 0)
            {
                ConnectionFailed(new AerospikeException.Connection("Connection closed"));
                return;
            }

            dataOffset += eventArgs.BytesTransferred;

            if (dataOffset < dataLength)
            {
                eventArgs.SetBuffer(dataOffset, dataLength - dataOffset);
                Receive();
                return;
            }
            dataOffset = segment.offset;

            if (inHeader)
            {
                int length = (int)(ByteUtil.BytesToLong(dataBuffer, dataOffset) & 0xFFFFFFFFFFFFL);

                if (length <= 0)
                {
                    ReceiveBegin();
                    return;
                }

                inHeader = false;

                if (length > segment.size)
                {
                    ResizeBuffer(length);
                    dataBuffer = segment.buffer;
                    dataOffset = segment.offset;
                }
                eventArgs.SetBuffer(dataBuffer, dataOffset, length);
                dataLength = dataOffset + length;
                Receive();
            }
            else
            {
                if (inAuthenticate)
                {
                    inAuthenticate = false;
                    inHeader       = true;

                    int resultCode = dataBuffer[dataOffset + 1];

                    if (resultCode != 0)
                    {
                        // Authentication failed. Session token probably expired.
                        // Signal tend thread to perform node login, so future
                        // transactions do not fail.
                        node.SignalLogin();

                        // This is a rare event because the client tracks session
                        // expiration and will relogin before session expiration.
                        // Do not try to login on same socket because login can take
                        // a long time and thousands of simultaneous logins could
                        // overwhelm server.
                        throw new AerospikeException(resultCode);
                    }
                    ConnectionReady();
                    return;
                }
                ParseCommand();
            }
        }
コード例 #11
0
        private object UnpackObject()
        {
            int type = buffer[offset++];

            switch (type)
            {
            case 0xc0:                     // nil
            {
                return(null);
            }

            case 0xc3:                     // boolean true
            {
                return(true);
            }

            case 0xc2:                     // boolean false
            {
                return(false);
            }

            case 0xca:                     // float
            {
                float val = ByteUtil.BytesToFloat(buffer, offset);
                offset += 4;
                return(val);
            }

            case 0xcb:                     // double
            {
                double val = ByteUtil.BytesToDouble(buffer, offset);
                offset += 8;
                return(val);
            }

            case 0xd0:                     // signed 8 bit integer
            {
                return((long)(sbyte)(buffer[offset++]));
            }

            case 0xcc:                     // unsigned 8 bit integer
            {
                return((long)(buffer[offset++]));
            }

            case 0xd1:                     // signed 16 bit integer
            {
                int val = ByteUtil.BytesToShort(buffer, offset);
                offset += 2;
                return((long)(short)val);
            }

            case 0xcd:                     // unsigned 16 bit integer
            {
                int val = ByteUtil.BytesToShort(buffer, offset);
                offset += 2;
                return((long)val);
            }

            case 0xd2:                     // signed 32 bit integer
            {
                int val = ByteUtil.BytesToInt(buffer, offset);
                offset += 4;
                return((long)val);
            }

            case 0xce:                     // unsigned 32 bit integer
            {
                uint val = ByteUtil.BytesToUInt(buffer, offset);
                offset += 4;
                return((long)val);
            }

            case 0xd3:                     // signed 64 bit integer
            {
                long val = ByteUtil.BytesToLong(buffer, offset);
                offset += 8;
                return(val);
            }

            case 0xcf:                     // unsigned 64 bit integer
            {
                // The contract is to always return long.
                // The caller can always cast back to ulong.
                long val = ByteUtil.BytesToLong(buffer, offset);
                offset += 8;
                return(val);
            }

            case 0xda:                     // raw bytes with 16 bit header
            {
                int count = ByteUtil.BytesToShort(buffer, offset);
                offset += 2;
                return(UnpackBlob(count));
            }

            case 0xdb:                     // raw bytes with 32 bit header
            {
                // Array length is restricted to positive int values (0 - int.MAX_VALUE).
                int count = ByteUtil.BytesToInt(buffer, offset);
                offset += 4;
                return(UnpackBlob(count));
            }

            case 0xdc:                     // list with 16 bit header
            {
                int count = ByteUtil.BytesToShort(buffer, offset);
                offset += 2;
                return(UnpackList(count));
            }

            case 0xdd:                     // list with 32 bit header
            {
                // List size is restricted to positive int values (0 - int.MAX_VALUE).
                int count = ByteUtil.BytesToInt(buffer, offset);
                offset += 4;
                return(UnpackList(count));
            }

            case 0xde:                     // map with 16 bit header
            {
                int count = ByteUtil.BytesToShort(buffer, offset);
                offset += 2;
                return(UnpackMap(count));
            }

            case 0xdf:                     // map with 32 bit header
            {
                // Map size is restricted to positive int values (0 - int.MAX_VALUE).
                int count = ByteUtil.BytesToInt(buffer, offset);
                offset += 4;
                return(UnpackMap(count));
            }

            default:
            {
                if ((type & 0xe0) == 0xa0)                         // raw bytes with 8 bit combined header
                {
                    return(UnpackBlob(type & 0x1f));
                }

                if ((type & 0xf0) == 0x80)                         // map with 8 bit combined header
                {
                    return(UnpackMap(type & 0x0f));
                }

                if ((type & 0xf0) == 0x90)                         // list with 8 bit combined header
                {
                    return(UnpackList(type & 0x0f));
                }

                if (type < 0x80)                         // 8 bit combined unsigned integer
                {
                    return((long)type);
                }

                if (type >= 0xe0)                         // 8 bit combined signed integer
                {
                    return((long)(type - 0xe0 - 32));
                }
                throw new IOException("Unknown unpack type: " + type);
            }
            }
        }
コード例 #12
0
        public void Login(Cluster cluster, Connection conn, out byte[] sessionToken, out DateTime?sessionExpiration)
        {
            sessionToken      = null;
            sessionExpiration = null;
            dataOffset        = 8;

            conn.SetTimeout(cluster.loginTimeout);

            try
            {
                if (cluster.authMode == AuthMode.INTERNAL)
                {
                    WriteHeader(LOGIN, 2);
                    WriteField(USER, cluster.user);
                    WriteField(CREDENTIAL, cluster.passwordHash);
                }
                else
                {
                    WriteHeader(LOGIN, 3);
                    WriteField(USER, cluster.user);
                    WriteField(CREDENTIAL, cluster.passwordHash);
                    WriteField(CLEAR_PASSWORD, cluster.password);
                }
                WriteSize();
                conn.Write(dataBuffer, dataOffset);
                conn.ReadFully(dataBuffer, HEADER_SIZE);

                int result = dataBuffer[RESULT_CODE];

                if (result != 0)
                {
                    if (result == INVALID_COMMAND)
                    {
                        // New login not supported.  Try old authentication.
                        AuthenticateOld(cluster, conn);
                        return;
                    }

                    // login failed.
                    throw new AerospikeException(result, "Login failed");
                }

                // Read session token.
                long size        = ByteUtil.BytesToLong(dataBuffer, 0);
                int  receiveSize = ((int)(size & 0xFFFFFFFFFFFFL)) - HEADER_REMAINING;
                int  fieldCount  = dataBuffer[11];

                if (receiveSize <= 0 || receiveSize > dataBuffer.Length || fieldCount <= 0)
                {
                    throw new AerospikeException(result, "Failed to retrieve session token");
                }

                conn.ReadFully(dataBuffer, receiveSize);
                dataOffset = 0;

                for (int i = 0; i < fieldCount; i++)
                {
                    int len = ByteUtil.BytesToInt(dataBuffer, dataOffset);
                    dataOffset += 4;
                    int id = dataBuffer[dataOffset++];
                    len--;

                    if (id == SESSION_TOKEN)
                    {
                        sessionToken = new byte[len];
                        Array.Copy(dataBuffer, dataOffset, sessionToken, 0, len);
                    }
                    else if (id == SESSION_TTL)
                    {
                        // Subtract 60 seconds from ttl so client session expires before server session.
                        long seconds = ByteUtil.BytesToUInt(dataBuffer, dataOffset) - 60;

                        if (seconds > 0)
                        {
                            sessionExpiration = DateTime.UtcNow.AddSeconds(seconds);
                        }
                        else
                        {
                            Log.Warn("Invalid session TTL: " + seconds);
                        }
                    }
                    dataOffset += len;
                }

                if (sessionToken == null)
                {
                    throw new AerospikeException(result, "Failed to retrieve session token");
                }
            }
            finally
            {
                conn.SetTimeout(cluster.connectionTimeout);
            }
        }
コード例 #13
0
        private void ReceiveEvent()
        {
            //Log.Info("Receive Event: " + eventArgs.BytesTransferred + "," + dataOffset + "," + dataLength + "," + inHeader);
            if (socketWatch != null)
            {
                eventReceived = true;
            }

            if (eventArgs.BytesTransferred <= 0)
            {
                ConnectionFailed(new AerospikeException.Connection("Connection closed"));
                return;
            }

            dataOffset += eventArgs.BytesTransferred;

            if (dataOffset < dataLength)
            {
                eventArgs.SetBuffer(dataOffset, dataLength - dataOffset);
                Receive();
                return;
            }
            dataOffset = segment.offset;

            if (inHeader)
            {
                long proto  = ByteUtil.BytesToLong(dataBuffer, dataOffset);
                int  length = (int)(proto & 0xFFFFFFFFFFFFL);

                if (length <= 0)
                {
                    ReceiveBegin();
                    return;
                }

                compressed = ((proto >> 48) & 0xFF) == (long)Command.MSG_TYPE_COMPRESSED;
                inHeader   = false;

                if (length > segment.size)
                {
                    ResizeBuffer(length);
                    dataBuffer = segment.buffer;
                    dataOffset = segment.offset;
                }
                eventArgs.SetBuffer(dataBuffer, dataOffset, length);
                dataLength = dataOffset + length;
                Receive();
            }
            else
            {
                if (inAuthenticate)
                {
                    inAuthenticate = false;
                    inHeader       = true;

                    int resultCode = dataBuffer[dataOffset + 1];

                    if (resultCode != 0 && resultCode != ResultCode.SECURITY_NOT_ENABLED)
                    {
                        // Authentication failed. Session token probably expired.
                        // Signal tend thread to perform node login, so future
                        // transactions do not fail.
                        node.SignalLogin();

                        // This is a rare event because the client tracks session
                        // expiration and will relogin before session expiration.
                        // Do not try to login on same socket because login can take
                        // a long time and thousands of simultaneous logins could
                        // overwhelm server.
                        throw new AerospikeException(resultCode);
                    }
                    ConnectionReady();
                    return;
                }

                conn.UpdateLastUsed();

                if (compressed)
                {
                    int usize = (int)ByteUtil.BytesToLong(dataBuffer, dataOffset);
                    dataOffset += 8;
                    byte[] ubuf = new byte[usize];

                    ByteUtil.Decompress(dataBuffer, dataOffset, dataLength, ubuf, usize);
                    dataBuffer = ubuf;
                    dataOffset = 8;
                    dataLength = usize;
                }

                ParseCommand();
            }
        }
コード例 #14
0
        private void ReceiveEvent()
        {
            //Log.Info("Receive Event: " + eventArgs.BytesTransferred + "," + dataOffset + "," + dataLength + "," + inHeader);
            if (usingSocketTimeout)
            {
                eventReceived = true;
            }

            if (eventArgs.BytesTransferred <= 0)
            {
                ConnectionFailed(new AerospikeException.Connection("Connection closed"));
                return;
            }

            dataOffset += eventArgs.BytesTransferred;

            if (dataOffset < dataLength)
            {
                eventArgs.SetBuffer(dataOffset, dataLength - dataOffset);
                Receive();
                return;
            }
            dataOffset = segment.offset;

            if (inHeader)
            {
                int length = (int)(ByteUtil.BytesToLong(dataBuffer, dataOffset) & 0xFFFFFFFFFFFFL);

                if (length <= 0)
                {
                    ReceiveBegin();
                    return;
                }

                inHeader = false;

                if (length > segment.size)
                {
                    ResizeBuffer(length);
                    dataBuffer = segment.buffer;
                    dataOffset = segment.offset;
                }
                eventArgs.SetBuffer(dataBuffer, dataOffset, length);
                dataLength = dataOffset + length;
                Receive();
            }
            else
            {
                if (inAuthenticate)
                {
                    inAuthenticate = false;
                    inHeader       = true;

                    int resultCode = dataBuffer[dataOffset + 1];

                    if (resultCode != 0)
                    {
                        throw new AerospikeException(resultCode);
                    }
                    ConnectionReady();
                    return;
                }
                ParseCommand();
            }
        }
コード例 #15
0
        protected internal sealed override void ParseResult(Connection conn)
        {
            // Read blocks of records.  Do not use thread local receive buffer because each
            // block will likely be too big for a cache.  Also, scan callbacks can nest
            // further database commands which would contend with the thread local receive buffer.
            // Instead, use separate heap allocated buffers.
            byte[] protoBuf = new byte[8];
            byte[] buf      = null;
            byte[] ubuf     = null;
            int    receiveSize;

            while (true)
            {
                // Read header
                conn.ReadFully(protoBuf, 8);

                long proto = ByteUtil.BytesToLong(protoBuf, 0);
                int  size  = (int)(proto & 0xFFFFFFFFFFFFL);

                if (size <= 0)
                {
                    continue;
                }

                // Prepare buffer
                if (buf == null || size > buf.Length)
                {
                    // Corrupted data streams can result in a huge length.
                    // Do a sanity check here.
                    if (size > MAX_BUFFER_SIZE)
                    {
                        throw new AerospikeException("Invalid proto size: " + size);
                    }

                    int capacity = (size + 16383) & ~16383;                     // Round up in 16KB increments.
                    buf = new byte[capacity];
                }

                // Read remaining message bytes in group.
                conn.ReadFully(buf, size);
                conn.UpdateLastUsed();

                ulong type = (ulong)((proto >> 48) & 0xff);

                if (type == Command.AS_MSG_TYPE)
                {
                    dataBuffer  = buf;
                    dataOffset  = 0;
                    receiveSize = size;
                }
                else if (type == Command.MSG_TYPE_COMPRESSED)
                {
                    int usize = (int)ByteUtil.BytesToLong(buf, 0);

                    if (ubuf == null || usize > ubuf.Length)
                    {
                        if (usize > MAX_BUFFER_SIZE)
                        {
                            throw new AerospikeException("Invalid proto size: " + usize);
                        }

                        int capacity = (usize + 16383) & ~16383;                         // Round up in 16KB increments.
                        ubuf = new byte[capacity];
                    }

                    ByteUtil.Decompress(buf, 8, size, ubuf, usize);
                    dataBuffer  = ubuf;
                    dataOffset  = 8;
                    receiveSize = usize;
                }
                else
                {
                    throw new AerospikeException("Invalid proto type: " + type + " Expected: " + Command.AS_MSG_TYPE);
                }

                if (!ParseGroup(receiveSize))
                {
                    break;
                }
            }
        }